Added SpellList Dialog

This commit is contained in:
Thaum
2015-02-13 08:44:30 +00:00
parent 7441f09f37
commit b200478425
10 changed files with 207 additions and 31 deletions

View File

@@ -3,10 +3,12 @@ SpellLists = new Meteor.Collection("spellLists");
Schemas.SpellLists = new SimpleSchema({
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
name: {type: String},
description: {type: String, optional: true},
saveDC: {type: String, optional: true},
attackBonus: {type: String, optional: true},
maxPrepared: {type: String, optional: true},
"settings.showUnprepared": {type: Boolean, defaultValue: true}
color: {type: String, allowedValues: _.keys(colorOptions), defaultValue: "green"},
"settings.showUnprepared": {type: Boolean, defaultValue: true},
});
SpellLists.attachSchema(Schemas.SpellLists);

View File

@@ -0,0 +1,8 @@
Template.registerHelper("evaluate", function(charId, string){
return evaluate(charId, string);
});
Template.registerHelper("evaluateSigned", function(charId, string){
var number = evaluate(charId, string);
return number > 0? "+" + number : "" + number;
});

View File

@@ -1,10 +1,7 @@
#inventory {
padding: 4px;
}
.containers {
display: flex;
flex-wrap: wrap;
padding: 4px;
}
.container {
@@ -16,6 +13,7 @@
cursor: pointer;
margin: -16px -16px 0 -16px;
padding: 16px;
position: relative;
}
.equipmentTop {
@@ -39,6 +37,16 @@
transition: box-shadow 0.35s cubic-bezier(0.4, 0, 0.2, 1);
height: 40px;
margin: 1px 0 1px 0;
font-size: 16px;
color: rgba(0,0,0,0.87);
letter-spacing: 0.010em;
}
.inventoryItem /deep/ .button-content {
-webkit-flex: 1;
flex: 1;
-webkit-flex-basis: 0.000000001px;
flex-basis: 0.000000001px;
}
.inventoryItem[hero] {

View File

@@ -0,0 +1,3 @@
.spellListDialog .colorDropdown {
top: 0;
}

View File

@@ -0,0 +1,48 @@
<template name="spellListDialog">
{{#with spellList}}
<core-header-panel fit class="spellListDialog">
<core-toolbar hero-id="toolbar" class={{colorClass}} hero>
<paper-icon-button id="backButton" role="button" tabindex="0" icon="arrow-back" aria-label="close"></paper-icon-button>
<div flex hero-id="title" hero>{{name}}</div>
<paper-icon-button id="deleteSpellList"
role="button"
tabindex="0"
icon="delete"
aria-label="Delete Feature"
noink></paper-icon-button>
</core-toolbar>
<div class="detailContent">
<!--Name-->
<div horizontal layout>
<paper-input id="spellListNameInput" label="Name" floatinglabel value={{name}} flex></paper-input>
<!--Color-->
{{> colorDropdown}}<br>
</div>
<!--Save DC-->
<paper-input id="spellListSaveDCInput"
label="Save DC"
floatinglabel
value={{saveDC}}
style="width: 100%;"></paper-input><br>
<!--Attack Bonus-->
<paper-input id="spellListAttackBonusInput"
label="Attack Bonus"
floatinglabel
value={{attackBonus}}
style="width: 100%;"></paper-input><br>
<!--Max Prepared-->
<paper-input id="spellListMaxPreparedInput"
label="Maximum Prepared Spells"
floatinglabel
value={{maxPrepared}}
style="width: 100%;"></paper-input><br>
<!--Description-->
<paper-input-decorator label="Description" floatinglabel layout vertical>
<paper-autogrow-textarea>
<textarea id="spellListDescriptionInput" placeholder value={{description}}></textarea>
</paper-autogrow-textarea>
</paper-input-decorator>
</div>
</core-header-panel>
{{/with}}
</template>

View File

@@ -0,0 +1,61 @@
Template.spellListDialog.rendered = function(){
var self = this;
//update all autogrows after they've been filled
var pata = this.$("paper-autogrow-textarea");
pata.each(function(index, el){
el.update($(el).children().get(0));
})
//update all input fields as well
var input = this.$("paper-input");
input.each(function(index, el){
el.valueChanged();
})
//after the dialog is built, open it
if (!this.alreadyRendered){
Session.set("global.ui.detailShow", true);
this.alreadyRendered = true;
}
}
Template.spellListDialog.events({
"tap #backButton": function(){
GlobalUI.closeDetail();
},
"tap #deleteSpellList": function(){
SpellLists.remove(this._id);
GlobalUI.closeDetail();
},
//TODO clean up String -> num here so they don't need casting by Schema.clean
//TODO validate input (integer, non-negative, etc) for these inputs and give validation errors
"change #spellListNameInput, input #spellListNameInput": function(event){
var value = event.currentTarget.value
SpellLists.update(this._id, {$set: {name: value}});
},
"change #spellListSaveDCInput, input #spellListNameInput": function(event){
var value = event.currentTarget.value
SpellLists.update(this._id, {$set: {saveDC: value}});
},
"change #spellListAttackBonusInput, input #spellListNameInput": function(event){
var value = event.currentTarget.value
SpellLists.update(this._id, {$set: {attackBonus: value}});
},
"change #spellListMaxPreparedInput, input #spellListNameInput": function(event){
var value = event.currentTarget.value
SpellLists.update(this._id, {$set: {maxPrepared: value}});
},
"core-select .colorDropdown": function(event){
var detail = event.originalEvent.detail;
if(!detail.isSelected) return;
var value = detail.item.getAttribute("name");
SpellLists.update(this._id, {$set: {color: value}});
}
});
Template.spellListDialog.helpers({
spellList: function(){
return SpellLists.findOne(this.spellListId);
},
colorClass: function(){
return getColorClass(this.color)
}
});

View File

@@ -1,3 +0,0 @@
#spells {
padding: 4px;
}

View File

@@ -3,12 +3,23 @@
<div id="spells" class="scroll-y" fit>
<div class="containers">
{{#each spellLists}}
<paper-shadow class="card container" hero-id="main" {{detailHero}}>
<div class="containerTop green white-text" hero-id="toolbar" layout horizontal center {{detailHero}}>
<div class="containerName subhead" hero-id="title" flex {{detailHero}}>{{name}}</div>
<paper-shadow class="card container" hero-id="main" {{detailHero}} style="order: {{order}};">
<div class="containerTop {{colorClass}}" hero-id="toolbar" layout horizontal center {{detailHero}}>
<div flex>
<div class="containerName subhead">{{name}}</div>
<div class="caption">
{{#if saveDC}}
Save DC: {{evaluate charId saveDC}}
<div style="width: 16px; display: inline-block;"></div>
{{/if}}
{{#if attackBonus}}
Attack Bonus: {{evaluateSigned charId attackBonus}}
{{/if}}
</div>
</div>
{{#if maxPrepared}}<div class="subhead">{{numPrepared}} / {{maxPrepared}}</div>{{/if}}
</div>
<div flex class="containerMain">
<div class="containerMain">
{{#each levels}}
{{#if spellCount ../_id ../../_id}}
<div class="list-subhead" layout horizontal center>{{name}}</div>
@@ -16,7 +27,9 @@
{{#each spells ../_id ../../_id}}
<div class="itemSlot">
<paper-item class="inventoryItem" hero-id="main" {{detailHero}} layout horizontal center>
<!--school icon here--><div flex>{{name}}</div><!--prepared checkbox here-->
<core-icon icon="social:whatshot"></core-icon>
<div flex>{{name}}</div>
<paper-icon-button class="castButton" icon="send"></paper-icon-button>
</paper-item>
</div>
{{/each}}

View File

@@ -1,31 +1,66 @@
var spellLevels = [
{ name: "Cantrips", level: 0 },
{ name: "Level 1", level: 1 },
{ name: "Level 2", level: 2 },
{ name: "Level 3", level: 3 },
{ name: "Level 4", level: 4 },
{ name: "Level 5", level: 5 },
{ name: "Level 6", level: 6 },
{ name: "Level 7", level: 7 },
{ name: "Level 8", level: 8 },
{ name: "Level 9", level: 9 },
{ name: "Cantrips", level: 0 },
{ name: "Level 1", level: 1 },
{ name: "Level 2", level: 2 },
{ name: "Level 3", level: 3 },
{ name: "Level 4", level: 4 },
{ name: "Level 5", level: 5 },
{ name: "Level 6", level: 6 },
{ name: "Level 7", level: 7 },
{ name: "Level 8", level: 8 },
{ name: "Level 9", level: 9 },
];
Template.spells.helpers({
spellLists: function(){
return SpellLists.find({charId: this._id});
},
spellLists: function(){
return SpellLists.find({charId: this._id});
},
spellCount: function(listId, charId){
console.log(listId, charId);
return Spells.find( {charId: charId, listId: listId, level: this.level}, {fields: {_id: 1, level: 1}} ).count() > 0;
},
spells: function(listId, charId){
return Spells.find( {charId: charId, listId: listId, level: this.level} );
},
spells: function(listId, charId){
return Spells.find( {charId: charId, listId: listId, level: this.level} );
},
levels: function(){
return spellLevels;
},
numPrepared: function(){
return Spells.find({charId: Template.parentData()._id, listId: this._id, prepared: "prepared"}).count();
},
order: function(){
return _.indexOf(_.keys(colorOptions), this.color);
}
})
});
Template.spells.events({
"tap .containerTop": function(event){
GlobalUI.setDetail({
template: "spellListDialog",
data: {spellListId: this._id, charId: this.charId},
heroId: this._id
});
},
"tap #addSpellList": function(event){
var charId = this.charId;
SpellLists.insert({
name: "New SpellList",
charId: this._id,
saveDC: "8 + intelligenceMod + proficiencyBonus",
attackBonus: "intelligenceMod + proficiencyBonus"
}, function(error, id){
if(!error){
GlobalUI.setDetail({
template: "spellListDialog",
data: {spellListId: id, charId: charId},
heroId: id
});
}
});
},
"downAction .castButton": function(event){
event.stopPropagation()
},
"upAction .castButton": function(event){
event.stopPropagation()
}
});

View File

@@ -6,6 +6,7 @@
<link rel="import" href="/components/core-icons/av-icons.html">
<link rel="import" href="/components/core-icons/core-icons.html">
<link rel="import" href="/components/core-icons/image-icons.html">
<link rel="import" href="/components/core-icons/social-icons.html">
<link rel="import" href="/components/core-item/core-item.html">
<link rel="import" href="/components/core-menu/core-menu.html">
<link rel="import" href="/components/core-scaffold/core-scaffold.html">