mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-24 22:42:25 -05:00
220 lines
7 KiB
CoffeeScript
220 lines
7 KiB
CoffeeScript
CocoView = require 'views/core/CocoView'
|
|
template = require 'templates/editor/level/scripts_tab'
|
|
Level = require 'models/Level'
|
|
Surface = require 'lib/surface/Surface'
|
|
nodes = require './../treema_nodes'
|
|
defaultScripts = require 'lib/DefaultScripts'
|
|
require 'vendor/treema'
|
|
|
|
module.exports = class ScriptsTabView extends CocoView
|
|
id: 'editor-level-scripts-tab-view'
|
|
template: template
|
|
className: 'tab-pane'
|
|
|
|
subscriptions:
|
|
'editor:level-loaded': 'onLevelLoaded'
|
|
'editor:thangs-edited': 'onThangsEdited'
|
|
|
|
constructor: (options) ->
|
|
super options
|
|
@world = options.world
|
|
@files = options.files
|
|
$(window).on 'resize', @onWindowResize
|
|
|
|
destroy: ->
|
|
@scriptTreema?.destroy()
|
|
@scriptTreemas?.destroy()
|
|
$(window).off 'resize', @onWindowResize
|
|
super()
|
|
|
|
onLoaded: ->
|
|
onLevelLoaded: (e) ->
|
|
@level = e.level
|
|
@dimensions = @level.dimensions()
|
|
scripts = $.extend(true, [], @level.get('scripts') ? [])
|
|
if scripts.length is 0
|
|
scripts = $.extend(true, [], defaultScripts)
|
|
treemaOptions =
|
|
schema: Level.schema.properties.scripts
|
|
data: scripts
|
|
callbacks:
|
|
change: @onScriptsChanged
|
|
select: @onScriptSelected
|
|
addChild: @onNewScriptAdded
|
|
removeChild: @onScriptDeleted
|
|
nodeClasses:
|
|
array: ScriptsNode
|
|
object: ScriptNode
|
|
view: @
|
|
@scriptsTreema = @$el.find('#scripts-treema').treema treemaOptions
|
|
@scriptsTreema.build()
|
|
if @scriptsTreema.childrenTreemas[0]?
|
|
@scriptsTreema.childrenTreemas[0].select()
|
|
@scriptsTreema.childrenTreemas[0].broadcastChanges() # can get rid of this after refactoring treema
|
|
|
|
onScriptsChanged: (e) =>
|
|
@level.set 'scripts', @scriptsTreema.data
|
|
|
|
onScriptSelected: (e, selected) =>
|
|
selected = if selected.length > 1 then selected[0].getLastSelectedTreema() else selected[0]
|
|
unless selected
|
|
@$el.find('#script-treema').replaceWith($('<div id="script-treema"></div>'))
|
|
@selectedScriptPath = null
|
|
return
|
|
|
|
@thangIDs = @getThangIDs()
|
|
treemaOptions =
|
|
world: @world
|
|
filePath: "db/level/#{@level.get('original')}"
|
|
files: @files
|
|
view: @
|
|
schema: Level.schema.properties.scripts.items
|
|
data: selected.data
|
|
thangIDs: @thangIDs
|
|
dimensions: @dimensions
|
|
supermodel: @supermodel
|
|
readOnly: me.get('anonymous')
|
|
callbacks:
|
|
change: @onScriptChanged
|
|
nodeClasses:
|
|
object: PropertiesNode
|
|
'event-value-chain': EventPropsNode
|
|
'event-prereqs': EventPrereqsNode
|
|
'event-prereq': EventPrereqNode
|
|
'event-channel': ChannelNode
|
|
'thang': nodes.ThangNode
|
|
'milliseconds': nodes.MillisecondsNode
|
|
'seconds': nodes.SecondsNode
|
|
'point2d': nodes.WorldPointNode
|
|
'viewport': nodes.WorldViewportNode
|
|
'bounds': nodes.WorldBoundsNode
|
|
|
|
newPath = selected.getPath()
|
|
return if newPath is @selectedScriptPath
|
|
#@scriptTreema?.destroy() # TODO: get this to work
|
|
@scriptTreema = @$el.find('#script-treema').treema treemaOptions
|
|
@scriptTreema.build()
|
|
@scriptTreema.childrenTreemas?.noteChain?.open()
|
|
@selectedScriptPath = newPath
|
|
|
|
getThangIDs: ->
|
|
(t.id for t in @level.get('thangs') ? [])
|
|
|
|
onNewScriptAdded: (scriptNode) =>
|
|
return unless scriptNode
|
|
if scriptNode.data.id is undefined
|
|
scriptNode.disableTracking()
|
|
scriptNode.set '/id', 'Script-' + @scriptsTreema.data.length
|
|
scriptNode.enableTracking()
|
|
|
|
onScriptDeleted: =>
|
|
for key, treema of @scriptsTreema.childrenTreemas
|
|
key = parseInt(key)
|
|
treema.disableTracking()
|
|
if /Script-[0-9]*/.test treema.data.id
|
|
existingKey = parseInt(treema.data.id.substr(7))
|
|
if existingKey isnt key+1
|
|
treema.set 'id', 'Script-' + (key+1)
|
|
treema.enableTracking()
|
|
|
|
onScriptChanged: =>
|
|
return unless @selectedScriptPath
|
|
@scriptsTreema.set(@selectedScriptPath, @scriptTreema.data)
|
|
|
|
onThangsEdited: (e) ->
|
|
# Update in-place so existing Treema nodes refer to the same array.
|
|
@thangIDs?.splice(0, @thangIDs.length, @getThangIDs()...)
|
|
|
|
onWindowResize: (e) =>
|
|
@$el.find('#scripts-treema').collapse('show') if $('body').width() > 800
|
|
|
|
class ScriptsNode extends TreemaArrayNode
|
|
nodeDescription: 'Script'
|
|
addNewChild: ->
|
|
newTreema = super()
|
|
if @callbacks.addChild
|
|
@callbacks.addChild newTreema
|
|
newTreema
|
|
|
|
class ScriptNode extends TreemaObjectNode
|
|
valueClass: 'treema-script'
|
|
collection: false
|
|
buildValueForDisplay: (valEl, data) ->
|
|
val = data.id or data.channel
|
|
s = "#{val}"
|
|
@buildValueForDisplaySimply valEl, s
|
|
|
|
onTabPressed: (e) ->
|
|
@tabToCurrentScript()
|
|
e.preventDefault()
|
|
|
|
onDeletePressed: (e) ->
|
|
returnVal = super(e)
|
|
if @callbacks.removeChild
|
|
@callbacks.removeChild()
|
|
returnVal
|
|
|
|
onRightArrowPressed: ->
|
|
@tabToCurrentScript()
|
|
|
|
tabToCurrentScript: ->
|
|
@settings.view.scriptTreema?.keepFocus()
|
|
firstRow = @settings.view.scriptTreema?.$el.find('.treema-node:visible').data('instance')
|
|
return unless firstRow?
|
|
firstRow.select()
|
|
|
|
class PropertiesNode extends TreemaObjectNode
|
|
nodeDescription: 'Script Property'
|
|
|
|
class EventPropsNode extends TreemaNode.nodeMap.string
|
|
valueClass: 'treema-event-props'
|
|
|
|
arrayToString: -> (@getData() or []).join('.')
|
|
|
|
buildValueForDisplay: (valEl, data) ->
|
|
joined = @arrayToString()
|
|
joined = '(unset)' if not joined.length
|
|
@buildValueForDisplaySimply valEl, joined
|
|
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
channel = @getRoot().data.channel
|
|
channelSchema = Backbone.Mediator.channelSchemas[channel]
|
|
autocompleteValues = []
|
|
autocompleteValues.push key for key, val of channelSchema?.properties
|
|
valEl.find('input').autocomplete(source: autocompleteValues, minLength: 0, delay: 0, autoFocus: true).autocomplete('search')
|
|
valEl
|
|
|
|
saveChanges: (valEl) ->
|
|
@data = (s for s in $('input', valEl).val().split('.') when s.length)
|
|
|
|
class EventPrereqsNode extends TreemaNode.nodeMap.array
|
|
open: (depth=2) ->
|
|
super(depth)
|
|
|
|
addNewChild: ->
|
|
newTreema = super(arguments)
|
|
return unless newTreema?
|
|
newTreema.open()
|
|
newTreema.childrenTreemas.eventProps?.edit()
|
|
|
|
class EventPrereqNode extends TreemaNode.nodeMap.object
|
|
buildValueForDisplay: (valEl, data) ->
|
|
eventProp = (data.eventProps or []).join('.')
|
|
eventProp = '(unset)' unless eventProp.length
|
|
statements = []
|
|
for key, value of data
|
|
continue if key is 'eventProps'
|
|
comparison = @workingSchema.properties[key].title
|
|
value = value.toString()
|
|
statements.push("#{comparison} #{value}")
|
|
statements = statements.join(', ')
|
|
s = "#{eventProp} #{statements}"
|
|
@buildValueForDisplaySimply valEl, s
|
|
|
|
class ChannelNode extends TreemaNode.nodeMap.string
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
autocompleteValues = ({label: val?.title or key, value: key} for key, val of Backbone.Mediator.channelSchemas)
|
|
valEl.find('input').autocomplete(source: autocompleteValues, minLength: 0, delay: 0, autoFocus: true)
|
|
valEl
|