summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2022-03-06 23:25:39 +0100
committerGitHub <noreply@github.com>2022-03-06 23:25:39 +0100
commit1fbd498307103d0f80f0c780bbb647214dfed4b0 (patch)
tree1a3971f7b11cb320bcefde6a0252b829ff24f094
parent78ad01cae7d68c34cd187b9c3a94583e95ff306f (diff)
parent2ed334f95fa67b5ef9451a44ff7820b1164e6b9c (diff)
Merge pull request #58842 from IgorKordiukiewicz/save-as-scene-visual-feedback
Added visual feedback when drag and dropping from scene tree to filesystem
-rw-r--r--editor/filesystem_dock.cpp122
-rw-r--r--editor/filesystem_dock.h7
2 files changed, 129 insertions, 0 deletions
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index e5cd7b8974..e8a2a46dd2 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -396,12 +396,25 @@ void FileSystemDock::_notification(int p_what) {
}
} else if ((String(dd["type"]) == "files") || (String(dd["type"]) == "files_and_dirs") || (String(dd["type"]) == "resource")) {
tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM | Tree::DROP_MODE_INBETWEEN);
+ } else if ((String(dd["type"]) == "nodes")) {
+ holding_branch = true;
+ TreeItem *item = tree->get_next_selected(tree->get_root());
+ while (item) {
+ tree_items_selected_on_drag_begin.push_back(item);
+ item = tree->get_next_selected(item);
+ }
+ list_items_selected_on_drag_begin = files->get_selected_items();
}
}
} break;
case NOTIFICATION_DRAG_END: {
tree->set_drop_mode_flags(0);
+
+ if (holding_branch) {
+ holding_branch = false;
+ _reselect_items_selected_on_drag_begin(true);
+ }
} break;
case NOTIFICATION_THEME_CHANGED: {
@@ -2647,8 +2660,79 @@ void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) {
call_deferred(SNAME("_update_import_dock"));
}
+void FileSystemDock::_tree_mouse_exited() {
+ if (holding_branch) {
+ _reselect_items_selected_on_drag_begin();
+ }
+}
+
+void FileSystemDock::_reselect_items_selected_on_drag_begin(bool reset) {
+ TreeItem *selected_item = tree->get_next_selected(tree->get_root());
+ if (selected_item) {
+ selected_item->deselect(0);
+ }
+ if (!tree_items_selected_on_drag_begin.is_empty()) {
+ bool reselected = false;
+ for (TreeItem *item : tree_items_selected_on_drag_begin) {
+ if (item->get_tree()) {
+ item->select(0);
+ reselected = true;
+ }
+ }
+
+ if (reset) {
+ tree_items_selected_on_drag_begin.clear();
+ }
+
+ if (!reselected) {
+ // If couldn't reselect the items selected on drag begin, select the "res://" item.
+ tree->get_root()->get_child(1)->select(0);
+ }
+ }
+
+ files->deselect_all();
+ if (!list_items_selected_on_drag_begin.is_empty()) {
+ for (const int idx : list_items_selected_on_drag_begin) {
+ files->select(idx, false);
+ }
+
+ if (reset) {
+ list_items_selected_on_drag_begin.clear();
+ }
+ }
+}
+
void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventKey> key = p_event;
+
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
+ TreeItem *item = tree->get_item_at_position(mm->get_position());
+ if (item && holding_branch) {
+ String fpath = item->get_metadata(0);
+ while (!fpath.ends_with("/") && fpath != "res://" && item->get_parent()) { // Find the parent folder tree item.
+ item = item->get_parent();
+ fpath = item->get_metadata(0);
+ }
+
+ TreeItem *deselect_item = tree->get_next_selected(tree->get_root());
+ while (deselect_item) {
+ deselect_item->deselect(0);
+ deselect_item = tree->get_next_selected(deselect_item);
+ }
+ item->select(0);
+
+ if (display_mode == DisplayMode::DISPLAY_MODE_SPLIT) {
+ files->deselect_all();
+ // Try to select the corresponding file list item.
+ const int files_item_idx = files->find_metadata(fpath);
+ if (files_item_idx != -1) {
+ files->select(files_item_idx);
+ }
+ }
+ }
+ }
+
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) {
_tree_rmb_option(FILE_DUPLICATE);
@@ -2669,6 +2753,43 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) {
}
void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) {
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid() && holding_branch) {
+ const int item_idx = files->get_item_at_position(mm->get_position());
+ if (item_idx != -1) {
+ files->deselect_all();
+ String fpath = files->get_item_metadata(item_idx);
+ if (fpath.ends_with("/") || fpath == "res://") {
+ files->select(item_idx);
+ }
+
+ TreeItem *deselect_item = tree->get_next_selected(tree->get_root());
+ while (deselect_item) {
+ deselect_item->deselect(0);
+ deselect_item = tree->get_next_selected(deselect_item);
+ }
+
+ // Try to select the corresponding tree item.
+ TreeItem *tree_item = tree->get_item_with_text(files->get_item_text(item_idx));
+ if (tree_item) {
+ tree_item->select(0);
+ } else {
+ // Find parent folder.
+ fpath = fpath.substr(0, fpath.rfind("/") + 1);
+ if (fpath.size() > String("res://").size()) {
+ fpath = fpath.left(fpath.size() - 2); // Remove last '/'.
+ const int slash_idx = fpath.rfind("/");
+ fpath = fpath.substr(slash_idx + 1, fpath.size() - slash_idx - 1);
+ }
+
+ tree_item = tree->get_item_with_text(fpath);
+ if (tree_item) {
+ tree_item->select(0);
+ }
+ }
+ }
+ }
+
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) {
@@ -2932,6 +3053,7 @@ FileSystemDock::FileSystemDock() {
tree->connect("empty_rmb", callable_mp(this, &FileSystemDock::_tree_rmb_empty));
tree->connect("nothing_selected", callable_mp(this, &FileSystemDock::_tree_empty_selected));
tree->connect("gui_input", callable_mp(this, &FileSystemDock::_tree_gui_input));
+ tree->connect("mouse_exited", callable_mp(this, &FileSystemDock::_tree_mouse_exited));
file_list_vb = memnew(VBoxContainer);
file_list_vb->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 21c50beeb2..d457c6acd4 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -185,6 +185,13 @@ private:
ItemList *files;
bool import_dock_needs_update;
+ bool holding_branch = false;
+ Vector<TreeItem *> tree_items_selected_on_drag_begin;
+ PackedInt32Array list_items_selected_on_drag_begin;
+
+ void _tree_mouse_exited();
+ void _reselect_items_selected_on_drag_begin(bool reset = false);
+
Ref<Texture2D> _get_tree_item_icon(bool p_is_valid, String p_file_type);
bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path = false);
Vector<String> _compute_uncollapsed_paths();