diff --git a/app/schemas/subscriptions/play.coffee b/app/schemas/subscriptions/play.coffee index 04764da5f..0db11f30d 100644 --- a/app/schemas/subscriptions/play.coffee +++ b/app/schemas/subscriptions/play.coffee @@ -63,9 +63,6 @@ module.exports = "next-game-pressed": {} # TODO schema - "focus-editor": - {} # TODO schema - "end-current-script": {} # TODO schema @@ -87,14 +84,14 @@ module.exports = scriptRunning: { type: 'string' } noteGroupRunning: { type: 'string' } timeSinceLastScriptEnded: { type: 'number' } - scriptStates: + scriptStates: type: 'object' additionalProperties: title: 'Script State' type: 'object' additionalProperties: false properties: - timeSinceLastEnded: + timeSinceLastEnded: type: 'number' description: 'seconds since this script ended last' timeSinceLastTriggered: @@ -143,7 +140,7 @@ module.exports = additionalProperties: false properties: showModal: { type: 'boolean' } - + "level-highlight-dom": type: 'object' additionalProperties: false diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee index 7c6a5a11f..aa5f96eb1 100644 --- a/app/schemas/subscriptions/tome.coffee +++ b/app/schemas/subscriptions/tome.coffee @@ -67,7 +67,27 @@ module.exports = "tome:spell-shown": {} # TODO schema - # TODO proposition: add tome to name - "focus-editor": + "tome:focus-editor": {} # TODO schema + "tome:change-language": + title: "Tome Change Language" + $schema: "http://json-schema.org/draft-04/schema#" + description: "Published when the Tome should update its programming language." + type: "object" + additionalProperties: false + properties: + language: + type: "string" + required: ["language"] + + "tome:spell-changed-language": + title: "Spell Changed Language" + $schema: "http://json-schema.org/draft-04/schema#" + description: "Published when an individual spell has updated its code language." + type: "object" + additionalProperties: false + properties: + spell: + type: "object" + required: ["spell"] diff --git a/app/styles/play/level/tome/spell_palette.sass b/app/styles/play/level/tome/spell_palette.sass index 52ce37658..5e19cc0ce 100644 --- a/app/styles/play/level/tome/spell_palette.sass +++ b/app/styles/play/level/tome/spell_palette.sass @@ -60,3 +60,29 @@ display: inline-block margin-right: 3px vertical-align: top + + .code-language-logo + position: absolute + width: 20px + height: 20px + left: 12px + top: 34px + z-index: 10 + background-color: transparent + background-repeat: no-repeat + background-size: contain + cursor: pointer + + &.javascript + background-image: url(/images/pages/home/language_logo_javascript.png) + &.python + background-image: url(/images/pages/home/language_logo_python.png) + &.coffeescript + background-image: url(/images/pages/home/language_logo_coffeescript.png) + &.clojure + background-image: url(/images/pages/home/language_logo_clojure.png) + &.lua + background-image: url(/images/pages/home/language_logo_lua.png) + &.io + background-image: url(/images/pages/home/language_logo_io.png) + diff --git a/app/templates/play/level/tome/spell_list_tab_entry.jade b/app/templates/play/level/tome/spell_list_tab_entry.jade index eb9d01e0c..8ebad097f 100644 --- a/app/templates/play/level/tome/spell_list_tab_entry.jade +++ b/app/templates/play/level/tome/spell_list_tab_entry.jade @@ -2,7 +2,7 @@ i.icon-chevron-down .thang-avatar-placeholder -code #{spell.name}(#{parameters}) +code #{methodSignature} .btn.btn-small.reload-code(title="Reload original code for " + spell.name) i.icon-repeat diff --git a/app/templates/play/level/tome/spell_palette.jade b/app/templates/play/level/tome/spell_palette.jade index f87259d77..03450f9c2 100644 --- a/app/templates/play/level/tome/spell_palette.jade +++ b/app/templates/play/level/tome/spell_palette.jade @@ -1,4 +1,5 @@ img(src="/images/level/code_palette_background.png").code-palette-background +.code-language-logo ul(class="nav nav-pills" + (tabbed ? ' multiple-tabs' : '')) each slug, group in entryGroupSlugs li(class=group == "this" || slug == "available-spells" ? "active" : "") diff --git a/app/views/play/level/control_bar_view.coffee b/app/views/play/level/control_bar_view.coffee index 9c1076edb..d5102c60b 100644 --- a/app/views/play/level/control_bar_view.coffee +++ b/app/views/play/level/control_bar_view.coffee @@ -28,7 +28,7 @@ module.exports = class ControlBarView extends View 'click #next-game-button': -> Backbone.Mediator.publish 'next-game-pressed' - 'click': -> Backbone.Mediator.publish 'focus-editor' + 'click': -> Backbone.Mediator.publish 'tome:focus-editor' constructor: (options) -> @worldName = options.worldName diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index ca03899fc..612dcae41 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -31,7 +31,7 @@ module.exports = class HUDView extends View @$el.addClass 'no-selection' onClick: (e) -> - Backbone.Mediator.publish 'focus-editor' unless $(e.target).parents('.thang-props').length + Backbone.Mediator.publish 'tome:focus-editor' unless $(e.target).parents('.thang-props').length onFrameChanged: (e) -> @timeProgress = e.progress diff --git a/app/views/play/level/playback_view.coffee b/app/views/play/level/playback_view.coffee index d3f66d89d..fb0ba5fd7 100644 --- a/app/views/play/level/playback_view.coffee +++ b/app/views/play/level/playback_view.coffee @@ -36,7 +36,7 @@ module.exports = class PlaybackView extends View 'click #zoom-out-button': -> Backbone.Mediator.publish('camera-zoom-out') unless @shouldIgnore() 'click #volume-button': 'onToggleVolume' 'click #play-button': 'onTogglePlay' - 'click': -> Backbone.Mediator.publish 'focus-editor' + 'click': -> Backbone.Mediator.publish 'tome:focus-editor' 'mouseenter #timeProgress': 'onProgressEnter' 'mouseleave #timeProgress': 'onProgressLeave' 'mousemove #timeProgress': 'onProgressHover' diff --git a/app/views/play/level/tome/cast_button_view.coffee b/app/views/play/level/tome/cast_button_view.coffee index 5f368a51c..560de1dbe 100644 --- a/app/views/play/level/tome/cast_button_view.coffee +++ b/app/views/play/level/tome/cast_button_view.coffee @@ -46,7 +46,7 @@ module.exports = class CastButtonView extends View Backbone.Mediator.publish 'tome:manual-cast', {} onCastOptionsClick: (e) => - Backbone.Mediator.publish 'focus-editor' + Backbone.Mediator.publish 'tome:focus-editor' @castButtonGroup.removeClass 'open' @setAutocastDelay $(e.target).attr 'data-delay' false diff --git a/app/views/play/level/tome/spell.coffee b/app/views/play/level/tome/spell.coffee index 5e3501014..98077a4e0 100644 --- a/app/views/play/level/tome/spell.coffee +++ b/app/views/play/level/tome/spell.coffee @@ -146,6 +146,7 @@ module.exports = class Spell for thangId, spellThang of @thangs spellThang.aether?.setLanguage @language spellThang.castAether = null + Backbone.Mediator.publish 'tome:spell-changed-language', spell: @ workerMessage = function: "updateLanguageAether" newLanguage: @language diff --git a/app/views/play/level/tome/spell_list_entry_view.coffee b/app/views/play/level/tome/spell_list_entry_view.coffee index 7f72cab5d..76354fe84 100644 --- a/app/views/play/level/tome/spell_list_entry_view.coffee +++ b/app/views/play/level/tome/spell_list_entry_view.coffee @@ -13,6 +13,7 @@ module.exports = class SpellListEntryView extends View subscriptions: 'tome:problems-updated': "onProblemsUpdated" + 'tome:spell-changed-language': 'onSpellChangedLanguage' 'level-disable-controls': 'onDisableControls' 'level-enable-controls': 'onEnableControls' 'god:new-world-created': 'onNewWorld' @@ -30,11 +31,38 @@ module.exports = class SpellListEntryView extends View getRenderData: (context={}) -> context = super context context.spell = @spell - context.parameters = (@spell.parameters or []).join ', ' + context.methodSignature = @createMethodSignature() context.thangNames = (thangID for thangID, spellThang of @spell.thangs when spellThang.thang.exists).join(', ') # + ", Marcus, Robert, Phoebe, Will Smith, Zap Brannigan, You, Gandaaaaalf" context.showTopDivider = @showTopDivider context + createMethodSignature: -> + parameters = (@spell.parameters or []).slice() + if @spell.language in ['python', 'lua'] + parameters.unshift 'self' + else if @spell.language is 'io' + parameters.unshift '...' + paramString = parameters.join ', ' + name = @spell.name + switch @spell.language + when 'io' + "#{name} := method(#{paramString})" + when 'clojure' + "(defn #{name} [#{paramString}] ...)" + when 'python' + "def #{name}(#{paramString}):" + when 'lua' + "function #{name}(#{paramString}) ... end" + when 'coffeescript' + if parameters.length + "@#{name} = (#{paramString}) ->" + else + "@#{name} = ->" + when 'javascript' + "function #{name}(#{paramString}) { ... }" + else + "#{name}(#{paramString})" + getPrimarySpellThang: -> if @lastSelectedThang spellThang = _.find @spell.thangs, (spellThang) => spellThang.thang.id is @lastSelectedThang.id @@ -42,7 +70,7 @@ module.exports = class SpellListEntryView extends View for thangID, spellThang of @spell.thangs continue unless spellThang.thang.exists return spellThang # Just do the first one else - + afterRender: -> super() return unless @options.showTopDivider # Don't repeat Thang avatars when not changed from previous entry @@ -92,6 +120,10 @@ module.exports = class SpellListEntryView extends View return unless e.spell is @spell @$el.toggleClass "user-code-problem", e.problems.length + onSpellChangedLanguage: (e) -> + return unless e.spell is @spell + @render() # So that we can update parameters if needed + onDisableControls: (e) -> @toggleControls e, false onEnableControls: (e) -> @toggleControls e, true toggleControls: (e, enabled) -> @@ -105,7 +137,7 @@ module.exports = class SpellListEntryView extends View onNewWorld: (e) -> @lastSelectedThang = e.world.thangMap[@lastSelectedThang.id] if @lastSelectedThang - + destroy: -> @avatar?.destroy() super() diff --git a/app/views/play/level/tome/spell_palette_view.coffee b/app/views/play/level/tome/spell_palette_view.coffee index e14ff1507..d8746f80e 100644 --- a/app/views/play/level/tome/spell_palette_view.coffee +++ b/app/views/play/level/tome/spell_palette_view.coffee @@ -4,6 +4,7 @@ template = require 'templates/play/level/tome/spell_palette' filters = require 'lib/image_filter' SpellPaletteEntryView = require './spell_palette_entry_view' LevelComponent = require 'models/LevelComponent' +EditorConfigModal = require '../modal/editor_config_modal' N_ROWS = 4 @@ -16,6 +17,10 @@ module.exports = class SpellPaletteView extends View 'level-disable-controls': 'onDisableControls' 'level-enable-controls': 'onEnableControls' 'surface:frame-changed': "onFrameChanged" + 'tome:change-language': 'onTomeChangedLanguage' + + events: + 'click .code-language-logo': 'onEditEditorConfig' constructor: (options) -> super options @@ -39,7 +44,12 @@ module.exports = class SpellPaletteView extends View for entry in entryColumn col.append entry.el entry.render() # Render after appending so that we can access parent container for popover - $('.nano').nanoScroller() + $('.nano').nanoScroller() + @updateCodeLanguage @options.language + + updateCodeLanguage: (language) -> + @options.language = language + @$el.find('.code-language-logo').removeClass().addClass 'code-language-logo ' + language createPalette: -> lcs = @supermodel.getModels LevelComponent @@ -128,6 +138,12 @@ module.exports = class SpellPaletteView extends View return unless e.selectedThang?.id is @thang.id @options.thang = @thang = e.selectedThang # Update our thang to the current version + onTomeChangedLanguage: (e) -> + @updateCodeLanguage e.language + + onEditEditorConfig: (e) -> + @openModalView new EditorConfigModal session: @options.session + destroy: -> entry.destroy() for entry in @entries @toggleBackground = null diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee index 3c69d79c2..c519f7558 100644 --- a/app/views/play/level/tome/spell_view.coffee +++ b/app/views/play/level/tome/spell_view.coffee @@ -41,7 +41,7 @@ module.exports = class SpellView extends View 'tome:spell-changed': 'onSpellChanged' 'level:session-will-save': 'onSessionWillSave' 'modal-closed': 'focus' - 'focus-editor': 'focus' + 'tome:focus-editor': 'focus' 'tome:spell-statement-index-updated': 'onStatementIndexUpdated' 'tome:change-language': 'onChangeLanguage' 'tome:change-config': 'onChangeEditorConfig' diff --git a/app/views/play/level/tome/tome_view.coffee b/app/views/play/level/tome/tome_view.coffee index 1366722e8..1fca60902 100644 --- a/app/views/play/level/tome/tome_view.coffee +++ b/app/views/play/level/tome/tome_view.coffee @@ -162,7 +162,7 @@ module.exports = class TomeView extends View @spellList.$el.hide() onClick: (e) -> - Backbone.Mediator.publish 'focus-editor' unless $(e.target).parents('.popover').length + Backbone.Mediator.publish 'tome:focus-editor' unless $(e.target).parents('.popover').length clearSpellView: -> @spellView?.dismiss() @@ -201,7 +201,7 @@ module.exports = class TomeView extends View updateSpellPalette: (thang, spell) -> return unless thang and @spellPaletteView?.thang isnt thang and thang.programmableProperties or thang.apiProperties - @spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead() + @spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead(), language: spell.language, session: @options.session @spellPaletteView.toggleControls {}, spell.view.controlsEnabled if spell # TODO: know when palette should have been disabled but didn't exist spellFor: (thang, spellName) ->