瀏覽代碼

Add drag and drop for NodePaths

(cherry picked from commit acf563e59f14ed650ee04b4a91731bfd3ad61247)
kobewi 3 年之前
父節點
當前提交
664f36308a
共有 4 個文件被更改,包括 49 次插入12 次删除
  1. 26 0
      editor/editor_properties.cpp
  2. 4 0
      editor/editor_properties.h
  3. 18 12
      editor/scene_tree_dock.cpp
  4. 1 0
      editor/scene_tree_dock.h

+ 26 - 0
editor/editor_properties.cpp

@@ -2139,6 +2139,29 @@ void EditorPropertyNodePath::_node_clear() {
 	update_property();
 	update_property();
 }
 }
 
 
+bool EditorPropertyNodePath::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
+	return !is_read_only() && is_drop_valid(p_data);
+}
+
+void EditorPropertyNodePath::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+	ERR_FAIL_COND(!is_drop_valid(p_data));
+	Dictionary data = p_data;
+	Array nodes = data["nodes"];
+	Node *node = get_tree()->get_edited_scene_root()->get_node(nodes[0]);
+
+	if (node) {
+		_node_selected(node->get_path());
+	}
+}
+
+bool EditorPropertyNodePath::is_drop_valid(const Dictionary &p_drag_data) const {
+	if (p_drag_data["type"] != "nodes") {
+		return false;
+	}
+	Array nodes = p_drag_data["nodes"];
+	return nodes.size() == 1;
+}
+
 void EditorPropertyNodePath::update_property() {
 void EditorPropertyNodePath::update_property() {
 	NodePath p = get_edited_object()->get(get_edited_property());
 	NodePath p = get_edited_object()->get(get_edited_property());
 
 
@@ -2196,6 +2219,8 @@ void EditorPropertyNodePath::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_node_selected"), &EditorPropertyNodePath::_node_selected);
 	ClassDB::bind_method(D_METHOD("_node_selected"), &EditorPropertyNodePath::_node_selected);
 	ClassDB::bind_method(D_METHOD("_node_assign"), &EditorPropertyNodePath::_node_assign);
 	ClassDB::bind_method(D_METHOD("_node_assign"), &EditorPropertyNodePath::_node_assign);
 	ClassDB::bind_method(D_METHOD("_node_clear"), &EditorPropertyNodePath::_node_clear);
 	ClassDB::bind_method(D_METHOD("_node_clear"), &EditorPropertyNodePath::_node_clear);
+	ClassDB::bind_method(D_METHOD("_can_drop_data_fw", "position", "data", "from"), &EditorPropertyNodePath::can_drop_data_fw);
+	ClassDB::bind_method(D_METHOD("_drop_data_fw", "position", "data", "from"), &EditorPropertyNodePath::drop_data_fw);
 }
 }
 
 
 EditorPropertyNodePath::EditorPropertyNodePath() {
 EditorPropertyNodePath::EditorPropertyNodePath() {
@@ -2206,6 +2231,7 @@ EditorPropertyNodePath::EditorPropertyNodePath() {
 	assign->set_h_size_flags(SIZE_EXPAND_FILL);
 	assign->set_h_size_flags(SIZE_EXPAND_FILL);
 	assign->set_clip_text(true);
 	assign->set_clip_text(true);
 	assign->connect("pressed", this, "_node_assign");
 	assign->connect("pressed", this, "_node_assign");
+	assign->set_drag_forwarding(this);
 	hbc->add_child(assign);
 	hbc->add_child(assign);
 
 
 	clear = memnew(Button);
 	clear = memnew(Button);

+ 4 - 0
editor/editor_properties.h

@@ -522,6 +522,10 @@ class EditorPropertyNodePath : public EditorProperty {
 	void _node_assign();
 	void _node_assign();
 	void _node_clear();
 	void _node_clear();
 
 
+	bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
+	void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+	bool is_drop_valid(const Dictionary &p_drag_data) const;
+
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
 	void _notification(int p_what);
 	void _notification(int p_what);

+ 18 - 12
editor/scene_tree_dock.cpp

@@ -228,7 +228,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
 	}
 	}
 
 
 	editor_data->get_undo_redo().commit_action();
 	editor_data->get_undo_redo().commit_action();
-	editor->push_item(instances[instances.size() - 1]);
+	_push_item(instances[instances.size() - 1]);
 	for (int i = 0; i < instances.size(); i++) {
 	for (int i = 0; i < instances.size(); i++) {
 		emit_signal("node_created", instances[i]);
 		emit_signal("node_created", instances[i]);
 	}
 	}
@@ -748,7 +748,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 			editor_data->get_undo_redo().commit_action();
 			editor_data->get_undo_redo().commit_action();
 
 
 			if (dupsingle) {
 			if (dupsingle) {
-				editor->push_item(dupsingle);
+				_push_item(dupsingle);
 			}
 			}
 		} break;
 		} break;
 		case TOOL_REPARENT: {
 		case TOOL_REPARENT: {
@@ -853,7 +853,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 				mne->add_node(root->get_path_to(E->key()));
 				mne->add_node(root->get_path_to(E->key()));
 			}
 			}
 
 
