diff --git a/direct/src/leveleditor/ActionMgr.py b/direct/src/leveleditor/ActionMgr.py new file mode 100755 index 0000000000..e12a8ed4cb --- /dev/null +++ b/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 diff --git a/direct/src/leveleditor/LevelEditorBase.py b/direct/src/leveleditor/LevelEditorBase.py index 1035edaec5..ccbefb33f8 100755 --- a/direct/src/leveleditor/LevelEditorBase.py +++ b/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: diff --git a/direct/src/leveleditor/LevelEditorUI.py b/direct/src/leveleditor/LevelEditorUI.py index 2b863fde76..ec5eac44a0 100755 --- a/direct/src/leveleditor/LevelEditorUI.py +++ b/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 """