first stage of undo/redo functionality -- there are still a number of actions that...
[potlatch2.git] / net / systemeD / halcyon / connection / MainUndoStack.as
1 package net.systemeD.halcyon.connection {
2
3     import flash.events.*;
4
5     public class MainUndoStack extends EventDispatcher {
6         private static const GLOBAL_INSTANCE:MainUndoStack = new MainUndoStack();
7         
8         public static function getGlobalStack():MainUndoStack {
9             return GLOBAL_INSTANCE;
10         }
11         
12         private var undoActions:Array = [];
13         private var redoActions:Array = [];
14
15         /*
16          * Performs the action, then puts it on the undo stack.
17          *
18          * If you want to delay execution don't put it on this
19          * stack -- find another one.
20          */
21         public function addAction(action:UndoableAction):void {
22             trace("doing "+action);
23             var result:uint = action.doAction();
24             
25             switch ( result ) {
26             
27             case UndoableAction.FAIL:
28                 throw new Error("Failure performing "+action);
29                 
30             case UndoableAction.NO_CHANGE:
31                 // nothing to do, and don't add to stack
32                 break;
33                 
34             case UndoableAction.SUCCESS:
35             default:
36                 if ( undoActions.length > 0 ) {
37                     var previous:UndoableAction = undoActions[undoActions.length - 1];
38                     var isMerged:Boolean = action.mergePrevious(previous);
39                     if ( isMerged )
40                         undoActions.pop();
41                 }
42                 undoActions.push(action);
43                 redoActions = [];
44                 dispatchEvent(new Event("new_undo_item"));
45                 dispatchEvent(new Event("new_redo_item"));
46                 break;
47                 
48             }
49         }
50         
51         /*
52          * Call to kill the undo queue -- the user will not be able to undo
53          * anything they previously did after this is called.
54          */
55         public function breakUndo():void {
56             undoActions = [];
57             redoActions = [];
58         }
59         
60         [Bindable(event="new_undo_item")]
61         public function canUndo():Boolean {
62             return undoActions.length > 0;
63         }
64         
65         [Bindable(event="new_redo_item")]
66         public function canRedo():Boolean {
67             return redoActions.length > 0;
68         }
69         
70         public function undo():void {
71             var action:UndoableAction = undoActions.pop();
72             trace("undoing "+action);
73             action.undoAction();
74             redoActions.push(action);
75             dispatchEvent(new Event("new_undo_item"));
76             dispatchEvent(new Event("new_redo_item"));
77         }
78         
79         public function redo():void {
80             var action:UndoableAction = redoActions.pop();
81             trace("redoing "+action);
82             action.doAction();
83             undoActions.push(action);
84             dispatchEvent(new Event("new_undo_item"));
85             dispatchEvent(new Event("new_redo_item"));
86         }
87        
88     }
89 }