Browse Source

Merge pull request #21426 from groud/add_files_to_tree_view

Add files to tree view
Rémi Verschelde 7 years ago
parent
commit
69ee33896a

+ 4 - 4
doc/classes/EditorSettings.xml

@@ -48,11 +48,11 @@
 				Erase a given setting (pass full property path).
 			</description>
 		</method>
-		<method name="get_favorite_dirs" qualifiers="const">
+		<method name="get_favorites" qualifiers="const">
 			<return type="PoolStringArray">
 			</return>
 			<description>
-				Get the list of favorite directories for this project.
+				Get the list of favorite files and directories for this project.
 			</description>
 		</method>
 		<method name="get_project_metadata" qualifiers="const">
@@ -122,13 +122,13 @@
 			<description>
 			</description>
 		</method>
-		<method name="set_favorite_dirs">
+		<method name="set_favorites">
 			<return type="void">
 			</return>
 			<argument index="0" name="dirs" type="PoolStringArray">
 			</argument>
 			<description>
-				Set the list of favorite directories for this project.
+				Set the list of favorite files and directories for this project.
 			</description>
 		</method>
 		<method name="set_initial_value">

+ 16 - 12
editor/dependency_editor.cpp

@@ -504,7 +504,7 @@ void DependencyRemoveDialog::ok_pressed() {
 	}
 
 	if (dirs_to_delete.size() == 0) {
-		//If we only deleted files we should only need to tell the file system about the files we touched.
+		// If we only deleted files we should only need to tell the file system about the files we touched.
 		for (int i = 0; i < files_to_delete.size(); ++i)
 			EditorFileSystem::get_singleton()->update_file(files_to_delete[i]);
 	} else {
@@ -518,21 +518,25 @@ void DependencyRemoveDialog::ok_pressed() {
 			}
 		}
 
-		// if some dirs would be deleted, favorite dirs need to be updated
-		Vector<String> previous_favorite_dirs = EditorSettings::get_singleton()->get_favorite_dirs();
-		Vector<String> new_favorite_dirs;
+		EditorFileSystem::get_singleton()->scan_changes();
+	}
 
-		for (int i = 0; i < previous_favorite_dirs.size(); ++i) {
-			if (dirs_to_delete.find(previous_favorite_dirs[i] + "/") < 0) {
-				new_favorite_dirs.push_back(previous_favorite_dirs[i]);
-			}
-		}
+	// If some files/dirs would be deleted, favorite dirs need to be updated
+	Vector<String> previous_favorites = EditorSettings::get_singleton()->get_favorites();
+	Vector<String> new_favorites;
 
-		if (new_favorite_dirs.size() < previous_favorite_dirs.size()) {
-			EditorSettings::get_singleton()->set_favorite_dirs(new_favorite_dirs);
+	for (int i = 0; i < previous_favorites.size(); ++i) {
+		if (previous_favorites[i].ends_with("/")) {
+			if (dirs_to_delete.find(previous_favorites[i]) < 0)
+				new_favorites.push_back(previous_favorites[i]);
+		} else {
+			if (files_to_delete.find(previous_favorites[i]) < 0)
+				new_favorites.push_back(previous_favorites[i]);
 		}
+	}
 
-		EditorFileSystem::get_singleton()->scan_changes();
+	if (new_favorites.size() < previous_favorites.size()) {
+		EditorSettings::get_singleton()->set_favorites(new_favorites);
 	}
 }
 

+ 10 - 10
editor/editor_file_dialog.cpp

@@ -269,7 +269,7 @@ void EditorFileDialog::_post_popup() {
 	set_process_unhandled_input(true);
 }
 
-void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) {
+void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) {
 
 	if (display_mode == DISPLAY_LIST || p_preview.is_null())
 		return;
@@ -284,7 +284,7 @@ void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture
 	}
 }
 
