diff options
Diffstat (limited to 'scene/gui/line_edit.cpp')
| -rw-r--r-- | scene/gui/line_edit.cpp | 507 |
1 files changed, 255 insertions, 252 deletions
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index fdddf0b5fa..251f31ce4e 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -36,39 +36,36 @@ #include "core/print_string.h" #include "core/translation.h" #include "label.h" - +#include "servers/display_server.h" #ifdef TOOLS_ENABLED #include "editor/editor_scale.h" #include "editor/editor_settings.h" #endif - +#include "scene/main/window.h" static bool _is_text_char(CharType c) { - return !is_symbol(c); } void LineEdit::_gui_input(Ref<InputEvent> p_event) { - Ref<InputEventMouseButton> b = p_event; if (b.is_valid()) { - if (b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && context_menu_enabled) { menu->set_position(get_global_transform().xform(get_local_mouse_position())); menu->set_size(Vector2(1, 1)); - menu->set_scale(get_global_transform().get_scale()); + //menu->set_scale(get_global_transform().get_scale()); menu->popup(); grab_focus(); accept_event(); return; } - if (b->get_button_index() != BUTTON_LEFT) + if (b->get_button_index() != BUTTON_LEFT) { return; + } _reset_caret_blink_timer(); if (b->is_pressed()) { - accept_event(); //don't pass event further when clicked on text field if (!text.empty() && is_editable() && _is_over_clear_button(b->get_position())) { clear_button_status.press_attempt = true; @@ -81,14 +78,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { set_cursor_at_pixel_pos(b->get_position().x); if (b->get_shift()) { - selection_fill_at_cursor(); selection.creating = true; } else { - if (b->is_doubleclick() && selecting_enabled) { - selection.enabled = true; selection.begin = 0; selection.end = text.length(); @@ -98,12 +92,10 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { selection.drag_attempt = false; if ((cursor_pos < selection.begin) || (cursor_pos > selection.end) || !selection.enabled) { - deselect(); selection.cursor_start = cursor_pos; selection.creating = true; } else if (selection.enabled) { - selection.drag_attempt = true; } } @@ -111,7 +103,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { update(); } else { - if (!text.empty() && is_editable() && clear_button_enabled) { bool press_attempt = clear_button_status.press_attempt; clear_button_status.press_attempt = false; @@ -127,8 +118,13 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { selection.creating = false; selection.doubleclick = false; - if (OS::get_singleton()->has_virtual_keyboard()) - OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length); + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) { + if (selection.enabled) { + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end); + } else { + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos); + } + } } update(); @@ -137,7 +133,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { - if (!text.empty() && is_editable() && clear_button_enabled) { bool last_press_inside = clear_button_status.pressing_inside; clear_button_status.pressing_inside = clear_button_status.press_attempt && _is_over_clear_button(m->get_position()); @@ -147,7 +142,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } if (m->get_button_mask() & BUTTON_LEFT) { - if (selection.creating) { set_cursor_at_pixel_pos(m->get_position().x); selection_fill_at_cursor(); @@ -158,9 +152,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventKey> k = p_event; if (k.is_valid()) { - - if (!k->is_pressed()) + if (!k->is_pressed()) { return; + } #ifdef APPLE_STYLE_KEYS if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) { @@ -202,11 +196,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { unsigned int code = k->get_keycode(); if (k->get_command() && is_shortcut_keys_enabled()) { - bool handled = true; switch (code) { - case (KEY_X): { // CUT. if (editable) { @@ -224,7 +216,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { case (KEY_V): { // PASTE. if (editable) { - paste_text(); } @@ -243,7 +234,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { case (KEY_U): { // Delete from start to cursor. if (editable) { - deselect(); text = text.substr(cursor_pos, text.length() - cursor_pos); update_cached_width(); @@ -256,7 +246,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { case (KEY_Y): { // PASTE (Yank for unix users). if (editable) { - paste_text(); } @@ -264,7 +253,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { case (KEY_K): { // Delete from cursor_pos to end. if (editable) { - deselect(); text = text.substr(0, cursor_pos); _text_changed(); @@ -277,10 +265,30 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } break; #ifdef APPLE_STYLE_KEYS case (KEY_LEFT): { // Go to start of text - like HOME key. + shift_selection_check_pre(k->get_shift()); set_cursor_position(0); + shift_selection_check_post(k->get_shift()); } break; case (KEY_RIGHT): { // Go to end of text - like END key. + shift_selection_check_pre(k->get_shift()); set_cursor_position(text.length()); + shift_selection_check_post(k->get_shift()); + } break; + case (KEY_BACKSPACE): { + if (!editable) + break; + + // If selected, delete the selection + if (selection.enabled) { + selection_delete(); + break; + } + + // Otherwise delete from cursor to beginning of text edit + int current_pos = get_cursor_position(); + if (current_pos != 0) { + delete_text(0, current_pos); + } } break; #endif default: { @@ -296,24 +304,21 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { _reset_caret_blink_timer(); if (!k->get_metakey()) { - bool handled = true; switch (code) { - case KEY_KP_ENTER: case KEY_ENTER: { - emit_signal("text_entered", text); - if (OS::get_singleton()->has_virtual_keyboard()) - OS::get_singleton()->hide_virtual_keyboard(); + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) { + DisplayServer::get_singleton()->virtual_keyboard_hide(); + } - return; } break; case KEY_BACKSPACE: { - - if (!editable) + if (!editable) { break; + } if (selection.enabled) { selection_delete(); @@ -334,8 +339,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { while (cc > 0) { bool ischar = _is_text_char(text[cc - 1]); - if (prev_char && !ischar) + if (prev_char && !ischar) { break; + } prev_char = ischar; cc--; @@ -377,7 +383,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (k->get_command()) { set_cursor_position(0); } else if (k->get_alt()) { - #else if (k->get_alt()) { handled = false; @@ -390,8 +395,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { while (cc > 0) { bool ischar = _is_text_char(text[cc - 1]); - if (prev_char && !ischar) + if (prev_char && !ischar) { break; + } prev_char = ischar; cc--; @@ -445,8 +451,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { while (cc < text.length()) { bool ischar = _is_text_char(text[cc]); - if (prev_char && !ischar) + if (prev_char && !ischar) { break; + } prev_char = ischar; cc++; @@ -462,23 +469,25 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } break; case KEY_UP: { - shift_selection_check_pre(k->get_shift()); - if (get_cursor_position() == 0) handled = false; + if (get_cursor_position() == 0) { + handled = false; + } set_cursor_position(0); shift_selection_check_post(k->get_shift()); } break; case KEY_DOWN: { - shift_selection_check_pre(k->get_shift()); - if (get_cursor_position() == text.length()) handled = false; + if (get_cursor_position() == text.length()) { + handled = false; + } set_cursor_position(text.length()); shift_selection_check_post(k->get_shift()); } break; case KEY_DELETE: { - - if (!editable) + if (!editable) { break; + } if (k->get_shift() && !k->get_command() && !k->get_alt()) { cut_text(); @@ -492,8 +501,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { int text_len = text.length(); - if (cursor_pos == text_len) + if (cursor_pos == text_len) { break; // Nothing to do. + } #ifdef APPLE_STYLE_KEYS if (k->get_alt()) { @@ -508,11 +518,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { bool prev_char = false; while (cc < text.length()) { - bool ischar = _is_text_char(text[cc]); - if (prev_char && !ischar) + if (prev_char && !ischar) { break; + } prev_char = ischar; cc++; } @@ -533,7 +543,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { [[fallthrough]]; } case KEY_HOME: { - shift_selection_check_pre(k->get_shift()); set_cursor_position(0); shift_selection_check_post(k->get_shift()); @@ -546,24 +555,22 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { [[fallthrough]]; } case KEY_END: { - shift_selection_check_pre(k->get_shift()); set_cursor_position(text.length()); shift_selection_check_post(k->get_shift()); } break; case KEY_MENU: { if (context_menu_enabled) { - Point2 pos = Point2(get_cursor_pixel_pos(), (get_size().y + get_font("font")->get_height()) / 2); + Point2 pos = Point2(get_cursor_pixel_pos(), (get_size().y + get_theme_font("font")->get_height()) / 2); menu->set_position(get_global_transform().xform(pos)); menu->set_size(Vector2(1, 1)); - menu->set_scale(get_global_transform().get_scale()); + // menu->set_scale(get_global_transform().get_scale()); menu->popup(); menu->grab_focus(); } } break; default: { - handled = false; } break; } @@ -572,7 +579,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { accept_event(); } else if (!k->get_command()) { if (k->get_unicode() >= 32 && k->get_keycode() != KEY_DELETE) { - if (editable) { selection_delete(); CharType ucodestr[2] = { (CharType)k->get_unicode(), 0 }; @@ -597,19 +603,16 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } void LineEdit::set_align(Align p_align) { - ERR_FAIL_INDEX((int)p_align, 4); align = p_align; update(); } LineEdit::Align LineEdit::get_align() const { - return align; } Variant LineEdit::get_drag_data(const Point2 &p_point) { - if (selection.drag_attempt && selection.enabled) { String t = text.substr(selection.begin, selection.end - selection.begin); Label *l = memnew(Label); @@ -620,20 +623,21 @@ Variant LineEdit::get_drag_data(const Point2 &p_point) { return Variant(); } -bool LineEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const { +bool LineEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const { return p_data.get_type() == Variant::STRING; } -void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) { +void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) { if (p_data.get_type() == Variant::STRING) { set_cursor_at_pixel_pos(p_point.x); int selected = selection.end - selection.begin; - Ref<Font> font = get_font("font"); - if (font != NULL) { - for (int i = selection.begin; i < selection.end; i++) - cached_width -= font->get_char_size(text[i]).width; + Ref<Font> font = get_theme_font("font"); + if (font != nullptr) { + for (int i = selection.begin; i < selection.end; i++) { + cached_width -= font->get_char_size(pass ? secret_character[0] : text[i]).width; + } } text.erase(selection.begin, selected); @@ -655,13 +659,12 @@ bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const { if (!clear_button_enabled || !has_point(p_pos)) { return false; } - Ref<Texture2D> icon = Control::get_icon("clear"); - int x_ofs = get_stylebox("normal")->get_offset().x; + Ref<Texture2D> icon = Control::get_theme_icon("clear"); + int x_ofs = get_theme_stylebox("normal")->get_offset().x; return p_pos.x > get_size().width - icon->get_width() - x_ofs; } void LineEdit::_notification(int p_what) { - switch (p_what) { #ifdef TOOLS_ENABLED case NOTIFICATION_ENTER_TREE: { @@ -676,7 +679,6 @@ void LineEdit::_notification(int p_what) { } break; #endif case NOTIFICATION_RESIZED: { - window_pos = 0; set_cursor_position(get_cursor_position()); @@ -686,18 +688,17 @@ void LineEdit::_notification(int p_what) { update_placeholder_width(); update(); } break; - case MainLoop::NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { window_has_focus = true; draw_caret = true; update(); } break; - case MainLoop::NOTIFICATION_WM_FOCUS_OUT: { + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { window_has_focus = false; draw_caret = false; update(); } break; case NOTIFICATION_DRAW: { - if ((!has_focus() && !menu->has_focus()) || !window_has_focus) { draw_caret = false; } @@ -710,19 +711,18 @@ void LineEdit::_notification(int p_what) { RID ci = get_canvas_item(); - Ref<StyleBox> style = get_stylebox("normal"); + Ref<StyleBox> style = get_theme_stylebox("normal"); if (!is_editable()) { - style = get_stylebox("read_only"); + style = get_theme_stylebox("read_only"); draw_caret = false; } - Ref<Font> font = get_font("font"); + Ref<Font> font = get_theme_font("font"); style->draw(ci, Rect2(Point2(), size)); if (has_focus()) { - - get_stylebox("focus")->draw(ci, Rect2(Point2(), size)); + get_theme_stylebox("focus")->draw(ci, Rect2(Point2(), size)); } int x_ofs = 0; @@ -730,21 +730,18 @@ void LineEdit::_notification(int p_what) { int cached_text_width = using_placeholder ? cached_placeholder_width : cached_width; switch (align) { - case ALIGN_FILL: case ALIGN_LEFT: { - x_ofs = style->get_offset().x; } break; case ALIGN_CENTER: { - - if (window_pos != 0) + if (window_pos != 0) { x_ofs = style->get_offset().x; - else + } else { x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - (cached_text_width)) / 2); + } } break; case ALIGN_RIGHT: { - x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_text_width))); } break; } @@ -757,25 +754,26 @@ void LineEdit::_notification(int p_what) { int font_ascent = font->get_ascent(); - Color selection_color = get_color("selection_color"); - Color font_color = is_editable() ? get_color("font_color") : get_color("font_color_uneditable"); - Color font_color_selected = get_color("font_color_selected"); - Color cursor_color = get_color("cursor_color"); + Color selection_color = get_theme_color("selection_color"); + Color font_color = is_editable() ? get_theme_color("font_color") : get_theme_color("font_color_uneditable"); + Color font_color_selected = get_theme_color("font_color_selected"); + Color cursor_color = get_theme_color("cursor_color"); const String &t = using_placeholder ? placeholder_translated : text; // Draw placeholder color. - if (using_placeholder) + if (using_placeholder) { font_color.a *= placeholder_alpha; + } bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture2D> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon("clear") : right_icon; Color color_icon(1, 1, 1, !is_editable() ? .5 * .9 : .9); if (display_clear_icon) { if (clear_button_status.press_attempt && clear_button_status.pressing_inside) { - color_icon = get_color("clear_button_color_pressed"); + color_icon = get_theme_color("clear_button_color_pressed"); } else { - color_icon = get_color("clear_button_color"); + color_icon = get_theme_color("clear_button_color"); } } @@ -795,30 +793,32 @@ void LineEdit::_notification(int p_what) { int caret_height = font->get_height() > y_area ? y_area : font->get_height(); FontDrawer drawer(font, Color(1, 1, 1)); while (true) { - // End of string, break. - if (char_ofs >= t.length()) + if (char_ofs >= t.length()) { break; + } if (char_ofs == cursor_pos) { if (ime_text.length() > 0) { int ofs = 0; while (true) { - if (ofs >= ime_text.length()) + if (ofs >= ime_text.length()) { break; + } CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs]; CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1]; int im_char_width = font->get_char_size(cchar, next).width; - if ((x_ofs + im_char_width) > ofs_max) + if ((x_ofs + im_char_width) > ofs_max) { break; + } bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y; if (selected) { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 3)), font_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 3)), font_color); } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 1)), font_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 1)), font_color); } drawer.draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, font_color); @@ -834,13 +834,15 @@ void LineEdit::_notification(int p_what) { int char_width = font->get_char_size(cchar, next).width; // End of widget, break. - if ((x_ofs + char_width) > ofs_max) + if ((x_ofs + char_width) > ofs_max) { break; + } bool selected = selection.enabled && char_ofs >= selection.begin && char_ofs < selection.end; - if (selected) - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, caret_height)), selection_color); + if (selected) { + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, caret_height)), selection_color); + } int yofs = y_ofs + (caret_height - font->get_height()) / 2; drawer.draw_char(ci, Point2(x_ofs, yofs + font_ascent), cchar, next, selected ? font_color_selected : font_color); @@ -848,9 +850,9 @@ void LineEdit::_notification(int p_what) { if (char_ofs == cursor_pos && draw_caret && !using_placeholder) { if (ime_text.length() == 0) { #ifdef TOOLS_ENABLED - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(Math::round(EDSCALE), caret_height)), cursor_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(Math::round(EDSCALE), caret_height)), cursor_color); #else - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(1, caret_height)), cursor_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(1, caret_height)), cursor_color); #endif } } @@ -863,21 +865,23 @@ void LineEdit::_notification(int p_what) { if (ime_text.length() > 0) { int ofs = 0; while (true) { - if (ofs >= ime_text.length()) + if (ofs >= ime_text.length()) { break; + } CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs]; CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1]; int im_char_width = font->get_char_size(cchar, next).width; - if ((x_ofs + im_char_width) > ofs_max) + if ((x_ofs + im_char_width) > ofs_max) { break; + } bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y; if (selected) { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 3)), font_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 3)), font_color); } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 1)), font_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 1)), font_color); } drawer.draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, font_color); @@ -906,55 +910,63 @@ void LineEdit::_notification(int p_what) { } } #ifdef TOOLS_ENABLED - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(caret_x_ofs, y_ofs), Size2(Math::round(EDSCALE), caret_height)), cursor_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(caret_x_ofs, y_ofs), Size2(Math::round(EDSCALE), caret_height)), cursor_color); #else - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(caret_x_ofs, y_ofs), Size2(1, caret_height)), cursor_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(caret_x_ofs, y_ofs), Size2(1, caret_height)), cursor_color); #endif } } if (has_focus()) { - - OS::get_singleton()->set_ime_active(true); - OS::get_singleton()->set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + caret_height)); + if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) { + 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 + caret_height), get_viewport()->get_window_id()); + } } } break; case NOTIFICATION_FOCUS_ENTER: { - if (caret_blink_enabled) { caret_blink_timer->start(); } else { draw_caret = true; } - OS::get_singleton()->set_ime_active(true); - Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height; - OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos); + if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id()); + Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height; + DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id()); + } - if (OS::get_singleton()->has_virtual_keyboard()) - OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length); + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) { + if (selection.enabled) { + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end); + } else { + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos); + } + } } break; case NOTIFICATION_FOCUS_EXIT: { - if (caret_blink_enabled) { caret_blink_timer->stop(); } - OS::get_singleton()->set_ime_position(Point2()); - OS::get_singleton()->set_ime_active(false); + if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_set_ime_position(Point2(), get_viewport()->get_window_id()); + DisplayServer::get_singleton()->window_set_ime_active(false, get_viewport()->get_window_id()); + } ime_text = ""; ime_selection = Point2(); - if (OS::get_singleton()->has_virtual_keyboard()) - OS::get_singleton()->hide_virtual_keyboard(); + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) { + DisplayServer::get_singleton()->virtual_keyboard_hide(); + } } break; case MainLoop::NOTIFICATION_OS_IME_UPDATE: { - if (has_focus()) { - ime_text = OS::get_singleton()->get_ime_text(); - ime_selection = OS::get_singleton()->get_ime_selection(); + ime_text = DisplayServer::get_singleton()->ime_get_text(); + ime_selection = DisplayServer::get_singleton()->ime_get_selection(); update(); } } break; @@ -962,29 +974,27 @@ void LineEdit::_notification(int p_what) { } void LineEdit::copy_text() { - if (selection.enabled && !pass) { - OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); + DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin)); } } void LineEdit::cut_text() { - if (selection.enabled && !pass) { - OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); + DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin)); selection_delete(); } } void LineEdit::paste_text() { - // Strip escape characters like \n and \t as they can't be displayed on LineEdit. - String paste_buffer = OS::get_singleton()->get_clipboard().strip_escapes(); + String paste_buffer = DisplayServer::get_singleton()->clipboard_get().strip_escapes(); if (paste_buffer != "") { - int prev_len = text.length(); - if (selection.enabled) selection_delete(); + if (selection.enabled) { + selection_delete(); + } append_at_cursor(paste_buffer); if (!text_changed_dirty) { @@ -997,7 +1007,7 @@ void LineEdit::paste_text() { } void LineEdit::undo() { - if (undo_stack_pos == NULL) { + if (undo_stack_pos == nullptr) { if (undo_stack.size() <= 1) { return; } @@ -1012,14 +1022,15 @@ void LineEdit::undo() { window_pos = op.window_pos; set_cursor_position(op.cursor_pos); - if (expand_to_text_length) + if (expand_to_text_length) { minimum_size_changed(); + } _emit_text_change(); } void LineEdit::redo() { - if (undo_stack_pos == NULL) { + if (undo_stack_pos == nullptr) { return; } if (undo_stack_pos == undo_stack.back()) { @@ -1032,68 +1043,66 @@ void LineEdit::redo() { window_pos = op.window_pos; set_cursor_position(op.cursor_pos); - if (expand_to_text_length) + if (expand_to_text_length) { minimum_size_changed(); + } _emit_text_change(); } void LineEdit::shift_selection_check_pre(bool p_shift) { - if (!selection.enabled && p_shift) { selection.cursor_start = cursor_pos; } - if (!p_shift) + if (!p_shift) { deselect(); + } } void LineEdit::shift_selection_check_post(bool p_shift) { - - if (p_shift) + if (p_shift) { selection_fill_at_cursor(); + } } void LineEdit::set_cursor_at_pixel_pos(int p_x) { - - Ref<Font> font = get_font("font"); + Ref<Font> font = get_theme_font("font"); int ofs = window_pos; - Ref<StyleBox> style = get_stylebox("normal"); + Ref<StyleBox> style = get_theme_stylebox("normal"); int pixel_ofs = 0; Size2 size = get_size(); bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled; - int r_icon_width = Control::get_icon("clear")->get_width(); + int r_icon_width = Control::get_theme_icon("clear")->get_width(); switch (align) { - case ALIGN_FILL: case ALIGN_LEFT: { - pixel_ofs = int(style->get_offset().x); } break; case ALIGN_CENTER: { - - if (window_pos != 0) + if (window_pos != 0) { pixel_ofs = int(style->get_offset().x); - else + } else { pixel_ofs = int(size.width - (cached_width)) / 2; + } - if (display_clear_icon) + if (display_clear_icon) { pixel_ofs -= int(r_icon_width / 2 + style->get_margin(MARGIN_RIGHT)); + } } break; case ALIGN_RIGHT: { - pixel_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_width)); - if (display_clear_icon) + if (display_clear_icon) { pixel_ofs -= int(r_icon_width + style->get_margin(MARGIN_RIGHT)); + } } break; } while (ofs < text.length()) { - int char_w = 0; - if (font != NULL) { - char_w = font->get_char_size(text[ofs]).width; + if (font != nullptr) { + char_w = font->get_char_size(pass ? secret_character[0] : text[ofs]).width; } pixel_ofs += char_w; @@ -1108,44 +1117,42 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) { } int LineEdit::get_cursor_pixel_pos() { - - Ref<Font> font = get_font("font"); + Ref<Font> font = get_theme_font("font"); int ofs = window_pos; - Ref<StyleBox> style = get_stylebox("normal"); + Ref<StyleBox> style = get_theme_stylebox("normal"); int pixel_ofs = 0; Size2 size = get_size(); bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled; - int r_icon_width = Control::get_icon("clear")->get_width(); + int r_icon_width = Control::get_theme_icon("clear")->get_width(); switch (align) { - case ALIGN_FILL: case ALIGN_LEFT: { - pixel_ofs = int(style->get_offset().x); } break; case ALIGN_CENTER: { - - if (window_pos != 0) + if (window_pos != 0) { pixel_ofs = int(style->get_offset().x); - else + } else { pixel_ofs = int(size.width - (cached_width)) / 2; + } - if (display_clear_icon) + if (display_clear_icon) { pixel_ofs -= int(r_icon_width / 2 + style->get_margin(MARGIN_RIGHT)); + } } break; case ALIGN_RIGHT: { - pixel_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_width)); - if (display_clear_icon) + if (display_clear_icon) { pixel_ofs -= int(r_icon_width + style->get_margin(MARGIN_RIGHT)); + } } break; } while (ofs < cursor_pos) { - if (font != NULL) { - pixel_ofs += font->get_char_size(text[ofs]).width; + if (font != nullptr) { + pixel_ofs += font->get_char_size(pass ? secret_character[0] : text[ofs]).width; } ofs++; } @@ -1199,12 +1206,13 @@ void LineEdit::_toggle_draw_caret() { } void LineEdit::delete_char() { + if ((text.length() <= 0) || (cursor_pos == 0)) { + return; + } - if ((text.length() <= 0) || (cursor_pos == 0)) return; - - Ref<Font> font = get_font("font"); - if (font != NULL) { - cached_width -= font->get_char_size(text[cursor_pos - 1]).width; + Ref<Font> font = get_theme_font("font"); + if (font != nullptr) { + cached_width -= font->get_char_size(pass ? secret_character[0] : text[cursor_pos - 1]).width; } text.erase(cursor_pos - 1, 1); @@ -1219,12 +1227,14 @@ void LineEdit::delete_char() { } void LineEdit::delete_text(int p_from_column, int p_to_column) { - + ERR_FAIL_COND_MSG(p_from_column < 0 || p_from_column > p_to_column || p_to_column > text.length(), + vformat("Positional parameters (from: %d, to: %d) are inverted or outside the text length (%d).", p_from_column, p_to_column, text.length())); if (text.size() > 0) { - Ref<Font> font = get_font("font"); - if (font != NULL) { - for (int i = p_from_column; i < p_to_column; i++) - cached_width -= font->get_char_size(text[i]).width; + Ref<Font> font = get_theme_font("font"); + if (font != nullptr) { + for (int i = p_from_column; i < p_to_column; i++) { + cached_width -= font->get_char_size(pass ? secret_character[0] : text[i]).width; + } } } else { cached_width = 0; @@ -1234,11 +1244,9 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) { cursor_pos -= CLAMP(cursor_pos - p_from_column, 0, p_to_column - p_from_column); if (cursor_pos >= text.length()) { - cursor_pos = text.length(); } if (window_pos > cursor_pos) { - window_pos = cursor_pos; } @@ -1255,7 +1263,6 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) { } void LineEdit::set_text(String p_text) { - clear_internal(); append_at_cursor(p_text); @@ -1269,18 +1276,15 @@ void LineEdit::set_text(String p_text) { } void LineEdit::clear() { - clear_internal(); _text_changed(); } String LineEdit::get_text() const { - return text; } void LineEdit::set_placeholder(String p_text) { - placeholder = p_text; placeholder_translated = tr(placeholder); update_placeholder_width(); @@ -1288,39 +1292,36 @@ void LineEdit::set_placeholder(String p_text) { } String LineEdit::get_placeholder() const { - return placeholder; } void LineEdit::set_placeholder_alpha(float p_alpha) { - placeholder_alpha = p_alpha; update(); } float LineEdit::get_placeholder_alpha() const { - return placeholder_alpha; } void LineEdit::set_cursor_position(int p_pos) { - - if (p_pos > (int)text.length()) + if (p_pos > (int)text.length()) { p_pos = text.length(); + } - if (p_pos < 0) + if (p_pos < 0) { p_pos = 0; + } cursor_pos = p_pos; if (!is_inside_tree()) { - window_pos = cursor_pos; return; } - Ref<StyleBox> style = get_stylebox("normal"); - Ref<Font> font = get_font("font"); + Ref<StyleBox> style = get_theme_stylebox("normal"); + Ref<Font> font = get_theme_font("font"); if (cursor_pos <= window_pos) { // Adjust window if cursor goes too much to the left. @@ -1330,52 +1331,56 @@ void LineEdit::set_cursor_position(int p_pos) { int window_width = get_size().width - style->get_minimum_size().width; bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture2D> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon("clear") : right_icon; window_width -= r_icon->get_width(); } - if (window_width < 0) + if (window_width < 0) { return; + } int wp = window_pos; if (font.is_valid()) { - int accum_width = 0; for (int i = cursor_pos; i >= window_pos; i--) { - if (i >= text.length()) { // Do not do this, because if the cursor is at the end, its just fine that it takes no space. // accum_width = font->get_char_size(' ').width; } else { - accum_width += font->get_char_size(text[i], i + 1 < text.length() ? text[i + 1] : 0).width; // Anything should do. + if (pass) { + accum_width += font->get_char_size(secret_character[0], i + 1 < text.length() ? secret_character[0] : 0).width; + } else { + accum_width += font->get_char_size(text[i], i + 1 < text.length() ? text[i + 1] : 0).width; // Anything should do. + } } - if (accum_width > window_width) + if (accum_width > window_width) { break; + } wp = i; } } - if (wp != window_pos) + if (wp != window_pos) { set_window_pos(wp); + } } update(); } int LineEdit::get_cursor_position() const { - return cursor_pos; } void LineEdit::set_window_pos(int p_pos) { - window_pos = p_pos; - if (window_pos < 0) window_pos = 0; + if (window_pos < 0) { + window_pos = 0; + } } void LineEdit::append_at_cursor(String p_text) { - if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) { String pre = text.substr(0, cursor_pos); String post = text.substr(cursor_pos, text.length() - cursor_pos); @@ -1388,7 +1393,6 @@ void LineEdit::append_at_cursor(String p_text) { } void LineEdit::clear_internal() { - deselect(); _clear_undo_stack(); cached_width = 0; @@ -1400,15 +1404,14 @@ void LineEdit::clear_internal() { } Size2 LineEdit::get_minimum_size() const { - - Ref<StyleBox> style = get_stylebox("normal"); - Ref<Font> font = get_font("font"); + Ref<StyleBox> style = get_theme_stylebox("normal"); + Ref<Font> font = get_theme_font("font"); Size2 min_size; // Minimum size of text. int space_size = font->get_char_size(' ').x; - min_size.width = get_constant("minimum_spaces") * space_size; + min_size.width = get_theme_constant("minimum_spaces") * space_size; if (expand_to_text_length) { // Add a space because some fonts are too exact, and because cursor needs a bit more when at the end. @@ -1419,8 +1422,8 @@ Size2 LineEdit::get_minimum_size() const { // Take icons into account. if (!text.empty() && is_editable() && clear_button_enabled) { - min_size.width = MAX(min_size.width, Control::get_icon("clear")->get_width()); - min_size.height = MAX(min_size.height, Control::get_icon("clear")->get_height()); + min_size.width = MAX(min_size.width, Control::get_theme_icon("clear")->get_width()); + min_size.height = MAX(min_size.height, Control::get_theme_icon("clear")->get_height()); } if (right_icon.is_valid()) { min_size.width = MAX(min_size.width, right_icon->get_width()); @@ -1431,7 +1434,6 @@ Size2 LineEdit::get_minimum_size() const { } void LineEdit::deselect() { - selection.begin = 0; selection.end = 0; selection.cursor_start = 0; @@ -1442,28 +1444,27 @@ void LineEdit::deselect() { } void LineEdit::selection_delete() { - - if (selection.enabled) + if (selection.enabled) { delete_text(selection.begin, selection.end); + } deselect(); } void LineEdit::set_max_length(int p_max_length) { - ERR_FAIL_COND(p_max_length < 0); max_length = p_max_length; set_text(text); } int LineEdit::get_max_length() const { - return max_length; } void LineEdit::selection_fill_at_cursor() { - if (!selecting_enabled) + if (!selecting_enabled) { return; + } selection.begin = cursor_pos; selection.end = selection.cursor_start; @@ -1478,11 +1479,13 @@ void LineEdit::selection_fill_at_cursor() { } void LineEdit::select_all() { - if (!selecting_enabled) + if (!selecting_enabled) { return; + } - if (!text.length()) + if (!text.length()) { return; + } selection.begin = 0; selection.end = text.length(); @@ -1491,9 +1494,9 @@ void LineEdit::select_all() { } void LineEdit::set_editable(bool p_editable) { - - if (editable == p_editable) + if (editable == p_editable) { return; + } editable = p_editable; _generate_context_menu(); @@ -1503,24 +1506,20 @@ void LineEdit::set_editable(bool p_editable) { } bool LineEdit::is_editable() const { - return editable; } void LineEdit::set_secret(bool p_secret) { - pass = p_secret; update_cached_width(); update(); } bool LineEdit::is_secret() const { - return pass; } void LineEdit::set_secret_character(const String &p_string) { - // An empty string as the secret character would crash the engine. // It also wouldn't make sense to use multiple characters as the secret character. ERR_FAIL_COND_MSG(p_string.length() != 1, "Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given)."); @@ -1535,8 +1534,9 @@ String LineEdit::get_secret_character() const { } void LineEdit::select(int p_from, int p_to) { - if (!selecting_enabled) + if (!selecting_enabled) { return; + } if (p_from == 0 && p_to == 0) { deselect(); @@ -1544,15 +1544,19 @@ void LineEdit::select(int p_from, int p_to) { } int len = text.length(); - if (p_from < 0) + if (p_from < 0) { p_from = 0; - if (p_from > len) + } + if (p_from > len) { p_from = len; - if (p_to < 0 || p_to > len) + } + if (p_to < 0 || p_to > len) { p_to = len; + } - if (p_from >= p_to) + if (p_from >= p_to) { return; + } selection.enabled = true; selection.begin = p_from; @@ -1563,12 +1567,10 @@ void LineEdit::select(int p_from, int p_to) { } bool LineEdit::is_text_field() const { - return true; } void LineEdit::menu_option(int p_option) { - switch (p_option) { case MENU_CUT: { if (editable) { @@ -1576,7 +1578,6 @@ void LineEdit::menu_option(int p_option) { } } break; case MENU_COPY: { - copy_text(); } break; case MENU_PASTE: { @@ -1625,7 +1626,6 @@ void LineEdit::_editor_settings_changed() { } void LineEdit::set_expand_to_text_length(bool p_enabled) { - expand_to_text_length = p_enabled; minimum_size_changed(); set_window_pos(0); @@ -1661,8 +1661,9 @@ bool LineEdit::is_shortcut_keys_enabled() const { void LineEdit::set_selecting_enabled(bool p_enabled) { selecting_enabled = p_enabled; - if (!selecting_enabled) + if (!selecting_enabled) { deselect(); + } _generate_context_menu(); } @@ -1685,8 +1686,9 @@ Ref<Texture2D> LineEdit::get_right_icon() { } void LineEdit::_text_changed() { - if (expand_to_text_length) + if (expand_to_text_length) { minimum_size_changed(); + } _emit_text_change(); _clear_redo(); @@ -1699,9 +1701,9 @@ void LineEdit::_emit_text_change() { } void LineEdit::update_cached_width() { - Ref<Font> font = get_font("font"); + Ref<Font> font = get_theme_font("font"); cached_width = 0; - if (font != NULL) { + if (font != nullptr) { String text = get_text(); for (int i = 0; i < text.length(); i++) { cached_width += font->get_char_size(pass ? secret_character[0] : text[i]).width; @@ -1710,20 +1712,18 @@ void LineEdit::update_cached_width() { } void LineEdit::update_placeholder_width() { - if ((max_length <= 0) || (placeholder_translated.length() <= max_length)) { - Ref<Font> font = get_font("font"); - cached_placeholder_width = 0; - if (font != NULL) { - for (int i = 0; i < placeholder_translated.length(); i++) { - cached_placeholder_width += font->get_char_size(placeholder_translated[i]).width; - } + Ref<Font> font = get_theme_font("font"); + cached_placeholder_width = 0; + if (font != nullptr) { + for (int i = 0; i < placeholder_translated.length(); i++) { + cached_placeholder_width += font->get_char_size(placeholder_translated[i]).width; } } } void LineEdit::_clear_redo() { _create_undo_state(); - if (undo_stack_pos == NULL) { + if (undo_stack_pos == nullptr) { return; } @@ -1738,7 +1738,7 @@ void LineEdit::_clear_redo() { void LineEdit::_clear_undo_stack() { undo_stack.clear(); - undo_stack_pos = NULL; + undo_stack_pos = nullptr; _create_undo_state(); } @@ -1754,14 +1754,17 @@ void LineEdit::_create_undo_state() { void LineEdit::_generate_context_menu() { // Reorganize context menu. menu->clear(); - if (editable) + if (editable) { menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0); + } menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0); - if (editable) + if (editable) { menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0); + } menu->add_separator(); - if (is_selecting_enabled()) + if (is_selecting_enabled()) { menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0); + } if (editable) { menu->add_item(RTR("Clear"), MENU_CLEAR); menu->add_separator(); @@ -1771,7 +1774,6 @@ void LineEdit::_generate_context_menu() { } void LineEdit::_bind_methods() { - ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed); ClassDB::bind_method(D_METHOD("set_align", "align"), &LineEdit::set_align); @@ -1799,6 +1801,8 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_max_length", "chars"), &LineEdit::set_max_length); ClassDB::bind_method(D_METHOD("get_max_length"), &LineEdit::get_max_length); ClassDB::bind_method(D_METHOD("append_at_cursor", "text"), &LineEdit::append_at_cursor); + ClassDB::bind_method(D_METHOD("delete_char_at_cursor"), &LineEdit::delete_char); + ClassDB::bind_method(D_METHOD("delete_text", "from_column", "to_column"), &LineEdit::delete_text); ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &LineEdit::set_editable); ClassDB::bind_method(D_METHOD("is_editable"), &LineEdit::is_editable); ClassDB::bind_method(D_METHOD("set_secret", "enabled"), &LineEdit::set_secret); @@ -1858,8 +1862,7 @@ void LineEdit::_bind_methods() { } LineEdit::LineEdit() { - - undo_stack_pos = NULL; + undo_stack_pos = nullptr; _create_undo_state(); align = ALIGN_LEFT; cached_width = 0; |
