From f63728cb9f5550b1de202cc014bdc3f110d485c9 Mon Sep 17 00:00:00 2001 From: David Giardi Date: Wed, 14 Feb 2024 23:45:49 +0100 Subject: [PATCH] Fix item positioning & pointer detection areas of ItemList --- doc/classes/ItemList.xml | 2 +- editor/themes/editor_theme_manager.cpp | 2 +- scene/gui/item_list.cpp | 44 ++++++++++++++------------ scene/theme/default_theme.cpp | 2 +- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 593f41bc70fb..dde3f46ddfcc 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -483,7 +483,7 @@ The size of the item text outline. [b]Note:[/b] If using a font with [member FontFile.multichannel_signed_distance_field] enabled, its [member FontFile.msdf_pixel_range] must be set to at least [i]twice[/i] the value of [theme_item outline_size] for outline rendering to look correct. Otherwise, the outline may appear to be cut off earlier than intended. - + The vertical spacing between items. diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index f55ac6f59a9c..6849d8792311 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -1036,7 +1036,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref &p_the p_theme->set_color("font_selected_color", "ItemList", p_config.mono_color); p_theme->set_color("font_outline_color", "ItemList", p_config.font_outline_color); p_theme->set_color("guide_color", "ItemList", Color(1, 1, 1, 0)); - p_theme->set_constant("v_separation", "ItemList", p_config.forced_even_separation * 0.5 * EDSCALE); + p_theme->set_constant("v_separation", "ItemList", p_config.forced_even_separation * EDSCALE); p_theme->set_constant("h_separation", "ItemList", (p_config.increased_margin + 2) * EDSCALE); p_theme->set_constant("icon_margin", "ItemList", (p_config.increased_margin + 2) * EDSCALE); p_theme->set_constant("line_separation", "ItemList", p_config.separation_margin); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 162c9cf801ca..8376ef48b67a 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -1150,10 +1150,6 @@ void ItemList::_notification(int p_what) { if (should_draw_selected_bg || should_draw_hovered_bg || should_draw_custom_bg) { Rect2 r = rcache; r.position += base_ofs; - r.position.y -= theme_cache.v_separation / 2; - r.size.y += theme_cache.v_separation; - r.position.x -= theme_cache.h_separation / 2; - r.size.x += theme_cache.h_separation; if (rtl) { r.position.x = size.width - r.position.x - r.size.x; @@ -1185,6 +1181,12 @@ void ItemList::_notification(int p_what) { Point2 pos = items[i].rect_cache.position + icon_ofs + base_ofs; + if (icon_mode == ICON_MODE_TOP) { + pos.y += theme_cache.v_separation / 2; + } else { + pos.x += theme_cache.h_separation / 2; + } + if (icon_mode == ICON_MODE_TOP) { pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width) / 2); pos.y += theme_cache.icon_margin; @@ -1224,6 +1226,8 @@ void ItemList::_notification(int p_what) { if (items[i].tag_icon.is_valid()) { Point2 draw_pos = items[i].rect_cache.position; + draw_pos.x += theme_cache.h_separation / 2; + draw_pos.y += theme_cache.v_separation / 2; if (rtl) { draw_pos.x = size.width - draw_pos.x - items[i].tag_icon->get_width(); } @@ -1261,12 +1265,18 @@ void ItemList::_notification(int p_what) { text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; + text_ofs.x += theme_cache.h_separation / 2; + text_ofs.y += theme_cache.v_separation / 2; + if (rtl) { text_ofs.x = size.width - text_ofs.x - max_len; } items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_CENTER); + float text_w = items[i].rect_cache.size.width - theme_cache.h_separation; + items.write[i].text_buf->set_width(text_w); + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, theme_cache.font_outline_size, theme_cache.font_outline_color); } @@ -1279,14 +1289,17 @@ void ItemList::_notification(int p_what) { if (icon_mode == ICON_MODE_TOP) { text_ofs.x += (items[i].rect_cache.size.width - size2.x) / 2; + text_ofs.x += theme_cache.h_separation / 2; + text_ofs.y += theme_cache.v_separation / 2; } else { text_ofs.y += (items[i].rect_cache.size.height - size2.y) / 2; + text_ofs.x += theme_cache.h_separation / 2; } text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; - float text_w = width - text_ofs.x; + float text_w = width - text_ofs.x - theme_cache.h_separation; items.write[i].text_buf->set_width(text_w); if (rtl) { @@ -1309,10 +1322,6 @@ void ItemList::_notification(int p_what) { if (select_mode == SELECT_MULTI && i == current) { Rect2 r = rcache; r.position += base_ofs; - r.position.y -= theme_cache.v_separation / 2; - r.size.y += theme_cache.v_separation; - r.position.x -= theme_cache.h_separation / 2; - r.size.x += theme_cache.h_separation; if (rtl) { r.position.x = size.width - r.position.x - r.size.x; @@ -1382,9 +1391,10 @@ void ItemList::force_update_list_size() { } max_column_width = MAX(max_column_width, minsize.x); - // elements need to adapt to the selected size + // Elements need to adapt to the selected size. minsize.y += theme_cache.v_separation; minsize.x += theme_cache.h_separation; + items.write[i].rect_cache.size = minsize; items.write[i].min_rect_cache.size = minsize; } @@ -1415,18 +1425,18 @@ void ItemList::force_update_list_size() { } if (same_column_width) { - items.write[i].rect_cache.size.x = max_column_width; + items.write[i].rect_cache.size.x = max_column_width + theme_cache.h_separation; } items.write[i].rect_cache.position = ofs; max_h = MAX(max_h, items[i].rect_cache.size.y); - ofs.x += items[i].rect_cache.size.x + theme_cache.h_separation; + ofs.x += items[i].rect_cache.size.x; items.write[i].column = col; col++; if (col == current_columns) { if (i < items.size() - 1) { - separators.push_back(ofs.y + max_h + theme_cache.v_separation / 2); + separators.push_back(ofs.y + max_h); } for (int j = i; j >= 0 && col > 0; j--, col--) { @@ -1434,7 +1444,7 @@ void ItemList::force_update_list_size() { } ofs.x = 0; - ofs.y += max_h + theme_cache.v_separation; + ofs.y += max_h; col = 0; max_h = 0; } @@ -1496,12 +1506,6 @@ int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const { for (int i = 0; i < items.size(); i++) { Rect2 rc = items[i].rect_cache; - // Grow the detection rectangle to match the grown selection indicator. - rc.position.y -= theme_cache.v_separation / 2; - rc.size.y += theme_cache.v_separation; - rc.position.x -= theme_cache.h_separation / 2; - rc.size.x += theme_cache.h_separation; - if (i % current_columns == current_columns - 1) { rc.size.width = get_size().width - rc.position.x; // Make sure you can still select the last item when clicking past the column. } diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp index 634b32c9f61a..ec3bdd2eec02 100644 --- a/scene/theme/default_theme.cpp +++ b/scene/theme/default_theme.cpp @@ -832,7 +832,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const theme->set_stylebox("panel", "ItemList", make_flat_stylebox(style_normal_color)); theme->set_stylebox("focus", "ItemList", focus); theme->set_constant("h_separation", "ItemList", Math::round(4 * scale)); - theme->set_constant("v_separation", "ItemList", Math::round(2 * scale)); + theme->set_constant("v_separation", "ItemList", Math::round(4 * scale)); theme->set_constant("icon_margin", "ItemList", Math::round(4 * scale)); theme->set_constant("line_separation", "ItemList", Math::round(2 * scale));