Browse Source

Merge pull request #42590 from Chaosus/vs_fix_move_undo_3.2

[3.2] Fix undo for moving multiple visual shader nodes
Yuri Roubinsky 4 years ago
parent
commit
cc3c671f3b

+ 18 - 4
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) {
 void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) {
-
 	VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
 	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<DragOp>::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;
 	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_do_method(this, "_update_graph");
 	undo_redo->add_undo_method(this, "_update_graph");
 	undo_redo->add_undo_method(this, "_update_graph");
+
+	drag_buffer.clear();
 	undo_redo->commit_action();
 	undo_redo->commit_action();
 	updating = false;
 	updating = false;
 }
 }
@@ -2331,6 +2344,7 @@ void VisualShaderEditor::_bind_methods() {
 	ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer);
 	ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer);
 	ClassDB::bind_method("_show_preview_text", &VisualShaderEditor::_show_preview_text);
 	ClassDB::bind_method("_show_preview_text", &VisualShaderEditor::_show_preview_text);
 	ClassDB::bind_method("_update_preview", &VisualShaderEditor::_update_preview);
 	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("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
 	ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
 	ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);

+ 9 - 0
editor/plugins/visual_shader_editor_plugin.h

@@ -166,7 +166,16 @@ class VisualShaderEditor : public VBoxContainer {
 
 
 	static VisualShaderEditor *singleton;
 	static VisualShaderEditor *singleton;
 
 
+	struct DragOp {
+		VisualShader::Type type;
+		int node;
+		Vector2 from;
+		Vector2 to;
+	};
+	List<DragOp> drag_buffer;
+	bool drag_dirty = false;
 	void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node);
 	void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node);
+	void _nodes_dragged();
 	bool updating;
 	bool updating;
 
 
 	void _connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index);
 	void _connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index);