From 925460b12450afb0d6fd16644403e2fa92ed5a4f Mon Sep 17 00:00:00 2001 From: Gyedo Jeon Date: Wed, 10 Feb 2010 19:16:46 +0000 Subject: [PATCH] Made property update undoable --- direct/src/leveleditor/ActionMgr.py | 54 ++++++++++++++++--- direct/src/leveleditor/LevelEditorBase.py | 9 ++++ direct/src/leveleditor/ObjectMgr.py | 63 ++++++++++++++--------- 3 files changed, 95 insertions(+), 31 deletions(-) diff --git a/direct/src/leveleditor/ActionMgr.py b/direct/src/leveleditor/ActionMgr.py index 48db2a127a..f3f12c9558 100755 --- a/direct/src/leveleditor/ActionMgr.py +++ b/direct/src/leveleditor/ActionMgr.py @@ -17,6 +17,8 @@ class ActionMgr: def push(self, action): self.undoList.append(action) + if len(self.redoList) > 0: + self.redoList.pop() print 'current undoList', self.undoList def undo(self): @@ -41,6 +43,11 @@ class ActionBase(Functor): """ Base class for user actions """ def __init__(self, function, *args, **kargs): + self.function = function + if function is None: + def nullFunc(): + pass + function = nullFunc Functor.__init__(self, function, *args, **kargs) self.result = None @@ -225,14 +232,15 @@ class ActionTransformObj(ActionBase): def saveStatus(self): obj = self.editor.objectMgr.findObjectById(self.uid) if obj: - self.origMat = Mat4(obj[OG.OBJ_NP].getMat()) + self.origMat = Mat4(self.editor.objectMgr.objectsLastXform[obj[OG.OBJ_UID]]) + #self.origMat = Mat4(obj[OG.OBJ_NP].getMat()) - def redo(self): - if self.uid is None: - print "Can't redo this add" - else: - self.result = self._do__call__()#uid=self.uid, xformMat=self.xformMat) - return self.result + def _do__call__(self, *args, **kargs): + self.result = ActionBase._do__call__(self, *args, **kargs) + obj = self.editor.objectMgr.findObjectById(self.uid) + if obj: + self.editor.objectMgr.objectsLastXform[self.uid] = Mat4(obj[OG.OBJ_NP].getMat()) + return self.result def undo(self): if self.origMat is None: @@ -242,6 +250,7 @@ class ActionTransformObj(ActionBase): obj = self.editor.objectMgr.findObjectById(self.uid) if obj: obj[OG.OBJ_NP].setMat(self.origMat) + self.editor.objectMgr.objectsLastXform[self.uid] = Mat4(self.origMat) del self.origMat self.origMat = None @@ -270,3 +279,34 @@ class ActionDeselectAll(ActionBase): if obj: self.editor.select(obj[OG.OBJ_NP], fMultiSelect=1, fUndo=0) self.selectedUIDs = [] + +class ActionUpdateObjectProp(ActionBase): + """ Action class for updating object property """ + + def __init__(self, editor, fSelectObject, obj, propName, val, oldVal, function, undoFunc, *args, **kargs): + self.editor = editor + self.fSelectObject = fSelectObject + self.obj = obj + self.propName = propName + self.newVal = val + self.oldVal = oldVal + self.undoFunc = undoFunc + ActionBase.__init__(self, function, *args, **kargs) + + def saveStatus(self): + self.obj[OG.OBJ_PROP][self.propName] = self.newVal + + def redo(self): + self.result = self._do__call__()#uid=self.uid, xformMat=self.xformMat) + if self.editor and self.fSelectObject: + base.direct.select(self.obj[OG.OBJ_NP], fUndo=0) + return self.result + + def undo(self): + print "Undo : updateObjectProp" + if self.oldVal: + self.obj[OG.OBJ_PROP][self.propName] = self.oldVal + if self.undoFunc: + self.undoFunc() + if self.editor and self.fSelectObject: + base.direct.select(self.obj[OG.OBJ_NP], fUndo=0) diff --git a/direct/src/leveleditor/LevelEditorBase.py b/direct/src/leveleditor/LevelEditorBase.py index 359598ea57..07ad0b1507 100755 --- a/direct/src/leveleditor/LevelEditorBase.py +++ b/direct/src/leveleditor/LevelEditorBase.py @@ -120,6 +120,7 @@ class LevelEditorBase(DirectObject): ('DIRECT_deselectAll', self.deselectAll), ('LE-Undo', self.actionMgr.undo), ('LE-Redo', self.actionMgr.redo), + ('DIRECT_manipulateObjectCleanup', self.cleanUpManipulating), ]) # Add all the action events @@ -170,6 +171,14 @@ class LevelEditorBase(DirectObject): ## coa = Vec3(row[0], row[1], row[2]) ## base.direct.cameraControl.updateCoa(coa) + def cleanUpManipulating(self, selectedNPs): + for np in selectedNPs: + obj = self.objectMgr.findObjectByNodePath(np) + if obj: + action = ActionTransformObj(self, obj[OG.OBJ_UID], Mat4(np.getMat())) + self.actionMgr.push(action) + action() + def select(self, nodePath, fMultiSelect=0, fSelectTag=1, fResetAncestry=1, fLEPane=0, fUndo=1): if fUndo: # Select tagged object if present diff --git a/direct/src/leveleditor/ObjectMgr.py b/direct/src/leveleditor/ObjectMgr.py index e86967e948..81c54ae7b1 100755 --- a/direct/src/leveleditor/ObjectMgr.py +++ b/direct/src/leveleditor/ObjectMgr.py @@ -20,6 +20,7 @@ class ObjectMgr: self.objects = {} self.npIndex = {} self.saveData = [] + self.objectsLastXform = {} self.lastUid = '' self.lastUidMode = 0 @@ -180,6 +181,7 @@ class ObjectMgr: return self.currNodePath = obj[OG.OBJ_NP] + self.objectsLastXform[obj[OG.OBJ_UID]] = Mat4(self.currNodePath.getMat()) # [gjeon] to connect transform UI with nodepath's transform self.spawnUpdateObjectUITask() self.updateObjectPropertyUI(obj) @@ -443,34 +445,47 @@ class ObjectMgr: propDataType = propDef[OG.PROP_DATATYPE] val = OG.TYPE_CONV[propDataType](val) - objProp[propName] = val - - if propDef[OG.PROP_FUNC] is None: - return + oldVal = objProp[propName] + #objProp[propName] = val - funcName = propDef[OG.PROP_FUNC][OG.FUNC_NAME] - funcArgs = propDef[OG.PROP_FUNC][OG.FUNC_ARGS] - - if funcName.startswith('.'): - if self.editor: - func = Functor(eval("base.le.objectHandler%s"%funcName)) - else: # when loaded outside of LE - func = Functor(eval("base.objectHandler%s"%funcName)) + if propDef[OG.PROP_FUNC] is None: + func = None + undoFunc = None else: - func = Functor(eval(funcName)) + funcName = propDef[OG.PROP_FUNC][OG.FUNC_NAME] + funcArgs = propDef[OG.PROP_FUNC][OG.FUNC_ARGS] - # populate keyword arguments - kwargs = {} - for key in funcArgs.keys(): - if funcArgs[key] == OG.ARG_VAL: - kwargs[key] = val - elif funcArgs[key] == OG.ARG_OBJ: - kwargs[key] = obj + # populate keyword arguments + kwargs = {} + undoKwargs = {} + for key in funcArgs.keys(): + if funcArgs[key] == OG.ARG_VAL: + kwargs[key] = val + undoKwargs[key] = oldVal + elif funcArgs[key] == OG.ARG_OBJ: + undoKwargs[key] = obj + objProp[propName] = val + kwargs[key] = obj + else: + kwargs[key] = funcArgs[key] + undoKwargs[key] = funcArgs[key] + + if funcName.startswith('.'): + if self.editor: + func = Functor(eval("base.le.objectHandler%s"%funcName), **kwargs) + undoFunc = Functor(eval("base.le.objectHandler%s"%funcName), **undoKwargs) + else: # when loaded outside of LE + func = Functor(eval("base.objectHandler%s"%funcName), **kwargs) + undoFunc = Functor(eval("base.objectHandler%s"%funcName), **undoKwargs) else: - kwargs[key] = funcArgs[key] - - # finally call update function - func(**kwargs) + func = Functor(eval(funcName), **kwargs) + undoFunc = Functor(eval(funcName), **undoKwargs) + + # finally call update function + #func(**kwargs) + action = ActionUpdateObjectProp(self.editor, fSelectObject, obj, propName, val, oldVal, func, undoFunc) + self.editor.actionMgr.push(action) + action() if self.editor and fSelectObject: base.direct.select(obj[OG.OBJ_NP], fUndo=0)