我正在做一个图像编辑器,有点自得其乐,想知道我怎么才能做一个撤销按钮来撤销我上一次所做的画?我想知道我会如何看待这一点,一个教程或示例代码会很好,或者至少是为我指明了正确的方向。
谢谢!
发布于 2010-05-28 02:29:44
嘿,撤销真的不像听起来那么难。这里的神奇之处在于,您应该将每个操作记录为绘制在列表或队列中的对象,f.ex,用户绘制一条线,因此您的记录可能看起来像x,y的起始点,以及具有方法Draw()的终结点或对象本身的x,y,所以撤消操作只会删除该对象。
在代码中可能看起来像这样:
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.发布于 2010-05-28 02:08:40
http://en.wikipedia.org/wiki/Command_pattern
命令对象对于实现以下功能非常有用:
多级撤消如果程序中的所有用户操作都作为命令对象实现,则程序可以保留最近执行的命令的堆栈。当用户想要撤销一个命令时,程序只是弹出最近的命令对象并执行它的undo()方法。
编辑:放在正确的角度,如果我要解决这个问题,我会做的是记录用户喜欢的每个“动作”,画一条线等作为命令,并在将其应用于绘图上下文之前,在该命令中存储完成该动作的所有相关信息。
因此,每个操作都被推送到堆栈上,这样您就可以弹出项目。
为了加快速度,我可能还会考虑记录一系列操作的绘图对象的状态。因为它是绘图的上下文,所以从已知的绘图状态开始并重新应用命令来创建当前版本可能会更容易。
因此,作为一个例子,我将有一个运行的命令堆栈和一个运行的绘图对象堆栈。每5个命令,我会把绘制对象的状态推到它的堆栈上,所以当用户按下撤销时,我会抓取绘制对象的顶部状态,并将最新的命令应用到对象上,只保留最后一个。要撤消10个操作,我将返回绘图对象的2个状态,并且不需要对其应用任何新命令。
你很可能想要限制在你的程序中可以做的撤销/重做状态的深度,否则它将在内存中无限增长。
发布于 2010-05-28 02:08:55
一种基本的方法是保留一个Stack,它将保存您所做的每一个新的笔画。
当你点击undo按钮时,弹出堆栈并撤销你的更改(取决于你的应用程序的具体情况,可以通过重新绘制背景颜色来购买吗?)
https://stackoverflow.com/questions/2923626
复制相似问题