-void EditorFileDialog::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) {
+void EditorFileDialog::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) {
 
 	set_process(false);
 	preview_waiting = false;
@@ -1115,7 +1115,7 @@ void EditorFileDialog::_update_drives() {
 
 void EditorFileDialog::_favorite_selected(int p_idx) {
 
-	Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+	Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
 	ERR_FAIL_INDEX(p_idx, favorited.size());
 
 	dir_access->change_dir(favorited[p_idx]);
@@ -1130,7 +1130,7 @@ void EditorFileDialog::_favorite_move_up() {
 	int current = favorites->get_current();
 
 	if (current > 0 && current < favorites->get_item_count()) {
-		Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+		Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
 
 		int a_idx = favorited.find(String(favorites->get_item_metadata(current - 1)));
 		int b_idx = favorited.find(String(favorites->get_item_metadata(current)));
@@ -1139,7 +1139,7 @@ void EditorFileDialog::_favorite_move_up() {
 			return;
 		SWAP(favorited.write[a_idx], favorited.write[b_idx]);
 
-		EditorSettings::get_singleton()->set_favorite_dirs(favorited);
+		EditorSettings::get_singleton()->set_favorites(favorited);
 
 		_update_favorites();
 		update_file_list();
@@ -1150,7 +1150,7 @@ void EditorFileDialog::_favorite_move_down() {
 	int current = favorites->get_current();
 
 	if (current >= 0 && current < favorites->get_item_count() - 1) {
-		Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+		Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
 
 		int a_idx = favorited.find(String(favorites->get_item_metadata(current + 1)));
 		int b_idx = favorited.find(String(favorites->get_item_metadata(current)));
@@ -1159,7 +1159,7 @@ void EditorFileDialog::_favorite_move_down() {
 			return;
 		SWAP(favorited.write[a_idx], favorited.write[b_idx]);
 
-		EditorSettings::get_singleton()->set_favorite_dirs(favorited);
+		EditorSettings::get_singleton()->set_favorites(favorited);
 
 		_update_favorites();
 		update_file_list();
@@ -1176,7 +1176,7 @@ void EditorFileDialog::_update_favorites() {
 
 	favorite->set_pressed(false);
 
-	Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+	Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
 	for (int i = 0; i < favorited.size(); i++) {
 		bool cres = favorited[i].begins_with("res://");
 		if (cres != res)
@@ -1206,7 +1206,7 @@ void EditorFileDialog::_favorite_toggled(bool p_toggle) {
 
 	String cd = get_current_dir();
 
-	Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+	Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
 
 	bool found = false;
 	for (int i = 0; i < favorited.size(); i++) {
@@ -1228,7 +1228,7 @@ void EditorFileDialog::_favorite_toggled(bool p_toggle) {
 		favorite->set_pressed(true);
 	}
 
-	EditorSettings::get_singleton()->set_favorite_dirs(favorited);
+	EditorSettings::get_singleton()->set_favorites(favorited);
 
 	_update_favorites();
 }

+ 2 - 2
editor/editor_file_dialog.h

@@ -190,8 +190,8 @@ private:
 	void _save_to_recent();
 	//callback function is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load
 
-	void _thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata);
-	void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata);
+	void _thumbnail_result(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata);
+	void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata);
 	void _request_single_thumbnail(const String &p_path);
 
 	void _unhandled_input(const Ref<InputEvent> &p_event);

+ 11 - 2
editor/editor_node.cpp

@@ -2039,6 +2039,14 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
 			emit_signal("stop_pressed");
 
 		} break;
+
+		case FILE_SHOW_IN_FILESYSTEM: {
+			String path = editor_data.get_scene_path(editor_data.get_edited_scene());
+			if (path != String()) {
+				filesystem_dock->navigate_to_path(path);
+			}
+		} break;
+
 		case RUN_PLAY_SCENE: {
 
 			_save_default_environment();
@@ -3975,6 +3983,7 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
 			scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), FILE_SAVE_ALL_SCENES);
 			if (scene_tabs->get_hovered_tab() >= 0) {
 				scene_tabs_context_menu->add_separator();
+				scene_tabs_context_menu->add_item(TTR("Show in filesystem"), FILE_SHOW_IN_FILESYSTEM);
 				scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
 				scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE);
 			}
@@ -3989,7 +3998,7 @@ void EditorNode::_reposition_active_tab(int idx_to) {
 	_update_scene_tabs();
 }
 
-void EditorNode::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) {
+void EditorNode::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) {
 	int p_tab = p_udata.operator signed int();
 	if (p_preview.is_valid()) {
 		Rect2 rect = scene_tabs->get_tab_rect(p_tab);
@@ -5514,7 +5523,7 @@ EditorNode::EditorNode() {
 	}
 
 	filesystem_dock = memnew(FileSystemDock(this));
-	filesystem_dock->set_file_list_display_mode(int(EditorSettings::get_singleton()->get("docks/filesystem/display_mode")));
+	filesystem_dock->set_file_list_display_mode(int(EditorSettings::get_singleton()->get("docks/filesystem/files_display_mode")));
 
 	if (use_single_dock_column) {
 		dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(filesystem_dock);

+ 2 - 1
editor/editor_node.h

@@ -125,6 +125,7 @@ private:
 		FILE_SAVE_ALL_SCENES,
 		FILE_SAVE_BEFORE_RUN,
 		FILE_SAVE_AND_RUN,
+		FILE_SHOW_IN_FILESYSTEM,
 		FILE_IMPORT_SUBSCENE,
 		FILE_EXPORT_PROJECT,
 		FILE_EXPORT_MESH_LIBRARY,
@@ -535,7 +536,7 @@ private:
 	void _scene_tab_exit();
 	void _scene_tab_input(const Ref<InputEvent> &p_input);
 	void _reposition_active_tab(int idx_to);
-	void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata);
+	void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata);
 	void _scene_tab_script_edited(int p_tab);
 
 	Dictionary _get_main_scene_state();

+ 74 - 35
editor/editor_resource_preview.cpp

@@ -30,11 +30,14 @@
 
 #include "editor_resource_preview.h"
 
+#include "core/method_bind_ext.gen.inc"
+
 #include "core/io/resource_loader.h"
 #include "core/io/resource_saver.h"
 #include "core/message_queue.h"
 #include "core/os/file_access.h"
 #include "core/project_settings.h"
+#include "editor_node.h"
 #include "editor_scale.h"
 #include "editor_settings.h"
 
@@ -46,32 +49,37 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
 	ERR_EXPLAIN("EditorResourcePreviewGenerator::handles needs to be overridden");
 	ERR_FAIL_V(false);
 }
-Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) const {
+
+Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 p_size) const {
 
 	if (get_script_instance() && get_script_instance()->has_method("generate")) {
-		return get_script_instance()->call("generate", p_from);
+		return get_script_instance()->call("generate", p_from, p_size);
 	}
 	ERR_EXPLAIN("EditorResourcePreviewGenerator::generate needs to be overridden");
 	ERR_FAIL_V(Ref<Texture>());
 }
 
-Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) const {
+Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path, const Size2 p_size) const {
 
 	if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) {
-		return get_script_instance()->call("generate_from_path", p_path);
+		return get_script_instance()->call("generate_from_path", p_path, p_size);
 	}
 
 	RES res = ResourceLoader::load(p_path);
 	if (!res.is_valid())
 		return res;
-	return generate(res);
+	return generate(res, p_size);
+}
+
+bool EditorResourcePreviewGenerator::should_generate_small_preview() const {
+	return false;
 }
 
 void EditorResourcePreviewGenerator::_bind_methods() {
 
 	ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "handles", PropertyInfo(Variant::STRING, "type")));
-	ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
-	ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate_from_path", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE)));
+	ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::VECTOR2, "size")));
+	ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture), "generate_from_path", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE), PropertyInfo(Variant::VECTOR2, "size")));
 }
 
 EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() {
@@ -85,7 +93,7 @@ void EditorResourcePreview::_thread_func(void *ud) {
 	erp->_thread();
 }
 
-void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture> &p_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) {
+void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture> &p_texture, const Ref<Texture> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) {
 
 	preview_mutex->lock();
 
@@ -103,6 +111,7 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur
 	Item item;
 	item.order = order++;
 	item.preview = p_texture;
+	item.small_preview = p_small_texture;
 	item.last_hash = hash;
 	item.modified_time = modified_time;
 
@@ -110,11 +119,10 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur
 
 	preview_mutex->unlock();
 
-	MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_ud);
+	MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_small_texture, p_ud);
 }
 
-Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem &p_item, const String &cache_base) {
-
+void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<ImageTexture> &r_small_texture, const QueueItem &p_item, const String &cache_base) {
 	String type;
 
 	if (p_item.resource.is_valid())
@@ -122,40 +130,59 @@ Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem &p_item, c
 	else
 		type = ResourceLoader::get_resource_type(p_item.path);
 
-	if (type == "")
-		return Ref<Texture>(); //could not guess type
+	if (type == "") {
+		r_texture = Ref<ImageTexture>();
+		r_small_texture = Ref<ImageTexture>();
+		return; //could not guess type
+	}
 
-	Ref<Texture> generated;
+	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
+	thumbnail_size *= EDSCALE;
 
-	for (int i = 0; i < preview_generators.size(); i++) {
+	r_texture = Ref<ImageTexture>();
+	r_small_texture = Ref<ImageTexture>();
 
+	for (int i = 0; i < preview_generators.size(); i++) {
 		if (!preview_generators[i]->handles(type))
 			continue;
+
+		Ref<Texture> generated;
 		if (p_item.resource.is_valid()) {
-			generated = preview_generators[i]->generate(p_item.resource);
+			generated = preview_generators[i]->generate(p_item.resource, Vector2(thumbnail_size, thumbnail_size));
 		} else {
-			generated = preview_generators[i]->generate_from_path(p_item.path);
+			generated = preview_generators[i]->generate_from_path(p_item.path, Vector2(thumbnail_size, thumbnail_size));
 		}
+		r_texture = generated;
 
+		if (r_texture.is_valid() && preview_generators[i]->should_generate_small_preview()) {
+			int small_thumbnail_size = EditorNode::get_singleton()->get_theme_base()->get_icon("Object", "EditorIcons")->get_width(); // Kind of a workaround to retreive the default icon size
+			small_thumbnail_size *= EDSCALE;
+
+			Ref<Image> small_image = r_texture->get_data();
+			small_image->resize(small_thumbnail_size, small_thumbnail_size, Image::INTERPOLATE_CUBIC);
+			r_small_texture.instance();
+			r_small_texture->create_from_image(small_image);
+		}
 		break;
 	}
 
 	if (!p_item.resource.is_valid()) {
 		// cache the preview in case it's a resource on disk
-		if (generated.is_valid()) {
-			int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-			thumbnail_size *= EDSCALE;
+		if (r_texture.is_valid()) {
 			//wow it generated a preview... save cache
-			ResourceSaver::save(cache_base + ".png", generated);
+			bool has_small_texture = r_small_texture.is_valid();
+			ResourceSaver::save(cache_base + ".png", r_texture);
+			if (has_small_texture) {
+				ResourceSaver::save(cache_base + "_small.png", r_small_texture);
+			}
 			FileAccess *f = FileAccess::open(cache_base + ".txt", FileAccess::WRITE);
 			f->store_line(itos(thumbnail_size));
+			f->store_line(itos(has_small_texture));
 			f->store_line(itos(FileAccess::get_modified_time(p_item.path)));
 			f->store_line(FileAccess::get_md5(p_item.path));
 			memdelete(f);
 		}
 	}
-
-	return generated;
 }
 
 void EditorResourcePreview::_thread() {
@@ -177,7 +204,7 @@ void EditorResourcePreview::_thread() {
 					path += ":" + itos(cache[item.path].last_hash); //keep last hash (see description of what this is in condition below)
 				}
 
-				_preview_ready(path, cache[item.path].preview, item.id, item.function, item.userdata);
+				_preview_ready(path, cache[item.path].preview, cache[item.path].small_preview, item.id, item.function, item.userdata);
 
 				preview_mutex->unlock();
 			} else {
@@ -185,15 +212,17 @@ void EditorResourcePreview::_thread() {
 				preview_mutex->unlock();
 
 				Ref<ImageTexture> texture;
+				Ref<ImageTexture> small_texture;
 
 				int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
 				thumbnail_size *= EDSCALE;
 
 				if (item.resource.is_valid()) {
 
-					texture = _generate_preview(item, String());
+					_generate_preview(texture, small_texture, item, String());
+
 					//adding hash to the end of path (should be ID:<objid>:<hash>) because of 5 argument limit to call_deferred
-					_preview_ready(item.path + ":" + itos(item.resource->hash_edited_version()), texture, item.id, item.function, item.userdata);
+					_preview_ready(item.path + ":" + itos(item.resource->hash_edited_version()), texture, small_texture, item.id, item.function, item.userdata);
 
 				} else {
 
@@ -207,12 +236,13 @@ void EditorResourcePreview::_thread() {
 					FileAccess *f = FileAccess::open(file, FileAccess::READ);
 					if (!f) {
 
-						//generate
-						texture = _generate_preview(item, cache_base);
+						// No cache found, generate
+						_generate_preview(texture, small_texture, item, cache_base);
 					} else {
 
 						uint64_t modtime = FileAccess::get_modified_time(item.path);
 						int tsize = f->get_line().to_int64();
+						bool has_small_texture = f->get_line().to_int();
 						uint64_t last_modtime = f->get_line().to_int64();
 
 						bool cache_valid = true;
@@ -236,6 +266,7 @@ void EditorResourcePreview::_thread() {
 
 								f = FileAccess::open(file, FileAccess::WRITE);
 								f->store_line(itos(modtime));
+								f->store_line(itos(has_small_texture));
 								f->store_line(md5);
 								memdelete(f);
 							}
@@ -243,12 +274,12 @@ void EditorResourcePreview::_thread() {
 							memdelete(f);
 						}
 
-						//cache_valid = false;
-
 						if (cache_valid) {
 
 							Ref<Image> img;
 							img.instance();
+							Ref<Image> small_img;
+							small_img.instance();
 
 							if (img->load(cache_base + ".png") != OK) {
 								cache_valid = false;
@@ -256,16 +287,24 @@ void EditorResourcePreview::_thread() {
 
 								texture.instance();
 								texture->create_from_image(img, Texture::FLAG_FILTER);
+
+								if (has_small_texture) {
+									if (small_img->load(cache_base + "_small.png") != OK) {
+										cache_valid = false;
+									} else {
+										small_texture.instance();
+										small_texture->create_from_image(small_img, Texture::FLAG_FILTER);
+									}
+								}
 							}
 						}
 
 						if (!cache_valid) {
 
-							texture = _generate_preview(item, cache_base);
+							_generate_preview(texture, small_texture, item, cache_base);
 						}
 					}
-
-					_preview_ready(item.path, texture, item.id, item.function, item.userdata);
+					_preview_ready(item.path, texture, small_texture, item.id, item.function, item.userdata);
 				}
 			}
 
@@ -287,7 +326,7 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
 	if (cache.has(path_id) && cache[path_id].last_hash == p_res->hash_edited_version()) {
 
 		cache[path_id].order = order++;
-		p_receiver->call_deferred(p_receiver_func, path_id, cache[path_id].preview, p_userdata);
+		p_receiver->call_deferred(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata);
 		preview_mutex->unlock();
 		return;
 	}
@@ -312,7 +351,7 @@ void EditorResourcePreview::queue_resource_preview(const String &p_path, Object
 	preview_mutex->lock();
 	if (cache.has(p_path)) {
 		cache[p_path].order = order++;
-		p_receiver->call_deferred(p_receiver_func, p_path, cache[p_path].preview, p_userdata);
+		p_receiver->call_deferred(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata);
 		preview_mutex->unlock();
 		return;
 	}

+ 7 - 4
editor/editor_resource_preview.h

@@ -63,8 +63,10 @@ protected:
 
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
-	virtual Ref<Texture> generate_from_path(const String &p_path) const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
+	virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const;
+
+	virtual bool should_generate_small_preview() const;
 
 	EditorResourcePreviewGenerator();
 };
@@ -92,6 +94,7 @@ class EditorResourcePreview : public Node {
 
 	struct Item {
 		Ref<Texture> preview;
+		Ref<Texture> small_preview;
 		int order;
 		uint32_t last_hash;
 		uint64_t modified_time;
@@ -101,8 +104,8 @@ class EditorResourcePreview : public Node {
 
 	Map<String, Item> cache;
 
-	void _preview_ready(const String &p_str, const Ref<Texture> &p_texture, ObjectID id, const StringName &p_func, const Variant &p_ud);
-	Ref<Texture> _generate_preview(const QueueItem &p_item, const String &cache_base);
+	void _preview_ready(const String &p_str, const Ref<Texture> &p_texture, const Ref<Texture> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud);
+	void _generate_preview(Ref<ImageTexture> &r_texture, Ref<ImageTexture> &r_small_texture, const QueueItem &p_item, const String &cache_base);
 
 	static void _thread_func(void *ud);
 	void _thread();

+ 16 - 16
editor/editor_settings.cpp

@@ -511,17 +511,17 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 	_initial_set("filesystem/file_dialog/show_hidden_files", false);
 	_initial_set("filesystem/file_dialog/display_mode", 0);
 	hints["filesystem/file_dialog/display_mode"] = PropertyInfo(Variant::INT, "filesystem/file_dialog/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List");
+
 	_initial_set("filesystem/file_dialog/thumbnail_size", 64);
 	hints["filesystem/file_dialog/thumbnail_size"] = PropertyInfo(Variant::INT, "filesystem/file_dialog/thumbnail_size", PROPERTY_HINT_RANGE, "32,128,16");
 
-	_initial_set("docks/filesystem/disable_split", false);
-	_initial_set("docks/filesystem/split_mode_minimum_height", 600);
 	_initial_set("docks/filesystem/display_mode", 0);
-	hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List");
+	hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Tree only, Split");
+	_initial_set("docks/filesystem/split_mode_minimum_height", 600);
 	_initial_set("docks/filesystem/thumbnail_size", 64);
 	hints["docks/filesystem/thumbnail_size"] = PropertyInfo(Variant::INT, "docks/filesystem/thumbnail_size", PROPERTY_HINT_RANGE, "32,128,16");
-	_initial_set("docks/filesystem/display_mode", 0);
-	hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List");
+	_initial_set("docks/filesystem/files_display_mode", 0);
+	hints["docks/filesystem/files_display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/files_display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List");
 	_initial_set("docks/filesystem/always_show_folders", true);
 
 	_initial_set("editors/animation/autorename_animation_tracks", true);
@@ -1152,20 +1152,20 @@ Variant EditorSettings::get_project_metadata(const String &p_section, const Stri
 	return cf->get_value(p_section, p_key, p_default);
 }
 
-void EditorSettings::set_favorite_dirs(const Vector<String> &p_favorites_dirs) {
+void EditorSettings::set_favorites(const Vector<String> &p_favorites) {
 
-	favorite_dirs = p_favorites_dirs;
-	FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorite_dirs"), FileAccess::WRITE);
+	favorites = p_favorites;
+	FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::WRITE);
 	if (f) {
-		for (int i = 0; i < favorite_dirs.size(); i++)
-			f->store_line(favorite_dirs[i]);
+		for (int i = 0; i < favorites.size(); i++)
+			f->store_line(favorites[i]);
 		memdelete(f);
 	}
 }
 
-Vector<String> EditorSettings::get_favorite_dirs() const {
+Vector<String> EditorSettings::get_favorites() const {
 
-	return favorite_dirs;
+	return favorites;
 }
 
 void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) {
@@ -1186,11 +1186,11 @@ Vector<String> EditorSettings::get_recent_dirs() const {
 
 void EditorSettings::load_favorites() {
 
-	FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorite_dirs"), FileAccess::READ);
+	FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::READ);
 	if (f) {
 		String line = f->get_line().strip_edges();
 		while (line != "") {
-			favorite_dirs.push_back(line);
+			favorites.push_back(line);
 			line = f->get_line().strip_edges();
 		}
 		memdelete(f);
@@ -1471,8 +1471,8 @@ void EditorSettings::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_project_metadata", "section", "key", "data"), &EditorSettings::set_project_metadata);
 	ClassDB::bind_method(D_METHOD("get_project_metadata", "section", "key", "default"), &EditorSettings::get_project_metadata, DEFVAL(Variant()));
 
-	ClassDB::bind_method(D_METHOD("set_favorite_dirs", "dirs"), &EditorSettings::set_favorite_dirs);
-	ClassDB::bind_method(D_METHOD("get_favorite_dirs"), &EditorSettings::get_favorite_dirs);
+	ClassDB::bind_method(D_METHOD("set_favorites", "dirs"), &EditorSettings::set_favorites);
+	ClassDB::bind_method(D_METHOD("get_favorites"), &EditorSettings::get_favorites);
 	ClassDB::bind_method(D_METHOD("set_recent_dirs", "dirs"), &EditorSettings::set_recent_dirs);
 	ClassDB::bind_method(D_METHOD("get_recent_dirs"), &EditorSettings::get_recent_dirs);
 

+ 3 - 3
editor/editor_settings.h

@@ -107,7 +107,7 @@ private:
 	String config_file_path;
 	String project_config_dir;
 
-	Vector<String> favorite_dirs;
+	Vector<String> favorites;
 	Vector<String> recent_dirs;
 
 	bool save_changed_setting;
@@ -173,8 +173,8 @@ public:
 	void set_project_metadata(const String &p_section, const String &p_key, Variant p_data);
 	Variant get_project_metadata(const String &p_section, const String &p_key, Variant p_default) const;
 
-	void set_favorite_dirs(const Vector<String> &p_favorites_dirs);
-	Vector<String> get_favorite_dirs() const;
+	void set_favorites(const Vector<String> &p_favorites);
+	Vector<String> get_favorites() const;
 	void set_recent_dirs(const Vector<String> &p_recent_dirs);
 	Vector<String> get_recent_dirs() const;
 	void load_favorites();

File diff suppressed because it is too large
+ 455 - 230
editor/filesystem_dock.cpp


+ 53 - 37
editor/filesystem_dock.h

@@ -66,15 +66,22 @@ public:
 	};
 
 private:
+	enum DisplayModeSetting {
+		DISPLAY_MODE_SETTING_TREE_ONLY,
+		DISPLAY_MODE_SETTING_SPLIT,
+	};
+
 	enum DisplayMode {
-		DISPLAY_TREE_ONLY,
-		DISPLAY_FILE_LIST_ONLY,
-		DISPLAY_SPLIT,
+		DISPLAY_MODE_TREE_ONLY,
+		DISPLAY_MODE_FILE_LIST_ONLY,
+		DISPLAY_MODE_SPLIT,
 	};
 
 	enum FileMenu {
 		FILE_OPEN,
 		FILE_INSTANCE,
+		FILE_ADD_FAVORITE,
+		FILE_REMOVE_FAVORITE,
 		FILE_DEPENDENCIES,
 		FILE_OWNERS,
 		FILE_MOVE,
@@ -87,18 +94,9 @@ private:
 		FILE_NEW_SCRIPT,
 		FILE_SHOW_IN_EXPLORER,
 		FILE_COPY_PATH,
-		FILE_NEW_RESOURCE
-	};
-
-	enum FolderMenu {
+		FILE_NEW_RESOURCE,
 		FOLDER_EXPAND_ALL,
 		FOLDER_COLLAPSE_ALL,
-		FOLDER_MOVE,
-		FOLDER_RENAME,
-		FOLDER_REMOVE,
-		FOLDER_NEW_FOLDER,
-		FOLDER_SHOW_IN_EXPLORER,
-		FOLDER_COPY_PATH
 	};
 
 	VBoxContainer *scanning_vb;
@@ -109,24 +107,30 @@ private:
 	EditorNode *editor;
 	Set<String> favorites;
 
+	Button *button_toggle_display_mode;
 	Button *button_reload;
-	Button *button_favorite;
 	Button *button_tree;
 	Button *button_file_list_display_mode;
 	Button *button_hist_next;
 	Button *button_hist_prev;
-	Button *button_show;
 	LineEdit *current_path;
-	LineEdit *search_box;
+	LineEdit *tree_search_box;
+	LineEdit *file_list_search_box;
+
+	String searched_string;
+	Vector<String> uncollapsed_paths_before_search;
+
 	TextureRect *search_icon;
 	HBoxContainer *path_hb;
 
 	FileListDisplayMode file_list_display_mode;
 	DisplayMode display_mode;
+	DisplayModeSetting display_mode_setting;
+	DisplayModeSetting old_display_mode_setting;
 	bool file_list_view;
 
-	PopupMenu *file_options;
-	PopupMenu *folder_options;
+	PopupMenu *file_list_popup;
+	PopupMenu *tree_popup;
 
 	DependencyEditor *deps_editor;
 	DependencyEditorOwners *owners_editor;
@@ -143,6 +147,8 @@ private:
 	ScriptCreateDialog *make_script_dialog_text;
 	CreateDialog *new_resource_dialog;
 
+	bool always_show_folders;
+
 	class FileOrFolder {
 	public:
 		String path;
@@ -169,14 +175,18 @@ private:
 	bool initialized;
 
 	bool updating_tree;
+	int tree_update_id;
 	Tree *tree; //directories
 	ItemList *files;
 	bool import_dock_needs_update;
 
+	Ref<Texture> _get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx);
 	bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths);
-	void _update_tree(bool keep_collapse_state, bool p_uncollapse_root = false);
+	Vector<String> _compute_uncollapsed_paths();
+	void _update_tree(const Vector<String> p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false);
 
-	void _files_gui_input(Ref<InputEvent> p_event);
+	void _file_list_gui_input(Ref<InputEvent> p_event);
+	void _tree_gui_input(Ref<InputEvent> p_event);
 
 	void _update_files(bool p_keep_selection);
 	void _update_file_list_display_mode_button();
@@ -186,12 +196,13 @@ private:
 	void _go_to_tree();
 	void _go_to_file_list();
 
-	void _select_file(int p_idx);
+	void _select_file(const String p_path);
+	void _tree_activate_file();
+	void _file_list_activate_file(int p_idx);
 	void _file_multi_selected(int p_index, bool p_selected);
-	void _update_import_dock();
+	void _tree_multi_selected(Object *p_item, int p_column, bool p_selected);
 
-	void _file_selected();
-	void _dir_selected();
+	void _update_import_dock();
 
 	void _get_all_items_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files, Vector<String> &folders) const;
 	void _find_remaps(EditorFileSystemDirectory *efsd, const Map<String, String> &renames, Vector<String> &to_remaps) const;
@@ -199,8 +210,8 @@ private:
 	void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const;
 	void _update_dependencies_after_move(const Map<String, String> &p_renames) const;
 	void _update_resource_paths_after_move(const Map<String, String> &p_renames) const;
-	void _update_favorite_dirs_list_after_move(const Map<String, String> &p_renames) const;
-	void _update_project_settings_after_move(const Map<String, String> &p_renames) const;
+	void _update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const;
+	void _update_project_settings_after_move(const Map<String, String> &p_folders_renames) const;
 
 	void _resource_created() const;
 	void _make_dir_confirm();
@@ -210,8 +221,9 @@ private:
 	bool _check_existing();
 	void _move_operation_confirm(const String &p_to_path, bool overwrite = false);
 
-	void _file_option(int p_option);
-	void _folder_option(int p_option);
+	void _tree_rmb_option(int p_option);
+	void _file_list_rmb_option(int p_option);
+	void _file_option(int p_option, const Vector<String> p_selected);
 
 	void _fw_history();
 	void _bw_history();
@@ -221,13 +233,14 @@ private:
 	void _set_scanning_mode();
 	void _rescan();
 
-	void _favorites_pressed();
-	void _show_current_scene_file();
-	void _search_changed(const String &p_text);
+	void _toggle_split_mode(bool p_active);
 
-	void _dir_rmb_pressed(const Vector2 &p_pos);
-	void _files_list_rmb_select(int p_item, const Vector2 &p_pos);
-	void _rmb_pressed(const Vector2 &p_pos);
+	void _search_changed(const String &p_text, const Control *p_from);
+
+	void _file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths);
+	void _tree_rmb_select(const Vector2 &p_pos);
+	void _file_list_rmb_select(int p_item, const Vector2 &p_pos);
+	void _file_list_rmb_pressed(const Vector2 &p_pos);
 
 	struct FileInfo {
 		String name;
@@ -238,7 +251,7 @@ private:
 		bool import_broken;
 
 		bool operator<(const FileInfo &fi) const {
-			return name < fi.name;
+			return NaturalNoCaseComparator()(name, fi.name);
 		}
 	};
 
@@ -247,13 +260,16 @@ private:
 	Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
 	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);
-	String _get_drag_target_folder(const Point2 &p_point, Control *p_from) const;
+	void _get_drag_target_folder(String &target, bool &target_favorites, const Point2 &p_point, Control *p_from) const;
 
 	void _preview_invalidated(const String &p_path);
-	void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata);
+	void _file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata);
+	void _tree_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata);
 
 	void _update_display_mode();
 
+	Vector<String> _tree_get_selected(bool remove_self_inclusion = true);
+
 protected:
 	void _notification(int p_what);
 	static void _bind_methods();

+ 74 - 77
editor/plugins/editor_preview_plugins.cpp

@@ -78,7 +78,11 @@ bool EditorTexturePreviewPlugin::handles(const String &p_type) const {
 	return ClassDB::is_parent_class(p_type, "Texture");
 }
 
-Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
+bool EditorTexturePreviewPlugin::should_generate_small_preview() const {
+	return true;
+}
+
+Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
 	Ref<Image> img;
 	Ref<AtlasTexture> atex = p_from;
@@ -100,8 +104,6 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
 	img = img->duplicate();
 	img->clear_mipmaps();
 
-	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-	thumbnail_size *= EDSCALE;
 	if (img->is_compressed()) {
 		if (img->decompress() != OK)
 			return Ref<Texture>();
@@ -109,22 +111,15 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
 		img->convert(Image::FORMAT_RGBA8);
 	}
 
-	int width, height;
-	if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
-
-		width = thumbnail_size;
-		height = img->get_height() * thumbnail_size / img->get_width();
-	} else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
-
-		height = thumbnail_size;
-		width = img->get_width() * thumbnail_size / img->get_height();
-	} else {
-
-		width = img->get_width();
-		height = img->get_height();
+	Vector2 new_size = img->get_size();
+	if (new_size.x > p_size.x) {
+		new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
 	}
+	if (new_size.y > p_size.y) {
+		new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
+	}
+	img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
 
-	img->resize(width, height);
 	post_process_preview(img);
 
 	Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
@@ -143,7 +138,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const {
 	return p_type == "Image";
 }
 
-Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
 	Ref<Image> img = p_from;
 
@@ -153,8 +148,6 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
 	img = img->duplicate();
 	img->clear_mipmaps();
 
-	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-	thumbnail_size *= EDSCALE;
 	if (img->is_compressed()) {
 		if (img->decompress() != OK)
 			return Ref<Image>();
@@ -162,22 +155,15 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
 		img->convert(Image::FORMAT_RGBA8);
 	}
 
-	int width, height;
-	if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
-
-		width = thumbnail_size;
-		height = img->get_height() * thumbnail_size / img->get_width();
-	} else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
-
-		height = thumbnail_size;
-		width = img->get_width() * thumbnail_size / img->get_height();
-	} else {
-
-		width = img->get_width();
-		height = img->get_height();
+	Vector2 new_size = img->get_size();
+	if (new_size.x > p_size.x) {
+		new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+	}
+	if (new_size.y > p_size.y) {
+		new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
 	}
+	img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
 
-	img->resize(width, height);
 	post_process_preview(img);
 
 	Ref<ImageTexture> ptex;
@@ -190,6 +176,9 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
 EditorImagePreviewPlugin::EditorImagePreviewPlugin() {
 }
 
+bool EditorImagePreviewPlugin::should_generate_small_preview() const {
+	return true;
+}
 ////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////
 bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
@@ -197,7 +186,7 @@ bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
 	return ClassDB::is_parent_class(p_type, "BitMap");
 }
 
-Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
 	Ref<BitMap> bm = p_from;
 
@@ -227,8 +216,6 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
 	img.instance();
 	img->create(bm->get_size().width, bm->get_size().height, 0, Image::FORMAT_L8, data);
 
-	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-	thumbnail_size *= EDSCALE;
 	if (img->is_compressed()) {
 		if (img->decompress() != OK)
 			return Ref<Texture>();
@@ -236,22 +223,15 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
 		img->convert(Image::FORMAT_RGBA8);
 	}
 
-	int width, height;
-	if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
-
-		width = thumbnail_size;
-		height = img->get_height() * thumbnail_size / img->get_width();
-	} else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
-
-		height = thumbnail_size;
-		width = img->get_width() * thumbnail_size / img->get_height();
-	} else {
-
-		width = img->get_width();
-		height = img->get_height();
+	Vector2 new_size = img->get_size();
+	if (new_size.x > p_size.x) {
+		new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+	}
+	if (new_size.y > p_size.y) {
+		new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
 	}
+	img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
 
-	img->resize(width, height);
 	post_process_preview(img);
 
 	Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
@@ -260,6 +240,10 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
 	return ptex;
 }
 
+bool EditorBitmapPreviewPlugin::should_generate_small_preview() const {
+	return true;
+}
+
 EditorBitmapPreviewPlugin::EditorBitmapPreviewPlugin() {
 }
 
