Skip to content

Commit

Permalink
Starting to add a select tool
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmire committed Apr 1, 2012
1 parent 23374ce commit ab60ef7
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 87 deletions.
8 changes: 0 additions & 8 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,8 @@
* Add undo/redo -- this will require refactoring all the tools into a more
object-oriented approach

* BUG: Can't move an object after placing it (have to refresh)

* BUG: When dragging another item of the same type, type is not stored in saved
data

* Add ability to dupe an object without having to drag it again all the way from
the sidebar

* For map objects, group the $elem and the object together, everywhere, as one
MapObject

* BUG: Switch from fill to tiles and then back, some of the map objects in the
tiles layer are still moveable.
32 changes: 27 additions & 5 deletions app/javascripts/common/ender_ext.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,34 @@ enderMembers =
removeAllClasses: -> # ...

moveBy: (args) ->
x = parseInt(this.css('left'), 10) + (args.x or 0)
y = parseInt(this.css('top'), 10) + (args.y or 0)
this.css('left', "#{x}px").css('top', "#{y}px")
pos = @position()
x = pos.x + (args.x or 0)
y = pos.y + (args.y or 0)
@css('left', "#{x}px")
@css('top', "#{y}px")

moveTo: (x, y) ->
this.css('left', "#{x}px").css('top', "#{y}px")
moveTo: (pos) ->
@position(pos)

position: (pos) ->
if pos
@css('left', "#{pos.x}px")
@css('top', "#{pos.y}px")
return this
else
x = parseInt(@css('left'), 10)
y = parseInt(@css('top'), 10)
{x, y}

size: (dim) ->
if dim
@css('width', "#{dim.w}px")
@css('height', "#{dim.h}px")
return this
else
w = parseInt(@css('width'), 10)
h = parseInt(@css('height'), 10)
{w, h}

contains: (elem) ->
elem = elem[0] if elem instanceof Array
Expand Down
4 changes: 2 additions & 2 deletions app/javascripts/editor/core.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ define 'editor.core', ->
helper: true
# TODO: Need to ensure that dropTarget can receive sidebar objects...
# what if we switch to a different layer?
dropTarget: @viewport.$element
dropTarget: @viewport.getElement()
.bind "mousedragstart.#{evtns}", (evt) ->
console.log "#{evtns}: mousedragstart"
$draggee = $(this)
Expand Down Expand Up @@ -234,7 +234,7 @@ define 'editor.core', ->
_initToolbox: ->
that = this
@$toolbox = $('<div id="editor-toolbox"/>')
@viewport.$element.append(@$toolbox)
@viewport.getElement().append(@$toolbox)
@currentTool = null
@prevTool = null

Expand Down
2 changes: 1 addition & 1 deletion app/javascripts/editor/drag_object.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ define 'editor.DragObject', ->
y = 0
else if (y + @offset.height) > dropTargetOffset.height
y = (dropTargetOffset.height - @offset.height)
$elem.moveTo(x, y)
$elem.moveTo({x, y})

getDraggee: ->
if @options.helper then @$helper else @$elem
Expand Down
136 changes: 120 additions & 16 deletions app/javascripts/editor/viewport.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,26 @@ define 'editor.viewport', ->
Bounds = require('game.Bounds')
require('editor.DropTarget')

DRAG_SNAP_GRID_SIZE = 16
GRID_SIZE = 16

meta.def
init: (@core) ->
@$element = $('#editor-viewport')
@$elem = $('#editor-viewport')
@_initMapElement()
@_initBounds()
@map = null
@objectsByLayer = $.v.reduce @core.getLayers(), ((h, n) -> h[n] = {}; h), {}
@objectId = 0
return this

getElement: -> @$elem

setWidth: (width) ->
@$element.width(width)
@$elem.width(width)
@bounds.setWidth(width)

setHeight: (height) ->
@$element.height(height)
@$elem.height(height)
@bounds.setHeight(height)

loadMap: ->
Expand All @@ -39,7 +41,7 @@ define 'editor.viewport', ->
.removeClass('editor-map-unloaded')

# TODO: Refactor
# localStorage.removeItem('editor.map')
localStorage.removeItem('editor.map')
if data = localStorage.getItem('editor.map')
console.log 'map data': data
try
Expand All @@ -64,7 +66,7 @@ define 'editor.viewport', ->
layerSel = '#editor-map .editor-layer[data-layer=tiles]'
mapObjectsSel = "#{layerSel} .editor-map-object"

