UndoManager.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System.Collections.Generic;
  2. namespace PaintDotNet.Annotation
  3. {
  4. /// <summary>
  5. /// 管理类,可用于撤销、恢复
  6. /// </summary>
  7. public class UndoManager
  8. {
  9. /// <summary>
  10. /// 每个画布对应的标注、测量、视场、其它工具的集合
  11. /// </summary>
  12. GraphicsList graphicsList;
  13. /// <summary>
  14. /// 命令的集合
  15. /// </summary>
  16. List<Command.Command> historyList;
  17. /// <summary>
  18. /// 命令位置标记
  19. /// </summary>
  20. int nextUndo;
  21. public UndoManager(GraphicsList graphicsList)
  22. {
  23. this.graphicsList = graphicsList;
  24. ClearHistory();
  25. }
  26. public void RemoveCommandFromHistory(DrawObject o)
  27. {
  28. }
  29. /// <summary>
  30. /// Return true if Undo operation is available
  31. /// </summary>
  32. public bool CanUndo
  33. {
  34. get
  35. {
  36. // If the NextUndo pointer is -1, no commands to undo
  37. if (nextUndo < 0 ||
  38. nextUndo > historyList.Count - 1) // precaution
  39. {
  40. return false;
  41. }
  42. return true;
  43. }
  44. }
  45. /// <summary>
  46. /// Return true if Redo operation is available
  47. /// </summary>
  48. public bool CanRedo
  49. {
  50. get
  51. {
  52. // If the NextUndo pointer points to the last item, no commands to redo
  53. if (nextUndo == historyList.Count - 1)
  54. {
  55. return false;
  56. }
  57. return true;
  58. }
  59. }
  60. /// <summary>
  61. /// Clear History
  62. /// </summary>
  63. public void ClearHistory()
  64. {
  65. historyList = new List<Command.Command>();
  66. nextUndo = -1;
  67. }
  68. /// <summary>
  69. /// Add new command to history.
  70. /// Called by client after executing some action.
  71. /// </summary>
  72. /// <param name="command"></param>
  73. public void AddCommandToHistory(Command.Command command)
  74. {
  75. // Purge history list
  76. this.TrimHistoryList();
  77. // Add command and increment undo counter
  78. historyList.Add(command);
  79. nextUndo++;
  80. }
  81. /// <summary>
  82. /// Undo
  83. /// </summary>
  84. public void Undo()
  85. {
  86. if (!CanUndo)
  87. {
  88. return;
  89. }
  90. // Get the Command object to be undone
  91. Command.Command command = historyList[nextUndo];
  92. // Execute the Command object's undo method
  93. command.Undo(graphicsList);
  94. // Move the pointer up one item
  95. nextUndo--;
  96. }
  97. /// <summary>
  98. /// Redo
  99. /// </summary>
  100. public void Redo()
  101. {
  102. if (!CanRedo)
  103. {
  104. return;
  105. }
  106. // Get the Command object to redo
  107. int itemToRedo = nextUndo + 1;
  108. Command.Command command = historyList[itemToRedo];
  109. // Execute the Command object
  110. command.Redo(graphicsList);
  111. // Move the undo pointer down one item
  112. nextUndo++;
  113. }
  114. private void TrimHistoryList()
  115. {
  116. // We can redo any undone command until we execute a new
  117. // command. The new command takes us off in a new direction,
  118. // which means we can no longer redo previously undone actions.
  119. // So, we purge all undone commands from the history list.*/
  120. // Exit if no items in History list
  121. if (historyList.Count == 0)
  122. {
  123. return;
  124. }
  125. // Exit if NextUndo points to last item on the list
  126. if (nextUndo == historyList.Count - 1)
  127. {
  128. return;
  129. }
  130. // Purge all items below the NextUndo pointer
  131. for (int i = historyList.Count - 1; i > nextUndo; i--)
  132. {
  133. historyList.RemoveAt(i);
  134. }
  135. }
  136. }
  137. }