zoukankan      html  css  js  c++  java
  • 软件中Undo(撤回)和Redo(重做)的实现

      在一般软件中,都会有Undo和Redo的功能,那么这个功能该怎么实现呢?在此介绍一种实现方法。(以lua语言为例)

      1. 操作事件化。将用户的操作转换成一个事件数据,里面包括事件类型、操作目标、目标原始状态、操作后状态等。比如:

    -- 移动某结点可转换为
    local moveEvent = {event = "Move", target = "selectNode", orginPos = cc.p(0, 0), endPos = cc.p(100, 100)}
    -- 新建结点可转换为
    local newEvent = {event = "Delete", name = "bgSprite"}

      2. 事件处理与存储。新建一个类EventManager,用于存储所有的操作事件。在用户操作时并不直接执行对应的处理,而是将操作命令发给EventManager进行统一的处理。EventManager大致像这样:

    -- eventList:存储用户操作的事件列表
    -- statusIndex: 当前软件的执行事件位置
    -- saveIndex: 当前软件的保存事件位置
    EventManager = {eventList = {}, statusIndex = 0}
    -- 新加事件
    function EventManager:doEvent(cmd)
        -- 执行真正的操作变化
        UIController:doEvent(cmd)
    
        -- 将当前操作位置之后的抛弃,statusIndex在发生Redo后将不再是列表长度
        for i=#self.eventList, (self.statusIndex + 1), -1 do
            table.remove(self.eventList, i)
        end
        -- 加入事件队列
        table.insert(self.eventList, cmd)
        self.statusIndex = #self.eventList
    end

    用户撤回(Undo)时,需要将上一个事件转换为撤回事件,如上文的moveEvent可转换为:

    {event = "Move", target = "selectNode", orginPos = cc.p(100, 100), endPos = cc.p(0, 0)}

    newEvent可转换为:

    {event = "Delete", name = "bgSprite"}

    具体undo方法大致如下:

    -- 撤回操作
    function EventManager:undo()
        if self.statusIndex > 0 then
            -- 获取撤回事件,依事件情况实现
            local undoCmd = self:getUndoCmd(self.eventList[self.statusIndex])
            self.statusIndex = self.statusIndex - 1
    
            -- 执行真正的操作变化
            UIController:doEvent(undoCmd)
        end
    end

    redo方法就比较简单了,只需将存储的事件再次执行即可:

    -- 重做
    function EventManager:redo()
        if self.statusIndex < #self.eventList then
            self.statusIndex = self.statusIndex + 1
            local redoCmd = self.eventList[self.statusIndex]
    
            -- 执行真正的操作变化
            UIController:doEvent(redoCmd)
        end
    end

       以上我们就实现了操作的Undo和Redo功能。基于此我们可以引出另外一个功能:在软件中标注当前的修改状态,如图。我们只需要在EventManager中添加一个变量saveIndex来标记当前的保存位置。当saveIndex==statusIndex时表示当前状态已保存,否则当前的修改未保存。需要在doEvent/undo/redo方法中刷新软件标题的显示状态。当用户保存时,则重置saveIndex的位置:

    function EventManager:save()
        self.saveIndex = self.statusIndex
        -- 重置软件的标题
        fc.SetWindowTitle("fcediter")
    end

  • 相关阅读:
    tar命令,vi编辑器
    Linux命令、权限
    Color Transfer between Images code实现
    利用Eclipse使用Java OpenCV(Using OpenCV Java with Eclipse)
    Matrix Factorization SVD 矩阵分解
    ZOJ Problem Set
    Machine Learning
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/hghhe/p/9669107.html
Copyright © 2011-2022 走看看