diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-23 15:36:11 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-23 15:36:11 +0100 |
commit | 1f22c482e192ef7df57fdc182243459d3dc4f232 (patch) | |
tree | affce408b8ede80561ca3dd8132693c43c3cf499 /editor | |
parent | 81fe3715b825dfc2b02adced8c08f8bc88220cb7 (diff) | |
parent | daad4aed62bfa471421f960179f0ac0fd78e8040 (diff) |
Merge pull request #70052 from bruvzg/key_unicode_actions
Cleanup and unify keyboard input.
Diffstat (limited to 'editor')
-rw-r--r-- | editor/action_map_editor.cpp | 8 | ||||
-rw-r--r-- | editor/event_listener_line_edit.cpp | 36 | ||||
-rw-r--r-- | editor/icons/Keyboard.svg | 2 | ||||
-rw-r--r-- | editor/icons/KeyboardError.svg | 1 | ||||
-rw-r--r-- | editor/icons/KeyboardLabel.svg | 1 | ||||
-rw-r--r-- | editor/icons/KeyboardPhysical.svg | 2 | ||||
-rw-r--r-- | editor/input_event_configuration_dialog.cpp | 156 | ||||
-rw-r--r-- | editor/input_event_configuration_dialog.h | 17 |
8 files changed, 163 insertions, 60 deletions
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index cb8d98932d..ae54c20fe2 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -449,10 +449,14 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info // First Column - Icon Ref<InputEventKey> k = event; if (k.is_valid()) { - if (k->get_physical_keycode() == Key::NONE) { + if (k->get_physical_keycode() == Key::NONE && k->get_keycode() == Key::NONE && k->get_key_label() != Key::NONE) { + event_item->set_icon(0, action_tree->get_theme_icon(SNAME("KeyboardLabel"), SNAME("EditorIcons"))); + } else if (k->get_keycode() != Key::NONE) { event_item->set_icon(0, action_tree->get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons"))); - } else { + } else if (k->get_physical_keycode() != Key::NONE) { event_item->set_icon(0, action_tree->get_theme_icon(SNAME("KeyboardPhysical"), SNAME("EditorIcons"))); + } else { + event_item->set_icon(0, action_tree->get_theme_icon(SNAME("KeyboardError"), SNAME("EditorIcons"))); } } diff --git a/editor/event_listener_line_edit.cpp b/editor/event_listener_line_edit.cpp index 274fe34c52..ea4a7133bf 100644 --- a/editor/event_listener_line_edit.cpp +++ b/editor/event_listener_line_edit.cpp @@ -59,16 +59,42 @@ static const char *_joy_axis_descriptions[(size_t)JoyAxis::MAX * 2] = { String EventListenerLineEdit::get_event_text(const Ref<InputEvent> &p_event, bool p_include_device) { ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEvent"); - String text = p_event->as_text(); - + String text; Ref<InputEventKey> key = p_event; - if (key.is_valid() && key->is_command_or_control_autoremap()) { + if (key.is_valid()) { + String mods_text = key->InputEventWithModifiers::as_text(); + mods_text = mods_text.is_empty() ? mods_text : mods_text + "+"; + if (key->is_command_or_control_autoremap()) { #ifdef MACOS_ENABLED - text = text.replace("Command", "Command/Ctrl"); + mods_text = mods_text.replace("Command", "Command/Ctrl"); #else - text = text.replace("Ctrl", "Command/Ctrl"); + mods_text = mods_text.replace("Ctrl", "Command/Ctrl"); #endif + } + + if (key->get_keycode() != Key::NONE) { + text += mods_text + keycode_get_string(key->get_keycode()); + } + if (key->get_physical_keycode() != Key::NONE) { + if (!text.is_empty()) { + text += " or "; + } + text += mods_text + keycode_get_string(key->get_physical_keycode()) + " (" + RTR("Physical") + ")"; + } + if (key->get_key_label() != Key::NONE) { + if (!text.is_empty()) { + text += " or "; + } + text += mods_text + keycode_get_string(key->get_key_label()) + " (Unicode)"; + } + + if (text.is_empty()) { + text = "(" + RTR("Unset") + ")"; + } + } else { + text = p_event->as_text(); } + Ref<InputEventMouse> mouse = p_event; Ref<InputEventJoypadMotion> jp_motion = p_event; Ref<InputEventJoypadButton> jp_button = p_event; diff --git a/editor/icons/Keyboard.svg b/editor/icons/Keyboard.svg index b9dfab71ed..b6d963f9d7 100644 --- a/editor/icons/Keyboard.svg +++ b/editor/icons/Keyboard.svg @@ -1 +1 @@ -<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".996"><path d="m4 2a1 1 0 0 0 -1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916v-9.084a1 1 0 0 0 -1-1zm1.543 1.139h1.393l1.834 4.199h1.295v.437c.708.052 1.246.239 1.61.559.368.316.55.747.55 1.295 0 .552-.182.99-.55 1.314-.368.32-.906.505-1.61.553v.467h-1.294v-.473c-.708-.06-1.247-.248-1.615-.564-.364-.316-.545-.75-.545-1.297 0-.548.181-.977.545-1.29.368-.315.907-.504 1.615-.564v-.437h-1.464l-.282-.733h-1.595l-.284.733h-1.439l1.836-4.2zm.684 1.39-.409 1.057h.817zm3.84 4.338v1.526c.28-.04.483-.12.607-.24.124-.125.185-.302.185-.53 0-.224-.063-.396-.191-.516-.124-.12-.326-.2-.602-.24zm-1.296.006c-.284.04-.487.12-.61.24-.12.116-.182.288-.182.516 0 .22.065.392.193.512.132.12.331.202.6.246v-1.514z" fill="#e0e0e0"/><path d="m27 2h7v14h-7z" fill="#fff"/><path d="m1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9z" fill="#e0e0e0"/></g></svg> +<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16"><path d="M6.584 5.135 6.17 4.059l-.412 1.076h.826zm3.203 2.976a1.032 1.032 0 0 0-.287.041.953.953 0 0 0-.09.034c-.028.012-.057.024-.084.039a.912.912 0 0 0-.152.107.988.988 0 0 0-.23.305.937.937 0 0 0-.04.097 1.017 1.017 0 0 0-.068.323 1.553 1.553 0 0 0 0 .244 1.374 1.374 0 0 0 .068.328 1.03 1.03 0 0 0 .201.336c.023.022.045.044.069.064a.96.96 0 0 0 .152.104c.027.015.056.027.084.039.03.012.06.024.09.033a.965.965 0 0 0 .19.035 1.028 1.028 0 0 0 .197 0 .974.974 0 0 0 .36-.107.876.876 0 0 0 .077-.049.872.872 0 0 0 .074-.055.882.882 0 0 0 .13-.136.978.978 0 0 0 .177-.368 1.225 1.225 0 0 0 .035-.224 1.61 1.61 0 0 0 0-.244 1.361 1.361 0 0 0-.035-.223 1.092 1.092 0 0 0-.121-.285.87.87 0 0 0-.12-.15.862.862 0 0 0-.14-.124c-.025-.017-.05-.035-.078-.05-.027-.015-.056-.027-.086-.04a.892.892 0 0 0-.373-.074z" style="fill-opacity:.99607843;fill:#e0e0e0"/><path d="M4 2c-.616-.02-1.084.59-1 1.178.003 3-.007 6 .005 9 .057.577.672.889 1.203.822 2.631-.003 5.263.006 7.894-.005a.973.973 0 0 0 .898-1.09c-.003-3.002.007-6.005-.005-9.007-.042-.592-.643-.976-1.203-.898H4Zm1.475.646H6.89l1.865 4.27H7.268l-.286-.744H5.36l-.287.744H3.61l1.866-4.27Zm4.312 4.301c1.069-.042 2.164.679 2.363 1.766.232 1.01-.34 2.144-1.326 2.502.296.465.837-.109 1.06-.007l.544.642c-.64.756-1.883.677-2.605.084-.394-.448-.866-.673-1.409-.887-1.175-.66-1.391-2.456-.43-3.39.463-.486 1.141-.716 1.803-.71Z" style="fill:#e0e0e0;fill-opacity:.996078"/><path fill="#e0e0e0" d="M1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4Z" style="fill-opacity:.996"/></svg> diff --git a/editor/icons/KeyboardError.svg b/editor/icons/KeyboardError.svg new file mode 100644 index 0000000000..e20d133155 --- /dev/null +++ b/editor/icons/KeyboardError.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16"><path d="M4 2c-.616-.02-1.084.59-1 1.178.003 3-.007 6 .005 9 .057.577.672.889 1.203.822 2.631-.003 5.263.006 7.894-.005a.973.973 0 0 0 .898-1.09c-.003-3.002.007-6.005-.005-9.007-.042-.592-.643-.976-1.203-.898H4Zm4.223 1.262c1.06.005 2.29.257 2.92 1.197.532.862.275 2.057-.484 2.703-.346.382-.862.629-1.075 1.117.055.345-.33.172-.537.213H7.148c-.037-.749.503-1.335 1.026-1.796.406-.253.744-1.002.129-1.22-.626-.25-1.374.117-1.645.715l-2.08-1.039c.599-1.147 1.868-1.818 3.136-1.872.17-.013.339-.018.509-.018Zm.127 5.697c.798-.057 1.616.616 1.54 1.45-.023.81-.841 1.413-1.623 1.328-.833.022-1.6-.771-1.443-1.613.097-.721.83-1.195 1.526-1.165z" style="fill:#ff5f5f;fill-opacity:1"/><path fill="#e0e0e0" d="M1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4Z" style="fill-opacity:1;fill:#ff5f5f"/></svg> diff --git a/editor/icons/KeyboardLabel.svg b/editor/icons/KeyboardLabel.svg new file mode 100644 index 0000000000..07a687f447 --- /dev/null +++ b/editor/icons/KeyboardLabel.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M11.814 1.977c-.078 0-.157.008-.232.023H4c-.7-.034-1.143.765-1 1.39.008 2.95-.017 5.9.014 8.848.13.705.965.847 1.562.76 2.542-.008 5.085.02 7.627-.014.734-.1.9-.952.797-1.564-.003-2.84.006-5.68-.006-8.522-.035-.594-.628-.927-1.18-.921zM9.797 4.016l.572.58-.572.578-.57-.578.57-.58zm-.606 1.05.594.606-.594.601-.591-.601.591-.606zm1.213 0 .596.606-.596.601-.593-.601.593-.606zm.717 1.436h1.06c.053.217.093.428.122.63.028.201.043.395.043.58a2.363 2.363 0 0 1-.133.724 1.425 1.425 0 0 1-.31.515c-.249.265-.598.399-1.05.399-.331 0-.594-.08-.785-.235a1.091 1.091 0 0 1-.236-.275c-.063.1-.14.19-.236.265-.206.163-.467.245-.787.245-.252 0-.457-.057-.614-.166a2.75 2.75 0 0 1-.095.42 1.936 1.936 0 0 1-.403.722c-.2.22-.452.383-.756.49-.303.11-.654.166-1.052.166-.466 0-.865-.089-1.2-.265a1.817 1.817 0 0 1-.765-.752c-.18-.327-.27-.715-.27-1.164 0-.256.027-.525.082-.809.055-.284.126-.545.21-.781h1.001c-.062.232-.112.46-.15.684a3.87 3.87 0 0 0-.053.613c0 .37.1.643.3.82.204.177.523.264.96.264.222 0 .425-.03.61-.092a.97.97 0 0 0 .439-.299.803.803 0 0 0 .166-.521 5.463 5.463 0 0 0-.051-.725 11.61 11.61 0 0 0-.068-.482 26.51 26.51 0 0 0-.096-.606h1.135l.043.276c.047.32.123.532.228.634.105.1.24.15.402.15.165 0 .284-.04.358-.124.076-.086.115-.224.115-.412v-.524h1.027v.524c0 .203.032.351.096.447.065.095.202.142.412.142a.637.637 0 0 0 .33-.078c.089-.052.133-.15.133-.297 0-.128-.019-.295-.054-.498l-.108-.605z" style="fill:#e0e0e0;fill-opacity:.996078"/><path fill="#e0e0e0" d="M1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4Z" style="fill-opacity:.996"/></svg> diff --git a/editor/icons/KeyboardPhysical.svg b/editor/icons/KeyboardPhysical.svg index 4364e0b4fa..7d4b7e2999 100644 --- a/editor/icons/KeyboardPhysical.svg +++ b/editor/icons/KeyboardPhysical.svg @@ -1 +1 @@ -<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".996"><path d="m4 2a1 1 0 0 0 -1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916v-9.084a1 1 0 0 0 -1-1zm2.762 1.768h2.476l3.264 7.464h-2.604l-.502-1.3h-2.835l-.502 1.3h-2.561zm1.217 2.474-.725 1.878h1.45z" fill="#e0e0e0"/><path d="m27 2h7v14h-7z" fill="#fff"/><path d="m1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9z" fill="#e0e0e0"/></g></svg> +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M4 2a1 1 0 0 0-1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916V3a1 1 0 0 0-1-1Zm2.762 1.768h2.476l3.264 7.464H9.898l-.502-1.3H6.561l-.502 1.3H3.498Zm1.217 2.474L7.254 8.12h1.45z" style="fill-opacity:.996"/><path fill="#e0e0e0" d="M1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4Z" style="fill-opacity:.996"/></svg> diff --git a/editor/input_event_configuration_dialog.cpp b/editor/input_event_configuration_dialog.cpp index 4f7d99c567..48e3759e57 100644 --- a/editor/input_event_configuration_dialog.cpp +++ b/editor/input_event_configuration_dialog.cpp @@ -38,9 +38,10 @@ #include "scene/gui/separator.h" #include "scene/gui/tree.h" -void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, bool p_update_input_list_selection) { +void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, const Ref<InputEvent> &p_original_event, bool p_update_input_list_selection) { if (p_event.is_valid()) { event = p_event; + original_event = p_original_event; // If the event is changed to something which is not the same as the listener, // clear out the event from the listener text box to avoid confusion. @@ -61,7 +62,7 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b // Update option values and visibility bool show_mods = false; bool show_device = false; - bool show_phys_key = false; + bool show_key = false; if (mod.is_valid()) { show_mods = true; @@ -74,9 +75,25 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b } if (k.is_valid()) { - show_phys_key = true; - physical_key_checkbox->set_pressed(k->get_physical_keycode() != Key::NONE && k->get_keycode() == Key::NONE); - + show_key = true; + if (k->get_keycode() == Key::NONE && k->get_physical_keycode() == Key::NONE && k->get_key_label() != Key::NONE) { + key_mode->select(KEYMODE_UNICODE); + } else if (k->get_keycode() != Key::NONE) { + key_mode->select(KEYMODE_KEYCODE); + } else if (k->get_physical_keycode() != Key::NONE) { + key_mode->select(KEYMODE_PHY_KEYCODE); + } else { + // Invalid key. + event = Ref<InputEvent>(); + original_event = Ref<InputEvent>(); + event_listener->clear_event(); + event_as_text->set_text(TTR("No Event Configured")); + + additional_options_container->hide(); + input_list_tree->deselect_all(); + _update_input_list(); + return; + } } else if (joyb.is_valid() || joym.is_valid() || mb.is_valid()) { show_device = true; _set_current_device(event->get_device()); @@ -84,11 +101,20 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b mod_container->set_visible(show_mods); device_container->set_visible(show_device); - physical_key_checkbox->set_visible(show_phys_key); + key_mode->set_visible(show_key); additional_options_container->show(); + // Update mode selector based on original key event. + Ref<InputEventKey> ko = p_original_event; + if (ko.is_valid()) { + key_mode->set_item_disabled(KEYMODE_KEYCODE, ko->get_keycode() == Key::NONE); + key_mode->set_item_disabled(KEYMODE_PHY_KEYCODE, ko->get_physical_keycode() == Key::NONE); + key_mode->set_item_disabled(KEYMODE_UNICODE, ko->get_key_label() == Key::NONE); + } + // Update selected item in input list. if (p_update_input_list_selection && (k.is_valid() || joyb.is_valid() || joym.is_valid() || mb.is_valid())) { + in_tree_update = true; TreeItem *category = input_list_tree->get_root()->get_first_child(); while (category) { TreeItem *input_item = category->get_first_child(); @@ -97,6 +123,7 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b // input_type should always be > 0, unless the tree structure has been misconfigured. int input_type = input_item->get_parent()->get_meta("__type", 0); if (input_type == 0) { + in_tree_update = false; return; } @@ -112,6 +139,7 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b category->set_collapsed(false); input_item->select(0); input_list_tree->ensure_cursor_is_visible(); + in_tree_update = false; return; } input_item = input_item->get_next(); @@ -122,10 +150,12 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b category->set_collapsed(true); // Event not in this category, so collapse; category = category->get_next(); } + in_tree_update = false; } } else { // Event is not valid, reset dialog - event = p_event; + event = Ref<InputEvent>(); + original_event = Ref<InputEvent>(); event_listener->clear_event(); event_as_text->set_text(TTR("No Event Configured")); @@ -141,8 +171,10 @@ void InputEventConfigurationDialog::_on_listen_input_changed(const Ref<InputEven return; } - // Create an editable reference + // Create an editable reference and a copy of full event. Ref<InputEvent> received_event = p_event; + Ref<InputEvent> received_original_event = received_event->duplicate(); + // Check what the type is and if it is allowed. Ref<InputEventKey> k = received_event; Ref<InputEventJoypadButton> joyb = received_event; @@ -169,12 +201,16 @@ void InputEventConfigurationDialog::_on_listen_input_changed(const Ref<InputEven } if (k.is_valid()) { - k->set_pressed(false); // To avoid serialization of 'pressed' property - doesn't matter for actions anyway. - // Maintain physical keycode option state - if (physical_key_checkbox->is_pressed()) { + k->set_pressed(false); // To avoid serialisation of 'pressed' property - doesn't matter for actions anyway. + if (key_mode->get_selected_id() == KEYMODE_KEYCODE) { + k->set_physical_keycode(Key::NONE); + k->set_key_label(Key::NONE); + } else if (key_mode->get_selected_id() == KEYMODE_PHY_KEYCODE) { k->set_keycode(Key::NONE); - } else { + k->set_key_label(Key::NONE); + } else if (key_mode->get_selected_id() == KEYMODE_UNICODE) { k->set_physical_keycode(Key::NONE); + k->set_keycode(Key::NONE); } } @@ -186,7 +222,7 @@ void InputEventConfigurationDialog::_on_listen_input_changed(const Ref<InputEven // Maintain device selection. received_event->set_device(_get_current_device()); - _set_event(received_event); + _set_event(received_event, received_original_event); } void InputEventConfigurationDialog::_on_listen_focus_changed() { @@ -326,14 +362,14 @@ void InputEventConfigurationDialog::_mod_toggled(bool p_checked, int p_index) { } } - _set_event(ie); + _set_event(ie, original_event); } void InputEventConfigurationDialog::_autoremap_command_or_control_toggled(bool p_checked) { Ref<InputEventWithModifiers> ie = event; if (ie.is_valid()) { ie->set_command_or_control_autoremap(p_checked); - _set_event(ie); + _set_event(ie, original_event); } if (p_checked) { @@ -345,27 +381,38 @@ void InputEventConfigurationDialog::_autoremap_command_or_control_toggled(bool p } } -void InputEventConfigurationDialog::_physical_keycode_toggled(bool p_checked) { +void InputEventConfigurationDialog::_key_mode_selected(int p_mode) { Ref<InputEventKey> k = event; - - if (k.is_null()) { + Ref<InputEventKey> ko = original_event; + if (k.is_null() || ko.is_null()) { return; } - if (p_checked) { - k->set_physical_keycode(k->get_keycode()); + if (key_mode->get_selected_id() == KEYMODE_KEYCODE) { + k->set_keycode(ko->get_keycode()); + k->set_physical_keycode(Key::NONE); + k->set_key_label(Key::NONE); + } else if (key_mode->get_selected_id() == KEYMODE_PHY_KEYCODE) { k->set_keycode(Key::NONE); - } else { - k->set_keycode((Key)k->get_physical_keycode()); + k->set_physical_keycode(ko->get_physical_keycode()); + k->set_key_label(Key::NONE); + } else if (key_mode->get_selected_id() == KEYMODE_UNICODE) { k->set_physical_keycode(Key::NONE); + k->set_keycode(Key::NONE); + k->set_key_label(ko->get_key_label()); } - _set_event(k); + _set_event(k, original_event); } void InputEventConfigurationDialog::_input_list_item_selected() { TreeItem *selected = input_list_tree->get_selected(); + // Called form _set_event, do not update for a second time. + if (in_tree_update) { + return; + } + // Invalid tree selection - type only exists on the "category" items, which are not a valid selection. if (selected->has_meta("__type")) { return; @@ -379,15 +426,11 @@ void InputEventConfigurationDialog::_input_list_item_selected() { Ref<InputEventKey> k; k.instantiate(); - if (physical_key_checkbox->is_pressed()) { - k->set_physical_keycode(keycode); - k->set_keycode(Key::NONE); - } else { - k->set_physical_keycode(Key::NONE); - k->set_keycode(keycode); - } + k->set_physical_keycode(keycode); + k->set_keycode(keycode); + k->set_key_label(keycode); - // Maintain modifier state from checkboxes + // Maintain modifier state from checkboxes. k->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed()); k->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed()); if (autoremap_command_or_control_checkbox->is_pressed()) { @@ -397,7 +440,23 @@ void InputEventConfigurationDialog::_input_list_item_selected() { k->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed()); } - _set_event(k, false); + Ref<InputEventKey> ko = k->duplicate(); + + if (key_mode->get_selected_id() == KEYMODE_UNICODE) { + key_mode->select(KEYMODE_PHY_KEYCODE); + } + + if (key_mode->get_selected_id() == KEYMODE_KEYCODE) { + k->set_physical_keycode(Key::NONE); + k->set_keycode(keycode); + k->set_key_label(Key::NONE); + } else if (key_mode->get_selected_id() == KEYMODE_PHY_KEYCODE) { + k->set_physical_keycode(keycode); + k->set_keycode(Key::NONE); + k->set_key_label(Key::NONE); + } + + _set_event(k, ko, false); } break; case INPUT_MOUSE_BUTTON: { MouseButton idx = (MouseButton)(int)selected->get_meta("__index"); @@ -417,7 +476,7 @@ void InputEventConfigurationDialog::_input_list_item_selected() { // Maintain selected device mb->set_device(_get_current_device()); - _set_event(mb, false); + _set_event(mb, mb, false); } break; case INPUT_JOY_BUTTON: { JoyButton idx = (JoyButton)(int)selected->get_meta("__index"); @@ -426,7 +485,7 @@ void InputEventConfigurationDialog::_input_list_item_selected() { // Maintain selected device jb->set_device(_get_current_device()); - _set_event(jb, false); + _set_event(jb, jb, false); } break; case INPUT_JOY_MOTION: { JoyAxis axis = (JoyAxis)(int)selected->get_meta("__axis"); @@ -440,7 +499,7 @@ void InputEventConfigurationDialog::_input_list_item_selected() { // Maintain selected device jm->set_device(_get_current_device()); - _set_event(jm, false); + _set_event(jm, jm, false); } break; } } @@ -470,7 +529,9 @@ void InputEventConfigurationDialog::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { input_list_search->set_right_icon(input_list_search->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); - physical_key_checkbox->set_icon(get_theme_icon(SNAME("KeyboardPhysical"), SNAME("EditorIcons"))); + key_mode->set_item_icon(KEYMODE_KEYCODE, get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons"))); + key_mode->set_item_icon(KEYMODE_PHY_KEYCODE, get_theme_icon(SNAME("KeyboardPhysical"), SNAME("EditorIcons"))); + key_mode->set_item_icon(KEYMODE_UNICODE, get_theme_icon(SNAME("KeyboardLabel"), SNAME("EditorIcons"))); icon_cache.keyboard = get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons")); icon_cache.mouse = get_theme_icon(SNAME("Mouse"), SNAME("EditorIcons")); @@ -484,22 +545,22 @@ void InputEventConfigurationDialog::_notification(int p_what) { void InputEventConfigurationDialog::popup_and_configure(const Ref<InputEvent> &p_event) { if (p_event.is_valid()) { - _set_event(p_event); + _set_event(p_event, p_event->duplicate()); } else { // Clear Event - _set_event(p_event); + _set_event(Ref<InputEvent>(), Ref<InputEvent>()); // Clear Checkbox Values for (int i = 0; i < MOD_MAX; i++) { mod_checkboxes[i]->set_pressed(false); } - // Enable the Physical Key checkbox by default to encourage its use. + // Enable the Physical Key by default to encourage its use. // Physical Key should be used for most game inputs as it allows keys to work // on non-QWERTY layouts out of the box. // This is especially important for WASD movement layouts. - physical_key_checkbox->set_pressed(true); + key_mode->select(KEYMODE_PHY_KEYCODE); autoremap_command_or_control_checkbox->set_pressed(false); // Select "All Devices" by default. @@ -621,14 +682,15 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() { mod_container->hide(); additional_options_container->add_child(mod_container); - // Physical Key Checkbox + // Key Mode Selection - physical_key_checkbox = memnew(CheckBox); - physical_key_checkbox->set_text(TTR("Use Physical Keycode")); - physical_key_checkbox->set_tooltip_text(TTR("Stores the physical position of the key on the keyboard rather than the key's value. Used for compatibility with non-latin layouts.\nThis should generally be enabled for most game shortcuts, but not in non-game applications.")); - physical_key_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_physical_keycode_toggled)); - physical_key_checkbox->hide(); - additional_options_container->add_child(physical_key_checkbox); + key_mode = memnew(OptionButton); + key_mode->add_item("Keycode (Latin equvialent)", KEYMODE_KEYCODE); + key_mode->add_item("Physical Keycode (poistion of US QWERTY keyboard)", KEYMODE_PHY_KEYCODE); + key_mode->add_item("Unicode (case-insencetive)", KEYMODE_UNICODE); + key_mode->connect("item_selected", callable_mp(this, &InputEventConfigurationDialog::_key_mode_selected)); + key_mode->hide(); + additional_options_container->add_child(key_mode); main_vbox->add_child(additional_options_container); } diff --git a/editor/input_event_configuration_dialog.h b/editor/input_event_configuration_dialog.h index 67906233dd..e7ab0da4d6 100644 --- a/editor/input_event_configuration_dialog.h +++ b/editor/input_event_configuration_dialog.h @@ -50,7 +50,10 @@ private: Ref<Texture2D> joypad_axis; } icon_cache; - Ref<InputEvent> event = Ref<InputEvent>(); + Ref<InputEvent> event; + Ref<InputEvent> original_event; + + bool in_tree_update = false; // Listening for input EventListenerLineEdit *event_listener = nullptr; @@ -88,9 +91,15 @@ private: CheckBox *mod_checkboxes[MOD_MAX]; CheckBox *autoremap_command_or_control_checkbox = nullptr; - CheckBox *physical_key_checkbox = nullptr; + enum KeyMode { + KEYMODE_KEYCODE, + KEYMODE_PHY_KEYCODE, + KEYMODE_UNICODE, + }; + + OptionButton *key_mode = nullptr; - void _set_event(const Ref<InputEvent> &p_event, bool p_update_input_list_selection = true); + void _set_event(const Ref<InputEvent> &p_event, const Ref<InputEvent> &p_original_event, bool p_update_input_list_selection = true); void _on_listen_input_changed(const Ref<InputEvent> &p_event); void _on_listen_focus_changed(); @@ -100,7 +109,7 @@ private: void _mod_toggled(bool p_checked, int p_index); void _autoremap_command_or_control_toggled(bool p_checked); - void _physical_keycode_toggled(bool p_checked); + void _key_mode_selected(int p_mode); void _device_selection_changed(int p_option_button_index); void _set_current_device(int p_device); |