diff --git a/src/coffee/controllers/multiblock_controller.coffee b/src/coffee/controllers/multiblock_controller.coffee index 03701e88d..85c5beac7 100644 --- a/src/coffee/controllers/multiblock_controller.coffee +++ b/src/coffee/controllers/multiblock_controller.coffee @@ -13,6 +13,8 @@ BaseController = require './base_controller' module.exports = class MultiblockController extends BaseController + @::HOVER_TIMEOUT = 5000 # ms + @::IMAGE_SIZE = 48 # px @::X_LAYER_H_SHIFT = -24 # px @@ -34,6 +36,7 @@ module.exports = class MultiblockController extends BaseController @_blockCache = null @_imageLoader = options.imageLoader @_modPack = options.modPack + @_onHovering = options.onHovering ?= (itemDisplay)-> # do nothing # Public Methods ############################################################################### @@ -53,16 +56,24 @@ module.exports = class MultiblockController extends BaseController return false unless @model? return @_currentLayer < @model.height - 1 + # Property Methods ############################################################################# + + Object.defineProperties @prototype, + currentLayer: + get: -> return @_currentLayer + # BaseController Overrides ##################################################################### onDidRender: -> - # do nothing + @$outline = @$('.outline') + super refresh: -> @$el.css 'min-height':@_computeMinHeight(), 'min-width':@_computeMinWidth() @_refreshBlockCache() @_refreshAllBlocks() + super # Private Methods ############################################################################## @@ -82,7 +93,7 @@ module.exports = class MultiblockController extends BaseController top = (pxHeight - @IMAGE_SIZE) + (x * @X_LAYER_V_SHIFT) + (z * @Z_LAYER_V_SHIFT) + (y * @Y_LAYER_V_SHIFT) opacity = 1.0 - zindex = (@model.width - x) + (@model.depth - z) + ((@model.width * @model.depth) * y) + zindex = ((@model.width - x) + (@model.depth - z) + ((@model.width * @model.depth) * y)) * 2 return left:left, top:top, 'z-index':zindex, opacity:opacity @@ -101,6 +112,11 @@ module.exports = class MultiblockController extends BaseController rightPosition = @_computePosition 0, 0, @model.depth return rightPosition.left - leftPosition.left + _endHovering: -> + @$outline.css opacity:0.0 + @_hoverTimer = null + @_onHovering null + _randomDropDelay: -> return Math.random() * @MAX_DROP_DELAY @@ -134,6 +150,7 @@ module.exports = class MultiblockController extends BaseController if not $block? $block = $("#{itemDisplay.itemName}") $block.css position, top:-@IMAGE_SIZE, opacity:0.0 + @_registerHoverHandlers $block, y, itemDisplay @_imageLoader.load itemDisplay.iconUrl, $block @_blockCache[x][y][z] = $block @$el.append $block @@ -149,8 +166,23 @@ module.exports = class MultiblockController extends BaseController _refreshAllBlocks: -> return unless @model? + if @_endHovering? then @_endHovering() for x in [0...@model.width] for y in [0...@model.height] for z in [0...@model.depth] @_refreshBlock(x, y, z) + + _registerHoverHandlers: ($el, y, itemDisplay)-> + startHovering = => + return unless y is @_currentLayer + zIndex = parseInt($el.css('z-index')) + 1 + zIndex = if _.isNaN(zIndex) then 0 else zIndex + + @$outline.css opacity:1.0, top:$el.css('top'), left:$el.css('left'), 'z-index':zIndex + @_onHovering itemDisplay + + if @_hoverTimer? then clearTimeout @_hoverTimer + @_hoverTimer = setTimeout (=> @_endHovering()), @HOVER_TIMEOUT + + $el.hover startHovering, (->) diff --git a/src/coffee/controllers/multiblock_viewer_controller.coffee b/src/coffee/controllers/multiblock_viewer_controller.coffee index ca18a7914..9744ac79d 100644 --- a/src/coffee/controllers/multiblock_viewer_controller.coffee +++ b/src/coffee/controllers/multiblock_viewer_controller.coffee @@ -7,6 +7,7 @@ All rights reserved. _ = require '../underscore_mixins' BaseController = require './base_controller' +InventoryController = require './inventory_controller' MultiblockController = require './multiblock_controller' ######################################################################################################################## @@ -21,42 +22,67 @@ module.exports = class MultiblockViewerController extends BaseController @_imageLoader = options.imageLoader @_modPack = options.modPack + @_hoverTimer = null # Event Methods ################################################################################ onBackClicked: -> - return if @backButton.hasClass 'disabled' + return if @$backButton.hasClass 'disabled' @multiblockController.goBackLayer() @refresh() onNextClicked: -> - return if @nextButton.hasClass 'disabled' + return if @$nextButton.hasClass 'disabled' @multiblockController.goNextLayer() @refresh() + onBlockHovered: (itemDisplay)-> + if itemDisplay? + @$captionText.html itemDisplay.itemName + @_imageLoader.load itemDisplay.iconUrl, @$captionIcon + else + @$captionText.html ' ' + @$captionIcon.attr 'src', '/images/empty.png' + # BaseController Overrides ##################################################################### onDidRender: -> - @multiblockController = @addChild MultiblockController, '.view__multiblock', + @completeInventoryController = @addChild InventoryController, '.view__inventory.complete', + editable: false imageLoader: @_imageLoader modPack: @_modPack - @backButton = @$('.button.back') - @nextButton = @$('.button.next') + @layerInventoryController = @addChild InventoryController, '.view__inventory.layer', + editable: false + imageLoader: @_imageLoader + modPack: @_modPack + + @multiblockController = @addChild MultiblockController, '.view__multiblock', + imageLoader: @_imageLoader + modPack: @_modPack + onHovering: (itemDisplay)=> @onBlockHovered(itemDisplay) + + @$backButton = @$('.button.back') + @$nextButton = @$('.button.next') + @$captionText = @$('.caption p') + @$captionIcon = @$('.caption img') super refresh: -> - @multiblockController.model = @model + if @model? + @completeInventoryController.model = @model.inventory + @layerInventoryController.model = @model.getLayerInventory @multiblockController.currentLayer + @multiblockController.model = @model if @multiblockController.hasBackLayer() - @backButton.removeClass 'disabled' + @$backButton.removeClass 'disabled' else - @backButton.addClass 'disabled' + @$backButton.addClass 'disabled' if @multiblockController.hasNextLayer() - @nextButton.removeClass 'disabled' + @$nextButton.removeClass 'disabled' else - @nextButton.addClass 'disabled' + @$nextButton.addClass 'disabled' super diff --git a/src/coffee/models/multiblock.coffee b/src/coffee/models/multiblock.coffee index 29f973de5..333fb34e6 100644 --- a/src/coffee/models/multiblock.coffee +++ b/src/coffee/models/multiblock.coffee @@ -5,9 +5,9 @@ Copyright (c) 2014-2015 by Redwood Labs All rights reserved. ### -_ = require '../underscore_mixins' -BaseModel = require './base_model' -SimpleInventory = require './simple_inventory' +_ = require '../underscore_mixins' +BaseModel = require './base_model' +Inventory = require './inventory' ######################################################################################################################## @@ -28,6 +28,12 @@ module.exports = class Multiblock extends BaseModel return null if value is undefined return value + getLayerInventory: (y)-> + @_layerInventories ?= [] + result = @_layerInventories[y] + if not result? then result = @_layerInventories[y] = new Inventory + return result + # Property Methods ############################################################################# Object.defineProperties @prototype, @@ -45,7 +51,7 @@ module.exports = class Multiblock extends BaseModel # Private Methods ############################################################################## - _analyzeLayer: (layer, stackCacheLayer)-> + _analyzeLayer: (layer, y, stackCacheLayer)-> rows = layer.split ' ' @_depth = Math.max @_depth, rows.length @@ -53,21 +59,21 @@ module.exports = class Multiblock extends BaseModel @_width = Math.max @_width, row.length stackCacheRow = [] stackCacheLayer.push stackCacheRow - @_analyzeRow row, stackCacheRow + @_analyzeRow row, stackCacheRow, @getLayerInventory(y) _analyzePattern: -> @_depth = @_height = @_width = 0 - @_inventory = new SimpleInventory + @_inventory = new Inventory @_stackCache = [] - for layer in @layers + for layer, y in @layers stackCacheLayer = [] @_stackCache.push stackCacheLayer - @_analyzeLayer layer, stackCacheLayer + @_analyzeLayer layer, y, stackCacheLayer @_height = @layers.length - _analyzeRow: (row, stackCacheRow)-> + _analyzeRow: (row, stackCacheRow, layerInventory)-> for cell, x in row.split '' index = parseInt cell stack = null @@ -75,5 +81,6 @@ module.exports = class Multiblock extends BaseModel if not _.isNaN index stack = @input[index] @_inventory.add stack.itemSlug, stack.quantity + layerInventory.add stack.itemSlug, stack.quantity stackCacheRow.push stack diff --git a/src/jade/templates/multiblock.jade b/src/jade/templates/multiblock.jade index 38a476b8b..3e3b719c3 100644 --- a/src/jade/templates/multiblock.jade +++ b/src/jade/templates/multiblock.jade @@ -6,3 +6,4 @@ //- .view__multiblock + img.outline(src="/images/outline.png") \ No newline at end of file diff --git a/src/jade/templates/multiblock_viewer.jade b/src/jade/templates/multiblock_viewer.jade index 307b25405..a93f8faad 100644 --- a/src/jade/templates/multiblock_viewer.jade +++ b/src/jade/templates/multiblock_viewer.jade @@ -6,7 +6,17 @@ //- .view__multiblock_viewer - .view__multiblock - .buttons - .button.back: p back - .button.next: p next + .left + h3 Current Layer + .view__inventory.layer + + h3 Complete Materials + .view__inventory.complete + .right + .caption + img + p   + .view__multiblock + .buttons + .button.back: p back + .button.next: p next diff --git a/src/scss/classes.scss b/src/scss/classes.scss index 4f4d9ac9e..605ee0704 100644 --- a/src/scss/classes.scss +++ b/src/scss/classes.scss @@ -53,7 +53,7 @@ All rights reserved. clear: both; } -.content { +body > .content { background: $color-content; box-shadow: 10px 10px 20px #666; margin: 2em auto; diff --git a/src/scss/templates/multiblock.scss b/src/scss/templates/multiblock.scss index 65ec555ab..af46e1b66 100644 --- a/src/scss/templates/multiblock.scss +++ b/src/scss/templates/multiblock.scss @@ -12,4 +12,10 @@ All rights reserved. position: absolute; transition: all $animate-slow cubic-bezier(0.615, -0.090, 0.010, 1.090); } + + .outline { + position: absolute; + opacity: 0.0; + transition: opacity $animate-fast; + } } diff --git a/src/scss/templates/multiblock_viewer.scss b/src/scss/templates/multiblock_viewer.scss index 5c8c2f957..d16ef2421 100644 --- a/src/scss/templates/multiblock_viewer.scss +++ b/src/scss/templates/multiblock_viewer.scss @@ -7,20 +7,55 @@ All rights reserved. .view__multiblock_viewer { display: flex; - flex-direction: column; + align-items: flex-start; - .view__multiblock_viewer { - flex: 0 1 100%; + h3 { + margin-bottom: 1em; + margin-left: 0; } - .buttons { - display: flex; - flex: 0 0 auto; - margin: 1em 25% 0 25%; + .left { + border-right: 1px solid $color-gray-light; + flex: 1 0 40%; + padding: 2em 0 0 2em; + } - .button { - flex: 50%; - margin: 1em; + .right { + display: flex; + flex-direction: column; + flex: 0 1 60%; + + .caption { + display: flex; + justify-content: center; + align-items: center; + margin-top: 1em; + + img { + border: none; + margin-right: 1em; + height: 3.6em; + max-width: 3.6em; + } + + p { + font-weight: bold; + } + } + + .view__multiblock_viewer { + flex: 1 1 100%; + } + + .buttons { + display: flex; + flex: 0 0 auto; + margin: 1em 10% 0 10%; + + .button { + flex: 50%; + margin: 1em; + } } } } diff --git a/static/images/outline.png b/static/images/outline.png new file mode 100644 index 000000000..2280b831c Binary files /dev/null and b/static/images/outline.png differ