Initial implementation of the InventoryController

This commit is contained in:
Andrew Miner
2015-01-06 10:25:05 -08:00
parent d499e8e9cf
commit a1a7ee5dc9
13 changed files with 330 additions and 23 deletions
-1
View File
@@ -92,7 +92,6 @@ module.exports = (grunt)->
options: options:
client: true client: true
node: true node: true
pretty: true
processName: (f)-> processName: (f)->
f = f.replace './src/templates/', '' f = f.replace './src/templates/', ''
f = f.replace '_view', '' f = f.replace '_view', ''
+12 -11
View File
@@ -25,21 +25,25 @@ $color-brick-dark: #7A7A7A;
$color-brick-light: #D9D9D9; $color-brick-light: #D9D9D9;
$color-content: rgba(230, 230, 230, 0.90); $color-content: rgba(230, 230, 230, 0.90);
$color-dirt: #906647; $color-dirt: #906647;
$color-error-new: #CD0000;
$color-error: #F3C2C2;
$color-ice: #8AA7E6; $color-ice: #8AA7E6;
$color-footer: #3D1D09; $color-footer: #3D1D09;
$color-footer-text: white; $color-footer-text: white;
$color-gray-faint: #F2F2F2; $color-gray-faint: #F2F2F2;
$color-gray-light: #CCCCCC; $color-gray-light: #CCCCCC;
$color-table-background: white; $color-table-background: white;
$color-toolbar-background: rgba(255, 255, 255, 0.75);
$font-family-header: 'PressStart'; $font-family-header: 'PressStart';
$font-family-normal: sans-serif; $font-family-normal: sans-serif;
$font-family-input: monospace; $font-family-input: monospace;
$font-size-small: 1.1em; $font-size-small: 1.1em;
$font-size-normal: 1.3em; $font-size-normal: 1.3em;
$font-size-large: 2.0em; $font-size-large: 1.6em;
$font-size-x-large: 3.0em; $font-size-x-large: 2.0em;
$font-size-xx-large: 3.0em;
// Common ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Common //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -61,7 +65,7 @@ h1 {
p { p {
font-family: $font-family-header; font-family: $font-family-header;
font-size: $font-size-x-large; font-size: $font-size-xx-large;
position: relative; top: -0.5em; position: relative; top: -0.5em;
} }
} }
@@ -79,7 +83,7 @@ h2 {
p { p {
font-family: $font-family-header; font-family: $font-family-header;
font-size: $font-size-large; font-size: $font-size-x-large;
position: relative; top: -0.25em; position: relative; top: -0.25em;
} }
} }
@@ -119,12 +123,9 @@ label {
width: 100%; width: 100%;
} }
.page > div { .error { background: $color-error; }
position: relative; width: 100%;
padding: 2em 2em 0 2em;
&:first-child { padding-top: 0; } .error-new { background: $color-error-new; }
}
// Views /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Views ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+1
View File
@@ -41,6 +41,7 @@ th,td,caption {
font-weight: normal; font-weight: normal;
vertical-align: top; vertical-align: top;
text-align: left; text-align: left;
@include box-sizing(border-box);
} }
q { q {
+2
View File
@@ -6,5 +6,7 @@ All rights reserved.
*/ */
@import 'crafting_table'; @import 'crafting_table';
@import 'inventory';
@import 'item_page';
@import 'mod_pack'; @import 'mod_pack';
@import 'stack'; @import 'stack';
+85
View File
@@ -0,0 +1,85 @@
/*
Crafting Guide - inventory.scss
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
*/
.view__inventory {
min-height: 14em;
width: 100%;
.edit td {
padding-top: 1em;
}
.panel {
position: absolute; top: 5em; right: 2em; bottom: 0; left: 2em;
background: $color-table-background;
text-align: right;
}
.scrollbox {
position: absolute; top: 0em; right: 0em; bottom: 3em; left: 0em;
padding: 0.5em 1em;
overflow: auto;
}
.toolbar {
position: absolute; right: 0; bottom: 0; left: 0; height: 3em;
background: $color-toolbar-background;
border-top: 1px solid $color-gray-light;
}
button[name="clear"] {
position: absolute; bottom: 0.5em; right: 0.5em;
}
input {
border: 1px solid $color-gray-light;
}
table {
width: 100%;
}
td {
height: 3.6em;
padding-bottom: 0.25em;
&:nth-child(1) {
width: 3.6em;
input {
border-radius: 0.75em;
margin: 0 auto;
text-align: center;
width: 90%;
}
}
&:nth-child(2) {
@include box-sizing(content-box);
padding: 0 2.0em 0 1.0em;
input {
height: 100%; width: 100%;
border: 0;
border-bottom: 1px dashed $color-gray-light;
outline: 0;
&:focus {
border: 1px solid $color-gray-light;
}
}
}
&:nth-child(3) {
width: 3.6em;
button {
width: 100%;
}
}
}
}
+19
View File
@@ -0,0 +1,19 @@
/*
Crafting Guide - item_page.scss
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
*/
.view__item_page {
& > div {
display: inline-block;
padding: 0 2em;
position: relative;
vertical-align: top;
}
.view__inventory { width: 50%; height: 26em; }
.view__crafting_table, .view__mod_pack { margin-top: 2em; width: 100%; }
}
+7 -8
View File
@@ -7,17 +7,14 @@ All rights reserved.
.view__stack { .view__stack {
font-family: $font-family-normal; font-family: $font-family-normal;
td { vertical-align: middle; }
td { border-left: 0 !important; padding-bottom: 0.25em; }
td:nth-child(2) { padding-left: 0.5em; width: 100%; }
td:nth-child(3) { width: 1.6em; }
.quantity { .quantity {
border-radius: 0.75em; border-radius: 0.75em;
background: $color-ice; background: $color-ice;
color: $color-table-background; color: $color-table-background;
font-size: $font-size-small; font-size: $font-size-large;
font-weight: bold;
text-align: center; text-align: center;
min-width: 3em; min-width: 3em;
padding: 0.1em 0.5em; padding: 0.1em 0.5em;
@@ -25,10 +22,12 @@ All rights reserved.
} }
.name { .name {
font-size: $font-size-small; display: inline;
font-size: $font-size-large;
} }
img { img {
height: 1.6em; width: 1.6em; width: 100%; height: auto;
max-height: 4.8em;
} }
} }
@@ -0,0 +1,164 @@
###
Crafting Guide - inventory_controller.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
BaseController = require './base_controller'
{Duration} = require '../constants'
{Key} = require '../constants'
StackController = require './stack_controller'
########################################################################################################################
module.exports = class InventoryController extends BaseController
@ONLY_DIGITS = /^[0-9]*$/
constructor: (options={})->
if not options.model? then throw new Error 'options.model is required'
if not options.modPack? then throw new Error 'options.modPack is required'
options.icon ?= '/images/chest_front.png'
options.editable ?= true
options.templateName = 'inventory'
options.title ?= 'Inventory'
super options
@editable = options.editable
@icon = options.icon
@modPack = options.modPack
@title = options.title
@_stackControllers = []
@listenTo @modPack, 'change', => @refresh()
# Event Methods ################################################################################
onAddButtonClicked: ->
item = @modPack.findItemByName @$nameField.val()
return unless item?
@model.add item.slug, parseInt(@$quantityField.val())
@$nameField.val ''
@$quantityField.val '1'
@$scrollbox.scrollTop @$scrollbox.prop 'scrollHeight'
onClearButtonClicked: ->
@model.clear()
onNameFieldBlur: ->
item = @modPack.findItemByName @$nameField.val()
@$nameField.val if item? then item.name else ''
@onNameFieldChanged()
onNameFieldChanged: ->
item = @modPack.findItemByName @$nameField.val()
@_updateButtonState()
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'
@$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.fast
@$quantityField.removeClass 'error-new', Duration.fast
@_updateButtonState()
# BaseController Overrides #####################################################################
onDidRender: ->
@$addButton = @$('button[name="add"]')
@$clearButton = @$('button[name="clear"]')
@$icon = @$('.icon')
@$editPanel = @$('.edit')
@$nameField = @$('input[name="name"]')
@$quantityField = @$('input[name="quantity"]')
@$scrollbox = @$('.scrollbox')
@$table = @$('table')
@$title = @$('.title')
super
refresh: ->
display = if @editable then 'block' else 'none'
@$clearButton.css display:(if @editable then 'block' else 'none')
@$editPanel.css display:(if @editable then 'table-row' else 'none')
@$icon.attr 'src', @icon
@$title.html @title
if _.isEmpty(@$quantityField.val()) then @$quantityField.val '1'
@$table.find('tr:not(:last-child)').remove()
$lastRow = @$table.find 'tr:last-child'
@_stackControllers = []
@model.each (stack)=>
options =
model: stack
modPack: @modPack
onRemove: if not @editable then null else (stack)=> @_removeStack(stack)
controller = new StackController options
controller.render()
controller.$el.insertBefore $lastRow
@_stackControllers.push controller
@_updateNameAutocomplete()
@_updateButtonState()
super
# Backbone.View Overrides ######################################################################
events:
'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'
'input input[name="name"]': 'onNameFieldChanged'
'input input[name="quantity"]': 'onQuantityFieldChanged'
'keyup input[name="name"]': 'onNameFieldKeyUp'
# Private Methods ##############################################################################
_removeStack: (stack)->
_updateNameAutocomplete: ->
onChanged = => @onNameFieldChanged()
@$nameField.autocomplete
source: @modPack.gatherRecipeNames()
delay: 0
minLength: 0
change: onChanged
close: onChanged
select: onChanged
_updateButtonState: ->
if @model.isEmpty then @$clearButton.attr('disabled', 'disabled') else @$clearButton.removeAttr('disabled')
itemValid = @modPack.findItemByName(@$nameField.val())?
quantityValid = @$quantityField.val().match(InventoryController.ONLY_DIGITS)
disable = not (itemValid and quantityValid)
if disable then @$addButton.attr('disabled', 'disabled') else @$addButton.removeAttr('disabled')
@@ -7,8 +7,9 @@ All rights reserved.
BaseController = require './base_controller' BaseController = require './base_controller'
CraftingTableController = require './crafting_table_controller' CraftingTableController = require './crafting_table_controller'
ItemPage = require '../models/item_page' InventoryController = require './inventory_controller'
ModPackController = require './mod_pack_controller' ItemPage = require '../models/item_page'
ModPackController = require './mod_pack_controller'
######################################################################################################################## ########################################################################################################################
@@ -28,6 +29,17 @@ module.exports = class ItemPageController extends BaseController
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
options = model:@model.table.have, modPack:@model.modPack, editable:true
@haveController = @addChild InventoryController, '.view__inventory.have', options
options =
editable: false
icon: '/images/workbench_top.png',
model: @model.table.want,
modPack: @model.modPack,
title: 'Items to Craft'
@wantController = @addChild InventoryController, '.view__inventory.want', options
@modPackController = @addChild ModPackController, '.view__mod_pack', model:@model.modPack @modPackController = @addChild ModPackController, '.view__mod_pack', model:@model.modPack
@tableController = @addChild CraftingTableController, '.view__crafting_table', model:@model.table @tableController = @addChild CraftingTableController, '.view__crafting_table', model:@model.table
super super
+1
View File
@@ -21,6 +21,7 @@ module.exports = class CraftingTable extends BaseModel
attributes.includingTools ?= false attributes.includingTools ?= false
attributes.have ?= new Inventory attributes.have ?= new Inventory
attributes.plan ?= null attributes.plan ?= null
attributes.want ?= new Inventory
super attributes, options super attributes, options
# Public Methods ############################################################################### # Public Methods ###############################################################################
+1
View File
@@ -44,6 +44,7 @@ module.exports = class Inventory extends BaseModel
clear: -> clear: ->
@_stacks = {} @_stacks = {}
@_slugs = [] @_slugs = []
@trigger 'change', self
clone: -> clone: ->
inventory = new Inventory inventory = new Inventory
+20
View File
@@ -0,0 +1,20 @@
//-
//- Crafting Guide - inventory.jade
//-
//- Copyright (c) 2014-2015 by Redwood Labs
//- All rights reserved.
//-
.view__inventory
h2
img.icon
p.title
.panel
.scrollbox
table
tr.edit
td: input(name="quantity")
td(width="*"): input(name="name")
td: button(name="add") add
.toolbar
button(name="clear") clear
+4 -1
View File
@@ -5,6 +5,9 @@
//- All rights reserved. //- All rights reserved.
//- //-
.view__landing_page .view__item_page
.view__inventory.have
.view__inventory.want
.view__crafting_table .view__crafting_table
.view__mod_pack .view__mod_pack