Преглед изворни кода

Merge pull request #8114 from RandomShaper/improve-snapping-2.1

Improved 2D snapping behavior (2.1)
Rémi Verschelde пре 8 година
родитељ
комит
8f5b15754c
2 измењених фајлова са 49 додато и 48 уклоњено
  1. 47 48
      editor/plugins/canvas_item_editor_plugin.cpp
  2. 2 0
      editor/plugins/canvas_item_editor_plugin.h

+ 47 - 48
editor/plugins/canvas_item_editor_plugin.cpp

@@ -594,30 +594,7 @@ bool CanvasItemEditor::_select(CanvasItem *item, Point2 p_click_pos, bool p_appe
 		}
 		}
 
 
 		if (p_drag) {
 		if (p_drag) {
-			//prepare to move!
-
-			List<Node *> &selection = editor_selection->get_selected_node_list();
-
-			for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
-				CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>();
-				if (!canvas_item || !canvas_item->is_visible())
-					continue;
-				if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
-					continue;
-
-				CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
-				if (!se)
-					continue;
-
-				se->undo_state = canvas_item->edit_get_state();
-				if (canvas_item->cast_to<Node2D>())
-					se->undo_pivot = canvas_item->cast_to<Node2D>()->edit_get_pivot();
-			}
-
-			drag = DRAG_ALL;
-			drag_from = transform.affine_inverse().xform(p_click_pos);
-			drag_point_from = _find_topleftmost_point();
+			_prepare_drag(p_click_pos);
 		}
 		}
 
 
 		viewport->update();
 		viewport->update();
@@ -835,6 +812,37 @@ CanvasItemEditor::DragType CanvasItemEditor::_find_drag_type(const Matrix32 &p_x
 	return DRAG_NONE;
 	return DRAG_NONE;
 }
 }
 
 
+void CanvasItemEditor::_prepare_drag(const Point2 &p_click_pos) {
+
+	List<Node *> &selection = editor_selection->get_selected_node_list();
+
+	for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+		CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>();
+		if (!canvas_item || !canvas_item->is_visible())
+			continue;
+		if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+			continue;
+
+		CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
+		if (!se)
+			continue;
+
+		se->undo_state = canvas_item->edit_get_state();
+		if (canvas_item->cast_to<Node2D>())
+			se->undo_pivot = canvas_item->cast_to<Node2D>()->edit_get_pivot();
+	}
+
+	if (selection.size() == 1 && selection[0]->cast_to<Node2D>()) {
+		drag = DRAG_NODE_2D;
+		drag_point_from = selection[0]->cast_to<Node2D>()->get_global_pos();
+	} else {
+		drag = DRAG_ALL;
+		drag_point_from = _find_topleftmost_point();
+	}
+	drag_from = transform.affine_inverse().xform(p_click_pos);
+}
+
 void CanvasItemEditor::incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric) {
 void CanvasItemEditor::incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric) {
 
 
 	if (minsize < 0) {
 	if (minsize < 0) {
@@ -1371,28 +1379,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent &p_event) {
 
 
 		if ((b.mod.alt || tool == TOOL_MOVE) && get_item_count()) {
 		if ((b.mod.alt || tool == TOOL_MOVE) && get_item_count()) {
 
 
-			List<Node *> &selection = editor_selection->get_selected_node_list();
-
-			for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
-				CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>();
-				if (!canvas_item || !canvas_item->is_visible())
-					continue;
-				if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
-					continue;
-
-				CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
-				if (!se)
-					continue;
-
-				se->undo_state = canvas_item->edit_get_state();
-				if (canvas_item->cast_to<Node2D>())
-					se->undo_pivot = canvas_item->cast_to<Node2D>()->edit_get_pivot();
-			}
-
-			drag = DRAG_ALL;
-			drag_from = transform.affine_inverse().xform(click);
-			drag_point_from = _find_topleftmost_point();
+			_prepare_drag(click);
 			viewport->update();
 			viewport->update();
 			return;
 			return;
 		}
 		}
@@ -1540,7 +1527,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent &p_event) {
 			bool uniform = m.mod.shift;
 			bool uniform = m.mod.shift;
 			bool symmetric = m.mod.alt;
 			bool symmetric = m.mod.alt;
 
 
-			dto = dto - (drag == DRAG_ALL ? drag_from - drag_point_from : Vector2(0, 0));
+			dto = dto - (drag == DRAG_ALL || drag == DRAG_NODE_2D ? drag_from - drag_point_from : Vector2(0, 0));
 
 
 			if (uniform && drag == DRAG_ALL) {
 			if (uniform && drag == DRAG_ALL) {
 				if (ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) {
 				if (ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) {
@@ -1639,6 +1626,12 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent &p_event) {
 					}
 					}
 					continue;
 					continue;
 				} break;
 				} break;
+				case DRAG_NODE_2D: {
+
+					ERR_FAIL_COND(!canvas_item->cast_to<Node2D>());
+					canvas_item->cast_to<Node2D>()->set_global_pos(dto);
+					continue;
+				} break;
 
 
 				default: {}
 				default: {}
 			}
 			}
@@ -3541,6 +3534,8 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
 	if (default_type == "Polygon2D" || default_type == "TouchScreenButton" || default_type == "TextureFrame" || default_type == "Patch9Frame") {
 	if (default_type == "Polygon2D" || default_type == "TouchScreenButton" || default_type == "TextureFrame" || default_type == "Patch9Frame") {
 		target_pos -= texture_size / 2;
 		target_pos -= texture_size / 2;
 	}
 	}
+	// there's nothing to be used as source position so snapping will work as absolute if enabled
+	target_pos = canvas->snap_point(target_pos, Vector2());
 	editor_data->get_undo_redo().add_do_method(child, "set_pos", target_pos);
 	editor_data->get_undo_redo().add_do_method(child, "set_pos", target_pos);
 }
 }
 
 
@@ -3585,7 +3580,11 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
 		}
 		}
 	}
 	}
 	Matrix32 trans = canvas->get_canvas_transform();
 	Matrix32 trans = canvas->get_canvas_transform();
-	editor_data->get_undo_redo().add_do_method(instanced_scene, "set_pos", (p_point - trans.get_origin()) / trans.get_scale().x - pos);
+	Vector2 target_pos = (p_point - trans.get_origin()) / trans.get_scale().x - pos;
+	// in relative snapping it may be useful for the user to take the original node position into account
+	Vector2 start_pos = instanced_scene->cast_to<Node2D>() ? instanced_scene->cast_to<Node2D>()->get_pos() : target_pos;
+	target_pos = canvas->snap_point(target_pos, start_pos);
+	editor_data->get_undo_redo().add_do_method(instanced_scene, "set_pos", target_pos);
 
 
 	return true;
 	return true;
 }
 }

+ 2 - 0
editor/plugins/canvas_item_editor_plugin.h

@@ -143,6 +143,7 @@ class CanvasItemEditor : public VBoxContainer {
 		DRAG_ALL,
 		DRAG_ALL,
 		DRAG_ROTATE,
 		DRAG_ROTATE,
 		DRAG_PIVOT,
 		DRAG_PIVOT,
+		DRAG_NODE_2D,
 
 
 	};
 	};
 
 
@@ -320,6 +321,7 @@ class CanvasItemEditor : public VBoxContainer {
 	void _list_select(const InputEventMouseButton &b);
 	void _list_select(const InputEventMouseButton &b);
 
 
 	DragType _find_drag_type(const Matrix32 &p_xform, const Rect2 &p_local_rect, const Point2 &p_click, Vector2 &r_point);
 	DragType _find_drag_type(const Matrix32 &p_xform, const Rect2 &p_local_rect, const Point2 &p_click, Vector2 &r_point);
+	void _prepare_drag(const Point2 &p_click_pos);
 
 
 	void _popup_callback(int p_op);
 	void _popup_callback(int p_op);
 	bool updating_scroll;
 	bool updating_scroll;