From fe000277eaea77bb19ca0c5dae650ab4f76ccef0 Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Tue, 12 Sep 2023 15:01:42 +0200 Subject: [PATCH] Bind remaining theme properties to their respective classes This adds binds for GraphEdit/GraphElement/GraphNode, which were skipped before due to a rework. This also adds binds for Window, which was skipped before due to a complicated code organization. Also adds theme cache entries/direct cache access to a few places that previously missed it. Some theme properties are now exposed to other classes via friendships or public getters for convenience. This removes all string-based theme access from scene/ classes. --- scene/gui/code_edit.cpp | 17 ++- scene/gui/code_edit.h | 6 ++ scene/gui/color_mode.cpp | 20 ++-- scene/gui/color_picker.cpp | 13 +-- scene/gui/color_picker.h | 11 +- scene/gui/graph_edit.cpp | 140 ++++++++++++++----------- scene/gui/graph_edit.h | 73 +++++++++---- scene/gui/graph_element.cpp | 7 +- scene/gui/graph_element.h | 4 + scene/gui/graph_node.cpp | 62 ++++++----- scene/gui/graph_node.h | 18 +++- scene/gui/grid_container.cpp | 4 + scene/gui/grid_container.h | 2 + scene/gui/margin_container.cpp | 17 +++ scene/gui/margin_container.h | 2 + scene/gui/popup_menu.cpp | 4 +- scene/gui/rich_text_label.cpp | 13 +-- scene/gui/rich_text_label.h | 3 + scene/gui/split_container.cpp | 6 +- scene/gui/split_container.h | 4 +- scene/gui/text_edit.cpp | 19 ++-- scene/gui/text_edit.h | 15 +-- scene/main/viewport.cpp | 38 +++---- scene/main/window.cpp | 19 +++- scene/main/window.h | 26 ++++- scene/resources/syntax_highlighter.cpp | 2 +- 26 files changed, 356 insertions(+), 189 deletions(-) diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index f74d7fb906a..6ef8eacfd00 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -2399,6 +2399,19 @@ void CodeEdit::set_symbol_lookup_word_as_valid(bool p_valid) { } } +/* Visual */ +Color CodeEdit::_get_brace_mismatch_color() const { + return theme_cache.brace_mismatch_color; +} + +Color CodeEdit::_get_code_folding_color() const { + return theme_cache.code_folding_color; +} + +Ref CodeEdit::_get_folded_eol_icon() const { + return theme_cache.folded_eol_icon; +} + void CodeEdit::_bind_methods() { /* Indent management */ ClassDB::bind_method(D_METHOD("set_indent_size", "size"), &CodeEdit::set_indent_size); @@ -2644,7 +2657,7 @@ void CodeEdit::_bind_methods() { BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, CodeEdit, folded_eol_icon); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, breakpoint_color); - BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_COLOR, CodeEdit, breakpoint_icon, "breakpoint"); + BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, breakpoint_icon, "breakpoint"); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, bookmark_color); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, bookmark_icon, "bookmark"); @@ -2677,6 +2690,8 @@ void CodeEdit::_bind_methods() { /* Other visuals */ BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, CodeEdit, style_normal, "normal"); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, brace_mismatch_color); + BIND_THEME_ITEM(Theme::DATA_TYPE_FONT, CodeEdit, font); BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, CodeEdit, font_size); diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index 53ff65f3760..e688af2bda9 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -278,11 +278,17 @@ private: /* Other visuals */ Ref style_normal; + Color brace_mismatch_color; + Ref font; int font_size = 16; int line_spacing = 1; } theme_cache; + virtual Color _get_brace_mismatch_color() const override; + virtual Color _get_code_folding_color() const override; + virtual Ref _get_folded_eol_icon() const override; + /* Callbacks */ int lines_edited_changed = 0; int lines_edited_from = -1; diff --git a/scene/gui/color_mode.cpp b/scene/gui/color_mode.cpp index adea06eee7c..7d068a101e6 100644 --- a/scene/gui/color_mode.cpp +++ b/scene/gui/color_mode.cpp @@ -73,10 +73,10 @@ void ColorModeRGB::slider_draw(int p_which) { Color left_color; Color right_color; Color color = color_picker->get_pick_color(); - const real_t margin = 16 * color_picker->get_theme_default_base_scale(); + const real_t margin = 16 * color_picker->theme_cache.base_scale; if (p_which == ColorPicker::SLIDER_COUNT) { - slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true); + slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true); left_color = color; left_color.a = 0; @@ -168,10 +168,10 @@ void ColorModeHSV::slider_draw(int p_which) { Color left_color; Color right_color; Color color = color_picker->get_pick_color(); - const real_t margin = 16 * color_picker->get_theme_default_base_scale(); + const real_t margin = 16 * color_picker->theme_cache.base_scale; if (p_which == ColorPicker::SLIDER_COUNT) { - slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true); + slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true); left_color = color; left_color.a = 0; @@ -204,7 +204,7 @@ void ColorModeHSV::slider_draw(int p_which) { slider->draw_polygon(pos, col); if (p_which == 0) { // H - Ref hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker")); + Ref hue = color_picker->theme_cache.color_hue; slider->draw_texture_rect(hue, Rect2(Vector2(), Vector2(size.x, margin)), false, Color::from_hsv(0, 0, color.get_v(), color.get_s())); } } @@ -243,10 +243,10 @@ void ColorModeRAW::slider_draw(int p_which) { Color left_color; Color right_color; Color color = color_picker->get_pick_color(); - const real_t margin = 16 * color_picker->get_theme_default_base_scale(); + const real_t margin = 16 * color_picker->theme_cache.base_scale; if (p_which == ColorPicker::SLIDER_COUNT) { - slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true); + slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true); left_color = color; left_color.a = 0; @@ -334,7 +334,7 @@ Color ColorModeOKHSL::get_color() const { void ColorModeOKHSL::slider_draw(int p_which) { HSlider *slider = color_picker->get_slider(p_which); Size2 size = slider->get_size(); - const real_t margin = 16 * color_picker->get_theme_default_base_scale(); + const real_t margin = 16 * color_picker->theme_cache.base_scale; Vector pos; Vector col; @@ -370,7 +370,7 @@ void ColorModeOKHSL::slider_draw(int p_which) { col.resize(4); if (p_which == ColorPicker::SLIDER_COUNT) { - slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true); + slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true); left_color = color; left_color.a = 0; @@ -399,7 +399,7 @@ void ColorModeOKHSL::slider_draw(int p_which) { slider->draw_polygon(pos, col); if (p_which == 0) { // H - Ref hue = color_picker->get_theme_icon(SNAME("color_okhsl_hue"), SNAME("ColorPicker")); + Ref hue = color_picker->theme_cache.color_okhsl_hue; slider->draw_texture_rect(hue, Rect2(Vector2(), Vector2(size.x, margin)), false, Color::from_hsv(0, 0, color.get_ok_hsl_l() * 2.0, color.get_ok_hsl_s())); return; } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index d8342356d4f..5ec0714b64f 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -673,7 +673,7 @@ ColorPicker::PickerShapeType ColorPicker::get_picker_shape() const { } inline int ColorPicker::_get_preset_size() { - return (int(get_minimum_size().width) - (preset_container->get_theme_constant(SNAME("h_separation")) * (PRESET_COLUMN_COUNT - 1))) / PRESET_COLUMN_COUNT; + return (int(get_minimum_size().width) - (preset_container->get_h_separation() * (PRESET_COLUMN_COUNT - 1))) / PRESET_COLUMN_COUNT; } void ColorPicker::_add_preset_button(int p_size, const Color &p_color) { @@ -997,7 +997,7 @@ 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(theme_cache.sample_background_icon, rect_old, true); + sample->draw_texture_rect(theme_cache.sample_bg, rect_old, true); } sample->draw_rect(rect_old, old_color); @@ -1011,7 +1011,7 @@ void ColorPicker::_sample_draw() { } if (color.a < 1.0) { - sample->draw_texture_rect(theme_cache.sample_background_icon, rect_new, true); + sample->draw_texture_rect(theme_cache.sample_bg, rect_new, true); } sample->draw_rect(rect_new, color); @@ -1125,7 +1125,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) { } else if (p_which == 1) { if (actual_shape == SHAPE_HSV_RECTANGLE) { c->draw_set_transform(Point2(), -Math_PI / 2, Size2(c->get_size().x, -c->get_size().y)); - c->draw_texture_rect(theme_cache.color_hue_icon, Rect2(Point2(), Size2(1, 1))); + c->draw_texture_rect(theme_cache.color_hue, 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; @@ -1703,10 +1703,11 @@ void ColorPicker::_bind_methods() { BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, shape_circle); BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, bar_arrow); - BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPicker, sample_background_icon, "sample_bg"); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, sample_bg); BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, overbright_indicator); BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, picker_cursor); - BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPicker, color_hue_icon, "color_hue"); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_hue); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_okhsl_hue); BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_normal, "tab_unselected", "TabContainer"); BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_pressed, "tab_selected", "TabContainer"); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 12c7018149d..96dbca9a0cf 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -81,6 +81,12 @@ public: class ColorPicker : public VBoxContainer { GDCLASS(ColorPicker, VBoxContainer); + // These classes poke into theme items for their internal logic. + friend class ColorModeRGB; + friend class ColorModeHSV; + friend class ColorModeRAW; + friend class ColorModeOKHSL; + public: enum ColorModeType { MODE_RGB, @@ -229,10 +235,11 @@ private: Ref shape_circle; Ref bar_arrow; - Ref sample_background_icon; + Ref sample_bg; Ref overbright_indicator; Ref picker_cursor; - Ref color_hue_icon; + Ref color_hue; + Ref color_okhsl_hue; /* Mode buttons */ Ref mode_button_normal; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index be0ae45e7e0..80c115cd4d2 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -38,6 +38,7 @@ #include "scene/gui/graph_edit_arranger.h" #include "scene/gui/view_panner.h" #include "scene/resources/style_box_flat.h" +#include "scene/theme/theme_db.h" constexpr int MINIMAP_OFFSET = 12; constexpr int MINIMAP_PADDING = 5; @@ -56,23 +57,8 @@ GraphEditFilter::GraphEditFilter(GraphEdit *p_edit) { ge = p_edit; } -GraphEditMinimap::GraphEditMinimap(GraphEdit *p_edit) { - ge = p_edit; - - graph_proportions = Vector2(1, 1); - graph_padding = Vector2(0, 0); - camera_position = Vector2(100, 50); - camera_size = Vector2(200, 200); - minimap_padding = Vector2(MINIMAP_PADDING, MINIMAP_PADDING); - minimap_offset = minimap_padding + _convert_from_graph_position(graph_padding); - - is_pressing = false; - is_resizing = false; -} - Control::CursorShape GraphEditMinimap::get_cursor_shape(const Point2 &p_pos) const { - Ref resizer = get_theme_icon(SNAME("resizer")); - if (is_resizing || (p_pos.x < resizer->get_width() && p_pos.y < resizer->get_height())) { + if (is_resizing || (p_pos.x < theme_cache.resizer->get_width() && p_pos.y < theme_cache.resizer->get_height())) { return CURSOR_FDIAGSIZE; } @@ -172,8 +158,7 @@ void GraphEditMinimap::gui_input(const Ref &p_ev) { if (mb->is_pressed()) { is_pressing = true; - Ref resizer = get_theme_icon(SNAME("resizer")); - Rect2 resizer_hitbox = Rect2(Point2(), resizer->get_size()); + Rect2 resizer_hitbox = Rect2(Point2(), theme_cache.resizer->get_size()); if (resizer_hitbox.has_point(mb->get_position())) { is_resizing = true; } else { @@ -207,6 +192,21 @@ void GraphEditMinimap::_adjust_graph_scroll(const Vector2 &p_offset) { ge->set_scroll_offset(p_offset + graph_offset - camera_size / 2); } +void GraphEditMinimap::_bind_methods() { + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphEditMinimap, panel); + BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, GraphEditMinimap, node_style, "node"); + BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, GraphEditMinimap, camera_style, "camera"); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEditMinimap, resizer); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEditMinimap, resizer_color); +} + +GraphEditMinimap::GraphEditMinimap(GraphEdit *p_edit) { + ge = p_edit; + + minimap_padding = Vector2(MINIMAP_PADDING, MINIMAP_PADDING); + minimap_offset = minimap_padding + _convert_from_graph_position(graph_padding); +} + Control::CursorShape GraphEdit::get_cursor_shape(const Point2 &p_pos) const { if (moving_selection) { return CURSOR_MOVE; @@ -493,22 +493,25 @@ void GraphEdit::remove_child_notify(Node *p_child) { } } +void GraphEdit::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.base_scale = get_theme_default_base_scale(); +} + void GraphEdit::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - port_hotzone_inner_extent = get_theme_constant("port_hotzone_inner_extent"); - port_hotzone_outer_extent = get_theme_constant("port_hotzone_outer_extent"); + zoom_minus_button->set_icon(theme_cache.zoom_out); + zoom_reset_button->set_icon(theme_cache.zoom_reset); + zoom_plus_button->set_icon(theme_cache.zoom_in); - zoom_minus_button->set_icon(get_theme_icon(SNAME("zoom_out"))); - zoom_reset_button->set_icon(get_theme_icon(SNAME("zoom_reset"))); - zoom_plus_button->set_icon(get_theme_icon(SNAME("zoom_in"))); + toggle_snapping_button->set_icon(theme_cache.snapping_toggle); + show_grid_button->set_icon(theme_cache.grid_toggle); + minimap_button->set_icon(theme_cache.minimap_toggle); + layout_button->set_icon(theme_cache.layout); - toggle_snapping_button->set_icon(get_theme_icon(SNAME("snapping_toggle"))); - show_grid_button->set_icon(get_theme_icon(SNAME("grid_toggle"))); - minimap_button->set_icon(get_theme_icon(SNAME("minimap_toggle"))); - layout_button->set_icon(get_theme_icon(SNAME("layout"))); - - zoom_label->set_custom_minimum_size(Size2(48, 0) * get_theme_default_base_scale()); + zoom_label->set_custom_minimum_size(Size2(48, 0) * theme_cache.base_scale); } break; case NOTIFICATION_READY: { @@ -528,7 +531,7 @@ void GraphEdit::_notification(int p_what) { case NOTIFICATION_DRAW: { // Draw background fill. - draw_style_box(get_theme_stylebox(SNAME("panel")), Rect2(Point2(), get_size())); + draw_style_box(theme_cache.panel, Rect2(Point2(), get_size())); // Draw background grid. if (show_grid) { @@ -538,16 +541,13 @@ void GraphEdit::_notification(int p_what) { Point2i from_pos = (offset / float(snapping_distance)).floor(); Point2i len = (size / float(snapping_distance)).floor() + Vector2(1, 1); - Color grid_minor = get_theme_color(SNAME("grid_minor")); - Color grid_major = get_theme_color(SNAME("grid_major")); - for (int i = from_pos.x; i < from_pos.x + len.x; i++) { Color color; if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) { - color = grid_major; + color = theme_cache.grid_major; } else { - color = grid_minor; + color = theme_cache.grid_minor; } float base_offset = i * snapping_distance * zoom - offset.x * zoom; @@ -558,9 +558,9 @@ void GraphEdit::_notification(int p_what) { Color color; if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) { - color = grid_major; + color = theme_cache.grid_major; } else { - color = grid_minor; + color = theme_cache.grid_minor; } float base_offset = i * snapping_distance * zoom - offset.y * zoom; @@ -578,14 +578,14 @@ void GraphEdit::_notification(int p_what) { } bool GraphEdit::_filter_input(const Point2 &p_point) { - Ref port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); - for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *graph_node = Object::cast_to(get_child(i)); if (!graph_node || !graph_node->is_visible_in_tree()) { continue; } + Ref port_icon = graph_node->theme_cache.port; + for (int j = 0; j < graph_node->get_input_port_count(); j++) { Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); @@ -620,8 +620,6 @@ bool GraphEdit::_filter_input(const Point2 &p_point) { void GraphEdit::_top_layer_input(const Ref &p_ev) { Ref mb = p_ev; if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { - Ref port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); - connecting_valid = false; click_pos = mb->get_position() / zoom; for (int i = get_child_count() - 1; i >= 0; i--) { @@ -630,6 +628,8 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { continue; } + Ref port_icon = graph_node->theme_cache.port; + for (int j = 0; j < graph_node->get_output_port_count(); j++) { Vector2 pos = graph_node->get_output_port_position(j) * zoom + graph_node->get_position(); Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height()); @@ -756,12 +756,13 @@ void GraphEdit::_top_layer_input(const Ref &p_ev) { if (connecting_valid) { Vector2 mpos = mm->get_position() / zoom; for (int i = get_child_count() - 1; i >= 0; i--) { - Ref port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); GraphNode *graph_node = Object::cast_to(get_child(i)); if (!graph_node || !graph_node->is_visible_in_tree()) { continue; } + Ref port_icon = graph_node->theme_cache.port; + if (!connecting_out) { for (int j = 0; j < graph_node->get_output_port_count(); j++) { Vector2 pos = graph_node->get_output_port_position(j) * zoom + graph_node->get_position(); @@ -877,7 +878,7 @@ bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_port_idx, con bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { if (p_graph_node->is_resizable()) { - Ref resizer = p_graph_node->get_theme_icon(SNAME("resizer")); + Ref resizer = p_graph_node->theme_cache.resizer; Rect2 resizer_rect = Rect2(p_graph_node->get_position() / zoom + p_graph_node->get_size() - resizer->get_size(), resizer->get_size()); if (resizer_rect.has_point(p_mouse_pos)) { return false; @@ -895,9 +896,9 @@ bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, co bool GraphEdit::is_in_port_hotzone(const Vector2 &p_pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) { Rect2 hotzone = Rect2( - p_pos.x - (p_left ? port_hotzone_outer_extent : port_hotzone_inner_extent), + p_pos.x - (p_left ? theme_cache.port_hotzone_outer_extent : theme_cache.port_hotzone_inner_extent), p_pos.y - p_port_size.height / 2.0, - port_hotzone_inner_extent + port_hotzone_outer_extent, + theme_cache.port_hotzone_inner_extent + theme_cache.port_hotzone_outer_extent, p_port_size.height); if (!hotzone.has_point(p_mouse_pos)) { @@ -965,12 +966,10 @@ void GraphEdit::_draw_connection_line(CanvasItem *p_where, const Vector2 &p_from } // Thickness below 0.5 doesn't look good on the graph or its minimap. - p_where->draw_polyline_colors(scaled_points, colors, MAX(0.5, Math::floor(p_width * get_theme_default_base_scale())), lines_antialiased); + p_where->draw_polyline_colors(scaled_points, colors, MAX(0.5, Math::floor(p_width * theme_cache.base_scale)), lines_antialiased); } void GraphEdit::_connections_layer_draw() { - Color activity_color = get_theme_color(SNAME("activity")); - // Draw connections. List::Element *> to_erase; for (List::Element *E = connections.front(); E; E = E->next()) { @@ -998,8 +997,8 @@ void GraphEdit::_connections_layer_draw() { Color tocolor = gnode_to->get_input_port_color(c.to_port); if (c.activity > 0) { - color = color.lerp(activity_color, c.activity); - tocolor = tocolor.lerp(activity_color, c.activity); + color = color.lerp(theme_cache.activity_color, c.activity); + tocolor = tocolor.lerp(theme_cache.activity_color, c.activity); } _draw_connection_line(connections_layer, frompos, topos, color, tocolor, lines_thickness, zoom); } @@ -1042,8 +1041,8 @@ void GraphEdit::_top_layer_draw() { } if (box_selecting) { - top_layer->draw_rect(box_selecting_rect, get_theme_color(SNAME("selection_fill"))); - top_layer->draw_rect(box_selecting_rect, get_theme_color(SNAME("selection_stroke")), false); + top_layer->draw_rect(box_selecting_rect, theme_cache.selection_fill); + top_layer->draw_rect(box_selecting_rect, theme_cache.selection_stroke, false); } } @@ -1056,7 +1055,7 @@ void GraphEdit::_minimap_draw() { // Draw the minimap background. Rect2 minimap_rect = Rect2(Point2(), minimap->get_size()); - minimap->draw_style_box(minimap->get_theme_stylebox(SNAME("panel")), minimap_rect); + minimap->draw_style_box(minimap->theme_cache.panel, minimap_rect); Vector2 graph_offset = minimap->_get_graph_offset(); Vector2 minimap_offset = minimap->minimap_offset; @@ -1072,10 +1071,10 @@ void GraphEdit::_minimap_draw() { Vector2 node_size = minimap->_convert_from_graph_position(graph_node->get_size() * zoom); Rect2 node_rect = Rect2(node_position, node_size); - Ref sb_minimap = minimap->get_theme_stylebox(SNAME("node"))->duplicate(); + Ref sb_minimap = minimap->theme_cache.node_style->duplicate(); // Override default values with colors provided by the GraphNode's stylebox, if possible. - Ref sb_frame = graph_node->get_theme_stylebox(graph_node->is_selected() ? "panel_selected" : "panel"); + Ref sb_frame = graph_node->is_selected() ? graph_node->theme_cache.panel_selected : graph_node->theme_cache.panel; if (sb_frame.is_valid()) { Color node_color = sb_frame->get_bg_color(); sb_minimap->set_bg_color(node_color); @@ -1085,7 +1084,6 @@ void GraphEdit::_minimap_draw() { } // Draw node connections. - Color activity_color = get_theme_color(SNAME("activity")); for (const Connection &E : connections) { Node *from = get_node(NodePath(E.from_node)); GraphNode *graph_node_from = Object::cast_to(from); @@ -1107,19 +1105,19 @@ void GraphEdit::_minimap_draw() { Color to_color = graph_node_to->get_input_port_color(E.to_port); if (E.activity > 0) { - from_color = from_color.lerp(activity_color, E.activity); - to_color = to_color.lerp(activity_color, E.activity); + from_color = from_color.lerp(theme_cache.activity_color, E.activity); + to_color = to_color.lerp(theme_cache.activity_color, E.activity); } _draw_connection_line(minimap, from_position, to_position, from_color, to_color, 0.5, minimap->_convert_from_graph_position(Vector2(zoom, zoom)).length()); } // Draw the "camera" viewport. Rect2 camera_rect = minimap->get_camera_rect(); - minimap->draw_style_box(minimap->get_theme_stylebox(SNAME("camera")), camera_rect); + minimap->draw_style_box(minimap->theme_cache.camera_style, camera_rect); // Draw the resizer control. - Ref resizer = minimap->get_theme_icon(SNAME("resizer")); - Color resizer_color = minimap->get_theme_color(SNAME("resizer_color")); + Ref resizer = minimap->theme_cache.resizer; + Color resizer_color = minimap->theme_cache.resizer_color; minimap->draw_texture(resizer, Point2(), resizer_color); } @@ -1909,6 +1907,26 @@ void GraphEdit::_bind_methods() { BIND_ENUM_CONSTANT(SCROLL_ZOOMS); BIND_ENUM_CONSTANT(SCROLL_PANS); + + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphEdit, panel); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, grid_major); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, grid_minor); + + BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_COLOR, GraphEdit, activity_color, "activity"); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, selection_fill); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, selection_stroke); + + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, zoom_in); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, zoom_out); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, zoom_reset); + + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, snapping_toggle); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, grid_toggle); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, minimap_toggle); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, layout); + + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphEdit, port_hotzone_inner_extent); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphEdit, port_hotzone_outer_extent); } GraphEdit::GraphEdit() { diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 5e97ea353da..6b5698ad414 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -47,6 +47,7 @@ class GraphEditFilter : public Control { friend class GraphEdit; friend class GraphEditMinimap; + GraphEdit *ge = nullptr; virtual bool has_point(const Point2 &p_point) const override; @@ -63,24 +64,24 @@ class GraphEditMinimap : public Control { GraphEdit *ge = nullptr; -public: - GraphEditMinimap(GraphEdit *p_edit); - - virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override; - - void update_minimap(); - Rect2 get_camera_rect(); - -private: Vector2 minimap_padding; Vector2 minimap_offset; - Vector2 graph_proportions; - Vector2 graph_padding; - Vector2 camera_position; - Vector2 camera_size; + Vector2 graph_proportions = Vector2(1, 1); + Vector2 graph_padding = Vector2(0, 0); + Vector2 camera_position = Vector2(100, 50); + Vector2 camera_size = Vector2(200, 200); - bool is_pressing; - bool is_resizing; + bool is_pressing = false; + bool is_resizing = false; + + struct ThemeCache { + Ref panel; + Ref node_style; + Ref camera_style; + + Ref resizer; + Color resizer_color; + } theme_cache; Vector2 _get_render_size(); Vector2 _get_graph_offset(); @@ -92,6 +93,17 @@ private: virtual void gui_input(const Ref &p_ev) override; void _adjust_graph_scroll(const Vector2 &p_offset); + +protected: + static void _bind_methods(); + +public: + virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override; + + void update_minimap(); + Rect2 get_camera_rect(); + + GraphEditMinimap(GraphEdit *p_edit); }; class GraphEdit : public Control { @@ -150,9 +162,6 @@ private: HScrollBar *h_scrollbar = nullptr; VScrollBar *v_scrollbar = nullptr; - float port_hotzone_inner_extent = 0.0; - float port_hotzone_outer_extent = 0.0; - Ref panner; bool warped_panning = true; @@ -218,7 +227,30 @@ private: HashSet valid_left_disconnect_types; HashSet valid_right_disconnect_types; - void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); + struct ThemeCache { + float base_scale = 1.0; + + Ref panel; + Color grid_major; + Color grid_minor; + + Color activity_color; + Color selection_fill; + Color selection_stroke; + + Ref zoom_in; + Ref zoom_out; + Ref zoom_reset; + + Ref snapping_toggle; + Ref grid_toggle; + Ref minimap_toggle; + Ref layout; + + float port_hotzone_inner_extent = 0.0; + float port_hotzone_outer_extent = 0.0; + } theme_cache; + void _pan_callback(Vector2 p_scroll_vec, Ref p_event); void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref p_event); @@ -262,12 +294,13 @@ private: bool _check_clickable_control(Control *p_control, const Vector2 &r_mouse_pos, const Vector2 &p_offset); protected: - static void _bind_methods(); + virtual void _update_theme_item_cache() override; virtual void add_child_notify(Node *p_child) override; virtual void remove_child_notify(Node *p_child) override; void _notification(int p_what); + static void _bind_methods(); virtual bool is_in_input_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); virtual bool is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); diff --git a/scene/gui/graph_element.cpp b/scene/gui/graph_element.cpp index 04c4aa6ce86..ac2cb8bd5d6 100644 --- a/scene/gui/graph_element.cpp +++ b/scene/gui/graph_element.cpp @@ -32,6 +32,7 @@ #include "core/string/translation.h" #include "scene/gui/graph_edit.h" +#include "scene/theme/theme_db.h" #ifdef TOOLS_ENABLED void GraphElement::_edit_set_position(const Point2 &p_position) { @@ -154,9 +155,7 @@ void GraphElement::gui_input(const Ref &p_ev) { if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { Vector2 mpos = mb->get_position(); - Ref resizer = get_theme_icon(SNAME("resizer")); - - if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) { + if (resizable && mpos.x > get_size().x - theme_cache.resizer->get_width() && mpos.y > get_size().y - theme_cache.resizer->get_height()) { resizing = true; resizing_from = mpos; resizing_from_size = get_size(); @@ -241,4 +240,6 @@ void GraphElement::_bind_methods() { ADD_SIGNAL(MethodInfo("raise_request")); ADD_SIGNAL(MethodInfo("close_request")); ADD_SIGNAL(MethodInfo("resize_request", PropertyInfo(Variant::VECTOR2, "new_minsize"))); + + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphElement, resizer); } diff --git a/scene/gui/graph_element.h b/scene/gui/graph_element.h index 2c0a4760d84..a50c2953fd3 100644 --- a/scene/gui/graph_element.h +++ b/scene/gui/graph_element.h @@ -49,6 +49,10 @@ protected: Vector2 position_offset; + struct ThemeCache { + Ref resizer; + } theme_cache; + #ifdef TOOLS_ENABLED void _edit_set_position(const Point2 &p_position) override; #endif diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 385b564b7c0..fdebca3d288 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -33,6 +33,7 @@ #include "core/string/translation.h" #include "scene/gui/box_container.h" #include "scene/gui/label.h" +#include "scene/theme/theme_db.h" bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { String str = p_name; @@ -151,8 +152,8 @@ void GraphNode::_get_property_list(List *p_list) const { void GraphNode::_resort() { Size2 new_size = get_size(); - Ref sb_panel = get_theme_stylebox(SNAME("panel")); - Ref sb_titlebar = get_theme_stylebox(SNAME("titlebar")); + Ref sb_panel = theme_cache.panel; + Ref sb_titlebar = theme_cache.titlebar; // Resort titlebar first. Size2 titlebar_size = Size2(new_size.width, titlebar_hbox->get_size().height); @@ -164,8 +165,8 @@ void GraphNode::_resort() { Size2i titlebar_min_size = titlebar_hbox->get_combined_minimum_size(); // First pass, determine minimum size AND amount of stretchable elements. - Ref sb_slot = get_theme_stylebox(SNAME("slot")); - int separation = get_theme_constant(SNAME("separation")); + Ref sb_slot = theme_cache.slot; + int separation = theme_cache.separation; int children_count = 0; int stretch_min = 0; @@ -300,7 +301,7 @@ void GraphNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Co Point2 icon_offset; if (!port_icon.is_valid()) { - port_icon = get_theme_icon(SNAME("port")); + port_icon = theme_cache.port; } icon_offset = -port_icon->get_size() * 0.5; @@ -311,19 +312,15 @@ void GraphNode::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { // Used for layout calculations. - Ref sb_panel = get_theme_stylebox(SNAME("panel")); - Ref sb_titlebar = get_theme_stylebox(SNAME("titlebar")); + Ref sb_panel = theme_cache.panel; + Ref sb_titlebar = theme_cache.titlebar; // Used for drawing. - Ref sb_to_draw_panel = get_theme_stylebox(selected ? SNAME("panel_selected") : SNAME("panel")); - Ref sb_to_draw_titlebar = get_theme_stylebox(selected ? SNAME("titlebar_selected") : SNAME("titlebar")); + Ref sb_to_draw_panel = selected ? theme_cache.panel_selected : theme_cache.panel; + Ref sb_to_draw_titlebar = selected ? theme_cache.titlebar_selected : theme_cache.titlebar; - Ref sb_slot = get_theme_stylebox(SNAME("slot")); + Ref sb_slot = theme_cache.slot; - int port_h_offset = get_theme_constant(SNAME("port_h_offset")); - - Ref resizer_icon = get_theme_icon(SNAME("resizer")); - - Color resizer_color = get_theme_color(SNAME("resizer_color")); + int port_h_offset = theme_cache.port_h_offset; Rect2 titlebar_rect(Point2(), titlebar_hbox->get_size() + sb_titlebar->get_minimum_size()); Size2 body_size = get_size(); @@ -377,7 +374,7 @@ void GraphNode::_notification(int p_what) { } if (resizable) { - draw_texture(resizer_icon, get_size() - resizer_icon->get_size(), resizer_color); + draw_texture(theme_cache.resizer, get_size() - theme_cache.resizer->get_size(), theme_cache.resizer_color); } } break; } @@ -566,11 +563,11 @@ void GraphNode::set_slot_draw_stylebox(int p_slot_index, bool p_enable) { } Size2 GraphNode::get_minimum_size() const { - Ref sb_panel = get_theme_stylebox(SNAME("panel")); - Ref sb_titlebar = get_theme_stylebox(SNAME("titlebar")); - Ref sb_slot = get_theme_stylebox(SNAME("slot")); + Ref sb_panel = theme_cache.panel; + Ref sb_titlebar = theme_cache.titlebar; + Ref sb_slot = theme_cache.slot; - int separation = get_theme_constant(SNAME("separation")); + int separation = theme_cache.separation; Size2 minsize = titlebar_hbox->get_minimum_size() + sb_titlebar->get_minimum_size(); for (int i = 0; i < get_child_count(false); i++) { @@ -599,11 +596,11 @@ Size2 GraphNode::get_minimum_size() const { } void GraphNode::_port_pos_update() { - int edgeofs = get_theme_constant(SNAME("port_h_offset")); - int separation = get_theme_constant(SNAME("separation")); + int edgeofs = theme_cache.port_h_offset; + int separation = theme_cache.separation; - Ref sb_panel = get_theme_stylebox(SNAME("panel")); - Ref sb_titlebar = get_theme_stylebox(SNAME("titlebar")); + Ref sb_panel = theme_cache.panel; + Ref sb_titlebar = theme_cache.titlebar; left_port_cache.clear(); right_port_cache.clear(); @@ -754,9 +751,7 @@ HBoxContainer *GraphNode::get_titlebar_hbox() { Control::CursorShape GraphNode::get_cursor_shape(const Point2 &p_pos) const { if (resizable) { - Ref resizer = get_theme_icon(SNAME("resizer")); - - if (resizing || (p_pos.x > get_size().x - resizer->get_width() && p_pos.y > get_size().y - resizer->get_height())) { + if (resizing || (p_pos.x > get_size().x - theme_cache.resizer->get_width() && p_pos.y > get_size().y - theme_cache.resizer->get_height())) { return CURSOR_FDIAGSIZE; } } @@ -830,6 +825,19 @@ void GraphNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "slot_index"))); + + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, panel); + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, panel_selected); + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, titlebar); + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, titlebar_selected); + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, slot); + + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphNode, separation); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphNode, port_h_offset); + + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphNode, port); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphNode, resizer); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphNode, resizer_color); } GraphNode::GraphNode() { diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 11784218192..04ca9e7cb4e 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -38,6 +38,8 @@ class HBoxContainer; class GraphNode : public GraphElement { GDCLASS(GraphNode, GraphElement); + friend class GraphEdit; + struct Slot { bool enable_left = false; int type_left = 0; @@ -74,9 +76,23 @@ class GraphNode : public GraphElement { Vector right_port_cache; HashMap slot_table; - Vector slot_y_cache; + struct ThemeCache { + Ref panel; + Ref panel_selected; + Ref titlebar; + Ref titlebar_selected; + Ref slot; + + int separation = 0; + int port_h_offset = 0; + + Ref port; + Ref resizer; + Color resizer_color; + } theme_cache; + bool port_pos_dirty = true; void _port_pos_update(); diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 1db51e45b7c..a4baf3bb8d1 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -259,6 +259,10 @@ int GridContainer::get_columns() const { return columns; } +int GridContainer::get_h_separation() const { + return theme_cache.h_separation; +} + void GridContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_columns", "columns"), &GridContainer::set_columns); ClassDB::bind_method(D_METHOD("get_columns"), &GridContainer::get_columns); diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h index e98acef165e..f6a51511a98 100644 --- a/scene/gui/grid_container.h +++ b/scene/gui/grid_container.h @@ -52,6 +52,8 @@ public: int get_columns() const; virtual Size2 get_minimum_size() const override; + int get_h_separation() const; + GridContainer(); }; diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index 5688d8b8f3a..6d331afbb54 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -80,6 +80,23 @@ Vector MarginContainer::get_allowed_size_flags_vertical() const { return flags; } +int MarginContainer::get_margin_size(Side p_side) const { + ERR_FAIL_INDEX_V((int)p_side, 4, 0); + + switch (p_side) { + case SIDE_LEFT: + return theme_cache.margin_left; + case SIDE_RIGHT: + return theme_cache.margin_right; + case SIDE_TOP: + return theme_cache.margin_top; + case SIDE_BOTTOM: + return theme_cache.margin_bottom; + } + + return 0; +} + void MarginContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_SORT_CHILDREN: { diff --git a/scene/gui/margin_container.h b/scene/gui/margin_container.h index 4ad9a56cf49..d57ab9b4529 100644 --- a/scene/gui/margin_container.h +++ b/scene/gui/margin_container.h @@ -53,6 +53,8 @@ public: virtual Vector get_allowed_size_flags_horizontal() const override; virtual Vector get_allowed_size_flags_vertical() const override; + int get_margin_size(Side p_side) const; + MarginContainer(); }; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 1fd9030a866..1fac301f9a5 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -559,8 +559,8 @@ void PopupMenu::_draw_items() { RID ci = control->get_canvas_item(); Size2 margin_size; - margin_size.width = margin_container->get_theme_constant(SNAME("margin_right")) + margin_container->get_theme_constant(SNAME("margin_left")); - margin_size.height = margin_container->get_theme_constant(SNAME("margin_top")) + margin_container->get_theme_constant(SNAME("margin_bottom")); + margin_size.width = margin_container->get_margin_size(SIDE_LEFT) + margin_container->get_margin_size(SIDE_RIGHT); + margin_size.height = margin_container->get_margin_size(SIDE_TOP) + margin_container->get_margin_size(SIDE_BOTTOM); // Space between the item content and the sides of popup menu. bool rtl = control->is_layout_rtl(); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 3f4fd880538..15dd119c91a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5817,6 +5817,9 @@ void RichTextLabel::_bind_methods() { BIND_THEME_ITEM(Theme::DATA_TYPE_FONT, RichTextLabel, mono_font); BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, RichTextLabel, mono_font_size); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, text_highlight_h_padding); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, text_highlight_v_padding); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, table_h_separation); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, table_v_separation); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, RichTextLabel, table_odd_row_bg); @@ -6029,8 +6032,6 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item Vector2i fbg_index = Vector2i(end, start); Color last_color = Color(0, 0, 0, 0); bool draw_box = false; - int hpad = get_theme_constant(SNAME("text_highlight_h_padding")); - int vpad = get_theme_constant(SNAME("text_highlight_v_padding")); // Draw a box based on color tags associated with glyphs for (int i = start; i < end; i++) { Item *it = _get_item_at_pos(it_from, it_to, i); @@ -6060,8 +6061,8 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item if (draw_box) { Vector sel = TS->shaped_text_get_selection(p_rid, fbg_index.x, fbg_index.y); for (int j = 0; j < sel.size(); j++) { - Vector2 rect_off = line_off + Vector2(sel[j].x - hpad, -TS->shaped_text_get_ascent(p_rid) - vpad); - Vector2 rect_size = Vector2(sel[j].y - sel[j].x + 2 * hpad, TS->shaped_text_get_size(p_rid).y + 2 * vpad); + Vector2 rect_off = line_off + Vector2(sel[j].x - theme_cache.text_highlight_h_padding, -TS->shaped_text_get_ascent(p_rid) - theme_cache.text_highlight_v_padding); + Vector2 rect_size = Vector2(sel[j].y - sel[j].x + 2 * theme_cache.text_highlight_h_padding, TS->shaped_text_get_size(p_rid).y + 2 * theme_cache.text_highlight_v_padding); RenderingServer::get_singleton()->canvas_item_add_rect(p_ci, Rect2(rect_off, rect_size), last_color); } fbg_index = Vector2i(end, start); @@ -6079,8 +6080,8 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item if (last_color.a > 0) { Vector sel = TS->shaped_text_get_selection(p_rid, fbg_index.x, end); for (int i = 0; i < sel.size(); i++) { - Vector2 rect_off = line_off + Vector2(sel[i].x - hpad, -TS->shaped_text_get_ascent(p_rid) - vpad); - Vector2 rect_size = Vector2(sel[i].y - sel[i].x + 2 * hpad, TS->shaped_text_get_size(p_rid).y + 2 * vpad); + Vector2 rect_off = line_off + Vector2(sel[i].x - theme_cache.text_highlight_h_padding, -TS->shaped_text_get_ascent(p_rid) - theme_cache.text_highlight_v_padding); + Vector2 rect_size = Vector2(sel[i].y - sel[i].x + 2 * theme_cache.text_highlight_h_padding, TS->shaped_text_get_size(p_rid).y + 2 * theme_cache.text_highlight_v_padding); RenderingServer::get_singleton()->canvas_item_add_rect(p_ci, Rect2(rect_off, rect_size), last_color); } } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index af48e7efce1..d88623073d2 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -592,6 +592,9 @@ private: Ref mono_font; int mono_font_size; + int text_highlight_h_padding; + int text_highlight_v_padding; + int table_h_separation; int table_v_separation; Color table_odd_row_bg; diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 4a76c341e27..06b32b548f0 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -97,7 +97,7 @@ void SplitContainerDragger::_notification(int p_what) { case NOTIFICATION_MOUSE_ENTER: { mouse_inside = true; SplitContainer *sc = Object::cast_to(get_parent()); - if (sc->get_theme_constant(SNAME("autohide"))) { + if (sc->theme_cache.autohide) { queue_redraw(); } } break; @@ -105,14 +105,14 @@ void SplitContainerDragger::_notification(int p_what) { case NOTIFICATION_MOUSE_EXIT: { mouse_inside = false; SplitContainer *sc = Object::cast_to(get_parent()); - if (sc->get_theme_constant(SNAME("autohide"))) { + if (sc->theme_cache.autohide) { queue_redraw(); } } break; case NOTIFICATION_DRAW: { SplitContainer *sc = Object::cast_to(get_parent()); - if (!dragging && !mouse_inside && sc->get_theme_constant(SNAME("autohide"))) { + if (!dragging && !mouse_inside && sc->theme_cache.autohide) { return; } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 878560dd590..f008d2678bb 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -73,7 +73,7 @@ private: struct ThemeCache { int separation = 0; int minimum_grab_thickness = 0; - int autohide = 0; + bool autohide = false; Ref grabber_icon; Ref grabber_icon_h; Ref grabber_icon_v; @@ -85,8 +85,6 @@ private: void _compute_middle_sep(bool p_clamp); void _resort(); - void _dragging_area_gui_input(const Ref &p_event); - protected: bool is_fixed = false; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index cc519ad38ba..f28f20b5847 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1254,7 +1254,7 @@ void TextEdit::_notification(int p_what) { if ((brace_matching[c].open_match_line == line && brace_matching[c].open_match_column == glyphs[j].start) || (get_caret_column(c) == glyphs[j].start && get_caret_line(c) == line && carets_wrap_index[c] == line_wrap_index && (brace_matching[c].open_matching || brace_matching[c].open_mismatch))) { if (brace_matching[c].open_mismatch) { - gl_color = theme_cache.brace_mismatch_color; + gl_color = _get_brace_mismatch_color(); } Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1)); draw_rect(rect, gl_color); @@ -1263,7 +1263,7 @@ void TextEdit::_notification(int p_what) { if ((brace_matching[c].close_match_line == line && brace_matching[c].close_match_column == glyphs[j].start) || (get_caret_column(c) == glyphs[j].start + 1 && get_caret_line(c) == line && carets_wrap_index[c] == line_wrap_index && (brace_matching[c].close_matching || brace_matching[c].close_mismatch))) { if (brace_matching[c].close_mismatch) { - gl_color = theme_cache.brace_mismatch_color; + gl_color = _get_brace_mismatch_color(); } Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1)); draw_rect(rect, gl_color); @@ -1313,12 +1313,12 @@ void TextEdit::_notification(int p_what) { // is_line_folded if (line_wrap_index == line_wrap_amount && line < text.size() - 1 && _is_line_hidden(line + 1)) { - int xofs = char_ofs + char_margin + ofs_x + (theme_cache.folded_eol_icon->get_width() / 2); + int xofs = char_ofs + char_margin + ofs_x + (_get_folded_eol_icon()->get_width() / 2); if (xofs >= xmargin_beg && xofs < xmargin_end) { - int yofs = (text_height - theme_cache.folded_eol_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); - Color eol_color = theme_cache.code_folding_color; + int yofs = (text_height - _get_folded_eol_icon()->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); + Color eol_color = _get_code_folding_color(); eol_color.a = 1; - theme_cache.folded_eol_icon->draw(ci, Point2(xofs, ofs_y + yofs), eol_color); + _get_folded_eol_icon()->draw(ci, Point2(xofs, ofs_y + yofs), eol_color); } } @@ -3000,7 +3000,6 @@ void TextEdit::_update_theme_item_cache() { Control::_update_theme_item_cache(); theme_cache.base_scale = get_theme_default_base_scale(); - theme_cache.folded_code_region_color = get_theme_color(SNAME("folded_code_region_color"), SNAME("CodeEdit")); use_selected_font_color = theme_cache.font_selected_color != Color(0, 0, 0, 0); if (text.get_line_height() + theme_cache.line_spacing < 1) { @@ -6474,12 +6473,6 @@ void TextEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("gutter_removed")); /* Theme items */ - /* Internal API for CodeEdit */ - BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, brace_mismatch_color, "brace_mismatch_color", "CodeEdit"); - BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, code_folding_color, "code_folding_color", "CodeEdit"); - BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, folded_code_region_color, "folded_code_region_color", "CodeEdit"); - BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_ICON, TextEdit, folded_eol_icon, "folded_eol_icon", "CodeEdit"); - /* Search */ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, TextEdit, search_result_color); BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, TextEdit, search_result_border_color); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index d874db34bf4..7be58bd9274 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -41,6 +41,8 @@ class TextEdit : public Control { GDCLASS(TextEdit, Control); + friend class CodeHighlighter; + public: /* Edit Actions. */ enum EditAction { @@ -543,12 +545,6 @@ private: struct ThemeCache { float base_scale = 1.0; - /* Internal API for CodeEdit */ - Color brace_mismatch_color; - Color code_folding_color = Color(1, 1, 1); - Color folded_code_region_color = Color(1, 1, 1); - Ref folded_eol_icon; - /* Search */ Color search_result_color = Color(1, 1, 1); Color search_result_border_color = Color(1, 1, 1); @@ -633,7 +629,7 @@ protected: virtual void _update_theme_item_cache() override; /* Internal API for CodeEdit, pending public API. */ - // brace matching + // Brace matching. struct BraceMatchingData { int open_match_line = -1; int open_match_column = -1; @@ -662,6 +658,11 @@ protected: String lookup_symbol_word; void _set_symbol_lookup_word(const String &p_symbol); + // Theme items. + virtual Color _get_brace_mismatch_color() const { return Color(); }; + virtual Color _get_code_folding_color() const { return Color(); }; + virtual Ref _get_folded_eol_icon() const { return Ref(); }; + /* Text manipulation */ // Overridable actions diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 5f8f5225c91..518cc4b7c92 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -319,16 +319,16 @@ void Viewport::_sub_window_update(Window *p_window) { Rect2i r = Rect2i(p_window->get_position(), sw.window->get_size()); if (!p_window->get_flag(Window::FLAG_BORDERLESS)) { - Ref panel = p_window->get_theme_stylebox(gui.subwindow_focused == p_window ? SNAME("embedded_border") : SNAME("embedded_unfocused_border")); + Ref panel = gui.subwindow_focused == p_window ? p_window->theme_cache.embedded_border : p_window->theme_cache.embedded_unfocused_border; panel->draw(sw.canvas_item, r); // Draw the title bar text. - Ref title_font = p_window->get_theme_font(SNAME("title_font")); - int font_size = p_window->get_theme_font_size(SNAME("title_font_size")); - Color title_color = p_window->get_theme_color(SNAME("title_color")); - int title_height = p_window->get_theme_constant(SNAME("title_height")); - int close_h_ofs = p_window->get_theme_constant(SNAME("close_h_offset")); - int close_v_ofs = p_window->get_theme_constant(SNAME("close_v_offset")); + Ref title_font = p_window->theme_cache.title_font; + int font_size = p_window->theme_cache.title_font_size; + Color title_color = p_window->theme_cache.title_color; + int title_height = p_window->theme_cache.title_height; + int close_h_ofs = p_window->theme_cache.close_h_offset; + int close_v_ofs = p_window->theme_cache.close_v_offset; TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size); title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs); @@ -336,15 +336,15 @@ void Viewport::_sub_window_update(Window *p_window) { int x = (r.size.width - title_text.get_size().x) / 2; int y = (-title_height - title_text.get_size().y) / 2; - Color font_outline_color = p_window->get_theme_color(SNAME("title_outline_modulate")); - int outline_size = p_window->get_theme_constant(SNAME("title_outline_size")); + Color font_outline_color = p_window->theme_cache.title_outline_modulate; + int outline_size = p_window->theme_cache.title_outline_size; if (outline_size > 0 && font_outline_color.a > 0) { title_text.draw_outline(sw.canvas_item, r.position + Point2(x, y), outline_size, font_outline_color); } title_text.draw(sw.canvas_item, r.position + Point2(x, y), title_color); bool pressed = gui.subwindow_focused == sw.window && gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE && gui.subwindow_drag_close_inside; - Ref close_icon = p_window->get_theme_icon(pressed ? "close_pressed" : "close"); + Ref close_icon = pressed ? p_window->theme_cache.close_pressed : p_window->theme_cache.close; close_icon->draw(sw.canvas_item, r.position + Vector2(r.size.width - close_h_ofs, -close_v_ofs)); } @@ -2039,7 +2039,7 @@ void Viewport::_gui_input_event(Ref p_event) { Window *sw = embedder->gui.sub_windows[i].window; Rect2 swrect = Rect2i(sw->get_position(), sw->get_size()); if (!sw->get_flag(Window::FLAG_BORDERLESS)) { - int title_height = sw->get_theme_constant(SNAME("title_height")); + int title_height = sw->theme_cache.title_height; swrect.position.y -= title_height; swrect.size.y += title_height; } @@ -2669,7 +2669,7 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw Rect2i r = Rect2i(p_subwindow->get_position(), p_subwindow->get_size()); - int title_height = p_subwindow->get_theme_constant(SNAME("title_height")); + int title_height = p_subwindow->theme_cache.title_height; r.position.y -= title_height; r.size.y += title_height; @@ -2681,7 +2681,7 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw int dist_x = p_point.x < r.position.x ? (p_point.x - r.position.x) : (p_point.x > (r.position.x + r.size.x) ? (p_point.x - (r.position.x + r.size.x)) : 0); int dist_y = p_point.y < r.position.y ? (p_point.y - r.position.y) : (p_point.y > (r.position.y + r.size.y) ? (p_point.y - (r.position.y + r.size.y)) : 0); - int limit = p_subwindow->get_theme_constant(SNAME("resize_margin")); + int limit = p_subwindow->theme_cache.resize_margin; if (ABS(dist_x) > limit) { return SUB_WINDOW_RESIZE_DISABLED; @@ -2866,7 +2866,7 @@ bool Viewport::_sub_windows_forward_input(const Ref &p_event) { if (!sw.window->get_flag(Window::FLAG_BORDERLESS)) { // Check top bar. - int title_height = sw.window->get_theme_constant(SNAME("title_height")); + int title_height = sw.window->theme_cache.title_height; Rect2i title_bar = r; title_bar.position.y -= title_height; title_bar.size.y = title_height; @@ -2874,9 +2874,9 @@ bool Viewport::_sub_windows_forward_input(const Ref &p_event) { if (title_bar.size.y > 0 && title_bar.has_point(mb->get_position())) { click_on_window = sw.window; - int close_h_ofs = sw.window->get_theme_constant(SNAME("close_h_offset")); - int close_v_ofs = sw.window->get_theme_constant(SNAME("close_v_offset")); - Ref close_icon = sw.window->get_theme_icon(SNAME("close")); + int close_h_ofs = sw.window->theme_cache.close_h_offset; + int close_v_ofs = sw.window->theme_cache.close_v_offset; + Ref close_icon = sw.window->theme_cache.close; Rect2 close_rect; close_rect.position = Vector2(r.position.x + r.size.x - close_h_ofs, r.position.y - close_v_ofs); @@ -3016,8 +3016,8 @@ void Viewport::_update_mouse_over(Vector2 p_pos) { Rect2 swrect_border = swrect; if (!sw->get_flag(Window::FLAG_BORDERLESS)) { - int title_height = sw->get_theme_constant(SNAME("title_height")); - int margin = sw->get_theme_constant(SNAME("resize_margin")); + int title_height = sw->theme_cache.title_height; + int margin = sw->theme_cache.resize_margin; swrect_border.position.y -= title_height + margin; swrect_border.size.y += title_height + margin * 2; swrect_border.position.x -= margin; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index a34fda3065a..c345c3d179e 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1804,7 +1804,7 @@ Rect2i Window::fit_rect_in_parent(Rect2i p_rect, const Rect2i &p_parent_rect) co p_rect.position.x = 0; } - int title_height = get_flag(Window::FLAG_BORDERLESS) ? 0 : get_theme_constant(SNAME("title_height")); + int title_height = get_flag(Window::FLAG_BORDERLESS) ? 0 : theme_cache.title_height; if (p_rect.position.y < title_height) { p_rect.position.y = title_height; @@ -2910,6 +2910,23 @@ void Window::_bind_methods() { BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_KEYBOARD_FOCUS); GDVIRTUAL_BIND(_get_contents_minimum_size); + + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, Window, embedded_border); + BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, Window, embedded_unfocused_border); + + BIND_THEME_ITEM(Theme::DATA_TYPE_FONT, Window, title_font); + BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, Window, title_font_size); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Window, title_color); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, title_height); + BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Window, title_outline_modulate); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, title_outline_size); + + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, Window, close); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, Window, close_pressed); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, close_h_offset); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, close_v_offset); + + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, resize_margin); } Window::Window() { diff --git a/scene/main/window.h b/scene/main/window.h index 26b974a9c15..11b986239e2 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -42,7 +42,8 @@ class ThemeOwner; class ThemeContext; class Window : public Viewport { - GDCLASS(Window, Viewport) + GDCLASS(Window, Viewport); + public: // Keep synced with enum hint for `mode` property. enum Mode { @@ -191,6 +192,25 @@ private: void _notify_theme_override_changed(); void _invalidate_theme_cache(); + struct ThemeCache { + Ref embedded_border; + Ref embedded_unfocused_border; + + Ref title_font; + int title_font_size = 0; + Color title_color; + int title_height = 0; + Color title_outline_modulate; + int title_outline_size = 0; + + Ref close; + Ref close_pressed; + int close_h_offset = 0; + int close_v_offset = 0; + + int resize_margin = 0; + } theme_cache; + Viewport *embedder = nullptr; Transform2D window_transform; @@ -212,12 +232,12 @@ private: protected: virtual Rect2i _popup_adjust_rect() const { return Rect2i(); } + virtual void _post_popup() {} virtual void _update_theme_item_cache(); - virtual void _post_popup() {} - static void _bind_methods(); void _notification(int p_what); + static void _bind_methods(); bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index 903be41c26c..aa311baa43c 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -419,7 +419,7 @@ void CodeHighlighter::_clear_highlighting_cache() { } void CodeHighlighter::_update_cache() { - font_color = text_edit->get_theme_color(SNAME("font_color")); + font_color = text_edit->theme_cache.font_color; } void CodeHighlighter::add_keyword_color(const String &p_keyword, const Color &p_color) {