WorldSelectModal = require './modals/WorldSelectModal' ThangType = require '/models/ThangType' LevelComponent = require 'models/LevelComponent' CocoCollection = require 'collections/CocoCollection' makeButton = -> $('') shorten = (f) -> parseFloat(f.toFixed(1)) WIDTH = 924 module.exports.WorldPointNode = class WorldPointNode extends TreemaNode.nodeMap.point2d constructor: (args...) -> super(args...) console.error 'Point Treema node needs a World included in the settings.' unless @settings.world? console.error 'Point Treema node needs a RootView included in the settings.' unless @settings.view? buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) buildValueForEditing: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) onClick: (e) -> btn = $(e.target).closest('.treema-map-button') if btn.length then @openMap() else super(arguments...) openMap: -> modal = new WorldSelectModal(world: @settings.world, dataType: 'point', default: @getData(), supermodel: @settings.supermodel) modal.callback = @callback @settings.view.openModalView modal callback: (e) => return unless e?.point? @data.x = shorten(e.point.x) @data.y = shorten(e.point.y) @refreshDisplay() class WorldRegionNode extends TreemaNode.nodeMap.object # this class is not yet used, later will be used to configure the Physical component constructor: (args...) -> super(args...) console.error 'Region Treema node needs a World included in the settings.' unless @settings.world? console.error 'Region Treema node needs a RootView included in the settings.' unless @settings.view? buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) buildValueForEditing: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) onClick: (e) -> btn = $(e.target).closest('.treema-map-button') if btn.length then @openMap() else super(arguments...) openMap: -> modal = new WorldSelectModal(world: @settings.world, dataType: 'region', default: @createWorldBounds(), supermodel: @settings.supermodel) modal.callback = @callback @settings.view.openModalView modal callback: (e) => x = Math.min e.points[0].x, e.points[1].x y = Math.min e.points[0].y, e.points[1].y @data.pos = {x: x, y: y, z: 0} @data.width = Math.abs e.points[0].x - e.points[1].x @data.height = Math.min e.points[0].y - e.points[1].y @refreshDisplay() createWorldBounds: -> # not yet written module.exports.WorldViewportNode = class WorldViewportNode extends TreemaNode.nodeMap.object # selecting ratio'd dimensions in the world, ie the camera in level scripts constructor: (args...) -> super(args...) console.error 'Viewport Treema node needs a World included in the settings.' unless @settings.world? console.error 'Viewport Treema node needs a RootView included in the settings.' unless @settings.view? buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) buildValueForEditing: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) onClick: (e) -> btn = $(e.target).closest('.treema-map-button') if btn.length then @openMap() else super(arguments...) openMap: -> # can't really get the bounds from this data, so will have to hack this solution options = world: @settings.world, dataType: 'ratio-region' data = @getData() options.defaultFromZoom = data if data?.target?.x? options.supermodel = @settings.supermodel modal = new WorldSelectModal(options) modal.callback = @callback @settings.view.openModalView modal callback: (e) => return unless e target = { x: shorten((e.points[0].x + e.points[1].x) / 2) y: shorten((e.points[0].y + e.points[1].y) / 2) } @set('target', target) bounds = e.camera.normalizeBounds(e.points) @set('zoom', shorten(WIDTH / bounds.width)) @refreshDisplay() module.exports.WorldBoundsNode = class WorldBoundsNode extends TreemaNode.nodeMap.array # selecting camera boundaries for a world dataType: 'region' constructor: (args...) -> super(args...) console.error 'Bounds Treema node needs a World included in the settings.' unless @settings.world? console.error 'Bounds Treema node needs a RootView included in the settings.' unless @settings.view? buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) buildValueForEditing: (valEl, data) -> super(valEl, data) valEl.find('.treema-shortened').prepend(makeButton()) onClick: (e) -> btn = $(e.target).closest('.treema-map-button') if btn.length then @openMap() else super(arguments...) openMap: -> bounds = @getData() or [{x: 0, y: 0}, {x: 100, y: 80}] modal = new WorldSelectModal(world: @settings.world, dataType: 'region', default: bounds, supermodel: @settings.supermodel) modal.callback = @callback @settings.view.openModalView modal callback: (e) => return unless e @set '/0', {x: shorten(e.points[0].x), y: shorten(e.points[0].y)} @set '/1', {x: shorten(e.points[1].x), y: shorten(e.points[1].y)} module.exports.ThangNode = class ThangNode extends TreemaNode.nodeMap.string buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.find('input').autocomplete(source: @settings.thangIDs, minLength: 0, delay: 0, autoFocus: true) valEl module.exports.TeamNode = class TeamNode extends TreemaNode.nodeMap.string buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.find('input').autocomplete(source: @settings.teams, minLength: 0, delay: 0, autoFocus: true) valEl module.exports.SuperteamNode = class SuperteamNode extends TreemaNode.nodeMap.string buildValueForEditing: (valEl, data) -> super(valEl, data) valEl.find('input').autocomplete(source: @settings.superteams, minLength: 0, delay: 0, autoFocus: true) valEl module.exports.RadiansNode = class RadiansNode extends TreemaNode.nodeMap.number buildValueForDisplay: (valEl, data) -> super(valEl, data) deg = data / Math.PI * 180 valEl.text valEl.text() + "rad (#{deg.toFixed(0)}˚)" module.exports.MetersNode = class MetersNode extends TreemaNode.nodeMap.number buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.text valEl.text() + 'm' module.exports.KilogramsNode = class KilogramsNode extends TreemaNode.nodeMap.number buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.text valEl.text() + 'kg' module.exports.SecondsNode = class SecondsNode extends TreemaNode.nodeMap.number buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.text valEl.text() + 's' module.exports.MillisecondsNode = class MillisecondsNode extends TreemaNode.nodeMap.number buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.text valEl.text() + 'ms' module.exports.SpeedNode = class SpeedNode extends TreemaNode.nodeMap.number buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.text valEl.text() + 'm/s' module.exports.AccelerationNode = class AccelerationNode extends TreemaNode.nodeMap.number buildValueForDisplay: (valEl, data) -> super(valEl, data) valEl.text valEl.text() + 'm/s^2' module.exports.ThangTypeNode = class ThangTypeNode extends TreemaNode.nodeMap.string valueClass: 'treema-thang-type' @thangTypes: null @thangTypesCollection: null constructor: (args...) -> super args... data = @getData() @thangType = _.find @settings.supermodel.getModels(ThangType), (m) => m.get('original') is data if data buildValueForDisplay: (valEl) -> @buildValueForDisplaySimply(valEl, @thangType?.get('name') or 'None') buildValueForEditing: (valEl, data) -> super(valEl, data) thangTypeNames = (m.get('name') for m in @settings.supermodel.getModels ThangType) input = valEl.find('input').autocomplete(source: thangTypeNames, minLength: 0, delay: 0, autoFocus: true) input.val(@thangType?.get('name') or 'None') valEl saveChanges: -> thangTypeName = @$el.find('input').val() @thangType = _.find @settings.supermodel.getModels(ThangType), (m) -> m.get('name') is thangTypeName if @thangType @data = @thangType.get('original') else @data = null module.exports.ThangTypeNode = ThangTypeNode = class ThangTypeNode extends TreemaNode.nodeMap.string valueClass: 'treema-thang-type' @thangTypesCollection: null # Lives in ThangTypeNode parent class @thangTypes: null # Lives in ThangTypeNode or subclasses constructor: -> super(arguments...) @getThangTypes() unless ThangTypeNode.thangTypesCollection.loaded ThangTypeNode.thangTypesCollection.once('sync', @refreshDisplay, @) buildValueForDisplay: (valEl, data) -> @buildValueForDisplaySimply(valEl, @getCurrentThangType() or '') valEl buildValueForEditing: (valEl, data) -> super(valEl, data) input = valEl.find 'input' if @constructor.thangTypes source = (thangType.name for thangType in @constructor.thangTypes when @filterThangType thangType) input.autocomplete(source: source, minLength: 0, delay: 0, autoFocus: true) input.val(@getCurrentThangType() or '') valEl filterThangType: (thangType) -> true getCurrentThangType: -> return null unless @constructor.thangTypes return null unless original = @getData() thangType = _.find @constructor.thangTypes, { original: original } thangType?.name or '...' getThangTypes: -> return if ThangTypeNode.thangTypesCollection ThangTypeNode.thangTypesCollection = new CocoCollection([], { url: '/db/thang.type' project:['name', 'components', 'original'] model: ThangType }) res = ThangTypeNode.thangTypesCollection.fetch() ThangTypeNode.thangTypesCollection.once 'sync', => @processThangTypes(ThangTypeNode.thangTypesCollection) processThangTypes: (thangTypeCollection) -> @constructor.thangTypes = [] @processThangType thangType for thangType in thangTypeCollection.models processThangType: (thangType) -> @constructor.thangTypes.push name: thangType.get('name'), original: thangType.get('original') saveChanges: -> thangTypeName = @$el.find('input').val() thangType = _.find(@constructor.thangTypes, {name: thangTypeName}) return @remove() unless thangType @data = thangType.original module.exports.ItemThangTypeNode = ItemThangTypeNode = class ItemThangTypeNode extends ThangTypeNode valueClass: 'treema-item-thang-type' filterThangType: (thangType) -> @keyForParent in thangType.slots processThangType: (thangType) -> return unless itemComponent = _.find thangType.get('components'), {original: LevelComponent.ItemID} @constructor.thangTypes.push name: thangType.get('name'), original: thangType.get('original'), slots: itemComponent.config?.slots ? ['right-hand']