软件中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

 

转载于:https://www.cnblogs.com/hghhe/p/9669107.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值