101 lines
2.6 KiB
C#
101 lines
2.6 KiB
C#
using System.Collections.Generic;
|
|
|
|
namespace Unity.PlasticSCM.Editor.UI.UndoRedo
|
|
{
|
|
internal class UndoRedoHelper
|
|
{
|
|
internal interface IUndoRedoHost
|
|
{
|
|
UndoRedoState UndoRedoState { get; set; }
|
|
}
|
|
|
|
internal bool CanUndo
|
|
{
|
|
get { return mCurrentNode != null && mCurrentNode.Previous != null; }
|
|
}
|
|
|
|
internal bool CanRedo
|
|
{
|
|
get { return mCurrentNode != null && mCurrentNode.Next != null; }
|
|
}
|
|
|
|
internal UndoRedoHelper(IUndoRedoHost host)
|
|
{
|
|
mHost = host;
|
|
}
|
|
|
|
internal bool TryGetLastState(out UndoRedoState state)
|
|
{
|
|
state = null;
|
|
if (!IsInLastState)
|
|
return false;
|
|
|
|
state = mCurrentNode.Value;
|
|
return true;
|
|
}
|
|
|
|
internal void UpdateLastState()
|
|
{
|
|
UpdateLastState(mHost.UndoRedoState);
|
|
}
|
|
|
|
internal void Undo()
|
|
{
|
|
if (mCurrentNode != null && mCurrentNode.Previous != null)
|
|
{
|
|
mCurrentNode = mCurrentNode.Previous;
|
|
mHost.UndoRedoState = mCurrentNode.Value;
|
|
}
|
|
}
|
|
|
|
internal void Redo()
|
|
{
|
|
if (mCurrentNode != null && mCurrentNode.Next != null)
|
|
{
|
|
mCurrentNode = mCurrentNode.Next;
|
|
mHost.UndoRedoState = mCurrentNode.Value;
|
|
}
|
|
}
|
|
|
|
internal void Snapshot()
|
|
{
|
|
UndoRedoState current = mHost.UndoRedoState;
|
|
if (mCurrentNode == null || !mCurrentNode.Value.Equals(current))
|
|
{
|
|
if (mCurrentNode != null && mCurrentNode.Next != null)
|
|
DiscardRedo();
|
|
|
|
mStates.AddLast(current);
|
|
mCurrentNode = mStates.Last;
|
|
|
|
if (mStates.Count > UNDO_LIMIT)
|
|
mStates.RemoveFirst();
|
|
}
|
|
}
|
|
|
|
bool IsInLastState
|
|
{
|
|
get { return mCurrentNode != null && mCurrentNode.Next == null; }
|
|
}
|
|
|
|
void UpdateLastState(UndoRedoState state)
|
|
{
|
|
if (mStates.Last != null)
|
|
mStates.Last.Value = state;
|
|
}
|
|
|
|
void DiscardRedo()
|
|
{
|
|
while (mCurrentNode != null && mCurrentNode.Next != null)
|
|
mStates.Remove(mCurrentNode.Next);
|
|
}
|
|
|
|
LinkedListNode<UndoRedoState> mCurrentNode;
|
|
|
|
readonly IUndoRedoHost mHost;
|
|
readonly LinkedList<UndoRedoState> mStates = new LinkedList<UndoRedoState>();
|
|
|
|
const int UNDO_LIMIT = 250;
|
|
}
|
|
}
|