Files
godot-docs-l10n/classes/zh_Hans/class_undoredo.rst

556 lines
26 KiB
ReStructuredText
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

:github_url: hide
.. _class_UndoRedo:
UndoRedo
========
**继承:** :ref:`Object<class_Object>`
为实现撤销和重做操作提供高阶接口。
.. rst-class:: classref-introduction-group
描述
----
UndoRedo 的原理是在“动作”中注册方法和属性的变化。你可以创建一个动作然后提供执行do和撤销undo这个动作需要进行的函数调用和属性更改然后提交该动作。
动作提交后就会执行所有 ``do_*`` 方法。如果使用 :ref:`undo()<class_UndoRedo_method_undo>` 方法,那么就会执行 ``undo_*`` 方法。如果使用 :ref:`redo()<class_UndoRedo_method_redo>` 方法,那么就会再次执行所有 ``do_*`` 方法。
以下是添加动作的示例:
.. tabs::
.. code-tab:: gdscript
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()
.. code-tab:: csharp
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_*`` 方法之前,你需要先调用 :ref:`create_action()<class_UndoRedo_method_create_action>`\ 。调用之后则需要调用 :ref:`commit_action()<class_UndoRedo_method_commit_action>`\ 。
如果你不需要注册方法,则可以将 :ref:`add_do_method()<class_UndoRedo_method_add_do_method>`:ref:`add_undo_method()<class_UndoRedo_method_add_undo_method>` 省去;属性同理。你也可以注册多个方法/属性。
如果你要制作 :ref:`EditorPlugin<class_EditorPlugin>`\ ,希望集成编辑器的撤销历史,请改用 :ref:`EditorUndoRedoManager<class_EditorUndoRedoManager>`\ 。
如果你所注册的不同属性/方法之间有相互依赖,请注意默认情况下撤销操作的调用顺序和添加顺序是一致的。因此请不要将 do 操作和 undo 操作写在一起,最好还是和下面一样 do 和 do 一起写undo 和 undo 一起写。
.. tabs::
.. code-tab:: gdscript
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()
.. code-tab:: csharp
_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();
.. rst-class:: classref-reftable-group
属性
----
.. table::
:widths: auto
+-----------------------+-----------------------------------------------------+-------+
| :ref:`int<class_int>` | :ref:`max_steps<class_UndoRedo_property_max_steps>` | ``0`` |
+-----------------------+-----------------------------------------------------+-------+
.. rst-class:: classref-reftable-group
方法
----
.. table::
:widths: auto
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`add_do_method<class_UndoRedo_method_add_do_method>`\ (\ callable\: :ref:`Callable<class_Callable>`\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`add_do_property<class_UndoRedo_method_add_do_property>`\ (\ object\: :ref:`Object<class_Object>`, property\: :ref:`StringName<class_StringName>`, value\: :ref:`Variant<class_Variant>`\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`add_do_reference<class_UndoRedo_method_add_do_reference>`\ (\ object\: :ref:`Object<class_Object>`\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`add_undo_method<class_UndoRedo_method_add_undo_method>`\ (\ callable\: :ref:`Callable<class_Callable>`\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`add_undo_property<class_UndoRedo_method_add_undo_property>`\ (\ object\: :ref:`Object<class_Object>`, property\: :ref:`StringName<class_StringName>`, value\: :ref:`Variant<class_Variant>`\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`add_undo_reference<class_UndoRedo_method_add_undo_reference>`\ (\ object\: :ref:`Object<class_Object>`\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`clear_history<class_UndoRedo_method_clear_history>`\ (\ increase_version\: :ref:`bool<class_bool>` = true\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`commit_action<class_UndoRedo_method_commit_action>`\ (\ execute\: :ref:`bool<class_bool>` = true\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`create_action<class_UndoRedo_method_create_action>`\ (\ name\: :ref:`String<class_String>`, merge_mode\: :ref:`MergeMode<enum_UndoRedo_MergeMode>` = 0, backward_undo_ops\: :ref:`bool<class_bool>` = false\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`end_force_keep_in_merge_ends<class_UndoRedo_method_end_force_keep_in_merge_ends>`\ (\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`String<class_String>` | :ref:`get_action_name<class_UndoRedo_method_get_action_name>`\ (\ id\: :ref:`int<class_int>`\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`get_current_action<class_UndoRedo_method_get_current_action>`\ (\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`String<class_String>` | :ref:`get_current_action_name<class_UndoRedo_method_get_current_action_name>`\ (\ ) |const| |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`get_history_count<class_UndoRedo_method_get_history_count>`\ (\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`get_version<class_UndoRedo_method_get_version>`\ (\ ) |const| |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`bool<class_bool>` | :ref:`has_redo<class_UndoRedo_method_has_redo>`\ (\ ) |const| |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`bool<class_bool>` | :ref:`has_undo<class_UndoRedo_method_has_undo>`\ (\ ) |const| |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`bool<class_bool>` | :ref:`is_committing_action<class_UndoRedo_method_is_committing_action>`\ (\ ) |const| |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`bool<class_bool>` | :ref:`redo<class_UndoRedo_method_redo>`\ (\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |void| | :ref:`start_force_keep_in_merge_ends<class_UndoRedo_method_start_force_keep_in_merge_ends>`\ (\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`bool<class_bool>` | :ref:`undo<class_UndoRedo_method_undo>`\ (\ ) |
+-----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
.. rst-class:: classref-section-separator
----
.. rst-class:: classref-descriptions-group
信号
----
.. _class_UndoRedo_signal_version_changed:
.. rst-class:: classref-signal
**version_changed**\ (\ ) :ref:`🔗<class_UndoRedo_signal_version_changed>`
:ref:`undo()<class_UndoRedo_method_undo>`:ref:`redo()<class_UndoRedo_method_redo>` 被调用时调用。
.. rst-class:: classref-section-separator
----
.. rst-class:: classref-descriptions-group
枚举
----
.. _enum_UndoRedo_MergeMode:
.. rst-class:: classref-enumeration
enum **MergeMode**: :ref:`🔗<enum_UndoRedo_MergeMode>`
.. _class_UndoRedo_constant_MERGE_DISABLE:
.. rst-class:: classref-enumeration-constant
:ref:`MergeMode<enum_UndoRedo_MergeMode>` **MERGE_DISABLE** = ``0``
使“do”/“undo”操作保持在单独的动作中。
.. _class_UndoRedo_constant_MERGE_ENDS:
.. rst-class:: classref-enumeration-constant
:ref:`MergeMode<enum_UndoRedo_MergeMode>` **MERGE_ENDS** = ``1``
如果当前动作与上一个动作的名称相同则将两者合并。仅保留第一个动作的“undo”操作和最后一个动作的“do”操作。适用于对单个值的连续更改。
.. _class_UndoRedo_constant_MERGE_ALL:
.. rst-class:: classref-enumeration-constant
:ref:`MergeMode<enum_UndoRedo_MergeMode>` **MERGE_ALL** = ``2``
如果当前动作与上一个动作的名称相同,则将两者合并。
.. rst-class:: classref-section-separator
----
.. rst-class:: classref-descriptions-group
属性说明
--------
.. _class_UndoRedo_property_max_steps:
.. rst-class:: classref-property
:ref:`int<class_int>` **max_steps** = ``0`` :ref:`🔗<class_UndoRedo_property_max_steps>`
.. rst-class:: classref-property-setget
- |void| **set_max_steps**\ (\ value\: :ref:`int<class_int>`\ )
- :ref:`int<class_int>` **get_max_steps**\ (\ )
撤销/重做历史中能够存储的最大步数。如果存储的步数超出了这个限制,就会将最早的步骤从历史中移除,无法再通过调用 :ref:`undo()<class_UndoRedo_method_undo>` 到达。小于等于 ``0`` 表示没有限制。
.. rst-class:: classref-section-separator
----
.. rst-class:: classref-descriptions-group
方法说明
--------
.. _class_UndoRedo_method_add_do_method:
.. rst-class:: classref-method
|void| **add_do_method**\ (\ callable\: :ref:`Callable<class_Callable>`\ ) :ref:`🔗<class_UndoRedo_method_add_do_method>`
注册 :ref:`Callable<class_Callable>`\ ,会在提交动作时调用。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_add_do_property:
.. rst-class:: classref-method
|void| **add_do_property**\ (\ object\: :ref:`Object<class_Object>`, property\: :ref:`StringName<class_StringName>`, value\: :ref:`Variant<class_Variant>`\ ) :ref:`🔗<class_UndoRedo_method_add_do_property>`
注册 ``property``\ ,会在提交动作时将其值更改为 ``value``\ 。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_add_do_reference:
.. rst-class:: classref-method
|void| **add_do_reference**\ (\ object\: :ref:`Object<class_Object>`\ ) :ref:`🔗<class_UndoRedo_method_add_do_reference>`
注册对象的引用删除“do”历史时会擦除该引用。适用于“do”动作添加的对象和“undo”动作移除的对象。
删除“do”历史时如果该对象为 :ref:`RefCounted<class_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()
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_add_undo_method:
.. rst-class:: classref-method
|void| **add_undo_method**\ (\ callable\: :ref:`Callable<class_Callable>`\ ) :ref:`🔗<class_UndoRedo_method_add_undo_method>`
注册 :ref:`Callable<class_Callable>`\ ,会在撤销动作时调用。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_add_undo_property:
.. rst-class:: classref-method
|void| **add_undo_property**\ (\ object\: :ref:`Object<class_Object>`, property\: :ref:`StringName<class_StringName>`, value\: :ref:`Variant<class_Variant>`\ ) :ref:`🔗<class_UndoRedo_method_add_undo_property>`
注册 ``property``\ ,会在撤销动作时将其值更改为 ``value``\ 。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_add_undo_reference:
.. rst-class:: classref-method
|void| **add_undo_reference**\ (\ object\: :ref:`Object<class_Object>`\ ) :ref:`🔗<class_UndoRedo_method_add_undo_reference>`
注册对象的引用删除“undo”历史时会擦除该引用。适用于“undo”动作添加的对象和“do”动作移除的对象。
删除“undo”历史时如果该对象为 :ref:`RefCounted<class_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()
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_clear_history:
.. rst-class:: classref-method
|void| **clear_history**\ (\ increase_version\: :ref:`bool<class_bool>` = true\ ) :ref:`🔗<class_UndoRedo_method_clear_history>`
清除撤销/重做历史和相关的引用。
``false`` 传递给 ``increase_version`` 将防止在清除历史记录时增加版本号。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_commit_action:
.. rst-class:: classref-method
|void| **commit_action**\ (\ execute\: :ref:`bool<class_bool>` = true\ ) :ref:`🔗<class_UndoRedo_method_commit_action>`
提交动作。如果 ``execute````true``\ (默认情况),则会在调用此函数时调用/设置所有“执行do”方法/属性。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_create_action:
.. rst-class:: classref-method
|void| **create_action**\ (\ name\: :ref:`String<class_String>`, merge_mode\: :ref:`MergeMode<enum_UndoRedo_MergeMode>` = 0, backward_undo_ops\: :ref:`bool<class_bool>` = false\ ) :ref:`🔗<class_UndoRedo_method_create_action>`
创建一个新的动作。调用后,请执行所有你需要的 :ref:`add_do_method()<class_UndoRedo_method_add_do_method>`\ 、\ :ref:`add_undo_method()<class_UndoRedo_method_add_undo_method>`\ 、\ :ref:`add_do_property()<class_UndoRedo_method_add_do_property>` 和 :ref:`add_undo_property()<class_UndoRedo_method_add_undo_property>` 调用,然后再用 :ref:`commit_action()<class_UndoRedo_method_commit_action>` 提交这个动作。
动作的合并方式由 ``merge_mode`` 决定。
动作中撤销操作的顺序由 ``backward_undo_ops`` 决定。\ ``backward_undo_ops````false`` 时,撤销选项的顺序和添加顺序一致。也就是说,先添加的操作会先撤销。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_end_force_keep_in_merge_ends:
.. rst-class:: classref-method
|void| **end_force_keep_in_merge_ends**\ (\ ) :ref:`🔗<class_UndoRedo_method_end_force_keep_in_merge_ends>`
停止将操作标记为要处理,即使该动作在 :ref:`MERGE_ENDS<class_UndoRedo_constant_MERGE_ENDS>` 模式下与另一个动作合并。请参阅 :ref:`start_force_keep_in_merge_ends()<class_UndoRedo_method_start_force_keep_in_merge_ends>`\ 。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_get_action_name:
.. rst-class:: classref-method
:ref:`String<class_String>` **get_action_name**\ (\ id\: :ref:`int<class_int>`\ ) :ref:`🔗<class_UndoRedo_method_get_action_name>`
根据索引获取动作名称。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_get_current_action:
.. rst-class:: classref-method
:ref:`int<class_int>` **get_current_action**\ (\ ) :ref:`🔗<class_UndoRedo_method_get_current_action>`
获取当前动作的索引。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_get_current_action_name:
.. rst-class:: classref-method
:ref:`String<class_String>` **get_current_action_name**\ (\ ) |const| :ref:`🔗<class_UndoRedo_method_get_current_action_name>`
获取当前动作的名称,等价于 ``get_action_name(get_current_action())``\ 。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_get_history_count:
.. rst-class:: classref-method
:ref:`int<class_int>` **get_history_count**\ (\ ) :ref:`🔗<class_UndoRedo_method_get_history_count>`
返回历史中有多少元素。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_get_version:
.. rst-class:: classref-method
:ref:`int<class_int>` **get_version**\ (\ ) |const| :ref:`🔗<class_UndoRedo_method_get_version>`
获取版本。每次提交一个新的操作,\ **UndoRedo** 的版本号都会自动增加。
这主要用于检查保存的版本是否发生了更改。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_has_redo:
.. rst-class:: classref-method
:ref:`bool<class_bool>` **has_redo**\ (\ ) |const| :ref:`🔗<class_UndoRedo_method_has_redo>`
有“重做”动作可用时返回 ``true``\ 。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_has_undo:
.. rst-class:: classref-method
:ref:`bool<class_bool>` **has_undo**\ (\ ) |const| :ref:`🔗<class_UndoRedo_method_has_undo>`
有“撤销”动作可用时返回 ``true``\ 。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_is_committing_action:
.. rst-class:: classref-method
:ref:`bool<class_bool>` **is_committing_action**\ (\ ) |const| :ref:`🔗<class_UndoRedo_method_is_committing_action>`
如果 **UndoRedo** 当前正在提交动作即运行其“do”的方法或属性变化则返回 ``true``\ (请参阅 :ref:`commit_action()<class_UndoRedo_method_commit_action>`\ )。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_redo:
.. rst-class:: classref-method
:ref:`bool<class_bool>` **redo**\ (\ ) :ref:`🔗<class_UndoRedo_method_redo>`
重做上一个动作。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_start_force_keep_in_merge_ends:
.. rst-class:: classref-method
|void| **start_force_keep_in_merge_ends**\ (\ ) :ref:`🔗<class_UndoRedo_method_start_force_keep_in_merge_ends>`
标记要处理的下一个“执行”和“撤消”操作,即使该动作在 :ref:`MERGE_ENDS<class_UndoRedo_constant_MERGE_ENDS>` 模式下与另一个动作合并。使用 :ref:`end_force_keep_in_merge_ends()<class_UndoRedo_method_end_force_keep_in_merge_ends>` 返回到正常操作。
.. rst-class:: classref-item-separator
----
.. _class_UndoRedo_method_undo:
.. rst-class:: classref-method
:ref:`bool<class_bool>` **undo**\ (\ ) :ref:`🔗<class_UndoRedo_method_undo>`
撤销上一个动作。
.. |virtual| replace:: :abbr:`virtual (本方法通常需要用户覆盖才能生效。)`
.. |required| replace:: :abbr:`required (This method is required to be overridden when extending its base class.)`
.. |const| replace:: :abbr:`const (本方法无副作用,不会修改该实例的任何成员变量。)`
.. |vararg| replace:: :abbr:`vararg (本方法除了能接受在此处描述的参数外,还能够继续接受任意数量的参数。)`
.. |constructor| replace:: :abbr:`constructor (本方法用于构造某个类型。)`
.. |static| replace:: :abbr:`static (调用本方法无需实例,可直接使用类名进行调用。)`
.. |operator| replace:: :abbr:`operator (本方法描述的是使用本类型作为左操作数的有效运算符。)`
.. |bitfield| replace:: :abbr:`BitField (这个值是由下列位标志构成位掩码的整数。)`
.. |void| replace:: :abbr:`void (无返回值。)`