diff --git a/app/styles/play/level/tome/spell_palette.sass b/app/styles/play/level/tome/spell_palette.sass index 91a27a7ab..287f4e8e8 100644 --- a/app/styles/play/level/tome/spell_palette.sass +++ b/app/styles/play/level/tome/spell_palette.sass @@ -54,11 +54,12 @@ &.multiple-tabs li:not(.active) a cursor: pointer - .tab-content - height: 80px - .nano-pane - width: 7px - right: 5px + &:not(.hero) + .tab-content + height: 80px + .nano-pane + width: 7px + right: 5px //.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus // background-color: lighten(rgb(230, 212, 146), 10%) diff --git a/app/templates/play/level/tome/spell_palette.jade b/app/templates/play/level/tome/spell_palette.jade index 4d9af9f42..d56b1d444 100644 --- a/app/templates/play/level/tome/spell_palette.jade +++ b/app/templates/play/level/tome/spell_palette.jade @@ -10,11 +10,29 @@ if entryGroupSlugs each slug, group in entryGroupSlugs div(id="palette-tab-" + slug, class="tab-pane nano" + (group == "this" || slug == defaultGroupSlug ? " active" : "")) div(class="properties properties-" + slug + " nano-content") + +else if tabs + // Hero; group by items, but also include tabs + ul(class="nav nav-pills multiple-tabs") + li.active + a(data-toggle="pill", data-target="#palette-tab-this") + h4= thisName + each entries, tab in tabs + li + a(data-toggle="pill", data-target='#palette-tab-' + _.string.slugify(tab)) + h4= tab + .tab-content + div#palette-tab-this.tab-pane.active + .properties.properties-this + each entries, tab in tabs + div(id="palette-tab-" + _.string.slugify(tab), class="tab-pane") + div(class="properties properties-" + _.string.slugify(tab)) + else // Hero; group by items, no tabs. if showsHelp button.btn.btn-sm.btn-info.banner#spell-palette-help-button(data-i18n="play_level.tome_help") - .properties + .properties.properties-this else - .properties.no-help + .properties.properties-this.no-help diff --git a/app/views/play/level/tome/SpellPaletteView.coffee b/app/views/play/level/tome/SpellPaletteView.coffee index f25fc84aa..4e2a25c1b 100644 --- a/app/views/play/level/tome/SpellPaletteView.coffee +++ b/app/views/play/level/tome/SpellPaletteView.coffee @@ -42,6 +42,9 @@ module.exports = class SpellPaletteView extends CocoView c.tabbed = _.size(@entryGroups) > 1 c.defaultGroupSlug = @defaultGroupSlug c.showsHelp = @showsHelp + c.tabs = @tabs # For hero-based, non-this-owned tabs like Vector, Math, etc. + c.thisName = {coffeescript: '@', lua: 'self', python: 'self'}[@options.language] or 'this' + c._ = _ c afterRender: -> @@ -59,7 +62,7 @@ module.exports = class SpellPaletteView extends CocoView else @entryGroupElements = {} for group, entries of @entryGroups - @entryGroupElements[group] = itemGroup = $('
').appendTo @$el.find('.properties') + @entryGroupElements[group] = itemGroup = $('
').appendTo @$el.find('.properties-this') if entries[0].options.item?.getPortraitURL itemImage = $('').attr('src', entries[0].options.item.getPortraitURL()).css('top', Math.max(0, 19 * (entries.length - 2) / 2) + 2) itemGroup.append itemImage @@ -74,6 +77,18 @@ module.exports = class SpellPaletteView extends CocoView entry.$el.addClass 'single-entry' if entryIndex is 0 entry.$el.addClass 'first-entry' + for tab, entries of @tabs or {} + tabSlug = _.string.slugify tab + itemsInGroup = 0 + for entry, entryIndex in entries + if itemsInGroup is 0 or (itemsInGroup is 2 and entryIndex isnt entries.length - 1) + itemGroup = $('
').appendTo @$el.find(".properties-#{tabSlug}") + itemsInGroup = 0 + ++itemsInGroup + itemGroup.append entry.el + entry.render() # Render after appending so that we can access parent container for popover + if itemsInGroup is 0 + entry.$el.addClass 'first-entry' @$el.addClass 'hero' @$el.toggleClass 'shortenize', Boolean @shortenize @updateMaxHeight() unless application.isIPadApp @@ -90,7 +105,7 @@ module.exports = class SpellPaletteView extends CocoView # We figure out how many columns we can fit, width-wise, and then guess how many rows will be needed. # We can then assign a height based on the number of rows, and the flex layout will do the rest. columnWidth = if @shortenize then 175 else 212 - nColumns = Math.floor @$el.find('.properties').innerWidth() / columnWidth # will always have 2 columns, since at 1024px screen we have 424px .properties + nColumns = Math.floor @$el.find('.properties-this').innerWidth() / columnWidth # will always have 2 columns, since at 1024px screen we have 424px .properties columns = ({items: [], nEntries: 0} for i in [0 ... nColumns]) orderedColumns = [] nRows = 0 @@ -105,7 +120,7 @@ module.exports = class SpellPaletteView extends CocoView nRows = Math.max nRows, shortestColumn.nEntries for column in orderedColumns for item in column.items - item.detach().appendTo @$el.find('.properties') + item.detach().appendTo @$el.find('.properties-this') desiredHeight = 19 * (nRows + 1) @$el.find('.properties').css('height', desiredHeight) @@ -176,7 +191,7 @@ module.exports = class SpellPaletteView extends CocoView console.log 'could not find doc for', prop, 'from', allDocs['__' + prop], 'for', owner, 'of', propGroups doc ?= prop if doc - @entries.push @addEntry(doc, @shortenize, tabbify, owner is 'snippets') + @entries.push @addEntry(doc, @shortenize, owner is 'snippets') groupForEntry = (entry) -> return 'more' if entry.doc.owner is 'this' and entry.doc.name in (propGroups.more ? []) entry.doc.owner @@ -199,7 +214,7 @@ module.exports = class SpellPaletteView extends CocoView @entryGroups[group] = _.groupBy entries, (entry, i) -> Math.floor i / N_ROWS @entryGroupSlugs[group] = _.string.slugify group @entryGroupNames[group] = group - if thisName = {coffeescript: '@', lua: 'self', clojure: 'self'}[@options.language] + if thisName = {coffeescript: '@', lua: 'self', python: 'self'}[@options.language] if @entryGroupNames.this @entryGroupNames.this = thisName @@ -231,8 +246,22 @@ module.exports = class SpellPaletteView extends CocoView else console.log @thang.id, "couldn't find item ThangType for", slot, thangTypeName + # Get any Math-, Vector-, etc.-owned properties into their own tabs + for owner, storage of propStorage when not (owner in ['this', 'more', 'snippets']) + continue unless @thang[storage]?.length + @tabs ?= {} + @tabs[owner] = [] + programmaticonName = @thang.inventoryThangTypeNames['programming-book'] + programmaticon = itemThangTypes[programmaticonName] + sortedProps = @thang[storage].slice().sort() + for prop in sortedProps + if doc = _.find (allDocs['__' + prop] ? []), {owner: owner} # Not all languages have all props + entry = @addEntry doc, false, false, programmaticon + @tabs[owner].push entry + # Assign any unassigned properties to the hero itself. for owner, storage of propStorage + continue unless owner in ['this', 'more', 'snippets'] for prop in _.reject(@thang[storage] ? [], (prop) -> itemsByProp[prop] or prop[0] is '_') # no private properties continue if prop is 'say' and @options.level.get 'hidesSay' # Hide for Dungeon Campaign continue if prop is 'moveXY' and @options.level.get('slug') is 'slalom' # Hide for Slalom @@ -256,7 +285,7 @@ module.exports = class SpellPaletteView extends CocoView console.log 'could not find doc for', prop, 'from', allDocs['__' + prop], 'for', owner, 'of', propsByItem, 'with item', item doc ?= prop if doc - @entries.push @addEntry(doc, @shortenize, false, owner is 'snippets', item, propIndex > 0) + @entries.push @addEntry(doc, @shortenize, owner is 'snippets', item, propIndex > 0) @entryGroups = _.groupBy @entries, (entry) -> itemsByProp[entry.doc.name]?.get('name') ? 'Hero' iOSEntryGroups = {} for group, entries of @entryGroups @@ -265,9 +294,9 @@ module.exports = class SpellPaletteView extends CocoView props: (entry.doc for entry in entries) Backbone.Mediator.publish 'tome:palette-updated', thangID: @thang.id, entryGroups: JSON.stringify(iOSEntryGroups) - addEntry: (doc, shortenize, tabbify, isSnippet=false, item=null, showImage=false) -> + addEntry: (doc, shortenize, isSnippet=false, item=null, showImage=false) -> writable = (if _.isString(doc) then doc else doc.name) in (@thang.apiUserProperties ? []) - new SpellPaletteEntryView doc: doc, thang: @thang, shortenize: shortenize, tabbify: tabbify, isSnippet: isSnippet, language: @options.language, writable: writable, level: @options.level, item: item, showImage: showImage + new SpellPaletteEntryView doc: doc, thang: @thang, shortenize: shortenize, isSnippet: isSnippet, language: @options.language, writable: writable, level: @options.level, item: item, showImage: showImage onDisableControls: (e) -> @toggleControls e, false onEnableControls: (e) -> @toggleControls e, true