diff options
Diffstat (limited to 'tools/editor')
32 files changed, 1023 insertions, 612 deletions
diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp index 151208ace0..8bce415fb8 100644 --- a/tools/editor/create_dialog.cpp +++ b/tools/editor/create_dialog.cpp @@ -255,6 +255,15 @@ void CreateDialog::set_base_type(const String& p_base) { _update_search(); } +String CreateDialog::get_selected_type() { + + TreeItem *selected = search_options->get_selected(); + if (selected) + return selected->get_text(0); + else + return String(); +} + Object *CreateDialog::instance_selected() { TreeItem *selected = search_options->get_selected(); diff --git a/tools/editor/create_dialog.h b/tools/editor/create_dialog.h index a46ff5ae06..8957479beb 100644 --- a/tools/editor/create_dialog.h +++ b/tools/editor/create_dialog.h @@ -66,6 +66,7 @@ protected: public: Object *instance_selected(); + String get_selected_type(); void set_base_type(const String& p_base); String get_base_type() const; diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index 1062417fec..3fd5f7e444 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -149,6 +149,41 @@ bool EditorFileSystemDirectory::is_missing_sources(int p_idx) const { 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; + +} +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 { ERR_FAIL_INDEX_V(p_idx,files.size(),""); @@ -210,8 +245,11 @@ EditorFileSystemDirectory::ImportMeta EditorFileSystem::_get_meta(const String& 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); @@ -649,7 +687,13 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess 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; } p_dir->files.push_back(fi); @@ -764,6 +808,9 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S ia.dir=p_dir; ia.file=f; scan_actions.push_back(ia); + fi->meta.sources_changed=true; + } else { + fi->meta.sources_changed=false; } } else { @@ -800,6 +847,9 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S 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; } } @@ -1113,6 +1163,25 @@ String EditorFileSystem::get_file_type(const String& p_file) const { } +EditorFileSystemDirectory* EditorFileSystem::find_file(const String& p_file,int* r_index) const { + + if (!filesystem || scanning) + return NULL; + + EditorFileSystemDirectory *fs=NULL; + int cpos=-1; + if (!_find_file(p_file,&fs,cpos)) { + + return NULL; + } + + + if (r_index) + *r_index=cpos; + + return fs; +} + EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) { diff --git a/tools/editor/editor_file_system.h b/tools/editor/editor_file_system.h index 254dd68c14..b96e947569 100644 --- a/tools/editor/editor_file_system.h +++ b/tools/editor/editor_file_system.h @@ -55,7 +55,7 @@ class EditorFileSystemDirectory : public Object { String path; String md5; uint64_t modified_time; - bool missing; + bool missing; }; @@ -63,6 +63,7 @@ class EditorFileSystemDirectory : public Object { String import_editor; Vector<String> deps; bool enabled; + bool sources_changed; }; @@ -102,8 +103,12 @@ public: 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(); @@ -230,6 +235,7 @@ public: String find_resource_from_source(const String& p_path) const; EditorFileSystemDirectory *get_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; EditorFileSystem(); ~EditorFileSystem(); }; diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp index 25dced4745..ac7ea514d7 100644 --- a/tools/editor/editor_import_export.cpp +++ b/tools/editor/editor_import_export.cpp @@ -85,6 +85,9 @@ void EditorImportPlugin::_bind_methods() { ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("import_dialog",PropertyInfo(Variant::STRING,"from"))); ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetadata"))); ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"))); + ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("import_from_drop",PropertyInfo(Variant::STRING_ARRAY,"files"),PropertyInfo(Variant::STRING,"dest_path"))); + ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("reimport_multiple_files",PropertyInfo(Variant::STRING_ARRAY,"files"))); + ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"can_reimport_multiple_files")); // BIND_VMETHOD( mi ); } @@ -130,13 +133,37 @@ Error EditorImportPlugin::import(const String& p_path, const Ref<ResourceImportM Vector<uint8_t> EditorImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) { - if (get_script_instance() && get_script_instance()->has_method("_custom_export")) { - get_script_instance()->call("_custom_export",p_path,p_platform); + if (get_script_instance() && get_script_instance()->has_method("custom_export")) { + get_script_instance()->call("custom_export",p_path,p_platform); } return Vector<uint8_t>(); } +bool EditorImportPlugin::can_reimport_multiple_files() const { + + if (get_script_instance() && get_script_instance()->has_method("can_reimport_multiple_files")) { + return get_script_instance()->call("can_reimport_multiple_files"); + } + + return false; +} +void EditorImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (get_script_instance() && get_script_instance()->has_method("reimport_multiple_files")) { + get_script_instance()->call("reimport_multiple_files",p_list); + } + +} + +void EditorImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + if (get_script_instance() && get_script_instance()->has_method("import_from_drop")) { + get_script_instance()->call("import_from_drop",p_drop,p_dest_path); + } + +} + EditorImportPlugin::EditorImportPlugin() { diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h index 5e09d674d1..e21fd8c8f8 100644 --- a/tools/editor/editor_import_export.h +++ b/tools/editor/editor_import_export.h @@ -60,6 +60,9 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; virtual Vector<uint8_t> custom_export(const String& p_path,const Ref<EditorExportPlatform> &p_platform); EditorImportPlugin(); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 69dfc556b4..af27f7d4a7 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -288,6 +288,7 @@ void EditorNode::_notification(int p_what) { get_tree()->get_root()->set_as_audio_listener(false); get_tree()->get_root()->set_as_audio_listener_2d(false); get_tree()->set_auto_accept_quit(false); + get_tree()->connect("files_dropped",this,"_dropped_files"); //VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport(),false); //import_monitor->scan_changes(); @@ -375,6 +376,7 @@ void EditorNode::_notification(int p_what) { _menu_option_confirm(DEPENDENCY_LOAD_CHANGED_IMAGES,true); } + waiting_for_sources_changed=true; EditorFileSystem::get_singleton()->scan_sources(); } @@ -412,6 +414,42 @@ void EditorNode::_fs_changed() { void EditorNode::_sources_changed(bool p_exist) { + if (p_exist && bool(EditorSettings::get_singleton()->get("import/automatic_reimport_on_sources_changed"))) { + p_exist=false; + + List<String> changed_sources; + EditorFileSystem::get_singleton()->get_changed_sources(&changed_sources); + + + EditorProgress ep("reimport",TTR("Re-Importing"),changed_sources.size()); + int step_idx=0; + + for(List<String>::Element *E=changed_sources.front();E;E=E->next()) { + + ep.step(TTR("Importing:")+" "+E->get(),step_idx++); + + 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()); + } + + } + + EditorFileSystem::get_singleton()->scan_sources(); + waiting_for_sources_changed=false; + + return; + } + + if (p_exist) { sources_button->set_icon(gui_base->get_icon("DependencyChanged","EditorIcons")); @@ -424,6 +462,8 @@ void EditorNode::_sources_changed(bool p_exist) { } + waiting_for_sources_changed=false; + } void EditorNode::_vp_resized() { @@ -435,13 +475,13 @@ void EditorNode::_rebuild_import_menu() { PopupMenu* p = import_menu->get_popup(); p->clear(); - p->add_item(TTR("Node From Scene"), FILE_IMPORT_SUBSCENE); - p->add_separator(); + //p->add_item(TTR("Node From Scene"), FILE_IMPORT_SUBSCENE); + //p->add_separator(); for (int i = 0; i < editor_import_export->get_import_plugin_count(); i++) { p->add_item(editor_import_export->get_import_plugin(i)->get_visible_name(), IMPORT_PLUGIN_BASE + i); } - p->add_separator(); - p->add_item(TTR("Re-Import.."), SETTINGS_IMPORT); + //p->add_separator(); + //p->add_item(TTR("Re-Import.."), SETTINGS_IMPORT); } void EditorNode::_node_renamed() { @@ -2858,6 +2898,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } break; + default: { if (p_option>=OBJECT_METHOD_BASE) { @@ -4899,6 +4940,7 @@ Variant EditorNode::drag_resource(const Ref<Resource>& p_res,Control* p_from) { TextureFrame *drag_preview = memnew( TextureFrame ); Label* label=memnew( Label ); + waiting_for_sources_changed=true; // Ref<Texture> preview; { @@ -5000,6 +5042,15 @@ Variant EditorNode::drag_files_and_dirs(const Vector<String>& p_files, Control * } + +void EditorNode::_dropped_files(const Vector<String>& p_files,int p_screen) { + + String cur_path = scenes_dock->get_current_path(); + for(int i=0;i<EditorImportExport::get_singleton()->get_import_plugin_count();i++) { + EditorImportExport::get_singleton()->get_import_plugin(i)->import_from_drop(p_files,cur_path); + } +} + void EditorNode::_bind_methods() { @@ -5067,6 +5118,9 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("_toggle_search_bar",&EditorNode::_toggle_search_bar); ObjectTypeDB::bind_method("_clear_search_box",&EditorNode::_clear_search_box); ObjectTypeDB::bind_method("_clear_undo_history",&EditorNode::_clear_undo_history); + ObjectTypeDB::bind_method("_dropped_files",&EditorNode::_dropped_files); + + ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin); ObjectTypeDB::bind_method(_MD("remove_editor_import_plugin", "plugin"), &EditorNode::remove_editor_import_plugin); @@ -6185,10 +6239,7 @@ EditorNode::EditorNode() { file_server = memnew( EditorFileServer ); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_2D) ))); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_ATLAS) ))); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_LARGE) ))); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_3D) ))); + editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this) ))); Ref<EditorSceneImportPlugin> _scene_import = memnew(EditorSceneImportPlugin(this) ); Ref<EditorSceneImporterCollada> _collada_import = memnew( EditorSceneImporterCollada); _scene_import->add_importer(_collada_import); @@ -6401,6 +6452,7 @@ EditorNode::EditorNode() { _load_docks(); + } diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 18a88f63bb..db589bb1c3 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -366,6 +366,8 @@ private: String open_navigate; bool changing_scene; + bool waiting_for_sources_changed; + uint32_t circle_step_msec; uint64_t circle_step_frame; int circle_step; @@ -464,6 +466,7 @@ private: void _add_to_recent_scenes(const String& p_scene); void _update_recent_scenes(); void _open_recent_scene(int p_idx); + void _dropped_files(const Vector<String>& p_files,int p_screen); //void _open_recent_scene_confirm(); String _recent_scene; @@ -607,6 +610,8 @@ public: void save_resource(const Ref<Resource>& p_resource); void save_resource_as(const Ref<Resource>& p_resource, const String &p_at_path=String()); + void merge_from_scene() { _menu_option_confirm(FILE_IMPORT_SUBSCENE,false); } + static bool has_unsaved_changes() { return singleton->unsaved_cache; } static HBoxContainer *get_menu_hb() { return singleton->menu_hb; } diff --git a/tools/editor/editor_resource_preview.cpp b/tools/editor/editor_resource_preview.cpp index f684b49a2c..d31cf9e0fd 100644 --- a/tools/editor/editor_resource_preview.cpp +++ b/tools/editor/editor_resource_preview.cpp @@ -36,14 +36,24 @@ void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture //print_line("preview is ready"); preview_mutex->lock(); + String path = p_str; + uint32_t hash=0; + + if (p_str.begins_with("ID:")) { + hash=p_str.get_slicec(':',2).to_int(); + path="ID:"+p_str.get_slicec(':',1); + } + Item item; item.order=order++; item.preview=p_texture; - cache[p_str]=item; + item.last_hash=hash; + + cache[path]=item; Object *recv = ObjectDB::get_instance(id); if (recv) { - recv->call_deferred(p_func,p_str,p_texture,p_ud); + recv->call_deferred(p_func,path,p_texture,p_ud); } preview_mutex->unlock(); @@ -51,7 +61,12 @@ void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem& p_item,const String& cache_base) { - String type = ResourceLoader::get_resource_type(p_item.path); + String type; + + if (p_item.resource.is_valid()) + type=p_item.resource->get_type(); + else + type=ResourceLoader::get_resource_type(p_item.path); //print_line("resource type is: "+type); if (type=="") @@ -62,24 +77,31 @@ Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem& p_item,co for(int i=0;i<preview_generators.size();i++) { if (!preview_generators[i]->handles(type)) continue; - generated = preview_generators[i]->generate_from_path(p_item.path); + if (p_item.resource.is_valid()) { + generated = preview_generators[i]->generate(p_item.resource); + } else { + generated = preview_generators[i]->generate_from_path(p_item.path); + } break; } - if (generated.is_valid()) { - //print_line("was generated"); - int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); - //wow it generated a preview... save cache - ResourceSaver::save(cache_base+".png",generated); - FileAccess *f=FileAccess::open(cache_base+".txt",FileAccess::WRITE); - f->store_line(itos(thumbnail_size)); - f->store_line(itos(FileAccess::get_modified_time(p_item.path))); - f->store_line(FileAccess::get_md5(p_item.path)); - memdelete(f); - } else { - //print_line("was not generated"); + if (!p_item.resource.is_valid()) { + // cache the preview in case it's a resource on disk + if (generated.is_valid()) { + //print_line("was generated"); + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + //wow it generated a preview... save cache + ResourceSaver::save(cache_base+".png",generated); + FileAccess *f=FileAccess::open(cache_base+".txt",FileAccess::WRITE); + f->store_line(itos(thumbnail_size)); + f->store_line(itos(FileAccess::get_modified_time(p_item.path))); + f->store_line(FileAccess::get_md5(p_item.path)); + memdelete(f); + } else { + //print_line("was not generated"); + } } return generated; @@ -113,8 +135,17 @@ void EditorResourcePreview::_thread() { if (cache.has(item.path)) { //already has it because someone loaded it, just let it know it's ready + if (item.resource.is_valid()) { + item.path+=":"+itos(cache[item.path].last_hash); //keep last hash (see description of what this is in condition below) + } call_deferred("_preview_ready",item.path,cache[item.path].preview,item.id,item.function,item.userdata); + } else if (item.resource.is_valid()){ + + texture=_generate_preview(item,String()); + //adding hash to the end of path (should be ID:<objid>:<hash>) because of 5 argument limit to call_deferred + call_deferred("_preview_ready",item.path+":"+itos(item.resource->hash_edited_version()),texture,item.id,item.function,item.userdata); + } else { @@ -194,6 +225,35 @@ void EditorResourcePreview::_thread() { +void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource>& p_res, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata) { + + ERR_FAIL_NULL(p_receiver); + ERR_FAIL_COND(!p_res.is_valid()); + + preview_mutex->lock(); + + String path_id = "ID:"+itos(p_res->get_instance_ID()); + 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); + preview_mutex->unlock(); + return; + + } + + //print_line("send to thread "+p_path); + QueueItem item; + item.function=p_receiver_func; + item.id=p_receiver->get_instance_ID(); + item.resource=p_res; + item.path=path_id; + item.userdata=p_userdata; + + queue.push_back(item); + preview_mutex->unlock(); + preview_sem->post(); +} void EditorResourcePreview::queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata) { @@ -204,7 +264,6 @@ void EditorResourcePreview::queue_resource_preview(const String& p_path, Object* p_receiver->call_deferred(p_receiver_func,p_path,cache[p_path].preview,p_userdata); preview_mutex->unlock(); return; - } //print_line("send to thread "+p_path); diff --git a/tools/editor/editor_resource_preview.h b/tools/editor/editor_resource_preview.h index aadae75597..13c3d51313 100644 --- a/tools/editor/editor_resource_preview.h +++ b/tools/editor/editor_resource_preview.h @@ -47,6 +47,7 @@ class EditorResourcePreview : public Node { static EditorResourcePreview* singleton; struct QueueItem { + Ref<Resource> resource; String path; ObjectID id; StringName function; @@ -63,6 +64,7 @@ class EditorResourcePreview : public Node { struct Item { Ref<Texture> preview; int order; + uint32_t last_hash; }; int order; @@ -84,7 +86,8 @@ public: static EditorResourcePreview* get_singleton(); //callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load - void queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); + void queue_resource_preview(const String& p_res, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); + void queue_edited_resource_preview(const Ref<Resource>& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); void add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator); diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index ad990e3fab..05c4f74b0d 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -507,6 +507,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("resources/save_compressed_resources",true); set("resources/auto_reload_modified_images",true); + set("import/automatic_reimport_on_sources_changed",true); + if (p_extra_config.is_valid()) { if (p_extra_config->has_section("init_projects") && p_extra_config->has_section_key("init_projects", "list")) { diff --git a/tools/editor/icons/icon_dependency_changed.png b/tools/editor/icons/icon_dependency_changed.png Binary files differindex ecf8a011cf..f48906f256 100644 --- a/tools/editor/icons/icon_dependency_changed.png +++ b/tools/editor/icons/icon_dependency_changed.png diff --git a/tools/editor/icons/icon_dependency_ok.png b/tools/editor/icons/icon_dependency_ok.png Binary files differindex f4d4c9ea29..fe4d7053f7 100644 --- a/tools/editor/icons/icon_dependency_ok.png +++ b/tools/editor/icons/icon_dependency_ok.png diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp index 6ac67ab8a6..7cc5b579fe 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp @@ -601,6 +601,13 @@ public: } } + + void set_source_and_dest(const String& p_font,const String& p_dest) { + source->get_line_edit()->set_text(p_font); + dest->get_line_edit()->set_text(p_dest); + _prop_changed(); + } + EditorFontImportDialog(EditorFontImportPlugin *p_plugin) { plugin=p_plugin; VBoxContainer *vbc = memnew( VBoxContainer ); @@ -1629,6 +1636,20 @@ Error EditorFontImportPlugin::import(const String& p_path, const Ref<ResourceImp } +void EditorFontImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + String file = p_drop[i].get_file(); + if (ext=="ttf" || ext=="otf" || ext=="fnt") { + + import_dialog(); + dialog->set_source_and_dest(p_drop[i],p_dest_path.plus_file(file.basename()+".fnt")); + break; + } + } +} + EditorFontImportPlugin::EditorFontImportPlugin(EditorNode* p_editor) { diff --git a/tools/editor/io_plugins/editor_font_import_plugin.h b/tools/editor/io_plugins/editor_font_import_plugin.h index ce26ef91e2..25914e6f83 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.h +++ b/tools/editor/io_plugins/editor_font_import_plugin.h @@ -48,6 +48,7 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); EditorFontImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp index 9af7d8daa5..c77256f27b 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -331,7 +331,7 @@ String EditorMeshImportPlugin::get_name() const { } String EditorMeshImportPlugin::get_visible_name() const{ - return "3D Mesh"; + return "Mesh"; } void EditorMeshImportPlugin::import_dialog(const String& p_from){ @@ -536,6 +536,26 @@ Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImp } +void EditorMeshImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + Vector<String> files; + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + String file = p_drop[i].get_file(); + if (ext=="obj") { + + files.push_back(p_drop[i]); + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + EditorMeshImportPlugin::EditorMeshImportPlugin(EditorNode* p_editor) { dialog = memnew( EditorMeshImportDialog(this)); diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.h b/tools/editor/io_plugins/editor_mesh_import_plugin.h index 014954685d..ed30d69e18 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.h +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.h @@ -21,6 +21,7 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); EditorMeshImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp index c608fe906f..631273a878 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp @@ -823,6 +823,58 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D EditorSampleImportPlugin* EditorSampleImportPlugin::singleton=NULL; +void EditorSampleImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + Vector<String> files; + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + + if (ext=="wav") { + + files.push_back(p_drop[i]); + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + +void EditorSampleImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (p_list.size()==0) + return; + + Vector<String> sources; + for(int i=0;i<p_list.size();i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(p_list[i],&idx); + if (efsd) { + for(int j=0;j<efsd->get_source_count(idx);j++) { + String file = expand_source_path(efsd->get_source_file(idx,j)); + if (sources.find(file)==-1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->popup_import(p_list[0]); + dialog->_choose_files(sources); + dialog->_choose_save_dir(p_list[0].get_base_dir()); + } +} + +bool EditorSampleImportPlugin::can_reimport_multiple_files() const { + + return true; +} EditorSampleImportPlugin::EditorSampleImportPlugin(EditorNode* p_editor) { @@ -865,6 +917,7 @@ Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref } + EditorSampleExportPlugin::EditorSampleExportPlugin() { } diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.h b/tools/editor/io_plugins/editor_sample_import_plugin.h index b31562af76..a2686ebe4f 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.h +++ b/tools/editor/io_plugins/editor_sample_import_plugin.h @@ -49,6 +49,9 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; EditorSampleImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index 84ef5f1973..00bd5413d3 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -41,6 +41,7 @@ #include "scene/3d/physics_body.h" #include "scene/3d/portal.h" #include "scene/3d/vehicle_body.h" +#include "tools/editor/create_dialog.h" #include "os/os.h" @@ -95,6 +96,7 @@ class EditorImportAnimationOptions : public VBoxContainer { Tree *optimization_tree; Vector<TreeItem*> items; + bool updating; bool validating; @@ -167,6 +169,7 @@ class EditorSceneImportDialog : public ConfirmationDialog { EditorFileDialog *script_select; EditorDirDialog *save_select; OptionButton *texture_action; + CreateDialog *root_type_choose; ConfirmationDialog *confirm_open; @@ -178,8 +181,13 @@ class EditorSceneImportDialog : public ConfirmationDialog { Map<Ref<Mesh>,Ref<Shape> > collision_map; ConfirmationDialog *error_dialog; - OptionButton *this_import; - OptionButton *next_import; + Button *root_type; + CheckBox *root_default; + + + void _root_default_pressed(); + void _root_type_pressed(); + void _set_root_type(); void _choose_file(const String& p_path); void _choose_save_file(const String& p_path); @@ -206,6 +214,11 @@ protected: static void _bind_methods(); public: + void setup_popup(const String& p_from,const String& p_to_path) { + _choose_file(p_from); + _choose_save_file(p_to_path); + } + Error import(const String& p_from, const String& p_to, const String& p_preset); void popup_import(const String& p_from); EditorSceneImportDialog(EditorNode *p_editor,EditorSceneImportPlugin *p_plugin); @@ -764,9 +777,10 @@ void EditorSceneImportDialog::_import(bool p_and_open) { rim->set_option("animation_filters",animation_options->get_filter()); rim->set_option("animation_clips",animation_options->get_clips()); rim->set_option("post_import_script",script_path->get_text()); - rim->set_option("import_this_time",this_import->get_selected()); - rim->set_option("import_next_time",next_import->get_selected()); rim->set_option("reimport",true); + if (!root_default->is_pressed()) { + rim->set_option("root_type",root_type->get_text()); + } List<String> missing; Error err = plugin->import1(rim,&scene,&missing); @@ -909,12 +923,24 @@ void EditorSceneImportDialog::popup_import(const String &p_from) { if (rimd->has_option("animation_optimizer_max_angle")) animation_options->set_optimize_max_angle(rimd->get_option("animation_optimizer_max_angle")); + if (rimd->has_option("root_type")) { + root_default->set_pressed(false); + String type = rimd->get_option("root_type"); + root_type->set_text(type); + root_type->set_disabled(false); + + if (has_icon(type,"EditorIcons")) { + root_type->set_icon(get_icon(type,"EditorIcons")); + } else { + root_type->set_icon(get_icon("Object","EditorIcons")); + } + + } else { + root_default->set_pressed(true); + root_type->set_disabled(true); + } script_path->set_text(rimd->get_option("post_import_script")); - if (rimd->has_option("import_this_time")) - this_import->select(rimd->get_option("import_this_time")); - if (rimd->has_option("import_next_time")) - next_import->select(rimd->get_option("import_next_time")); save_path->set_text(p_from.get_base_dir()); import_path->set_text(EditorImportPlugin::expand_source_path(rimd->get_source_path(0))); @@ -931,6 +957,9 @@ void EditorSceneImportDialog::_notification(int p_what) { List<String> extensions; file_select->clear_filters(); + root_type->set_icon(get_icon("Spatial","EditorIcons")); + root_type->set_text("Spatial"); + root_type->set_disabled(true); for(int i=0;i<plugin->get_importers().size();i++) { plugin->get_importers()[i]->get_extensions(&extensions); @@ -981,7 +1010,30 @@ void EditorSceneImportDialog::_dialog_hid() { wip_rimd=Ref<ResourceImportMetadata>(); } } +void EditorSceneImportDialog::_root_default_pressed() { + + root_type->set_disabled(root_default->is_pressed()); +} + +void EditorSceneImportDialog::_root_type_pressed() { + + + root_type_choose->popup(false); +} + + +void EditorSceneImportDialog::_set_root_type() { + String type = root_type_choose->get_selected_type(); + if (type==String()) + return; + root_type->set_text(type); + if (has_icon(type,"EditorIcons")) { + root_type->set_icon(get_icon(type,"EditorIcons")); + } else { + root_type->set_icon(get_icon("Object","EditorIcons")); + } +} void EditorSceneImportDialog::_bind_methods() { @@ -996,13 +1048,16 @@ void EditorSceneImportDialog::_bind_methods() { ObjectTypeDB::bind_method("_dialog_hid",&EditorSceneImportDialog::_dialog_hid); ObjectTypeDB::bind_method("_import_confirm",&EditorSceneImportDialog::_import_confirm); ObjectTypeDB::bind_method("_open_and_import",&EditorSceneImportDialog::_open_and_import); + ObjectTypeDB::bind_method("_root_default_pressed",&EditorSceneImportDialog::_root_default_pressed); + ObjectTypeDB::bind_method("_root_type_pressed",&EditorSceneImportDialog::_root_type_pressed); + ObjectTypeDB::bind_method("_set_root_type",&EditorSceneImportDialog::_set_root_type); + ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); } - const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_names[]={ {EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,("Actions"),"Remove Nodes (-noimp)",true}, @@ -1162,6 +1217,23 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce error_dialog->get_ok()->set_text(TTR("Accept")); // error_dialog->get_cancel()->hide(); + + HBoxContainer *custom_root_hb = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Custom Root Node Type:"),custom_root_hb); + root_type = memnew(Button); + root_type->set_h_size_flags(SIZE_EXPAND_FILL); + root_type->set_text_align(Button::ALIGN_LEFT); + root_type->connect("pressed",this,"_root_type_pressed"); + custom_root_hb->add_child(root_type); + + root_default = memnew(CheckBox); + root_default->set_text("Auto"); + root_default->set_pressed(true); + root_default->connect("pressed",this,"_root_default_pressed"); + custom_root_hb->add_child(root_default); + + + /* this_import = memnew( OptionButton ); this_import->add_item(TTR("Overwrite Existing Scene")); this_import->add_item(TTR("Overwrite Existing, Keep Materials")); @@ -1175,7 +1247,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce next_import->add_item(TTR("Keep Existing, Merge with New")); next_import->add_item(TTR("Keep Existing, Ignore New")); vbc->add_margin_child(TTR("Next Time:"),next_import); - +*/ set_hide_on_ok(false); GLOBAL_DEF("import/shared_textures","res://"); @@ -1183,6 +1255,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce import_hb->add_constant_override("separation",30); + VBoxContainer *ovb = memnew( VBoxContainer); ovb->set_h_size_flags(SIZE_EXPAND_FILL); import_hb->add_child(ovb); @@ -1232,6 +1305,10 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce wip_open=false; //texture_options->set_format(EditorImport::IMAGE_FORMAT_C); + root_type_choose = memnew( CreateDialog ); + add_child(root_type_choose); + root_type_choose->set_base_type("Node"); + root_type_choose->connect("create",this,"_set_root_type"); } @@ -1247,7 +1324,7 @@ String EditorSceneImportPlugin::get_name() const { String EditorSceneImportPlugin::get_visible_name() const{ - return "3D Scene"; + return "Scene"; } void EditorSceneImportPlugin::import_dialog(const String& p_from){ @@ -1906,397 +1983,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> } -void EditorSceneImportPlugin::_merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes) { - - - NodePath path = p_node->get_import_path(); - - if (!path.is_empty() && p_imported_scene->has_node(path)) { - - Node *imported_node = p_imported_scene->get_node(path); - - if (imported_node->get_type()==p_node->get_type()) { - //same thing, check what it is - - if (p_node->get_type()=="MeshInstance") { - - //merge mesh instance, this is a special case! - MeshInstance *mi_imported=imported_node->cast_to<MeshInstance>(); - MeshInstance *mi_node=p_node->cast_to<MeshInstance>(); - - Ref<Mesh> mesh_imported = mi_imported->get_mesh(); - Ref<Mesh> mesh_node = mi_node->get_mesh(); - - if (mesh_node.is_null() && mesh_imported.is_valid()) { - - mi_node->set_mesh(mesh_imported); - - } else if (mesh_node.is_valid() && mesh_imported.is_valid()) { - - if (checked_resources.has(mesh_imported)) { - - mi_node->set_mesh(mesh_imported); - } else { - //mix up meshes - //import new geometry but keep materials - for(int i=0;i<mesh_imported->get_surface_count();i++) { - - String name = mesh_imported->surface_get_name(i); - - for(int j=0;j<mesh_node->get_surface_count();j++) { - - Ref<Material> mat = mesh_node->surface_get_material(j); - if (mat.is_valid() && mesh_node->surface_get_name(j)==name ) { - - mesh_imported->surface_set_material(i,mat); - break; - } - } - } - // was imported, do nothing further - checked_resources.insert(mesh_imported); - mi_node->set_mesh(mesh_imported); - } - - } - } else if (p_node->get_type()=="Path") { - //for paths, overwrite path - Path *path_imported =imported_node->cast_to<Path>(); - Path *path_node =p_node->cast_to<Path>(); - - if (path_imported->get_curve().is_valid()) { - - path_node->set_curve(path_imported->get_curve()); - } - } else if (p_node->get_type()=="Portal") { - //for paths, overwrite path - - Portal *portal_imported =imported_node->cast_to<Portal>(); - Portal *portal_node =p_node->cast_to<Portal>(); - - portal_node->set_shape( portal_imported->get_shape() ); - - } else if (p_node->get_type()=="Room") { - //for paths, overwrite path - - Room *room_imported =imported_node->cast_to<Room>(); - Room *room_node =p_node->cast_to<Room>(); - - room_node->set_room( room_imported->get_room() ); - } else if (p_node->get_type()=="Skeleton") { - //for paths, overwrite path - - Skeleton *skeleton_imported =imported_node->cast_to<Skeleton>(); - Skeleton *skeleton_node =p_node->cast_to<Skeleton>(); - - //use imported bones, obviously - skeleton_node->clear_bones(); - for(int i=0;i<skeleton_imported->get_bone_count();i++) { - - skeleton_node->add_bone(skeleton_imported->get_bone_name(i)); - skeleton_node->set_bone_parent(i,skeleton_imported->get_bone_parent(i)); - skeleton_node->set_bone_rest(i,skeleton_imported->get_bone_rest(i)); - //skeleton_node->set_bone_pose(i,skeleton_imported->get_bone_pose(i)); // not in a scene, will throw errors - } - } - else if (p_node->get_type() == "AnimationPlayer") { - //for paths, overwrite path - AnimationPlayer *aplayer_imported = imported_node->cast_to<AnimationPlayer>(); - AnimationPlayer *aplayer_node = p_node->cast_to<AnimationPlayer>(); - - //use imported bones, obviously - List<StringName> anims; - List<StringName> existing_anims; - aplayer_imported->get_animation_list(&anims); - aplayer_node->get_animation_list(&existing_anims); - - //use imported animations - for (List<StringName>::Element *N = anims.front(); N; N = N->next()) { - - Ref<Animation> candidate = aplayer_imported->get_animation(N->get()); - - if (aplayer_node->has_animation(N->get())) { - - Ref<Animation> found = aplayer_node->get_animation(N->get()); - - candidate->set_loop(found->has_loop()); - candidate->set_step(found->get_step()); - - //For each track candidate - for (int i = 0; i < candidate->get_track_count(); i++) { - - NodePath track_path = candidate->track_get_path(i); - // For each track existing - for (int x = 0; x < found->get_track_count(); x++) { - - NodePath path_to_compare = found->track_get_path(x); - - if (track_path.hash() == path_to_compare.hash() && candidate->track_get_type(x) == found->track_get_type(i)) { - - //Tracks matches - if (candidate->track_get_interpolation_type(i) != found->track_get_interpolation_type(x)) - candidate->track_set_interpolation_type(i, found->track_get_interpolation_type(x)); - if (candidate->track_get_type(i) == Animation::TYPE_VALUE && candidate->value_track_is_continuous(i) != found->value_track_is_continuous(x)) - candidate->value_track_set_continuous(i, found->value_track_is_continuous(x)); - - //Key transitions might have changed, but the animation remained unchanged - if (candidate->track_get_key_count(i) == found->track_get_key_count(x)) { - for (int k = 0; k < candidate->track_get_key_count(i); k++) { - - if (candidate->track_get_key_transition(i, k) != found->track_get_key_transition(x, k)) - candidate->track_set_key_transition(i, k, found->track_get_key_transition(x, k)); - } - } - - } - - } - } - - // Append function callbacks and values - for (int x = 0; x < found->get_track_count(); x++) { - if (found->track_get_type(x) == Animation::TYPE_METHOD || found->track_get_type(x) == Animation::TYPE_VALUE) - candidate->add_track(found->track_get_type(x), candidate->get_track_count()); - - for (int k = 0; k < found->track_get_key_count(x); k++) - candidate->track_insert_key(x, found->track_get_key_time(x, k), found->track_get_key_value(x, k), found->track_get_key_transition(x, k)); - } - } - - aplayer_node->add_animation(N->get(), candidate); - } - - } else if (p_node->get_type()=="CollisionShape") { - //for paths, overwrite path - - CollisionShape *collision_imported =imported_node->cast_to<CollisionShape>(); - CollisionShape *collision_node =p_node->cast_to<CollisionShape>(); - - collision_node->set_shape( collision_imported->get_shape() ); - } - } - - if (p_node->cast_to<Spatial>() && imported_node->cast_to<Spatial>()) { - //apply transform if changed - Spatial *snode = p_node->cast_to<Spatial>(); - Spatial *simp = imported_node->cast_to<Spatial>(); - - if (snode->get_import_transform() == snode->get_transform()) { - //not moved, apply new - snode->set_import_transform(simp->get_transform()); - snode->set_transform(simp->get_transform()); - } else if (snode->get_import_transform() == simp->get_import_transform()) { - //do nothing, nothing changed keep local changes - } else { - //changed both, imported and edited, merge - Transform local_xform = snode->get_import_transform().affine_inverse() * snode->get_transform(); - snode->set_import_transform(simp->get_import_transform()); - snode->set_transform(simp->get_import_transform() * local_xform); - } - } - - checked_nodes.insert(imported_node); - - } -#if 0 - else { - - if (p_node!=p_root && p_existing->has_node(p_root->get_path_to(p_node->get_parent()))) { - - Node *parent = p_existing->get_node(p_root->get_path_to(p_node->get_parent())); - NodePath path = p_root->get_path_to(p_node); - - //add it.. because not existing in existing scene - Object *o = ObjectTypeDB::instance(p_existing->get_type()); - Node *n=NULL; - if (o) - n=o->cast_to<Node>(); - - if (n) { - - List<PropertyInfo> pl; - p_existing->get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) - continue; - n->set( E->get().name, p_existing->get(E->get().name) ); - } - - parent->add_child(n); - - valid=true; - } - } - - } -#endif - - for(int i=0;i<p_node->get_child_count();i++) { - _merge_existing_node(p_node->get_child(i),p_imported_scene,checked_resources,checked_nodes); - } -} - - -void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Node *p_existing_scene,Set<Node*> &checked_nodes) { - - - for(int i=0;i<p_imported->get_child_count();i++) { - - - Node *imported_node = p_imported->get_child(i); - - if (imported_node->get_owner()!=p_imported_scene) { - // print_line("skipping because not imported at "+String(imported_node->get_name())); - continue; //end of the road - } - - Vector<StringName> nn; - nn.push_back(imported_node->get_name()); - NodePath imported_path(nn,false); - //print_line("check for: "+String(imported_path)); - - if (!p_node->has_node(imported_path) && !checked_nodes.has(imported_node)) { - //not there, re-add it - //add it.. because not existing in existing scene - Object *o = ObjectTypeDB::instance(imported_node->get_type()); - Node *n=NULL; - if (o) - n=o->cast_to<Node>(); - - //print_line("creating node of same type.."); - - if (n) { - - //print_line("copy props and add"); - List<PropertyInfo> pl; - imported_node->get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) - continue; - n->set( E->get().name, imported_node->get(E->get().name) ); - } - - p_node->add_child(n); - n->set_owner(p_existing_scene); - } - - } else { - //print_line("already exists"); - } - - - if (p_node->has_node(imported_path)) { - - Node *other_node = p_node->get_node(imported_path); - - _add_new_nodes(other_node,imported_node,p_imported_scene,p_existing_scene,checked_nodes); - - } - - } -} - - -void EditorSceneImportPlugin::_merge_scenes(Node *p_node,Node *p_imported) { - - Set<Ref<Resource> > checked_resources; - Set<Node*> checked_nodes; - _merge_existing_node(p_node,p_imported,checked_resources,checked_nodes); - _add_new_nodes(p_node,p_imported,p_imported,p_node,checked_nodes); - //add existing.. ? -} - - -void EditorSceneImportPlugin::_scan_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials) { - - if (!p_base && p_node->get_owner()!=p_base) - return; - MeshInstance *mi=p_node->cast_to<MeshInstance>(); - - if (mi) { - if (mi->get_material_override().is_valid()) { - String path = p_base->get_path_to(p_node); - override_materials[path]=mi->get_material_override(); - } - Ref<Mesh> mesh = mi->get_mesh(); - if (mesh.is_valid()) { - - for(int i=0;i<mesh->get_surface_count();i++) { - - String name = mesh->get_name()+":"+mesh->surface_get_name(i); - if (!mesh_materials.has(name)) { - mesh_materials[name]=mesh->surface_get_material(i); - } - } - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - _scan_materials(p_base,p_node->get_child(i),mesh_materials,override_materials); - } -} - - -void EditorSceneImportPlugin::_apply_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials,Set<Ref<Mesh> >& meshes_processed) { - - if (p_node!=p_base && p_node->get_owner()!=p_base) - return; - - MeshInstance *mi=p_node->cast_to<MeshInstance>(); - - if (mi) { - - print_line("is mesh "+String(p_node->get_name())); - String path = p_base->get_path_to(p_node); - if (override_materials.has(path)) { - print_line("is in material overrides"); - mi->set_material_override(override_materials[path]); - } - - Ref<Mesh> mesh = mi->get_mesh(); - if (mesh.is_valid() && !meshes_processed.has(mesh)) { - print_line("mesh was not processed"); - meshes_processed.insert(mesh); - for(int i=0;i<mesh->get_surface_count();i++) { - - String name = mesh->get_name()+":"+mesh->surface_get_name(i); - print_line("name for surface "+itos(i)+": "+name); - if (mesh_materials.has(name)) { - - Ref<Material> mat = mesh_materials[name]; - mesh->surface_set_material(i,mat); - print_line("overriding!"); - } - } - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - _apply_materials(p_base,p_node->get_child(i),mesh_materials,override_materials,meshes_processed); - } -} - -void EditorSceneImportPlugin::_merge_materials(Node *p_node,Node *p_imported) { - - Map<String,Ref<Material> > mesh_materials; - Map<String,Ref<Material> > override_materials; - - _scan_materials(p_node,p_node,mesh_materials,override_materials); - - for (Map<String,Ref<Material> >::Element *E=mesh_materials.front();E;E=E->next()) { - print_line("Mats: "+String(E->key())); - } - - for (Map<String,Ref<Material> >::Element *E=override_materials.front();E;E=E->next()) { - print_line("Overrides: "+String(E->key())); - } - - Set<Ref<Mesh> > mp; - _apply_materials(p_imported,p_imported,mesh_materials,override_materials,mp); - - -} #if 0 @@ -2397,6 +2084,21 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from return err; } + if (from->has_option("root_type")) { + String type = from->get_option("root_type"); + Object *base = ObjectTypeDB::instance(type); + Node *base_node = NULL; + if (base) + base_node=base->cast_to<Node>(); + + if (base_node) { + + scene->replace_by(base_node); + memdelete(scene); + scene=base_node; + } + } + _tag_import_paths(scene,scene); *r_node=scene; @@ -2839,66 +2541,12 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c } } - Error err = EditorTextureImportPlugin::get_singleton(EditorTextureImportPlugin::MODE_TEXTURE_3D)->import(target_path,imd); + Error err = EditorTextureImportPlugin::get_singleton()->import(target_path,imd); } } - /// BEFORE SAVING - MERGE - - - if (import_action!=SCENE_UPDATE_REPLACE_WITH_NEW) { - - - progress.step(TTR("Merging.."),103); - - FileAccess *fa = FileAccess::create(FileAccess::ACCESS_RESOURCES); - - if (fa->file_exists(p_dest_path)) { - - - //try to merge - - Ref<PackedScene> s = ResourceLoader::load(p_dest_path); - if (s.is_valid()) { - - Node *existing = s->instance(true); - - if (existing) { - - - switch(import_action) { - - case SCENE_UPDATE_REPLACE_WITH_NEW: break; - case SCENE_UPDATE_REPLACE_WITH_NEW_KEEP_MATERIALS: { - - _merge_materials(existing,scene); - memdelete(existing); - - } break; - case SCENE_UPDATE_KEEP_OLD_MERGE_CHANGES: { - - _merge_scenes(existing,scene); - memdelete(scene); - scene=existing; - - } break; - case SCENE_UPDATE_KEEP_OLD: { - - memdelete(scene); - scene=existing; - } break; - } - - } - } - - } - - memdelete(fa); - } - progress.step(TTR("Saving.."),104); @@ -2957,6 +2605,30 @@ void EditorSceneImportPlugin::add_importer(const Ref<EditorSceneImporter>& p_imp importers.push_back(p_importer); } +void EditorSceneImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { + + List<String> extensions; + for(int i=0;i<importers.size();i++) { + importers[i]->get_extensions(&extensions); + } + //bool warn_compatible=false; + for(int i=0;i<p_drop.size();i++) { + + String extension = p_drop[i].extension().to_lower(); + + for(List<String>::Element *E=extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + + dialog->popup_import(String()); + dialog->setup_popup(p_drop[i],p_dest_path); + return; + } + } + } + +} + EditorSceneImportPlugin::EditorSceneImportPlugin(EditorNode* p_editor) { diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h index a1a090de7e..8a2d30f1f6 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ b/tools/editor/io_plugins/editor_scene_import_plugin.h @@ -45,6 +45,7 @@ #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "scene/resources/animation.h" + class EditorNode; class EditorSceneImportDialog; @@ -111,16 +112,8 @@ class EditorSceneImportPlugin : public EditorImportPlugin { void _create_clips(Node *scene, const Array& p_clips, bool p_bake_all); void _filter_anim_tracks(Ref<Animation> anim,Set<String> &keep); void _filter_tracks(Node *scene, const String& p_text); - void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes); - - void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Node *p_existing_scene,Set<Node*> &checked_nodes); void _optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle); - void _merge_scenes(Node *p_node, Node *p_imported); - void _scan_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials); - void _apply_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials,Set<Ref<Mesh> >& meshes_processed); - void _merge_materials(Node *p_node,Node *p_imported); - void _tag_import_paths(Node *p_scene,Node *p_node); public: @@ -150,13 +143,6 @@ public: SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30, }; - enum SceneUpdate { - SCENE_UPDATE_REPLACE_WITH_NEW, - SCENE_UPDATE_REPLACE_WITH_NEW_KEEP_MATERIALS, - SCENE_UPDATE_KEEP_OLD_MERGE_CHANGES, - SCENE_UPDATE_KEEP_OLD, - }; - virtual String get_name() const; virtual String get_visible_name() const; @@ -169,6 +155,8 @@ public: void add_importer(const Ref<EditorSceneImporter>& p_importer); const Vector<Ref<EditorSceneImporter> >& get_importers() { return importers; } + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + EditorSceneImportPlugin(EditorNode* p_editor=NULL); diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 0e2d35b9f2..c7598466d5 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -35,6 +35,9 @@ #include "io/md5.h" #include "io/marshalls.h" #include "globals.h" +#include "scene/gui/check_button.h" +#include "scene/gui/button_group.h" +#include "scene/gui/margin_container.h" static const char *flag_names[]={ ("Streaming Format"), @@ -164,12 +167,13 @@ void EditorImportTextureOptions::_notification(int p_what) { void EditorImportTextureOptions::show_2d_notice() { - notice_for_2d->show(); + //notice_for_2d->show(); } EditorImportTextureOptions::EditorImportTextureOptions() { + add_constant_override("separation",3); updating=false; format = memnew( OptionButton ); @@ -223,12 +227,6 @@ EditorImportTextureOptions::EditorImportTextureOptions() { add_margin_child(TTR("Texture Options"),flags,true); - notice_for_2d = memnew( Label ); - notice_for_2d->set_text(TTR("NOTICE: You are not forced to import textures for 2D projects. Just copy your .jpg or .png files to your project, and change export options later. Atlases can be generated on export too.")); - notice_for_2d->set_custom_minimum_size(Size2(0,50)); - notice_for_2d->set_autowrap(true); - add_child(notice_for_2d); - notice_for_2d->hide(); } @@ -242,8 +240,13 @@ class EditorTextureImportDialog : public ConfirmationDialog { OBJ_TYPE(EditorTextureImportDialog,ConfirmationDialog); + + HBoxContainer *mode_hb; + CheckBox *mode_check[EditorTextureImportPlugin::MODE_MAX]; + EditorImportTextureOptions *texture_options; + EditorTextureImportPlugin::Mode mode; //EditorNode *editor; LineEdit *import_path; @@ -255,11 +258,16 @@ class EditorTextureImportDialog : public ConfirmationDialog { ConfirmationDialog *error_dialog; CheckButton *crop_source; SpinBox *size; - bool atlas; - bool large; + + MarginContainer *size_mc; + Label* size_label; + + Label* source_label; + Label *notice_for_2d; EditorTextureImportPlugin *plugin; + void _mode_changed(int p_mode); void _choose_files(const Vector<String>& p_path); void _choose_file(const String& p_path); void _choose_save_dir(const String& p_path); @@ -274,9 +282,23 @@ protected: static void _bind_methods(); public: + + void setup_multiple_import_3d(const Vector<String>& p_path,const String& p_dest) { + + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); + _choose_files(p_path); + _choose_save_dir(p_dest); + } + + void add_sources_and_dest(const Vector<String>& p_path,const String& p_dest) { + + _choose_files(p_path); + _choose_save_dir(p_dest); + } + Error import(const String& p_from, const String& p_to, const String& p_preset); void popup_import(const String &p_from=String()); - EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL,bool p_2d=false,bool p_atlas=false,bool p_large=false); + EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL); }; @@ -349,13 +371,13 @@ void EditorTextureImportDialog::_import() { } - if (!atlas && !large && !DirAccess::exists(save_path->get_text())) { + if (mode!=EditorTextureImportPlugin::MODE_ATLAS && mode!=EditorTextureImportPlugin::MODE_LARGE && !DirAccess::exists(save_path->get_text())) { error_dialog->set_text(TTR("Target path must exist.")); error_dialog->popup_centered_minsize(); return; } - if (atlas) { //atlas + if (mode==EditorTextureImportPlugin::MODE_ATLAS) { //atlas if (files.size()==0) { @@ -378,6 +400,7 @@ void EditorTextureImportDialog::_import() { imd->set_option("atlas_size",int(size->get_val())); imd->set_option("large",false); imd->set_option("crop",crop_source->is_pressed()); + imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { @@ -387,7 +410,7 @@ void EditorTextureImportDialog::_import() { return; } - } else if (large) { //atlas + } else if (mode==EditorTextureImportPlugin::MODE_LARGE) { //large if (files.size()!=1) { @@ -410,6 +433,7 @@ void EditorTextureImportDialog::_import() { imd->set_option("large",true); imd->set_option("large_cell_size",int(size->get_val())); imd->set_option("crop",crop_source->is_pressed()); + imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { @@ -434,6 +458,7 @@ void EditorTextureImportDialog::_import() { imd->set_option("quality",texture_options->get_quality()); imd->set_option("atlas",false); imd->set_option("large",false); + imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { @@ -456,7 +481,7 @@ void EditorTextureImportDialog::_browse() { void EditorTextureImportDialog::_browse_target() { - if (atlas || large) { + if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) { save_file_select->popup_centered_ratio(); } else { save_select->popup_centered_ratio(); @@ -467,12 +492,28 @@ void EditorTextureImportDialog::_browse_target() { void EditorTextureImportDialog::popup_import(const String& p_from) { - popup_centered(Size2(400,400)); + popup_centered(Size2(600,500)); if (p_from!="") { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); ERR_FAIL_COND(!rimd.is_valid()); - if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS || plugin->get_mode()==EditorTextureImportPlugin::MODE_LARGE) + if (rimd->has_option("mode")) { + //new imported stuff uses this option + _mode_changed(rimd->get_option("mode")); + } else { + //this one is for compatibility, will have to guess it + if (rimd->has_option("atlas") && rimd->get_option("atlas")) { + _mode_changed(EditorTextureImportPlugin::MODE_ATLAS); + } else if (rimd->has_option("large") && rimd->get_option("large")) { + _mode_changed(EditorTextureImportPlugin::MODE_LARGE); + } else { + //guess by usage of mipmaps..? + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_2D); + } + + } + + if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) save_path->set_text(p_from); else save_path->set_text(p_from.get_base_dir()); @@ -518,6 +559,81 @@ Error EditorTextureImportDialog::import(const String& p_from, const String& p_to return OK; } +void EditorTextureImportDialog::_mode_changed(int p_mode) { + + mode = EditorTextureImportPlugin::Mode(p_mode); + + for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { + mode_check[i]->set_pressed(i==mode); + } + + if (p_mode==EditorTextureImportPlugin::MODE_ATLAS) { + + size_label->set_text(TTR("Max Texture Size:")); + size->set_val(2048); + crop_source->show(); + size_label->show(); + size->show(); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); + set_title(TTR("Import Textures for Atlas (2D)")); + + } else { + crop_source->hide(); + } + + + if (p_mode==EditorTextureImportPlugin::MODE_LARGE) { + + size_label->set_text(TTR("Cell Size:")); + size->set_val(256); + size_label->show(); + size->show(); + + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + save_file_select->add_filter("*.ltex;"+TTR("Large Texture")); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); + set_title(TTR("Import Large Textures (2D)")); + source_label->set_text(TTR("Source Texture")); + + } else { + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + save_file_select->add_filter("*.tex;"+TTR("Base Atlas Texture")); + source_label->set_text(TTR("Source Texture(s)")); + } + + if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_2D) { + + size_label->hide(); + size->hide(); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); + notice_for_2d->show(); + set_title(TTR("Import Textures for 2D")); + + } else { + notice_for_2d->hide(); + } + + if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_3D) { + + size_label->hide(); + size->hide(); + //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_); + //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS); + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER|EditorTextureImportPlugin::IMAGE_FLAG_REPEAT); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); + set_title(TTR("Import Textures for 3D")); + } +} + void EditorTextureImportDialog::_bind_methods() { @@ -527,28 +643,64 @@ void EditorTextureImportDialog::_bind_methods() { ObjectTypeDB::bind_method("_import",&EditorTextureImportDialog::_import); ObjectTypeDB::bind_method("_browse",&EditorTextureImportDialog::_browse); ObjectTypeDB::bind_method("_browse_target",&EditorTextureImportDialog::_browse_target); + ObjectTypeDB::bind_method("_mode_changed",&EditorTextureImportDialog::_mode_changed); // ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); } -EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas,bool p_large) { +EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin) { + + + - atlas=p_atlas; - large=p_large; plugin=p_plugin; set_title(TTR("Import Textures")); + mode_hb = memnew( HBoxContainer ); + add_child(mode_hb); + set_child_rect(mode_hb); + + VBoxContainer *vbcg = memnew( VBoxContainer); + + + mode_hb->add_child(vbcg); + mode_hb->add_constant_override("separation",15); + ButtonGroup *bg = memnew( ButtonGroup ); + vbcg->add_margin_child("Import Mode",bg); + + for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { + String mode_name[EditorTextureImportPlugin::MODE_MAX]={ + TTR("2D Texture"), + TTR("3D Texture"), + TTR("Atlas Texture"), + TTR("Large Texture") + }; + + + mode_check[i]=memnew(CheckBox); + bg->add_child(mode_check[i]); + mode_check[i]->set_text(mode_name[i]); + mode_check[i]->connect("pressed",this,"_mode_changed",varray(i)); + } VBoxContainer *vbc = memnew(VBoxContainer); - add_child(vbc); - set_child_rect(vbc); + mode_hb->add_child(vbc); + vbc->set_h_size_flags(SIZE_EXPAND_FILL); + vbc->add_constant_override("separation",4); + notice_for_2d = memnew( Label ); + notice_for_2d->set_text(TTR("NOTICE: Importing 2D textures is not mandatory. Just copy png/jpg files to the project.")); + //notice_for_2d->set_custom_minimum_size(Size2(0,50)); + notice_for_2d->set_autowrap(true); + notice_for_2d->hide(); + vbcg->add_child(notice_for_2d); + notice_for_2d->set_v_size_flags(SIZE_EXPAND_FILL); + notice_for_2d->set_valign(Label::VALIGN_BOTTOM); VBoxContainer *source_vb=memnew(VBoxContainer); - if (large) - vbc->add_margin_child(TTR("Source Texture:"),source_vb); - else - vbc->add_margin_child(TTR("Source Texture(s):"),source_vb); + MarginContainer *source_mc = vbc->add_margin_child(TTR("Source Texture(s):"),source_vb); + + source_label = vbc->get_child(source_mc->get_index()-1)->cast_to<Label>(); HBoxContainer *hbc = memnew( HBoxContainer ); source_vb->add_child(hbc); @@ -560,8 +712,6 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* crop_source->set_pressed(true); source_vb->add_child(crop_source); crop_source->set_text(TTR("Crop empty space.")); - if (!p_atlas) - crop_source->hide(); Button * import_choose = memnew( Button ); @@ -577,13 +727,10 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* size->set_min(128); size->set_max(16384); - if (p_atlas) { - size->set_val(2048); - vbc->add_margin_child(TTR("Max Texture Size:"),size); - } else { - size->set_val(256); - vbc->add_margin_child(TTR("Cell Size:"),size); - } + + size->set_val(256); + size_mc=vbc->add_margin_child(TTR("Cell Size:"),size); + size_label=vbc->get_child(size_mc->get_index()-1)->cast_to<Label>(); save_path = memnew( LineEdit ); @@ -599,10 +746,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* file_select = memnew(EditorFileDialog); file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - if (!large) - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); - else - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + file_select->connect("files_selected", this,"_choose_files"); file_select->connect("file_selected", this,"_choose_file"); @@ -611,10 +755,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* add_child(save_file_select); save_file_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); save_file_select->clear_filters(); - if (large) - save_file_select->add_filter("*.ltex;"+TTR("Large Texture")); - else - save_file_select->add_filter("*.tex;"+TTR("Base Atlas Texture")); + save_file_select->connect("file_selected", this,"_choose_save_dir"); save_select = memnew( EditorDirDialog ); @@ -641,36 +782,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* vbc->add_child(texture_options); texture_options->set_v_size_flags(SIZE_EXPAND_FILL); - if (atlas) { - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - //texture_options->show_2d_notice(); - set_title(TTR("Import Textures for Atlas (2D)")); - } else if (large) { - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); - texture_options->show_2d_notice(); - set_title(TTR("Import Large Textures (2D)")); - - } else if (p_2d) { - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - texture_options->show_2d_notice(); - set_title(TTR("Import Textures for 2D")); - } else { - - //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_); - //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS); - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER|EditorTextureImportPlugin::IMAGE_FLAG_REPEAT); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); - set_title(TTR("Import Textures for 3D")); - } + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); // GLOBAL_DEF("import/shared_textures","res://"); @@ -686,6 +798,8 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* String EditorTextureImportPlugin::get_name() const { + return "texture"; +#if 0 //old names, kept for compatibility reference switch(mode) { case MODE_TEXTURE_2D: { @@ -707,34 +821,14 @@ String EditorTextureImportPlugin::get_name() const { } - return ""; + return ""; +#endif } String EditorTextureImportPlugin::get_visible_name() const { - switch(mode) { - case MODE_TEXTURE_2D: { - - return "2D Texture"; - } break; - case MODE_TEXTURE_3D: { - - return "3D Texture"; - - } break; - case MODE_ATLAS: { - - return "2D Atlas Texture"; - } break; - case MODE_LARGE: { - - return "2D Large Texture"; - } break; - - } - - return ""; + return "Texture"; } void EditorTextureImportPlugin::import_dialog(const String& p_from) { @@ -1626,15 +1720,93 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c return ret; } +void EditorTextureImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { + + Vector<String> valid; + + List<String> valid_extensions; + ImageLoader::get_recognized_extensions(&valid_extensions); + for(int i=0;i<p_drop.size();i++) { + + String extension=p_drop[i].extension().to_lower(); + + for (List<String>::Element *E=valid_extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + valid.push_back(p_drop[i]); + break; + } + } + } + + if (valid.size()) { + dialog->popup_import(); + dialog->setup_multiple_import_3d(valid,p_dest_path); + } +} + +void EditorTextureImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + Vector<String> valid; + + + bool warning=false; + for(int i=0;i<p_list.size();i++) { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_list[i]); + String type = rimd->get_editor(); + if (type=="texture" || type.begins_with("texture_")) { + + if ((rimd->has_option("atlas") && rimd->get_option("atlas")) || (rimd->has_option("large") && rimd->get_option("large"))) { + warning=true; + continue; + } + + valid.push_back(p_list[i]); + } + } + + if (valid.size()) { + + dialog->popup_import(valid[0]); + + Vector<String> sources; + for(int i=0;i<valid.size();i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(valid[i],&idx); + if (efsd) { + for(int j=0;j<efsd->get_source_count(idx);j++) { + String file = expand_source_path(efsd->get_source_file(idx,j)); + if (sources.find(file)==-1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->add_sources_and_dest(sources,valid[0].get_base_dir()); + } + } +} + +bool EditorTextureImportPlugin::can_reimport_multiple_files() const { + + return true; + +} + + -EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[EditorTextureImportPlugin::MODE_MAX]={NULL,NULL,NULL,NULL}; +EditorTextureImportPlugin *EditorTextureImportPlugin::singleton=NULL; -EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor, Mode p_mode) { +EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor) { - singleton[p_mode]=this; - editor=p_editor; - mode=p_mode; - dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS || p_mode==MODE_LARGE,p_mode==MODE_ATLAS,p_mode==MODE_LARGE) ); + singleton=this; + editor=p_editor; + dialog = memnew( EditorTextureImportDialog(this) ); editor->get_gui_base()->add_child(dialog); } diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index cb63ba98c8..5c8abd10a4 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -64,10 +64,10 @@ public: private: - Mode mode; + EditorNode *editor; EditorTextureImportDialog *dialog; - static EditorTextureImportPlugin *singleton[MODE_MAX]; + static EditorTextureImportPlugin *singleton; //used by other importers such as mesh Error _process_texture_data(Ref<ImageTexture> &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink); @@ -75,7 +75,7 @@ private: public: - static EditorTextureImportPlugin *get_singleton(Mode p_mode) { return singleton[p_mode]; } + static EditorTextureImportPlugin *get_singleton() { return singleton; } enum ImageFormat { @@ -100,7 +100,6 @@ public: IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear }; - Mode get_mode() const { return mode; } virtual String get_name() const; virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); @@ -108,8 +107,11 @@ public: virtual Error import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external=false); virtual Vector<uint8_t> custom_export(const String& p_path,const Ref<EditorExportPlatform> &p_platform); + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; - EditorTextureImportPlugin(EditorNode* p_editor=NULL,Mode p_mode=MODE_TEXTURE_2D); + EditorTextureImportPlugin(EditorNode* p_editor=NULL); }; @@ -134,7 +136,7 @@ class EditorImportTextureOptions : public VBoxContainer { HSlider *quality; Tree *flags; Vector<TreeItem*> items; - Label *notice_for_2d; + bool updating; diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.cpp b/tools/editor/io_plugins/editor_translation_import_plugin.cpp index b57e4cb84c..282153fa73 100644 --- a/tools/editor/io_plugins/editor_translation_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_translation_import_plugin.cpp @@ -394,6 +394,26 @@ void EditorTranslationImportPlugin::import_dialog(const String& p_from) { dialog->popup_import(p_from); } + + +void EditorTranslationImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + + if (ext=="csv") { + + import_dialog(); + dialog->_choose_file(p_drop[i]); + dialog->_choose_save_dir(p_dest_path); + break; + } + } + + +} + Error EditorTranslationImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { Ref<ResourceImportMetadata> from = p_from; diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.h b/tools/editor/io_plugins/editor_translation_import_plugin.h index cadcdc03b3..532f2cedcc 100644 --- a/tools/editor/io_plugins/editor_translation_import_plugin.h +++ b/tools/editor/io_plugins/editor_translation_import_plugin.h @@ -46,6 +46,7 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); EditorTranslationImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/tools/editor/plugins/mesh_editor_plugin.cpp index c4f44f6082..ecf17fec19 100644 --- a/tools/editor/plugins/mesh_editor_plugin.cpp +++ b/tools/editor/plugins/mesh_editor_plugin.cpp @@ -71,6 +71,22 @@ void MeshEditor::edit(Ref<Mesh> p_mesh) { rot_x=0; rot_y=0; _update_rotation(); + + AABB aabb= mesh->get_aabb(); + Vector3 ofs = aabb.pos + aabb.size*0.5; + aabb.pos-=ofs; + float m = MAX(aabb.size.x,aabb.size.y)*0.5; + if (m!=0) { + m=1.0/m; + m*=0.5; + //print_line("scale: "+rtos(m)); + Transform xform; + xform.basis.scale(Vector3(m,m,m)); + xform.origin=-xform.basis.xform(ofs); //-ofs*m; + xform.origin.z-=aabb.size.z*2; + mesh_instance->set_transform(xform); + } + } } diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index afc6396ab3..ddbaad5ea1 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1673,6 +1673,7 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns,int } + void CustomPropertyEditor::_bind_methods() { ObjectTypeDB::bind_method("_focus_enter", &CustomPropertyEditor::_focus_enter); @@ -1691,6 +1692,7 @@ void CustomPropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_menu_option",&CustomPropertyEditor::_menu_option); + ADD_SIGNAL( MethodInfo("variant_changed") ); ADD_SIGNAL( MethodInfo("resource_edit_request") ); } @@ -2180,6 +2182,11 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } } + if (!res->is_type("Texture")) { + //texture already previews via itself + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res,this,"_resource_preview_done",p_item->get_instance_ID()); + } + } @@ -3357,6 +3364,10 @@ void PropertyEditor::update_tree() { } else if (res.is_valid()) { item->set_tooltip(1,res->get_name()+" ("+res->get_type()+")"); } + if (!res->is_type("Texture")) { + //texture already previews via itself + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res,this,"_resource_preview_done",item->get_instance_ID()); + } } @@ -3870,6 +3881,29 @@ void PropertyEditor::_filter_changed(const String& p_text) { update_tree(); } + + +void PropertyEditor::_resource_preview_done(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud) { + + if (p_preview.is_null()) + return; //don't bother with empty preview + + ObjectID id = p_ud; + Object *obj = ObjectDB::get_instance(id); + + if (!obj) + return; + + TreeItem *ti = obj->cast_to<TreeItem>(); + + ERR_FAIL_COND(!ti); + + int tw = EditorSettings::get_singleton()->get("property_editor/texture_preview_width"); + + ti->set_icon(1,p_preview); //should be scaled I think? + ti->set_icon_max_width(1,tw); + ti->set_text(1,""); +} void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_item_edited",&PropertyEditor::_item_edited); @@ -3884,6 +3918,7 @@ void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_set_range_def",&PropertyEditor::_set_range_def); ObjectTypeDB::bind_method( "_filter_changed",&PropertyEditor::_filter_changed); ObjectTypeDB::bind_method( "update_tree",&PropertyEditor::update_tree); + ObjectTypeDB::bind_method( "_resource_preview_done",&PropertyEditor::_resource_preview_done); ObjectTypeDB::bind_method(_MD("get_drag_data_fw"), &PropertyEditor::get_drag_data_fw); ObjectTypeDB::bind_method(_MD("can_drop_data_fw"), &PropertyEditor::can_drop_data_fw); diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index ac58011d43..a909b5ccd3 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -131,6 +131,7 @@ class CustomPropertyEditor : public Popup { void config_value_editors(int p_amount, int p_columns,int p_label_w,const List<String>& p_strings); void config_action_buttons(const List<String>& p_strings); + protected: void _notification(int p_what); @@ -231,6 +232,7 @@ class PropertyEditor : public Control { 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); + void _resource_preview_done(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud); UndoRedo *undo_redo; protected: diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 517162b81e..3e36a30361 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -542,6 +542,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } break; + case TOOL_MERGE_FROM_SCENE: { + + EditorNode::get_singleton()->merge_from_scene(); + } break; case TOOL_NEW_SCENE_FROM: { Node *scene = editor_data->get_edited_scene_root(); @@ -1696,6 +1700,7 @@ void SceneTreeDock::_tree_rmb(const Vector2& p_menu_pos) { if (selection.size()==1) { menu->add_separator(); + menu->add_item(TTR("Merge From Scene"),TOOL_MERGE_FROM_SCENE); menu->add_item(TTR("Save Branch as Scene"),TOOL_NEW_SCENE_FROM); } menu->add_separator(); diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index 0894dc8ffa..a5866944f3 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -64,6 +64,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_DUPLICATE, TOOL_REPARENT, TOOL_NEW_SCENE_FROM, + TOOL_MERGE_FROM_SCENE, TOOL_MULTI_EDIT, TOOL_ERASE, TOOL_BUTTON_MAX diff --git a/tools/editor/scenes_dock.cpp b/tools/editor/scenes_dock.cpp index fc0bcfe7b9..a814dc2d9a 100644 --- a/tools/editor/scenes_dock.cpp +++ b/tools/editor/scenes_dock.cpp @@ -326,6 +326,10 @@ String ScenesDock::get_selected_path() const { return "res://"+path; } +String ScenesDock::get_current_path() const { + + return path; +} void ScenesDock::_thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) { @@ -388,6 +392,25 @@ void ScenesDock::_search(EditorFileSystemDirectory *p_path,List<FileInfo>* match 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); + } + matches->push_back(fi); if (matches->size()>p_max_items) return; @@ -517,6 +540,27 @@ void ScenesDock::_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; + } + + filelist.push_back(fi); } @@ -533,12 +577,33 @@ void ScenesDock::_update_files(bool p_keep_selection) { Ref<Texture> type_icon; - if (has_icon(type,ei)) { - type_icon=get_icon(type,ei); - } else { - type_icon=get_icon(oi,ei); + String tooltip=fname; + + if (E->get().import_status==0) { + + if (has_icon(type,ei)) { + type_icon=get_icon(type,ei); + } else { + type_icon=get_icon(oi,ei); + } + } else if (E->get().import_status==1) { + type_icon=get_icon("DependencyOk","EditorIcons"); + } else if (E->get().import_status==2) { + type_icon=get_icon("DependencyChanged","EditorIcons"); + tooltip+"\nStatus: Needs Re-Import"; + } else if (E->get().import_status==3) { + type_icon=get_icon("ImportFail","EditorIcons"); + tooltip+"\nStatus: Missing Dependencies"; + } + + if (E->get().sources.size()) { + for(int i=0;i<E->get().sources.size();i++) { + tooltip+="\nSource: "+E->get().sources[i]; + } } + + if (use_thumbnails) { files->add_item(fname,file_thumbnail,true); files->set_item_metadata(files->get_item_count()-1,fp); @@ -557,6 +622,9 @@ void ScenesDock::_update_files(bool p_keep_selection) { if (cselection.has(fname)) files->select(files->get_item_count()-1,false); + files->set_item_tooltip(files->get_item_count()-1,tooltip); + + } @@ -997,6 +1065,40 @@ void ScenesDock::_file_option(int p_option) { case FILE_INFO: { } break; + case FILE_REIMPORT: { + + + Vector<String> reimport; + for(int i=0;i<files->get_item_count();i++) { + + if (!files->is_selected(i)) + continue; + + String path = files->get_item_metadata(i); + reimport.push_back(path); + } + + ERR_FAIL_COND(reimport.size()==0); + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(reimport[0]); + ERR_FAIL_COND(!rimd.is_valid()); + String editor=rimd->get_editor(); + + if (editor.begins_with("texture_")) { //compatibility fix for old texture format + editor="texture"; + } + + Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(editor); + ERR_FAIL_COND(!rimp.is_valid()); + + if (reimport.size()==1) { + rimp->import_dialog(reimport[0]); + } else { + rimp->reimport_multiple_files(reimport); + + } + + } break; } } @@ -1362,6 +1464,8 @@ void ScenesDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) { Vector<String> filenames; bool all_scenes=true; + bool all_can_reimport=true; + Set<String> types; for(int i=0;i<files->get_item_count();i++) { @@ -1381,6 +1485,38 @@ void ScenesDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) { } + EditorFileSystemDirectory *efsd=NULL; + int pos; + + efsd = EditorFileSystem::get_singleton()->find_file(path,&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; + + } + filenames.push_back(path); if (EditorFileSystem::get_singleton()->get_file_type(path)!="PackedScene") all_scenes=false; @@ -1412,12 +1548,34 @@ void ScenesDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) { file_options->add_item(TTR("Move To.."),FILE_MOVE); } + file_options->add_item(TTR("Delete"),FILE_REMOVE); + //file_options->add_item(TTR("Info"),FILE_INFO); file_options->add_separator(); file_options->add_item(TTR("Show In File Manager"),FILE_SHOW_IN_EXPLORER); + if (all_can_reimport && types.size()==1) { //all can reimport and are of the same type + + + bool valid=true; + Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(types.front()->get()); + if (rimp.is_valid()) { + + if (filenames.size()>1 && !rimp->can_reimport_multiple_files()) { + valid=false; + } + } else { + valid=false; + } + + if (valid) { + file_options->add_separator(); + file_options->add_item(TTR("Re-Import.."),FILE_REIMPORT); + } + } + file_options->set_pos(files->get_global_pos() + p_pos); file_options->popup(); diff --git a/tools/editor/scenes_dock.h b/tools/editor/scenes_dock.h index 1d6d03374a..9a0d6c87cf 100644 --- a/tools/editor/scenes_dock.h +++ b/tools/editor/scenes_dock.h @@ -153,6 +153,8 @@ class ScenesDock : public VBoxContainer { String name; String path; StringName type; + int import_status; //0 not imported, 1 - ok, 2- must reimport, 3- broken + Vector<String> sources; bool operator<(const FileInfo& fi) const { return name < fi.name; @@ -171,6 +173,8 @@ protected: public: String get_selected_path() const; + + String get_current_path() const; void focus_on_filter(); void fix_dependencies(const String& p_for_file); |