ya2 · news · projects · code · about

undo/redo
authorFlavio Calva <f.calva@gmail.com>
Mon, 24 Jan 2022 19:28:42 +0000 (20:28 +0100)
committerFlavio Calva <f.calva@gmail.com>
Mon, 24 Jan 2022 19:28:42 +0000 (20:28 +0100)
pmachines/items/box.py
pmachines/scene.py
prj.org

index 42253cca356507c1b5a9ec31bc97940197cd9aaa..2565a55f050f0acbec63ba2845da0cb97e090902 100644 (file)
@@ -5,6 +5,13 @@ from direct.gui.OnscreenText import OnscreenText
 from lib.lib.p3d.gfx import P3dGfxMgr, set_srgb
 
 
+class Command:
+
+    def __init__(self, pos, rot):
+        self.pos = pos
+        self.rot = rot
+
+
 class Box:
 
     def __init__(self, world, plane_node, count, cb_inst):
@@ -14,6 +21,9 @@ class Box:
         self._cb_inst = cb_inst
         self._paused = False
         self._overlapping = False
+        self._first_command = True
+        self._commands = []
+        self._command_idx = -1
         self._shape = BulletBoxShape((.5, .5, .5))
         self.node = BulletGhostNode('box')
         self.node.add_shape(self._shape)
@@ -86,6 +96,16 @@ class Box:
         self._np.set_y(0)
         return task.cont
 
+    def undo(self):
+        self._command_idx -= 1
+        self._np.set_pos(self._commands[self._command_idx].pos)
+        self._np.set_hpr(self._commands[self._command_idx].rot)
+
+    def redo(self):
+        self._command_idx += 1
+        self._np.set_pos(self._commands[self._command_idx].pos)
+        self._np.set_hpr(self._commands[self._command_idx].rot)
+
     def play(self):
         if not self._instantiated:
             return
@@ -125,6 +145,10 @@ class Box:
     def on_release(self):
         if self._start_drag_pos or self._prev_rot_info:
             loader.load_sfx('assets/audio/sfx/release.ogg').play()
+            self._command_idx += 1
+            self._commands = self._commands[:self._command_idx]
+            self._commands += [Command(self._np.get_pos(), self._np.get_hpr())]
+            self._first_command = False
         self._start_drag_pos = self._prev_rot_info = None
         if self._overlapping:
             self._np.set_pos(self._last_nonoverlapping_pos)
index 6c120923986ed74614014fd345b49ab0dadcce3d..80725d85e477bb439d3f4e0d3fbe70d290ea7efc 100644 (file)
@@ -28,9 +28,12 @@ class Scene(DirectObject):
         self._set_input()
         self._set_mouse_plane()
         self.items = [Box(world, self._mouse_plane_node, 3, self.cb_inst)]
+        self._commands = []
+        self._command_idx = 0
         self._paused = False
         self._item_active = None
         if auto_close_instr:
+            self.__store_state()
             self.__restore_state()
         else:
             self._set_instructions()
@@ -39,6 +42,8 @@ class Scene(DirectObject):
         self._scene_tsk = taskMgr.add(self.on_frame, 'on_frame')
 
     def reset(self):
+        self._commands = []
+        self._command_idx = 0
         [itm.destroy() for itm in self.items]
         self.items = [Box(self._world, self._mouse_plane_node, 3, self.cb_inst)]
 
@@ -192,6 +197,16 @@ class Scene(DirectObject):
         self._on_click('on_click_r')
 
     def on_release(self):
+        if self._item_active and not self._item_active._first_command:
+            self._commands = self._commands[:self._command_idx]
+            self._commands += [self._item_active]
+            self._command_idx += 1
+            self.__prev_btn['state'] = NORMAL
+            fcols = (.4, .4, .4, .14), (.3, .3, .3, .05)
+            self.__prev_btn['frameColor'] = fcols[0]
+            if self._item_active._command_idx == len(self._item_active._commands) - 1:
+                self.__next_btn['state'] = DISABLED
+                self.__next_btn['frameColor'] = fcols[1]
         self._item_active = None
         [item.on_release() for item in self.items]
         self._cursor.set_image('assets/buttons/arrowUpLeft.png')
@@ -225,10 +240,23 @@ class Scene(DirectObject):
         [itm.play() for itm in self.items]
 
     def on_next(self):
-        print('on_next')
+        self._commands[self._command_idx].redo()
+        self._command_idx += 1
+        fcols = (.4, .4, .4, .14), (.3, .3, .3, .05)
+        self.__prev_btn['state'] = NORMAL
+        self.__prev_btn['frameColor'] = fcols[0]
+        more_commands = self._command_idx < len(self._commands)
+        self.__next_btn['state'] = NORMAL if more_commands else DISABLED
+        self.__next_btn['frameColor'] = fcols[0] if more_commands else fcols[1]
 
     def on_prev(self):
-        print('on_prev')
+        self._command_idx -= 1
+        self._commands[self._command_idx].undo()
+        fcols = (.4, .4, .4, .14), (.3, .3, .3, .05)
+        self.__next_btn['state'] = NORMAL
+        self.__next_btn['frameColor'] = fcols[0]
+        self.__prev_btn['state'] = NORMAL if self._command_idx else DISABLED
+        self.__prev_btn['frameColor'] = fcols[0] if self._command_idx else fcols[1]
 
     def on_home(self):
         self._exit_cb()
diff --git a/prj.org b/prj.org
index 82f7db1fe4d8c350f95cf7995c5ad528d2a39d64..0585ba5aec72fe59cb7e852dcca84eaae0e5a051 100644 (file)
--- a/prj.org
+++ b/prj.org
@@ -1,8 +1,5 @@
 * issues
 * todo
-** implement the operations of the buttons
-*** undo
-*** redo
 ** implement other items
 *** shelf
 *** domino