From 1e1dbd8e3a16eb3fee2b50a5aead4c2e14b45f6a Mon Sep 17 00:00:00 2001 From: Gamemap <71942164+Gamemap@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:58:59 +0200 Subject: [PATCH] Add `Auto width` behavior to ItemList Co-authored-by: Craig Hupin --- doc/classes/ItemList.xml | 3 +++ scene/gui/item_list.cpp | 37 +++++++++++++++++++++++++++++++++---- scene/gui/item_list.h | 6 ++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 2d898673c19..fdaeb54bdfa 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -379,6 +379,9 @@ If [code]true[/code], the control will automatically resize the height to fit its content. + + If [code]true[/code], the control will automatically resize the width to fit its content. + The width all columns will be adjusted to. diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 58907e233df..f3cf29d0cf9 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -1446,12 +1446,13 @@ void ItemList::force_update_list_size() { bool all_fit = true; Vector2 ofs; int col = 0; + int max_w = 0; int max_h = 0; separators.clear(); for (int i = 0; i < items.size(); i++) { - if (current_columns > 1 && items[i].rect_cache.size.width + ofs.x > fit_size) { + if (current_columns > 1 && items[i].rect_cache.size.width + ofs.x > fit_size && !auto_width) { // Went past. current_columns = MAX(col, 1); all_fit = false; @@ -1477,6 +1478,7 @@ void ItemList::force_update_list_size() { items.write[j].rect_cache.size.y = max_h; } + max_w = MAX(max_w, ofs.x); ofs.x = 0; ofs.y += max_h; col = 0; @@ -1498,12 +1500,16 @@ void ItemList::force_update_list_size() { if (auto_height) { auto_height_value = ofs.y + max_h + theme_cache.panel_style->get_minimum_size().height; } + if (auto_width) { + auto_width_value = max_w + theme_cache.panel_style->get_minimum_size().width; + } scroll_bar->set_max(max); scroll_bar->set_page(page); if (max <= page) { scroll_bar->set_value(0); scroll_bar->hide(); } else { + auto_width_value += scroll_bar_minwidth; scroll_bar->show(); if (do_autoscroll_to_bottom) { @@ -1704,16 +1710,35 @@ bool ItemList::is_anything_selected() { } Size2 ItemList::get_minimum_size() const { - if (auto_height) { - return Size2(0, auto_height_value); + Size2 min_size; + if (auto_width) { + min_size.x = auto_width_value; } - return Size2(); + + if (auto_height) { + min_size.y = auto_height_value; + } + return min_size; } void ItemList::set_autoscroll_to_bottom(const bool p_enable) { do_autoscroll_to_bottom = p_enable; } +void ItemList::set_auto_width(bool p_enable) { + if (auto_width == p_enable) { + return; + } + + auto_width = p_enable; + shape_changed = true; + queue_redraw(); +} + +bool ItemList::has_auto_width() const { + return auto_width; +} + void ItemList::set_auto_height(bool p_enable) { if (auto_height == p_enable) { return; @@ -1869,6 +1894,9 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("set_allow_search", "allow"), &ItemList::set_allow_search); ClassDB::bind_method(D_METHOD("get_allow_search"), &ItemList::get_allow_search); + ClassDB::bind_method(D_METHOD("set_auto_width", "enable"), &ItemList::set_auto_width); + ClassDB::bind_method(D_METHOD("has_auto_width"), &ItemList::has_auto_width); + ClassDB::bind_method(D_METHOD("set_auto_height", "enable"), &ItemList::set_auto_height); ClassDB::bind_method(D_METHOD("has_auto_height"), &ItemList::has_auto_height); @@ -1890,6 +1918,7 @@ void ItemList::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_text_lines", PROPERTY_HINT_RANGE, "1,10,1,or_greater"), "set_max_text_lines", "get_max_text_lines"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_width"), "set_auto_width", "has_auto_width"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_"); diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 5bb56581cbb..0836ea33d52 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -100,6 +100,9 @@ private: bool same_column_width = false; bool allow_search = true; + bool auto_width = false; + float auto_width_value = 0.0; + bool auto_height = false; float auto_height_value = 0.0; @@ -291,6 +294,9 @@ public: void set_icon_scale(real_t p_scale); real_t get_icon_scale() const; + void set_auto_width(bool p_enable); + bool has_auto_width() const; + void set_auto_height(bool p_enable); bool has_auto_height() const;