diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 2f316139031..82495960451 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -4125,6 +4125,7 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in int from = p_from.to_int(); int to = p_to.to_int(); + bool swap = last_to_node != -1 && Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL); if (!visual_shader->can_connect_nodes(type, from, p_from_index, to, p_to_index)) { return; @@ -4142,6 +4143,14 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + + if (swap) { + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, last_to_node, last_to_port); + } + break; } } @@ -4155,6 +4164,9 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, to); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", (int)type, to); undo_redo->commit_action(); + + last_to_node = -1; + last_to_port = -1; } void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) { @@ -4165,6 +4177,11 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from int from = p_from.to_int(); int to = p_to.to_int(); + last_to_node = to; + last_to_port = p_to_index; + + info_label->show(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); undo_redo->create_action(TTR("Nodes Disconnected")); undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index); @@ -4176,6 +4193,10 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from undo_redo->commit_action(); } +void VisualShaderEditor::_connection_drag_ended() { + info_label->hide(); +} + void VisualShaderEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) { from_node = p_from.to_int(); from_slot = p_from_slot; @@ -6370,6 +6391,7 @@ VisualShaderEditor::VisualShaderEditor() { graph->connect(SceneStringName(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)); + graph->connect("connection_drag_ended", callable_mp(this, &VisualShaderEditor::_connection_drag_ended)); graph->connect(SceneStringName(visibility_changed), callable_mp(this, &VisualShaderEditor::_visibility_changed)); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT); @@ -6430,6 +6452,13 @@ VisualShaderEditor::VisualShaderEditor() { graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SAMPLER, VisualShaderNode::PORT_TYPE_SAMPLER); + info_label = memnew(Label); + info_label->set_text(vformat(TTR("Hold %s Key To Swap Connections"), keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL))); + info_label->set_anchors_and_offsets_preset(Control::PRESET_BOTTOM_WIDE, PRESET_MODE_MINSIZE, 20); + info_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + info_label->hide(); + graph->get_top_layer()->add_child(info_label); + PanelContainer *toolbar_panel = static_cast(graph->get_menu_hbox()->get_parent()); toolbar_panel->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE, PRESET_MODE_MINSIZE, 10); toolbar_panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index a8655b81418..6b7c07e5a74 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -221,6 +221,10 @@ class VisualShaderEditor : public ShaderEditor { Button *code_preview_button = nullptr; Button *shader_preview_button = nullptr; + int last_to_node = -1; + int last_to_port = -1; + Label *info_label = nullptr; + OptionButton *edit_type = nullptr; OptionButton *edit_type_standard = nullptr; OptionButton *edit_type_particles = nullptr; @@ -502,6 +506,7 @@ class VisualShaderEditor : public ShaderEditor { void _unlink_node_from_parent_frame(int p_node_id); + void _connection_drag_ended(); void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position); void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position); bool _check_node_drop_on_connection(const Vector2 &p_position, Ref *r_closest_connection, int *r_node_id = nullptr, int *r_to_port = nullptr);