diff options
Diffstat (limited to 'scene/gui/text_edit.cpp')
-rw-r--r-- | scene/gui/text_edit.cpp | 134 |
1 files changed, 99 insertions, 35 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index ab0ad2f4b7..d7799588ea 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1557,7 +1557,7 @@ void TextEdit::_notification(int p_what) { carets.write[c].draw_pos.x = rect.position.x; } } - { + if (ime_selection.y > 0) { // IME caret. const Vector<Vector2> sel = TS->shaped_text_get_selection(rid, get_caret_column(c) + ime_selection.x, get_caret_column(c) + ime_selection.x + ime_selection.y); for (int j = 0; j < sel.size(); j++) { @@ -1688,39 +1688,93 @@ void TextEdit::unhandled_key_input(const Ref<InputEvent> &p_event) { bool TextEdit::alt_input(const Ref<InputEvent> &p_gui_input) { Ref<InputEventKey> k = p_gui_input; if (k.is_valid()) { - if (!k->is_pressed()) { - if (alt_start && k->get_keycode() == Key::ALT) { - alt_start = false; - if ((alt_code > 0x31 && alt_code < 0xd800) || (alt_code > 0xdfff && alt_code <= 0x10ffff)) { - handle_unicode_input(alt_code); - } - return true; + // Start Unicode input (hold). + if (k->is_alt_pressed() && k->get_keycode() == Key::KP_ADD && !alt_start && !alt_start_no_hold) { + if (has_selection()) { + delete_selection(); } - return false; + alt_start = true; + alt_code = 0; + ime_text = "u"; + ime_selection = Vector2i(0, -1); + _update_ime_text(); + return true; } - if (k->is_alt_pressed()) { - if (!alt_start) { - if (k->get_keycode() == Key::KP_ADD) { - alt_start = true; - alt_code = 0; - return true; - } + // Start Unicode input (press). + if (k->is_action("ui_unicode_start", true) && !alt_start && !alt_start_no_hold) { + if (has_selection()) { + delete_selection(); + } + alt_start_no_hold = true; + alt_code = 0; + ime_text = "u"; + ime_selection = Vector2i(0, -1); + _update_ime_text(); + return true; + } + + // Update Unicode input. + if (k->is_pressed() && ((k->is_alt_pressed() && alt_start) || alt_start_no_hold)) { + if (k->get_keycode() >= Key::KEY_0 && k->get_keycode() <= Key::KEY_9) { + alt_code = alt_code << 4; + alt_code += (uint32_t)(k->get_keycode() - Key::KEY_0); + } else if (k->get_keycode() >= Key::KP_0 && k->get_keycode() <= Key::KP_9) { + alt_code = alt_code << 4; + alt_code += (uint32_t)(k->get_keycode() - Key::KP_0); + } else if (k->get_keycode() >= Key::A && k->get_keycode() <= Key::F) { + alt_code = alt_code << 4; + alt_code += (uint32_t)(k->get_keycode() - Key::A) + 10; + } else if ((Key)k->get_unicode() >= Key::KEY_0 && (Key)k->get_unicode() <= Key::KEY_9) { + alt_code = alt_code << 4; + alt_code += (uint32_t)((Key)k->get_unicode() - Key::KEY_0); + } else if ((Key)k->get_unicode() >= Key::A && (Key)k->get_unicode() <= Key::F) { + alt_code = alt_code << 4; + alt_code += (uint32_t)((Key)k->get_unicode() - Key::A) + 10; + } else if (k->get_physical_keycode() >= Key::KEY_0 && k->get_physical_keycode() <= Key::KEY_9) { + alt_code = alt_code << 4; + alt_code += (uint32_t)(k->get_physical_keycode() - Key::KEY_0); + } + if (k->get_keycode() == Key::BACKSPACE) { + alt_code = alt_code >> 4; + } + if (alt_code > 0x10ffff) { + alt_code = 0x10ffff; + } + if (alt_code > 0) { + ime_text = vformat("u%s", String::num_int64(alt_code, 16, true)); } else { - if (k->get_keycode() >= Key::KEY_0 && k->get_keycode() <= Key::KEY_9) { - alt_code = alt_code << 4; - alt_code += (uint32_t)(k->get_keycode() - Key::KEY_0); - } - if (k->get_keycode() >= Key::KP_0 && k->get_keycode() <= Key::KP_9) { - alt_code = alt_code << 4; - alt_code += (uint32_t)(k->get_keycode() - Key::KP_0); - } - if (k->get_keycode() >= Key::A && k->get_keycode() <= Key::F) { - alt_code = alt_code << 4; - alt_code += (uint32_t)(k->get_keycode() - Key::A) + 10; - } - return true; + ime_text = "u"; } + ime_selection = Vector2i(0, -1); + _update_ime_text(); + return true; + } + + // Submit Unicode input. + if ((!k->is_pressed() && alt_start && k->get_keycode() == Key::ALT) || (alt_start_no_hold && (k->is_action("ui_text_submit", true) || k->is_action("ui_accept", true)))) { + alt_start = false; + alt_start_no_hold = false; + if ((alt_code > 0x31 && alt_code < 0xd800) || (alt_code > 0xdfff && alt_code <= 0x10ffff)) { + ime_text = String(); + ime_selection = Vector2i(); + handle_unicode_input(alt_code); + } else { + ime_text = String(); + ime_selection = Vector2i(); + } + _update_ime_text(); + return true; + } + + // Cancel Unicode input. + if (alt_start_no_hold && k->is_action("ui_cancel", true)) { + alt_start = false; + alt_start_no_hold = false; + ime_text = String(); + ime_selection = Vector2i(); + _update_ime_text(); + return true; } } return false; @@ -3117,7 +3171,9 @@ void TextEdit::cancel_ime() { return; } ime_text = String(); - ime_selection = Point2(); + ime_selection = Vector2i(); + alt_start = false; + alt_start_no_hold = false; _close_ime_window(); _update_ime_text(); } @@ -3126,10 +3182,18 @@ void TextEdit::apply_ime() { if (!has_ime_text()) { return; } + // Force apply the current IME text. - String insert_ime_text = ime_text; - cancel_ime(); - insert_text_at_caret(insert_ime_text); + if (alt_start || alt_start_no_hold) { + cancel_ime(); + if ((alt_code > 0x31 && alt_code < 0xd800) || (alt_code > 0xdfff && alt_code <= 0x10ffff)) { + handle_unicode_input(alt_code); + } + } else { + String insert_ime_text = ime_text; + cancel_ime(); + insert_text_at_caret(insert_ime_text); + } } void TextEdit::set_editable(bool p_editable) { @@ -5966,7 +6030,7 @@ void TextEdit::adjust_viewport_to_caret(int p_caret) { // Get position of the end of caret. if (has_ime_text()) { - if (ime_selection.y != 0) { + if (ime_selection.y > 0) { caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x + ime_selection.y, get_caret_line(p_caret), get_caret_column(p_caret)); } else { caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_text.size(), get_caret_line(p_caret), get_caret_column(p_caret)); @@ -6018,7 +6082,7 @@ void TextEdit::center_viewport_to_caret(int p_caret) { // Get position of the end of caret. if (has_ime_text()) { - if (ime_selection.y != 0) { + if (ime_selection.y > 0) { caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x + ime_selection.y, get_caret_line(p_caret), get_caret_column(p_caret)); } else { caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_text.size(), get_caret_line(p_caret), get_caret_column(p_caret)); |