UndoManager.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 PixiEditor.Models
  16. {
  17. public static class UndoManager
  18. {
  19. private const int MaximumChangesInRam = 1;
  20. private static int _undosSavedOnDisk = 0;
  21. private static int _redosSavedOnDisk = 0;
  22. public static StackEx<Change> UndoStack { get; set; } = new StackEx<Change>();
  23. public static StackEx<Change> RedoStack { get; set; } = new StackEx<Change>();
  24. private static bool _stopRecording = false;
  25. private static List<Change> _recordedChanges = new List<Change>();
  26. private static bool _lastChangeWasUndo = false;
  27. public static bool CanUndo
  28. {
  29. get
  30. {
  31. return UndoStack.Count > 0;
  32. }
  33. }
  34. public static bool CanRedo
  35. {
  36. get
  37. {
  38. return RedoStack.Count > 0;
  39. }
  40. }
  41. public static object MainRoot { get; set; }
  42. /// <summary>
  43. /// Sets object(root) in which undo properties are stored.
  44. /// </summary>
  45. /// <param name="root">Parent object.</param>
  46. public static void SetMainRoot(object root)
  47. {
  48. MainRoot = root;
  49. }
  50. /// <summary>
  51. /// Records changes, used to save multiple changes as one
  52. /// </summary>
  53. /// <param name="property">Record property name.</param>
  54. /// <param name="oldValue">Old change value.</param>
  55. /// <param name="newValue">New change value.</param>
  56. /// <param name="undoDescription">Description of change.</param>
  57. public static void RecordChanges(string property, object oldValue, string undoDescription = "")
  58. {
  59. if (_stopRecording == false)
  60. {
  61. if (_recordedChanges.Count < 2)
  62. {
  63. _recordedChanges.Add(new Change(property, oldValue, undoDescription));
  64. }
  65. }
  66. }
  67. /// <summary>
  68. /// Stops recording changes and saves it as one.
  69. /// </summary>
  70. public static void StopRecording()
  71. {
  72. _stopRecording = true;
  73. if (_recordedChanges.Count > 0)
  74. {
  75. Change changeToSave = _recordedChanges[0];
  76. AddUndoChange(changeToSave.Property, changeToSave.OldValue, changeToSave.Description);
  77. _recordedChanges.Clear();
  78. }
  79. _stopRecording = false;
  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, 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, 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.Pop().OldValue);
  116. }
  117. }
  118. }