Merge pull request #87353 from OverloadedOrama/max-undo-steps

Implement maximum undo steps in UndoRedo
This commit is contained in:
Yuri Sizov 2024-01-24 14:08:25 +01:00
commit 412f5b3422
3 changed files with 29 additions and 0 deletions

View file

@ -316,6 +316,14 @@ void UndoRedo::commit_action(bool p_execute) {
_redo(p_execute); // perform action _redo(p_execute); // perform action
committing--; committing--;
if (max_steps > 0) {
// Clear early steps.
while (actions.size() > max_steps) {
_pop_history_tail();
}
}
if (add_message && callback && actions.size() > 0) { if (add_message && callback && actions.size() > 0) {
callback(callback_ud, actions[actions.size() - 1].name); callback(callback_ud, actions[actions.size() - 1].name);
} }
@ -473,6 +481,14 @@ uint64_t UndoRedo::get_version() const {
return version; return version;
} }
void UndoRedo::set_max_steps(int p_max_steps) {
max_steps = p_max_steps;
}
int UndoRedo::get_max_steps() const {
return max_steps;
}
void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback, void *p_ud) { void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback, void *p_ud) {
callback = p_callback; callback = p_callback;
callback_ud = p_ud; callback_ud = p_ud;
@ -517,9 +533,13 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_undo"), &UndoRedo::has_undo); ClassDB::bind_method(D_METHOD("has_undo"), &UndoRedo::has_undo);
ClassDB::bind_method(D_METHOD("has_redo"), &UndoRedo::has_redo); ClassDB::bind_method(D_METHOD("has_redo"), &UndoRedo::has_redo);
ClassDB::bind_method(D_METHOD("get_version"), &UndoRedo::get_version); ClassDB::bind_method(D_METHOD("get_version"), &UndoRedo::get_version);
ClassDB::bind_method(D_METHOD("set_max_steps", "max_steps"), &UndoRedo::set_max_steps);
ClassDB::bind_method(D_METHOD("get_max_steps"), &UndoRedo::get_max_steps);
ClassDB::bind_method(D_METHOD("redo"), &UndoRedo::redo); ClassDB::bind_method(D_METHOD("redo"), &UndoRedo::redo);
ClassDB::bind_method(D_METHOD("undo"), &UndoRedo::undo); ClassDB::bind_method(D_METHOD("undo"), &UndoRedo::undo);
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_steps", PROPERTY_HINT_RANGE, "0,50,1,or_greater"), "set_max_steps", "get_max_steps");
ADD_SIGNAL(MethodInfo("version_changed")); ADD_SIGNAL(MethodInfo("version_changed"));
BIND_ENUM_CONSTANT(MERGE_DISABLE); BIND_ENUM_CONSTANT(MERGE_DISABLE);

View file

@ -80,6 +80,7 @@ private:
int current_action = -1; int current_action = -1;
bool force_keep_in_merge_ends = false; bool force_keep_in_merge_ends = false;
int action_level = 0; int action_level = 0;
int max_steps = 0;
MergeMode merge_mode = MERGE_DISABLE; MergeMode merge_mode = MERGE_DISABLE;
bool merging = false; bool merging = false;
uint64_t version = 1; uint64_t version = 1;
@ -135,6 +136,9 @@ public:
uint64_t get_version() const; uint64_t get_version() const;
void set_max_steps(int p_max_steps);
int get_max_steps() const;
void set_commit_notify_callback(CommitNotifyCallback p_callback, void *p_ud); void set_commit_notify_callback(CommitNotifyCallback p_callback, void *p_ud);
void set_method_notify_callback(MethodNotifyCallback p_method_callback, void *p_ud); void set_method_notify_callback(MethodNotifyCallback p_method_callback, void *p_ud);

View file

@ -255,6 +255,11 @@
</description> </description>
</method> </method>
</methods> </methods>
<members>
<member name="max_steps" type="int" setter="set_max_steps" getter="get_max_steps" default="0">
The maximum number of steps that can be stored in the undo/redo history. If the number of stored steps exceeds this limit, older steps are removed from history and can no longer be reached by calling [method undo]. A value of [code]0[/code] or lower means no limit.
</member>
</members>
<signals> <signals>
<signal name="version_changed"> <signal name="version_changed">
<description> <description>