我正在制作一个图像编辑器,有点为了自己的乐趣,我想知道如何制作一个撤消按钮来撤消我所做的最后一次绘画?我想知道我会怎么做,教程或示例代码会很好,或者至少可以为我指明正确的方向。
谢谢!
我正在制作一个图像编辑器,有点为了自己的乐趣,我想知道如何制作一个撤消按钮来撤消我所做的最后一次绘画?我想知道我会怎么做,教程或示例代码会很好,或者至少可以为我指明正确的方向。
谢谢!
嘿撤消真的没有听起来那么难。这里的神奇之处在于您应该将每个动作记录为绘制在列表或队列中的对象,f.ex,用户画一条线,因此您的记录可能看起来像开始点的 x,y 和终点的 x,y 或对象它自己具有方法 Draw(),所以撤消将只删除该对象。
在看起来像这样的代码中:
interface IDrawObject
{
public void Draw();
}
class Line : IDrawObject
{
private Point _startP;
private Point _endP;
public Line(Point startPoint; Poing endPoint)
{
_startP = startPoint;
_endP = endPoint;
}
public void Draw()
{
//* call some generic draw processor to perform the action with your given parameters.
}
}
class Rectangle : IDrawObject
{
//* your code.
public void Draw()
{
//* call some generic draw processor to perform the action with your given parameters.
}
}
//* then in your code, you could have something like this.
List<IDrawObject> myObjectsINeedToDraw = new List<IDrawObject>();
myObjectsINeedToDraw.Add(new Line(new Point(0, 0), new Point(10, 10));
foreach(IDrawObject objectToDraw in myObjectsINeedToDraw)
{
//* will draw your object.
objectToDraw.Draw();
}
//* in this way you will have unlimited history of your objects, and you will always can remove object from that list.
http://en.wikipedia.org/wiki/Command_pattern
命令对象可用于实现:
多级撤消 如果程序中的所有用户操作都实现为命令对象,则程序可以保留最近执行的命令的堆栈。当用户想要撤消命令时,程序只需弹出最近的命令对象并执行其 undo() 方法。
编辑:为了透视这将如何有用如果我要解决这个问题,我会做的是记录用户所做的每个“动作”,比如画一条线等作为命令,并存储有关在里面完成该动作的所有相关信息该命令在将其应用于绘图上下文之前。
所以每个动作都被压入堆栈,这样你就可以弹出项目。
为了提高速度,我可能还会考虑记录绘图对象的状态以进行一系列操作。由于它是绘图的上下文,因此从已知的绘图状态开始并重新应用命令来创建当前版本可能会更容易。
例如,我将有一个正在运行的命令堆栈和一个正在运行的绘图对象堆栈。每 5 个命令我会将绘图对象的状态推送到它的堆栈上,因此当用户按下撤消时,我将获取绘图对象的顶部状态并将最新命令应用于对象保存最后一个。要撤消 10 个操作,我将返回绘图对象的 2 个状态,并且不需要对其应用任何新命令。
您很可能希望限制您可以在程序中执行的撤消/重做状态的深度,否则它将在内存中无限增长。
一种基本方法是保留一个堆栈,以容纳您所做的每一个新笔触。
当您点击撤消按钮时,弹出堆栈并反转您的更改(取决于您的应用程序的具体情况,是否可以通过重新绘制背景颜色来购买?)