diff options
Diffstat (limited to 'scene/gui')
| -rw-r--r-- | scene/gui/aspect_ratio_container.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/button.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/color_picker.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/control.cpp | 4 | ||||
| -rw-r--r-- | scene/gui/graph_node.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/label.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/line_edit.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/link_button.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.cpp | 43 | ||||
| -rw-r--r-- | scene/gui/rich_text_label.h | 2 | ||||
| -rw-r--r-- | scene/gui/scroll_container.cpp | 42 | ||||
| -rw-r--r-- | scene/gui/scroll_container.h | 3 | ||||
| -rw-r--r-- | scene/gui/split_container.cpp | 2 | ||||
| -rw-r--r-- | scene/gui/text_edit.cpp | 5 | ||||
| -rw-r--r-- | scene/gui/tree.cpp | 101 | ||||
| -rw-r--r-- | scene/gui/tree.h | 8 |
16 files changed, 151 insertions, 73 deletions
diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp index c7f6c0e2da..fb6fa9dec9 100644 --- a/scene/gui/aspect_ratio_container.cpp +++ b/scene/gui/aspect_ratio_container.cpp @@ -155,7 +155,7 @@ void AspectRatioContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_alignment_vertical"), &AspectRatioContainer::get_alignment_vertical); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ratio"), "set_ratio", "get_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Width controls height,Height controls width,Fit,Cover"), "set_stretch_mode", "get_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Width Controls Height,Height Controls Width,Fit,Cover"), "set_stretch_mode", "get_stretch_mode"); ADD_GROUP("Alignment", "alignment_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment_horizontal", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment_horizontal", "get_alignment_horizontal"); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index b0bcde8865..c0df5271b4 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -533,7 +533,7 @@ void Button::_bind_methods() { BIND_ENUM_CONSTANT(ALIGN_RIGHT); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 9ccb2886e1..c0b4563615 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -91,7 +91,6 @@ void ColorPicker::init_shaders() { wheel_shader.instance(); wheel_shader->set_code( "shader_type canvas_item;" - "const float TAU = 6.28318530718;" "void fragment() {" " float x = UV.x - 0.5;" " float y = UV.y - 0.5;" @@ -111,7 +110,6 @@ void ColorPicker::init_shaders() { circle_shader.instance(); circle_shader->set_code( "shader_type canvas_item;" - "const float TAU = 6.28318530718;" "uniform float v = 1.0;" "void fragment() {" " float x = UV.x - 0.5;" diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 83abd02b40..0ae1dec46d 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2801,7 +2801,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_v_grow_direction", "get_v_grow_direction"); ADD_GROUP("Layout Direction", "layout_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-right,Right-to-left"), "set_layout_direction", "get_layout_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); ADD_GROUP("Rect", "rect_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); @@ -2828,7 +2828,7 @@ void Control::_bind_methods() { ADD_GROUP("Mouse", "mouse_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_filter", PROPERTY_HINT_ENUM, "Stop,Pass,Ignore"), "set_mouse_filter", "get_mouse_filter"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,Ibeam,Pointing hand,Cross,Wait,Busy,Drag,Can drop,Forbidden,Vertical resize,Horizontal resize,Secondary diagonal resize,Main diagonal resize,Move,Vertical split,Horizontal split,Help"), "set_default_cursor_shape", "get_default_cursor_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,I-Beam,Pointing Hand,Cross,Wait,Busy,Drag,Can Drop,Forbidden,Vertical Resize,Horizontal Resize,Secondary Diagonal Resize,Main Diagonal Resize,Move,Vertical Split,Horizontal Split,Help"), "set_default_cursor_shape", "get_default_cursor_shape"); ADD_GROUP("Size Flags", "size_flags_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags"); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 1ca54a16ae..77c502cf8d 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -999,7 +999,7 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("get_overlay"), &GraphNode::get_overlay); ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset"), "set_position_offset", "get_position_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible"); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index be73fd8f51..de0ee626b9 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -695,7 +695,7 @@ void Label::_bind_methods() { BIND_ENUM_CONSTANT(VALIGN_FILL); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); ADD_PROPERTY(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign"); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 98dd9f624b..c2ed9c1a3c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -2209,7 +2209,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 1f7b61e3d1..d45ffde715 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -292,7 +292,7 @@ void LinkButton::_bind_methods() { BIND_ENUM_CONSTANT(UNDERLINE_MODE_NEVER); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 2800ab0442..a2c3b4ed8a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2232,18 +2232,22 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub int size = p_item->subitems.size(); if (size == 0) { p_item->parent->subitems.erase(p_item); + // If a newline was erased, all lines AFTER the newline need to be decremented. if (p_item->type == ITEM_NEWLINE) { current_frame->lines.remove(p_line); - for (int i = p_subitem_line; i < current->subitems.size(); i++) { - if (current->subitems[i]->line > 0) { + for (int i = 0; i < current->subitems.size(); i++) { + if (current->subitems[i]->line > p_subitem_line) { current->subitems[i]->line--; } } } } else { + // First, remove all child items for the provided item. for (int i = 0; i < size; i++) { _remove_item(p_item->subitems.front()->get(), p_line, p_subitem_line); } + // Then remove the provided item itself. + p_item->parent->subitems.erase(p_item); } } @@ -2303,21 +2307,23 @@ bool RichTextLabel::remove_line(const int p_line) { return false; } - int i = 0; - while (i < current->subitems.size() && current->subitems[i]->line < p_line) { - i++; + // Remove all subitems with the same line as that provided. + Vector<int> subitem_indices_to_remove; + for (int i = 0; i < current->subitems.size(); i++) { + if (current->subitems[i]->line == p_line) { + subitem_indices_to_remove.push_back(i); + } } - bool was_newline = false; - while (i < current->subitems.size()) { - was_newline = current->subitems[i]->type == ITEM_NEWLINE; - _remove_item(current->subitems[i], current->subitems[i]->line, p_line); - if (was_newline) { - break; - } + bool had_newline = false; + // Reverse for loop to remove items from the end first. + for (int i = subitem_indices_to_remove.size() - 1; i >= 0; i--) { + int subitem_idx = subitem_indices_to_remove[i]; + had_newline = had_newline || current->subitems[subitem_idx]->type == ITEM_NEWLINE; + _remove_item(current->subitems[subitem_idx], current->subitems[subitem_idx]->line, p_line); } - if (!was_newline) { + if (!had_newline) { current_frame->lines.remove(p_line); if (current_frame->lines.size() == 0) { current_frame->lines.resize(1); @@ -2329,6 +2335,7 @@ bool RichTextLabel::remove_line(const int p_line) { } main->first_invalid_line = 0; // p_line ??? + update(); return true; } @@ -2613,14 +2620,6 @@ void RichTextLabel::pop() { current = current->parent; } -// Creates a new line without adding an ItemNewline to the previous line. -// Useful when wanting to calling remove_line and add a new line immediately after. -void RichTextLabel::increment_line_count() { - _validate_line_caches(main); - current_frame->lines.resize(current_frame->lines.size() + 1); - _invalidate_current_line(current_frame); -} - void RichTextLabel::clear() { main->_clear_children(); current = main; @@ -3935,7 +3934,7 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, "RichTextEffect", (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index afc88e070a..e3e457d1f2 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -483,8 +483,6 @@ public: void push_cell(); void pop(); - void increment_line_count(); - void clear(); void set_offset(int p_pixel); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 46db4a3c2f..5f872644ab 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -238,32 +238,25 @@ void ScrollContainer::_update_scrollbar_position() { _updating_scrollbars = false; } -void ScrollContainer::_ensure_focused_visible(Control *p_control) { - if (!follow_focus) { - return; +void ScrollContainer::_gui_focus_changed(Control *p_control) { + if (follow_focus && is_a_parent_of(p_control)) { + ensure_control_visible(p_control); } +} - if (is_a_parent_of(p_control)) { - Rect2 global_rect = get_global_rect(); - Rect2 other_rect = p_control->get_global_rect(); - float right_margin = 0.0; - if (v_scroll->is_visible()) { - right_margin += v_scroll->get_size().x; - } - float bottom_margin = 0.0; - if (h_scroll->is_visible()) { - bottom_margin += h_scroll->get_size().y; - } +void ScrollContainer::ensure_control_visible(Control *p_control) { + ERR_FAIL_COND_MSG(!is_a_parent_of(p_control), "Must be a parent of the control."); - float diff = MAX(MIN(other_rect.position.y, global_rect.position.y), other_rect.position.y + other_rect.size.y - global_rect.size.y + bottom_margin); - set_v_scroll(get_v_scroll() + (diff - global_rect.position.y)); - if (is_layout_rtl()) { - diff = MAX(MIN(other_rect.position.x, global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x); - } else { - diff = MAX(MIN(other_rect.position.x, global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x + right_margin); - } - set_h_scroll(get_h_scroll() + (diff - global_rect.position.x)); - } + Rect2 global_rect = get_global_rect(); + Rect2 other_rect = p_control->get_global_rect(); + float right_margin = v_scroll->is_visible() ? v_scroll->get_size().x : 0.0f; + float bottom_margin = h_scroll->is_visible() ? h_scroll->get_size().y : 0.0f; + + Vector2 diff = Vector2(MAX(MIN(other_rect.position.x, global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x + (!is_layout_rtl() ? right_margin : 0.0f)), + MAX(MIN(other_rect.position.y, global_rect.position.y), other_rect.position.y + other_rect.size.y - global_rect.size.y + bottom_margin)); + + set_h_scroll(get_h_scroll() + (diff.x - global_rect.position.x)); + set_v_scroll(get_v_scroll() + (diff.y - global_rect.position.y)); } void ScrollContainer::_update_dimensions() { @@ -334,7 +327,7 @@ void ScrollContainer::_notification(int p_what) { }; if (p_what == NOTIFICATION_READY) { - get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_ensure_focused_visible)); + get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_gui_focus_changed)); _update_dimensions(); } @@ -608,6 +601,7 @@ void ScrollContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_h_scrollbar"), &ScrollContainer::get_h_scrollbar); ClassDB::bind_method(D_METHOD("get_v_scrollbar"), &ScrollContainer::get_v_scrollbar); + ClassDB::bind_method(D_METHOD("ensure_control_visible", "control"), &ScrollContainer::ensure_control_visible); ADD_SIGNAL(MethodInfo("scroll_started")); ADD_SIGNAL(MethodInfo("scroll_ended")); diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index f61df70b85..c77a0d62f5 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -69,6 +69,7 @@ protected: Size2 get_minimum_size() const override; void _gui_input(const Ref<InputEvent> &p_gui_input); + void _gui_focus_changed(Control *p_control); void _update_dimensions(); void _notification(int p_what); @@ -77,7 +78,6 @@ protected: bool _updating_scrollbars = false; void _update_scrollbar_position(); - void _ensure_focused_visible(Control *p_node); public: void set_h_scroll(int p_pos); @@ -106,6 +106,7 @@ public: HScrollBar *get_h_scrollbar(); VScrollBar *get_v_scrollbar(); + void ensure_control_visible(Control *p_control); virtual bool clips_input() const override; diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 13ff2c5b86..df4cf9a740 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -353,7 +353,7 @@ void SplitContainer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "split_offset"), "set_split_offset", "get_split_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collapsed"), "set_collapsed", "is_collapsed"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden & Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden and Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); BIND_ENUM_CONSTANT(DRAGGER_VISIBLE); BIND_ENUM_CONSTANT(DRAGGER_HIDDEN); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index d19d95f6f4..65d4433f4e 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1187,7 +1187,8 @@ void TextEdit::_notification(int p_what) { if (rect.position.x < xmargin_beg) { rect.size.x -= (xmargin_beg - rect.position.x); rect.position.x = xmargin_beg; - } else if (rect.position.x + rect.size.x > xmargin_end) { + } + if (rect.position.x + rect.size.x > xmargin_end) { rect.size.x = xmargin_end - rect.position.x; } draw_rect(rect, cache.selection_color, true); @@ -7055,7 +7056,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_minimap_width"), &TextEdit::get_minimap_width); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "readonly"), "set_readonly", "is_readonly"); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 2f78736a12..d2b98eb0fa 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1184,15 +1184,23 @@ void Tree::update_cache() { cache.font_color = get_theme_color("font_color"); cache.font_selected_color = get_theme_color("font_selected_color"); - cache.guide_color = get_theme_color("guide_color"); cache.drop_position_color = get_theme_color("drop_position_color"); cache.hseparation = get_theme_constant("hseparation"); cache.vseparation = get_theme_constant("vseparation"); cache.item_margin = get_theme_constant("item_margin"); cache.button_margin = get_theme_constant("button_margin"); + cache.draw_guides = get_theme_constant("draw_guides"); + cache.guide_color = get_theme_color("guide_color"); cache.draw_relationship_lines = get_theme_constant("draw_relationship_lines"); + cache.relationship_line_width = get_theme_constant("relationship_line_width"); + cache.parent_hl_line_width = get_theme_constant("parent_hl_line_width"); + cache.children_hl_line_width = get_theme_constant("children_hl_line_width"); + cache.parent_hl_line_margin = get_theme_constant("parent_hl_line_margin"); cache.relationship_line_color = get_theme_color("relationship_line_color"); + cache.parent_hl_line_color = get_theme_color("parent_hl_line_color"); + cache.children_hl_line_color = get_theme_color("children_hl_line_color"); + cache.scroll_border = get_theme_constant("scroll_border"); cache.scroll_speed = get_theme_constant("scroll_speed"); @@ -1813,38 +1821,79 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 TreeItem *c = p_item->first_child; - int prev_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + int base_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + int prev_ofs = base_ofs; + int prev_hl_ofs = base_ofs; while (c) { if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) { int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); - int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); + int parent_ofs = p_pos.x + cache.item_margin; Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; if (c->get_first_child() != nullptr) { root_pos -= Point2i(cache.arrow->get_width(), 0); } - float line_width = 1.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 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; + int more_prev_ofs = 0; + if (root_pos.y + line_width >= 0) { if (rtl) { root_pos.x = get_size().width - root_pos.x; parent_pos.x = get_size().width - parent_pos.x; } - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x - Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), Point2i(parent_pos.x, prev_ofs), cache.relationship_line_color, line_width); + + // Order of parts on this bend: the horizontal line first, then the vertical line. + if (_is_branch_selected(c)) { + // If this item or one of its children is selected, we draw the line using parent highlight style. + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.parent_hl_line_color, parent_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + more_prev_ofs = cache.parent_hl_line_margin; + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else if (p_item->is_selected(0)) { + // If parent item is selected (but this item is not), we draw the line using children highlight style. + // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. + if (_is_sibling_branch_selected(c)) { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(children_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(children_line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(children_line_width / 2)), cache.children_hl_line_color, children_line_width); + } + } else { + // If nothing of the above is true, we draw the line using normal style. + // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. + if (_is_sibling_branch_selected(c)) { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + cache.parent_hl_line_margin, root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(line_width / 2)), cache.relationship_line_color, line_width); + } + } } if (htotal < 0) { return -1; } - prev_ofs = root_pos.y; + prev_ofs = root_pos.y + more_prev_ofs; } if (htotal >= 0) { @@ -1853,10 +1902,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (child_h < 0) { if (cache.draw_relationship_lines == 0) { return -1; // break, stop drawing, no need to anymore - } else { - htotal = -1; - children_pos.y = cache.offset.y + p_draw_size.height; } + + htotal = -1; + children_pos.y = cache.offset.y + p_draw_size.height; } else { htotal += child_h; children_pos.y += child_h; @@ -1889,6 +1938,36 @@ int Tree::_count_selected_items(TreeItem *p_from) const { return count; } +bool Tree::_is_branch_selected(TreeItem *p_from) const { + for (int i = 0; i < columns.size(); i++) { + if (p_from->is_selected(i)) { + return true; + } + } + + TreeItem *child_item = p_from->get_first_child(); + while (child_item) { + if (_is_branch_selected(child_item)) { + return true; + } + child_item = child_item->get_next(); + } + + return false; +} + +bool Tree::_is_sibling_branch_selected(TreeItem *p_from) const { + TreeItem *sibling_item = p_from->get_next(); + while (sibling_item) { + if (_is_branch_selected(sibling_item)) { + return true; + } + sibling_item = sibling_item->get_next(); + } + + return false; +} + void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev, bool *r_in_range, bool p_force_deselect) { TreeItem::Cell &selected_cell = p_selected->cells.write[p_col]; @@ -4386,7 +4465,7 @@ void Tree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In between"), "set_drop_mode_flags", "get_drop_mode_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In Between"), "set_drop_mode_flags", "get_drop_mode_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Row,Multi"), "set_select_mode", "get_select_mode"); ADD_SIGNAL(MethodInfo("item_selected")); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 9dbfd93082..c0948f1b80 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -494,6 +494,8 @@ private: Color guide_color; Color drop_position_color; Color relationship_line_color; + Color parent_hl_line_color; + Color children_hl_line_color; Color custom_button_font_highlight; int hseparation = 0; @@ -502,6 +504,10 @@ private: int button_margin = 0; Point2 offset; int draw_relationship_lines = 0; + int relationship_line_width = 0; + int parent_hl_line_width = 0; + int children_hl_line_width = 0; + int parent_hl_line_margin = 0; int draw_guides = 0; int scroll_border = 0; int scroll_speed = 0; @@ -574,6 +580,8 @@ private: bool hide_folding = false; int _count_selected_items(TreeItem *p_from) const; + bool _is_branch_selected(TreeItem *p_from) const; + bool _is_sibling_branch_selected(TreeItem *p_from) const; void _go_left(); void _go_right(); void _go_down(); |