From a8fc8ee70e2d8e1ea264c22d577df4609860bd14 Mon Sep 17 00:00:00 2001 From: Chris Cranford Date: Sat, 6 Jan 2024 04:52:28 -0500 Subject: [PATCH] GH-59 Support border/corner radius & gradient title bars --- src/editor/graph/graph_node.cpp | 132 ++++++++++++++++++++++++++++---- src/editor/graph/graph_node.h | 24 +++++- src/plugin/settings.cpp | 2 + 3 files changed, 143 insertions(+), 15 deletions(-) diff --git a/src/editor/graph/graph_node.cpp b/src/editor/graph/graph_node.cpp index 3a61992a..d506b8e5 100644 --- a/src/editor/graph/graph_node.cpp +++ b/src/editor/graph/graph_node.cpp @@ -27,6 +27,8 @@ #include #include +#include +#include #include #include #include @@ -36,6 +38,7 @@ #include #include #include +#include OrchestratorGraphNode::OrchestratorGraphNode(OrchestratorGraphEdit* p_graph, const Ref& p_node) { @@ -341,37 +344,68 @@ void OrchestratorGraphNode::_update_styles() apply_style_defaults = false; Color color = os->get_setting(key); - Ref panel = _make_colored_style("panel_selected", color); + Ref panel = _make_colored_style("panel_selected", color); if (panel.is_valid()) add_theme_stylebox_override("panel", panel); - Ref panel_selected = _make_selected_style("panel"); + Ref panel_selected = _make_selected_style("panel"); if (panel_selected.is_valid()) add_theme_stylebox_override("panel_selected", panel_selected); - Ref titlebar = _make_colored_style("titlebar_selected", color, true); - if (titlebar.is_valid()) - add_theme_stylebox_override("titlebar", titlebar); + if (_use_gradient_color_style()) + { + Ref sb = _make_colored_style("titlebar_selected", color, true); + if (sb.is_valid()) + add_theme_stylebox_override("titlebar", sb); + + Ref sb_selected = _make_selected_style("titlebar", true); + if (sb_selected.is_valid()) + add_theme_stylebox_override("titlebar_selected", sb_selected); + + Ref sb2 = _make_gradient_titlebar_style("titlebar_selected", color, false); + if (sb2.is_valid()) + add_theme_stylebox_override("titlebar", sb2); + } + else + { + Ref sb = _make_colored_style("titlebar_selected", color, true); + if (sb.is_valid()) + add_theme_stylebox_override("titlebar", sb); - Ref titlebar_selected = _make_selected_style("titlebar", true); - if (titlebar_selected.is_valid()) - add_theme_stylebox_override("titlebar_selected", titlebar_selected); + Ref sb_selected = _make_selected_style("titlebar", true); + if (sb_selected.is_valid()) + add_theme_stylebox_override("titlebar_selected", sb_selected); + } } } if (apply_style_defaults) { - Ref panel_selected = _make_selected_style("panel_selected"); + Ref panel_selected = _make_selected_style("panel_selected"); if (panel_selected.is_valid()) add_theme_stylebox_override("panel_selected", panel_selected); - Ref titlebar_selected = _make_selected_style("titlebar_selected", true); + Ref titlebar_selected = _make_selected_style("titlebar_selected", true); if (titlebar_selected.is_valid()) add_theme_stylebox_override("titlebar_selected", titlebar_selected); } } -Ref OrchestratorGraphNode::_make_colored_style(const String& p_existing_name, const Color& p_color, bool p_titlebar) +Color OrchestratorGraphNode::_get_selection_color() const +{ + return { 0.68f, 0.44f, 0.09f }; +} + +bool OrchestratorGraphNode::_use_gradient_color_style() const +{ + OrchestratorSettings* os = OrchestratorSettings::get_singleton(); + if (os) + return os->get_setting("ui/nodes/titlebar/use_gradient_colors", false); + + return false; +} + +Ref OrchestratorGraphNode::_make_colored_style(const String& p_existing_name, const Color& p_color, bool p_titlebar) { Ref sb = get_theme_stylebox(p_existing_name); if (sb.is_valid()) @@ -381,26 +415,98 @@ Ref OrchestratorGraphNode::_make_colored_style(const String& p_exi dup->set_bg_color(p_color); else dup->set_border_color(p_color); + + _apply_corner_radius(dup, p_titlebar); + return dup; } return sb; } -Ref OrchestratorGraphNode::_make_selected_style(const String& p_existing_name, bool p_titlebar) +Ref OrchestratorGraphNode::_make_selected_style(const String& p_existing_name, bool p_titlebar) { Ref sb = get_theme_stylebox(p_existing_name); if (sb.is_valid()) { Ref dup = sb->duplicate(true); - dup->set_border_color(Color(0.68f, 0.44f, 0.09f)); + dup->set_border_color(_get_selection_color()); dup->set_border_width(p_titlebar ? SIDE_TOP : SIDE_BOTTOM, 2); dup->set_border_width(SIDE_LEFT, 2); dup->set_border_width(SIDE_RIGHT, 2); + + _apply_corner_radius(dup, p_titlebar); + return dup; } return sb; } +Ref OrchestratorGraphNode::_make_gradient_titlebar_style(const String& p_existing_name, const Color& p_color, + bool p_selected) +{ + Ref gradient(memnew(Gradient)); + + PackedFloat32Array offsets; + offsets.push_back(0); + offsets.push_back(1); + gradient->set_offsets(offsets); + + PackedColorArray colors = gradient->get_colors(); + colors.reverse(); + gradient->set_colors(colors); + + Ref texture(memnew(GradientTexture2D)); + texture->set_gradient(gradient); + texture->set_width(64); + texture->set_height(64); + texture->set_fill_to(Vector2(1.1, 0)); + + Ref titlebar_tex(memnew(StyleBoxTexture)); + titlebar_tex->set_texture(texture); + titlebar_tex->set_modulate(p_color); + + Ref sb = get_theme_stylebox(p_existing_name); + if (sb.is_valid()) + { + titlebar_tex->set_content_margin(SIDE_TOP, sb->get_content_margin(SIDE_TOP)); + titlebar_tex->set_content_margin(SIDE_RIGHT, sb->get_content_margin(SIDE_RIGHT)); + titlebar_tex->set_content_margin(SIDE_BOTTOM, sb->get_content_margin(SIDE_BOTTOM)); + titlebar_tex->set_content_margin(SIDE_LEFT, sb->get_content_margin(SIDE_LEFT)); + } + + if (p_selected) + titlebar_tex->set_modulate(_get_selection_color()); + + return titlebar_tex; +} + +void OrchestratorGraphNode::_apply_corner_radius(Ref& p_stylebox, bool p_titlebar) +{ + if (p_stylebox.is_valid() && _use_gradient_color_style()) + { + // In this case, we explicitly only support a border radius of 6 on the bottom part. + p_stylebox->set_corner_radius(CORNER_BOTTOM_LEFT, 6); + p_stylebox->set_corner_radius(CORNER_BOTTOM_RIGHT, 6); + return; + } + + OrchestratorSettings* os = OrchestratorSettings::get_singleton(); + if (p_stylebox.is_valid() && os) + { + int border_radius = os->get_setting("ui/nodes/border_radius", 6); + if (p_titlebar) + { + p_stylebox->set_corner_radius(CORNER_TOP_LEFT, border_radius); + p_stylebox->set_corner_radius(CORNER_TOP_RIGHT, border_radius); + } + else + { + p_stylebox->set_corner_radius(CORNER_BOTTOM_LEFT, border_radius); + p_stylebox->set_corner_radius(CORNER_BOTTOM_RIGHT, border_radius); + } + } +} + void OrchestratorGraphNode::_update_node_attributes() { // Attempt to shrink the container diff --git a/src/editor/graph/graph_node.h b/src/editor/graph/graph_node.h index 603cd242..bc7de8ed 100644 --- a/src/editor/graph/graph_node.h +++ b/src/editor/graph/graph_node.h @@ -172,16 +172,36 @@ class OrchestratorGraphNode : public GraphNode /// Update the node's styles void _update_styles(); + /// Returns the selection color when a node is selected by the user. + /// @return the selection color + Color _get_selection_color() const; + + /// Returns whether to use gradient color scheme + /// @return true to use gradient title bar color scheme, false otherwise + bool _use_gradient_color_style() const; + /// Creates a style based on a specific color. /// @param p_existing_name the existing style to clone from /// @param p_color the color to be applied /// @param p_titlebar whether to treat the style box as a titlebar or panel border - Ref _make_colored_style(const String& p_existing_name, const Color& p_color, bool p_titlebar = false); + Ref _make_colored_style(const String& p_existing_name, const Color& p_color, bool p_titlebar = false); /// Creates a style based on node selection color. /// @param p_existing_name the existing style to clone from /// @param p_titlebar whether to treat the style box as a titlebar or panel border - Ref _make_selected_style(const String& p_existing_name, bool p_titlebar = false); + Ref _make_selected_style(const String& p_existing_name, bool p_titlebar = false); + + /// Creates a gradient style box + /// @param p_existing_name the existing style name to use as a basis + /// @param p_color the color to use + /// @param p_selected whether it should render as selected + /// @return the created style box + Ref _make_gradient_titlebar_style(const String& p_existing_name, const Color& p_color, bool p_selected = false); + + /// Apply the configured corner radius to the given style box. + /// @param p_stylebox the style box to be modified + /// @param p_titlebar whether the style box represents the titlebar + void _apply_corner_radius(Ref& p_stylebox, bool p_titlebar = false); /// Called by various callbacks to update node attributes void _update_node_attributes(); diff --git a/src/plugin/settings.cpp b/src/plugin/settings.cpp index 9c2993dd..db5844ca 100644 --- a/src/plugin/settings.cpp +++ b/src/plugin/settings.cpp @@ -94,6 +94,8 @@ void OrchestratorSettings::_register_settings() _settings.emplace_back(BOOL_SETTING("ui/nodes/show_type_icons", true)); _settings.emplace_back(BOOL_SETTING("ui/nodes/show_conversion_nodes", false)); + _settings.emplace_back(RANGE_SETTING("ui/nodes/border_radius", "0,24,1", 6)); + _settings.emplace_back(BOOL_SETTING("ui/nodes/titlebar/use_gradient_colors", false)); // Nodes _settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/constants_and_literals", Color(0.271, 0.392, 0.2)));