Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs
2023-03-26 23:23:34 +08:00

167 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AIStudio.Wpf.DiagramDesigner
{
public class DoCommandManager
{
#region Command定义
public class Command
{
string name;
Action action;
Action unDoAction;
Action clearAction;
internal Command(string name, Action action, Action unDoAction, Action clearAction)
{
this.name = name;
this.action = action;
this.unDoAction = unDoAction;
this.clearAction = clearAction;
}
internal void Do()
{
action();
}
internal void UnDo()
{
unDoAction();
}
internal void Clear()
{
if (clearAction != null) clearAction();
}
public override string ToString()
{
return name.ToString();
}
}
#endregion
public Stack<Command> ReDoActionStack
{
get; private set;
}
public Stack<Command> UnDoActionStack
{
get; private set;
}
public int Capacity { get; set; } = 100;
public DoCommandManager()
{
Init();
}
public void Init()
{
ReDoActionStack = new Stack<Command>();
UnDoActionStack = new Stack<Command>();
}
public bool BeginDo
{
get;set;
}
private bool _undoing;
public void DoNewCommand(string name, Action action, Action unDoAction, Action clearAction = null, bool doit = true)
{
if (BeginDo == true)
return;
if (_undoing == true)
return;
try
{
_undoing = true;
if (UnDoActionStack.Count >= Capacity)
{
//清理
var clear = UnDoActionStack.LastOrDefault();
clear.Clear();
UnDoActionStack = new Stack<Command>(UnDoActionStack.Take(Capacity - 1).Reverse());
}
var cmd = new Command(name, action, unDoAction, clearAction);
UnDoActionStack.Push(cmd);
ReDoActionStack.Clear();
if (doit)
{
cmd.Do();
}
}
finally
{
_undoing = false;
}
}
public void UnDo()
{
if (!CanUnDo)
return;
if (_undoing == true)
return;
try
{
_undoing = true;
var cmd = UnDoActionStack.Pop();
ReDoActionStack.Push(cmd);
cmd.UnDo();
}
finally
{
_undoing = false;
}
}
public void ReDo()
{
if (!CanReDo)
return;
if (_undoing == true)
return;
try
{
_undoing = true;
var cmd = ReDoActionStack.Pop();
UnDoActionStack.Push(cmd);
cmd.Do();
}
finally
{
_undoing = false;
}
}
public bool CanUnDo
{
get
{
return UnDoActionStack.Count != 0;
}
}
public bool CanReDo
{
get
{
return ReDoActionStack.Count != 0;
}
}
//public IEnumerable<Command> Actions { get { return ReDoActionStack.Reverse().Concat(UnDoActionStack); } }
}
}