From a65252018c5e19caba094bf4a785845abad59733 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Tue, 6 Oct 2020 08:29:41 +0300 Subject: [PATCH] [3.2] Fix undo for moving multiple visual shader nodes --- .../plugins/visual_shader_editor_plugin.cpp | 22 +++++++++++++++---- editor/plugins/visual_shader_editor_plugin.h | 9 ++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 3379422c7ea3..fb8241ee6d25 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1497,15 +1497,28 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { } void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + drag_buffer.push_back({ type, p_node, p_from, p_to }); + if (!drag_dirty) { + call_deferred("_nodes_dragged"); + } + drag_dirty = true; +} + +void VisualShaderEditor::_nodes_dragged() { + drag_dirty = false; + undo_redo->create_action(TTR("Node(s) Moved")); + + for (List::Element *E = drag_buffer.front(); E; E = E->next()) { + undo_redo->add_do_method(visual_shader.ptr(), "set_node_position", E->get().type, E->get().node, E->get().to); + undo_redo->add_undo_method(visual_shader.ptr(), "set_node_position", E->get().type, E->get().node, E->get().from); + } updating = true; - undo_redo->create_action(TTR("Node Moved")); - undo_redo->add_do_method(visual_shader.ptr(), "set_node_position", type, p_node, p_to); - undo_redo->add_undo_method(visual_shader.ptr(), "set_node_position", type, p_node, p_from); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); + + drag_buffer.clear(); undo_redo->commit_action(); updating = false; } @@ -2331,6 +2344,7 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer); ClassDB::bind_method("_show_preview_text", &VisualShaderEditor::_show_preview_text); ClassDB::bind_method("_update_preview", &VisualShaderEditor::_update_preview); + ClassDB::bind_method("_nodes_dragged", &VisualShaderEditor::_nodes_dragged); ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 700033e1c40e..01372455193a 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -166,7 +166,16 @@ class VisualShaderEditor : public VBoxContainer { static VisualShaderEditor *singleton; + struct DragOp { + VisualShader::Type type; + int node; + Vector2 from; + Vector2 to; + }; + List drag_buffer; + bool drag_dirty = false; void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node); + void _nodes_dragged(); bool updating; void _connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index);