UndoManager.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. using PixiEditorDotNetCore3.Models.DataHolders;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Reflection;
  6. namespace PixiEditor.Models.Controllers
  7. {
  8. public static class UndoManager
  9. {
  10. public static StackEx<Change> UndoStack { get; set; } = new StackEx<Change>();
  11. public static StackEx<Change> RedoStack { get; set; } = new StackEx<Change>();
  12. private static bool _stopRecording = false;
  13. private static List<Change> _recordedChanges = new List<Change>();
  14. private static bool _lastChangeWasUndo = false;
  15. public static bool CanUndo
  16. {
  17. get
  18. {
  19. return UndoStack.Count > 0;
  20. }
  21. }
  22. public static bool CanRedo
  23. {
  24. get
  25. {
  26. return RedoStack.Count > 0;
  27. }
  28. }
  29. public static object MainRoot { get; set; }
  30. /// <summary>
  31. /// Sets object(root) in which undo properties are stored.
  32. /// </summary>
  33. /// <param name="root">Parent object.</param>
  34. public static void SetMainRoot(object root)
  35. {
  36. MainRoot = root;
  37. }
  38. /// <summary>
  39. /// Records changes, used to save multiple changes as one
  40. /// </summary>
  41. /// <param name="property">Record property name.</param>
  42. /// <param name="oldValue">Old change value.</param>
  43. /// <param name="newValue">New change value.</param>
  44. /// <param name="undoDescription">Description of change.</param>
  45. public static void RecordChanges(string property, object oldValue, object newValue, string undoDescription = "")
  46. {
  47. if (_stopRecording == false)
  48. {
  49. if (_recordedChanges.Count >= 2)
  50. {
  51. _recordedChanges.RemoveAt(_recordedChanges.Count - 1);
  52. }
  53. _recordedChanges.Add(new Change(property, oldValue, newValue, undoDescription));
  54. }
  55. }
  56. /// <summary>
  57. /// Stops recording changes and saves it as one.
  58. /// </summary>
  59. public static void StopRecording()
  60. {
  61. _stopRecording = true;
  62. if (_recordedChanges.Count > 0)
  63. {
  64. Change changeToSave = _recordedChanges[0];
  65. changeToSave.NewValue = _recordedChanges.Last().OldValue;
  66. AddUndoChange(changeToSave);
  67. _recordedChanges.Clear();
  68. }
  69. _stopRecording = false;
  70. }
  71. public static void AddUndoChange(Change change)
  72. {
  73. if (_lastChangeWasUndo == false && RedoStack.Count > 0) //Cleares RedoStack if las move wasn't redo or undo and if redo stack is greater than 0
  74. {
  75. RedoStack.Clear();
  76. }
  77. _lastChangeWasUndo = false;
  78. UndoStack.Push(change);
  79. Debug.WriteLine("UndoStackCount: " + UndoStack.Count + " RedoStackCount: " + RedoStack.Count);
  80. }
  81. /// <summary>
  82. /// Adds property change to UndoStack
  83. /// </summary>
  84. /// <param name="property">Changed property name.</param>
  85. /// <param name="oldValue">Old value of property.</param>
  86. /// <param name="newValue">New value of property.</param>
  87. /// <param name="undoDescription">Description of change.</param>
  88. public static void AddUndoChange(string property, object oldValue, object newValue, string undoDescription = "")
  89. {
  90. if (_lastChangeWasUndo == false && RedoStack.Count > 0) //Cleares RedoStack if las move wasn't redo or undo and if redo stack is greater than 0
  91. {
  92. RedoStack.Clear();
  93. }
  94. _lastChangeWasUndo = false;
  95. UndoStack.Push(new Change(property, oldValue, newValue, undoDescription));
  96. Debug.WriteLine("UndoStackCount: " + UndoStack.Count + " RedoStackCount: " + RedoStack.Count);
  97. }
  98. /// <summary>
  99. /// Sets top property in UndoStack to Old Value
  100. /// </summary>
  101. public static void Undo()
  102. {
  103. _lastChangeWasUndo = true;
  104. PropertyInfo propInfo = MainRoot.GetType().GetProperty(UndoStack.Peek().Property);
  105. propInfo.SetValue(MainRoot, UndoStack.Peek().OldValue);
  106. RedoStack.Push(UndoStack.Pop());
  107. }
  108. /// <summary>
  109. /// Sets top property from RedoStack to old value
  110. /// </summary>
  111. public static void Redo()
  112. {
  113. _lastChangeWasUndo = true;
  114. PropertyInfo propinfo = MainRoot.GetType().GetProperty(RedoStack.Peek().Property);
  115. propinfo.SetValue(MainRoot, RedoStack.Peek().NewValue);
  116. UndoStack.Push(RedoStack.Pop());
  117. }
  118. }
  119. }