diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2022-12-11 01:21:22 +0200 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2023-01-23 15:08:12 +0200 |
commit | daad4aed62bfa471421f960179f0ac0fd78e8040 (patch) | |
tree | 86b7f69d180f253c51c4b567139d68850f9e365d /scene/gui | |
parent | 9937915ad77059b63582ffd4e324afb26f467b76 (diff) |
Cleanup and unify keyboard input.
- Unify keycode values (secondary label printed on a key), remove unused hardcoded Latin-1 codes.
- Unify IME behaviour, add inline composition string display on Windows and X11.
- Add key_label (localized label printed on a key) value to the key events, and allow mapping actions to the unshifted Unicode events.
- Add support for physical keyboard (Bluetooth or Sidecar) handling on iOS.
- Add support for media key handling on macOS.
Co-authored-by: Raul Santos <raulsntos@gmail.com>
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/line_edit.cpp | 48 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 14 |
2 files changed, 39 insertions, 23 deletions
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index ad4e667278..e2a5b0c8a3 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -952,9 +952,9 @@ void LineEdit::_notification(int p_what) { // Prevent carets from disappearing at theme scales below 1.0 (if the caret width is 1). const int caret_width = theme_cache.caret_width * MAX(1, theme_cache.base_scale); - if (ime_text.length() == 0) { + if (ime_text.is_empty() || ime_selection.y == 0) { // Normal caret. - CaretInfo caret = TS->shaped_text_get_carets(text_rid, caret_column); + CaretInfo caret = TS->shaped_text_get_carets(text_rid, ime_text.is_empty() ? caret_column : caret_column + ime_selection.x); if (using_placeholder || (caret.l_caret == Rect2() && caret.t_caret == Rect2())) { // No carets, add one at the start. int h = theme_cache.font->get_height(theme_cache.font_size); @@ -980,6 +980,7 @@ void LineEdit::_notification(int p_what) { } } break; } + RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color); } else { if (caret.l_caret != Rect2() && caret.l_dir == TextServer::DIRECTION_AUTO) { @@ -1009,7 +1010,8 @@ void LineEdit::_notification(int p_what) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.t_caret, caret_color); } - } else { + } + if (!ime_text.is_empty()) { { // IME intermediate text range. Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, caret_column, caret_column + ime_text.length()); @@ -1030,20 +1032,22 @@ void LineEdit::_notification(int p_what) { } { // IME caret. - Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, caret_column + ime_selection.x, caret_column + ime_selection.x + ime_selection.y); - for (int i = 0; i < sel.size(); i++) { - Rect2 rect = Rect2(sel[i].x + ofs.x, ofs.y, sel[i].y - sel[i].x, text_height); - if (rect.position.x + rect.size.x <= x_ofs || rect.position.x > ofs_max) { - continue; - } - if (rect.position.x < x_ofs) { - rect.size.x -= (x_ofs - rect.position.x); - rect.position.x = x_ofs; - } else if (rect.position.x + rect.size.x > ofs_max) { - rect.size.x = ofs_max - rect.position.x; + if (ime_selection.y > 0) { + Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, caret_column + ime_selection.x, caret_column + ime_selection.x + ime_selection.y); + for (int i = 0; i < sel.size(); i++) { + Rect2 rect = Rect2(sel[i].x + ofs.x, ofs.y, sel[i].y - sel[i].x, text_height); + if (rect.position.x + rect.size.x <= x_ofs || rect.position.x > ofs_max) { + continue; + } + if (rect.position.x < x_ofs) { + rect.size.x -= (x_ofs - rect.position.x); + rect.position.x = x_ofs; + } else if (rect.position.x + rect.size.x > ofs_max) { + rect.size.x = ofs_max - rect.position.x; + } + rect.size.y = caret_width * 3; + RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, caret_color); } - rect.size.y = caret_width * 3; - RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, caret_color); } } } @@ -1052,7 +1056,8 @@ void LineEdit::_notification(int p_what) { if (has_focus()) { if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) { DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id()); - DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + TS->shaped_text_get_size(text_rid).y), get_viewport()->get_window_id()); + Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + theme_cache.font->get_height(theme_cache.font_size)) / 2); + DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + pos, get_viewport()->get_window_id()); } } } break; @@ -1071,8 +1076,8 @@ void LineEdit::_notification(int p_what) { if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) { DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id()); - Point2 column = Point2(get_caret_column(), 1) * get_minimum_size().height; - DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + column, get_viewport()->get_window_id()); + Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + theme_cache.font->get_height(theme_cache.font_size)) / 2); + DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + pos, get_viewport()->get_window_id()); } show_virtual_keyboard(); @@ -1103,6 +1108,11 @@ void LineEdit::_notification(int p_what) { if (has_focus()) { ime_text = DisplayServer::get_singleton()->ime_get_text(); ime_selection = DisplayServer::get_singleton()->ime_get_selection(); + + if (!ime_text.is_empty()) { + selection_delete(); + } + _shape(); set_caret_column(caret_column); // Update scroll_offset diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 8ffaa9e81f..56bd5c872a 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1319,11 +1319,12 @@ void TextEdit::_notification(int p_what) { if (!clipped && get_caret_line(c) == line && carets_wrap_index[c] == line_wrap_index) { carets.write[c].draw_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index); - if (ime_text.length() == 0) { + if (ime_text.is_empty() || ime_selection.y == 0) { + // Normal caret. CaretInfo ts_caret; - if (str.length() != 0) { + if (!str.is_empty() || !ime_text.is_empty()) { // Get carets. - ts_caret = TS->shaped_text_get_carets(rid, get_caret_column(c)); + ts_caret = TS->shaped_text_get_carets(rid, ime_text.is_empty() ? get_caret_column(c) : get_caret_column(c) + ime_selection.x); } else { // No carets, add one at the start. int h = font->get_height(font_size); @@ -1426,7 +1427,8 @@ void TextEdit::_notification(int p_what) { } } } - } else { + } + if (!ime_text.is_empty()) { { // IME Intermediate text range. Vector<Vector2> sel = TS->shaped_text_get_selection(rid, get_caret_column(c), get_caret_column(c) + ime_text.length()); @@ -1546,6 +1548,10 @@ void TextEdit::_notification(int p_what) { ime_text = DisplayServer::get_singleton()->ime_get_text(); ime_selection = DisplayServer::get_singleton()->ime_get_selection(); + if (!ime_text.is_empty()) { + delete_selection(); + } + for (int i = 0; i < carets.size(); i++) { String t; if (get_caret_column(i) >= 0) { |