/// <summary> /// Add an undo state to the current stage (if one is active) or directly /// to the stack as a new stage (if one isn't). /// </summary> /// <param name="state"></param> /// <param name="clearRedo">If true, the redo stack will be invalidated</param> public void AddUndoState(UndoState state, bool clearRedo = true) { if (!Locked && Active) { if (state != null && state.IsValid) { if (ActiveStage != null)// && !ActiveStage.Contains(state)) { ActiveStage.Add(state); if (!UndoStack.Contains(ActiveStage)) { AddUndoStage(ActiveStage); } } else { UndoStage stage = new UndoStage(); stage.Add(state); AddUndoStage(stage); } } if (clearRedo) { RedoStack.Clear(); } } }
/// <summary> /// Add a new stage to the redo stack /// </summary> /// <param name="stage"></param> private void AddRedoStage(UndoStage stage) { if (stage != null && stage.Count > 0) { RedoStack.Add(stage); if (RedoStack.Count > MaxStackSize) { RedoStack.RemoveAt(0); } } }
/// <summary> /// Redo the last redoable action /// </summary> public virtual void Redo() { Locked = true; if (RedoStack.Count > 0) { UndoStage stage = RedoStack[RedoStack.Count - 1]; RedoStack.RemoveAt(RedoStack.Count - 1); UndoStage redo = stage.Undo(); AddUndoStage(redo, false); BeginStage(); } Locked = false; }
/// <summary> /// Add a new stage to the undo stack /// </summary> /// <param name="stage"></param> private void AddUndoStage(UndoStage stage, bool clearRedo = true) { if (stage != null && stage.Count > 0) { UndoStack.Add(stage); if (UndoStack.Count > MaxStackSize) { UndoStack.RemoveAt(0); } if (clearRedo) { RedoStack.Clear(); } } }
/// <summary> /// Revert this stage by restoring the states stored /// within this collection /// </summary> /// <returns>The redo stage necessary to redo this undo.</returns> public UndoStage Undo() { var redo = new UndoStage(); for (int i = Count - 1; i >= 0; i--) { UndoState state = this[i]; if (state.IsValid) { try { redo.Add(state.GenerateRedo()); state.Restore(); } catch { } } } return redo; }
/// <summary> /// Begin a new undo stage. /// Until EndStage() is called, all undo states added will be combined together into a single MultiUndoState. /// </summary> /// <returns>The new MultiUndoState that represents the current stage</returns> public UndoStage BeginStage() { EndStage(); ActiveStage = new UndoStage(); return(ActiveStage); }