UndoManager.cs 5.0 KB

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