diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/code_edit.cpp | 10 | ||||
-rw-r--r-- | scene/gui/color_picker.cpp | 53 | ||||
-rw-r--r-- | scene/gui/color_picker.h | 1 | ||||
-rw-r--r-- | scene/gui/control.cpp | 179 | ||||
-rw-r--r-- | scene/gui/control.h | 12 | ||||
-rw-r--r-- | scene/gui/dialogs.cpp | 6 | ||||
-rw-r--r-- | scene/gui/gradient_edit.cpp | 41 | ||||
-rw-r--r-- | scene/gui/gradient_edit.h | 7 | ||||
-rw-r--r-- | scene/gui/graph_edit.cpp | 16 | ||||
-rw-r--r-- | scene/gui/label.cpp | 78 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 111 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 29 | ||||
-rw-r--r-- | scene/gui/tabs.cpp | 15 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 195 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 8 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 18 | ||||
-rw-r--r-- | scene/gui/tree.h | 2 |
17 files changed, 448 insertions, 333 deletions
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 28d1689ff8..b816f12bc3 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -614,6 +614,11 @@ void CodeEdit::_backspace_internal() { return; } + if (has_selection()) { + delete_selection(); + return; + } + int cc = get_caret_column(); int cl = get_caret_line(); @@ -621,11 +626,6 @@ void CodeEdit::_backspace_internal() { return; } - if (has_selection()) { - delete_selection(); - return; - } - if (cl > 0 && _is_line_hidden(cl - 1)) { unfold_line(get_caret_line() - 1); } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 611035fff9..54548e1941 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -35,7 +35,6 @@ #include "core/os/os.h" #ifdef TOOLS_ENABLED -#include "editor/editor_scale.h" #include "editor/editor_settings.h" #endif #include "scene/main/window.h" @@ -44,17 +43,7 @@ List<Color> ColorPicker::preset_cache; void ColorPicker::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_THEME_CHANGED: { - btn_pick->set_icon(get_theme_icon(SNAME("screen_picker"), SNAME("ColorPicker"))); - btn_add_preset->set_icon(get_theme_icon(SNAME("add_preset"))); - _update_presets(); - _update_controls(); - } break; case NOTIFICATION_ENTER_TREE: { - btn_pick->set_icon(get_theme_icon(SNAME("screen_picker"), SNAME("ColorPicker"))); - btn_add_preset->set_icon(get_theme_icon(SNAME("add_preset"))); - - _update_controls(); _update_color(); #ifdef TOOLS_ENABLED @@ -71,18 +60,39 @@ void ColorPicker::_notification(int p_what) { } } #endif - } break; - case NOTIFICATION_PARENTED: { + [[fallthrough]]; + } + case NOTIFICATION_THEME_CHANGED: { + btn_pick->set_icon(get_theme_icon(SNAME("screen_picker"), SNAME("ColorPicker"))); + btn_add_preset->set_icon(get_theme_icon(SNAME("add_preset"))); + + uv_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height")))); + w_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("h_width")), 0)); + + wheel_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height")))); + wheel_margin->add_theme_constant_override("margin_bottom", 8 * get_theme_default_base_scale()); + for (int i = 0; i < 4; i++) { + labels[i]->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0)); set_offset((Side)i, get_offset((Side)i) + get_theme_constant(SNAME("margin"))); } + + if (Engine::get_singleton()->is_editor_hint()) { + // Adjust for the width of the "Script" icon. + text_type->set_custom_minimum_size(Size2(28 * get_theme_default_base_scale(), 0)); + } + + _update_presets(); + _update_controls(); } break; + case NOTIFICATION_VISIBILITY_CHANGED: { Popup *p = Object::cast_to<Popup>(get_parent()); if (p) { p->set_size(Size2(get_combined_minimum_size().width + get_theme_constant(SNAME("margin")) * 2, get_combined_minimum_size().height + get_theme_constant(SNAME("margin")) * 2)); } } break; + case NOTIFICATION_WM_CLOSE_REQUEST: { if (screen != nullptr && screen->is_visible()) { screen->hide(); @@ -762,11 +772,7 @@ void ColorPicker::_slider_draw(int p_which) { Size2 size = scroll[p_which]->get_size(); Color left_color; Color right_color; -#ifdef TOOLS_ENABLED - const real_t margin = 4 * EDSCALE; -#else - const real_t margin = 4; -#endif + const real_t margin = 4 * get_theme_default_base_scale(); if (p_which == 3) { scroll[p_which]->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true); @@ -1147,7 +1153,6 @@ ColorPicker::ColorPicker() : uv_edit->set_mouse_filter(MOUSE_FILTER_PASS); uv_edit->set_h_size_flags(SIZE_EXPAND_FILL); uv_edit->set_v_size_flags(SIZE_EXPAND_FILL); - uv_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height")))); uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, uv_edit)); HBoxContainer *hb_smpl = memnew(HBoxContainer); @@ -1219,9 +1224,6 @@ ColorPicker::ColorPicker() : text_type->set_text("#"); text_type->set_tooltip(TTR("Switch between hexadecimal and code values.")); if (Engine::get_singleton()->is_editor_hint()) { -#ifdef TOOLS_ENABLED - text_type->set_custom_minimum_size(Size2(28 * EDSCALE, 0)); // Adjust for the width of the "Script" icon. -#endif text_type->connect("pressed", callable_mp(this, &ColorPicker::_text_type_toggled)); } else { text_type->set_flat(true); @@ -1236,7 +1238,6 @@ ColorPicker::ColorPicker() : wheel_edit->set_h_size_flags(SIZE_EXPAND_FILL); wheel_edit->set_v_size_flags(SIZE_EXPAND_FILL); - wheel_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height")))); hb_edit->add_child(wheel_edit); wheel_mat.instantiate(); @@ -1244,12 +1245,7 @@ ColorPicker::ColorPicker() : circle_mat.instantiate(); circle_mat->set_shader(circle_shader); - MarginContainer *wheel_margin(memnew(MarginContainer)); -#ifdef TOOLS_ENABLED - wheel_margin->add_theme_constant_override("margin_bottom", 8 * EDSCALE); -#else wheel_margin->add_theme_constant_override("margin_bottom", 8); -#endif wheel_edit->add_child(wheel_margin); wheel_margin->add_child(wheel); @@ -1261,7 +1257,6 @@ ColorPicker::ColorPicker() : wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, wheel_uv)); hb_edit->add_child(w_edit); - w_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("h_width")), 0)); w_edit->set_h_size_flags(SIZE_FILL); w_edit->set_v_size_flags(SIZE_EXPAND_FILL); w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input)); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 67ca007eb5..ad4f5ad5b1 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -81,6 +81,7 @@ private: Control *uv_edit = memnew(Control); Control *w_edit = memnew(Control); AspectRatioContainer *wheel_edit = memnew(AspectRatioContainer); + MarginContainer *wheel_margin = memnew(MarginContainer); Ref<ShaderMaterial> wheel_mat; Ref<ShaderMaterial> circle_mat; Control *wheel = memnew(Control); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 81411d5844..38da40a402 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -38,7 +38,6 @@ #include "core/os/os.h" #include "core/string/print_string.h" #include "core/string/translation.h" - #include "scene/gui/label.h" #include "scene/gui/panel.h" #include "scene/main/canvas_layer.h" @@ -48,7 +47,6 @@ #include "servers/text_server.h" #ifdef TOOLS_ENABLED -#include "editor/editor_settings.h" #include "editor/plugins/canvas_item_editor_plugin.h" #endif @@ -742,7 +740,7 @@ bool Control::has_point(const Point2 &p_point) const { return Rect2(Point2(), get_size()).has_point(p_point); } -void Control::set_drag_forwarding(Control *p_target) { +void Control::set_drag_forwarding(Node *p_target) { if (p_target) { data.drag_owner = p_target->get_instance_id(); } else { @@ -754,8 +752,7 @@ Variant Control::get_drag_data(const Point2 &p_point) { if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { - Control *c = Object::cast_to<Control>(obj); - return c->call("_get_drag_data_fw", p_point, this); + return obj->call("_get_drag_data_fw", p_point, this); } } @@ -771,8 +768,7 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { - Control *c = Object::cast_to<Control>(obj); - return c->call("_can_drop_data_fw", p_point, p_data, this); + return obj->call("_can_drop_data_fw", p_point, p_data, this); } } @@ -787,8 +783,7 @@ void Control::drop_data(const Point2 &p_point, const Variant &p_data) { if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { - Control *c = Object::cast_to<Control>(obj); - c->call("_drop_data_fw", p_point, p_data, this); + obj->call("_drop_data_fw", p_point, p_data, this); return; } } @@ -836,11 +831,12 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); // First, look through each control or window node in the branch, until no valid parent can be found. - // For each control iterate through its inheritance chain and see if p_name exists in any of them. + // Only nodes with a theme resource attached are considered. Control *theme_owner = p_theme_owner; Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. for (const StringName &E : p_theme_types) { if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); @@ -891,11 +887,12 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); // First, look through each control or window node in the branch, until no valid parent can be found. - // For each control iterate through its inheritance chain and see if p_name exists in any of them. + // Only nodes with a theme resource attached are considered. Control *theme_owner = p_theme_owner; Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. for (const StringName &E : p_theme_types) { if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { return true; @@ -1133,6 +1130,150 @@ bool Control::has_theme_constant(const StringName &p_name, const StringName &p_t return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } +float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_theme_base_scale()) { + return theme_owner->data.theme->get_default_theme_base_scale(); + } + + if (theme_owner_window && theme_owner_window->theme->has_default_theme_base_scale()) { + return theme_owner_window->theme->get_default_theme_base_scale(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } + } + } + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_theme_base_scale()) { + return Theme::get_project_default()->get_default_theme_base_scale(); + } + } + + // Lastly, fall back on the default Theme. + return Theme::get_default()->get_default_theme_base_scale(); +} + +float Control::get_theme_default_base_scale() const { + return fetch_theme_default_base_scale(data.theme_owner, data.theme_owner_window); +} + +Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_theme_font()) { + return theme_owner->data.theme->get_default_theme_font(); + } + + if (theme_owner_window && theme_owner_window->theme->has_default_theme_font()) { + return theme_owner_window->theme->get_default_theme_font(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } + } + } + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_theme_font()) { + return Theme::get_project_default()->get_default_theme_font(); + } + } + + // Lastly, fall back on the default Theme. + return Theme::get_default()->get_default_theme_font(); +} + +Ref<Font> Control::get_theme_default_font() const { + return fetch_theme_default_font(data.theme_owner, data.theme_owner_window); +} + +int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_theme_font_size()) { + return theme_owner->data.theme->get_default_theme_font_size(); + } + + if (theme_owner_window && theme_owner_window->theme->has_default_theme_font_size()) { + return theme_owner_window->theme->get_default_theme_font_size(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } + } + } + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_theme_font_size()) { + return Theme::get_project_default()->get_default_theme_font_size(); + } + } + + // Lastly, fall back on the default Theme. + return Theme::get_default()->get_default_theme_font_size(); +} + +int Control::get_theme_default_font_size() const { + return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window); +} + Rect2 Control::get_parent_anchorable_rect() const { if (!is_inside_tree()) { return Rect2(); @@ -2452,8 +2593,8 @@ bool Control::is_text_field() const { return false; } -Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const { - Vector<Vector2i> ret; +Array Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const { + Array ret; switch (p_theme_type) { case STRUCTURED_TEXT_URI: { int prev = 0; @@ -2619,12 +2760,6 @@ bool Control::is_visibility_clip_disabled() const { } void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { -#ifdef TOOLS_ENABLED - const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; -#else - const String quote_style = "\""; -#endif - Node::get_argument_options(p_function, p_idx, r_options); if (p_idx == 0) { @@ -2644,7 +2779,7 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List sn.sort_custom<StringName::AlphCompare>(); for (const StringName &name : sn) { - r_options->push_back(String(name).quote(quote_style)); + r_options->push_back(String(name).quote()); } } } @@ -2792,6 +2927,10 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Control::has_theme_color, DEFVAL("")); ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Control::has_theme_constant, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_default_base_scale"), &Control::get_theme_default_base_scale); + ClassDB::bind_method(D_METHOD("get_theme_default_font"), &Control::get_theme_default_font); + ClassDB::bind_method(D_METHOD("get_theme_default_font_size"), &Control::get_theme_default_font_size); + ClassDB::bind_method(D_METHOD("get_parent_control"), &Control::get_parent_control); ClassDB::bind_method(D_METHOD("set_h_grow_direction", "direction"), &Control::set_h_grow_direction); diff --git a/scene/gui/control.h b/scene/gui/control.h index 9cec5d6e8d..bdc06319ea 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -283,7 +283,7 @@ protected: //virtual void _window_gui_input(InputEvent p_event); - virtual Vector<Vector2i> structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const; + virtual Array structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const; bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -355,7 +355,7 @@ public: virtual Size2 get_minimum_size() const; virtual Size2 get_combined_minimum_size() const; virtual bool has_point(const Point2 &p_point) const; - virtual void set_drag_forwarding(Control *p_target); + virtual void set_drag_forwarding(Node *p_target); virtual Variant get_drag_data(const Point2 &p_point); virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const; virtual void drop_data(const Point2 &p_point, const Variant &p_data); @@ -509,6 +509,14 @@ public: bool has_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const; bool has_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + static float fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window); + static Ref<Font> fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window); + static int fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window); + + float get_theme_default_base_scale() const; + Ref<Font> get_theme_default_font() const; + int get_theme_default_font_size() const; + /* TOOLTIP */ void set_tooltip(const String &p_tooltip); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 5d98aaa698..71d2778cc3 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -37,7 +37,6 @@ #ifdef TOOLS_ENABLED #include "editor/editor_node.h" -#include "editor/editor_scale.h" #include "scene/main/window.h" // Only used to check for more modals when dimming the editor. #endif @@ -363,8 +362,7 @@ Button *ConfirmationDialog::get_cancel_button() { ConfirmationDialog::ConfirmationDialog() { set_title(TTRC("Please Confirm...")); -#ifdef TOOLS_ENABLED - set_min_size(Size2(200, 70) * EDSCALE); -#endif + set_min_size(Size2(200, 70)); + cancel = add_cancel_button(); } diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 56b8a936e1..5d024d3be7 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -32,15 +32,6 @@ #include "core/os/keyboard.h" -#ifdef TOOLS_ENABLED -#include "editor/editor_scale.h" -#define SPACING (3 * EDSCALE) -#define POINT_WIDTH (8 * EDSCALE) -#else -#define SPACING 3 -#define POINT_WIDTH 8 -#endif - GradientEdit::GradientEdit() { set_focus_mode(FOCUS_ALL); @@ -53,12 +44,12 @@ GradientEdit::GradientEdit() { int GradientEdit::_get_point_from_pos(int x) { int result = -1; - int total_w = get_size().width - get_size().height - SPACING; + int total_w = get_size().width - get_size().height - draw_spacing; float min_distance = 1e20; for (int i = 0; i < points.size(); i++) { //Check if we clicked at point float distance = ABS(x - points[i].offset * total_w); - float min = (POINT_WIDTH / 2 * 1.7); //make it easier to grab + float min = (draw_point_width / 2 * 1.7); //make it easier to grab if (distance <= min && distance < min_distance) { result = i; min_distance = distance; @@ -129,7 +120,7 @@ void GradientEdit::gui_input(const Ref<InputEvent> &p_event) { grabbed = _get_point_from_pos(x); if (grabbed != -1) { - int total_w = get_size().width - get_size().height - SPACING; + int total_w = get_size().width - get_size().height - draw_spacing; Gradient::Point newPoint = points[grabbed]; newPoint.offset = CLAMP(x / float(total_w), 0, 1); @@ -151,10 +142,10 @@ void GradientEdit::gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { update(); int x = mb->get_position().x; - int total_w = get_size().width - get_size().height - SPACING; + int total_w = get_size().width - get_size().height - draw_spacing; //Check if color selector was clicked. - if (x > total_w + SPACING) { + if (x > total_w + draw_spacing) { _show_color_picker(); return; } @@ -225,7 +216,7 @@ void GradientEdit::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid() && grabbing) { - int total_w = get_size().width - get_size().height - SPACING; + int total_w = get_size().width - get_size().height - draw_spacing; int x = mm->get_position().x; @@ -297,6 +288,12 @@ void GradientEdit::_notification(int p_what) { picker->connect("color_changed", callable_mp(this, &GradientEdit::_color_changed)); } } + + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + draw_spacing = BASE_SPACING * get_theme_default_base_scale(); + draw_point_width = BASE_POINT_WIDTH * get_theme_default_base_scale(); + } + if (p_what == NOTIFICATION_DRAW) { int w = get_size().x; int h = get_size().y; @@ -305,7 +302,7 @@ void GradientEdit::_notification(int p_what) { return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size } - int total_w = get_size().width - get_size().height - SPACING; + int total_w = get_size().width - get_size().height - draw_spacing; //Draw checker pattern for ramp draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(0, 0, total_w, h), true); @@ -358,7 +355,7 @@ void GradientEdit::_notification(int p_what) { col.a = 0.9; draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col); - Rect2 rect = Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2); + Rect2 rect = Rect2(points[i].offset * total_w - draw_point_width / 2, h / 2, draw_point_width, h / 2); draw_rect(rect, points[i].color, true); draw_rect(rect, col, false); if (grabbed == i) { @@ -375,15 +372,15 @@ void GradientEdit::_notification(int p_what) { } //Draw "button" for color selector - draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(total_w + SPACING, 0, h, h), true); + draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(total_w + draw_spacing, 0, h, h), true); if (grabbed != -1) { //Draw with selection color - draw_rect(Rect2(total_w + SPACING, 0, h, h), points[grabbed].color); + draw_rect(Rect2(total_w + draw_spacing, 0, h, h), points[grabbed].color); } else { //if no color selected draw grey color with 'X' on top. - draw_rect(Rect2(total_w + SPACING, 0, h, h), Color(0.5, 0.5, 0.5, 1)); - draw_line(Vector2(total_w + SPACING, 0), Vector2(total_w + SPACING + h, h), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + SPACING, h), Vector2(total_w + SPACING + h, 0), Color(1, 1, 1, 0.6)); + draw_rect(Rect2(total_w + draw_spacing, 0, h, h), Color(0.5, 0.5, 0.5, 1)); + draw_line(Vector2(total_w + draw_spacing, 0), Vector2(total_w + draw_spacing + h, h), Color(1, 1, 1, 0.6)); + draw_line(Vector2(total_w + draw_spacing, h), Vector2(total_w + draw_spacing + h, 0), Color(1, 1, 1, 0.6)); } //Draw borders around color ramp if in focus diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index a173631963..f3a39daaf6 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -46,6 +46,13 @@ class GradientEdit : public Control { int grabbed = -1; Vector<Gradient::Point> points; + // Make sure to use the scaled value below. + const int BASE_SPACING = 3; + const int BASE_POINT_WIDTH = 8; + + int draw_spacing = BASE_SPACING; + int draw_point_width = BASE_POINT_WIDTH; + void _draw_checker(int x, int y, int w, int h); void _color_changed(const Color &p_color); int _get_point_from_pos(int x); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index d9c08ec272..35e31be9af 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -36,10 +36,6 @@ #include "scene/gui/box_container.h" #include "scene/gui/button.h" -#ifdef TOOLS_ENABLED -#include "editor/editor_scale.h" -#endif - constexpr int MINIMAP_OFFSET = 12; constexpr int MINIMAP_PADDING = 5; @@ -436,6 +432,8 @@ void GraphEdit::_notification(int p_what) { snap_button->set_icon(get_theme_icon(SNAME("snap"))); minimap_button->set_icon(get_theme_icon(SNAME("minimap"))); layout_button->set_icon(get_theme_icon(SNAME("layout"))); + + zoom_label->set_custom_minimum_size(Size2(48, 0) * get_theme_default_base_scale()); } if (p_what == NOTIFICATION_READY) { Size2 hmin = h_scroll->get_combined_minimum_size(); @@ -816,11 +814,7 @@ void GraphEdit::_draw_connection_line(CanvasItem *p_where, const Vector2 &p_from scaled_points.push_back(points[i] * p_zoom); } -#ifdef TOOLS_ENABLED - p_where->draw_polyline_colors(scaled_points, colors, Math::floor(p_width * EDSCALE), lines_antialiased); -#else - p_where->draw_polyline_colors(scaled_points, colors, p_width, lines_antialiased); -#endif + p_where->draw_polyline_colors(scaled_points, colors, Math::floor(p_width * get_theme_default_base_scale()), lines_antialiased); } void GraphEdit::_connections_layer_draw() { @@ -2272,11 +2266,7 @@ GraphEdit::GraphEdit() { zoom_label->set_visible(false); zoom_label->set_v_size_flags(Control::SIZE_SHRINK_CENTER); zoom_label->set_align(Label::ALIGN_CENTER); -#ifdef TOOLS_ENABLED - zoom_label->set_custom_minimum_size(Size2(48, 0) * EDSCALE); -#else zoom_label->set_custom_minimum_size(Size2(48, 0)); -#endif _update_zoom_label(); zoom_minus = memnew(Button); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 18cde25e55..b8cb618171 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -108,7 +108,7 @@ void Label::_shape() { } lines_rid.clear(); - uint8_t autowrap_flags = TextServer::BREAK_MANDATORY; + uint16_t autowrap_flags = TextServer::BREAK_MANDATORY; switch (autowrap_mode) { case AUTOWRAP_WORD_SMART: autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY; @@ -122,10 +122,10 @@ void Label::_shape() { case AUTOWRAP_OFF: break; } - Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); - for (int i = 0; i < line_breaks.size(); i++) { - RID line = TS->shaped_text_substr(text_rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x); + for (int i = 0; i < line_breaks.size(); i = i + 2) { + RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); lines_rid.push_back(line); } } @@ -145,7 +145,7 @@ void Label::_shape() { } if (lines_dirty) { - uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; + uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; switch (overrun_behavior) { case OVERRUN_TRIM_WORD_ELLIPSIS: overrun_flags |= TextServer::OVERRUN_TRIM; @@ -231,7 +231,7 @@ void Label::_update_visible() { } } -inline void draw_glyph(const TextServer::Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) { +inline void draw_glyph(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) { if (p_gl.font_rid != RID()) { TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off), p_gl.index, p_font_color); } else { @@ -239,7 +239,7 @@ inline void draw_glyph(const TextServer::Glyph &p_gl, const RID &p_canvas, const } } -inline void draw_glyph_outline(const TextServer::Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Color &p_font_shadow_color, const Color &p_font_outline_color, const int &p_shadow_outline_size, const int &p_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) { +inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Color &p_font_shadow_color, const Color &p_font_outline_color, const int &p_shadow_outline_size, const int &p_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) { if (p_gl.font_rid != RID()) { if (p_font_shadow_color.a > 0) { TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off) + shadow_ofs, p_gl.index, p_font_shadow_color); @@ -387,21 +387,25 @@ void Label::_notification(int p_what) { } break; } - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(lines_rid[i]); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); - TextServer::TrimData trim_data = TS->shaped_text_get_trim_data(lines_rid[i]); + const Glyph *glyphs = TS->shaped_text_get_glyphs(lines_rid[i]); + int gl_size = TS->shaped_text_get_glyph_count(lines_rid[i]); + + int ellipsis_pos = TS->shaped_text_get_ellipsis_pos(lines_rid[i]); + int trim_pos = TS->shaped_text_get_trim_pos(lines_rid[i]); + + const Glyph *ellipsis_glyphs = TS->shaped_text_get_ellipsis_glyphs(lines_rid[i]); + int ellipsis_gl_size = TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]); // Draw outline. Note: Do not merge this into the single loop with the main text, to prevent overlaps. if (font_shadow_color.a > 0 || (font_outline_color.a != 0.0 && outline_size > 0)) { Vector2 offset = ofs; // Draw RTL ellipsis string when necessary. - if (rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = trim_data.ellipsis_glyph_buf.size() - 1; gl_idx >= 0; gl_idx--) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (rtl && ellipsis_pos >= 0) { + for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph_outline(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); - offset.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + offset.x += ellipsis_glyphs[gl_idx].advance; } } } @@ -410,13 +414,13 @@ void Label::_notification(int p_what) { for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { // Trim when necessary. - if (trim_data.trim_pos >= 0) { + if (trim_pos >= 0) { if (rtl) { - if (j < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { continue; } } else { - if (j >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { break; } } @@ -428,12 +432,12 @@ void Label::_notification(int p_what) { } } // Draw LTR ellipsis string when necessary. - if (!rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = 0; gl_idx < trim_data.ellipsis_glyph_buf.size(); gl_idx++) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (!rtl && ellipsis_pos >= 0) { + for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph_outline(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); - offset.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + offset.x += ellipsis_glyphs[gl_idx].advance; } } } @@ -442,12 +446,12 @@ void Label::_notification(int p_what) { // Draw main text. Note: Do not merge this into the single loop with the outline, to prevent overlaps. // Draw RTL ellipsis string when necessary. - if (rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = trim_data.ellipsis_glyph_buf.size() - 1; gl_idx >= 0; gl_idx--) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (rtl && ellipsis_pos >= 0) { + for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, ofs); - ofs.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + ofs.x += ellipsis_glyphs[gl_idx].advance; } } } @@ -456,13 +460,13 @@ void Label::_notification(int p_what) { for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { // Trim when necessary. - if (trim_data.trim_pos >= 0) { + if (trim_pos >= 0) { if (rtl) { - if (j < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { continue; } } else { - if (j >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { break; } } @@ -474,12 +478,12 @@ void Label::_notification(int p_what) { } } // Draw LTR ellipsis string when necessary. - if (!rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = 0; gl_idx < trim_data.ellipsis_glyph_buf.size(); gl_idx++) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (!rtl && ellipsis_pos >= 0) { + for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, ofs); - ofs.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + ofs.x += ellipsis_glyphs[gl_idx].advance; } } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 89fd9bfc88..653885aa08 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -40,7 +40,6 @@ #include "servers/display_server.h" #include "servers/text_server.h" #ifdef TOOLS_ENABLED -#include "editor/editor_scale.h" #include "editor/editor_settings.h" #endif #include "scene/main/window.h" @@ -67,10 +66,10 @@ void LineEdit::_move_caret_left(bool p_select, bool p_move_by_word) { if (p_move_by_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < cc) { + cc = words[i]; break; } } @@ -99,10 +98,10 @@ void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) { if (p_move_by_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > cc) { + cc = words[i]; break; } } @@ -151,10 +150,10 @@ void LineEdit::_backspace(bool p_word, bool p_all_to_left) { if (p_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < cc) { + cc = words[i]; break; } } @@ -194,10 +193,10 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) { if (p_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > cc) { + cc = words[i]; break; } } @@ -276,12 +275,12 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { // Double-click select word. last_dblclk = OS::get_singleton()->get_ticks_msec(); last_dblclk_pos = b->get_position(); - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if ((words[i].x < caret_column && words[i].y > caret_column) || (i == words.size() - 1 && caret_column == words[i].y)) { + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 0; i < words.size(); i = i + 2) { + if ((words[i] < caret_column && words[i + 1] > caret_column) || (i == words.size() - 2 && caret_column == words[i + 1])) { selection.enabled = true; - selection.begin = words[i].x; - selection.end = words[i].y; + selection.begin = words[i]; + selection.end = words[i + 1]; selection.double_click = true; caret_column = selection.end; break; @@ -713,11 +712,7 @@ void LineEdit::_notification(int p_what) { ofs_max -= r_icon->get_width(); } -#ifdef TOOLS_ENABLED - int caret_width = Math::round(EDSCALE); -#else - int caret_width = 1; -#endif + int caret_width = Math::round(1 * get_theme_default_base_scale()); // Draw selections rects. Vector2 ofs = Point2(x_ofs + scroll_offset, y_ofs); @@ -737,9 +732,8 @@ void LineEdit::_notification(int p_what) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, selection_color); } } - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(text_rid); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); + const Glyph *glyphs = TS->shaped_text_get_glyphs(text_rid); + int gl_size = TS->shaped_text_get_glyph_count(text_rid); // Draw text. ofs.y += TS->shaped_text_get_ascent(text_rid); @@ -783,38 +777,36 @@ void LineEdit::_notification(int p_what) { if (draw_caret) { if (ime_text.length() == 0) { // Normal caret. - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; - TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir); + CaretInfo caret = TS->shaped_text_get_carets(text_rid, caret_column); - if (l_caret == Rect2() && t_caret == Rect2()) { + if (caret.l_caret == Rect2() && caret.t_caret == Rect2()) { // No carets, add one at the start. int h = get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size"))); int y = style->get_offset().y + (y_area - h) / 2; if (rtl) { - l_dir = TextServer::DIRECTION_RTL; - l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h)); + caret.l_dir = TextServer::DIRECTION_RTL; + caret.l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h)); } else { - l_dir = TextServer::DIRECTION_LTR; - l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h)); + caret.l_dir = TextServer::DIRECTION_LTR; + caret.l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h)); } - RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color); } else { - if (l_caret != Rect2() && l_dir == TextServer::DIRECTION_AUTO) { + if (caret.l_caret != Rect2() && caret.l_dir == TextServer::DIRECTION_AUTO) { // Draw extra marker on top of mid caret. - Rect2 trect = Rect2(l_caret.position.x - 3 * caret_width, l_caret.position.y, 6 * caret_width, caret_width); + Rect2 trect = Rect2(caret.l_caret.position.x - 3 * caret_width, caret.l_caret.position.y, 6 * caret_width, caret_width); trect.position += ofs; RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color); } - l_caret.position += ofs; - l_caret.size.x = caret_width; - RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color); + caret.l_caret.position += ofs; + caret.l_caret.size.x = caret_width; + RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color); - t_caret.position += ofs; - t_caret.size.x = caret_width; + caret.t_caret.position += ofs; + caret.t_caret.size.x = caret_width; - RenderingServer::get_singleton()->canvas_item_add_rect(ci, t_caret, caret_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.t_caret, caret_color); } } else { { @@ -1114,32 +1106,31 @@ Vector2i LineEdit::get_caret_pixel_pos() { } Vector2i ret; - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; + CaretInfo caret; // Get position of the start of caret. if (ime_text.length() != 0 && ime_selection.x != 0) { - TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x, l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x); } else { - TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column); } - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - ret.x = x_ofs + l_caret.position.x + scroll_offset; + if ((caret.l_caret != Rect2() && (caret.l_dir == TextServer::DIRECTION_AUTO || caret.l_dir == (TextServer::Direction)input_direction)) || (caret.t_caret == Rect2())) { + ret.x = x_ofs + caret.l_caret.position.x + scroll_offset; } else { - ret.x = x_ofs + t_caret.position.x + scroll_offset; + ret.x = x_ofs + caret.t_caret.position.x + scroll_offset; } // Get position of the end of caret. if (ime_text.length() != 0) { if (ime_selection.y != 0) { - TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x + ime_selection.y, l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x + ime_selection.y); } else { - TS->shaped_text_get_carets(text_rid, caret_column + ime_text.size(), l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_text.size()); } - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - ret.y = x_ofs + l_caret.position.x + scroll_offset; + if ((caret.l_caret != Rect2() && (caret.l_dir == TextServer::DIRECTION_AUTO || caret.l_dir == (TextServer::Direction)input_direction)) || (caret.t_caret == Rect2())) { + ret.y = x_ofs + caret.l_caret.position.x + scroll_offset; } else { - ret.y = x_ofs + t_caret.position.x + scroll_offset; + ret.y = x_ofs + caret.t_caret.position.x + scroll_offset; } } else { ret.y = ret.x; @@ -1502,7 +1493,7 @@ void LineEdit::insert_text_at_caret(String p_text) { String post = text.substr(caret_column, text.length() - caret_column); text = pre + p_text + post; _shape(); - TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length()); + TextServer::Direction dir = TS->shaped_text_get_dominant_direction_in_range(text_rid, caret_column, caret_column + p_text.length()); if (dir != TextServer::DIRECTION_AUTO) { input_direction = (TextDirection)dir; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 277026cc28..4588966d88 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -41,10 +41,6 @@ #include "modules/regex/regex.h" #endif -#ifdef TOOLS_ENABLED -#include "editor/editor_scale.h" -#endif - RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) const { if (p_free) { if (p_item->subitems.size()) { @@ -819,9 +815,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); + const Glyph *glyphs = TS->shaped_text_get_glyphs(rid); + int gl_size = TS->shaped_text_get_glyph_count(rid); Vector2 gloff = off; // Draw oulines and shadow. @@ -996,19 +991,13 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o Color uc = font_color; uc.a *= 0.5; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid); -#ifdef TOOLS_ENABLED - underline_width *= EDSCALE; -#endif + float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width); } else if (_find_strikethrough(it)) { Color uc = font_color; uc.a *= 0.5; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; - float underline_width = TS->shaped_text_get_underline_thickness(rid); -#ifdef TOOLS_ENABLED - underline_width *= EDSCALE; -#endif + float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width); } @@ -1593,18 +1582,18 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) { if (c_frame) { const Line &l = c_frame->lines[c_line]; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(l.text_buf->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (c_index >= words[i].x && c_index < words[i].y) { + PackedInt32Array words = TS->shaped_text_get_word_breaks(l.text_buf->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if (c_index >= words[i] && c_index < words[i + 1]) { selection.from_frame = c_frame; selection.from_line = c_line; selection.from_item = c_item; - selection.from_char = words[i].x; + selection.from_char = words[i]; selection.to_frame = c_frame; selection.to_line = c_line; selection.to_item = c_item; - selection.to_char = words[i].y; + selection.to_char = words[i + 1]; selection.active = true; update(); diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index ef34bec347..f305bf7013 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -156,6 +156,7 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) { if (scrolling_enabled && buttons_visible) { if (missing_right) { offset++; + _ensure_no_over_offset(); // Avoid overreaching when scrolling fast. update(); } } @@ -164,7 +165,7 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) { if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (rb_hover != -1) { //pressed - emit_signal(SNAME("right_button_pressed"), rb_hover); + emit_signal(SNAME("tab_rmb_clicked"), rb_hover); } rb_pressing = false; @@ -401,7 +402,7 @@ void Tabs::_notification(int p_what) { w += tabs[i].size_text; if (tabs[i].right_button.is_valid()) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("button")); + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); Ref<Texture2D> rb = tabs[i].right_button; w += get_theme_constant(SNAME("hseparation")); @@ -433,7 +434,7 @@ void Tabs::_notification(int p_what) { } if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("button")); + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); Ref<Texture2D> cb = close; w += get_theme_constant(SNAME("hseparation")); @@ -449,7 +450,7 @@ void Tabs::_notification(int p_what) { if (!tabs[i].disabled && cb_hover == i) { if (cb_pressing) { - get_theme_stylebox(SNAME("button_pressed"))->draw(ci, cb_rect); + get_theme_stylebox(SNAME("close_bg_pressed"))->draw(ci, cb_rect); } else { style->draw(ci, cb_rect); } @@ -886,7 +887,7 @@ void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) { hover_now = get_tab_count() - 1; } move_tab(tab_from_id, hover_now); - emit_signal(SNAME("reposition_active_tab_request"), hover_now); + emit_signal(SNAME("active_tab_rearranged"), hover_now); set_current_tab(hover_now); } else if (get_tabs_rearrange_group() != -1) { // drag and drop between Tabs @@ -1165,10 +1166,10 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("get_select_with_rmb"), &Tabs::get_select_with_rmb); ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); - ADD_SIGNAL(MethodInfo("right_button_pressed", PropertyInfo(Variant::INT, "tab"))); + ADD_SIGNAL(MethodInfo("tab_rmb_clicked", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("tab_closed", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("tab_hovered", PropertyInfo(Variant::INT, "tab"))); - ADD_SIGNAL(MethodInfo("reposition_active_tab_request", PropertyInfo(Variant::INT, "idx_to"))); + ADD_SIGNAL(MethodInfo("active_tab_rearranged", PropertyInfo(Variant::INT, "idx_to"))); ADD_SIGNAL(MethodInfo("tab_clicked", PropertyInfo(Variant::INT, "tab"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 5e165be15e..57bcbb7c2d 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -42,10 +42,6 @@ #include "scene/main/window.h" -#ifdef TOOLS_ENABLED -#include "editor/editor_scale.h" -#endif - static bool _is_text_char(char32_t c) { return !is_symbol(c); } @@ -186,7 +182,7 @@ void TextEdit::Text::_calculate_max_line_width() { max_width = width; } -void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Vector<Vector2i> &p_bidi_override) { +void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Array &p_bidi_override) { ERR_FAIL_INDEX(p_line, text.size()); if (font.is_null() || font_size <= 0) { @@ -278,14 +274,14 @@ void TextEdit::Text::invalidate_all() { void TextEdit::Text::clear() { text.clear(); - insert(0, "", Vector<Vector2i>()); + insert(0, "", Array()); } int TextEdit::Text::get_max_width() const { return max_width; } -void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override) { +void TextEdit::Text::set(int p_line, const String &p_text, const Array &p_bidi_override) { ERR_FAIL_INDEX(p_line, text.size()); text.write[p_line].data = p_text; @@ -293,7 +289,7 @@ void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i invalidate_cache(p_line); } -void TextEdit::Text::insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override) { +void TextEdit::Text::insert(int p_at, const String &p_text, const Array &p_bidi_override) { Line line; line.gutters.resize(gutter_count); line.hidden = false; @@ -1076,9 +1072,8 @@ void TextEdit::_notification(int p_what) { ofs_y += (row_height - text_height) / 2; - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); + const Glyph *glyphs = TS->shaped_text_get_glyphs(rid); + int gl_size = TS->shaped_text_get_glyph_count(rid); ofs_y += ldata->get_line_ascent(line_wrap_index); int char_ofs = 0; @@ -1174,38 +1169,33 @@ void TextEdit::_notification(int p_what) { } } - // Carets -#ifdef TOOLS_ENABLED - int caret_width = Math::round(EDSCALE); -#else - int caret_width = 1; -#endif + // Carets. + int caret_width = Math::round(1 * get_theme_default_base_scale()); if (!clipped && caret.line == line && line_wrap_index == caret_wrap_index) { caret.draw_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index); if (ime_text.length() == 0) { - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; + CaretInfo ts_caret; if (str.length() != 0) { // Get carets. - TS->shaped_text_get_carets(rid, caret.column, l_caret, l_dir, t_caret, t_dir); + ts_caret = TS->shaped_text_get_carets(rid, caret.column); } else { // No carets, add one at the start. int h = font->get_height(font_size); if (rtl) { - l_dir = TextServer::DIRECTION_RTL; - l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h)); + ts_caret.l_dir = TextServer::DIRECTION_RTL; + ts_caret.l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h)); } else { - l_dir = TextServer::DIRECTION_LTR; - l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h)); + ts_caret.l_dir = TextServer::DIRECTION_LTR; + ts_caret.l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h)); } } - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - caret.draw_pos.x = char_margin + ofs_x + l_caret.position.x; + if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) { + caret.draw_pos.x = char_margin + ofs_x + ts_caret.l_caret.position.x; } else { - caret.draw_pos.x = char_margin + ofs_x + t_caret.position.x; + caret.draw_pos.x = char_margin + ofs_x + ts_caret.t_caret.position.x; } if (caret.draw_pos.x >= xmargin_beg && caret.draw_pos.x < xmargin_end) { @@ -1215,64 +1205,64 @@ void TextEdit::_notification(int p_what) { //Block or underline caret, draw trailing carets at full height. int h = font->get_height(font_size); - if (t_caret != Rect2()) { + if (ts_caret.t_caret != Rect2()) { if (overtype_mode) { - t_caret.position.y = TS->shaped_text_get_descent(rid); - t_caret.size.y = caret_width; + ts_caret.t_caret.position.y = TS->shaped_text_get_descent(rid); + ts_caret.t_caret.size.y = caret_width; } else { - t_caret.position.y = -TS->shaped_text_get_ascent(rid); - t_caret.size.y = h; + ts_caret.t_caret.position.y = -TS->shaped_text_get_ascent(rid); + ts_caret.t_caret.size.y = h; } - t_caret.position += Vector2(char_margin + ofs_x, ofs_y); - draw_rect(t_caret, caret_color, overtype_mode); + ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y); + draw_rect(ts_caret.t_caret, caret_color, overtype_mode); - if (l_caret != Rect2() && l_dir != t_dir) { - l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - l_caret.size.x = caret_width; - draw_rect(l_caret, caret_color * Color(1, 1, 1, 0.5)); + if (ts_caret.l_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) { + ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); + ts_caret.l_caret.size.x = caret_width; + draw_rect(ts_caret.l_caret, caret_color * Color(1, 1, 1, 0.5)); } } else { // End of the line. if (gl_size > 0) { // Adjust for actual line dimensions. if (overtype_mode) { - l_caret.position.y = TS->shaped_text_get_descent(rid); - l_caret.size.y = caret_width; + ts_caret.l_caret.position.y = TS->shaped_text_get_descent(rid); + ts_caret.l_caret.size.y = caret_width; } else { - l_caret.position.y = -TS->shaped_text_get_ascent(rid); - l_caret.size.y = h; + ts_caret.l_caret.position.y = -TS->shaped_text_get_ascent(rid); + ts_caret.l_caret.size.y = h; } } else if (overtype_mode) { - l_caret.position.y += l_caret.size.y; - l_caret.size.y = caret_width; + ts_caret.l_caret.position.y += ts_caret.l_caret.size.y; + ts_caret.l_caret.size.y = caret_width; } - if (l_caret.position.x >= TS->shaped_text_get_size(rid).x) { - l_caret.size.x = font->get_char_size('m', 0, font_size).x; + if (ts_caret.l_caret.position.x >= TS->shaped_text_get_size(rid).x) { + ts_caret.l_caret.size.x = font->get_char_size('m', 0, font_size).x; } else { - l_caret.size.x = 3 * caret_width; + ts_caret.l_caret.size.x = 3 * caret_width; } - l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - if (l_dir == TextServer::DIRECTION_RTL) { - l_caret.position.x -= l_caret.size.x; + ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); + if (ts_caret.l_dir == TextServer::DIRECTION_RTL) { + ts_caret.l_caret.position.x -= ts_caret.l_caret.size.x; } - draw_rect(l_caret, caret_color, overtype_mode); + draw_rect(ts_caret.l_caret, caret_color, overtype_mode); } } else { // Normal caret. - if (l_caret != Rect2() && l_dir == TextServer::DIRECTION_AUTO) { + if (ts_caret.l_caret != Rect2() && ts_caret.l_dir == TextServer::DIRECTION_AUTO) { // Draw extra marker on top of mid caret. - Rect2 trect = Rect2(l_caret.position.x - 3 * caret_width, l_caret.position.y, 6 * caret_width, caret_width); + Rect2 trect = Rect2(ts_caret.l_caret.position.x - 3 * caret_width, ts_caret.l_caret.position.y, 6 * caret_width, caret_width); trect.position += Vector2(char_margin + ofs_x, ofs_y); RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color); } - l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - l_caret.size.x = caret_width; + ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); + ts_caret.l_caret.size.x = caret_width; - draw_rect(l_caret, caret_color); + draw_rect(ts_caret.l_caret, caret_color); - t_caret.position += Vector2(char_margin + ofs_x, ofs_y); - t_caret.size.x = caret_width; + ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y); + ts_caret.t_caret.size.x = caret_width; - draw_rect(t_caret, caret_color); + draw_rect(ts_caret.t_caret, caret_color); } } } @@ -1968,10 +1958,10 @@ void TextEdit::_move_caret_left(bool p_select, bool p_move_by_word) { set_caret_line(caret.line - 1); set_caret_column(text[caret.line].length()); } else { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < cc) { + cc = words[i]; break; } } @@ -2019,10 +2009,10 @@ void TextEdit::_move_caret_right(bool p_select, bool p_move_by_word) { set_caret_line(caret.line + 1); set_caret_column(0); } else { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > cc) { + cc = words[i]; break; } } @@ -2214,10 +2204,10 @@ void TextEdit::_do_backspace(bool p_word, bool p_all_to_left) { int line = caret.line; int column = caret.column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < column) { - column = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < column) { + column = words[i]; break; } } @@ -2257,10 +2247,10 @@ void TextEdit::_delete(bool p_word, bool p_all_to_right) { int line = caret.line; int column = caret.column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > column) { - column = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > column) { + column = words[i]; break; } } @@ -3631,10 +3621,10 @@ int TextEdit::get_caret_wrap_index() const { } String TextEdit::get_word_under_caret() const { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].x <= caret.column && words[i].y > caret.column) { - return text[caret.line].substr(words[i].x, words[i].y - words[i].x); + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if (words[i] <= caret.column && words[i + 1] > caret.column) { + return text[caret.line].substr(words[i], words[i + 1] - words[i]); } } return ""; @@ -3718,11 +3708,11 @@ void TextEdit::select_word_under_caret() { int begin = 0; int end = 0; - const Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if ((words[i].x < caret.column && words[i].y > caret.column) || (i == words.size() - 1 && caret.column == words[i].y)) { - begin = words[i].x; - end = words[i].y; + const PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if ((words[i] < caret.column && words[i + 1] > caret.column) || (i == words.size() - 2 && caret.column == words[i + 1])) { + begin = words[i]; + end = words[i + 1]; break; } } @@ -5082,10 +5072,12 @@ void TextEdit::_cut_internal() { } int cl = get_caret_line(); + int cc = get_caret_column(); + int indent_level = get_indent_level(cl); + double hscroll = get_h_scroll(); String clipboard = text[cl]; DisplayServer::get_singleton()->clipboard_set(clipboard); - set_caret_line(cl); set_caret_column(0); if (cl == 0 && get_line_count() > 1) { @@ -5096,6 +5088,17 @@ void TextEdit::_cut_internal() { set_caret_line(get_caret_line() + 1); } + // Correct the visualy perceived caret column taking care of identation level of the lines. + int diff_indent = indent_level - get_indent_level(get_caret_line()); + cc += diff_indent; + if (diff_indent != 0) { + cc += diff_indent > 0 ? -1 : 1; + } + + // Restore horizontal scroll and caret column modified by the backspace() call. + set_h_scroll(hscroll); + set_caret_column(cc); + cut_copy_line = clipboard; } @@ -5376,14 +5379,12 @@ int TextEdit::_get_column_x_offset_for_line(int p_char, int p_line) const { } } - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; RID text_rid = text.get_line_data(p_line)->get_line_rid(row); - TS->shaped_text_get_carets(text_rid, caret.column, l_caret, l_dir, t_caret, t_dir); - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - return l_caret.position.x; + CaretInfo ts_caret = TS->shaped_text_get_carets(text_rid, caret.column); + if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) { + return ts_caret.l_caret.position.x; } else { - return t_caret.position.x; + return ts_caret.t_caret.position.x; } } @@ -5440,11 +5441,11 @@ void TextEdit::_update_selection_mode_word() { int caret_pos = CLAMP(col, 0, text[line].length()); int beg = caret_pos; int end = beg; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if ((words[i].x < caret_pos && words[i].y > caret_pos) || (i == words.size() - 1 && caret_pos == words[i].y)) { - beg = words[i].x; - end = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if ((words[i] < caret_pos && words[i + 1] > caret_pos) || (i == words.size() - 2 && caret_pos == words[i + 1])) { + beg = words[i]; + end = words[i + 1]; break; } } @@ -6032,7 +6033,7 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i r_end_line = p_line + substrings.size() - 1; r_end_column = text[r_end_line].length() - postinsert_text.length(); - TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text.get_line_data(r_end_line)->get_rid(), (r_end_line == p_line) ? caret.column : 0, r_end_column); + TextServer::Direction dir = TS->shaped_text_get_dominant_direction_in_range(text.get_line_data(r_end_line)->get_rid(), (r_end_line == p_line) ? caret.column : 0, r_end_column); if (dir != TextServer::DIRECTION_AUTO) { input_direction = (TextDirection)dir; } diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index db16d09c58..07e585847a 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -139,7 +139,7 @@ private: Vector<Gutter> gutters; String data; - Vector<Vector2i> bidi_override; + Array bidi_override; Ref<TextParagraph> data_buf; Color background_color = Color(0, 0, 0, 0); @@ -194,7 +194,7 @@ private: Vector<Vector2i> get_line_wrap_ranges(int p_line) const; const Ref<TextParagraph> get_line_data(int p_line) const; - void set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override); + void set(int p_line, const String &p_text, const Array &p_bidi_override); void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; if (!p_hidden && text[p_line].width > max_width) { @@ -204,12 +204,12 @@ private: } } bool is_hidden(int p_line) const { return text[p_line].hidden; } - void insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override); + void insert(int p_at, const String &p_text, const Array &p_bidi_override); void remove(int p_at); int size() const { return text.size(); } void clear(); - void invalidate_cache(int p_line, int p_column = -1, const String &p_ime_text = String(), const Vector<Vector2i> &p_bidi_override = Vector<Vector2i>()); + void invalidate_cache(int p_line, int p_column = -1, const String &p_ime_text = String(), const Array &p_bidi_override = Array()); void invalidate_all(); void invalidate_all_lines(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 7d7596635c..3f041bf65a 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -41,10 +41,6 @@ #include "box_container.h" -#ifdef TOOLS_ENABLED -#include "editor/editor_scale.h" -#endif - #include <limits.h> Size2 TreeItem::Cell::get_icon_size() const { @@ -1377,6 +1373,8 @@ void Tree::update_cache() { cache.title_button_hover = get_theme_stylebox(SNAME("title_button_hover")); cache.title_button_color = get_theme_color(SNAME("title_button_color")); + cache.base_scale = get_theme_default_base_scale(); + v_scroll->set_custom_step(cache.font->get_height(cache.font_size)); } @@ -2046,15 +2044,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 root_pos -= Point2i(cache.arrow->get_width(), 0); } - float line_width = cache.relationship_line_width; - float parent_line_width = cache.parent_hl_line_width; - float children_line_width = cache.children_hl_line_width; - -#ifdef TOOLS_ENABLED - line_width *= Math::round(EDSCALE); - parent_line_width *= Math::round(EDSCALE); - children_line_width *= Math::round(EDSCALE); -#endif + float line_width = cache.relationship_line_width * Math::round(cache.base_scale); + float parent_line_width = cache.parent_hl_line_width * Math::round(cache.base_scale); + float children_line_width = cache.children_hl_line_width * Math::round(cache.base_scale); Point2i parent_pos = Point2i(parent_ofs - cache.arrow->get_width() / 2, p_pos.y + label_h / 2 + cache.arrow->get_height() / 2) - cache.offset + p_draw_ofs; diff --git a/scene/gui/tree.h b/scene/gui/tree.h index c4a6b6b058..6ca9458e9b 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -516,6 +516,8 @@ private: Color custom_button_font_highlight; Color font_outline_color; + float base_scale = 1.0; + int hseparation = 0; int vseparation = 0; int item_margin = 0; |