summaryrefslogtreecommitdiffstats
path: root/scene/gui/text_edit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/text_edit.cpp')
-rw-r--r--scene/gui/text_edit.cpp134
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));