瀏覽代碼

[wip] undo/redo system

Gyedo Jeon 16 年之前
父節點
當前提交
312944e2f7

+ 61 - 0
direct/src/leveleditor/ActionMgr.py

@@ -0,0 +1,61 @@
+class ActionBase(Functor):
+    """ Base class for user actions """
+
+    def __init__(self, function, *args, **kargs):
+        Functor.__init__(self, function, *args, **kargs)
+        
+    def undo(self):
+        print "undo method is not defined for this action"
+
+class ActionMgr:
+    def __init__(self):
+        self.undoList = []
+        self.redoList = []
+
+    def reset(self):
+        while len(self.undoList) > 0:
+            action = self.undoList.pop()
+            action.destroy()
+
+        while len(self.redoList) > 0:
+            action = self.redoList.pop()
+            action.destroy()
+
+    def push(self, action):
+        self.undoList.append(action)
+
+    def undo(self):
+        if len(self.undoList) < 1:
+            print 'No more undo'
+        else:
+            action = self.undoList.pop()
+            self.redoList.append(action)
+            action.undo()
+
+    def redo(self):
+        if len(self.redoList) < 1:
+            print 'No more redo'
+        else:
+            action = self.redoList.pop()
+            self.undoList.append(action)
+            action()
+
+class ActionAddNewObj(ActionBase):
+    """ Action class for adding new object """
+    
+    def __init__(self, function, *args, **kargs):
+        ActionBase.__init__(self, function, *args, **kargs)
+        self.np = None
+
+    def _do__call__(self, *args, **kargs):
+        self.np = ActionBase._do__call__(self, *args, **kargs)
+        return self.np
+
+    def undo(self):
+        if self.np is None:
+            print "Can't undo this"
+        else:
+            base.direct.removeAllSelected()
+            base.le.objectMgr.deselectAll()
+            base.direct.removeNodePath(self.np)
+            self.np = None

+ 6 - 1
direct/src/leveleditor/LevelEditorBase.py

@@ -14,6 +14,7 @@ base = ShowBase(False)
 
 from ObjectMgr import *
 from FileMgr import *
+from ActionMgr import *
 from ProtoPalette import *
 
 class LevelEditorBase(DirectObject):
@@ -24,6 +25,7 @@ class LevelEditorBase(DirectObject):
         self.actionEvents = []
         self.objectMgr = ObjectMgr(self)
         self.fileMgr = FileMgr(self)
+        self.actionMgr = ActionMgr()
         self.protoPalette = ProtoPalette()
 
         # define your own config file in inherited class
@@ -81,6 +83,8 @@ class LevelEditorBase(DirectObject):
             ('preRemoveNodePath', self.removeNodePathHook),
             ('DIRECT_selectedNodePath_fMulti_fTag', self.selectedNodePathHook),
             ('DIRECT_deselectAll', self.deselectAll),
+            ('LE-Undo', self.actionMgr.undo),
+            ('LE-Redo', self.actionMgr.redo),
             ])
 
         # Add all the action events
@@ -137,6 +141,7 @@ class LevelEditorBase(DirectObject):
     def reset(self):
         base.direct.deselectAll()
         self.objectMgr.reset()
+        self.actionMgr.reset()
 
     def save(self):
         if self.currentFile:
@@ -182,7 +187,7 @@ class LevelEditorBase(DirectObject):
                 elif line.startswith('gridSpacing'):
                     gridSpacing = float(configLines[i])
                 elif line.startswith('hotKey'):
-                    base.direct.hotKeyMap = eval(configLines[i])
+                    base.direct.hotKeyMap.update(eval(configLines[i]))
 
             self.ui.updateGrids(gridSize, gridSpacing)
         except:

+ 4 - 1
direct/src/leveleditor/LevelEditorUI.py

@@ -12,6 +12,7 @@ from SceneGraphUI import *
 from LayerEditorUI import *
 from HotKeyUI import *
 from ProtoPaletteUI import *
+from ActionMgr import *
 
 class PandaTextDropTarget(wx.TextDropTarget):
     def __init__(self, editor):
@@ -19,7 +20,9 @@ class PandaTextDropTarget(wx.TextDropTarget):
         self.editor = editor
 
     def OnDropText(self, x, y, text):
-        self.editor.objectMgr.addNewObject(text)
+        action = ActionAddNewObj(self.editor.objectMgr.addNewObject, text)
+        self.editor.actionMgr.push(action)
+        action()
 
 class LevelEditorUI(WxAppShell):
     """ Class for Panda3D LevelEditor """