Merge pull request #109352 from sydist/itemlist-improvements

Add font color and StyleBox customization for disabled items in ItemList
This commit is contained in:
Thaddeus Crews
2026-06-24 10:16:12 -05:00
4 changed files with 71 additions and 33 deletions
+12
View File
@@ -535,6 +535,12 @@
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.65, 0.65, 0.65, 1)">
Default text [Color] of the item.
</theme_item>
<theme_item name="font_disabled_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.5)">
Text [Color] used when the item is disabled.
</theme_item>
<theme_item name="font_disabled_hovered_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.5)">
Text [Color] used when the item is disabled and hovered.
</theme_item>
<theme_item name="font_hovered_color" data_type="color" type="Color" default="Color(0.95, 0.95, 0.95, 1)">
Text [Color] used when the item is hovered and not selected yet.
</theme_item>
@@ -584,6 +590,12 @@
<theme_item name="cursor_unfocused" data_type="style" type="StyleBox">
[StyleBox] used for the cursor, when the [ItemList] is not being focused.
</theme_item>
<theme_item name="disabled" data_type="style" type="StyleBox">
[StyleBox] for items that are disabled.
</theme_item>
<theme_item name="disabled_hovered" data_type="style" type="StyleBox">
[StyleBox] for items that are disabled, hovered, but not selected.
</theme_item>
<theme_item name="focus" data_type="style" type="StyleBox">
The focused style for the [ItemList], drawn on top of everything.
</theme_item>
+50 -32
View File
@@ -1535,35 +1535,45 @@ void ItemList::_notification(int p_what) {
rcache.size.width = width - rcache.position.x;
}
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;
Rect2 r = rcache;
r.position += base_ofs;
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;
if (rtl) {
r.position.x = size.width - r.position.x - r.size.x + theme_cache.panel_style->get_margin(SIDE_LEFT) - theme_cache.panel_style->get_margin(SIDE_RIGHT);
}
if (rtl) {
r.position.x = size.width - r.position.x - r.size.x + theme_cache.panel_style->get_margin(SIDE_LEFT) - theme_cache.panel_style->get_margin(SIDE_RIGHT);
if (items[i].custom_bg.a > 0.001f) {
draw_rect(r, items[i].custom_bg);
}
Ref<StyleBox> style;
bool is_hovered = (hovered == i);
bool is_selected = items[i].selected;
bool is_disabled = items[i].disabled;
bool is_focused = has_focus();
if (is_disabled) {
if (is_hovered) {
style = theme_cache.disabled_hovered_style;
} else {
style = theme_cache.disabled_style;
}
if (should_draw_selected_bg) {
draw_style_box(sbsel, r);
}
if (should_draw_hovered_selected_bg) {
if (has_focus(true)) {
draw_style_box(theme_cache.hovered_selected_focus_style, r);
} else {
if (is_hovered && is_selected) {
if (is_focused) {
style = theme_cache.hovered_selected_focus_style;
} else {
draw_style_box(theme_cache.hovered_selected_style, r);
style = theme_cache.hovered_selected_style;
}
} else if (is_hovered) {
style = theme_cache.hovered_style;
} else if (is_selected) {
style = sbsel;
}
if (should_draw_hovered_bg) {
draw_style_box(theme_cache.hovered_style, r);
}
if (should_draw_custom_bg) {
draw_rect(r, items[i].custom_bg);
}
}
if (style.is_valid()) {
draw_style_box(style, r);
}
Vector2 text_ofs;
@@ -1641,20 +1651,24 @@ void ItemList::_notification(int p_what) {
Color txt_modulate;
if (items[i].custom_fg != Color()) {
txt_modulate = items[i].custom_fg;
} else 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) {
} else if (is_disabled) {
if (is_hovered) {
txt_modulate = theme_cache.font_disabled_hovered_color;
} else {
txt_modulate = theme_cache.font_disabled_color;
}
} else if (is_selected) {
if (is_hovered) {
txt_modulate = theme_cache.font_hovered_selected_color;
} else {
txt_modulate = theme_cache.font_selected_color;
}
} else if (is_hovered) {
txt_modulate = theme_cache.font_hovered_color;
} else {
txt_modulate = theme_cache.font_color;
}
if (items[i].disabled) {
txt_modulate.a *= 0.5;
}
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
text_ofs.y += MAX(theme_cache.v_separation, 0) / 2;
text_ofs.x += MAX(theme_cache.h_separation, 0) / 2;
@@ -2485,6 +2499,8 @@ void ItemList::_bind_methods() {
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);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_disabled_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, font_disabled_hovered_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ItemList, scroll_hint);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, scroll_hint_color);
@@ -2497,6 +2513,8 @@ void ItemList::_bind_methods() {
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");
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, cursor_focus_style, "cursor");
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, disabled_style, "disabled");
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, ItemList, disabled_hovered_style, "disabled_hovered");
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, ItemList, guide_color);
Item defaults(true);
+4
View File
@@ -175,6 +175,8 @@ protected:
Color font_selected_color;
int font_outline_size = 0;
Color font_outline_color;
Color font_disabled_color;
Color font_disabled_hovered_color;
int line_separation = 0;
int icon_margin = 0;
@@ -185,6 +187,8 @@ protected:
Ref<StyleBox> selected_focus_style;
Ref<StyleBox> cursor_style;
Ref<StyleBox> cursor_focus_style;
Ref<StyleBox> disabled_style;
Ref<StyleBox> disabled_hovered_style;
Color guide_color;
Ref<Texture2D> scroll_hint;
+5 -1
View File
@@ -976,14 +976,18 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_hovered_color", "ItemList", control_font_hover_color);
theme->set_color("font_hovered_selected_color", "ItemList", control_font_pressed_color);
theme->set_color("font_selected_color", "ItemList", control_font_pressed_color);
theme->set_color("font_disabled_color", "ItemList", control_font_disabled_color);
theme->set_color("font_disabled_hovered_color", "ItemList", control_font_disabled_color);
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_color("scroll_hint_color", "ItemList", Color(0, 0, 0));
theme->set_stylebox("hovered", "ItemList", make_flat_stylebox(Color(1, 1, 1, 0.07)));
theme->set_stylebox("hovered", "ItemList", make_flat_stylebox(style_hover_color));
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("disabled", "ItemList", make_flat_stylebox(style_disabled_color));
theme->set_stylebox("disabled_hovered", "ItemList", make_flat_stylebox(style_hover_color));
theme->set_stylebox("cursor", "ItemList", focus);
theme->set_stylebox("cursor_unfocused", "ItemList", focus);
theme->set_icon("scroll_hint", "ItemList", icons["scroll_hint_vertical"]);