-			EditorNode::get_singleton()->push_item(mne.ptr());
+			_push_item(mne.ptr());
 
 
 		} break;
 		} break;
 
 
@@ -1172,7 +1172,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 				Object *obj = ObjectDB::get_instance(subresources[idx]);
 				Object *obj = ObjectDB::get_instance(subresources[idx]);
 				ERR_FAIL_COND(!obj);
 				ERR_FAIL_COND(!obj);
 
 
-				editor->push_item(obj);
+				_push_item(obj);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -1362,6 +1362,12 @@ void SceneTreeDock::_script_open_request(const Ref<Script> &p_script) {
 	editor->edit_resource(p_script);
 	editor->edit_resource(p_script);
 }
 }
 
 
+void SceneTreeDock::_push_item(Object *p_object) {
+	if (!Input::get_singleton()->is_key_pressed(KEY_ALT)) {
+		editor->push_item(p_object);
+	}
+}
+
 void SceneTreeDock::_node_selected() {
 void SceneTreeDock::_node_selected() {
 	Node *node = scene_tree->get_selected();
 	Node *node = scene_tree->get_selected();
 
 
@@ -1373,7 +1379,7 @@ void SceneTreeDock::_node_selected() {
 		restore_script_editor_on_drag = true;
 		restore_script_editor_on_drag = true;
 	}
 	}
 
 
-	editor->push_item(node);
+	_push_item(node);
 }
 }
 
 
 void SceneTreeDock::_node_renamed() {
 void SceneTreeDock::_node_renamed() {
@@ -1944,7 +1950,7 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
 
 
 	editor_data->get_undo_redo().commit_action();
 	editor_data->get_undo_redo().commit_action();
 
 
-	editor->push_item(p_script.operator->());
+	_push_item(p_script.operator->());
 	_update_script_button();
 	_update_script_button();
 }
 }
 
 
@@ -2073,7 +2079,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
 		editor->get_viewport_control()->update();
 		editor->get_viewport_control()->update();
 	}
 	}
 
 
-	editor->push_item(nullptr);
+	_push_item(nullptr);
 
 
 	// Fixes the EditorHistory from still offering deleted notes
 	// Fixes the EditorHistory from still offering deleted notes
 	EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
 	EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
@@ -2117,9 +2123,9 @@ void SceneTreeDock::_selection_changed() {
 		//automatically turn on multi-edit
 		//automatically turn on multi-edit
 		_tool_selected(TOOL_MULTI_EDIT);
 		_tool_selected(TOOL_MULTI_EDIT);
 	} else if (selection_size == 1) {
 	} else if (selection_size == 1) {
-		editor->push_item(editor_selection->get_selection().front()->key());
+		_push_item(editor_selection->get_selection().front()->key());
 	} else if (selection_size == 0) {
 	} else if (selection_size == 0) {
-		editor->push_item(nullptr);
+		_push_item(nullptr);
 	}
 	}
 
 
 	_update_script_button();
 	_update_script_button();
@@ -2172,7 +2178,7 @@ void SceneTreeDock::_do_create(Node *p_parent) {
 	}
 	}
 
 
 	editor_data->get_undo_redo().commit_action();
 	editor_data->get_undo_redo().commit_action();
-	editor->push_item(c);
+	_push_item(c);
 	editor_selection->clear();
 	editor_selection->clear();
 	editor_selection->add_node(child);
 	editor_selection->add_node(child);
 	if (Object::cast_to<Control>(c)) {
 	if (Object::cast_to<Control>(c)) {
@@ -2328,7 +2334,7 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
 		memdelete(default_oldnode);
 		memdelete(default_oldnode);
 	}
 	}
 
 
-	editor->push_item(nullptr);
+	_push_item(nullptr);
 
 
 	//reconnect signals
 	//reconnect signals
 	List<MethodInfo> sl;
 	List<MethodInfo> sl;
@@ -2373,7 +2379,7 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
 	}
 	}
 	newnode->set_name(newname);
 	newnode->set_name(newname);
 
 
-	editor->push_item(newnode);
+	_push_item(newnode);
 
 
 	if (p_remove_old) {
 	if (p_remove_old) {
 		memdelete(n);
 		memdelete(n);

+ 1 - 0
editor/scene_tree_dock.h

@@ -194,6 +194,7 @@ class SceneTreeDock : public VBoxContainer {
 	void _node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode = MODE_BIDI);
 	void _node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode = MODE_BIDI);
 	void _load_request(const String &p_path);
 	void _load_request(const String &p_path);
 	void _script_open_request(const Ref<Script> &p_script);
 	void _script_open_request(const Ref<Script> &p_script);
+	void _push_item(Object *p_object);
 
 
 	bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node);
 	bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node);
 	bool _track_inherit(const String &p_target_scene_path, Node *p_desired_node);
 	bool _track_inherit(const String &p_target_scene_path, Node *p_desired_node);