zoukankan      html  css  js  c++  java
  • Undo

    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<IDrawObject> 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<IDrawObject> objects)
     30         {
     31             m_objects = new List<IDrawObject>(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<ICanvasLayer, List<IDrawObject>> m_objects = new Dictionary<ICanvasLayer, List<IDrawObject>>();
     57         public EditCommandRemove()
     58         {
     59         }
     60         public void AddLayerObjects(ICanvasLayer layer, List<IDrawObject> 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<IDrawObject> m_objects = new List<IDrawObject>();
     83         UnitPoint m_offset;
     84         public EditCommandMove(UnitPoint offset, IEnumerable<IDrawObject> objects)
     85         {
     86             m_objects = new List<IDrawObject>(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 : EditCommandBase
    106     {
    107         List<INodePoint> m_objects = new List<INodePoint>();
    108         public EditCommandNodeMove(IEnumerable<INodePoint> objects)
    109         {
    110             m_objects = new List<INodePoint>(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 : EditCommandBase
    126     {
    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 UndoRedoBuffer
    144     {
    145         List<EditCommandBase> m_undoBuffer = new List<EditCommandBase>();
    146         List<EditCommandBase> m_redoBuffer = new List<EditCommandBase>();
    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 Dirty
    158         {
    159             get { return m_dirty; }
    160             set { m_dirty = value;}
    161         }
    162         public bool CanCapture
    163         {
    164             get { return m_canCapture; }
    165         }
    166         public bool CanUndo
    167         {
    168             get { return m_undoBuffer.Count > 0; }
    169         }
    170         public bool CanRedo
    171         {
    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 }

     

  • 相关阅读:
    t=20点击发送pingback
    Hibernate 序列生成主键
    oracle创建存储过程
    mysql允许某ip访问
    ORACLE用户解锁
    oracle查询锁表
    oracle杀掉执行的死循环存储过程
    oracle以逗号分隔查询结果列表
    查询oracle的session数
    oracle存储过程-获取错误信息
  • 原文地址:https://www.cnblogs.com/yhlx125/p/3224979.html
Copyright © 2011-2022 走看看