From 62776842df7b23324b7d03b278f66f98ac9f1d1e Mon Sep 17 00:00:00 2001 From: Hendrik Brucker Date: Tue, 7 May 2024 16:48:03 +0200 Subject: [PATCH] [VisualShader] Add reroute node and improve port drawing --- doc/classes/GraphNode.xml | 3 + doc/classes/VisualShaderNodeReroute.xml | 19 ++ .../plugins/visual_shader_editor_plugin.cpp | 273 +++++++++++++----- editor/plugins/visual_shader_editor_plugin.h | 30 ++ editor/themes/editor_theme_manager.cpp | 17 +- scene/gui/graph_edit.cpp | 12 +- scene/gui/graph_node.cpp | 13 + scene/gui/graph_node.h | 5 + scene/register_scene_types.cpp | 1 + scene/resources/visual_shader.cpp | 96 +++++- scene/resources/visual_shader.h | 4 + scene/resources/visual_shader_nodes.cpp | 79 +++++ scene/resources/visual_shader_nodes.h | 31 ++ 13 files changed, 505 insertions(+), 78 deletions(-) create mode 100644 doc/classes/VisualShaderNodeReroute.xml diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index ad1028d7f43..cc3acad6d66 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -267,6 +267,9 @@ + + If [code]true[/code], you can connect ports with different types, even if the connection was not explicitly allowed in the parent [GraphEdit]. + The text displayed in the GraphNode's title bar. diff --git a/doc/classes/VisualShaderNodeReroute.xml b/doc/classes/VisualShaderNodeReroute.xml new file mode 100644 index 00000000000..1baaa7bbb66 --- /dev/null +++ b/doc/classes/VisualShaderNodeReroute.xml @@ -0,0 +1,19 @@ + + + + A node that allows rerouting a connection within the visual shader graph. + + + Automatically adapts its port type to the type of the incoming connection and ensures valid connections. + + + + + + + + Returns the port type of the reroute node. + + + + diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 35db52a42e4..5cb5f5660ed 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -45,6 +45,7 @@ #include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/shader_editor_plugin.h" #include "editor/themes/editor_scale.h" +#include "scene/animation/tween.h" #include "scene/gui/button.h" #include "scene/gui/check_box.h" #include "scene/gui/code_edit.h" @@ -104,6 +105,83 @@ void VisualShaderNodePlugin::_bind_methods() { /////////////////// +void VSGraphNode::_draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color, const Color &p_rim_color) { + Ref port_icon = p_left ? get_slot_custom_icon_left(p_slot_index) : get_slot_custom_icon_right(p_slot_index); + + Point2 icon_offset; + if (!port_icon.is_valid()) { + port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode")); + } + + icon_offset = -port_icon->get_size() * 0.5; + + // Draw "shadow"/outline in the connection rim color. + draw_texture_rect(port_icon, Rect2(p_pos + icon_offset - Size2(2, 2), port_icon->get_size() + Size2(4, 4)), false, p_rim_color); + draw_texture(port_icon, p_pos + icon_offset, p_color); +} + +void VSGraphNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) { + Color rim_color = get_theme_color(SNAME("connection_rim_color"), SNAME("GraphEdit")); + _draw_port(p_slot_index, p_pos, p_left, p_color, rim_color); +} + +/////////////////// + +void VSRerouteNode::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + connect("mouse_entered", callable_mp(this, &VSRerouteNode::_on_mouse_entered)); + connect("mouse_exited", callable_mp(this, &VSRerouteNode::_on_mouse_exited)); + } break; + case NOTIFICATION_DRAW: { + Vector2 offset = Vector2(0, -16); + Color drag_bg_color = get_theme_color(SNAME("drag_background"), SNAME("VSRerouteNode")); + draw_circle(get_size() * 0.5 + offset, 16, Color(drag_bg_color, selected ? 1 : icon_opacity)); + + Ref icon = get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")); + Point2 icon_offset = -icon->get_size() * 0.5 + get_size() * 0.5 + offset; + draw_texture(icon, icon_offset, Color(1, 1, 1, selected ? 1 : icon_opacity)); + } break; + } +} + +void VSRerouteNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) { + Color rim_color = selected ? get_theme_color("selected_rim_color", "VSRerouteNode") : get_theme_color("connection_rim_color", "GraphEdit"); + _draw_port(p_slot_index, p_pos, p_left, p_color, rim_color); +} + +VSRerouteNode::VSRerouteNode() { + Label *title_lbl = Object::cast_to