فهرست منبع

Merge pull request #12390 from MillionOstrich/filesystem-folder-drag

Improved file/folder drag preview for filesystem dock
Rémi Verschelde 7 سال پیش
والد
کامیت
346b4b5a1c
3فایلهای تغییر یافته به همراه54 افزوده شده و 105 حذف شده
  1. 38 46
      editor/editor_node.cpp
  2. 1 2
      editor/editor_node.h
  3. 15 57
      editor/filesystem_dock.cpp

+ 38 - 46
editor/editor_node.cpp

@@ -4226,61 +4226,53 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
 	return drag_data;
 }
 
-Variant EditorNode::drag_files(const Vector<String> &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++) {
-
+Variant EditorNode::drag_files_and_dirs(const Vector<String> &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;
+	}
+
+	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(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)"), 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);
 	}
-	Dictionary drag_data;
-	drag_data["type"] = "files";
-	drag_data["files"] = p_files;
-	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<String> &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++) {
 
+	if (p_paths.size() > num_rows) {
 		Label *label = memnew(Label);
-		label->set_text(p_files[i].get_file());
-		files->add_child(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
 
-	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["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;
 }
 

+ 1 - 2
editor/editor_node.h

@@ -765,8 +765,7 @@ public:
 	void remove_bottom_panel_item(Control *p_item);
 
 	Variant drag_resource(const Ref<Resource> &p_res, Control *p_from);
-	Variant drag_files(const Vector<String> &p_files, Control *p_from);
-	Variant drag_files_and_dirs(const Vector<String> &p_files, Control *p_from);
+	Variant drag_files_and_dirs(const Vector<String> &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);

+ 15 - 57
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<String> 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<String> 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<int> seldirs;
-		List<int> 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> resource = ResourceLoader::load(files->get_item_metadata(selfiles.front()->get()));
-			if (resource.is_valid()) {
-				return EditorNode::get_singleton()->drag_resource(resource,p_from);
-			}
-		}*/
-
-		Vector<String> fnames;
-		if (selfiles.size() > 0 || seldirs.size() > 0) {
-			if (selfiles.size() > 0) {
-				for (List<int>::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<int>::Element *E = seldirs.front(); E; E = E->next()) {
-				fnames.push_back(files->get_item_metadata(E->get()));
-			}
+	if (paths.empty())
+		return Variant();
 
-			return EditorNode::get_singleton()->drag_files_and_dirs(fnames, p_from);
-		}
+	Dictionary drag_data = EditorNode::get_singleton()->drag_files_and_dirs(paths, p_from);
+	if (is_favorite) {
+		drag_data["type"] = "favorite";
 	}
-
-	return Variant();
+	return drag_data;
 }
 
 bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {