undo.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _UNDO_H_
  23. #define _UNDO_H_
  24. #include "sim/simBase.h"
  25. #include "collection/vector.h"
  26. class UndoManager;
  27. //-----------------------------------------------------------------------------
  28. class UndoAction : public SimObject
  29. {
  30. private:
  31. // Other actions necessary to support this action of which the user need not be aware [KNM | 08/10/11 | ITGB-152]
  32. Vector<UndoAction*> mQuietSubActions;
  33. protected:
  34. // The manager this was added to.
  35. UndoManager* mUndoManager;
  36. public:
  37. /// A brief description of the action, for display in menus and the like.
  38. // not private because we're exposing it to the console.
  39. StringTableEntry mActionName;
  40. // Required in all ConsoleObject subclasses.
  41. typedef SimObject Parent;
  42. DECLARE_CONOBJECT(UndoAction);
  43. static void initPersistFields();
  44. /// Create a new action, asigning it a name for display in menus et cetera.
  45. UndoAction( const UTF8* actionName = " ");
  46. // Modified to clean up quiet sub actions [KNM | 08/10/11 | ITGB-152]
  47. virtual ~UndoAction();
  48. /// Implement these methods to perform your specific undo & redo tasks.
  49. // Implemented to trickle down into quiet sub actions [KNM | 08/10/11 | ITGB-152]
  50. virtual void undo();
  51. virtual void redo();
  52. // Adds a "quiet (hidden from user)" sub action [KNM | 08/10/11 | ITGB-152]
  53. void addQuietSubAction(UndoAction * quietSubAction);
  54. /// Adds the action to the undo stack of the default UndoManager, or the provided manager.
  55. void addToManager(UndoManager* theMan = NULL);
  56. };
  57. //-----------------------------------------------------------------------------
  58. class UndoManager : public SimObject
  59. {
  60. private:
  61. /// Default number of undo & redo levels.
  62. const static U32 kDefaultNumLevels = 100;
  63. /// The stacks of undo & redo actions. They will be capped at size mNumLevels.
  64. Vector<UndoAction*> mUndoStack;
  65. Vector<UndoAction*> mRedoStack;
  66. /// Deletes all the UndoActions in a stack, then clears it.
  67. void clearStack(Vector<UndoAction*> &stack);
  68. /// Clamps a Vector to mNumLevels entries.
  69. void clampStack(Vector<UndoAction*> &stack);
  70. public:
  71. /// Number of undo & redo levels.
  72. // not private because we're exposing it to the console.
  73. U32 mNumLevels;
  74. // Required in all ConsoleObject subclasses.
  75. typedef SimObject Parent;
  76. DECLARE_CONOBJECT(UndoManager);
  77. static void initPersistFields();
  78. /// Constructor. If levels = 0, we use the default number of undo levels.
  79. UndoManager(U32 levels = kDefaultNumLevels);
  80. /// Destructor. deletes and clears the undo & redo stacks.
  81. ~UndoManager();
  82. /// Accessor to the default undo manager singleton. Creates one if needed.
  83. static UndoManager& getDefaultManager();
  84. /// Undo last action, and put it on the redo stack.
  85. void undo();
  86. /// Redo the last action, and put it on the undo stack.
  87. void redo();
  88. /// Clears the undo and redo stacks.
  89. void clearAll();
  90. /// Returns the printable name of the top actions on the undo & redo stacks.
  91. StringTableEntry getNextUndoName();
  92. StringTableEntry getNextRedoName();
  93. S32 getUndoCount();
  94. S32 getRedoCount();
  95. StringTableEntry getUndoName(S32 index);
  96. StringTableEntry getRedoName(S32 index);
  97. /// Add an action to the top of the undo stack, and clear the redo stack.
  98. void addAction(UndoAction* action);
  99. void removeAction(UndoAction* action);
  100. };
  101. // Script Undo Action Creation
  102. //
  103. // Undo actions can be created in script like this:
  104. //
  105. // ...
  106. // %undo = new UndoScriptAction() { class = SampleUndo; actionName = "Sample Undo"; };
  107. // %undo.addToManager(UndoManager);
  108. // ...
  109. //
  110. // function SampleUndo::undo()
  111. // {
  112. // ...
  113. // }
  114. //
  115. // function SampleUndo::redo()
  116. // {
  117. // ...
  118. // }
  119. //
  120. class UndoScriptAction : public UndoAction
  121. {
  122. public:
  123. typedef UndoAction Parent;
  124. UndoScriptAction() : UndoAction()
  125. {
  126. };
  127. virtual void undo() { Con::executef(this, 1, "undo"); };
  128. virtual void redo() { Con::executef(this, 1, "redo"); }
  129. virtual bool onAdd()
  130. {
  131. // Let Parent Do Work.
  132. if(!Parent::onAdd())
  133. return false;
  134. // Return Success.
  135. return true;
  136. };
  137. virtual void onRemove()
  138. {
  139. if (mUndoManager)
  140. mUndoManager->removeAction((UndoAction*)this);
  141. Parent::onRemove();
  142. }
  143. DECLARE_CONOBJECT(UndoScriptAction);
  144. };
  145. #endif