Merge pull request #74739 from davthedev/itemlist-hover

Add theming support for hovered ItemList items
This commit is contained in:
Rémi Verschelde 2023-04-20 12:41:41 +02:00
commit 42d3ed2103
No known key found for this signature in database
GPG Key ID: C3336907360768E1
5 changed files with 62 additions and 19 deletions

View File

@ -439,6 +439,9 @@
<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_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>
<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The tint of text outline of the item.
</theme_item>
@ -479,6 +482,9 @@
<theme_item name="focus" data_type="style" type="StyleBox">
The focused style for the [ItemList], drawn on top of the background, but below everything else.
</theme_item>
<theme_item name="hovered" data_type="style" type="StyleBox">
[StyleBox] for the hovered, but not selected items.
</theme_item>
<theme_item name="panel" data_type="style" type="StyleBox">
The background style for the [ItemList].
</theme_item>

View File

@ -1296,13 +1296,20 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_itemlist_cursor->set_draw_center(false);
style_itemlist_cursor->set_border_width_all(border_width);
style_itemlist_cursor->set_border_color(highlight_color);
Ref<StyleBoxFlat> style_itemlist_hover = style_tree_selected->duplicate();
style_itemlist_hover->set_bg_color(highlight_color * Color(1, 1, 1, 0.3));
style_itemlist_hover->set_border_width_all(0);
theme->set_stylebox("panel", "ItemList", style_itemlist_bg);
theme->set_stylebox("focus", "ItemList", style_widget_focus);
theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor);
theme->set_stylebox("cursor_unfocused", "ItemList", style_itemlist_cursor);
theme->set_stylebox("selected_focus", "ItemList", style_tree_focus);
theme->set_stylebox("selected", "ItemList", style_tree_selected);
theme->set_stylebox("hovered", "ItemList", style_itemlist_hover);
theme->set_color("font_color", "ItemList", font_color);
theme->set_color("font_hovered_color", "ItemList", mono_color);
theme->set_color("font_selected_color", "ItemList", mono_color);
theme->set_color("font_outline_color", "ItemList", font_outline_color);
theme->set_color("guide_color", "ItemList", guide_color);

View File

@ -646,6 +646,14 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
return;
}
if (mm.is_valid()) {
int closest = get_item_at_position(mm->get_position(), true);
if (closest != hovered) {
hovered = closest;
queue_redraw();
}
}
if (mb.is_valid() && mb->is_pressed()) {
search_string = ""; //any mousepress cancels
Vector2 pos = mb->get_position();
@ -975,12 +983,14 @@ void ItemList::_update_theme_item_cache() {
theme_cache.font = get_theme_font(SNAME("font"));
theme_cache.font_size = get_theme_font_size(SNAME("font_size"));
theme_cache.font_color = get_theme_color(SNAME("font_color"));
theme_cache.font_hovered_color = get_theme_color(SNAME("font_hovered_color"));
theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color"));
theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size"));
theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color"));
theme_cache.line_separation = get_theme_constant(SNAME("line_separation"));
theme_cache.icon_margin = get_theme_constant(SNAME("icon_margin"));
theme_cache.hovered_style = get_theme_stylebox(SNAME("hovered"));
theme_cache.selected_style = get_theme_stylebox(SNAME("selected"));
theme_cache.selected_focus_style = get_theme_stylebox(SNAME("selected_focus"));
theme_cache.cursor_style = get_theme_stylebox(SNAME("cursor_unfocused"));
@ -1101,7 +1111,11 @@ void ItemList::_notification(int p_what) {
rcache.size.width = width - rcache.position.x;
}
if (items[i].selected) {
bool should_draw_selected_bg = items[i].selected;
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) {
Rect2 r = rcache;
r.position += base_ofs;
r.position.y -= theme_cache.v_separation / 2;
@ -1113,23 +1127,15 @@ void ItemList::_notification(int p_what) {
r.position.x = size.width - r.position.x - r.size.x;
}
draw_style_box(sbsel, r);
}
if (items[i].custom_bg.a > 0.001) {
Rect2 r = rcache;
r.position += base_ofs;
// Size rect to make the align the temperature colors
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;
if (should_draw_selected_bg) {
draw_style_box(sbsel, r);
}
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);
}
draw_rect(r, items[i].custom_bg);
}
Vector2 text_ofs;
@ -1204,7 +1210,17 @@ void ItemList::_notification(int p_what) {
max_len = size2.x;
}
Color txt_modulate = items[i].selected ? theme_cache.font_selected_color : (items[i].custom_fg != Color() ? items[i].custom_fg : theme_cache.font_color);
Color txt_modulate;
if (items[i].selected) {
txt_modulate = theme_cache.font_selected_color;
} else if (hovered == i) {
txt_modulate = theme_cache.font_hovered_color;
} else if (items[i].custom_fg != Color()) {
txt_modulate = items[i].custom_fg;
} else {
txt_modulate = theme_cache.font_color;
}
if (items[i].disabled) {
txt_modulate.a *= 0.5;
}
@ -1454,6 +1470,13 @@ void ItemList::_scroll_changed(double) {
queue_redraw();
}
void ItemList::_mouse_exited() {
if (hovered > -1) {
hovered = -1;
queue_redraw();
}
}
int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const {
Vector2 pos = p_pos;
pos -= theme_cache.panel_style->get_offset();
@ -1851,9 +1874,10 @@ void ItemList::_bind_methods() {
ItemList::ItemList() {
scroll_bar = memnew(VScrollBar);
add_child(scroll_bar, false, INTERNAL_MODE_FRONT);
scroll_bar->connect("value_changed", callable_mp(this, &ItemList::_scroll_changed));
connect("mouse_exited", callable_mp(this, &ItemList::_mouse_exited));
set_focus_mode(FOCUS_ALL);
set_clip_contents(true);
}

View File

@ -84,6 +84,7 @@ private:
};
int current = -1;
int hovered = -1;
bool shape_changed = true;
@ -130,12 +131,14 @@ private:
Ref<Font> font;
int font_size = 0;
Color font_color;
Color font_hovered_color;
Color font_selected_color;
int font_outline_size = 0;
Color font_outline_color;
int line_separation = 0;
int icon_margin = 0;
Ref<StyleBox> hovered_style;
Ref<StyleBox> selected_style;
Ref<StyleBox> selected_focus_style;
Ref<StyleBox> cursor_style;
@ -146,6 +149,7 @@ private:
void _scroll_changed(double);
void _check_shape_changed();
void _shape_text(int p_idx);
void _mouse_exited();
protected:
virtual void _update_theme_item_cache() override;

View File

@ -803,9 +803,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "ItemList", -1);
theme->set_color("font_color", "ItemList", control_font_lower_color);
theme->set_color("font_hovered_color", "ItemList", control_font_hover_color);
theme->set_color("font_selected_color", "ItemList", control_font_pressed_color);
theme->set_color("font_outline_color", "ItemList", Color(1, 1, 1));
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("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);