@$element
@$elem
.dropTarget(
receptor: "#{layerSel} .editor-layer-content"
)
Expand All @@ -81,11 +83,7 @@ define 'editor.viewport', ->
@addObject('tiles', $draggee, $dragOwner.data('so'))
@_addEventsToMapObjects($draggee)

x = parseInt($draggee.css('left'), 10)
y = parseInt($draggee.css('top'), 10)
x = Math.round(x / DRAG_SNAP_GRID_SIZE) * DRAG_SNAP_GRID_SIZE
y = Math.round(y / DRAG_SNAP_GRID_SIZE) * DRAG_SNAP_GRID_SIZE
$draggee.moveTo(x, y)
$draggee.position(@_roundCoordsToGrid($draggee.position()))
@saveMap()

@_addEventsToMapObjects $(mapObjectsSel)
Expand Down Expand Up @@ -122,15 +120,15 @@ define 'editor.viewport', ->
layerSel = '#editor-map .editor-layer[data-layer=tiles]'
mapObjectsSel = "#{layerSel} .editor-map-object"

@$element
@$elem
.dropTarget('destroy')
.unbind(".#{evtns}")
@_removeEventsFromMapObjects $(mapObjectsSel)
@$map.unbind(".#{evtns}")
$(window).unbind(".#{evtns}")

activate_hand_tool: ->
evtns = 'editor.viewport.layer-tiles.tool-normal'
evtns = 'editor.viewport.tool-hand'
@$map
.bind "mousedown.#{evtns}", (evt) =>
console.log 'viewport: mousedown (hand tool)'
Expand Down Expand Up @@ -183,10 +181,112 @@ define 'editor.viewport', ->
$(window).unbind "mousemove.#{evtns}"

deactivate_hand_tool: ->
evtns = 'editor.viewport.layer-tiles.tool-normal'
evtns = 'editor.viewport.tool-hand'
@$map.unbind(".#{evtns}")
$(window).unbind(".#{evtns}")

activate_fill_select_tool: ->
evtns = 'editor.viewport.layer-fill.tool-select'

mouseDownAt = null
selection = null

SELECTION_ACTIVATION_OFFSET = 4 # pixels

$layerElem = @core.getCurrentLayerElem().find('.editor-layer-content')

clearSelection = (evt) =>
console.log 'clearing selection'
evt.preventDefault()
# selection.$box.remove()
# the above does not work for some reason
$layerElem.find('.editor-selection-box').remove()
selection = null

mouseupBound = false
bindMouseup = =>
return if mouseupBound
console.log 'binding mouseup'
mouseupBound = true
# @$elem.bind("mouseup.#{evtns}", clearSelection)
unbindMouseup = =>
return if not mouseupBound
console.log 'unbinding mouseup'
mouseupBound = false
# @$elem.unbind(clearSelection)

adjustCoords = (p) =>
x: p.x - @bounds.x1
y: p.y - @bounds.y1

@$elem
.bind "mousedown.#{evtns}", (evt) =>
# don't open a selection box accidentally if the map is right-clicked
# FIXME so this handles ctrl-click too
return if evt.button is 2

evt.preventDefault()
mouse = mouseDownAt = {x: evt.pageX, y: evt.pageY}
pos = @_roundCoordsToGrid(adjustCoords(mouse))
selection = {}
selection.pos = pos

@$elem.bind "mousemove.#{evtns}", (evt) =>
evt.preventDefault()
mouse = {x: evt.pageX, y: evt.pageY}

dragOffsetX = Math.abs(evt.pageX - mouseDownAt.x)
dragOffsetY = Math.abs(evt.pageY - mouseDownAt.y)
return unless (
dragOffsetX > SELECTION_ACTIVATION_OFFSET or
dragOffsetY > SELECTION_ACTIVATION_OFFSET
)

unbindMouseup()

if not selection.isPresent
selection.$box = $('<div class="editor-selection-box">')
.appendTo($layerElem)
selection.isPresent = true

mouse = @_roundCoordsToGrid(adjustCoords(mouse))
if mouse.x < selection.pos.x
x = mouse.x
w = selection.pos.x - mouse.x
else
x = selection.pos.x
w = mouse.x - selection.pos.x
if mouse.y < selection.pos.y
y = mouse.y
h = selection.pos.y - mouse.y
else
y = selection.pos.y
h = mouse.y - selection.pos.y
if w is 0 and h is 0
selection.$box.hide()
else
selection.$box.show().moveTo({x, y}).size({w, h})