@@ -269,12 +253,12 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const {
 
 	return ClassDB::is_parent_class(p_type, "PackedScene");
 }
-Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
-	return generate_from_path(p_from->get_path());
+	return generate_from_path(p_from->get_path(), p_size);
 }
 
-Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) const {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const {
 
 	String temp_path = EditorSettings::get_singleton()->get_cache_dir();
 	String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text();
@@ -323,7 +307,11 @@ bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
 	return ClassDB::is_parent_class(p_type, "Material"); //any material
 }
 
-Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const {
+bool EditorMaterialPreviewPlugin::should_generate_small_preview() const {
+	return true;
+}
+
+Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
 	Ref<Material> material = p_from;
 	ERR_FAIL_COND_V(material.is_null(), Ref<Texture>());
@@ -346,10 +334,9 @@ Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const {
 
 		ERR_FAIL_COND_V(!img.is_valid(), Ref<ImageTexture>());
 
-		int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-		thumbnail_size *= EDSCALE;
 		img->convert(Image::FORMAT_RGBA8);
-		img->resize(thumbnail_size, thumbnail_size);
+		int thumbnail_size = MAX(p_size.x, p_size.y);
+		img->resize(thumbnail_size, thumbnail_size, Image::INTERPOLATE_CUBIC);
 		post_process_preview(img);
 		Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
 		ptex->create_from_image(img, 0);
@@ -490,7 +477,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const {
 	return ClassDB::is_parent_class(p_type, "Script");
 }
 
-Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
 	Ref<Script> scr = p_from;
 	if (scr.is_null())
@@ -512,10 +499,9 @@ Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const {
 
 	int line = 0;
 	int col = 0;
-	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-	thumbnail_size *= EDSCALE;
 	Ref<Image> img;
 	img.instance();
+	int thumbnail_size = MAX(p_size.x, p_size.y);
 	img->create(thumbnail_size, thumbnail_size, 0, Image::FORMAT_RGBA8);
 
 	Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color");
@@ -613,16 +599,15 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const {
 	return ClassDB::is_parent_class(p_type, "AudioStream");
 }
 
-Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
 	Ref<AudioStream> stream = p_from;
 	ERR_FAIL_COND_V(stream.is_null(), Ref<Texture>());
 
-	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-	thumbnail_size *= EDSCALE;
 	PoolVector<uint8_t> img;
-	int w = thumbnail_size;
-	int h = thumbnail_size;
+
+	int w = p_size.x;
+	int h = p_size.y;
 	img.resize(w * h * 3);
 
 	PoolVector<uint8_t>::Write imgdata = img.write();
@@ -711,7 +696,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
 	return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh
 }
 
-Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
 	Ref<Mesh> mesh = p_from;
 	ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture>());
@@ -749,10 +734,17 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const {
 
 	VS::get_singleton()->instance_set_base(mesh_instance, RID());
 
-	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-	thumbnail_size *= EDSCALE;
 	img->convert(Image::FORMAT_RGBA8);
-	img->resize(thumbnail_size, thumbnail_size);
+
+	Vector2 new_size = img->get_size();
+	if (new_size.x > p_size.x) {
+		new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+	}
+	if (new_size.y > p_size.y) {
+		new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
+	}
+	img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
+
 	post_process_preview(img);
 
 	Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
@@ -825,15 +817,12 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const {
 	return ClassDB::is_parent_class(p_type, "DynamicFontData");
 }
 
-Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) const {
+Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const {
 
 	Ref<DynamicFontData> SampledFont;
 	SampledFont.instance();
 	SampledFont->set_font_path(p_path);
 
-	int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
-	thumbnail_size *= EDSCALE;
-
 	Ref<DynamicFont> sampled_font;
 	sampled_font.instance();
 	sampled_font->set_size(50);
@@ -864,7 +853,15 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) c
 	ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>());
 
 	img->convert(Image::FORMAT_RGBA8);
-	img->resize(thumbnail_size, thumbnail_size);
+
+	Vector2 new_size = img->get_size();
+	if (new_size.x > p_size.x) {
+		new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+	}
+	if (new_size.y > p_size.y) {
+		new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
+	}
+	img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
 
 	post_process_preview(img);
 
@@ -874,9 +871,9 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) c
 	return ptex;
 }
 
-Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
 
-	return generate_from_path(p_from->get_path());
+	return generate_from_path(p_from->get_path(), p_size);
 }
 
 EditorFontPreviewPlugin::EditorFontPreviewPlugin() {

+ 15 - 11
editor/plugins/editor_preview_plugins.h

@@ -39,7 +39,8 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
 	GDCLASS(EditorTexturePreviewPlugin, EditorResourcePreviewGenerator)
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual bool should_generate_small_preview() const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
 
 	EditorTexturePreviewPlugin();
 };
@@ -48,7 +49,8 @@ class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator {
 	GDCLASS(EditorImagePreviewPlugin, EditorResourcePreviewGenerator)
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual bool should_generate_small_preview() const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
 
 	EditorImagePreviewPlugin();
 };
@@ -57,7 +59,8 @@ class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator {
 	GDCLASS(EditorBitmapPreviewPlugin, EditorResourcePreviewGenerator)
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual bool should_generate_small_preview() const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
 
 	EditorBitmapPreviewPlugin();
 };
@@ -66,8 +69,8 @@ class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator {
 
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
-	virtual Ref<Texture> generate_from_path(const String &p_path) const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
+	virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const;
 
 	EditorPackedScenePreviewPlugin();
 };
@@ -95,7 +98,8 @@ protected:
 
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual bool should_generate_small_preview() const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
 
 	EditorMaterialPreviewPlugin();
 	~EditorMaterialPreviewPlugin();
@@ -104,7 +108,7 @@ public:
 class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator {
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
 
 	EditorScriptPreviewPlugin();
 };
@@ -112,7 +116,7 @@ public:
 class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator {
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
 
 	EditorAudioStreamPreviewPlugin();
 };
@@ -139,7 +143,7 @@ protected:
 
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
 
 	EditorMeshPreviewPlugin();
 	~EditorMeshPreviewPlugin();
@@ -162,8 +166,8 @@ protected:
 
 public:
 	virtual bool handles(const String &p_type) const;
-	virtual Ref<Texture> generate(const RES &p_from) const;
-	virtual Ref<Texture> generate_from_path(const String &p_path) const;
+	virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
+	virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const;
 
 	EditorFontPreviewPlugin();
 	~EditorFontPreviewPlugin();

Some files were not shown because too many files changed in this diff