From 5afe78bd9c7e619ebc2dd2fb43d549d16382b51d Mon Sep 17 00:00:00 2001 From: Hendrik Brucker Date: Wed, 9 Aug 2023 18:31:15 +0200 Subject: Clean up/refactor GraphNode and make it more flexible Split GraphNode into GraphElement and GraphNode, add custom titlebar, and adjust theming. --- editor/plugins/visual_shader_editor_plugin.cpp | 421 +++++++++++++------------ 1 file changed, 219 insertions(+), 202 deletions(-) (limited to 'editor/plugins/visual_shader_editor_plugin.cpp') diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index b6330bdf75..8e1862d88b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -144,22 +144,26 @@ void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p bool is_dirty = link.preview_pos < 0; if (!is_dirty && link.preview_visible && link.preview_box != nullptr) { - link.graph_node->remove_child(link.preview_box); + link.graph_element->remove_child(link.preview_box); memdelete(link.preview_box); link.preview_box = nullptr; - link.graph_node->reset_size(); + link.graph_element->reset_size(); link.preview_visible = false; } if (p_port_id != -1 && link.output_ports[p_port_id].preview_button != nullptr) { if (is_dirty) { - link.preview_pos = link.graph_node->get_child_count(); + link.preview_pos = link.graph_element->get_child_count(); } VBoxContainer *vbox = memnew(VBoxContainer); - link.graph_node->add_child(vbox); - link.graph_node->move_child(vbox, link.preview_pos); - link.graph_node->set_slot_draw_stylebox(vbox->get_index(), false); + link.graph_element->add_child(vbox); + link.graph_element->move_child(vbox, link.preview_pos); + + GraphNode *graph_node = Object::cast_to(link.graph_element); + if (graph_node) { + graph_node->set_slot_draw_stylebox(vbox->get_index(false), false); + } Control *offset = memnew(Control); offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); @@ -293,7 +297,7 @@ void VisualShaderGraphPlugin::update_node_size(int p_node_id) { if (!links.has(p_node_id)) { return; } - links[p_node_id].graph_node->reset_size(); + links[p_node_id].graph_element->reset_size(); } void VisualShaderGraphPlugin::register_default_input_button(int p_node_id, int p_port_id, Button *p_button) { @@ -324,7 +328,7 @@ VisualShader::Type VisualShaderGraphPlugin::get_shader_type() const { void VisualShaderGraphPlugin::set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position) { if (visual_shader->get_shader_type() == p_type && links.has(p_id)) { - links[p_id].graph_node->set_position_offset(p_position); + links[p_id].graph_element->set_position_offset(p_position); } } @@ -336,8 +340,8 @@ void VisualShaderGraphPlugin::clear_links() { links.clear(); } -void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) { - links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, HashMap(), HashMap(), nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } }); +void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphElement *p_graph_element) { + links.insert(p_id, { p_type, p_visual_node, p_graph_element, p_visual_node->get_output_port_for_preview() != -1, -1, HashMap(), HashMap(), nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } }); } void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) { @@ -415,42 +419,49 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool // Visual shader specific theme for MSDF font. Ref vstheme; vstheme.instantiate(); - Ref label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorFonts)); + Ref label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorIcons)); + Ref label_bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_bold_msdf", EditorStringName(EditorIcons)); vstheme->set_font("font", "Label", label_font); + vstheme->set_font("font", "GraphNodeTitleLabel", label_bold_font); vstheme->set_font("font", "LineEdit", label_font); vstheme->set_font("font", "Button", label_font); Ref vsnode = visual_shader->get_node(p_type, p_id); - Ref resizable_node = Object::cast_to(vsnode.ptr()); - bool is_resizable = !resizable_node.is_null(); + Ref resizable_node = vsnode; + bool is_resizable = resizable_node.is_valid(); Size2 size = Size2(0, 0); - Ref group_node = Object::cast_to(vsnode.ptr()); - bool is_group = !group_node.is_null(); + Ref group_node = vsnode; + bool is_group = group_node.is_valid(); - Ref comment_node = Object::cast_to(vsnode.ptr()); + Ref comment_node = vsnode; bool is_comment = comment_node.is_valid(); - Ref expression_node = Object::cast_to(group_node.ptr()); - bool is_expression = !expression_node.is_null(); + Ref expression_node = group_node; + bool is_expression = expression_node.is_valid(); String expression = ""; - VisualShaderNodeCustom *custom_node = Object::cast_to(vsnode.ptr()); - if (custom_node) { + Ref custom_node = vsnode; + if (custom_node.is_valid()) { custom_node->_set_initialized(true); } - // Create graph node. GraphNode *node = memnew(GraphNode); + node->set_title(vsnode->get_caption()); + + // All nodes are closable except the output node. + if (p_id >= 2) { + vsnode->set_closable(true); + node->connect("close_request", callable_mp(editor, &VisualShaderEditor::_close_node_request).bind(p_type, p_id), CONNECT_DEFERRED); + } graph->add_child(node); node->set_theme(vstheme); - editor->_update_created_node(node); if (p_just_update) { Link &link = links[p_id]; - link.graph_node = node; + link.graph_element = node; link.preview_box = nullptr; link.preview_pos = -1; link.output_ports.clear(); @@ -474,19 +485,18 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool } node->set_position_offset(visual_shader->get_node_position(p_type, p_id)); - node->set_title(vsnode->get_caption()); - node->set_name(itos(p_id)); - if (p_id >= 2) { - node->set_show_close_button(true); - node->connect("close_request", callable_mp(editor, &VisualShaderEditor::_delete_node_request).bind(p_type, p_id), CONNECT_DEFERRED); - } + node->set_name(itos(p_id)); node->connect("dragged", callable_mp(editor, &VisualShaderEditor::_node_dragged).bind(p_id)); Control *custom_editor = nullptr; int port_offset = 1; + if (is_resizable) { + editor->call_deferred(SNAME("_set_node_size"), (int)p_type, p_id, size); + } + Control *content_offset = memnew(Control); content_offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); node->add_child(content_offset); @@ -495,10 +505,6 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool port_offset += 1; } - if (is_resizable) { - editor->call_deferred(SNAME("_set_node_size"), (int)p_type, p_id, size); - } - Ref emit = vsnode; if (emit.is_valid()) { node->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); @@ -608,7 +614,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool if (custom_editor) { if (is_curve || (hb == nullptr && !vsnode->is_use_prop_slots() && (vsnode->get_output_port_count() == 0 || vsnode->get_output_port_name(0) == "") && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == ""))) { - //will be embedded in first port + // Will be embedded in first port. } else { port_offset++; node->add_child(custom_editor); @@ -896,93 +902,97 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool if (!is_first_hbox) { idx = i + port_offset; } - node->set_slot(idx, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); + if (!is_comment) { + GraphNode *graph_node = Object::cast_to(node); - if (vsnode->_is_output_port_expanded(i)) { - switch (vsnode->get_output_port_type(i)) { - case VisualShaderNode::PORT_TYPE_VECTOR_2D: { - port_offset++; - valid_left = (i + 1) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 1); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]); - port_offset++; + graph_node->set_slot(idx, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); - valid_left = (i + 2) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 2); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]); - - expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_2D; - } break; - case VisualShaderNode::PORT_TYPE_VECTOR_3D: { - port_offset++; - valid_left = (i + 1) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 1); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]); - port_offset++; + if (vsnode->_is_output_port_expanded(i)) { + switch (vsnode->get_output_port_type(i)) { + case VisualShaderNode::PORT_TYPE_VECTOR_2D: { + port_offset++; + valid_left = (i + 1) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 1); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]); + port_offset++; - valid_left = (i + 2) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 2); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]); - port_offset++; + valid_left = (i + 2) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 2); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]); + + expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_2D; + } break; + case VisualShaderNode::PORT_TYPE_VECTOR_3D: { + port_offset++; + valid_left = (i + 1) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 1); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]); + port_offset++; - valid_left = (i + 3) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 3); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]); + valid_left = (i + 2) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 2); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]); + port_offset++; - expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_3D; - } break; - case VisualShaderNode::PORT_TYPE_VECTOR_4D: { - port_offset++; - valid_left = (i + 1) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 1); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]); - port_offset++; + valid_left = (i + 3) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 3); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]); + + expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_3D; + } break; + case VisualShaderNode::PORT_TYPE_VECTOR_4D: { + port_offset++; + valid_left = (i + 1) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 1); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]); + port_offset++; - valid_left = (i + 2) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 2); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]); - port_offset++; + valid_left = (i + 2) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 2); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]); + port_offset++; - valid_left = (i + 3) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 3); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]); - port_offset++; + valid_left = (i + 3) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 3); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]); + port_offset++; - valid_left = (i + 4) < vsnode->get_input_port_count(); - port_left = VisualShaderNode::PORT_TYPE_SCALAR; - if (valid_left) { - port_left = vsnode->get_input_port_type(i + 4); - } - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[3]); + valid_left = (i + 4) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 4); + } + graph_node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[3]); - expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_4D; - } break; - default: - break; + expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_4D; + } break; + default: + break; + } } } } @@ -1005,6 +1015,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool Label *error_label = memnew(Label); error_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("error_color"), EditorStringName(Editor))); error_label->set_text(error); + error_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD); node->add_child(error_label); } @@ -1061,16 +1072,13 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool expression_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_expression_focus_out).bind(expression_box, p_id)); } - - if (is_comment) { - graph->move_child(node, 0); // to prevents a bug where comment node overlaps its content - } } void VisualShaderGraphPlugin::remove_node(VisualShader::Type p_type, int p_id, bool p_just_update) { if (visual_shader->get_shader_type() == p_type && links.has(p_id)) { - links[p_id].graph_node->get_parent()->remove_child(links[p_id].graph_node); - memdelete(links[p_id].graph_node); + Node *graph_edit_node = links[p_id].graph_element->get_parent(); + graph_edit_node->remove_child(links[p_id].graph_element); + memdelete(links[p_id].graph_element); if (!p_just_update) { links.erase(p_id); } @@ -1374,7 +1382,7 @@ void VisualShaderEditor::_update_custom_script(const Ref