summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-01-23 15:36:11 +0100
committerRémi Verschelde <rverschelde@gmail.com>2023-01-23 15:36:11 +0100
commit1f22c482e192ef7df57fdc182243459d3dc4f232 (patch)
treeaffce408b8ede80561ca3dd8132693c43c3cf499 /editor
parent81fe3715b825dfc2b02adced8c08f8bc88220cb7 (diff)
parentdaad4aed62bfa471421f960179f0ac0fd78e8040 (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.cpp8
-rw-r--r--editor/event_listener_line_edit.cpp36
-rw-r--r--editor/icons/Keyboard.svg2
-rw-r--r--editor/icons/KeyboardError.svg1
-rw-r--r--editor/icons/KeyboardLabel.svg1
-rw-r--r--editor/icons/KeyboardPhysical.svg2
-rw-r--r--editor/input_event_configuration_dialog.cpp156
-rw-r--r--editor/input_event_configuration_dialog.h17
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);