Skip to content

Commit

Permalink
GH-59 Support border/corner radius & gradient title bars
Browse files Browse the repository at this point in the history
  • Loading branch information
Naros committed Jan 18, 2024
1 parent c864647 commit a8fc8ee
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 15 deletions.
132 changes: 119 additions & 13 deletions src/editor/graph/graph_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#include <godot_cpp/classes/button.hpp>
#include <godot_cpp/classes/editor_inspector.hpp>
#include <godot_cpp/classes/gradient.hpp>
#include <godot_cpp/classes/gradient_texture2d.hpp>
#include <godot_cpp/classes/input.hpp>
#include <godot_cpp/classes/input_event_action.hpp>
#include <godot_cpp/classes/input_event_mouse_button.hpp>
Expand All @@ -36,6 +38,7 @@
#include <godot_cpp/classes/script_editor.hpp>
#include <godot_cpp/classes/script_editor_base.hpp>
#include <godot_cpp/classes/style_box_flat.hpp>
#include <godot_cpp/classes/style_box_texture.hpp>

OrchestratorGraphNode::OrchestratorGraphNode(OrchestratorGraphEdit* p_graph, const Ref<OScriptNode>& p_node)
{
Expand Down Expand Up @@ -341,37 +344,68 @@ void OrchestratorGraphNode::_update_styles()
apply_style_defaults = false;
Color color = os->get_setting(key);

Ref<StyleBoxFlat> panel = _make_colored_style("panel_selected", color);
Ref<StyleBox> panel = _make_colored_style("panel_selected", color);
if (panel.is_valid())
add_theme_stylebox_override("panel", panel);

Ref<StyleBoxFlat> panel_selected = _make_selected_style("panel");
Ref<StyleBox> panel_selected = _make_selected_style("panel");
if (panel_selected.is_valid())
add_theme_stylebox_override("panel_selected", panel_selected);

Ref<StyleBoxFlat> titlebar = _make_colored_style("titlebar_selected", color, true);
if (titlebar.is_valid())
add_theme_stylebox_override("titlebar", titlebar);
if (_use_gradient_color_style())
{
Ref<StyleBox> sb = _make_colored_style("titlebar_selected", color, true);
if (sb.is_valid())
add_theme_stylebox_override("titlebar", sb);

Ref<StyleBox> sb_selected = _make_selected_style("titlebar", true);
if (sb_selected.is_valid())
add_theme_stylebox_override("titlebar_selected", sb_selected);

Ref<StyleBox> sb2 = _make_gradient_titlebar_style("titlebar_selected", color, false);
if (sb2.is_valid())
add_theme_stylebox_override("titlebar", sb2);
}
else
{
Ref<StyleBox> sb = _make_colored_style("titlebar_selected", color, true);
if (sb.is_valid())
add_theme_stylebox_override("titlebar", sb);

Ref<StyleBoxFlat> titlebar_selected = _make_selected_style("titlebar", true);
if (titlebar_selected.is_valid())
add_theme_stylebox_override("titlebar_selected", titlebar_selected);
Ref<StyleBox> 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<StyleBoxFlat> panel_selected = _make_selected_style("panel_selected");
Ref<StyleBox> panel_selected = _make_selected_style("panel_selected");
if (panel_selected.is_valid())
add_theme_stylebox_override("panel_selected", panel_selected);

Ref<StyleBoxFlat> titlebar_selected = _make_selected_style("titlebar_selected", true);
Ref<StyleBox> titlebar_selected = _make_selected_style("titlebar_selected", true);
if (titlebar_selected.is_valid())
add_theme_stylebox_override("titlebar_selected", titlebar_selected);
}
}

Ref<StyleBoxFlat> 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<StyleBox> OrchestratorGraphNode::_make_colored_style(const String& p_existing_name, const Color& p_color, bool p_titlebar)
{
Ref<StyleBoxFlat> sb = get_theme_stylebox(p_existing_name);
if (sb.is_valid())
Expand All @@ -381,26 +415,98 @@ Ref<StyleBoxFlat> 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<StyleBoxFlat> OrchestratorGraphNode::_make_selected_style(const String& p_existing_name, bool p_titlebar)
Ref<StyleBox> OrchestratorGraphNode::_make_selected_style(const String& p_existing_name, bool p_titlebar)
{
Ref<StyleBoxFlat> sb = get_theme_stylebox(p_existing_name);
if (sb.is_valid())
{
Ref<StyleBoxFlat> 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<StyleBox> OrchestratorGraphNode::_make_gradient_titlebar_style(const String& p_existing_name, const Color& p_color,
bool p_selected)
{
Ref<Gradient> 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<GradientTexture2D> texture(memnew(GradientTexture2D));
texture->set_gradient(gradient);
texture->set_width(64);
texture->set_height(64);
texture->set_fill_to(Vector2(1.1, 0));

Ref<StyleBoxTexture> titlebar_tex(memnew(StyleBoxTexture));
titlebar_tex->set_texture(texture);
titlebar_tex->set_modulate(p_color);

Ref<StyleBox> 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<StyleBoxFlat>& 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
Expand Down
24 changes: 22 additions & 2 deletions src/editor/graph/graph_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<StyleBoxFlat> _make_colored_style(const String& p_existing_name, const Color& p_color, bool p_titlebar = false);
Ref<StyleBox> _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<StyleBoxFlat> _make_selected_style(const String& p_existing_name, bool p_titlebar = false);
Ref<StyleBox> _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<StyleBox> _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<StyleBoxFlat>& p_stylebox, bool p_titlebar = false);

/// Called by various callbacks to update node attributes
void _update_node_attributes();
Expand Down
2 changes: 2 additions & 0 deletions src/plugin/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down

0 comments on commit a8fc8ee

Please sign in to comment.