From 7c73b6c71cad819cd7c53c8ccf14f7e909203c0d Mon Sep 17 00:00:00 2001 From: Eric M Date: Fri, 13 Jan 2023 21:36:44 +1000 Subject: [PATCH] Fix Project Settings array/dicts initial value being shared instances of the current value. --- core/config/project_settings.cpp | 8 ++++++-- editor/action_map_editor.cpp | 15 +++++++++++++++ editor/action_map_editor.h | 3 +++ editor/project_settings_editor.cpp | 14 +++----------- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 0bf7430d842..264883ffa82 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -220,7 +220,9 @@ String ProjectSettings::localize_path(const String &p_path) const { void ProjectSettings::set_initial_value(const String &p_name, const Variant &p_value) { ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); - props[p_name].initial = p_value; + + // Duplicate so that if value is array or dictionary, changing the setting will not change the stored initial value. + props[p_name].initial = p_value.duplicate(); } void ProjectSettings::set_restart_if_changed(const String &p_name, bool p_restart) { @@ -1122,7 +1124,9 @@ bool ProjectSettings::_property_get_revert(const StringName &p_name, Variant &r_ return false; } - r_property = props[p_name].initial; + // Duplicate so that if value is array or dictionary, changing the setting will not change the stored initial value. + r_property = props[p_name].initial.duplicate(); + return true; } diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index 712b11d7d72..cb457689e07 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -198,6 +198,14 @@ void ActionMapEditor::_tree_button_pressed(Object *p_item, int p_column, int p_i emit_signal(SNAME("action_edited"), action_name, action); } break; + case ActionMapEditor::BUTTON_REVERT_ACTION: { + ERR_FAIL_COND_MSG(!item->has_meta("__action_initial"), "Tree Item for action which can be reverted is expected to have meta value with initial value of action."); + + Dictionary action = item->get_meta("__action_initial").duplicate(); + String action_name = item->get_meta("__name"); + + emit_signal(SNAME("action_edited"), action_name, action); + } break; default: break; } @@ -431,6 +439,13 @@ void ActionMapEditor::update_action_list(const Vector &p_action_info action_item->set_range(1, deadzone); // Third column - buttons + if (action_info.has_initial) { + bool deadzone_eq = action_info.action_initial["deadzone"] == action_info.action["deadzone"]; + bool events_eq = Shortcut::is_event_array_equal(action_info.action_initial["events"], action_info.action["events"]); + bool action_eq = deadzone_eq && events_eq; + action_item->set_meta("__action_initial", action_info.action_initial); + action_item->add_button(2, action_tree->get_theme_icon(SNAME("ReloadSmall"), SNAME("EditorIcons")), BUTTON_REVERT_ACTION, action_eq, action_eq ? TTR("Cannot Revert - Action is same as initial") : TTR("Revert Action")); + } action_item->add_button(2, action_tree->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), BUTTON_ADD_EVENT, false, TTR("Add Event")); action_item->add_button(2, action_tree->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? TTR("Remove Action") : TTR("Cannot Remove Action")); diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h index 433a72a8078..2848d23e83c 100644 --- a/editor/action_map_editor.h +++ b/editor/action_map_editor.h @@ -49,6 +49,8 @@ public: struct ActionInfo { String name; Dictionary action; + bool has_initial = false; + Dictionary action_initial; Ref icon = Ref(); bool editable = true; @@ -60,6 +62,7 @@ private: BUTTON_EDIT_EVENT, BUTTON_REMOVE_ACTION, BUTTON_REMOVE_EVENT, + BUTTON_REVERT_ACTION, }; Vector actions_cache; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 69c21177f9a..7ef8bfcf6a8 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -370,17 +370,7 @@ void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionar } else { // Events changed - int act_event_count = ((Array)p_action["events"]).size(); - int old_event_count = ((Array)old_val["events"]).size(); - - if (act_event_count == old_event_count) { - undo_redo->create_action(TTR("Edit Input Action Event")); - } else if (act_event_count > old_event_count) { - undo_redo->create_action(TTR("Add Input Action Event")); - } else { - undo_redo->create_action(TTR("Remove Input Action Event")); - } - + undo_redo->create_action(TTR("Change Input Action Event(s)")); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", property_name, p_action); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val); } @@ -527,6 +517,8 @@ void ProjectSettingsEditor::_update_action_map_editor() { if (is_builtin_input) { action_info.editable = false; action_info.icon = builtin_icon; + action_info.has_initial = true; + action_info.action_initial = ProjectSettings::get_singleton()->property_get_revert(property_name); } actions.push_back(action_info);