summaryrefslogtreecommitdiffstats
path: root/scene/gui/tab_bar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/tab_bar.cpp')
-rw-r--r--scene/gui/tab_bar.cpp74
1 files changed, 64 insertions, 10 deletions
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index 5e378a0321..5eb5a519ff 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -63,10 +63,10 @@ Size2 TabBar::get_minimum_size() const {
}
ms.width += style->get_minimum_size().width;
- Ref<Texture2D> tex = tabs[i].icon;
- if (tex.is_valid()) {
- ms.height = MAX(ms.height, tex->get_size().height + y_margin);
- ms.width += tex->get_size().width + theme_cache.h_separation;
+ if (tabs[i].icon.is_valid()) {
+ const Size2 icon_size = _get_tab_icon_size(i);
+ ms.height = MAX(ms.height, icon_size.height + y_margin);
+ ms.width += icon_size.width + theme_cache.h_separation;
}
if (!tabs[i].text.is_empty()) {
@@ -304,6 +304,7 @@ void TabBar::_update_theme_item_cache() {
Control::_update_theme_item_cache();
theme_cache.h_separation = get_theme_constant(SNAME("h_separation"));
+ theme_cache.icon_max_width = get_theme_constant(SNAME("icon_max_width"));
theme_cache.tab_unselected_style = get_theme_stylebox(SNAME("tab_unselected"));
theme_cache.tab_selected_style = get_theme_stylebox(SNAME("tab_selected"));
@@ -492,9 +493,11 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in
// Draw the icon.
Ref<Texture2D> icon = tabs[p_index].icon;
if (icon.is_valid()) {
- icon->draw(ci, Point2i(rtl ? p_x - icon->get_width() : p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2));
+ const Size2 icon_size = _get_tab_icon_size(p_index);
+ const Point2 icon_pos = Point2i(rtl ? p_x - icon_size.width : p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon_size.height) / 2);
+ icon->draw_rect(ci, Rect2(icon_pos, icon_size));
- p_x = rtl ? p_x - icon->get_width() - theme_cache.h_separation : p_x + icon->get_width() + theme_cache.h_separation;
+ p_x = rtl ? p_x - icon_size.width - theme_cache.h_separation : p_x + icon_size.width + theme_cache.h_separation;
}
// Draw the text.
@@ -719,6 +722,29 @@ Ref<Texture2D> TabBar::get_tab_icon(int p_tab) const {
return tabs[p_tab].icon;
}
+void TabBar::set_tab_icon_max_width(int p_tab, int p_width) {
+ ERR_FAIL_INDEX(p_tab, tabs.size());
+
+ if (tabs[p_tab].icon_max_width == p_width) {
+ return;
+ }
+
+ tabs.write[p_tab].icon_max_width = p_width;
+
+ _update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
+ queue_redraw();
+ update_minimum_size();
+}
+
+int TabBar::get_tab_icon_max_width(int p_tab) const {
+ ERR_FAIL_INDEX_V(p_tab, tabs.size(), 0);
+ return tabs[p_tab].icon_max_width;
+}
+
void TabBar::set_tab_disabled(int p_tab, bool p_disabled) {
ERR_FAIL_INDEX(p_tab, tabs.size());
@@ -1023,9 +1049,14 @@ Variant TabBar::get_drag_data(const Point2 &p_point) {
HBoxContainer *drag_preview = memnew(HBoxContainer);
if (!tabs[tab_over].icon.is_null()) {
+ const Size2 icon_size = _get_tab_icon_size(tab_over);
+
TextureRect *tf = memnew(TextureRect);
tf->set_texture(tabs[tab_over].icon);
- tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
+ tf->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
+ tf->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);
+ tf->set_custom_minimum_size(icon_size);
+
drag_preview->add_child(tf);
}
@@ -1270,9 +1301,9 @@ int TabBar::get_tab_width(int p_idx) const {
}
int x = style->get_minimum_size().width;
- Ref<Texture2D> tex = tabs[p_idx].icon;
- if (tex.is_valid()) {
- x += tex->get_width() + theme_cache.h_separation;
+ if (tabs[p_idx].icon.is_valid()) {
+ const Size2 icon_size = _get_tab_icon_size(p_idx);
+ x += icon_size.width + theme_cache.h_separation;
}
if (!tabs[p_idx].text.is_empty()) {
@@ -1305,6 +1336,27 @@ int TabBar::get_tab_width(int p_idx) const {
return x;
}
+Size2 TabBar::_get_tab_icon_size(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, tabs.size(), Size2());
+ const TabBar::Tab &tab = tabs[p_index];
+ Size2 icon_size = tab.icon->get_size();
+
+ int icon_max_width = 0;
+ if (theme_cache.icon_max_width > 0) {
+ icon_max_width = theme_cache.icon_max_width;
+ }
+ if (tab.icon_max_width > 0 && (icon_max_width == 0 || tab.icon_max_width < icon_max_width)) {
+ icon_max_width = tab.icon_max_width;
+ }
+
+ if (icon_max_width > 0 && icon_size.width > icon_max_width) {
+ icon_size.height = icon_size.height * icon_max_width / icon_size.width;
+ icon_size.width = icon_max_width;
+ }
+
+ return icon_size;
+}
+
void TabBar::_ensure_no_over_offset() {
if (!is_inside_tree() || !buttons_visible) {
return;
@@ -1547,6 +1599,8 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tab_language", "tab_idx"), &TabBar::get_tab_language);
ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabBar::set_tab_icon);
ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &TabBar::get_tab_icon);
+ ClassDB::bind_method(D_METHOD("set_tab_icon_max_width", "tab_idx", "width"), &TabBar::set_tab_icon_max_width);
+ ClassDB::bind_method(D_METHOD("get_tab_icon_max_width", "tab_idx"), &TabBar::get_tab_icon_max_width);
ClassDB::bind_method(D_METHOD("set_tab_button_icon", "tab_idx", "icon"), &TabBar::set_tab_button_icon);
ClassDB::bind_method(D_METHOD("get_tab_button_icon", "tab_idx"), &TabBar::get_tab_button_icon);
ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabBar::set_tab_disabled);