2016-01-13 18:54:57 -05:00
|
|
|
CocoView = require 'views/core/CocoView'
|
2016-01-20 18:32:21 -05:00
|
|
|
template = require 'templates/editor/level/tasks-tab'
|
2016-01-13 18:54:57 -05:00
|
|
|
Level = require 'models/Level'
|
|
|
|
|
|
|
|
module.exports = class TasksTabView extends CocoView
|
|
|
|
id: 'editor-level-tasks-tab-view'
|
|
|
|
className: 'tab-pane'
|
|
|
|
template: template
|
|
|
|
events:
|
2016-01-21 15:14:37 -05:00
|
|
|
'click .task-row': 'onClickTaskRow'
|
|
|
|
'click .task-input': 'onClickTaskInput'
|
|
|
|
'click .start-edit': 'onClickStartEdit'
|
|
|
|
'click #create-task': 'onClickCreateTask'
|
|
|
|
'keydown #cur-edit': 'onKeyDownCurEdit'
|
|
|
|
'blur #cur-edit': 'onBlurCurEdit'
|
2016-01-22 16:54:20 -05:00
|
|
|
'click #add-default-tasks': 'onClickAddDefaultTasks'
|
2016-01-13 18:54:57 -05:00
|
|
|
|
|
|
|
subscriptions:
|
|
|
|
'editor:level-loaded': 'onLevelLoaded'
|
|
|
|
|
|
|
|
defaultTaskLinks:
|
|
|
|
# Order doesn't matter.
|
|
|
|
'Name the level.':'./'
|
|
|
|
'Create a Referee stub, if needed.':'./'
|
|
|
|
'Build the level.':'./'
|
|
|
|
'Set up goals.':'./'
|
|
|
|
'Choose the Existence System lifespan and frame rate.':'./'
|
|
|
|
'Choose the UI System paths and coordinate hover if needed.':'./'
|
|
|
|
'Choose the AI System pathfinding and Vision System line of sight.':'./'
|
|
|
|
'Write the sample code.':'./'
|
|
|
|
'Do basic set decoration.':'./'
|
|
|
|
'Adjust script camera bounds.':'./'
|
|
|
|
'Choose music file in Introduction script.':'./'
|
|
|
|
'Choose autoplay in Introduction script.':'./'
|
|
|
|
'Add to a campaign.':'./'
|
|
|
|
'Publish.':'./'
|
|
|
|
'Choose level options like required/restricted gear.':'./'
|
|
|
|
'Create achievements, including unlocking next level.':'./'
|
|
|
|
'Choose leaderboard score types.':'./'
|
|
|
|
'Playtest with a slow/tough hero.':'./'
|
|
|
|
'Playtest with a fast/weak hero.':'./'
|
|
|
|
'Playtest with a couple random seeds.':'./'
|
|
|
|
'Make sure the level ends promptly on success and failure.':'./'
|
|
|
|
'Remove/simplify unnecessary doodad collision.':'./'
|
|
|
|
'Release to adventurers via MailChimp.':'./'
|
|
|
|
'Write the description.':'./'
|
|
|
|
'Add i18n field for the sample code comments.':'./'
|
|
|
|
'Add Clojure/Lua/CoffeeScript.':'./'
|
|
|
|
'Write the guide.':'./'
|
|
|
|
'Write a loading tip, if needed.':'./'
|
|
|
|
'Click the Populate i18n button.':'./'
|
|
|
|
'Add programming concepts covered.':'./'
|
|
|
|
'Mark whether it requires a subscription.':'./'
|
|
|
|
'Release to everyone via MailChimp.':'./'
|
|
|
|
'Check completion/engagement/problem analytics.':'./'
|
|
|
|
'Do thorough set decoration.':'./'
|
|
|
|
'Add a walkthrough video.':'./'
|
|
|
|
|
2016-01-22 16:54:20 -05:00
|
|
|
missingDefaults: ->
|
|
|
|
missingTasks = []
|
|
|
|
if @level
|
|
|
|
for task in @level.schema().properties.tasks.default
|
|
|
|
unless _.findIndex(@level.get('tasks'), {name: task.name}) isnt -1
|
|
|
|
missingTasks.push task
|
|
|
|
return missingTasks
|
|
|
|
|
|
|
|
onClickAddDefaultTasks: ->
|
|
|
|
results = @missingDefaults()
|
|
|
|
for result in results
|
|
|
|
@tasks.add
|
|
|
|
name: result.name
|
|
|
|
complete: result.complete
|
|
|
|
curEdit: false
|
|
|
|
revert:
|
|
|
|
name: result.name
|
|
|
|
complete: false
|
|
|
|
@pushTasks()
|
|
|
|
@render()
|
|
|
|
|
2016-01-21 15:14:37 -05:00
|
|
|
applyTaskName: (_task, _input) ->
|
|
|
|
name = _input.value
|
2016-01-22 16:54:20 -05:00
|
|
|
potentialTask = @tasks.findWhere({'name':_input})
|
2016-01-21 15:14:37 -05:00
|
|
|
if potentialTask and potentialTask isnt _task
|
|
|
|
noty
|
|
|
|
timeout: 5000
|
|
|
|
text: 'Task with name already exists!'
|
|
|
|
type: 'error'
|
|
|
|
layout: 'topCenter'
|
|
|
|
_input.focus()
|
|
|
|
else if name is ''
|
|
|
|
@tasks.remove _task
|
|
|
|
@pushTasks()
|
|
|
|
@render()
|
|
|
|
else
|
|
|
|
_task.set 'name', name
|
|
|
|
_task.set 'curEdit', false
|
|
|
|
@pushTasks()
|
|
|
|
@render()
|
|
|
|
|
|
|
|
focusEditInput: ->
|
2016-01-22 16:54:20 -05:00
|
|
|
editInput = @$el.find('#cur-edit')[0]
|
|
|
|
if editInput
|
|
|
|
editInput.focus()
|
|
|
|
len = editInput.value.length * 2
|
|
|
|
editInput.setSelectionRange len, len
|
2016-01-21 15:14:37 -05:00
|
|
|
|
|
|
|
getTaskByCID: (_cid) ->
|
|
|
|
return @tasks.get _cid
|
|
|
|
|
2016-01-20 18:32:21 -05:00
|
|
|
taskMap: ->
|
|
|
|
return @tasks?.map((_obj) -> return (name: _obj.get('name'), complete: (_obj.get('complete') || false)))
|
|
|
|
|
|
|
|
taskArray: ->
|
|
|
|
return @tasks?.toArray()
|
|
|
|
|
2016-01-13 18:54:57 -05:00
|
|
|
onLevelLoaded: (e) ->
|
|
|
|
@level = e.level
|
2016-01-20 18:32:21 -05:00
|
|
|
Task = Backbone.Model.extend({
|
|
|
|
initialize: ->
|
2016-01-21 15:14:37 -05:00
|
|
|
# We want to keep track of the revertAttributes easily without digging back into the level every time.
|
|
|
|
# So per TaskModel we check to see if there is a revertAttribute associated with the task's name.
|
|
|
|
# If there is a reversion available, we use it, otherwise (e.g. new tasks without a reversion) we just use the Task's current name/completion status.
|
2016-01-20 18:32:21 -05:00
|
|
|
if e?.level?._revertAttributes?.tasks?
|
|
|
|
if _.find(e.level._revertAttributes.tasks, {name:arguments[0].name})
|
|
|
|
@set 'revert', _.find(e.level._revertAttributes.tasks, {name:arguments[0].name})
|
|
|
|
else
|
|
|
|
@set 'revert', arguments[0]
|
|
|
|
else
|
|
|
|
@set 'revert', arguments[0]
|
|
|
|
})
|
|
|
|
TaskList = Backbone.Collection.extend({
|
|
|
|
model: Task
|
|
|
|
})
|
|
|
|
@tasks = new TaskList(@level.get 'tasks')
|
2016-01-13 18:54:57 -05:00
|
|
|
@render()
|
2016-01-20 18:32:21 -05:00
|
|
|
|
2016-01-13 18:54:57 -05:00
|
|
|
pushTasks: ->
|
2016-01-20 18:32:21 -05:00
|
|
|
@level.set 'tasks', @taskMap()
|
2016-01-13 18:54:57 -05:00
|
|
|
|
2016-01-20 18:32:21 -05:00
|
|
|
onClickTaskRow: (e) ->
|
2016-01-22 16:54:20 -05:00
|
|
|
if not @$el.find(e.target).is('input') and not @$el.find(e.target).is('a') and not @$el.find(e.target).hasClass('start-edit') and @$el.find('#cur-edit').length is 0
|
|
|
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
|
|
|
checkbox = @$el.find(e.currentTarget).find('.task-input')[0]
|
2016-01-20 18:32:21 -05:00
|
|
|
if task.get 'complete'
|
|
|
|
task.set 'complete', false
|
|
|
|
else
|
|
|
|
task.set 'complete', true
|
|
|
|
checkbox.checked = task.get 'complete'
|
2016-01-13 18:54:57 -05:00
|
|
|
@pushTasks()
|
|
|
|
|
2016-01-20 18:32:21 -05:00
|
|
|
onClickTaskInput: (e) ->
|
2016-01-22 16:54:20 -05:00
|
|
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
2016-01-20 18:32:21 -05:00
|
|
|
task.set 'complete', e.currentTarget.checked
|
2016-01-13 18:54:57 -05:00
|
|
|
@pushTasks()
|
|
|
|
|
2016-01-20 18:32:21 -05:00
|
|
|
onClickStartEdit: (e) ->
|
2016-01-22 16:54:20 -05:00
|
|
|
if @$el.find('#cur-edit').length is 0
|
|
|
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
2016-01-20 18:32:21 -05:00
|
|
|
task.set 'curEdit', true
|
2016-01-13 18:54:57 -05:00
|
|
|
@render()
|
2016-01-22 16:54:20 -05:00
|
|
|
@focusEditInput()
|
2016-01-13 18:54:57 -05:00
|
|
|
|
2016-01-20 18:32:21 -05:00
|
|
|
onKeyDownCurEdit: (e) ->
|
2016-01-13 18:54:57 -05:00
|
|
|
if e.keyCode is 13
|
2016-01-22 16:54:20 -05:00
|
|
|
editInput = @$el.find('#cur-edit')[0]
|
2016-01-21 15:14:37 -05:00
|
|
|
editInput.blur()
|
|
|
|
|
|
|
|
onBlurCurEdit: (e) ->
|
2016-01-22 16:54:20 -05:00
|
|
|
editInput = @$el.find('#cur-edit')[0]
|
|
|
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
2016-01-21 15:14:37 -05:00
|
|
|
@applyTaskName(task, editInput)
|
2016-01-13 18:54:57 -05:00
|
|
|
|
2016-01-20 18:32:21 -05:00
|
|
|
onClickCreateTask: (e) ->
|
2016-01-22 16:54:20 -05:00
|
|
|
if @$el.find('#cur-edit').length is 0
|
2016-01-20 18:32:21 -05:00
|
|
|
@tasks.add
|
|
|
|
name: ''
|
|
|
|
complete: false
|
|
|
|
curEdit: true
|
|
|
|
revert:
|
|
|
|
name: 'null'
|
|
|
|
complete: false
|
2016-01-13 18:54:57 -05:00
|
|
|
@render()
|
2016-01-22 16:54:20 -05:00
|
|
|
@focusEditInput()
|