Closed jayantj closed 10 years ago
Looking good! I got it to work well, there are just a few things to do:
onZPressed call to onKeyDown:
onKeyDown: (e) ->
@onEscapePressed(e) if e.which is 27
@onTabPressed(e) if e.which is 9
@onLeftArrowPressed(e) if e.which is 37
@onUpArrowPressed(e) if e.which is 38
@onRightArrowPressed(e) if e.which is 39
@onDownArrowPressed(e) if e.which is 40
@onEnterPressed(e) if e.which is 13
@onNPressed(e) if e.which is 78
@onSpacePressed(e) if e.which is 32
@onTPressed(e) if e.which is 84
@onFPressed(e) if e.which is 70
@onZPressed(e) if e.which is 90
@onDeletePressed(e) if e.which in [8, 46] and not e.heldDown
the function itself:
onZPressed: (e) ->
if e.ctrlKey or e.metaKey
if e.shiftKey
@getRoot().redo()
else
@getRoot().undo()
I've added the keyboard shortcuts, and fixed the broken tests. I'll add additional tests by tomorrow, hopefully
A couple of things with tracking data changes made through set, insert and delete:
Hmm, something's still a bit wonky about undo/redo. I tested it out on the Overview page for Treema, with the first demonstration one on top, and it seems to break when I switch the product type between 'donut' and 'pastry'. Maybe the system isn't set up for enum type properties?
Re finding a better way for set, insert and delete, it might be best to break these functions out into regular functions which call recursive functions, so you can have logic that runs at the beginning and the end but never in the middle. Does that make sense?
Re the delete function, I've marked the two places where properties are removed. For the first one you can just use the current node's path, for the other one (which is when you delete a node that isn't currently opened to) you'll need to combine the current node's path plus the rest of the path to construct the delete action object.
delete: (path) ->
path = @normalizePath(path)
return @remove() if path.length is 0 # HERE
return @digDeeper(path, 'delete', false, []) if @childrenTreemas?
data = @data
for seg, i in path
seg = @normalizeKey(seg, data)
if path.length is i+1
if $.isArray(data) then data.splice(seg, 1) else delete data[seg]
# HERE
@refreshDisplay()
return true
else
data = data[seg]
return false if data is undefined
I've taken care of the stuff about the enum nodes, deletion of multiple nodes, and the constructor.name thing, and a few other bugs I found. I added some initial tests too, though I ran into some problems with insert and delete, so those are commented out for now.
As far as I understand, set, insert and delete form a sort of recursive loop along with digDeeper, with each of them calling the other till the appropriate node is reached. I'm not sure how they could be converted into simple recursive functions.
Initial implementation of undo-redo for treema. It seems to work fine for most actions I tried in the treema (deleting, editing, adding nodes, changing node types).
I'm not sure about the code, it's not very clean, and probably can be more efficient as well. @sderickson It'd be great to have some feedback about stuff I might have missed, and anything else really.
If this is fine, I'll begin implementing it for the level editor. I use chrome console to debug and test it out, adding keyboard shortcuts in treema itself didn't make much sense. For scratch.html, just call -