From 95403207e8590618eb699457615c6b8d045dc972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E9=9D=92=E5=B1=B1?= Date: Sun, 27 Jul 2025 13:03:20 +0800 Subject: [PATCH] Use `EditorUndoRedoManager` to track the property changes of the configured `InputEvent` in the plugin This allows undo and redo, and can mark in time whether the handled `InputEvent` resource is edited. `command_or_control_autoremap` needs to be handled separately, as its value will change the usage of other properties. --- core/input/input_event.cpp | 6 +++ .../inspector/input_event_editor_plugin.cpp | 54 ++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 509632c7ca..e53c7bfb55 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -153,6 +153,9 @@ int64_t InputEventFromWindow::get_window_id() const { /////////////////////////////////// void InputEventWithModifiers::set_command_or_control_autoremap(bool p_enabled) { + if (command_or_control_autoremap == p_enabled) { + return; + } command_or_control_autoremap = p_enabled; if (command_or_control_autoremap) { if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { @@ -166,6 +169,7 @@ void InputEventWithModifiers::set_command_or_control_autoremap(bool p_enabled) { ctrl_pressed = false; meta_pressed = false; } + notify_property_list_changed(); emit_changed(); } @@ -309,9 +313,11 @@ void InputEventWithModifiers::_validate_property(PropertyInfo &p_property) const // Cannot be used with Meta/Command or Control! if (p_property.name == "meta_pressed") { p_property.usage ^= PROPERTY_USAGE_STORAGE; + p_property.usage ^= PROPERTY_USAGE_EDITOR; } if (p_property.name == "ctrl_pressed") { p_property.usage ^= PROPERTY_USAGE_STORAGE; + p_property.usage ^= PROPERTY_USAGE_EDITOR; } } else { if (p_property.name == "command_or_control_autoremap") { diff --git a/editor/inspector/input_event_editor_plugin.cpp b/editor/inspector/input_event_editor_plugin.cpp index d56adaf2ed..8314ba8dbb 100644 --- a/editor/inspector/input_event_editor_plugin.cpp +++ b/editor/inspector/input_event_editor_plugin.cpp @@ -30,6 +30,7 @@ #include "input_event_editor_plugin.h" +#include "editor/editor_undo_redo_manager.h" #include "editor/settings/event_listener_line_edit.h" #include "editor/settings/input_event_configuration_dialog.h" @@ -51,8 +52,57 @@ void InputEventConfigContainer::_event_changed() { void InputEventConfigContainer::_config_dialog_confirmed() { Ref ie = config_dialog->get_event(); - input_event->copy_from(ie); - _event_changed(); + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Event Configured")); + + // When command_or_control_autoremap is toggled to false, it should be set first; + // and when it is toggled to true, it should be set last. + bool will_toggle = false; + bool pending = false; + Ref iewm = input_event; + if (iewm.is_valid()) { + Variant new_value = ie->get("command_or_control_autoremap"); + will_toggle = new_value != input_event->get("command_or_control_autoremap"); + if (will_toggle) { + pending = new_value; + if (pending) { + undo_redo->add_undo_property(input_event.ptr(), "command_or_control_autoremap", !pending); + } else { + undo_redo->add_do_property(input_event.ptr(), "command_or_control_autoremap", pending); + } + } + } + + List pi; + ie->get_property_list(&pi); + for (const PropertyInfo &E : pi) { + if (E.name == "resource_path") { + continue; // Do not change path. + } + if (E.name == "command_or_control_autoremap") { + continue; // Handle it separately. + } + Variant old_value = input_event->get(E.name); + Variant new_value = ie->get(E.name); + if (old_value == new_value) { + continue; + } + undo_redo->add_do_property(input_event.ptr(), E.name, new_value); + undo_redo->add_undo_property(input_event.ptr(), E.name, old_value); + } + + if (will_toggle) { + if (pending) { + undo_redo->add_do_property(input_event.ptr(), "command_or_control_autoremap", pending); + } else { + undo_redo->add_undo_property(input_event.ptr(), "command_or_control_autoremap", !pending); + } + } + + undo_redo->add_do_property(input_event_text, "text", ie->as_text()); + undo_redo->add_undo_property(input_event_text, "text", input_event->as_text()); + undo_redo->commit_action(); } void InputEventConfigContainer::set_event(const Ref &p_event) {