diff options
author | Hendrik Brucker <hendrik.brucker@mail.de> | 2023-08-09 18:31:15 +0200 |
---|---|---|
committer | Hendrik Brucker <hendrik.brucker@mail.de> | 2023-09-07 17:29:06 +0200 |
commit | 5afe78bd9c7e619ebc2dd2fb43d549d16382b51d (patch) | |
tree | cdf9e6e0979a1726fc4fb801fdd1f9591cf48b4f /editor/plugins/visual_shader_editor_plugin.cpp | |
parent | 08c578c54c352edf85f750992b2156bae5685fb8 (diff) | |
download | redot-engine-5afe78bd9c7e619ebc2dd2fb43d549d16382b51d.tar.gz |
Clean up/refactor GraphNode and make it more flexible
Split GraphNode into GraphElement and GraphNode, add custom
titlebar, and adjust theming.
Diffstat (limited to 'editor/plugins/visual_shader_editor_plugin.cpp')
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 421 |
1 files changed, 219 insertions, 202 deletions
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<GraphNode>(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<int, InputPort>(), HashMap<int, Port>(), 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<int, InputPort>(), HashMap<int, Port>(), 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<Theme> vstheme; vstheme.instantiate(); - Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorFonts)); + Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorIcons)); + Ref<Font> 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<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id); - Ref<VisualShaderNodeResizableBase> resizable_node = Object::cast_to<VisualShaderNodeResizableBase>(vsnode.ptr()); - bool is_resizable = !resizable_node.is_null(); + Ref<VisualShaderNodeResizableBase> resizable_node = vsnode; + bool is_resizable = resizable_node.is_valid(); Size2 size = Size2(0, 0); - Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(vsnode.ptr()); - bool is_group = !group_node.is_null(); + Ref<VisualShaderNodeGroupBase> group_node = vsnode; + bool is_group = group_node.is_valid(); - Ref<VisualShaderNodeComment> comment_node = Object::cast_to<VisualShaderNodeComment>(vsnode.ptr()); + Ref<VisualShaderNodeComment> comment_node = vsnode; bool is_comment = comment_node.is_valid(); - Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(group_node.ptr()); - bool is_expression = !expression_node.is_null(); + Ref<VisualShaderNodeExpression> expression_node = group_node; + bool is_expression = expression_node.is_valid(); String expression = ""; - VisualShaderNodeCustom *custom_node = Object::cast_to<VisualShaderNodeCustom>(vsnode.ptr()); - if (custom_node) { + Ref<VisualShaderNodeCustom> 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<VisualShaderNodeParticleEmit> 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<GraphNode>(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<Script> &p_script) { if (vsnode.is_null()) { continue; } - Ref<VisualShaderNodeCustom> custom_node = Ref<VisualShaderNodeCustom>(vsnode.ptr()); + Ref<VisualShaderNodeCustom> custom_node = vsnode; if (custom_node.is_null() || custom_node->get_script() != p_script) { continue; } @@ -1486,7 +1494,7 @@ void VisualShaderEditor::_resources_removed() { if (vsnode.is_null()) { continue; } - Ref<VisualShaderNodeCustom> custom_node = Ref<VisualShaderNodeCustom>(vsnode.ptr()); + Ref<VisualShaderNodeCustom> custom_node = vsnode; if (custom_node.is_null() || custom_node->get_script() != scr) { continue; } @@ -1916,8 +1924,8 @@ Size2 VisualShaderEditor::get_minimum_size() const { return Size2(10, 200); } -void VisualShaderEditor::_draw_color_over_button(Object *obj, Color p_color) { - Button *button = Object::cast_to<Button>(obj); +void VisualShaderEditor::_draw_color_over_button(Object *p_obj, Color p_color) { + Button *button = Object::cast_to<Button>(p_obj); if (!button) { return; } @@ -1926,18 +1934,6 @@ void VisualShaderEditor::_draw_color_over_button(Object *obj, Color p_color) { button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color); } -void VisualShaderEditor::_update_created_node(GraphNode *node) { - const Ref<StyleBoxFlat> sb = node->get_theme_stylebox(SNAME("frame"), SNAME("GraphNode")); - Color c = sb->get_border_color(); - const Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0, 0.85) : Color(0.0, 0.0, 0.0, 0.85); - c = mono_color; - - node->add_theme_color_override("title_color", c); - c.a = 0.7; - node->add_theme_color_override("close_color", c); - node->add_theme_color_override("resizer_color", c); -} - void VisualShaderEditor::_update_parameters(bool p_update_refs) { VisualShaderNodeParameterRef::clear_parameters(visual_shader->get_rid()); @@ -2025,9 +2021,9 @@ void VisualShaderEditor::_update_graph() { VisualShader::Type type = get_current_shader_type(); graph->clear_connections(); - //erase all nodes + // Remove all nodes. for (int i = 0; i < graph->get_child_count(); i++) { - if (Object::cast_to<GraphNode>(graph->get_child(i))) { + if (Object::cast_to<GraphElement>(graph->get_child(i))) { Node *node = graph->get_child(i); graph->remove_child(node); memdelete(node); @@ -2406,14 +2402,14 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) { undo_redo->commit_action(); } -void VisualShaderEditor::_expression_focus_out(Object *code_edit, int p_node) { +void VisualShaderEditor::_expression_focus_out(Object *p_code_edit, int p_node) { VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; } - CodeEdit *expression_box = Object::cast_to<CodeEdit>(code_edit); + CodeEdit *expression_box = Object::cast_to<CodeEdit>(p_code_edit); if (node->get_expression() == expression_box->get_text()) { return; @@ -2452,20 +2448,20 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p } } - GraphNode *gn = nullptr; + GraphElement *graph_element = nullptr; Node *node2 = graph->get_node(itos(p_node)); - gn = Object::cast_to<GraphNode>(node2); - if (!gn) { + graph_element = Object::cast_to<GraphElement>(node2); + if (!graph_element) { return; } - gn->set_custom_minimum_size(size); - gn->reset_size(); + graph_element->set_custom_minimum_size(size); + graph_element->reset_size(); if (!expression_node.is_null() && text_box) { Size2 box_size = size; if (box_size.x < 150 * EDSCALE || box_size.y < 0) { - box_size.x = gn->get_size().x; + box_size.x = graph_element->get_size().x; } box_size.x -= text_box->get_offset(SIDE_LEFT); box_size.x -= 28 * EDSCALE; @@ -2483,9 +2479,14 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in return; } + Vector2 new_size = p_new_size; + if (graph->is_snapping_enabled() ^ Input::get_singleton()->is_key_pressed(Key::CTRL)) { + new_size = new_size.snapped(Vector2(graph->get_snapping_distance(), graph->get_snapping_distance())); + } + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); undo_redo->create_action(TTR("Resize VisualShader Node"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size); + undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, new_size); undo_redo->add_undo_method(this, "_set_node_size", p_type, p_node, node->get_size()); undo_redo->commit_action(); } @@ -2547,7 +2548,7 @@ void VisualShaderEditor::_comment_title_popup_hide() { return; // nothing changed - ignored } EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Set Comment Node Title")); + undo_redo->create_action(TTR("Set Comment Title")); undo_redo->add_do_method(node.ptr(), "set_title", comment_title_change_edit->get_text()); undo_redo->add_undo_method(node.ptr(), "set_title", node->get_title()); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, node_id); @@ -2590,7 +2591,7 @@ void VisualShaderEditor::_comment_desc_popup_hide() { return; // nothing changed - ignored } EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Set Comment Node Description")); + undo_redo->create_action(TTR("Set Comment Description")); undo_redo->add_do_method(node.ptr(), "set_description", comment_desc_change_edit->get_text()); undo_redo->add_undo_method(node.ptr(), "set_description", node->get_title()); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, node_id); @@ -3544,12 +3545,12 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { } } - // delete nodes from the graph + // Delete nodes from the graph. for (const int &F : p_nodes) { undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F, false); } - // update parameter refs if any parameter has been deleted + // Update parameter refs if any parameter has been deleted. if (parameter_names.size() > 0) { undo_redo->add_do_method(this, "_update_parameters", true); undo_redo->add_undo_method(this, "_update_parameters", true); @@ -3789,7 +3790,12 @@ void VisualShaderEditor::_convert_constants_to_parameters(bool p_vice_versa) { undo_redo->commit_action(); } -void VisualShaderEditor::_delete_node_request(int p_type, int p_node) { +void VisualShaderEditor::_close_node_request(int p_type, int p_node) { + Ref<VisualShaderNode> node = visual_shader->get_node((VisualShader::Type)p_type, p_node); + if (!node->is_closable()) { + return; + } + List<int> to_erase; to_erase.push_back(p_node); @@ -3799,22 +3805,30 @@ void VisualShaderEditor::_delete_node_request(int p_type, int p_node) { undo_redo->commit_action(); } -void VisualShaderEditor::_delete_nodes_request(const TypedArray<StringName> &p_nodes) { +void VisualShaderEditor::_close_nodes_request(const TypedArray<StringName> &p_nodes) { List<int> to_erase; if (p_nodes.is_empty()) { // Called from context menu. for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected() && gn->is_close_button_visible()) { - to_erase.push_back(gn->get_name().operator String().to_int()); + GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i)); + if (graph_element && graph_element->is_selected()) { + VisualShader::Type type = get_current_shader_type(); + int id = String(graph_element->get_name()).to_int(); + Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id); + if (vsnode->is_closable()) { + to_erase.push_back(graph_element->get_name().operator String().to_int()); } } } } else { + VisualShader::Type type = get_current_shader_type(); for (int i = 0; i < p_nodes.size(); i++) { - to_erase.push_back(p_nodes[i].operator String().to_int()); + int id = p_nodes[i].operator String().to_int(); + Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id); + if (vsnode->is_closable()) { + to_erase.push_back(id); + } } } @@ -3831,59 +3845,62 @@ void VisualShaderEditor::_delete_nodes_request(const TypedArray<StringName> &p_n void VisualShaderEditor::_node_selected(Object *p_node) { VisualShader::Type type = get_current_shader_type(); - GraphNode *gn = Object::cast_to<GraphNode>(p_node); - ERR_FAIL_COND(!gn); + GraphElement *graph_element = Object::cast_to<GraphElement>(p_node); + ERR_FAIL_COND(!graph_element); - int id = String(gn->get_name()).to_int(); + int id = String(graph_element->get_name()).to_int(); Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id); ERR_FAIL_COND(!vsnode.is_valid()); - - //do not rely on this, makes editor more complex - //EditorNode::get_singleton()->push_item(vsnode.ptr(), "", true); } void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; VisualShader::Type type = get_current_shader_type(); + Ref<VisualShaderNode> selected_vsnode; + // Right click actions. if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { selected_constants.clear(); selected_parameters.clear(); selected_comment = -1; selected_float_constant = -1; - List<int> to_change; + List<int> selected_closable_graph_elements; for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected() && gn->is_close_button_visible()) { - int id = gn->get_name().operator String().to_int(); - to_change.push_back(id); + GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i)); + if (graph_element && graph_element->is_selected()) { + int id = String(graph_element->get_name()).to_int(); + Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id); + if (!vsnode->is_closable()) { + continue; + } - Ref<VisualShaderNode> node = visual_shader->get_node(type, id); + selected_closable_graph_elements.push_back(id); - VisualShaderNodeComment *comment_node = Object::cast_to<VisualShaderNodeComment>(node.ptr()); - if (comment_node != nullptr) { - selected_comment = id; - } - VisualShaderNodeConstant *constant_node = Object::cast_to<VisualShaderNodeConstant>(node.ptr()); - if (constant_node != nullptr) { - selected_constants.insert(id); - } - VisualShaderNodeFloatConstant *float_constant_node = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr()); - if (float_constant_node != nullptr) { - selected_float_constant = id; - } - VisualShaderNodeParameter *parameter_node = Object::cast_to<VisualShaderNodeParameter>(node.ptr()); - if (parameter_node != nullptr && parameter_node->is_convertible_to_constant()) { - selected_parameters.insert(id); - } + Ref<VisualShaderNode> node = visual_shader->get_node(type, id); + selected_vsnode = node; + + VisualShaderNodeComment *frame_node = Object::cast_to<VisualShaderNodeComment>(node.ptr()); + if (frame_node != nullptr) { + selected_comment = id; + } + VisualShaderNodeConstant *constant_node = Object::cast_to<VisualShaderNodeConstant>(node.ptr()); + if (constant_node != nullptr) { + selected_constants.insert(id); + } + VisualShaderNodeFloatConstant *float_constant_node = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr()); + if (float_constant_node != nullptr) { + selected_float_constant = id; + } + VisualShaderNodeParameter *parameter_node = Object::cast_to<VisualShaderNodeParameter>(node.ptr()); + if (parameter_node != nullptr && parameter_node->is_convertible_to_constant()) { + selected_parameters.insert(id); } } } - if (to_change.size() > 1) { + if (selected_closable_graph_elements.size() > 1) { selected_comment = -1; selected_float_constant = -1; } @@ -3896,14 +3913,14 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { } } - if (to_change.is_empty() && copy_buffer_empty) { + if (selected_closable_graph_elements.is_empty() && copy_buffer_empty) { _show_members_dialog(true); } else { - popup_menu->set_item_disabled(NodeMenuOptions::CUT, to_change.is_empty()); - popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::CUT, selected_closable_graph_elements.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::COPY, selected_closable_graph_elements.is_empty()); popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_buffer_empty); - popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.is_empty()); - popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::DELETE, selected_closable_graph_elements.is_empty()); + popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, selected_closable_graph_elements.is_empty()); popup_menu->set_item_disabled(NodeMenuOptions::CLEAR_COPY_BUFFER, copy_buffer_empty); int temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR2); @@ -4184,9 +4201,9 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<CopyItem> &r_items, Li HashSet<int> nodes; for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - int id = String(gn->get_name()).to_int(); + GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i)); + if (graph_element) { + int id = String(graph_element->get_name()).to_int(); Ref<VisualShaderNode> node = visual_shader->get_node(type, id); Ref<VisualShaderNodeOutput> output = node; @@ -4194,7 +4211,7 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<CopyItem> &r_items, Li continue; } - if (node.is_valid() && gn->is_selected()) { + if (node.is_valid() && graph_element->is_selected()) { Vector2 pos = visual_shader->get_node_position(type, id); selection_center += pos; @@ -4320,13 +4337,13 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c // reselect nodes by excluding the other ones for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - int id = String(gn->get_name()).to_int(); + GraphElement *graph_element = Object::cast_to<GraphElement>(graph->get_child(i)); + if (graph_element) { + int id = String(graph_element->get_name()).to_int(); if (added_set.has(id)) { - gn->set_selected(true); + graph_element->set_selected(true); } else { - gn->set_selected(false); + graph_element->set_selected(false); } } } @@ -4819,7 +4836,7 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) { _paste_nodes(true, menu_point); break; case NodeMenuOptions::DELETE: - _delete_nodes_request(TypedArray<StringName>()); + _close_nodes_request(TypedArray<StringName>()); break; case NodeMenuOptions::DUPLICATE: _duplicate_nodes(); @@ -5119,7 +5136,7 @@ VisualShaderEditor::VisualShaderEditor() { graph->connect("duplicate_nodes_request", callable_mp(this, &VisualShaderEditor::_duplicate_nodes)); graph->connect("copy_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes).bind(false)); graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes).bind(false, Point2())); - graph->connect("delete_nodes_request", callable_mp(this, &VisualShaderEditor::_delete_nodes_request)); + graph->connect("close_nodes_request", callable_mp(this, &VisualShaderEditor::_close_nodes_request)); graph->connect("gui_input", callable_mp(this, &VisualShaderEditor::_graph_gui_input)); graph->connect("connection_to_empty", callable_mp(this, &VisualShaderEditor::_connection_to_empty)); graph->connect("connection_from_empty", callable_mp(this, &VisualShaderEditor::_connection_from_empty)); |