.delegate '.editor-selection-box', "mouseup.#{evtns}", (evt) ->
console.log 'selection box mouseup'
# because otherwise the selection will be cleared
evt.stopPropagation()
evt.preventDefault()

.bind "mouseup.#{evtns}", (evt) =>
@$elem.unbind "mousemove.#{evtns}"
mouseDownAt = null
# delay the re-addition of the mouseup event ever so slightly
# otherwise it gets fired immediately (since we're in the mouseup
# event ourselves)
setTimeout bindMouseup, 0

bindMouseup()

deactivate_fill_select_tool: ->
evtns = 'editor.viewport.layer-fill.tool-select'
@$elem.unbind(".#{evtns}")

addObject: (layer, $elem, object) ->
console.log 'viewport: addObject'
obj = {}
Expand Down Expand Up @@ -226,7 +326,7 @@ define 'editor.viewport', ->
$draggee.attr('data-is-selected', newstate)
# CS bug #2221 regarding indentation
$draggees.dragObject
dropTarget: @$element
dropTarget: @$elem
containWithinDropTarget: true

_removeEventsFromMapObjects: ($draggees) ->
Expand All @@ -235,6 +335,10 @@ define 'editor.viewport', ->
.dragObject('destroy')
.unbind(".#{evtns}")

_roundCoordsToGrid: (p) ->
x: Math.round(p.x / GRID_SIZE) * GRID_SIZE,
y: Math.round(p.y / GRID_SIZE) * GRID_SIZE

_mouseWithinViewport: (evt) ->
@bounds.x1 <= evt.pageX <= @bounds.x2 and
@bounds.y1 <= evt.pageY <= @bounds.y2
Expand All @@ -252,5 +356,5 @@ define 'editor.viewport', ->
@$map.append($layer)

_initBounds: ->
offset = @$element.offset()
offset = @$elem.offset()
@bounds = Bounds.rect(offset.left, offset.top, offset.width, offset.height)
52 changes: 34 additions & 18 deletions app/stylesheets/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,29 @@ body {
font-family: Helvetica Neue, Arial, sans-serif;
}

.editor-drag-active,
.editor-tool-normal .editor-map-object,
#editor-sidebar div.img {
cursor: move
}

.editor-tool-select #editor-viewport {
cursor: crosshair;
}

#editor-viewport {
&.editor-tool-normal {
cursor: auto;
}
&.editor-tool-hand {
cursor: url('/images/editor/tool-hand.gif'), auto;
}
&.editor-tool-select {
cursor: url('/images/editor/tool-select.gif'), auto;
}
&.editor-tool-bucket {
cursor: url('/images/editor/tool-bucket.gif'), auto;
}
// &.editor-tool-normal {
// cursor: auto;
// }
// &.editor-tool-hand {
// cursor: url('/images/editor/tool-hand.gif'), auto;
// }
// &.editor-tool-select {
// cursor: url('/images/editor/tool-select.gif'), auto;
// }
// &.editor-tool-bucket {
// cursor: url('/images/editor/tool-bucket.gif'), auto;
// }

.editor-layer, .editor-layer-content, .editor-layer-bg {
position: absolute;
Expand All @@ -45,12 +55,6 @@ body {
}
}

.editor-drag-active,
.editor-layer-tiles.editor-tool-normal .editor-map-object,
#editor-sidebar div.img {
cursor: move
}

#editor-nav {
$height: 40px;

Expand Down Expand Up @@ -168,3 +172,15 @@ $sidebar-width: 300px;
// position: absolute;
// z-index: 100;
// }

// marching ants like it's 1995
// http://sunpig.com/martin/archives/2010/02/10/marching-ants-in-css.html
.editor-selection-box {
position: absolute;
z-index: 10;
background-color: white;
border: 1px dashed black;
-moz-border-image: url(/images/editor/selection-border.gif) 1 repeat;
-webkit-border-image: url(/images/editor/selection-border.gif) 1 repeat;
border-image: url(/images/editor/selection-border.gif) 1 repeat;
}
Binary file removed public/images/editor/ants.gif
Binary file not shown.
Binary file added public/images/editor/selection-border.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ab60ef7

Please sign in to comment.