Introduction
Not so long ago, I decided that I needed to add undo and redo functionality to my program. I thought about it for a while and decided that it would become easier if I created some kind of interface which could be easily derived from. Every time the user does anything, a new action is added to a std::vector
list and these instructions can be interpreted by your program. I would recommend keeping the amount of data stored about an instruction as small as possible.
Using the code
Basically, for everything your program can do (that you would like to be undone or redone), you create a class derived from the interface IActionBase
. This interface contains a run function which should contain the code to complete the action, and then an undo function which should contain the code to undo the action again.
The demo project's main window contains a box which you can drag around the screen. Every time you complete a drag cycle (released the mouse), you will then be able to click the undo button. I have also inserted an option under the "Edit" menu which enables you to clear the undo/redo history.
Technically, with this system, you could implement some kind of history feature like that in Adobe Photoshop so that you can revert to a specific point in history.
To use this system, declare an instance of the class CActionHistory
in the CMainFrame
class (if you are using MFC). I would recommend that you declare it publicly so that it is easy to access, especially from the CView
derived class. Then for every action your program does, derive a class from the interface IActionBase
. You then only need to create and add the action to the interface. Please note that the AddAction
member function of CActionHistory
does not run the action. You have to run the action separately. Here is a small example of its usage:
CActionDragBox* pNewAction = new CActionDragBox(&m_rtBox, this);
pNewAction->Run();
pMainFrm->m_ActionHistory.AddAction(pNewAction);
The CActionHistory
class will take care of cleaning up instances of your action classes created with the new
operator.
If you are interested in using this, I would suggest that you firstly take a close look at the demo.
I cannot see any problems with this method, but I am no expert and there may be a better method. I hope that this article will be of some benefit to you.
Points of Interest
When I was thinking about implementing an undo/redo system, I discovered the use of interfaces; ever since my programming has been a lot more structured.
History
No changes have been made.