From c2a2c0abed627b4a9065f374997063225a06340e 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 | 4 +- 3 files changed, 144 insertions(+), 16 deletions(-) diff --git a/src/editor/graph/graph_node.cpp b/src/editor/graph/graph_node.cpp index cd92dc93..f8e5f994 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 @@ -34,6 +36,7 @@ #include #include #include +#include OrchestratorGraphNode::OrchestratorGraphNode(OrchestratorGraphEdit* p_graph, const Ref& p_node) { @@ -339,37 +342,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()) @@ -379,26 +413,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 a30690d7..29b73071 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 5c834ac3..f5de0b15 100644 --- a/src/plugin/settings.cpp +++ b/src/plugin/settings.cpp @@ -85,7 +85,7 @@ void OrchestratorSettings::_register_settings() { // Orchestrator v2 _settings.emplace_back(RESOURCE_SETTING("settings/default_type", "Object", "Node")); - _settings.emplace_back(RANGE_SETTING("settings/runtime_max_call_stack", "256,1024", 1024)); + _settings.emplace_back(RANGE_SETTING("settings/runtime_max_call_stack", "256,1024,256", 1024)); _settings.emplace_back(SENUM_SETTING("settings/log_level", "FATAL,ERROR,WARN,INFO,DEBUG,TRACE", "INFO")); _settings.emplace_back(BOOL_SETTING("settings/save_copy_as_text_resource", false)); @@ -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)));