Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
UndoRedo
继承: Object
为实现撤销和重做操作提供高阶接口。
描述
UndoRedo 的原理是在“动作”中注册方法和属性的变化。你可以创建一个动作,然后提供执行(do)和撤销(undo)这个动作需要进行的函数调用和属性更改,然后提交该动作。
动作提交后就会执行所有 do_*
方法。如果使用 undo() 方法,那么就会执行 undo_*
方法。如果使用 redo() 方法,那么就会再次执行所有 do_*
方法。
以下是添加动作的示例:
var undo_redo = UndoRedo.new()
func do_something():
pass # 在此处编写你的代码。
func undo_something():
pass # 在此处编写恢复“do_something()”里所做事情的代码。
func _on_my_button_pressed():
var node = get_node("MyNode2D")
undo_redo.create_action("移动节点")
undo_redo.add_do_method(do_something)
undo_redo.add_undo_method(undo_something)
undo_redo.add_do_property(node, "position", Vector2(100,100))
undo_redo.add_undo_property(node, "position", node.position)
undo_redo.commit_action()
private UndoRedo _undoRedo;
public override void _Ready()
{
_undoRedo = new UndoRedo();
}
public void DoSomething()
{
// 在此处编写你的代码。
}
public void UndoSomething()
{
// 在此处编写恢复“DoSomething()”里所做事情的代码。
}
private void OnMyButtonPressed()
{
var node = GetNode<Node2D>("MyNode2D");
_undoRedo.CreateAction("移动节点");
_undoRedo.AddDoMethod(new Callable(this, MethodName.DoSomething));
_undoRedo.AddUndoMethod(new Callable(this, MethodName.UndoSomething));
_undoRedo.AddDoProperty(node, "position", new Vector2(100, 100));
_undoRedo.AddUndoProperty(node, "position", node.Position);
_undoRedo.CommitAction();
}
调用 add_(un)do_*
方法之前,你需要先调用 create_action()。调用之后则需要调用 commit_action()。
如果你不需要注册方法,则可以将 add_do_method() 和 add_undo_method() 省去;属性同理。你也可以注册多个方法/属性。
如果你要制作 EditorPlugin,希望集成编辑器的撤销历史,请改用 EditorUndoRedoManager。
如果你所注册的不同属性/方法之间有相互依赖,请注意默认情况下撤销操作的调用顺序和添加顺序是一致的。因此请不要将 do 操作和 undo 操作写在一起,最好还是和下面一样 do 和 do 一起写,undo 和 undo 一起写。
undo_redo.create_action("添加对象")
# DO
undo_redo.add_do_method(_create_object)
undo_redo.add_do_method(_add_object_to_singleton)
# UNDO
undo_redo.add_undo_method(_remove_object_from_singleton)
undo_redo.add_undo_method(_destroy_that_object)
undo_redo.commit_action()
_undo_redo.CreateAction("添加对象");
// DO
_undo_redo.AddDoMethod(new Callable(this, MethodName.CreateObject));
_undo_redo.AddDoMethod(new Callable(this, MethodName.AddObjectToSingleton));
// UNDO
_undo_redo.AddUndoMethod(new Callable(this, MethodName.RemoveObjectFromSingleton));
_undo_redo.AddUndoMethod(new Callable(this, MethodName.DestroyThatObject));
_undo_redo.CommitAction();
属性
|
方法
void |
add_do_method(callable: Callable) |
void |
add_do_property(object: Object, property: StringName, value: Variant) |
void |
add_do_reference(object: Object) |
void |
add_undo_method(callable: Callable) |
void |
add_undo_property(object: Object, property: StringName, value: Variant) |
void |
add_undo_reference(object: Object) |
void |
clear_history(increase_version: bool = true) |
void |
commit_action(execute: bool = true) |
void |
create_action(name: String, merge_mode: MergeMode = 0, backward_undo_ops: bool = false) |
void |
|
get_action_name(id: int) |
|
get_current_action_name() const |
|
get_version() const |
|
has_redo() const |
|
has_undo() const |
|
is_committing_action() const |
|
redo() |
|
void |
|
undo() |
信号
version_changed() 🔗
枚举
enum MergeMode: 🔗
MergeMode MERGE_DISABLE = 0
使“do”/“undo”操作保持在单独的动作中。
MergeMode MERGE_ENDS = 1
如果当前动作与上一个动作的名称相同,则将两者合并。仅保留第一个动作的“undo”操作和最后一个动作的“do”操作。适用于对单个值的连续更改。
MergeMode MERGE_ALL = 2
如果当前动作与上一个动作的名称相同,则将两者合并。
属性说明
撤销/重做历史中能够存储的最大步数。如果存储的步数超出了这个限制,就会将最早的步骤从历史中移除,无法再通过调用 undo() 到达。小于等于 0
表示没有限制。
方法说明
void add_do_method(callable: Callable) 🔗
注册 Callable,会在提交动作时调用。
void add_do_property(object: Object, property: StringName, value: Variant) 🔗
注册 property
,会在提交动作时将其值更改为 value
。
void add_do_reference(object: Object) 🔗
注册对象的引用,删除“do”历史时会擦除该引用。适用于“do”动作添加的对象和“undo”动作移除的对象。
删除“do”历史时,如果该对象为 RefCounted,则会解除引用。否则会执行释放。请勿用于资源。
var node = Node2D.new()
undo_redo.create_action("添加节点")
undo_redo.add_do_method(add_child.bind(node))
undo_redo.add_do_reference(node)
undo_redo.add_undo_method(remove_child.bind(node))
undo_redo.commit_action()
void add_undo_method(callable: Callable) 🔗
注册 Callable,会在撤销动作时调用。
void add_undo_property(object: Object, property: StringName, value: Variant) 🔗
注册 property
,会在撤销动作时将其值更改为 value
。
void add_undo_reference(object: Object) 🔗
注册对象的引用,删除“undo”历史时会擦除该引用。适用于“undo”动作添加的对象和“do”动作移除的对象。
删除“undo”历史时,如果该对象为 RefCounted,则会解除引用。否则会执行释放。请勿用于资源。
var node = $Node2D
undo_redo.create_action("移除节点")
undo_redo.add_do_method(remove_child.bind(node))
undo_redo.add_undo_method(add_child.bind(node))
undo_redo.add_undo_reference(node)
undo_redo.commit_action()
void clear_history(increase_version: bool = true) 🔗
清除撤销/重做历史和相关的引用。
将 false
传递给 increase_version
将防止在清除历史记录时增加版本号。
void commit_action(execute: bool = true) 🔗
提交动作。如果 execute
为 true
(默认情况),则会在调用此函数时调用/设置所有“执行(do)”方法/属性。
void create_action(name: String, merge_mode: MergeMode = 0, backward_undo_ops: bool = false) 🔗
创建一个新的动作。调用后,请执行所有你需要的 add_do_method()、add_undo_method()、add_do_property() 和 add_undo_property() 调用,然后再用 commit_action() 提交这个动作。
动作的合并方式由 merge_mode
决定。详见 MergeMode。
动作中撤销操作的顺序由 backward_undo_ops
决定。backward_undo_ops
为 false
时,撤销选项的顺序和添加顺序一致。也就是说,先添加的操作会先撤销。
void end_force_keep_in_merge_ends() 🔗
停止将操作标记为要处理,即使该动作在 MERGE_ENDS 模式下与另一个动作合并。请参阅 start_force_keep_in_merge_ends()。
String get_action_name(id: int) 🔗
根据索引获取动作名称。
获取当前动作的索引。
String get_current_action_name() const 🔗
获取当前动作的名称,等价于 get_action_name(get_current_action())
。
返回历史中有多少元素。
获取版本。每次提交一个新的操作,UndoRedo 的版本号都会自动增加。
这主要用于检查保存的版本是否发生了更改。
有“重做”动作可用时返回 true
。
有“撤销”动作可用时返回 true
。
bool is_committing_action() const 🔗
如果 UndoRedo 当前正在提交动作,即运行其“do”的方法或属性变化,则返回 true
(请参阅 commit_action())。
重做上一个动作。
void start_force_keep_in_merge_ends() 🔗
标记要处理的下一个“执行”和“撤消”操作,即使该动作在 MERGE_ENDS 模式下与另一个动作合并。使用 end_force_keep_in_merge_ends() 返回到正常操作。
撤销上一个动作。