From f6ca9d34a2f7111b2d1359ef517e44e3e257469d Mon Sep 17 00:00:00 2001 From: MillionOstrich <31486600+MillionOstrich@users.noreply.github.com> Date: Tue, 24 Oct 2017 23:09:04 +0100 Subject: [PATCH] Improve file/folder drag preview on filesystem dock Added icons for files/folders in drag preview Fixed folders getting an empty string label Don't show "1 more file(s)" label instead of the file Added "more folders" case if moving folders exclusively Merged drag_files and drag_files_and_dirs to reduce code duplication Simplified get_drag_data_fw and removed commented out code --- editor/editor_node.cpp | 90 +++++++++++++++++--------------------- editor/editor_node.h | 3 +- editor/filesystem_dock.cpp | 74 +++++++------------------------ 3 files changed, 58 insertions(+), 109 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3513126a9b2c..156e217b64b1 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -4217,61 +4217,53 @@ Variant EditorNode::drag_resource(const Ref &p_res, Control *p_from) { return drag_data; } -Variant EditorNode::drag_files(const Vector &p_files, Control *p_from) { - - VBoxContainer *files = memnew(VBoxContainer); - - int max_files = 6; - - for (int i = 0; i < MIN(max_files, p_files.size()); i++) { - - Label *label = memnew(Label); - label->set_text(p_files[i].get_file()); - files->add_child(label); +Variant EditorNode::drag_files_and_dirs(const Vector &p_paths, Control *p_from) { + bool has_folder = false; + bool has_file = false; + for (int i = 0; i < p_paths.size(); i++) { + bool is_folder = p_paths[i].ends_with("/"); + has_folder |= is_folder; + has_file |= !is_folder; } - if (p_files.size() > max_files) { - + int max_rows = 6; + int num_rows = p_paths.size() > max_rows ? max_rows - 1 : p_paths.size(); //Don't waste a row to say "1 more file" - list it instead. + VBoxContainer *vbox = memnew(VBoxContainer); + for (int i = 0; i < num_rows; i++) { + HBoxContainer *hbox = memnew(HBoxContainer); + TextureRect *icon = memnew(TextureRect); Label *label = memnew(Label); - label->set_text(vformat(TTR("%d more file(s)"), p_files.size() - max_files)); - files->add_child(label); + + if (p_paths[i].ends_with("/")) { + label->set_text(p_paths[i].substr(0, p_paths[i].length() - 1).get_file()); + icon->set_texture(gui_base->get_icon("Folder", "EditorIcons")); + } else { + label->set_text(p_paths[i].get_file()); + icon->set_texture(gui_base->get_icon("File", "EditorIcons")); + } + icon->set_size(Size2(16, 16)); + hbox->add_child(icon); + hbox->add_child(label); + vbox->add_child(hbox); } + + if (p_paths.size() > num_rows) { + Label *label = memnew(Label); + if (has_file && has_folder) { + label->set_text(vformat(TTR("%d more files or folders"), p_paths.size() - num_rows)); + } else if (has_folder) { + label->set_text(vformat(TTR("%d more folders"), p_paths.size() - num_rows)); + } else { + label->set_text(vformat(TTR("%d more files"), p_paths.size() - num_rows)); + } + vbox->add_child(label); + } + p_from->set_drag_preview(vbox); //wait until it enters scene + Dictionary drag_data; - drag_data["type"] = "files"; - drag_data["files"] = p_files; + drag_data["type"] = has_folder ? "files_and_dirs" : "files"; + drag_data["files"] = p_paths; drag_data["from"] = p_from; - - p_from->set_drag_preview(files); //wait until it enters scene - - return drag_data; -} - -Variant EditorNode::drag_files_and_dirs(const Vector &p_files, Control *p_from) { - - VBoxContainer *files = memnew(VBoxContainer); - - int max_files = 6; - - for (int i = 0; i < MIN(max_files, p_files.size()); i++) { - - Label *label = memnew(Label); - label->set_text(p_files[i].get_file()); - files->add_child(label); - } - - if (p_files.size() > max_files) { - - Label *label = memnew(Label); - label->set_text(vformat(TTR("%d more file(s) or folder(s)"), p_files.size() - max_files)); - files->add_child(label); - } - Dictionary drag_data; - drag_data["type"] = "files_and_dirs"; - drag_data["files"] = p_files; - drag_data["from"] = p_from; - - p_from->set_drag_preview(files); //wait until it enters scene - return drag_data; } diff --git a/editor/editor_node.h b/editor/editor_node.h index 32d46e686bba..6e0117a4ac9f 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -765,8 +765,7 @@ public: void remove_bottom_panel_item(Control *p_item); Variant drag_resource(const Ref &p_res, Control *p_from); - Variant drag_files(const Vector &p_files, Control *p_from); - Variant drag_files_and_dirs(const Vector &p_files, Control *p_from); + Variant drag_files_and_dirs(const Vector &p_paths, Control *p_from); void add_tool_menu_item(const String &p_name, Object *p_handler, const String &p_callback, const Variant &p_ud = Variant()); void add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 00cbd9bb72b0..96fa9773ade8 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1186,78 +1186,36 @@ void FileSystemDock::set_display_mode(int p_mode) { } Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) { + bool is_favorite = false; + Vector paths; if (p_from == tree) { - TreeItem *selected = tree->get_selected(); if (!selected) return Variant(); - String fpath = selected->get_metadata(0); - if (fpath == String()) + String folder = selected->get_metadata(0); + if (folder == String()) return Variant(); - if (!fpath.ends_with("/")) - fpath = fpath + "/"; - Vector paths; - paths.push_back(fpath); - Dictionary d = EditorNode::get_singleton()->drag_files(paths, p_from); - - if (selected->get_parent() && tree->get_root()->get_children() == selected->get_parent()) { - //a favorite.. treat as such - d["type"] = "favorite"; - } - - return d; - } - - if (p_from == files) { - - List seldirs; - List selfiles; + paths.push_back(folder.ends_with("/") ? folder : (folder + "/")); + is_favorite = selected->get_parent() != NULL && tree->get_root()->get_children() == selected->get_parent(); + } else if (p_from == files) { for (int i = 0; i < files->get_item_count(); i++) { if (files->is_selected(i)) { - String fpath = files->get_item_metadata(i); - if (fpath.ends_with("/")) - seldirs.push_back(i); - else - selfiles.push_back(i); + paths.push_back(files->get_item_metadata(i)); } } - - if (seldirs.empty() && selfiles.empty()) - return Variant(); - /* - if (seldirs.size() && selfiles.size()) - return Variant(); //can't really mix files and dirs (i think?) - yes you can, commenting - */ - - /*if (selfiles.size()==1) { - Ref resource = ResourceLoader::load(files->get_item_metadata(selfiles.front()->get())); - if (resource.is_valid()) { - return EditorNode::get_singleton()->drag_resource(resource,p_from); - } - }*/ - - Vector fnames; - if (selfiles.size() > 0 || seldirs.size() > 0) { - if (selfiles.size() > 0) { - for (List::Element *E = selfiles.front(); E; E = E->next()) { - fnames.push_back(files->get_item_metadata(E->get())); - } - if (seldirs.size() == 0) - return EditorNode::get_singleton()->drag_files(fnames, p_from); - } - - for (List::Element *E = seldirs.front(); E; E = E->next()) { - fnames.push_back(files->get_item_metadata(E->get())); - } - - return EditorNode::get_singleton()->drag_files_and_dirs(fnames, p_from); - } } - return Variant(); + if (paths.empty()) + return Variant(); + + Dictionary drag_data = EditorNode::get_singleton()->drag_files_and_dirs(paths, p_from); + if (is_favorite) { + drag_data["type"] = "favorite"; + } + return drag_data; } bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {