Replace use of InventoryTableController

The `InventoryTableController` had been split off from the existing
`InventoryController` some time ago, but was never properly factored
not to share common code. This change elimiates it altogether in
favor of the newly re-vamped `InventoryController` which is now
flexible enough to be used in both places.
This commit is contained in:
Andrew Miner
2015-04-20 11:10:42 -07:00
parent 87a6664728
commit 01a137cdc6
6 changed files with 11 additions and 289 deletions
@@ -9,7 +9,7 @@ BaseController = require './base_controller'
CraftingGridController = require './crafting_grid_controller'
ImageLoader = require './image_loader'
Inventory = require '../models/inventory'
InventoryTableController = require './inventory_table_controller'
InventoryController = require './inventory_controller'
{Duration} = require '../constants'
{StringBuilder} = require 'crafting-guide-common'
@@ -33,13 +33,13 @@ module.exports = class FullRecipeController extends BaseController
imageLoader: @imageLoader
modPack: @modPack
@inputController = @addChild InventoryTableController, '.input .view__inventory_table',
@inputController = @addChild InventoryController, '.input .view__inventory',
editable: false
imageLoader: @imageLoader
model: new Inventory
modPack: @modPack
@outputController = @addChild InventoryTableController, '.output .view__inventory_table',
@outputController = @addChild InventoryController, '.output .view__inventory',
editable: false
imageLoader: @imageLoader
model: new Inventory
@@ -1,201 +0,0 @@
###
Crafting Guide - inventory_table_controller.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
BaseController = require './base_controller'
{Duration} = require '../constants'
ImageLoader = require './image_loader'
ItemSlug = require '../models/item_slug'
{Key} = require '../constants'
NameFinder = require '../models/name_finder'
StackController = require './stack_controller'
########################################################################################################################
module.exports = class InventoryTableController extends BaseController
@ONLY_DIGITS = /^[0-9]*$/
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.model? then throw new Error 'options.model is required'
if not options.modPack? then throw new Error 'options.modPack is required'
@editable = options.editable ?= true
@imageLoader = options.imageLoader
@modPack = options.modPack
@nameFinder = options.nameFinder ?= new NameFinder options.modPack
@onChange = options.onChange ?= -> # do nothing
options.templateName = 'inventory_table'
super options
@_stackControllers = []
@listenTo @modPack, 'change', => @tryRefresh()
# Event Methods ################################################################################
onAddButtonClicked: ->
name = @modpack.findItemByName @$nameField.val()
return unless item?
@model.add item.slug, parseInt(@$quantityField.val())
@$nameField.val ''
@$quantityField.val '1'
@$scrollbox.scrollTop @$scrollbox.prop 'scrollHeight'
@$nameField.autocomplete 'close'
@onChange()
onClearButtonClicked: ->
@model.clear()
@onChange()
onItemSelected: ->
func = =>
@onNameFieldChanged()
@onAddButtonClicked()
@$nameField.blur()
setTimeout func, 10 # needed to allow the autocomplete to finish
return true
onNameFieldBlur: ->
item = @modPack.findItemByName @$nameField.val()
@$nameField.val if item? then item.name else ''
@onNameFieldChanged()
onNameFieldChanged: ->
item = @modPack.findItemByName @$nameField.val()
@_refreshButtonState()
onNameFieldFocused: ->
@$nameField.val ''
@$nameField.autocomplete('search')
onNameFieldKeyUp: (event)->
if event.which is Key.Return
@onAddButtonClicked()
onQuantityFieldBlur: ->
value = @$quantityField.val().replace /[^0-9]/g, ''
if value.length is 0 then value = '1'
value = Math.min value, 64
@$quantityField.val value
@onQuantityFieldChanged()
onQuantityFieldChanged: ->
if not @$quantityField.val().match /^[0-9]*$/
@$quantityField.addClass 'error', 0
@$quantityField.addClass 'error-new', 0
@$quantityField.removeClass 'error-new', Duration.slow
@$quantityField.focus()
return
@$quantityField.removeClass 'error', Duration.normal
@$quantityField.removeClass 'error-new', Duration.normal
@_refreshButtonState()
onQuantityFieldFocused: ->
@$quantityField.val ''
# BaseController Overrides #####################################################################
onDidRender: ->
@$addButton = @$('button[name="add"]')
@$clearButton = @$('button[name="clear"]')
@$editPanel = @$('.edit')
@$nameField = @$('input[name="name"]')
@$quantityField = @$('input[name="quantity"]')
@$scrollbox = @$('.scrollbox')
@$table = @$('table')
@$toolbar = @$('.toolbar')
super
refresh: ->
if @editable
@show @$editPanel
@show @$toolbar, =>
@$scrollbox.css bottom:@$toolbar.height()
else
@hide @$editPanel
@hide @$toolbar
@$scrollbox.css bottom:0
if _.isEmpty(@$quantityField.val()) then @$quantityField.val '1'
@_refreshNameAutocomplete()
@_refreshButtonState()
@_refreshStacks()
super
# Backbone.View Overrides ######################################################################
events: ->
return _.extend super,
'blur input[name="name"]': 'onNameFieldBlur'
'blur input[name="quantity"]': 'onQuantityFieldBlur'
'click button[name="add"]': 'onAddButtonClicked'
'click button[name="clear"]': 'onClearButtonClicked'
'focus input[name="name"]': 'onNameFieldFocused'
'focus input[name="quantity"]': 'onQuantityFieldFocused'
'input input[name="name"]': 'onNameFieldChanged'
'input input[name="quantity"]': 'onQuantityFieldChanged'
'keyup input[name="name"]': 'onNameFieldKeyUp'
# Private Methods ##############################################################################
_refreshButtonState: ->
if @model.isEmpty then @$clearButton.attr('disabled', 'disabled') else @$clearButton.removeAttr('disabled')
itemValid = @modPack.findItemByName(@$nameField.val())?
quantityValid = @$quantityField.val().match(InventoryTableController.ONLY_DIGITS)
disable = not (itemValid and quantityValid)
if disable then @$addButton.attr('disabled', 'disabled') else @$addButton.removeAttr('disabled')
_refreshNameAutocomplete: ->
onChanged = => @onNameFieldChanged()
onSelected = => @onItemSelected()
@$nameField.autocomplete
source: (request, callback)=> callback @nameFinder.search request.term
delay: 0
minLength: 0
change: onChanged
close: onChanged
select: onSelected
_refreshStacks: ->
@_stackControllers ?= []
index = 0
$lastRow = @$table.find 'tr:last-child'
@model.each (stack)=>
controller = @_stackControllers[index]
if not controller?
controller = new StackController
editable: @editable
imageLoader: @imageLoader
model: stack
modPack: @modPack
onRemove: if not @editable then null else (stack)=> @_removeStack(stack)
@_stackControllers.push controller
controller.$el.insertBefore $lastRow
controller.render()
else
controller.model = stack
index += 1
while @_stackControllers.length > index
@_stackControllers.pop().remove()
_removeStack: (stack)->
@model.remove stack.itemSlug, stack.quantity
+2 -2
View File
@@ -9,7 +9,7 @@
.input
h3 Ingredients
.view__inventory_table
.view__inventory
.pattern
table.view__crafting_grid
@@ -17,4 +17,4 @@
.output
h3 Produces
.view__inventory_table
.view__inventory
-16
View File
@@ -1,16 +0,0 @@
//-
//- Crafting Guide - inventory_table.jade
//-
//- Copyright (c) 2014-2015 by Redwood Labs
//- All rights reserved.
//-
.view__inventory_table
table
tr.edit.hideable.hidden
td.quantity: input(name="quantity")
td.icon: img(src="/images/unknown.png")
td.name(width="*"): input(name="name")
td.action: button(name="add") add
.toolbar.hideable.hidden
button(name="clear") clear
-1
View File
@@ -14,7 +14,6 @@ All rights reserved.
@import 'full_recipe';
@import 'home_page';
@import 'inventory';
@import 'inventory_table';
@import 'item';
@import 'item_page';
@import 'item_selector';
-60
View File
@@ -1,60 +0,0 @@
/*
Crafting Guide - inventory_table.scss
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
*/
.view__inventory_table {
table {
width: 100%;
td {
height: 2.4em;
vertical-align: middle;
}
td.name {
text-align: left;
padding-right: 1em;
input {
width: 100%;
border: 0;
border-bottom: 1px dashed $color-gray-light;
outline: 0;
&:focus {
border: 1px solid $color-gray-light;
}
}
}
td.action {
width: 4em;
}
.edit td {
padding-top: 1em;
}
}
.toolbar {
position: relative; width: 100%;
background: $color-background-toolbar;
border-top: 1px solid $color-gray-light;
}
button:disabled {
background: white;
color: $color-gray-light;
}
button[name="clear"] {
position: absolute; bottom: 0.5em; right: 0.5em;
}
input {
border: 1px solid $color-gray-light;
}
}