diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 48e37599816..23b5bb2c7bd 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -47,36 +47,47 @@ void ColorPicker::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { _update_color(); - [[fallthrough]]; - } + } break; + case NOTIFICATION_THEME_CHANGED: { - btn_pick->set_icon(get_theme_icon(SNAME("screen_picker"), SNAME("ColorPicker"))); + btn_pick->set_icon(theme_cache.screen_picker); _update_drop_down_arrow(btn_preset->is_pressed(), btn_preset); _update_drop_down_arrow(btn_recent_preset->is_pressed(), btn_recent_preset); - btn_add_preset->set_icon(get_theme_icon(SNAME("add_preset"))); + btn_add_preset->set_icon(theme_cache.add_preset); - btn_pick->set_custom_minimum_size(Size2(28 * get_theme_default_base_scale(), 0)); - btn_shape->set_custom_minimum_size(Size2(28 * get_theme_default_base_scale(), 0)); - btn_mode->set_custom_minimum_size(Size2(28 * get_theme_default_base_scale(), 0)); + btn_pick->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0)); + btn_shape->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0)); + btn_mode->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0)); - uv_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height")))); - w_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("h_width")), 0)); + uv_edit->set_custom_minimum_size(Size2(theme_cache.sv_width, theme_cache.sv_height)); + w_edit->set_custom_minimum_size(Size2(theme_cache.h_width, 0)); - wheel_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height")))); - wheel_margin->add_theme_constant_override("margin_bottom", 8 * get_theme_default_base_scale()); + wheel_edit->set_custom_minimum_size(Size2(theme_cache.sv_width, theme_cache.sv_height)); + wheel_margin->add_theme_constant_override("margin_bottom", 8 * theme_cache.base_scale); for (int i = 0; i < SLIDER_COUNT; i++) { - labels[i]->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0)); - set_offset((Side)i, get_offset((Side)i) + get_theme_constant(SNAME("margin"))); + labels[i]->set_custom_minimum_size(Size2(theme_cache.label_width, 0)); + set_offset((Side)i, get_offset((Side)i) + theme_cache.content_margin); } - alpha_label->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0)); - set_offset((Side)0, get_offset((Side)0) + get_theme_constant(SNAME("margin"))); + alpha_label->set_custom_minimum_size(Size2(theme_cache.label_width, 0)); + set_offset((Side)0, get_offset((Side)0) + theme_cache.content_margin); - _reset_theme(); + for (int i = 0; i < MODE_BUTTON_COUNT; i++) { + mode_btns[i]->add_theme_style_override("pressed", theme_cache.mode_button_pressed); + mode_btns[i]->add_theme_style_override("normal", theme_cache.mode_button_normal); + mode_btns[i]->add_theme_style_override("hover", theme_cache.mode_button_hover); + } + + shape_popup->set_item_icon(shape_popup->get_item_index(SHAPE_HSV_RECTANGLE), theme_cache.shape_rect); + shape_popup->set_item_icon(shape_popup->get_item_index(SHAPE_HSV_WHEEL), theme_cache.shape_rect_wheel); + shape_popup->set_item_icon(shape_popup->get_item_index(SHAPE_VHS_CIRCLE), theme_cache.shape_circle); + shape_popup->set_item_icon(shape_popup->get_item_index(SHAPE_OKHSL_CIRCLE), theme_cache.shape_circle); + + _reset_sliders_theme(); if (Engine::get_singleton()->is_editor_hint()) { // Adjust for the width of the "Script" icon. - text_type->set_custom_minimum_size(Size2(28 * get_theme_default_base_scale(), 0)); + text_type->set_custom_minimum_size(Size2(28 * theme_cache.base_scale, 0)); } _update_presets(); @@ -87,7 +98,7 @@ void ColorPicker::_notification(int p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { Popup *p = Object::cast_to(get_parent()); if (p && is_visible_in_tree()) { - p->set_size(Size2(get_combined_minimum_size().width + get_theme_constant(SNAME("margin")) * 2, get_combined_minimum_size().height + get_theme_constant(SNAME("margin")) * 2)); + p->set_size(Size2(get_combined_minimum_size().width + theme_cache.content_margin * 2, get_combined_minimum_size().height + theme_cache.content_margin * 2)); } } break; @@ -99,6 +110,38 @@ void ColorPicker::_notification(int p_what) { } } +void ColorPicker::_update_theme_item_cache() { + VBoxContainer::_update_theme_item_cache(); + + theme_cache.base_scale = get_theme_default_base_scale(); + + theme_cache.content_margin = get_theme_constant(SNAME("margin")); + theme_cache.label_width = get_theme_constant(SNAME("label_width")); + + theme_cache.sv_width = get_theme_constant(SNAME("sv_width")); + theme_cache.sv_height = get_theme_constant(SNAME("sv_height")); + theme_cache.h_width = get_theme_constant(SNAME("h_width")); + + theme_cache.screen_picker = get_theme_icon(SNAME("screen_picker")); + theme_cache.expanded_arrow = get_theme_icon(SNAME("expanded_arrow")); + theme_cache.folded_arrow = get_theme_icon(SNAME("folded_arrow")); + theme_cache.add_preset = get_theme_icon(SNAME("add_preset")); + + theme_cache.shape_rect = get_theme_icon(SNAME("shape_rect")); + theme_cache.shape_rect_wheel = get_theme_icon(SNAME("shape_rect_wheel")); + theme_cache.shape_circle = get_theme_icon(SNAME("shape_circle")); + + theme_cache.bar_arrow = get_theme_icon(SNAME("bar_arrow")); + theme_cache.sample_background_icon = get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")); + theme_cache.overbright_indicator = get_theme_icon(SNAME("overbright_indicator"), SNAME("ColorPicker")); + theme_cache.picker_cursor = get_theme_icon(SNAME("picker_cursor")); + theme_cache.color_hue_icon = get_theme_icon(SNAME("color_hue")); + + theme_cache.mode_button_normal = get_theme_stylebox("tab_unselected", "TabContainer"); + theme_cache.mode_button_pressed = get_theme_stylebox("tab_selected", "TabContainer"); + theme_cache.mode_button_hover = get_theme_stylebox("tab_selected", "TabContainer"); +} + Ref ColorPicker::wheel_shader; Ref ColorPicker::circle_shader; Ref ColorPicker::circle_ok_color_shader; @@ -475,21 +518,21 @@ ColorPicker::PickerShapeType ColorPicker::_get_actual_shape() const { return modes[current_mode]->get_shape_override() != SHAPE_MAX ? modes[current_mode]->get_shape_override() : current_shape; } -void ColorPicker::_reset_theme() { +void ColorPicker::_reset_sliders_theme() { Ref style_box_flat(memnew(StyleBoxFlat)); - style_box_flat->set_content_margin(SIDE_TOP, 16 * get_theme_default_base_scale()); + style_box_flat->set_content_margin(SIDE_TOP, 16 * theme_cache.base_scale); style_box_flat->set_bg_color(Color(0.2, 0.23, 0.31).lerp(Color(0, 0, 0, 1), 0.3).clamp()); for (int i = 0; i < SLIDER_COUNT; i++) { - sliders[i]->add_theme_icon_override("grabber", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker"))); - sliders[i]->add_theme_icon_override("grabber_highlight", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker"))); - sliders[i]->add_theme_constant_override("grabber_offset", 8 * get_theme_default_base_scale()); + sliders[i]->add_theme_icon_override("grabber", theme_cache.bar_arrow); + sliders[i]->add_theme_icon_override("grabber_highlight", theme_cache.bar_arrow); + sliders[i]->add_theme_constant_override("grabber_offset", 8 * theme_cache.base_scale); if (!colorize_sliders) { sliders[i]->add_theme_style_override("slider", style_box_flat); } } - alpha_slider->add_theme_icon_override("grabber", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker"))); - alpha_slider->add_theme_icon_override("grabber_highlight", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker"))); - alpha_slider->add_theme_constant_override("grabber_offset", 8 * get_theme_default_base_scale()); + alpha_slider->add_theme_icon_override("grabber", theme_cache.bar_arrow); + alpha_slider->add_theme_icon_override("grabber_highlight", theme_cache.bar_arrow); + alpha_slider->add_theme_constant_override("grabber_offset", 8 * theme_cache.base_scale); if (!colorize_sliders) { alpha_slider->add_theme_style_override("slider", style_box_flat); } @@ -676,9 +719,9 @@ void ColorPicker::_show_hide_preset(const bool &p_is_btn_pressed, Button *p_btn_ void ColorPicker::_update_drop_down_arrow(const bool &p_is_btn_pressed, Button *p_btn_preset) { if (p_is_btn_pressed) { - p_btn_preset->set_icon(get_theme_icon(SNAME("expanded_arrow"), SNAME("ColorPicker"))); + p_btn_preset->set_icon(theme_cache.expanded_arrow); } else { - p_btn_preset->set_icon(get_theme_icon(SNAME("folded_arrow"), SNAME("ColorPicker"))); + p_btn_preset->set_icon(theme_cache.folded_arrow); } } @@ -851,7 +894,7 @@ void ColorPicker::set_color_mode(ColorModeType p_mode) { } if (slider_theme_modified) { - _reset_theme(); + _reset_sliders_theme(); } mode_popup->set_item_checked(current_mode, false); @@ -896,7 +939,7 @@ void ColorPicker::set_colorize_sliders(bool p_colorize_sliders) { alpha_slider->add_theme_style_override("slider", style_box_empty); } else { Ref style_box_flat(memnew(StyleBoxFlat)); - style_box_flat->set_content_margin(SIDE_TOP, 16 * get_theme_default_base_scale()); + style_box_flat->set_content_margin(SIDE_TOP, 16 * theme_cache.base_scale); style_box_flat->set_bg_color(Color(0.2, 0.23, 0.31).lerp(Color(0, 0, 0, 1), 0.3).clamp()); if (!slider_theme_modified) { @@ -966,28 +1009,28 @@ void ColorPicker::_sample_draw() { const Rect2 rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95)); if (old_color.a < 1.0) { - sample->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), rect_old, true); + sample->draw_texture_rect(theme_cache.sample_background_icon, rect_old, true); } sample->draw_rect(rect_old, old_color); if (old_color.r > 1 || old_color.g > 1 || old_color.b > 1) { // Draw an indicator to denote that the old color is "overbright" and can't be displayed accurately in the preview. - sample->draw_texture(get_theme_icon(SNAME("overbright_indicator"), SNAME("ColorPicker")), Point2()); + sample->draw_texture(theme_cache.overbright_indicator, Point2()); } } else { rect_new = Rect2(Point2(), Size2(sample->get_size().width, sample->get_size().height * 0.95)); } if (color.a < 1.0) { - sample->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), rect_new, true); + sample->draw_texture_rect(theme_cache.sample_background_icon, rect_new, true); } sample->draw_rect(rect_new, color); if (color.r > 1 || color.g > 1 || color.b > 1) { // Draw an indicator to denote that the new color is "overbright" and can't be displayed accurately in the preview. - sample->draw_texture(get_theme_icon(SNAME("overbright_indicator"), SNAME("ColorPicker")), Point2(uv_edit->get_size().width * 0.5, 0)); + sample->draw_texture(theme_cache.overbright_indicator, Point2(uv_edit->get_size().width * 0.5, 0)); } } @@ -1063,21 +1106,21 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) { default: { } } - Ref cursor = get_theme_icon(SNAME("picker_cursor"), SNAME("ColorPicker")); + int x; int y; if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) { - x = center.x + (center.x * Math::cos(h * Math_TAU) * s) - (cursor->get_width() / 2); - y = center.y + (center.y * Math::sin(h * Math_TAU) * s) - (cursor->get_height() / 2); + x = center.x + (center.x * Math::cos(h * Math_TAU) * s) - (theme_cache.picker_cursor->get_width() / 2); + y = center.y + (center.y * Math::sin(h * Math_TAU) * s) - (theme_cache.picker_cursor->get_height() / 2); } else { real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0; real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0; Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2); - x = CLAMP(real_size.x * s, 0, real_size.x) + corner_x - (cursor->get_width() / 2); - y = CLAMP(real_size.y - real_size.y * v, 0, real_size.y) + corner_y - (cursor->get_height() / 2); + x = CLAMP(real_size.x * s, 0, real_size.x) + corner_x - (theme_cache.picker_cursor->get_width() / 2); + y = CLAMP(real_size.y - real_size.y * v, 0, real_size.y) + corner_y - (theme_cache.picker_cursor->get_height() / 2); } - c->draw_texture(cursor, Point2(x, y)); + c->draw_texture(theme_cache.picker_cursor, Point2(x, y)); col.set_hsv(h, 1, 1); if (actual_shape == SHAPE_HSV_WHEEL) { @@ -1093,9 +1136,8 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) { } else if (p_which == 1) { if (actual_shape == SHAPE_HSV_RECTANGLE) { - Ref hue = get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker")); c->draw_set_transform(Point2(), -Math_PI / 2, Size2(c->get_size().x, -c->get_size().y)); - c->draw_texture_rect(hue, Rect2(Point2(), Size2(1, 1))); + c->draw_texture_rect(theme_cache.color_hue_icon, Rect2(Point2(), Size2(1, 1))); c->draw_set_transform(Point2(), 0, Size2(1, 1)); int y = c->get_size().y - c->get_size().y * (1.0 - h); Color col; @@ -1663,10 +1705,10 @@ ColorPicker::ColorPicker() { current_shape = SHAPE_HSV_RECTANGLE; shape_popup = btn_shape->get_popup(); - shape_popup->add_icon_radio_check_item(get_theme_icon(SNAME("shape_rect"), SNAME("ColorPicker")), "HSV Rectangle", SHAPE_HSV_RECTANGLE); - shape_popup->add_icon_radio_check_item(get_theme_icon(SNAME("shape_rect_wheel"), SNAME("ColorPicker")), "HSV Wheel", SHAPE_HSV_WHEEL); - shape_popup->add_icon_radio_check_item(get_theme_icon(SNAME("shape_circle"), SNAME("ColorPicker")), "VHS Circle", SHAPE_VHS_CIRCLE); - shape_popup->add_icon_radio_check_item(get_theme_icon(SNAME("shape_circle"), SNAME("ColorPicker")), "OKHSL Circle", SHAPE_OKHSL_CIRCLE); + shape_popup->add_radio_check_item("HSV Rectangle", SHAPE_HSV_RECTANGLE); + shape_popup->add_radio_check_item("HSV Wheel", SHAPE_HSV_WHEEL); + shape_popup->add_radio_check_item("VHS Circle", SHAPE_VHS_CIRCLE); + shape_popup->add_radio_check_item("OKHSL Circle", SHAPE_OKHSL_CIRCLE); shape_popup->set_item_checked(current_shape, true); shape_popup->connect("id_pressed", callable_mp(this, &ColorPicker::set_picker_shape)); @@ -1687,9 +1729,6 @@ ColorPicker::ColorPicker() { mode_hbc->add_child(mode_btns[i]); mode_btns[i]->set_focus_mode(FOCUS_NONE); mode_btns[i]->set_h_size_flags(SIZE_EXPAND_FILL); - mode_btns[i]->add_theme_style_override("pressed", get_theme_stylebox("tab_selected", "TabContainer")); - mode_btns[i]->add_theme_style_override("normal", get_theme_stylebox("tab_unselected", "TabContainer")); - mode_btns[i]->add_theme_style_override("hover", get_theme_stylebox("tab_selected", "TabContainer")); mode_btns[i]->set_toggle_mode(true); mode_btns[i]->set_text(modes[i]->get_name()); mode_btns[i]->set_button_group(mode_group); @@ -1901,14 +1940,13 @@ void ColorPickerButton::pressed() { void ColorPickerButton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - const Ref normal = get_theme_stylebox(SNAME("normal")); - const Rect2 r = Rect2(normal->get_offset(), get_size() - normal->get_minimum_size()); - draw_texture_rect(Control::get_theme_icon(SNAME("bg"), SNAME("ColorPickerButton")), r, true); + const Rect2 r = Rect2(theme_cache.normal_style->get_offset(), get_size() - theme_cache.normal_style->get_minimum_size()); + draw_texture_rect(theme_cache.background_icon, r, true); draw_rect(r, color); if (color.r > 1 || color.g > 1 || color.b > 1) { // Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview - draw_texture(Control::get_theme_icon(SNAME("overbright_indicator"), SNAME("ColorPicker")), normal->get_offset()); + draw_texture(theme_cache.overbright_indicator, theme_cache.normal_style->get_offset()); } } break; @@ -1926,6 +1964,15 @@ void ColorPickerButton::_notification(int p_what) { } } +void ColorPickerButton::_update_theme_item_cache() { + Button::_update_theme_item_cache(); + + theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); + theme_cache.background_icon = get_theme_icon(SNAME("bg")); + + theme_cache.overbright_indicator = get_theme_icon(SNAME("overbright_indicator"), SNAME("ColorPicker")); +} + void ColorPickerButton::set_pick_color(const Color &p_color) { if (color == p_color) { return; @@ -2012,7 +2059,7 @@ void ColorPresetButton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { const Rect2 r = Rect2(Point2(0, 0), get_size()); - Ref sb_raw = get_theme_stylebox(SNAME("preset_fg"), SNAME("ColorPresetButton"))->duplicate(); + Ref sb_raw = theme_cache.foreground_style->duplicate(); Ref sb_flat = sb_raw; Ref sb_texture = sb_raw; @@ -2034,7 +2081,7 @@ void ColorPresetButton::_notification(int p_what) { bg_texture_rect = bg_texture_rect.grow_side(SIDE_TOP, -sb_flat->get_margin(SIDE_TOP)); bg_texture_rect = bg_texture_rect.grow_side(SIDE_BOTTOM, -sb_flat->get_margin(SIDE_BOTTOM)); - draw_texture_rect(get_theme_icon(SNAME("preset_bg"), SNAME("ColorPresetButton")), bg_texture_rect, true); + draw_texture_rect(theme_cache.background_icon, bg_texture_rect, true); sb_flat->set_bg_color(preset_color); } sb_flat->set_bg_color(preset_color); @@ -2043,7 +2090,7 @@ void ColorPresetButton::_notification(int p_what) { if (preset_color.a < 1) { // Draw a background pattern when the color is transparent. bool use_tile_texture = (sb_texture->get_h_axis_stretch_mode() == StyleBoxTexture::AxisStretchMode::AXIS_STRETCH_MODE_TILE) || (sb_texture->get_h_axis_stretch_mode() == StyleBoxTexture::AxisStretchMode::AXIS_STRETCH_MODE_TILE_FIT); - draw_texture_rect(get_theme_icon(SNAME("preset_bg"), SNAME("ColorPresetButton")), r, use_tile_texture); + draw_texture_rect(theme_cache.background_icon, r, use_tile_texture); } sb_texture->set_modulate(preset_color); sb_texture->draw(get_canvas_item(), r); @@ -2052,13 +2099,22 @@ void ColorPresetButton::_notification(int p_what) { } if (preset_color.r > 1 || preset_color.g > 1 || preset_color.b > 1) { // Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview - draw_texture(Control::get_theme_icon(SNAME("overbright_indicator"), SNAME("ColorPresetButton")), Vector2(0, 0)); + draw_texture(theme_cache.overbright_indicator, Vector2(0, 0)); } } break; } } +void ColorPresetButton::_update_theme_item_cache() { + BaseButton::_update_theme_item_cache(); + + theme_cache.foreground_style = get_theme_stylebox(SNAME("preset_fg")); + + theme_cache.background_icon = get_theme_icon(SNAME("preset_bg")); + theme_cache.overbright_indicator = get_theme_icon(SNAME("overbright_indicator")); +} + void ColorPresetButton::set_preset_color(const Color &p_color) { preset_color = p_color; } diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index d02c3278e6a..6e894efb00e 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -58,7 +58,16 @@ class ColorPresetButton : public BaseButton { Color preset_color; + struct ThemeCache { + Ref foreground_style; + + Ref background_icon; + Ref overbright_indicator; + } theme_cache; + protected: + virtual void _update_theme_item_cache() override; + void _notification(int); public: @@ -194,12 +203,43 @@ private: float v = 0.0; Color last_color; + struct ThemeCache { + float base_scale = 1.0; + + int content_margin = 0; + int label_width = 0; + + int sv_height = 0; + int sv_width = 0; + int h_width = 0; + + Ref screen_picker; + Ref expanded_arrow; + Ref folded_arrow; + Ref add_preset; + + Ref shape_rect; + Ref shape_rect_wheel; + Ref shape_circle; + + Ref bar_arrow; + Ref sample_background_icon; + Ref overbright_indicator; + Ref picker_cursor; + Ref color_hue_icon; + + /* Mode buttons */ + Ref mode_button_normal; + Ref mode_button_pressed; + Ref mode_button_hover; + } theme_cache; + void _copy_color_to_hsv(); void _copy_hsv_to_color(); PickerShapeType _get_actual_shape() const; void create_slider(GridContainer *gc, int idx); - void _reset_theme(); + void _reset_sliders_theme(); void _html_submitted(const String &p_html); void _value_changed(double); void _update_controls(); @@ -237,6 +277,8 @@ private: void _drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from_control); protected: + virtual void _update_theme_item_cache() override; + void _notification(int); static void _bind_methods(); @@ -326,6 +368,13 @@ class ColorPickerButton : public Button { Color color; bool edit_alpha = true; + struct ThemeCache { + Ref normal_style; + Ref background_icon; + + Ref overbright_indicator; + } theme_cache; + void _about_to_popup(); void _color_changed(const Color &p_color); void _modal_closed(); @@ -335,6 +384,8 @@ class ColorPickerButton : public Button { void _update_picker(); protected: + virtual void _update_theme_item_cache() override; + void _notification(int); static void _bind_methods();