Kaynağa Gözat

Merge pull request #986 from TheoXD/_tree_multiselect_move

Selected node(s) can now be moved up and down in scene tree dock.
Juan Linietsky 11 yıl önce
ebeveyn
işleme
35b0b3bc1d
1 değiştirilmiş dosya ile 42 ekleme ve 9 silme
  1. 42 9
      tools/editor/scene_tree_dock.cpp

+ 42 - 9
tools/editor/scene_tree_dock.cpp

@@ -212,17 +212,50 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 			if (!_validate_no_foreign())
 				break;
 
-			Node * node=scene_tree->get_selected();
-			ERR_FAIL_COND(!node->get_parent());
-			int current_pos = node->get_index();
-			int next_pos = current_pos + ((p_tool==TOOL_MOVE_DOWN)?1:-1);
+			bool MOVING_DOWN = (p_tool == TOOL_MOVE_DOWN);
+			bool MOVING_UP = !MOVING_DOWN;
 
-			if (next_pos< 0 || next_pos>=node->get_parent()->get_child_count())
-				break; // invalid position
+			Node *common_parent = scene_tree->get_selected()->get_parent();
+			List<Node*> selection = editor_selection->get_selected_node_list();
+			selection.sort_custom<Node::Comparator>();  // sort by index
+			if (MOVING_DOWN)
+				selection.invert();
+
+			int lowest_id = common_parent->get_child_count() - 1;
+			int highest_id = 0;
+			for (List<Node*>::Element *E = selection.front(); E; E = E->next()) {
+				int index = E->get()->get_index();
+
+				if (index > highest_id) highest_id = index;
+				if (index < lowest_id) lowest_id = index;
+
+				if (E->get()->get_parent() != common_parent)
+					common_parent = NULL;
+			}
+
+			if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count() - MOVING_DOWN) || (MOVING_UP && lowest_id == 0))
+				break; // one or more nodes can not be moved
+
+			if (selection.size() == 1) editor_data->get_undo_redo().create_action("Move Node In Parent");
+			if (selection.size() > 1) editor_data->get_undo_redo().create_action("Move Nodes In Parent");
+
+			for (int i = 0; i < selection.size(); i++) {
+				Node *top_node = selection[i];
+				Node *bottom_node = selection[selection.size() - 1 - i];
+				 
+				ERR_FAIL_COND(!top_node->get_parent());
+				ERR_FAIL_COND(!bottom_node->get_parent());
+
+				int top_node_pos = top_node->get_index();
+				int bottom_node_pos = bottom_node->get_index();
+
+				int top_node_pos_next = top_node_pos + (MOVING_DOWN ? 1 : -1);
+				int bottom_node_pos_next = bottom_node_pos + (MOVING_DOWN ? 1 : -1);
+
+				editor_data->get_undo_redo().add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next);
+				editor_data->get_undo_redo().add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos);
+			}
 
-			editor_data->get_undo_redo().create_action("Move Node In Parent");
-			editor_data->get_undo_redo().add_do_method(node->get_parent(),"move_child",node,next_pos);
-			editor_data->get_undo_redo().add_undo_method(node->get_parent(),"move_child",node,current_pos);
 			editor_data->get_undo_redo().commit_action();
 
 		} break;