博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Undo
阅读量:6706 次
发布时间:2019-06-25

本文共 5589 字,大约阅读时间需要 18 分钟。

1.  redo和undo的实现

  知道执行了什么命令,影响了那些数据
  终止条件和状态

2.  这里我犯了个错误,其实我根本不需要知道是执行的什么命令,对于绘图系统,我只需知道对数据产生了那些影响。撤销和重做其实都是针对数据(几何对象)来说的。

所有这里只需要在操作(添加几何对象、删除几何对象、修改几何对象、增加节点、删除节点、移动节点等)时另外引一条线,就是UndoRedoBuffer对象,他是一个List,其实如果是栈则更好,用它记录操作影响的数据。注意是操作影响的数据,和上面所说的操作是两个概念。

抽象了一个操作影响数据的EditCommandBase类,具体子类有:添加影响数据类,删除影响数据类、移动影响数据类。

在每一次修改Canvas对象的几何对象集合时都要引出一条线,记录这个操作影响数据信息,即加入UndoRedoBuffer。

Undo就是UndoRedoBuffer顶部的影响数据修改几何对象集合,实现回退。

1 using System;  2 using System.Collections.Generic;  3 using System.Text;  4 using System.Drawing;  5   6 namespace Canvas  7 {  8     class EditCommandBase  9     { 10         public virtual bool DoUndo(IModel data) 11         { 12             return false; 13         } 14         public virtual bool DoRedo(IModel data) 15         { 16             return false; 17         } 18     } 19     class EditCommandAdd : EditCommandBase 20     { 21         List
m_objects = null; 22 IDrawObject m_object; 23 ICanvasLayer m_layer; 24 public EditCommandAdd(ICanvasLayer layer, IDrawObject obj) 25 { 26 m_object = obj; 27 m_layer = layer; 28 } 29 public EditCommandAdd(ICanvasLayer layer, List
objects) 30 { 31 m_objects = new List
(objects); 32 m_layer = layer; 33 } 34 public override bool DoUndo(IModel data) 35 { 36 if (m_object != null) 37 data.DeleteObjects(new IDrawObject[] { m_object }); 38 if (m_objects != null) 39 data.DeleteObjects(m_objects); 40 return true; 41 } 42 public override bool DoRedo(IModel data) 43 { 44 if (m_object != null) 45 data.AddObject(m_layer, m_object); 46 if (m_objects != null) 47 { 48 foreach (IDrawObject obj in m_objects) 49 data.AddObject(m_layer, obj); 50 } 51 return true; 52 } 53 } 54 class EditCommandRemove : EditCommandBase 55 { 56 Dictionary
> m_objects = new Dictionary
>(); 57 public EditCommandRemove() 58 { 59 } 60 public void AddLayerObjects(ICanvasLayer layer, List
objects) 61 { 62 m_objects.Add(layer, objects); 63 } 64 public override bool DoUndo(IModel data) 65 { 66 foreach (ICanvasLayer layer in m_objects.Keys) 67 { 68 foreach (IDrawObject obj in m_objects[layer]) 69 data.AddObject(layer, obj); 70 } 71 return true; 72 } 73 public override bool DoRedo(IModel data) 74 { 75 foreach (ICanvasLayer layer in m_objects.Keys) 76 data.DeleteObjects(m_objects[layer]); 77 return true; 78 } 79 } 80 class EditCommandMove : EditCommandBase 81 { 82 List
m_objects = new List
(); 83 UnitPoint m_offset; 84 public EditCommandMove(UnitPoint offset, IEnumerable
objects) 85 { 86 m_objects = new List
(objects); 87 m_offset = offset; 88 } 89 public override bool DoUndo(IModel data) 90 { 91 foreach (IDrawObject obj in m_objects) 92 { 93 UnitPoint offset = new UnitPoint(-m_offset.X, -m_offset.Y); 94 obj.Move(offset); 95 } 96 return true; 97 } 98 public override bool DoRedo(IModel data) 99 {100 foreach (IDrawObject obj in m_objects)101 obj.Move(m_offset);102 return true;103 }104 }105 class EditCommandNodeMove : EditCommandBase106 {107 List
m_objects = new List
();108 public EditCommandNodeMove(IEnumerable
objects)109 {110 m_objects = new List
(objects);111 }112 public override bool DoUndo(IModel data)113 {114 foreach (INodePoint obj in m_objects)115 obj.Undo();116 return true;117 }118 public override bool DoRedo(IModel data)119 {120 foreach (INodePoint obj in m_objects)121 obj.Redo();122 return true;123 }124 }125 class EditCommandEditTool : EditCommandBase126 {127 IEditTool m_tool;128 public EditCommandEditTool(IEditTool tool)129 {130 m_tool = tool;131 }132 public override bool DoUndo(IModel data)133 {134 m_tool.Undo();135 return true;136 }137 public override bool DoRedo(IModel data)138 {139 m_tool.Redo();140 return true;141 }142 }143 class UndoRedoBuffer144 {145 List
m_undoBuffer = new List
();146 List
m_redoBuffer = new List
();147 bool m_canCapture = true;148 bool m_dirty = false;149 public UndoRedoBuffer()150 {151 }152 public void Clear()153 {154 m_undoBuffer.Clear();155 m_redoBuffer.Clear();156 }157 public bool Dirty158 {159 get { return m_dirty; }160 set { m_dirty = value;}161 }162 public bool CanCapture163 {164 get { return m_canCapture; }165 }166 public bool CanUndo167 {168 get { return m_undoBuffer.Count > 0; }169 }170 public bool CanRedo171 {172 get { return m_redoBuffer.Count > 0; }173 }174 public void AddCommand(EditCommandBase command)175 {176 if (m_canCapture && command != null)177 {178 m_undoBuffer.Add(command);179 m_redoBuffer.Clear();180 Dirty = true;181 }182 }183 public bool DoUndo(IModel data)184 {185 if (m_undoBuffer.Count == 0)186 return false;187 m_canCapture = false;188 EditCommandBase command = m_undoBuffer[m_undoBuffer.Count - 1];189 bool result = command.DoUndo(data);190 m_undoBuffer.RemoveAt(m_undoBuffer.Count - 1);191 m_redoBuffer.Add(command);192 m_canCapture = true;193 Dirty = true;194 return result;195 }196 public bool DoRedo(IModel data)197 {198 if (m_redoBuffer.Count == 0)199 return false;200 m_canCapture = false;201 EditCommandBase command = m_redoBuffer[m_redoBuffer.Count - 1];202 bool result = command.DoRedo(data);203 m_redoBuffer.RemoveAt(m_redoBuffer.Count - 1);204 m_undoBuffer.Add(command);205 m_canCapture = true;206 Dirty = true;207 return result;208 }209 }210 }

 

转载地址:http://hkflo.baihongyu.com/

你可能感兴趣的文章
css实现图片背景填充的正六边形
查看>>
Android反编译及破解API协议 记录1
查看>>
LocalBroadcastManager源码剖析
查看>>
一款Android App升级库
查看>>
Matrix源码分析————IO Canary
查看>>
Binder机制
查看>>
JS原型相关
查看>>
手把手教你使用Js实现前后台传送Json
查看>>
2018年规划
查看>>
关于行框盒子与vertical-align(一)
查看>>
修复苹果iOS 原生键盘遮挡input框
查看>>
学习编程,只跟对的人
查看>>
AQS源码详解
查看>>
AndroidSerialPort:安卓串口通信库
查看>>
咦,Oreo怎么收不到广播了?
查看>>
spring-控制反转IoC
查看>>
spring cloud微服务分布式云架构(三)-服务消费者(Feign)
查看>>
区块链软件公司:区块链的金融化体系
查看>>
常用的几个设计心理学
查看>>
Target runtime Apache Tomcat v6.0 is not defined.错误解决方法
查看>>