From fd483c729f90d709965546e53c306798f2b737e4 Mon Sep 17 00:00:00 2001 From: kleonc <9283098+kleonc@users.noreply.github.com> Date: Wed, 4 Aug 2021 20:32:37 +0200 Subject: [PATCH] TabContainer: Fix error on removing top-level Control child, Remove _get_tab method --- scene/gui/tab_container.cpp | 69 +++++++++++++++++-------------------- scene/gui/tab_container.h | 1 - 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index cc41d961f6..53a2fe4d93 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -535,7 +535,7 @@ void TabContainer::_notification(int p_what) { } void TabContainer::_draw_tab(Ref &p_tab_style, Color &p_font_color, int p_index, float p_x) { - Vector tabs = _get_tabs(); + Control *control = get_tab_control(p_index); RID canvas = get_canvas_item(); Ref font = get_theme_font(SNAME("font")); Color font_outline_color = get_theme_color(SNAME("font_outline_color")); @@ -549,7 +549,6 @@ void TabContainer::_draw_tab(Ref &p_tab_style, Color &p_font_color, in p_tab_style->draw(canvas, tab_rect); // Draw the tab contents. - Control *control = Object::cast_to(tabs[p_index]); String text = control->has_meta("_tab_name") ? String(atr(String(control->get_meta("_tab_name")))) : String(atr(control->get_name())); int x_content = tab_rect.position.x + p_tab_style->get_margin(SIDE_LEFT); @@ -620,10 +619,10 @@ void TabContainer::_repaint() { if (tabs_visible) { c->set_offset(SIDE_TOP, _get_top_margin()); } - c->set_offset(Side(SIDE_TOP), c->get_offset(Side(SIDE_TOP)) + sb->get_margin(Side(SIDE_TOP))); - c->set_offset(Side(SIDE_LEFT), c->get_offset(Side(SIDE_LEFT)) + sb->get_margin(Side(SIDE_LEFT))); - c->set_offset(Side(SIDE_RIGHT), c->get_offset(Side(SIDE_RIGHT)) - sb->get_margin(Side(SIDE_RIGHT))); - c->set_offset(Side(SIDE_BOTTOM), c->get_offset(Side(SIDE_BOTTOM)) - sb->get_margin(Side(SIDE_BOTTOM))); + c->set_offset(SIDE_TOP, c->get_offset(SIDE_TOP) + sb->get_margin(SIDE_TOP)); + c->set_offset(SIDE_LEFT, c->get_offset(SIDE_LEFT) + sb->get_margin(SIDE_LEFT)); + c->set_offset(SIDE_RIGHT, c->get_offset(SIDE_RIGHT) - sb->get_margin(SIDE_RIGHT)); + c->set_offset(SIDE_BOTTOM, c->get_offset(SIDE_BOTTOM) - sb->get_margin(SIDE_BOTTOM)); } else { c->hide(); @@ -682,7 +681,7 @@ Vector TabContainer::_get_tabs() const { Vector controls; for (int i = 0; i < get_child_count(); i++) { Control *control = Object::cast_to(get_child(i)); - if (!control || control->is_top_level_control()) { + if (!control || control->is_set_as_top_level()) { continue; } @@ -700,10 +699,7 @@ void TabContainer::add_child_notify(Node *p_child) { Container::add_child_notify(p_child); Control *c = Object::cast_to(p_child); - if (!c) { - return; - } - if (c->is_set_as_top_level()) { + if (!c || c->is_set_as_top_level()) { return; } @@ -726,10 +722,10 @@ void TabContainer::add_child_notify(Node *p_child) { c->set_offset(SIDE_TOP, _get_top_margin()); } Ref sb = get_theme_stylebox(SNAME("panel")); - c->set_offset(Side(SIDE_TOP), c->get_offset(Side(SIDE_TOP)) + sb->get_margin(Side(SIDE_TOP))); - c->set_offset(Side(SIDE_LEFT), c->get_offset(Side(SIDE_LEFT)) + sb->get_margin(Side(SIDE_LEFT))); - c->set_offset(Side(SIDE_RIGHT), c->get_offset(Side(SIDE_RIGHT)) - sb->get_margin(Side(SIDE_RIGHT))); - c->set_offset(Side(SIDE_BOTTOM), c->get_offset(Side(SIDE_BOTTOM)) - sb->get_margin(Side(SIDE_BOTTOM))); + c->set_offset(SIDE_TOP, c->get_offset(SIDE_TOP) + sb->get_margin(SIDE_TOP)); + c->set_offset(SIDE_LEFT, c->get_offset(SIDE_LEFT) + sb->get_margin(SIDE_LEFT)); + c->set_offset(SIDE_RIGHT, c->get_offset(SIDE_RIGHT) - sb->get_margin(SIDE_RIGHT)); + c->set_offset(SIDE_BOTTOM, c->get_offset(SIDE_BOTTOM) - sb->get_margin(SIDE_BOTTOM)); update(); p_child->connect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback)); if (first && is_inside_tree()) { @@ -739,8 +735,13 @@ void TabContainer::add_child_notify(Node *p_child) { void TabContainer::move_child_notify(Node *p_child) { Container::move_child_notify(p_child); - call_deferred(SNAME("_update_current_tab")); - _refresh_texts(); + + Control *c = Object::cast_to(p_child); + if (!c || c->is_set_as_top_level()) { + return; + } + + _update_current_tab(); update(); } @@ -785,21 +786,18 @@ Control *TabContainer::get_tab_control(int p_idx) const { } Control *TabContainer::get_current_tab_control() const { - Vector tabs = _get_tabs(); - if (current >= 0 && current < tabs.size()) { - return tabs[current]; - } else { - return nullptr; - } + return get_tab_control(current); } void TabContainer::remove_child_notify(Node *p_child) { Container::remove_child_notify(p_child); - if (!Object::cast_to(p_child)) { + Control *c = Object::cast_to(p_child); + if (!c || c->is_set_as_top_level()) { return; } + // Defer the call because tab is not yet removed (remove_child_notify is called right before p_child is actually removed). call_deferred(SNAME("_update_current_tab")); p_child->disconnect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback)); @@ -808,10 +806,9 @@ void TabContainer::remove_child_notify(Node *p_child) { } void TabContainer::_update_current_tab() { - Vector tabs = _get_tabs(); _refresh_texts(); - int tc = tabs.size(); + int tc = get_tab_count(); if (current >= tc) { current = tc - 1; } @@ -1019,12 +1016,8 @@ bool TabContainer::is_all_tabs_in_front() const { return all_tabs_in_front; } -Control *TabContainer::_get_tab(int p_idx) const { - return get_tab_control(p_idx); -} - void TabContainer::set_tab_title(int p_tab, const String &p_title) { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND(!child); child->set_meta("_tab_name", p_title); _refresh_texts(); @@ -1032,7 +1025,7 @@ void TabContainer::set_tab_title(int p_tab, const String &p_title) { } String TabContainer::get_tab_title(int p_tab) const { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND_V(!child, ""); if (child->has_meta("_tab_name")) { return child->get_meta("_tab_name"); @@ -1042,14 +1035,14 @@ String TabContainer::get_tab_title(int p_tab) const { } void TabContainer::set_tab_icon(int p_tab, const Ref &p_icon) { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND(!child); child->set_meta("_tab_icon", p_icon); update(); } Ref TabContainer::get_tab_icon(int p_tab) const { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND_V(!child, Ref()); if (child->has_meta("_tab_icon")) { return child->get_meta("_tab_icon"); @@ -1059,14 +1052,14 @@ Ref TabContainer::get_tab_icon(int p_tab) const { } void TabContainer::set_tab_disabled(int p_tab, bool p_disabled) { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND(!child); child->set_meta("_tab_disabled", p_disabled); update(); } bool TabContainer::get_tab_disabled(int p_tab) const { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND_V(!child, false); if (child->has_meta("_tab_disabled")) { return child->get_meta("_tab_disabled"); @@ -1076,7 +1069,7 @@ bool TabContainer::get_tab_disabled(int p_tab) const { } void TabContainer::set_tab_hidden(int p_tab, bool p_hidden) { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND(!child); child->set_meta("_tab_hidden", p_hidden); update(); @@ -1095,7 +1088,7 @@ void TabContainer::set_tab_hidden(int p_tab, bool p_hidden) { } bool TabContainer::get_tab_hidden(int p_tab) const { - Control *child = _get_tab(p_tab); + Control *child = get_tab_control(p_tab); ERR_FAIL_COND_V(!child, false); if (child->has_meta("_tab_hidden")) { return child->get_meta("_tab_hidden"); diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 4ed5255729..35f18eff8e 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -57,7 +57,6 @@ private: bool menu_hovered = false; int highlight_arrow = -1; TabAlign align = ALIGN_CENTER; - Control *_get_tab(int p_idx) const; int _get_top_margin() const; mutable ObjectID popup_obj_id; bool drag_to_rearrange_enabled = false;