diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-02-01 09:45:45 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-02-01 09:46:36 -0300 |
commit | 2cd2ca7bbc892eccc635b1c4aea80c956c9b92dc (patch) | |
tree | 0a212bf8786c53ec7b054757071dc2430667d3a1 /tools | |
parent | 36b6ba8e94d9afcb06aa2579bf627651f7ebfea0 (diff) |
Lot of work in new importer, importing textures now works.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/editor/SCsub | 1 | ||||
-rw-r--r-- | tools/editor/editor_file_system.cpp | 517 | ||||
-rw-r--r-- | tools/editor/editor_file_system.h | 53 | ||||
-rw-r--r-- | tools/editor/editor_node.cpp | 440 | ||||
-rw-r--r-- | tools/editor/editor_node.h | 13 | ||||
-rw-r--r-- | tools/editor/filesystem_dock.cpp | 117 | ||||
-rw-r--r-- | tools/editor/filesystem_dock.h | 5 | ||||
-rw-r--r-- | tools/editor/import/resource_import_texture.cpp | 274 | ||||
-rw-r--r-- | tools/editor/import/resource_import_texture.h | 43 | ||||
-rw-r--r-- | tools/editor/import_dock.cpp | 331 | ||||
-rw-r--r-- | tools/editor/import_dock.h | 42 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_texture_import_plugin.h | 5 | ||||
-rw-r--r-- | tools/editor/property_editor.cpp | 40 | ||||
-rw-r--r-- | tools/editor/property_editor.h | 4 |
14 files changed, 1141 insertions, 744 deletions
diff --git a/tools/editor/SCsub b/tools/editor/SCsub index 85d4d11073..a0e6802348 100644 --- a/tools/editor/SCsub +++ b/tools/editor/SCsub @@ -78,3 +78,4 @@ if (env["tools"] == "yes"): SConscript('plugins/SCsub') SConscript('fileserver/SCsub') SConscript('io_plugins/SCsub') + SConscript('import/SCsub') diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index 120cbb9712..f05aaa683c 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -34,8 +34,10 @@ #include "os/file_access.h" #include "editor_node.h" #include "io/resource_saver.h" +#include "io/resource_import.h" #include "editor_settings.h" #include "editor_resource_preview.h" +#include "variant_parser.h" EditorFileSystem *EditorFileSystem::singleton=NULL; @@ -115,75 +117,13 @@ String EditorFileSystemDirectory::get_file_path(int p_idx) const { return "res://"+file; } -bool EditorFileSystemDirectory::get_file_meta(int p_idx) const { - - ERR_FAIL_INDEX_V(p_idx,files.size(),""); - return files[p_idx]->meta.enabled; -} Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const { ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>()); - return files[p_idx]->meta.deps; + return files[p_idx]->deps; } -Vector<String> EditorFileSystemDirectory::get_missing_sources(int p_idx) const { - - ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>()); - Vector<String> missing; - for(int i=0;i<files[p_idx]->meta.sources.size();i++) { - if (files[p_idx]->meta.sources[i].missing) - missing.push_back(files[p_idx]->meta.sources[i].path); - } - - return missing; - - -} -bool EditorFileSystemDirectory::is_missing_sources(int p_idx) const { - - ERR_FAIL_INDEX_V(p_idx,files.size(),false); - for(int i=0;i<files[p_idx]->meta.sources.size();i++) { - if (files[p_idx]->meta.sources[i].missing) - return true; - } - - return false; -} - -bool EditorFileSystemDirectory::have_sources_changed(int p_idx) const { - - ERR_FAIL_INDEX_V(p_idx,files.size(),false); - return files[p_idx]->meta.sources_changed; - -} - -int EditorFileSystemDirectory::get_source_count(int p_idx) const { - - ERR_FAIL_INDEX_V(p_idx,files.size(),0); - if (!files[p_idx]->meta.enabled) - return 0; - return files[p_idx]->meta.sources.size(); -} -String EditorFileSystemDirectory::get_source_file(int p_idx,int p_source) const { - - ERR_FAIL_INDEX_V(p_idx,files.size(),String()); - ERR_FAIL_INDEX_V(p_source,files[p_idx]->meta.sources.size(),String()); - if (!files[p_idx]->meta.enabled) - return String(); - - return files[p_idx]->meta.sources[p_source].path; - -} -bool EditorFileSystemDirectory::is_source_file_missing(int p_idx,int p_source) const { - - ERR_FAIL_INDEX_V(p_idx,files.size(),false); - ERR_FAIL_INDEX_V(p_source,files[p_idx]->meta.sources.size(),false); - if (!files[p_idx]->meta.enabled) - return false; - - return files[p_idx]->meta.sources[p_source].missing; -} StringName EditorFileSystemDirectory::get_file_type(int p_idx) const { @@ -210,7 +150,6 @@ void EditorFileSystemDirectory::_bind_methods() { ClassDB::bind_method(_MD("get_file","idx"),&EditorFileSystemDirectory::get_file); ClassDB::bind_method(_MD("get_file_path","idx"),&EditorFileSystemDirectory::get_file_path); ClassDB::bind_method(_MD("get_file_type","idx"),&EditorFileSystemDirectory::get_file_type); - ClassDB::bind_method(_MD("is_missing_sources","idx"),&EditorFileSystemDirectory::is_missing_sources); ClassDB::bind_method(_MD("get_name"),&EditorFileSystemDirectory::get_name); ClassDB::bind_method(_MD("get_path"),&EditorFileSystemDirectory::get_path); ClassDB::bind_method(_MD("get_parent:EditorFileSystemDirectory"),&EditorFileSystemDirectory::get_parent); @@ -244,42 +183,6 @@ EditorFileSystemDirectory::~EditorFileSystemDirectory() { - -EditorFileSystemDirectory::ImportMeta EditorFileSystem::_get_meta(const String& p_path) { - - return EditorFileSystemDirectory::ImportMeta(); -#if 0 - Ref<ResourceImportMetadata> imd = ResourceLoader::load_import_metadata(p_path); - EditorFileSystemDirectory::ImportMeta m; - if (imd.is_null()) { - m.enabled=false; - m.sources_changed=false; - } else { - m.enabled=true; - m.sources_changed=false; - - for(int i=0;i<imd->get_source_count();i++) { - EditorFileSystemDirectory::ImportMeta::Source s; - s.path=imd->get_source_path(i); - s.md5=imd->get_source_md5(i); - s.modified_time=0; - s.missing=false; - m.sources.push_back(s); - } - m.import_editor=imd->get_editor(); - } - - List<String> deps; - ResourceLoader::get_dependencies(p_path,&deps); - for(List<String>::Element *E=deps.front();E;E=E->next()) { - m.deps.push_back(E->get()); - } - - return m; -#endif -} - - void EditorFileSystem::_scan_filesystem() { ERR_FAIL_COND(!scanning || new_filesystem); @@ -292,7 +195,7 @@ void EditorFileSystem::_scan_filesystem() { String project=GlobalConfig::get_singleton()->get_resource_path(); - String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache"); + String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2"); FileAccess *f =FileAccess::open(fscache,FileAccess::READ); if (f) { @@ -322,30 +225,14 @@ void EditorFileSystem::_scan_filesystem() { FileCache fc; fc.type=split[1]; fc.modification_time=split[2].to_int64(); - String meta = split[3].strip_edges(); - fc.meta.enabled=false; - if (meta.find("<>")!=-1){ - Vector<String> spl = meta.split("<>"); - int sc = spl.size()-1; - if (sc%3==0){ - fc.meta.enabled=true; - fc.meta.import_editor=spl[0]; - fc.meta.sources.resize(sc/3); - for(int i=0;i<fc.meta.sources.size();i++) { - fc.meta.sources[i].path=spl[1+i*3+0]; - fc.meta.sources[i].md5=spl[1+i*3+1]; - fc.meta.sources[i].modified_time=spl[1+i*3+2].to_int64(); - } + fc.import_modification_time = split[3].to_int64(); - } - - } String deps = split[4].strip_edges(); if (deps.length()) { Vector<String> dp = deps.split("<>"); for(int i=0;i<dp.size();i++) { String path=dp[i]; - fc.meta.deps.push_back(path); + fc.deps.push_back(path); } } @@ -393,7 +280,14 @@ void EditorFileSystem::_scan_filesystem() { } +void EditorFileSystem::_save_filesystem_cache() { + String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2"); + FileAccess *f=FileAccess::open(fscache,FileAccess::WRITE); + _save_filesystem_cache(filesystem,f); + f->close(); + memdelete(f); +} void EditorFileSystem::_thread_func(void *_userdata) { @@ -408,6 +302,8 @@ bool EditorFileSystem::_update_scan_actions() { bool fs_changed=false; + Vector<String> reimports; + for (List<ItemAction>::Element *E=scan_actions.front();E;E=E->next()) { ItemAction&ia = E->get(); @@ -472,18 +368,25 @@ bool EditorFileSystem::_update_scan_actions() { //print_line("*ACTION REMOVE FILE: "+ia.file); } break; - case ItemAction::ACTION_FILE_SOURCES_CHANGED: { + case ItemAction::ACTION_FILE_REIMPORT: { + int idx = ia.dir->find_file_index(ia.file); ERR_CONTINUE(idx==-1); String full_path = ia.dir->get_file_path(idx); - sources_changed.push_back(full_path); + reimports.push_back(full_path); + fs_changed=true; } break; } } + + if (reimports.size()) { + reimport_files(reimports); + + } scan_actions.clear(); return fs_changed; @@ -495,9 +398,10 @@ void EditorFileSystem::scan() { if (false /*&& bool(Globals::get_singleton()->get("debug/disable_scan"))*/) return; - if (scanning || scanning_sources|| thread) + if (scanning || scanning_changes|| thread) return; + _update_extensions(); abort_scan=false; if (!use_threads) { @@ -532,43 +436,6 @@ void EditorFileSystem::scan() { } -bool EditorFileSystem::_check_meta_sources(EditorFileSystemDirectory::ImportMeta & p_meta) { - - if (p_meta.enabled) { - - for(int j=0;j<p_meta.sources.size();j++) { - -#if 0 - String src = EditorImportPlugin::expand_source_path(p_meta.sources[j].path); - - if (!FileAccess::exists(src)) { - p_meta.sources[j].missing=true; - continue; - } - - p_meta.sources[j].missing=false; - - uint64_t mt = FileAccess::get_modified_time(src); - - if (mt!=p_meta.sources[j].modified_time) { - //scan - String md5 = FileAccess::get_md5(src); - //print_line("checking: "+src); - //print_line("md5: "+md5); - //print_line("vs: "+p_meta.sources[j].md5); - if (md5!=p_meta.sources[j].md5) { - //really changed - return true; - } - p_meta.sources[j].modified_time=mt; - } -#endif - } - } - - return false; -} - void EditorFileSystem::ScanProgress::update(int p_current,int p_total) const { float ratio = low + ((hi-low)/p_total)*p_current; @@ -586,8 +453,6 @@ EditorFileSystem::ScanProgress EditorFileSystem::ScanProgress::get_sub(int p_cur } - - void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess *da,const ScanProgress& p_progress) { List<String> dirs; @@ -675,9 +540,11 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess for (List<String>::Element*E=files.front();E;E=E->next(),idx++) { + String ext = E->get().get_extension().to_lower(); - if (!valid_extensions.has(ext)) + if (!valid_extensions.has(ext)) { continue; //invalid + } EditorFileSystemDirectory::FileInfo *fi = memnew( EditorFileSystemDirectory::FileInfo ); fi->file=E->get(); @@ -687,32 +554,45 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess FileCache *fc = file_cache.getptr(path); uint64_t mt = FileAccess::get_modified_time(path); - if (fc && fc->modification_time == mt) { + if (import_extensions.has(ext)) { - fi->meta=fc->meta; - fi->type=fc->type; - fi->modified_time=fc->modification_time; - } else { - fi->meta=_get_meta(path); - fi->type=ResourceLoader::get_resource_type(path); - fi->modified_time=mt; + //is imported + uint64_t import_mt=0; + if (FileAccess::exists(path+".import")) { + import_mt=FileAccess::get_modified_time(path+".import"); + } - } + if (fc && fc->modification_time==mt && fc->import_modification_time==import_mt) { + + fi->type=fc->type; + fi->modified_time=fc->modification_time; + fi->import_modified_time=fc->import_modification_time; + + } else { + + print_line("REIMPORT BECAUSE: time changed"); + fi->type=ResourceFormatImporter::get_singleton()->get_resource_type(path); + fi->modified_time=0; + fi->import_modified_time=0; - if (fi->meta.enabled) { - if (_check_meta_sources(fi->meta)) { ItemAction ia; - ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; + ia.action=ItemAction::ACTION_FILE_REIMPORT; ia.dir=p_dir; ia.file=E->get(); scan_actions.push_back(ia); - fi->meta.sources_changed=true; - } else { - fi->meta.sources_changed=false; } - } else { - fi->meta.sources_changed=true; + //not imported, so just update type if changed + if (fc && fc->modification_time == mt) { + + fi->type=fc->type; + fi->modified_time=fc->modification_time; + fi->import_modified_time=0; + } else { + fi->type=ResourceLoader::get_resource_type(path); + fi->modified_time=mt; + fi->import_modified_time=0; + } } p_dir->files.push_back(fi); @@ -722,11 +602,13 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess } + void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const ScanProgress& p_progress) { uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path()); bool updated_dir=false; + String cd = p_dir->get_path(); //print_line("dir: "+p_dir->get_path()+" MODTIME: "+itos(p_dir->modified_time)+" CTIME: "+itos(current_mtime)); @@ -751,7 +633,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S //then scan files and directories and check what's different DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - String cd = p_dir->get_path(); + da->change_dir(cd); da->list_dir_begin(); while (true) { @@ -807,7 +689,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S String path = cd.plus_file(fi->file); fi->modified_time=FileAccess::get_modified_time(path); - fi->meta=_get_meta(path); + fi->import_modified_time=0; fi->type=ResourceLoader::get_resource_type(path); { @@ -817,19 +699,18 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S ia.file=f; ia.new_file=fi; scan_actions.push_back(ia); - } - //take the chance and scan sources - if (_check_meta_sources(fi->meta)) { + } + + if (import_extensions.has(ext)) { + //if it can be imported, and it was added, it needs to be reimported + print_line("REIMPORT: file was not found before, reimport"); ItemAction ia; - ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; + ia.action=ItemAction::ACTION_FILE_REIMPORT; ia.dir=p_dir; ia.file=f; scan_actions.push_back(ia); - fi->meta.sources_changed=true; - } else { - fi->meta.sources_changed=false; } } else { @@ -859,15 +740,39 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S } - if (_check_meta_sources(p_dir->files[i]->meta)) { - ItemAction ia; - ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; - ia.dir=p_dir; - ia.file=p_dir->files[i]->file; - scan_actions.push_back(ia); - p_dir->files[i]->meta.sources_changed=true; - } else { - p_dir->files[i]->meta.sources_changed=false; + if (import_extensions.has(p_dir->files[i]->file.get_extension().to_lower())) { + //check here if file must be imported or not + + String path = cd.plus_file(p_dir->files[i]->file); + + uint64_t mt = FileAccess::get_modified_time(path); + + bool reimport=false; + + if (mt!=p_dir->files[i]->modified_time) { + print_line("REIMPORT: modified time changed, reimport"); + reimport=true; //it was modified, must be reimported. + } else if (!FileAccess::exists(path+".import")) { + print_line("REIMPORT: no .import exists, reimport"); + reimport=true; //no .import file, obviously reimport + } else { + + uint64_t import_mt=FileAccess::get_modified_time(path+".import"); + if (import_mt!=p_dir->files[i]->import_modified_time) { + print_line("REIMPORT: import modified changed, reimport"); + reimport=true; + } + } + + if (reimport) { + + ItemAction ia; + ia.action=ItemAction::ACTION_FILE_REIMPORT; + ia.dir=p_dir; + ia.file=p_dir->files[i]->file; + scan_actions.push_back(ia); + } + } EditorResourcePreview::get_singleton()->check_for_invalidation(p_dir->get_file_path(i)); @@ -900,7 +805,7 @@ void EditorFileSystem::_thread_func_sources(void *_userdata) { sp.low=0; efs->_scan_fs_changes(efs->filesystem,sp); } - efs->scanning_sources_done=true; + efs->scanning_changes_done=true; } void EditorFileSystem::get_changed_sources(List<String> *r_changed) { @@ -908,14 +813,15 @@ void EditorFileSystem::get_changed_sources(List<String> *r_changed) { *r_changed=sources_changed; } -void EditorFileSystem::scan_sources() { +void EditorFileSystem::scan_changes() { - if (scanning || scanning_sources|| thread) + if (scanning || scanning_changes|| thread) return; + _update_extensions(); sources_changed.clear(); - scanning_sources=true; - scanning_sources_done=false; + scanning_changes=true; + scanning_changes_done=false; abort_scan=false; @@ -931,8 +837,8 @@ void EditorFileSystem::scan_sources() { if (_update_scan_actions()) emit_signal("filesystem_changed"); } - scanning_sources=false; - scanning_sources_done=true; + scanning_changes=false; + scanning_changes_done=true; emit_signal("sources_changed",sources_changed.size()>0); } else { @@ -987,11 +893,11 @@ void EditorFileSystem::_notification(int p_what) { if (use_threads) { - if (scanning_sources) { + if (scanning_changes) { - if (scanning_sources_done) { + if (scanning_changes_done) { - scanning_sources=false; + scanning_changes=false; set_process(false); @@ -1053,22 +959,13 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory*p_dir,Fi for(int i=0;i<p_dir->files.size();i++) { - String s=p_dir->files[i]->file+"::"+p_dir->files[i]->type+"::"+String::num(p_dir->files[i]->modified_time)+"::"; - if (p_dir->files[i]->meta.enabled) { - s+=p_dir->files[i]->meta.import_editor; - for(int j=0;j<p_dir->files[i]->meta.sources.size();j++){ - s+="<>"+p_dir->files[i]->meta.sources[j].path; - s+="<>"+p_dir->files[i]->meta.sources[j].md5; - s+="<>"+String::num(p_dir->files[i]->meta.sources[j].modified_time); - - } - } + String s=p_dir->files[i]->file+"::"+p_dir->files[i]->type+"::"+itos(p_dir->files[i]->modified_time)+"::"+itos(p_dir->files[i]->import_modified_time); s+="::"; - for(int j=0;j<p_dir->files[i]->meta.deps.size();j++) { + for(int j=0;j<p_dir->files[i]->deps.size();j++) { if (j>0) s+="<>"; - s+=p_dir->files[i]->meta.deps[j]; + s+=p_dir->files[i]->deps[j]; } p_file->store_line(s); @@ -1261,34 +1158,8 @@ void EditorFileSystem::_resource_saved(const String& p_path){ } -String EditorFileSystem::_find_first_from_source(EditorFileSystemDirectory* p_dir,const String &p_src) const { - - for(int i=0;i<p_dir->files.size();i++) { - for(int j=0;j<p_dir->files[i]->meta.sources.size();j++) { - - if (p_dir->files[i]->meta.sources[j].path==p_src) - return p_dir->get_file_path(i); - } - } - - for(int i=0;i<p_dir->subdirs.size();i++) { - - String ret = _find_first_from_source(p_dir->subdirs[i],p_src); - if (ret.length()>0) - return ret; - } - - return String(); -} -String EditorFileSystem::find_resource_from_source(const String& p_path) const { - - - if (filesystem) - return _find_first_from_source(filesystem,p_path); - return String(); -} void EditorFileSystem::update_file(const String& p_file) { @@ -1339,7 +1210,7 @@ void EditorFileSystem::update_file(const String& p_file) { //print_line("UPDATING: "+p_file); fs->files[cpos]->type=type; fs->files[cpos]->modified_time=FileAccess::get_modified_time(p_file); - fs->files[cpos]->meta=_get_meta(p_file); + fs->files[cpos]->import_modified_time=0; EditorResourcePreview::get_singleton()->call_deferred("check_for_invalidation",p_file); call_deferred("emit_signal","filesystem_changed"); //update later @@ -1347,6 +1218,128 @@ void EditorFileSystem::update_file(const String& p_file) { } +void EditorFileSystem::_reimport_file(const String& p_file) { + + print_line("REIMPORTING: "+p_file); + + EditorFileSystemDirectory *fs=NULL; + int cpos=-1; + bool found = _find_file(p_file,&fs,cpos); + ERR_FAIL_COND(!found); + + //try to obtain existing params + + Map<StringName,Variant> params; + String importer_name; + + if (FileAccess::exists(p_file+".import")) { + + Ref<ConfigFile> cf; + cf.instance(); + Error err = cf->load(p_file+".import"); + if (err==OK) { + List<String> sk; + cf->get_section_keys("params",&sk); + for(List<String>::Element *E=sk.front();E;E=E->next()) { + params[E->get()]=cf->get_value("params",E->get()); + } + importer_name = cf->get_value("remap","importer"); + } + } + + Ref<ResourceImporter> importer; + //find the importer + if (importer_name!="") { + importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name); + } + + if (importer.is_null()) { + //not found by name, find by extension + importer = ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_file.get_extension()); + if (importer.is_null()) { + ERR_PRINT("BUG: File queued for import, but can't be imported!"); + ERR_FAIL(); + + } + } + + //mix with default params, in case a parameter is missing + + List<ResourceImporter::ImportOption> opts; + importer->get_import_options(&opts); + for (List<ResourceImporter::ImportOption>::Element *E=opts.front();E;E=E->next()) { + if (!params.has(E->get().option.name)) { //this one is not present + params[E->get().option.name]=E->get().default_value; + } + } + + //finally, perform import!! + String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file); + + List<String> import_variants; + + Error err = importer->import(p_file,base_path,params,&import_variants); + + ERR_EXPLAIN("Error importing: "+p_file); + ERR_FAIL_COND(err!=OK); + + //as import is complete, save the .import file + + FileAccess *f = FileAccess::open(p_file+".import",FileAccess::WRITE); + ERR_FAIL_COND(!f); + + //write manually, as order matters ([remap] has to go first for performance). + f->store_line("[remap]"); + f->store_line(""); + f->store_line("importer=\""+importer->get_importer_name()+"\""); + f->store_line("type=\""+importer->get_resource_type()+"\""); + + if (import_variants.size()) { + //import with variants + for(List<String>::Element *E=import_variants.front();E;E=E->next()) { + + + f->store_line("path."+E->get()+"=\""+base_path.c_escape()+"."+E->get()+"."+importer->get_save_extension()+"\""); + } + } else { + + f->store_line("path=\""+base_path+"."+importer->get_save_extension()+"\""); + } + + f->store_line(""); + f->store_line("[params]"); + f->store_line(""); + + //store options in provided order, to avoid file changing + for (List<ResourceImporter::ImportOption>::Element *E=opts.front();E;E=E->next()) { + + String base = E->get().option.name; + String value; + VariantWriter::write_to_string(params[base],value); + f->store_line(base+"="+value); + + + } + + memdelete(f); + + //update modified times, to avoid reimport + fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file); + fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file+".import"); +} + +void EditorFileSystem::reimport_files(const Vector<String>& p_files) { + + + EditorProgress pr("reimport",TTR("(Re)Importing Assets"),p_files.size()); + for(int i=0;i<p_files.size();i++) { + pr.step(p_files[i].get_file(),i); + + _reimport_file(p_files[i]); + } + + _save_filesystem_cache(); +} void EditorFileSystem::_bind_methods() { @@ -1355,7 +1348,7 @@ void EditorFileSystem::_bind_methods() { ClassDB::bind_method(_MD("is_scanning"),&EditorFileSystem::is_scanning); ClassDB::bind_method(_MD("get_scanning_progress"),&EditorFileSystem::get_scanning_progress); ClassDB::bind_method(_MD("scan"),&EditorFileSystem::scan); - ClassDB::bind_method(_MD("scan_sources"),&EditorFileSystem::scan_sources); + ClassDB::bind_method(_MD("scan_sources"),&EditorFileSystem::scan_changes); ClassDB::bind_method(_MD("update_file","path"),&EditorFileSystem::update_file); ClassDB::bind_method(_MD("get_filesystem_path:EditorFileSystemDirectory","path"),&EditorFileSystem::get_filesystem_path); ClassDB::bind_method(_MD("get_file_type","path"),&EditorFileSystem::get_file_type); @@ -1365,7 +1358,25 @@ void EditorFileSystem::_bind_methods() { } +void EditorFileSystem::_update_extensions() { + + valid_extensions.clear(); + import_extensions.clear(); + + List<String> extensionsl; + ResourceLoader::get_recognized_extensions_for_type("",&extensionsl); + for(List<String>::Element *E = extensionsl.front();E;E=E->next()) { + + valid_extensions.insert(E->get()); + } + + extensionsl.clear(); + ResourceFormatImporter::get_singleton()->get_recognized_extensions(&extensionsl); + for(List<String>::Element *E = extensionsl.front();E;E=E->next()) { + import_extensions.insert(E->get()); + } +} EditorFileSystem::EditorFileSystem() { @@ -1379,16 +1390,14 @@ EditorFileSystem::EditorFileSystem() { thread_sources=NULL; new_filesystem=NULL; - scanning_sources=false; + scanning_changes=false; ResourceSaver::set_save_callback(_resource_saved); - List<String> extensionsl; - ResourceLoader::get_recognized_extensions_for_type("",&extensionsl); - for(List<String>::Element *E = extensionsl.front();E;E=E->next()) { - - valid_extensions.insert(E->get()); + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (da->change_dir("res://.import")!=OK) { + da->make_dir("res://.import"); } - + memdelete(da); scan_total=0; } diff --git a/tools/editor/editor_file_system.h b/tools/editor/editor_file_system.h index 3a26f46aa9..3ad739ae9d 100644 --- a/tools/editor/editor_file_system.h +++ b/tools/editor/editor_file_system.h @@ -48,30 +48,13 @@ class EditorFileSystemDirectory : public Object { EditorFileSystemDirectory *parent; Vector<EditorFileSystemDirectory*> subdirs; - struct ImportMeta { - - struct Source { - - String path; - String md5; - uint64_t modified_time; - bool missing; - - }; - - Vector<Source> sources; - String import_editor; - Vector<String> deps; - bool enabled; - bool sources_changed; - - }; struct FileInfo { String file; StringName type; uint64_t modified_time; - ImportMeta meta; + uint64_t import_modified_time; + Vector<String> deps; bool verified; //used for checking changes }; @@ -101,14 +84,7 @@ public: String get_file(int p_idx) const; String get_file_path(int p_idx) const; StringName get_file_type(int p_idx) const; - bool get_file_meta(int p_idx) const; - bool is_missing_sources(int p_idx) const; - bool have_sources_changed(int p_idx) const; - Vector<String> get_missing_sources(int p_idx) const; Vector<String> get_file_deps(int p_idx) const; - int get_source_count(int p_idx) const; - String get_source_file(int p_idx,int p_source) const; - bool is_source_file_missing(int p_idx,int p_source) const; EditorFileSystemDirectory *get_parent(); @@ -136,7 +112,7 @@ class EditorFileSystem : public Node { ACTION_DIR_REMOVE, ACTION_FILE_ADD, ACTION_FILE_REMOVE, - ACTION_FILE_SOURCES_CHANGED + ACTION_FILE_REIMPORT }; Action action; @@ -171,7 +147,7 @@ class EditorFileSystem : public Node { String type; uint64_t modification_time; - EditorFileSystemDirectory::ImportMeta meta; + uint64_t import_modification_time; Vector<String> deps; }; @@ -186,25 +162,25 @@ class EditorFileSystem : public Node { ScanProgress get_sub(int p_current,int p_total) const; }; - static EditorFileSystemDirectory::ImportMeta _get_meta(const String& p_path); - - bool _check_meta_sources(EditorFileSystemDirectory::ImportMeta & p_meta); + void _save_filesystem_cache(); void _save_filesystem_cache(EditorFileSystemDirectory *p_dir,FileAccess *p_file); bool _find_file(const String& p_file,EditorFileSystemDirectory ** r_d, int &r_file_pos) const; void _scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress); + int md_count; Set<String> valid_extensions; + Set<String> import_extensions; void _scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess *da,const ScanProgress& p_progress); Thread *thread_sources; - bool scanning_sources; - bool scanning_sources_done; + bool scanning_changes; + bool scanning_changes_done; static void _thread_func_sources(void *_userdata); @@ -214,7 +190,10 @@ class EditorFileSystem : public Node { bool _update_scan_actions(); static void _resource_saved(const String& p_path); - String _find_first_from_source(EditorFileSystemDirectory* p_dir,const String &p_src) const; + + void _update_extensions(); + + void _reimport_file(const String &p_file); protected: @@ -229,14 +208,16 @@ public: bool is_scanning() const; float get_scanning_progress() const; void scan(); - void scan_sources(); + void scan_changes(); void get_changed_sources(List<String> *r_changed); void update_file(const String& p_file); - String find_resource_from_source(const String& p_path) const; + EditorFileSystemDirectory *get_filesystem_path(const String& p_path); String get_file_type(const String& p_file) const; EditorFileSystemDirectory* find_file(const String& p_file,int* r_index) const; + void reimport_files(const Vector<String>& p_files); + EditorFileSystem(); ~EditorFileSystem(); }; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 4bbef01acf..56384fb32d 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -99,7 +99,7 @@ #include "plugins/color_ramp_editor_plugin.h" #include "plugins/collision_shape_2d_editor_plugin.h" #include "plugins/gi_probe_editor_plugin.h" - +#include "import/resource_import_texture.h" // end #include "editor_settings.h" #include "io_plugins/editor_texture_import_plugin.h" @@ -333,21 +333,6 @@ void EditorNode::_notification(int p_what) { _editor_select(EDITOR_3D); - if (defer_load_scene!="") { - - load_scene(defer_load_scene); - defer_load_scene=""; - } - - if (defer_translatable!="") { - - Error ok = save_translatable_strings(defer_translatable); - if (ok!=OK) - OS::get_singleton()->set_exit_code(255); - defer_translatable=""; - get_tree()->quit(); - } - /* if (defer_optimize!="") { Error ok = save_optimized_copy(defer_optimize,defer_optimize_preset); @@ -370,40 +355,7 @@ void EditorNode::_notification(int p_what) { if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) { - /* - List<Ref<Resource> > cached; - ResourceCache::get_cached_resources(&cached); - - bool changes=false; - for(List<Ref<Resource> >::Element *E=cached.front();E;E=E->next()) { - - if (!E->get()->can_reload_from_file()) - continue; - if (E->get()->get_path().find("::")!=-1) - continue; - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - if (mt!=E->get()->get_last_modified_time()) { - changes=true; - break; - } - } - - - - sources_button->get_popup()->set_item_disabled(sources_button->get_popup()->get_item_index(DEPENDENCY_UPDATE_LOCAL),!changes); - if (changes && sources_button->get_popup()->is_item_disabled(sources_button->get_popup()->get_item_index(DEPENDENCY_UPDATE_IMPORTED))) { - sources_button->set_icon(gui_base->get_icon("DependencyLocalChanged","EditorIcons")); - } -*/ - - if (bool(EDITOR_DEF("filesystem/resources/auto_reload_modified_images",true))) { - - _menu_option_confirm(DEPENDENCY_LOAD_CHANGED_IMAGES,true); - } - - waiting_for_sources_changed=true; - EditorFileSystem::get_singleton()->scan_sources(); - + EditorFileSystem::get_singleton()->scan_changes(); } if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) { @@ -435,59 +387,69 @@ void EditorNode::_fs_changed() { export_defer.platform=""; } -} + { -void EditorNode::_sources_changed(bool p_exist) { + //reload changed resources + List<Ref<Resource> > changed; - if (p_exist && bool(EditorSettings::get_singleton()->get("filesystem/import/automatic_reimport_on_sources_changed"))) { - p_exist=false; + List<Ref<Resource> > cached; + ResourceCache::get_cached_resources(&cached); + //this should probably be done in a thread.. + for(List<Ref<Resource> >::Element *E=cached.front();E;E=E->next()) { - List<String> changed_sources; - EditorFileSystem::get_singleton()->get_changed_sources(&changed_sources); + if (!E->get()->editor_can_reload_from_file()) + continue; + if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path()) + continue; + if (!FileAccess::exists(E->get()->get_path())) + continue; + if (E->get()->get_import_path()!=String()) { + //imported resource + uint64_t mt = FileAccess::get_modified_time(E->get()->get_import_path()); - EditorProgress ep("reimport",TTR("Re-Importing"),changed_sources.size()); - int step_idx=0; -#if 0 - for(List<String>::Element *E=changed_sources.front();E;E=E->next()) { + if (mt!=E->get()->get_import_last_modified_time()) { + changed.push_back(E->get()); + } - ep.step(TTR("Importing:")+" "+E->get(),step_idx++); + } else { + uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(E->get()); - ERR_CONTINUE(rimd.is_null()); - String editor = rimd->get_editor(); - if (editor.begins_with("texture_")) { - editor="texture"; //compatibility fix for old versions - } - Ref<EditorImportPlugin> eip = EditorImportExport::get_singleton()->get_import_plugin_by_name(editor); - ERR_CONTINUE(eip.is_null()); - Error err = eip->import(E->get(),rimd); - if (err!=OK) { - EditorNode::add_io_error("Error Re Importing:\n "+E->get()); + if (mt!=E->get()->get_last_modified_time()) { + changed.push_back(E->get()); + } } + } + if (changed.size()) { + EditorProgress ep("reload_res","Reload Modified Resources",changed.size()); + int idx=0; + for(List<Ref<Resource> >::Element *E=changed.front();E;E=E->next()) { + + ep.step(E->get()->get_path(),idx++); + E->get()->reload_from_file(); + } } -#endif - EditorFileSystem::get_singleton()->scan_sources(); - waiting_for_sources_changed=false; - return; + } +} - if (p_exist) { +void EditorNode::_sources_changed(bool p_exist) { - sources_button->set_icon(gui_base->get_icon("DependencyChanged","EditorIcons")); - sources_button->set_disabled(false); + if (waiting_for_first_scan) { - } else { + if (defer_load_scene!="") { - sources_button->set_icon(gui_base->get_icon("DependencyOk","EditorIcons")); - sources_button->set_disabled(true); + print_line("loading scene DEFERED"); + load_scene(defer_load_scene); + defer_load_scene=""; + } + waiting_for_first_scan=false; } - waiting_for_sources_changed=false; } @@ -1206,12 +1168,6 @@ void EditorNode::_dialog_action(String p_file) { get_undo_redo()->clear_history(); } break; - case FILE_DUMP_STRINGS: { - - save_translatable_strings(p_file); - - } break; - case FILE_SAVE_SCENE: case FILE_SAVE_AS_SCENE: { @@ -2203,46 +2159,6 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { _menu_option_confirm(FILE_SAVE_AND_RUN, true); } break; - case FILE_DUMP_STRINGS: { - - Node *scene = editor_data.get_edited_scene_root(); - - if (!scene) { - - current_option=-1; - //confirmation->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text("This operation can't be done without a tree root."); - accept->popup_centered_minsize(); - break; - } - - String cpath; - if (scene->get_filename()!="") { - cpath = scene->get_filename(); - - String fn = cpath.substr(0,cpath.length() - cpath.get_extension().size()); - String ext=cpath.get_extension(); - cpath=fn+".pot"; - - - } else { - current_option=-1; - //confirmation->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("Please save the scene first.")); - accept->popup_centered_minsize(); - break; - - } - - file->set_mode(EditorFileDialog::MODE_SAVE_FILE); - - file->set_current_path(cpath); - file->set_title(TTR("Save Translatable Strings")); - file->popup_centered_ratio(); - - } break; case FILE_SAVE_OPTIMIZED: { #if 0 Node *scene = editor_data.get_edited_scene_root(); @@ -2867,24 +2783,6 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case DEPENDENCY_LOAD_CHANGED_IMAGES: { - List<Ref<Resource> > cached; - ResourceCache::get_cached_resources(&cached); - //this should probably be done in a thread.. - for(List<Ref<Resource> >::Element *E=cached.front();E;E=E->next()) { - - if (!E->get()->editor_can_reload_from_file()) - continue; - if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path()) - continue; - if (!FileAccess::exists(E->get()->get_path())) - continue; - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - if (mt!=E->get()->get_last_modified_time()) { - E->get()->reload_from_file(); - } - - } - } break; case DEPENDENCY_UPDATE_IMPORTED: { @@ -3211,232 +3109,6 @@ void EditorNode::set_edited_scene(Node *p_scene) { } -void EditorNode::_fetch_translatable_strings(const Object *p_object,Set<StringName>& strings) { - - - List<String> tstrings; - p_object->get_translatable_strings(&tstrings); - for(List<String>::Element *E=tstrings.front();E;E=E->next()) - strings.insert(E->get()); - - - - const Node * node = p_object->cast_to<Node>(); - - if (!node) - return; - - Ref<Script> script = node->get_script(); - if (script.is_valid()) - _fetch_translatable_strings(script.ptr(),strings); - - for(int i=0;i<node->get_child_count();i++) { - - Node *c=node->get_child(i); - if (c->get_owner()!=get_edited_scene()) - continue; - - _fetch_translatable_strings(c,strings); - } - -} - - -Error EditorNode::save_translatable_strings(const String& p_to_file) { - - if (!is_inside_tree()) { - defer_translatable=p_to_file; - return OK; - } - - ERR_FAIL_COND_V(!get_edited_scene(),ERR_INVALID_DATA); - - Set<StringName> strings; - _fetch_translatable_strings(get_edited_scene(),strings); - - Error err; - FileAccess *f = FileAccess::open(p_to_file,FileAccess::WRITE,&err); - ERR_FAIL_COND_V(err,err); - - OS::Date date = OS::get_singleton()->get_date(); - OS::Time time = OS::get_singleton()->get_time(); - f->store_line("# Translation Strings Dump."); - f->store_line("# Created By."); - f->store_line("# \t" VERSION_FULL_NAME " (c) 2008-2017 Juan Linietsky, Ariel Manzur."); - f->store_line("# From Scene: "); - f->store_line("# \t"+get_edited_scene()->get_filename()); - f->store_line(""); - f->store_line("msgid \"\""); - f->store_line("msgstr \"\""); - f->store_line("\"Report-Msgid-Bugs-To: <define>\\n\""); - f->store_line("\"POT-Creation-Date: "+itos(date.year)+"-"+itos(date.month)+"-"+itos(date.day)+" "+itos(time.hour)+":"+itos(time.min)+"0000\\n\""); - //f->store_line("\"PO-Revision-Date: 2006-08-30 13:56-0700\\n\""); - //f->store_line("\"Last-Translator: Rubén C. DÃaz Alonso <outime@gmail.com>\\n\""); - f->store_line("\"Language-Team: <define>\\n\""); - f->store_line("\"MIME-Version: 1.0\\n\""); - f->store_line("\"Content-Type: text/plain; charset=UTF-8\\n\""); - f->store_line("\"Content-Transfer-Encoding: 8bit\\n\""); - f->store_line(""); - - for(Set<StringName>::Element *E=strings.front();E;E=E->next()) { - - String s = E->get(); - if (s=="" || s.strip_edges()=="") - continue; - Vector<String> substr = s.split("\n"); - ERR_CONTINUE(substr.size()==0); - - f->store_line(""); - - if (substr.size()==1) { - - f->store_line("msgid \""+substr[0].c_escape()+"\""); - } else { - - f->store_line("msgid \"\""); - for(int i=0;i<substr.size();i++) { - - String s = substr[i]; - if (i!=substr.size()-1) - s+="\n"; - f->store_line("\""+s.c_escape()+"\""); - } - } - - f->store_line("msgstr \"\""); - - } - - - f->close(); - memdelete(f); - - return OK; - -} - -Error EditorNode::save_optimized_copy(const String& p_scene,const String& p_preset) { - -#if 0 - - if (!is_inside_scene()) { - defer_optimize=p_scene; - defer_optimize_preset=p_preset; - return OK; - } - - - if (!get_edited_scene()) { - - get_scene()->quit(); - ERR_EXPLAIN("No scene to optimize (loading failed?)"); - ERR_FAIL_V(ERR_FILE_NOT_FOUND); - } - - - String src_scene=GlobalConfig::get_singleton()->localize_path(get_edited_scene()->get_filename()); - - - String path=p_scene; - print_line("p_path: "+p_scene); - print_line("src_scene: "+p_scene); - - if (path.is_rel_path()) { - print_line("rel path!?"); - path=src_scene.get_base_dir()+"/"+path; - } - path = GlobalConfig::get_singleton()->localize_path(path); - - print_line("path: "+path); - - - String preset = "optimizer_presets/"+p_preset; - if (!GlobalConfig::get_singleton()->has(preset)) { - - //accept->"()->hide(); - accept->get_ok()->set_text("I see.."); - accept->set_text("Optimizer preset not found: "+p_preset); - accept->popup_centered(Size2(300,70)); - ERR_EXPLAIN("Optimizer preset not found: "+p_preset); - ERR_FAIL_V(ERR_INVALID_PARAMETER); - - } - - Dictionary d = GlobalConfig::get_singleton()->get(preset); - - ERR_FAIL_COND_V(!d.has("__type__"),ERR_INVALID_DATA); - String type=d["__type__"]; - - Ref<EditorOptimizedSaver> saver; - - for(int i=0;i<editor_data.get_optimized_saver_count();i++) { - - print_line(type+" vs "+editor_data.get_optimized_saver(i)->get_target_name()); - if (editor_data.get_optimized_saver(i)->get_target_name()==type) { - saver=editor_data.get_optimized_saver(i); - } - } - - ERR_EXPLAIN("Preset '"+p_preset+"' references nonexistent saver: "+type); - ERR_FAIL_COND_V(saver.is_null(),ERR_INVALID_DATA); - - List<Variant> keys; - d.get_key_list(&keys); - - saver->clear(); - - for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - - saver->set(E->get(),d[E->get()]); - } - - uint32_t flags=0; - - /* - if (saver->is_bundle_scenes_enabled()) - flags|=ResourceSaver::FLAG_BUNDLE_INSTANCED_SCENES; - */ - if (saver->is_bundle_resources_enabled()) - flags|=ResourceSaver::FLAG_BUNDLE_RESOURCES; - if (saver->is_remove_editor_data_enabled()) - flags|=ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES; - if (saver->is_big_endian_data_enabled()) - flags|=ResourceSaver::FLAG_SAVE_BIG_ENDIAN; - - String platform=saver->get_target_platform(); - if (platform=="") - platform="all"; - - Ref<PackedScene> sdata = memnew( PackedScene ); - Error err = sdata->pack(get_edited_scene()); - - if (err) { - - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text("I see.."); - accept->set_text("Couldn't save scene. Likely dependencies (instances) couldn't be satisfied."); - accept->popup_centered(Size2(300,70)); - return ERR_INVALID_DATA; - - } - err = ResourceSaver::save(path,sdata,flags); //todo, saverSceneSaver::save(path,get_edited_scene(),flags,saver); - - if (err) { - - //accept->"()->hide(); - accept->get_ok()->set_text("I see.."); - accept->set_text("Error saving optimized scene: "+path); - accept->popup_centered(Size2(300,70)); - - ERR_FAIL_COND_V(err,err); - - } - - project_settings->add_remapped_path(src_scene,path,platform); -#endif - return OK; -} int EditorNode::_get_current_main_editor() { @@ -3834,6 +3506,10 @@ void EditorNode::request_instance_scenes(const Vector<String>& p_files) { scene_tree_dock->instance_scenes(p_files); } +ImportDock *EditorNode::get_import_dock() { + return import_dock; +} + FileSystemDock *EditorNode::get_filesystem_dock() { return filesystem_dock; @@ -5063,7 +4739,6 @@ Variant EditorNode::drag_resource(const Ref<Resource>& p_res,Control* p_from) { TextureRect *drag_preview = memnew( TextureRect ); Label* label=memnew( Label ); - waiting_for_sources_changed=true; // Ref<Texture> preview; { @@ -5440,6 +5115,13 @@ EditorNode::EditorNode() { ResourceLoader::set_timestamp_on_load(true); ResourceSaver::set_timestamp_on_save(true); + + { //register importers at the begining, so dialogs are created with the right extensions + Ref<ResourceImporterTexture> import_texture; + import_texture.instance(); + ResourceFormatImporter::get_singleton()->add_importer(import_texture); + } + _pvrtc_register_compressors(); editor_selection = memnew( EditorSelection ); @@ -5765,7 +5447,6 @@ EditorNode::EditorNode() { pm_export->set_name("Export"); p->add_child(pm_export); p->add_submenu_item(TTR("Convert To.."),"Export"); - pm_export->add_item(TTR("Translatable Strings.."),FILE_DUMP_STRINGS); pm_export->add_separator(); pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_MeshLibrary", TTR("MeshLibrary..")), FILE_EXPORT_MESH_LIBRARY); pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_TileSet", TTR("TileSet..")), FILE_EXPORT_TILESET); @@ -6248,6 +5929,11 @@ EditorNode::EditorNode() { property_editor->set_undo_redo(&editor_data.get_undo_redo()); + import_dock = memnew( ImportDock ); + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(import_dock); + import_dock->set_name(TTR("Import")); + + node_dock = memnew( NodeDock ); //node_dock->set_undoredo(&editor_data.get_undo_redo()); if (use_single_dock_column) { @@ -6584,6 +6270,9 @@ EditorNode::EditorNode() { plugin_init_callbacks[i](); } + + + /*resource_preview->add_preview_generator( Ref<EditorTexturePreviewPlugin>( memnew(EditorTexturePreviewPlugin ))); resource_preview->add_preview_generator( Ref<EditorPackedScenePreviewPlugin>( memnew(EditorPackedScenePreviewPlugin ))); resource_preview->add_preview_generator( Ref<EditorMaterialPreviewPlugin>( memnew(EditorMaterialPreviewPlugin ))); @@ -6730,6 +6419,7 @@ EditorNode::EditorNode() { FileAccess::set_file_close_fail_notify_callback(_file_access_close_error_notify); + waiting_for_first_scan=true; } diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index faf11f5d20..785136a968 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -50,6 +50,7 @@ #include "tools/editor/reparent_dialog.h" #include "tools/editor/connections_dialog.h" #include "tools/editor/node_dock.h" +#include "tools/editor/import_dock.h" #include "tools/editor/settings_config_dialog.h" #include "tools/editor/groups_editor.h" #include "tools/editor/editor_data.h" @@ -134,7 +135,6 @@ private: FILE_EXPORT_MESH_LIBRARY, FILE_EXPORT_TILESET, FILE_SAVE_OPTIMIZED, - FILE_DUMP_STRINGS, FILE_OPEN_RECENT, FILE_OPEN_OLD_SCENE, FILE_QUICK_OPEN_SCENE, @@ -278,6 +278,7 @@ private: //ResourcesDock *resources_dock; PropertyEditor *property_editor; NodeDock *node_dock; + ImportDock *import_dock; VBoxContainer *prop_editor_vb; FileSystemDock *filesystem_dock; EditorRunNative *run_native; @@ -318,9 +319,6 @@ private: //TabContainer *prop_pallete; //TabContainer *top_pallete; String defer_load_scene; - String defer_translatable; - String defer_optimize; - String defer_optimize_preset; String defer_export; String defer_export_platform; bool defer_export_debug; @@ -376,6 +374,7 @@ private: bool unsaved_cache; String open_navigate; bool changing_scene; + bool waiting_for_first_scan; bool waiting_for_sources_changed; @@ -488,7 +487,6 @@ private: static void _load_error_notify(void* p_ud,const String& p_text); bool has_main_screen() const { return true; } - void _fetch_translatable_strings(const Object *p_object,Set<StringName>& strings); bool _find_editing_changed_scene(Node *p_from); @@ -683,7 +681,6 @@ public: Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } Viewport *get_scene_root() { return scene_root; } //root of the scene being edited - Error save_optimized_copy(const String& p_scene,const String& p_preset); void fix_dependencies(const String& p_for_file); void clear_scene() { _cleanup_scene(); } @@ -703,13 +700,12 @@ public: void request_instance_scene(const String &p_path); void request_instance_scenes(const Vector<String>& p_files); FileSystemDock *get_filesystem_dock(); + ImportDock *get_import_dock(); SceneTreeDock *get_scene_tree_dock(); static UndoRedo* get_undo_redo() { return &singleton->editor_data.get_undo_redo(); } EditorSelection *get_editor_selection() { return editor_selection; } - Error save_translatable_strings(const String& p_to_file); - void set_convert_old_scene(bool p_old) { convert_old=p_old; } void notify_child_process_exited(); @@ -784,7 +780,6 @@ public: }; - struct EditorProgress { String task; diff --git a/tools/editor/filesystem_dock.cpp b/tools/editor/filesystem_dock.cpp index 2af5650605..08b8307eb4 100644 --- a/tools/editor/filesystem_dock.cpp +++ b/tools/editor/filesystem_dock.cpp @@ -350,25 +350,9 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path,List<FileInfo>* m FileInfo fi; fi.name=file; fi.type=p_path->get_file_type(i); - fi.path=p_path->get_file_path(i); - if (p_path->get_file_meta(i)) { - if (p_path->is_missing_sources(i)) { - fi.import_status=3; - } else if (p_path->have_sources_changed(i)) { - fi.import_status=2; - } else { - fi.import_status=1; - } - } else { - fi.import_status=0; - } - for(int j=0;j<p_path->get_source_count(i);j++) { - /*String s = EditorImportPlugin::expand_source_path(p_path->get_source_file(i,j)); - if (p_path->is_source_file_missing(i,j)) { - s+=" (Missing)"; - } - fi.sources.push_back(s);*/ - } + fi.path=p_path->get_file_path(i); + fi.import_status=0; + matches->push_back(fi); if (matches->size()>p_max_items) @@ -500,25 +484,7 @@ void FileSystemDock::_update_files(bool p_keep_selection) { fi.name=efd->get_file(i); fi.path=path.plus_file(fi.name); fi.type=efd->get_file_type(i); - if (efd->get_file_meta(i)) { - if (efd->is_missing_sources(i)) { - fi.import_status=3; - } else if (efd->have_sources_changed(i)) { - fi.import_status=2; - } else { - fi.import_status=1; - } - - for(int j=0;j<efd->get_source_count(i);j++) { - /*String s = EditorImportPlugin::expand_source_path(efd->get_source_file(i,j)); - if (efd->is_source_file_missing(i,j)) { - s+=" (Missing)"; - } - fi.sources.push_back(s);*/ - } - } else { - fi.import_status=0; - } + fi.import_status=0; @@ -1538,26 +1504,6 @@ void FileSystemDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) { if (efsd) { - if (!efsd->get_file_meta(pos)) { - all_can_reimport=false; - - - } else { - /* - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(path); - if (rimd.is_valid()) { - - String editor=rimd->get_editor(); - if (editor.begins_with("texture_")) { //compatibility fix for old texture format - editor="texture"; - } - types.insert(editor); - - } else { - all_can_reimport=false; - - }*/ - } } else { all_can_reimport=false; @@ -1642,6 +1588,57 @@ void FileSystemDock::select_file(const String& p_file) { } +void FileSystemDock::_file_multi_selected(int p_index,bool p_selected) { + + + _file_selected(); +} + +void FileSystemDock::_file_selected() { + + //check import + Vector<String> imports; + String import_type; + + for(int i=0;i<files->get_item_count();i++) { + if (!files->is_selected(i)) + continue; + + String p = files->get_item_metadata(i); + if (!FileAccess::exists(p+".import")) { + imports.clear(); + break; + } + Ref<ConfigFile> cf; + cf.instance(); + Error err = cf->load(p+".import"); + if (err!=OK) { + imports.clear(); + break; + } + + String type = cf->get_value("remap","type"); + if (import_type=="") { + import_type=type; + } else if (import_type!=type) { + //all should be the same type + imports.clear(); + break; + } + imports.push_back(p); + } + + + if (imports.size()==0) { + EditorNode::get_singleton()->get_import_dock()->clear(); + } else if (imports.size()==1) { + EditorNode::get_singleton()->get_import_dock()->set_edit_path(imports[0]); + } else { + EditorNode::get_singleton()->get_import_dock()->set_edit_multiple_paths(imports); + } +} + + void FileSystemDock::_bind_methods() { ClassDB::bind_method(_MD("_update_tree"),&FileSystemDock::_update_tree); @@ -1673,6 +1670,8 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(_MD("_files_list_rmb_select"),&FileSystemDock::_files_list_rmb_select); ClassDB::bind_method(_MD("_preview_invalidated"),&FileSystemDock::_preview_invalidated); + ClassDB::bind_method(_MD("_file_selected"),&FileSystemDock::_file_selected); + ClassDB::bind_method(_MD("_file_multi_selected"),&FileSystemDock::_file_multi_selected); ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"))); @@ -1777,6 +1776,8 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { files->set_select_mode(ItemList::SELECT_MULTI); files->set_drag_forwarding(this); files->connect("item_rmb_selected",this,"_files_list_rmb_select"); + files->connect("item_selected",this,"_file_selected"); + files->connect("multi_selected",this,"_file_multi_selected"); files->set_allow_rmb_select(true); file_list_vb = memnew( VBoxContainer ); diff --git a/tools/editor/filesystem_dock.h b/tools/editor/filesystem_dock.h index 73265657e5..224efe0f28 100644 --- a/tools/editor/filesystem_dock.h +++ b/tools/editor/filesystem_dock.h @@ -126,6 +126,11 @@ private: Tree * tree; //directories ItemList *files; + + void _file_multi_selected(int p_index, bool p_selected); + void _file_selected(); + + void _go_to_tree(); void _go_to_dir(const String& p_dir); void _select_file(int p_idx); diff --git a/tools/editor/import/resource_import_texture.cpp b/tools/editor/import/resource_import_texture.cpp new file mode 100644 index 0000000000..41b330e12b --- /dev/null +++ b/tools/editor/import/resource_import_texture.cpp @@ -0,0 +1,274 @@ +#include "resource_import_texture.h" +#include "io/image_loader.h" +#include "scene/resources/texture.h" + +String ResourceImporterTexture::get_importer_name() const { + + return "texture"; +} + +String ResourceImporterTexture::get_visible_name() const{ + + return "Texture"; +} +void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const{ + + ImageLoader::get_recognized_extensions(p_extensions); +} +String ResourceImporterTexture::get_save_extension() const { + return "stex"; +} + +String ResourceImporterTexture::get_resource_type() const{ + + return "StreamTexture"; +} + +bool ResourceImporterTexture::get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const { + + if (p_option=="compress/lossy_quality" && int(p_options["compress/mode"])!=COMPRESS_LOSSY) + return false; + + return true; +} + +int ResourceImporterTexture::get_preset_count() const { + return 4; +} +String ResourceImporterTexture::get_preset_name(int p_idx) const { + + static const char* preset_names[]={ + "2D, Detect 3D", + "2D", + "2D Pixel", + "3D" + }; + + return preset_names[p_idx]; +} + + +void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,int p_preset) const { + + + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"compress/mode",PROPERTY_HINT_ENUM,"Lossless,Lossy,Video RAM,Uncompressed",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),p_preset==PRESET_3D?2:0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"compress/lossy_quality",PROPERTY_HINT_RANGE,"0,1,0.01"),0.7)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"flags/repeat",PROPERTY_HINT_ENUM,"Disabled,Enabled,Mirrored"),p_preset==PRESET_3D?1:0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/filter"),p_preset==PRESET_2D_PIXEL?false:true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/mipmaps"),p_preset==PRESET_3D?true:false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/anisotropic"),false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/srgb",PROPERTY_HINT_ENUM,"Disable,Enable,Detect"),2)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/fix_alpha_border"),p_preset!=PRESET_3D?true:false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/premult_alpha"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"stream"),false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"size_limit",PROPERTY_HINT_RANGE,"0,4096,1"),0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"detect_3d"),p_preset==PRESET_DETECT)); + +} + + +void ResourceImporterTexture::_save_stex(const Image& p_image,const String& p_to_path,int p_compress_mode,float p_lossy_quality,Image::CompressMode p_vram_compression,bool p_mipmaps,int p_texture_flags,bool p_streamable) { + + + FileAccess *f = FileAccess::open(p_to_path,FileAccess::WRITE); + f->store_8('G'); + f->store_8('D'); + f->store_8('S'); + f->store_8('T'); //godot streamable texture + + f->store_32(p_image.get_width()); + f->store_32(p_image.get_height()); + f->store_32(p_texture_flags); + + uint32_t format=0; + + if (p_streamable) + format|=StreamTexture::FORMAT_BIT_STREAM; + if (p_mipmaps || p_compress_mode==COMPRESS_VIDEO_RAM) //VRAM always uses mipmaps + format|=StreamTexture::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit + + switch (p_compress_mode) { + case COMPRESS_LOSSLESS: { + + Image image = p_image; + if (p_mipmaps) { + image.generate_mipmaps(); + } else { + image.clear_mipmaps(); + } + + int mmc = image.get_mipmap_count() + 1; + + format=StreamTexture::FORMAT_BIT_LOSSLESS; + f->store_32(format); + f->store_32(mmc); + + for(int i=0;i<mmc;i++) { + + if (i>0) { + image.shrink_x2(); + } + + PoolVector<uint8_t> data = Image::lossless_packer(image); + int data_len = data.size(); + f->store_32(data_len); + + PoolVector<uint8_t>::Read r= data.read(); + f->store_buffer(r.ptr(),data_len); + + } + + + } break; + case COMPRESS_LOSSY: { + Image image = p_image; + if (p_mipmaps) { + image.generate_mipmaps(); + } else { + image.clear_mipmaps(); + } + + int mmc = image.get_mipmap_count() + 1; + + format=StreamTexture::FORMAT_BIT_LOSSY; + f->store_32(format); + f->store_32(mmc); + + for(int i=0;i<mmc;i++) { + + if (i>0) { + image.shrink_x2(); + } + + PoolVector<uint8_t> data = Image::lossy_packer(image,p_lossy_quality); + int data_len = data.size(); + f->store_32(data_len); + + PoolVector<uint8_t>::Read r = data.read(); + f->store_buffer(r.ptr(),data_len); + + } + } break; + case COMPRESS_VIDEO_RAM: { + + Image image = p_image; + image.generate_mipmaps(); + image.compress(p_vram_compression); + + format |= image.get_format(); + + f->store_32(format); + + PoolVector<uint8_t> data=image.get_data(); + int dl = data.size(); + PoolVector<uint8_t>::Read r = data.read(); + + f->store_buffer(r.ptr(),dl); + + } break; + case COMPRESS_UNCOMPRESSED: { + + Image image = p_image; + if (p_mipmaps) { + image.generate_mipmaps(); + } else { + image.clear_mipmaps(); + } + + format |= image.get_format(); + f->store_32(format); + + PoolVector<uint8_t> data=image.get_data(); + int dl = data.size(); + PoolVector<uint8_t>::Read r = data.read(); + + f->store_buffer(r.ptr(),dl); + + } break; + } + + memdelete(f); +} + +Error ResourceImporterTexture::import(const String& p_source_file,const String& p_save_path,const Map<StringName,Variant>& p_options,List<String>* r_platform_variants) { + + int compress_mode = p_options["compress/mode"]; + float lossy= p_options["compress/lossy_quality"]; + int repeat= p_options["flags/repeat"]; + bool filter= p_options["flags/filter"]; + bool mipmaps= p_options["flags/mipmaps"]; + bool anisotropic= p_options["flags/anisotropic"]; + bool srgb= p_options["flags/srgb"]; + bool fix_alpha_border= p_options["process/fix_alpha_border"]; + bool premult_alpha= p_options["process/premult_alpha"]; + bool stream = p_options["stream"]; + int size_limit = p_options["size_limit"]; + + + Image image; + Error err = ImageLoader::load_image(p_source_file,&image); + if (err!=OK) + return err; + + + int tex_flags=0; + if (repeat>0) + tex_flags|=Texture::FLAG_REPEAT; + if (repeat==2) + tex_flags|=Texture::FLAG_MIRRORED_REPEAT; + if (filter) + tex_flags|=Texture::FLAG_FILTER; + if (mipmaps || compress_mode==COMPRESS_VIDEO_RAM) + tex_flags|=Texture::FLAG_MIPMAPS; + if (anisotropic) + tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; + if (srgb) + tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR; + + if (size_limit >0 && (image.get_width()>size_limit || image.get_height()>size_limit )) { + //limit size + if (image.get_width() >= image.get_height()) { + int new_width = size_limit; + int new_height = image.get_height() * new_width / image.get_width(); + + image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC); + } else { + + int new_height = size_limit; + int new_width = image.get_width() * new_height / image.get_height(); + + image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC); + } + } + + if (fix_alpha_border) { + image.fix_alpha_edges(); + } + + if (premult_alpha) { + image.premultiply_alpha(); + } + + + if (compress_mode==COMPRESS_VIDEO_RAM) { + //must import in all formats + //Android, GLES 2.x + _save_stex(image,p_save_path+".etc.stex",compress_mode,lossy,Image::COMPRESS_ETC,mipmaps,tex_flags,stream); + r_platform_variants->push_back("etc"); + //_save_stex(image,p_save_path+".etc2.stex",compress_mode,lossy,Image::COMPRESS_ETC2,mipmaps,tex_flags,stream); + //r_platform_variants->push_back("etc2"); + _save_stex(image,p_save_path+".s3tc.stex",compress_mode,lossy,Image::COMPRESS_S3TC,mipmaps,tex_flags,stream); + r_platform_variants->push_back("s3tc"); + + } else { + //import normally + _save_stex(image,p_save_path+".stex",compress_mode,lossy,Image::COMPRESS_16BIT /*this is ignored */,mipmaps,tex_flags,stream); + } + + return OK; +} + +ResourceImporterTexture::ResourceImporterTexture() +{ + +} diff --git a/tools/editor/import/resource_import_texture.h b/tools/editor/import/resource_import_texture.h new file mode 100644 index 0000000000..ac0a3f0575 --- /dev/null +++ b/tools/editor/import/resource_import_texture.h @@ -0,0 +1,43 @@ +#ifndef RESOURCEIMPORTTEXTURE_H +#define RESOURCEIMPORTTEXTURE_H + +#include "io/resource_import.h" + +class ResourceImporterTexture : public ResourceImporter { + GDCLASS(ResourceImporterTexture,ResourceImporter) +public: + virtual String get_importer_name() const; + virtual String get_visible_name() const; + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual String get_save_extension() const; + virtual String get_resource_type() const; + + + enum Preset { + PRESET_DETECT, + PRESET_2D, + PRESET_2D_PIXEL, + PRESET_3D, + }; + + enum CompressMode { + COMPRESS_LOSSLESS, + COMPRESS_LOSSY, + COMPRESS_VIDEO_RAM, + COMPRESS_UNCOMPRESSED + }; + + virtual int get_preset_count() const; + virtual String get_preset_name(int p_idx) const; + + virtual void get_import_options(List<ImportOption> *r_options,int p_preset=0) const; + virtual bool get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const; + + void _save_stex(const Image& p_image, const String& p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable); + + virtual Error import(const String& p_source_file,const String& p_save_path,const Map<StringName,Variant>& p_options,List<String>* r_platform_variants); + + ResourceImporterTexture(); +}; + +#endif // RESOURCEIMPORTTEXTURE_H diff --git a/tools/editor/import_dock.cpp b/tools/editor/import_dock.cpp new file mode 100644 index 0000000000..b1bd698239 --- /dev/null +++ b/tools/editor/import_dock.cpp @@ -0,0 +1,331 @@ +#include "import_dock.h" + +class ImportDockParameters : public Object { + GDCLASS(ImportDockParameters,Object) +public: + Map<StringName,Variant> values; + List<PropertyInfo> properties; + Ref<ResourceImporter> importer; + Vector<String> paths; + + + bool _set(const StringName& p_name, const Variant& p_value) { + + if (values.has(p_name)) { + values[p_name]=p_value; + return true; + } + + return false; + } + + bool _get(const StringName& p_name,Variant &r_ret) const { + + if (values.has(p_name)) { + r_ret=values[p_name]; + return true; + } + + return false; + + } + void _get_property_list( List<PropertyInfo> *p_list) const { + + for (const List<PropertyInfo>::Element *E=properties.front();E;E=E->next()) { + if (!importer->get_option_visibility(E->get().name,values)) + continue; + p_list->push_back(E->get()); + } + } + + void update() { + _change_notify(); + } +}; + +void ImportDock::set_edit_path(const String& p_path) { + + Ref<ConfigFile> config; + config.instance(); + Error err = config->load(p_path+".import"); + if (err!=OK) { + clear(); + return; + } + + + params->importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(config->get_value("remap","importer")); + if (params->importer.is_null()) { + clear(); + return; + } + + List<ResourceImporter::ImportOption> options; + params->importer->get_import_options(&options); + + params->properties.clear(); + params->values.clear(); + + for (List<ResourceImporter::ImportOption>::Element *E=options.front();E;E=E->next()) { + + params->properties.push_back(E->get().option); + if (config->has_section_key("params",E->get().option.name)) { + params->values[E->get().option.name]=config->get_value("params",E->get().option.name); + } else { + params->values[E->get().option.name]=E->get().default_value; + } + } + + params->update(); + + List<Ref<ResourceImporter> > importers; + ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_path.get_extension(),&importers); + List<Pair<String,String> > importer_names; + + for (List<Ref<ResourceImporter> > ::Element *E=importers.front();E;E=E->next()) { + importer_names.push_back(Pair<String,String>(E->get()->get_visible_name(),E->get()->get_importer_name())); + } + + importer_names.sort_custom<PairSort<String,String> >(); + + import_as->clear(); + + for (List<Pair<String,String> >::Element *E=importer_names.front();E;E=E->next()) { + import_as->add_item(E->get().first); + import_as->set_item_metadata(import_as->get_item_count()-1,E->get().second); + if (E->get().second==params->importer->get_importer_name()) { + import_as->select(import_as->get_item_count()-1); + } + } + + preset->get_popup()->clear(); + + if (params->importer->get_preset_count()==0) { + preset->get_popup()->add_item(TTR("Default")); + } else { + for (int i=0;i<params->importer->get_preset_count();i++) { + preset->get_popup()->add_item(params->importer->get_preset_name(i)); + } + } + + params->paths.clear(); + params->paths.push_back(p_path); + import->set_disabled(false); + import_as->set_disabled(false); + + imported->set_text(p_path.get_file()); +} + +void ImportDock::set_edit_multiple_paths(const Vector<String>& p_paths) { + + clear(); + + //use the value that is repeated the mot + Map<String,Dictionary> value_frequency; + + for(int i=0;i<p_paths.size();i++) { + + Ref<ConfigFile> config; + config.instance(); + Error err = config->load(p_paths[i]+".import"); + ERR_CONTINUE(err!=OK); + + if (i==0) { + params->importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(config->get_value("remap","importer")); + if (params->importer.is_null()) { + clear(); + return; + } + } + + List<String> keys; + config->get_section_keys("params",&keys); + + + for (List<String>::Element *E=keys.front();E;E=E->next()) { + + if (!value_frequency.has(E->get())) { + value_frequency[E->get()]=Dictionary(); + } + + Variant value = config->get_value("params",E->get()); + + if (value_frequency[E->get()].has(value)) { + value_frequency[E->get()][value]=int(value_frequency[E->get()][value])+1; + } else { + value_frequency[E->get()][value]=1; + } + } + + } + + ERR_FAIL_COND(params->importer.is_null()); + + List<ResourceImporter::ImportOption> options; + params->importer->get_import_options(&options); + + params->properties.clear(); + params->values.clear(); + + for (List<ResourceImporter::ImportOption>::Element *E=options.front();E;E=E->next()) { + + params->properties.push_back(E->get().option); + + if (value_frequency.has(E->get().option.name)) { + + Dictionary d = value_frequency[E->get().option.name]; + int freq=0; + List<Variant> v; + d.get_key_list(&v); + Variant value; + for (List<Variant>::Element *F=v.front();F;F=F->next()) { + int f = d[F->get()]; + if (f>freq) { + value=F->get(); + } + } + + params->values[E->get().option.name]=value; + } else { + params->values[E->get().option.name]=E->get().default_value; + } + } + + params->update(); + + List<Ref<ResourceImporter> > importers; + ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_paths[0].get_extension(),&importers); + List<Pair<String,String> > importer_names; + + for (List<Ref<ResourceImporter> > ::Element *E=importers.front();E;E=E->next()) { + importer_names.push_back(Pair<String,String>(E->get()->get_visible_name(),E->get()->get_importer_name())); + } + + importer_names.sort_custom<PairSort<String,String> >(); + + import_as->clear(); + + for (List<Pair<String,String> >::Element *E=importer_names.front();E;E=E->next()) { + import_as->add_item(E->get().first); + import_as->set_item_metadata(import_as->get_item_count()-1,E->get().second); + if (E->get().second==params->importer->get_importer_name()) { + import_as->select(import_as->get_item_count()-1); + } + } + + preset->get_popup()->clear(); + + if (params->importer->get_preset_count()==0) { + preset->get_popup()->add_item(TTR("Default")); + } else { + for (int i=0;i<params->importer->get_preset_count();i++) { + preset->get_popup()->add_item(params->importer->get_preset_name(i)); + } + } + + params->paths=p_paths; + import->set_disabled(false); + import_as->set_disabled(false); + + imported->set_text(itos(p_paths.size())+TTR(" Files")); +} + +void ImportDock::_preset_selected(int p_idx) { + + print_line("preset selected? "+p_idx); + List<ResourceImporter::ImportOption> options; + + params->importer->get_import_options(&options,p_idx); + + for (List<ResourceImporter::ImportOption>::Element *E=options.front();E;E=E->next()) { + + params->values[E->get().option.name]=E->get().default_value; + } + + params->update(); + +} + + +void ImportDock::clear() { + + imported->set_text(""); + import->set_disabled(true); + import_as->clear(); + import_as->set_disabled(true); + params->values.clear(); + params->properties.clear(); + params->update(); + preset->get_popup()->clear(); + +} + +void ImportDock::_reimport() { + + for(int i=0;i<params->paths.size();i++) { + + Ref<ConfigFile> config; + config.instance(); + Error err = config->load(params->paths[i]+".import"); + ERR_CONTINUE(err!=OK); + + config->erase_section("params"); + + for (List<PropertyInfo>::Element *E=params->properties.front();E;E=E->next()) { + config->set_value("params",E->get().name,params->values[E->get().name]); + } + + config->save(params->paths[i]+".import"); + } + + EditorFileSystem::get_singleton()->reimport_files(params->paths); + EditorFileSystem::get_singleton()->emit_signal("filesystem_changed"); //it changed, so force emitting the signal + +} + +void ImportDock::_bind_methods() { + + ClassDB::bind_method(_MD("_reimport"),&ImportDock::_reimport); + ClassDB::bind_method(_MD("_preset_selected"),&ImportDock::_preset_selected); +} + +ImportDock::ImportDock() { + + + imported = memnew( LineEdit ); + imported->set_editable(false); + add_child(imported); + HBoxContainer *hb = memnew(HBoxContainer); + add_margin_child(TTR("Import As:"),hb); + import_as = memnew( OptionButton ); + hb->add_child(import_as); + import_as->set_h_size_flags(SIZE_EXPAND_FILL); + preset = memnew( MenuButton ); + preset->set_text(TTR("Preset..")); + preset->get_popup()->connect("index_pressed",this,"_preset_selected"); + hb->add_child(preset); + + import_opts = memnew( PropertyEditor ); + add_child(import_opts); + import_opts->set_v_size_flags(SIZE_EXPAND_FILL); + import_opts->hide_top_label(); + import_opts->set_hide_script(true); + + hb = memnew( HBoxContainer ); + add_child(hb); + import = memnew( Button ); + import->set_text(TTR("Reimport")); + import->connect("pressed",this,"_reimport"); + hb->add_spacer(); + hb->add_child(import); + hb->add_spacer(); + + params = memnew( ImportDockParameters ); + import_opts->edit(params); + +} + +ImportDock::~ImportDock() { + + memdelete(params); +} diff --git a/tools/editor/import_dock.h b/tools/editor/import_dock.h new file mode 100644 index 0000000000..bddf5480b8 --- /dev/null +++ b/tools/editor/import_dock.h @@ -0,0 +1,42 @@ +#ifndef IMPORTDOCK_H +#define IMPORTDOCK_H + +#include "io/resource_import.h" +#include "editor_file_system.h" +#include "scene/gui/box_container.h" +#include "scene/gui/option_button.h" +#include "scene/gui/popup_menu.h" +#include "property_editor.h" + +class ImportDockParameters; +class ImportDock : public VBoxContainer { + GDCLASS(ImportDock,VBoxContainer) + + LineEdit *imported; + OptionButton *import_as; + MenuButton *preset; + PropertyEditor *import_opts; + + List<PropertyInfo> properties; + Map<StringName,Variant> property_values; + + Button *import; + + ImportDockParameters *params; + + void _preset_selected(int p_idx); + + void _reimport(); +protected: + static void _bind_methods(); +public: + + void set_edit_path(const String& p_path); + void set_edit_multiple_paths(const Vector<String>& p_paths); + void clear(); + + ImportDock(); + ~ImportDock(); +}; + +#endif // IMPORTDOCK_H diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index 08e0db5d6e..ce15df0f18 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -29,6 +29,11 @@ #ifndef EDITOR_TEXTURE_IMPORT_PLUGIN_H #define EDITOR_TEXTURE_IMPORT_PLUGIN_H + + + + + #if 0 #include "tools/editor/editor_import_export.h" #include "scene/gui/dialogs.h" diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 19720dfd65..8e3791eb8d 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -118,7 +118,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { Set<String> valid_extensions; for (List<String>::Element *E=extensions.front();E;E=E->next()) { - + print_line("found: "+E->get()); valid_extensions.insert(E->get()); } @@ -3140,6 +3140,10 @@ void PropertyEditor::update_tree() { } else if ( ! (p.usage&PROPERTY_USAGE_EDITOR ) ) continue; + + if (hide_script && p.name=="script/script") + continue; + String basename=p.name; if (group!="") { if (group_base!="") { @@ -3886,7 +3890,7 @@ void PropertyEditor::_item_selected() { } -void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { +void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value, bool p_refresh_all) { if (autoclear) { TreeItem *item = tree->get_selected(); @@ -3899,7 +3903,11 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { if (!undo_redo || obj->cast_to<MultiNodeEdit>() || obj->cast_to<ArrayPropertyEdit>()) { //kind of hacky obj->set(p_name,p_value); - _changed_callbacks(obj,p_name); + if (p_refresh_all) + _changed_callbacks(obj,""); + else + _changed_callbacks(obj,p_name); + emit_signal(_prop_edited,p_name); @@ -3909,9 +3917,14 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { undo_redo->add_do_property(obj,p_name,p_value); undo_redo->add_undo_property(obj,p_name,obj->get(p_name)); + if (p_refresh_all) { + undo_redo->add_do_method(this,"_changed_callback",obj,""); + undo_redo->add_undo_method(this,"_changed_callback",obj,""); + } else { - undo_redo->add_do_method(this,"_changed_callback",obj,p_name); - undo_redo->add_undo_method(this,"_changed_callback",obj,p_name); + undo_redo->add_do_method(this,"_changed_callback",obj,p_name); + undo_redo->add_undo_method(this,"_changed_callback",obj,p_name); + } Resource *r = obj->cast_to<Resource>(); if (r) { @@ -3973,6 +3986,9 @@ void PropertyEditor::_item_edited() { int type=d["type"]; int hint= d["hint"]; + int usage = d["usage"]; + bool refresh_all = usage&PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED; + String hint_text=d["hint_text"]; switch(type) { @@ -3981,7 +3997,7 @@ void PropertyEditor::_item_edited() { } break; case Variant::BOOL: { - _edit_set(name,item->is_checked(1)); + _edit_set(name,item->is_checked(1),refresh_all); item->set_tooltip(1, item->is_checked(1) ? "True" : "False"); } break; case Variant::INT: @@ -3995,9 +4011,9 @@ void PropertyEditor::_item_edited() { break; if (type==Variant::INT) - _edit_set(name,int(item->get_range(1))); + _edit_set(name,int(item->get_range(1)),refresh_all); else - _edit_set(name,item->get_range(1)); + _edit_set(name,item->get_range(1),refresh_all); } break; case Variant::STRING: { @@ -4012,9 +4028,9 @@ void PropertyEditor::_item_edited() { txt=strings[idx]; } - _edit_set(name,txt); + _edit_set(name,txt,refresh_all); } else { - _edit_set(name,item->get_text(1)); + _edit_set(name,item->get_text(1),refresh_all); } } break; // math types @@ -4045,7 +4061,7 @@ void PropertyEditor::_item_edited() { } break; case Variant::NODE_PATH: { - _edit_set(name, NodePath(item->get_text(1))); + _edit_set(name, NodePath(item->get_text(1)),refresh_all); } break; @@ -4476,6 +4492,8 @@ PropertyEditor::PropertyEditor() { _prop_edited="property_edited"; + hide_script=false; + undo_redo=NULL; obj=NULL; search_box=NULL; diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index 3f8d071a01..969340d5a2 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -192,6 +192,7 @@ class PropertyEditor : public Control { bool use_doc_hints; bool use_filter; bool subsection_selectable; + bool hide_script; HashMap<String,String> pending; String selected_property; @@ -224,7 +225,7 @@ class PropertyEditor : public Control { void _node_removed(Node *p_node); friend class ProjectExportDialog; - void _edit_set(const String& p_name, const Variant& p_value); + void _edit_set(const String& p_name, const Variant& p_value,bool p_refresh_all=false); void _draw_flags(Object *ti,const Rect2& p_rect); bool _might_be_in_instance(); @@ -276,6 +277,7 @@ public: void set_show_categories(bool p_show); void set_use_doc_hints(bool p_enable) { use_doc_hints=p_enable; } + void set_hide_script(bool p_hide) { hide_script=p_hide; } void set_use_filter(bool p_use); void register_text_enter(Node *p_line_edit); |