From 352f907c305c75b31bb67d0ccfa68f665dda9db4 Mon Sep 17 00:00:00 2001 From: havi05 Date: Mon, 11 Nov 2024 19:38:46 +0100 Subject: [PATCH] ItemList - highlight selected items && draw cursor last --- doc/classes/ItemList.xml | 11 +++++++- editor/themes/editor_theme_manager.cpp | 6 +++++ scene/gui/item_list.cpp | 37 +++++++++++++++++++------- scene/gui/item_list.h | 3 +++ scene/theme/default_theme.cpp | 3 +++ 5 files changed, 49 insertions(+), 11 deletions(-) diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 7754a61e8cea..34bdd947ec9f 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -481,11 +481,14 @@ Text [Color] used when the item is hovered and not selected yet. + + Text [Color] used when the item is hovered and selected. + The tint of text outline of the item. - Text [Color] used when the item is selected. + Text [Color] used when the item is selected, but not hovered. [Color] of the guideline. The guideline is a line drawn between each row of items. @@ -524,6 +527,12 @@ [StyleBox] for the hovered, but not selected items. + + [StyleBox] for the hovered and selected items, used when the [ItemList] is not being focused. + + + [StyleBox] for the hovered and selected items, used when the [ItemList] is being focused. + The background style for the [ItemList]. diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index f4e4f85b5e4a..88f777f99e90 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -1058,6 +1058,10 @@ void EditorThemeManager::_populate_standard_styles(const Ref &p_the style_itemlist_hover->set_bg_color(p_config.highlight_color * Color(1, 1, 1, 0.3)); style_itemlist_hover->set_border_width_all(0); + Ref style_itemlist_hover_selected = style_tree_selected->duplicate(); + style_itemlist_hover_selected->set_bg_color(p_config.highlight_color * Color(1, 1, 1, 1.2)); + style_itemlist_hover_selected->set_border_width_all(0); + p_theme->set_stylebox(SceneStringName(panel), "ItemList", style_itemlist_bg); p_theme->set_stylebox("focus", "ItemList", p_config.button_style_focus); p_theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor); @@ -1065,6 +1069,8 @@ void EditorThemeManager::_populate_standard_styles(const Ref &p_the p_theme->set_stylebox("selected_focus", "ItemList", style_tree_focus); p_theme->set_stylebox("selected", "ItemList", style_tree_selected); p_theme->set_stylebox("hovered", "ItemList", style_itemlist_hover); + p_theme->set_stylebox("hovered_selected", "ItemList", style_itemlist_hover_selected); + p_theme->set_stylebox("hovered_selected_focus", "ItemList", style_itemlist_hover_selected); p_theme->set_color(SceneStringName(font_color), "ItemList", p_config.font_color); p_theme->set_color("font_hovered_color", "ItemList", p_config.mono_color); p_theme->set_color("font_selected_color", "ItemList", p_config.mono_color); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 1ba5ef309b0f..f511664a39bc 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -1154,6 +1154,8 @@ void ItemList::_notification(int p_what) { first_item_visible = lo; } + Rect2 cursor_rcache; // Place to save the position of the cursor and draw it after everything else. + // Draw visible items. for (int i = first_item_visible; i < items.size(); i++) { Rect2 rcache = items[i].rect_cache; @@ -1170,11 +1172,12 @@ void ItemList::_notification(int p_what) { rcache.size.width = width - rcache.position.x; } - bool should_draw_selected_bg = items[i].selected; + bool should_draw_selected_bg = items[i].selected && hovered != i; + bool should_draw_hovered_selected_bg = items[i].selected && hovered == i; bool should_draw_hovered_bg = hovered == i && !items[i].selected; bool should_draw_custom_bg = items[i].custom_bg.a > 0.001; - if (should_draw_selected_bg || should_draw_hovered_bg || should_draw_custom_bg) { + if (should_draw_selected_bg || should_draw_hovered_selected_bg || should_draw_hovered_bg || should_draw_custom_bg) { Rect2 r = rcache; r.position += base_ofs; @@ -1185,6 +1188,13 @@ void ItemList::_notification(int p_what) { if (should_draw_selected_bg) { draw_style_box(sbsel, r); } + if (should_draw_hovered_selected_bg) { + if (has_focus()) { + draw_style_box(theme_cache.hovered_selected_focus_style, r); + } else { + draw_style_box(theme_cache.hovered_selected_style, r); + } + } if (should_draw_hovered_bg) { draw_style_box(theme_cache.hovered_style, r); } @@ -1282,7 +1292,9 @@ void ItemList::_notification(int p_what) { } Color txt_modulate; - if (items[i].selected) { + if (items[i].selected && hovered == i) { + txt_modulate = theme_cache.font_hovered_selected_color; + } else if (items[i].selected) { txt_modulate = theme_cache.font_selected_color; } else if (hovered == i) { txt_modulate = theme_cache.font_hovered_color; @@ -1354,15 +1366,17 @@ void ItemList::_notification(int p_what) { } if (select_mode == SELECT_MULTI && i == current) { - Rect2 r = rcache; - r.position += base_ofs; - - if (rtl) { - r.position.x = size.width - r.position.x - r.size.x; - } + cursor_rcache = rcache; + } + } + if (cursor_rcache.size != Size2()) { // Draw cursor last, so border isn't cut off. + cursor_rcache.position += base_ofs; - draw_style_box(cursor, r); + if (rtl) { + cursor_rcache.position.x = size.width - cursor_rcache.position.x - cursor_rcache.size.x; } + + draw_style_box(cursor, cursor_rcache); } } break; } @@ -1953,6 +1967,7 @@ void ItemList::_bind_methods() { BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, ItemList, font_size); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_color); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_hovered_color); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_hovered_selected_color); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_selected_color); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_CONSTANT, ItemList, font_outline_size, "outline_size"); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_outline_color); @@ -1960,6 +1975,8 @@ void ItemList::_bind_methods() { BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ItemList, line_separation); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, ItemList, icon_margin); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, hovered_style, "hovered"); + BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, hovered_selected_style, "hovered_selected"); + BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, hovered_selected_focus_style, "hovered_selected_focus"); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, selected_style, "selected"); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, selected_focus_style, "selected_focus"); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, cursor_style, "cursor_unfocused"); diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 0836ea33d52b..88cd45bb42b0 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -145,6 +145,7 @@ class ItemList : public Control { int font_size = 0; Color font_color; Color font_hovered_color; + Color font_hovered_selected_color; Color font_selected_color; int font_outline_size = 0; Color font_outline_color; @@ -152,6 +153,8 @@ class ItemList : public Control { int line_separation = 0; int icon_margin = 0; Ref hovered_style; + Ref hovered_selected_style; + Ref hovered_selected_focus_style; Ref selected_style; Ref selected_focus_style; Ref cursor_style; diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp index f7ba440faf71..3b592f80f8a8 100644 --- a/scene/theme/default_theme.cpp +++ b/scene/theme/default_theme.cpp @@ -129,6 +129,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const // StyleBox colors const Color style_normal_color = Color(0.1, 0.1, 0.1, 0.6); const Color style_hover_color = Color(0.225, 0.225, 0.225, 0.6); + const Color style_hover_selected_color = Color(1, 1, 1, 0.4); const Color style_pressed_color = Color(0, 0, 0, 0.6); const Color style_disabled_color = Color(0.1, 0.1, 0.1, 0.3); const Color style_focus_color = Color(1, 1, 1, 0.75); @@ -933,6 +934,8 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const theme->set_color("font_outline_color", "ItemList", Color(0, 0, 0)); theme->set_color("guide_color", "ItemList", Color(0.7, 0.7, 0.7, 0.25)); theme->set_stylebox("hovered", "ItemList", make_flat_stylebox(Color(1, 1, 1, 0.07))); + theme->set_stylebox("hovered_selected", "ItemList", make_flat_stylebox(style_hover_selected_color)); + theme->set_stylebox("hovered_selected_focus", "ItemList", make_flat_stylebox(style_hover_selected_color)); theme->set_stylebox("selected", "ItemList", make_flat_stylebox(style_selected_color)); theme->set_stylebox("selected_focus", "ItemList", make_flat_stylebox(style_selected_color)); theme->set_stylebox("cursor", "ItemList", focus);