Add drag and drop for NodePaths

(cherry picked from commit acf563e59f)
This commit is contained in:
kobewi 2021-12-09 18:50:57 +01:00 committed by Rémi Verschelde
parent d2558bdc8c
commit 664f36308a
No known key found for this signature in database
GPG key ID: C3336907360768E1
4 changed files with 49 additions and 12 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);