/*************************************************************************/ /* editor_node.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "version.h" #include "editor_node.h" #include "print_string.h" #include "editor_icons.h" #include "editor_fonts.h" #include "editor_help.h" #include "scene/io/scene_saver.h" #include "scene/io/scene_loader.h" #include "core/io/resource_saver.h" #include "core/io/resource_loader.h" #include "servers/physics_2d_server.h" #include "scene/resources/packed_scene.h" #include "editor_settings.h" #include "io_plugins/editor_import_collada.h" #include "globals.h" #include #include "object_type_db.h" #include "os/keyboard.h" #include "os/os.h" #include "os/file_access.h" #include "message_queue.h" #include "path_remap.h" #include "translation.h" #include "pvrtc_compress.h" #include "editor_file_system.h" #include "register_exporters.h" #include "bind/core_bind.h" #include "io/zip_io.h" // plugins #include "plugins/sprite_frames_editor_plugin.h" #include "plugins/canvas_item_editor_plugin.h" #include "plugins/spatial_editor_plugin.h" #include "plugins/sample_editor_plugin.h" #include "plugins/sample_library_editor_plugin.h" #include "plugins/sample_player_editor_plugin.h" #include "plugins/camera_editor_plugin.h" #include "plugins/style_box_editor_plugin.h" #include "plugins/resource_preloader_editor_plugin.h" #include "plugins/item_list_editor_plugin.h" #include "plugins/stream_editor_plugin.h" #include "plugins/multimesh_editor_plugin.h" #include "plugins/theme_editor_plugin.h" #include "plugins/tile_map_editor_plugin.h" #include "plugins/cube_grid_theme_editor_plugin.h" #include "plugins/shader_editor_plugin.h" #include "plugins/path_editor_plugin.h" #include "plugins/rich_text_editor_plugin.h" #include "plugins/collision_polygon_editor_plugin.h" #include "plugins/script_editor_plugin.h" #include "plugins/path_2d_editor_plugin.h" #include "plugins/particles_editor_plugin.h" #include "plugins/particles_2d_editor_plugin.h" #include "plugins/font_editor_plugin.h" #include "plugins/animation_editor_plugin.h" #include "plugins/animation_tree_editor_plugin.h" #include "plugins/tile_set_editor_plugin.h" #include "plugins/animation_player_editor_plugin.h" // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" #include "tools/editor/io_plugins/editor_font_import_plugin.h" #include "tools/editor/io_plugins/editor_sample_import_plugin.h" #include "tools/editor/io_plugins/editor_translation_import_plugin.h" EditorNode *EditorNode::singleton=NULL; void EditorNode::_update_title() { String edited = edited_scene?edited_scene->get_filename():String(); String title = edited.empty()?String(VERSION_FULL_NAME):String(_MKSTR(VERSION_NAME) + String(" - ")+edited.get_file()); if (unsaved_cache) title+=" (*)"; OS::get_singleton()->set_window_title(title); } void EditorNode::_unhandled_input(const InputEvent& p_event) { if (p_event.type==InputEvent::KEY && p_event.key.pressed && !p_event.key.echo) { switch(p_event.key.scancode) { case KEY_F1: _editor_select(3); break; case KEY_F2: _editor_select(0); break; case KEY_F3: _editor_select(1); break; case KEY_F4: _editor_select(2); break; case KEY_F5: _menu_option_confirm((p_event.key.mod.control&&p_event.key.mod.shift)?RUN_PLAY_CUSTOM_SCENE:RUN_PLAY,true); break; case KEY_F6: _menu_option_confirm(RUN_PLAY_SCENE,true); break; case KEY_F7: _menu_option_confirm(RUN_PAUSE,true); break; case KEY_F8: _menu_option_confirm(RUN_STOP,true); break; } } } void EditorNode::_notification(int p_what) { if (p_what==NOTIFICATION_EXIT_SCENE) { editor_data.save_editor_external_data(); log->deinit(); // do not get messages anymore } if (p_what==NOTIFICATION_PROCESS) { //force the whole tree viewport #if 0 { Rect2 grect = scene_root_base->get_global_rect(); Rect2 grectsrp = scene_root_parent->get_global_rect(); if (grect!=grectsrp) { scene_root_parent->set_pos(grect.pos); scene_root_parent->set_size(grect.size); } } #endif if (opening_prev && confirmation->is_hidden()) opening_prev=false; if (unsaved_cache != (saved_version!=editor_data.get_undo_redo().get_version())) { unsaved_cache = (saved_version!=editor_data.get_undo_redo().get_version()); _update_title(); } //get_root_node()->set_rect(viewport->get_global_rect()); //update the circle uint64_t frame = OS::get_singleton()->get_frames_drawn(); uint32_t tick = OS::get_singleton()->get_ticks_msec(); if (frame!=circle_step_frame && (tick-circle_step_msec)>(1000/8)) { circle_step++; if (circle_step>=8) circle_step=0; circle_step_msec=tick; circle_step_frame=frame+1; update_menu->set_icon(gui_base->get_icon("Progress"+itos(circle_step+1),"EditorIcons")); } scene_root->set_size_override(true,Size2(Globals::get_singleton()->get("display/width"),Globals::get_singleton()->get("display/height"))); editor_selection->update(); { uint32_t p32 = AudioServer::get_singleton()->read_output_peak()>>8; float peak = p32==0? -80 : Math::linear2db(p32 / 65535.0); if (peak<-80) peak=-80; float vu = audio_vu->get_val(); if (peak > vu) { audio_vu->set_val(peak); } else { float new_vu = vu - get_process_delta_time()*70.0; if (new_vu<-80) new_vu=-80; if (new_vu !=-80 && vu !=-80) audio_vu->set_val(new_vu); } } } if (p_what==NOTIFICATION_ENTER_SCENE) { //MessageQueue::get_singleton()->push_call(this,"_get_scene_metadata"); get_scene()->set_editor_hint(true); get_scene()->get_root()->set_as_audio_listener(false); get_scene()->get_root()->set_as_audio_listener_2d(false); get_scene()->set_auto_accept_quit(false); //VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport(),false); //import_monitor->scan_changes(); } if (p_what==NOTIFICATION_READY) { VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport(),true); VisualServer::get_singleton()->viewport_set_hide_canvas(get_scene_root()->get_viewport(),true); _editor_select(1); if (defer_load_scene!="") { #ifdef OLD_SCENE_FORMAT_ENABLED if (convert_old) { get_scene()->quit(); Node *scn = SceneLoader::load(defer_load_scene,true); ERR_EXPLAIN("Couldn't load scene: "+defer_load_scene); ERR_FAIL_COND(!scn); Ref sdata = memnew( PackedScene ); Error err = sdata->pack(scn); ERR_EXPLAIN("Couldn't repack scene: "+defer_load_scene); ERR_FAIL_COND(err!=OK); err = ResourceSaver::save(defer_load_scene,sdata); ERR_EXPLAIN("Couldn't resave scene: "+defer_load_scene); ERR_FAIL_COND(err!=OK); return; } #endif 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_scene()->quit(); } /* if (defer_optimize!="") { Error ok = save_optimized_copy(defer_optimize,defer_optimize_preset); defer_optimize_preset=""; if (ok!=OK) OS::get_singleton()->set_exit_code(255); get_scene()->quit(); } */ if (export_defer.platform!="") { project_export_settings->export_platform(export_defer.platform,export_defer.path,export_defer.debug,export_defer.password,true); export_defer.platform=""; } } if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) { /* List > cached; ResourceCache::get_cached_resources(&cached); bool changes=false; for(List >::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")); } */ EditorFileSystem::get_singleton()->scan_sources(); } if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) { _menu_option_confirm(FILE_QUIT, false); }; } void EditorNode::_fs_changed() { for(Set::Element *E=file_dialogs.front();E;E=E->next()) { E->get()->invalidate(); } } void EditorNode::_sources_changed(bool p_exist) { if (p_exist) { sources_button->set_icon(gui_base->get_icon("DependencyChanged","EditorIcons")); sources_button->set_disabled(false); } else { sources_button->set_icon(gui_base->get_icon("DependencyOk","EditorIcons")); sources_button->set_disabled(true); } } void EditorNode::_vp_resized() { } void EditorNode::_node_renamed() { if (property_editor) property_editor->update_tree(); } Error EditorNode::load_resource(const String& p_scene) { RES res = ResourceLoader::load(p_scene); ERR_FAIL_COND_V(!res.is_valid(),ERR_CANT_OPEN); edit_resource(res); return OK; } void EditorNode::edit_resource(const Ref& p_resource) { _resource_selected(p_resource,""); } void EditorNode::edit_node(Node *p_node) { push_item(p_node); } void EditorNode::open_resource(const String& p_type) { file->set_mode(FileDialog::MODE_OPEN_FILE); List extensions; ResourceLoader::get_recognized_extensions_for_type(p_type,&extensions); file->clear_filters(); for(int i=0;iadd_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); } //file->set_current_path(current_path); file->popup_centered_ratio(); current_option=RESOURCE_LOAD; } void EditorNode::save_resource(const Ref& p_resource) { ERR_FAIL_COND(p_resource.is_null() || p_resource->get_path()=="" || p_resource->get_path().find("::")!=-1); resources_dock->save_resource(p_resource->get_path(),p_resource); } void EditorNode::save_resource_as(const Ref& p_resource) { resources_dock->save_resource_as(p_resource); } void EditorNode::_menu_option(int p_option) { _menu_option_confirm(p_option,false); } void EditorNode::_menu_confirm_current() { _menu_option_confirm(current_option,true); } void EditorNode::_dialog_display_file_error(String p_file,Error p_error) { if (p_error) { current_option=-1; //accept->"()->hide(); accept->get_ok()->set_text("I see.."); switch(p_error) { case ERR_FILE_CANT_WRITE: { accept->set_text("Can't open file for writing: "+p_file.extension()); } break; case ERR_FILE_UNRECOGNIZED: { accept->set_text("File format requested unknown: "+p_file.extension()); } break; default: { accept->set_text("Error Saving."); }break; } accept->popup_centered(Size2(300,70));; } } void EditorNode::_get_scene_metadata() { Node *scene = edited_scene; if (!scene) return; if (scene->has_meta("__editor_plugin_states__")) { Dictionary md = scene->get_meta("__editor_plugin_states__"); editor_data.set_editor_states(md); } if (scene->has_meta("__editor_run_settings__")) { Dictionary md = scene->get_meta("__editor_run_settings__"); if (md.has("run_mode")) run_settings_dialog->set_run_mode(md["run_mode"]); if (md.has("custom_args")) run_settings_dialog->set_custom_arguments(md["custom_args"]); } } void EditorNode::_set_scene_metadata() { Node *scene = edited_scene; if (!scene) return; { /* Editor States */ Dictionary md = editor_data.get_editor_states(); if (!md.empty()) { scene->set_meta("__editor_plugin_states__",md); } } { /* Run Settings */ Dictionary md; md["run_mode"]=run_settings_dialog->get_run_mode(); md["custom_args"]=run_settings_dialog->get_custom_arguments(); scene->set_meta("__editor_run_settings__",md); } } static Error _fix_object_paths(Object* obj, Node* root, String save_path) { Globals* g = Globals::get_singleton(); String import_dir = root->get_meta("__editor_import_file__"); import_dir = import_dir.get_base_dir(); import_dir = DirAccess::normalize_path(import_dir); if (import_dir[import_dir.length()-1] != '/') { import_dir = import_dir + "/"; }; String resource_dir = DirAccess::normalize_path(g->get_resource_path()); if (resource_dir[resource_dir.length()-1] != '/') { resource_dir = resource_dir + "/"; }; List list; obj->get_property_list(&list, false); List::Element *E = list.front(); while (E) { Variant v = obj->get(E->get().name); if (v.get_type() == Variant::OBJECT) { Ref res = (RefPtr)v; if (res.is_null()) { E = E->next(); continue; } if (res->get_path() != "") { String res_path = res->get_path(); res_path = Globals::get_singleton()->globalize_path(res_path); res_path = DirAccess::normalize_path(res_path); if (res_path.find(resource_dir) != 0) { // path of resource is not inside engine's resource path String new_path; if (res_path.find(import_dir) == 0) { // path of resource is relative to path of import file new_path = save_path + "/" + res_path.substr(import_dir.length(), res_path.length() - import_dir.length()); } else { // path of resource is not relative to import file new_path = save_path + "/" + res_path.get_file(); }; res->set_path(g->localize_path(new_path)); DirAccess* d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->make_dir_recursive(new_path.get_base_dir()); printf("copying from %ls to %ls\n", res_path.c_str(), new_path.c_str()); Error err = d->copy(res_path, new_path); memdelete(d); ERR_FAIL_COND_V(err != OK, err); } } else { _fix_object_paths(res.operator->(), root, save_path); }; }; E = E->next(); }; return OK; }; static Error _fix_imported_scene_paths(Node* node, Node* root, String save_path) { if (node == root || node->get_owner() == root) { Error e = _fix_object_paths(node, root, save_path); ERR_FAIL_COND_V(e != OK, e); }; for (int i=0; iget_child_count(); i++) { Error e = _fix_imported_scene_paths(node->get_child(i), root, save_path); ERR_FAIL_COND_V(e != OK, e); }; return OK; }; bool EditorNode::_find_and_save_edited_subresources(Object *obj,Set& processed,int32_t flags) { bool ret_changed=false; List pi; obj->get_property_list(&pi); for (List::Element *E=pi.front();E;E=E->next()) { if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) continue; switch(E->get().type) { case Variant::OBJECT: { RES res = obj->get(E->get().name); if (res.is_null() || processed.has(res)) break; processed.insert(res); bool changed = res->is_edited(); res->set_edited(false); bool subchanged = _find_and_save_edited_subresources(res.ptr(),processed,flags); if (res->get_path().is_resource_file()) { if (changed || subchanged) { //save print_line("Also saving modified external resource: "+res->get_path()); Error err = ResourceSaver::save(res->get_path(),res,flags); } } else { ret_changed=true; } } break; case Variant::ARRAY: { /*Array varray=p_variant; int len=varray.size(); for(int i=0;i keys; d.get_key_list(&keys); for(List::Element *E=keys.front();E;E=E->next()) { Variant v = d[E->get()]; _find_resources(v); } */ } break; default: {} } } return ret_changed; } void EditorNode::_save_edited_subresources(Node* scene,Set& processed,int32_t flags) { _find_and_save_edited_subresources(scene,processed,flags); for(int i=0;iget_child_count();i++) { Node *n = scene->get_child(i); if (n->get_owner()!=edited_scene) continue; _save_edited_subresources(n,processed,flags); } } void EditorNode::_save_scene(String p_file) { Node *scene = edited_scene; if (!scene) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a tree root."); accept->popup_centered(Size2(300,70));; return; } editor_data.apply_changes_in_editors(); if (editor_plugin_screen) { scene->set_meta("__editor_plugin_screen__",editor_plugin_screen->get_name()); } _set_scene_metadata(); Ref sdata = memnew( PackedScene ); Error err = sdata->pack(scene); if (err!=OK) { 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; } sdata->set_import_metadata(scene_import_metadata); int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) flg|=ResourceSaver::FLAG_RELATIVE_PATHS; if (EditorSettings::get_singleton()->get("on_save/save_paths_without_extension")) flg|=ResourceSaver::FLAG_NO_EXTENSION; err = ResourceSaver::save(p_file,sdata,flg); Set processed; _save_edited_subresources(scene,processed,flg); editor_data.save_editor_external_data(); if (err==OK) { scene->set_filename( Globals::get_singleton()->localize_path(p_file) ); //EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type()); saved_version=editor_data.get_undo_redo().get_version(); _update_title(); } else { _dialog_display_file_error(p_file,err); } }; void EditorNode::_import_action(const String& p_action) { #if 0 import_confirmation->hide(); if (p_action=="re-import") { _import(_tmp_import_path); } if (p_action=="update") { Node *src = EditorImport::import_scene(_tmp_import_path); if (!src) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text("Error importing scene."); accept->popup_centered(Size2(300,70));; return; } //as soon as the scene is imported, version hashes must be generated for comparison against saved scene EditorImport::generate_version_hashes(src); Node *dst = SceneLoader::load(editor_data.get_imported_scene(Globals::get_singleton()->localize_path(_tmp_import_path))); if (!dst) { memdelete(src); //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text("Error load scene to update."); accept->popup_centered(Size2(300,70));; return; } List conflicts; EditorImport::check_conflicts(src,dst,&conflicts); bool conflicted=false; for (List::Element *E=conflicts.front();E;E=E->next()) { if (E->get().status==EditorImport::Conflict::STATUS_CONFLICT) { conflicted=true; break; } } if (conflicted) { import_conflicts_dialog->popup(src,dst,conflicts); return; } _import_with_conflicts(src,dst,conflicts); //not conflicted, just reimport! } #endif } void EditorNode::_import(const String &p_file) { #if 0 Node *new_scene = EditorImport::import_scene(p_file); if (!new_scene) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text("Error importing scene."); accept->popup_centered(Size2(300,70));; return; } //as soon as the scene is imported, version hashes must be generated for comparison against saved scene EditorImport::generate_version_hashes(new_scene); Node *old_scene = edited_scene; _hide_top_editors(); set_edited_scene(NULL); editor_data.clear_editor_states(); if (old_scene) { memdelete(old_scene); } set_edited_scene(new_scene); scene_tree_dock->set_selected(new_scene); //_get_scene_metadata(); editor_data.get_undo_redo().clear_history(); saved_version=editor_data.get_undo_redo().get_version(); _update_title(); #endif } void EditorNode::_dialog_action(String p_file) { switch(current_option) { case RESOURCE_LOAD: { RES res = ResourceLoader::load(p_file); if (res.is_null()) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("ok :("); accept->set_text("Failed to load resource."); return; }; push_item(res.operator->() ); } break; case FILE_OPEN_SCENE: { load_scene(p_file); } break; #ifdef OLD_SCENE_FORMAT_ENABLED case FILE_OPEN_OLD_SCENE: { String lpath = Globals::get_singleton()->localize_path(p_file); if (!lpath.begins_with("res://")) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text("Error loading scene, it must be inside the project path. Use 'Import' to open the scene, then save it inside the project path."); accept->popup_centered(Size2(300,120)); return ; } Node*new_scene=SceneLoader::load(lpath,true); if (!new_scene) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text("Error loading scene."); accept->popup_centered(Size2(300,70));; return ; } Node *old_scene = edited_scene; _hide_top_editors(); set_edited_scene(NULL); editor_data.clear_editor_states(); if (old_scene) { memdelete(old_scene); } set_edited_scene(new_scene); scene_tree_dock->set_selected(new_scene); _get_scene_metadata(); editor_data.get_undo_redo().clear_history(); saved_version=editor_data.get_undo_redo().get_version(); _update_title(); _add_to_recent_scenes(lpath); if (new_scene->has_meta("__editor_plugin_screen__")) { String editor = new_scene->get_meta("__editor_plugin_screen__"); for(int i=0;iget_name()==editor) { _editor_select(i); break; } } } } break; #endif case FILE_SAVE_OPTIMIZED: { } break; case FILE_DUMP_STRINGS: { save_translatable_strings(p_file); } break; case FILE_SAVE_SUBSCENE: { List selection = editor_selection->get_selected_node_list(); if (selection.size()!=1) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation requieres a single selected node."); accept->popup_centered(Size2(300,70));; break; } Node *base = selection.front()->get(); Map reown; reown[get_edited_scene()]=base; Node *copy = base->duplicate_and_reown(reown); if (copy) { Ref sdata = memnew( PackedScene ); Error err = sdata->pack(copy); memdelete(copy); if (err!=OK) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Couldn't save subscene. Likely dependencies (instances) couldn't be satisfied."); accept->popup_centered(Size2(300,70));; return; } int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) flg|=ResourceSaver::FLAG_RELATIVE_PATHS; if (EditorSettings::get_singleton()->get("on_save/save_paths_without_extension")) flg|=ResourceSaver::FLAG_NO_EXTENSION; err = ResourceSaver::save(p_file,sdata,flg); if (err!=OK) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Error saving scene."); accept->popup_centered(Size2(300,70));; break; } //EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type()); } else { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Error duplicating scene to save it."); accept->popup_centered(Size2(300,70));; break; } } break; case FILE_SAVE_SCENE: case FILE_SAVE_AS_SCENE: { if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { _save_scene(p_file); } } break; case FILE_EXPORT_MESH_LIBRARY: { Ref ml; if (file_export_lib_merge->is_pressed() && FileAccess::exists(p_file)) { ml=ResourceLoader::load(p_file,"MeshLibrary"); if (ml.is_null()) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Can't load MeshLibrary for merging!."); accept->popup_centered(Size2(300,70));; return; } } if (ml.is_null()) { ml = Ref( memnew( MeshLibrary )); } MeshLibraryEditor::update_library_file(edited_scene,ml,true); Error err = ResourceSaver::save(p_file,ml); if (err) { accept->get_ok()->set_text("I see.."); accept->set_text("Error saving MeshLibrary!."); accept->popup_centered(Size2(300,70));; return; } } break; case FILE_EXPORT_TILESET: { Ref ml; if (file_export_lib_merge->is_pressed() && FileAccess::exists(p_file)) { ml=ResourceLoader::load(p_file,"TileSet"); if (ml.is_null()) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Can't load TileSet for merging!."); accept->popup_centered(Size2(300,70));; return; } } if (ml.is_null()) { ml = Ref( memnew( TileSet )); } TileSetEditor::update_library_file(edited_scene,ml,true); Error err = ResourceSaver::save(p_file,ml); if (err) { accept->get_ok()->set_text("I see.."); accept->set_text("Error saving TileSet!."); accept->popup_centered(Size2(300,70));; return; } } break; case SETTINGS_LOAD_EXPORT_TEMPLATES: { FileAccess *fa=NULL; zlib_filefunc_def io = zipio_create_io_from_file(&fa); unzFile pkg = unzOpen2(p_file.utf8().get_data(), &io); if (!pkg) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Can't open export templates zip."); accept->popup_centered(Size2(300,70));; return; } int ret = unzGoToFirstFile(pkg); int fc=0; //coun them while(ret==UNZ_OK) { fc++; ret = unzGoToNextFile(pkg); } ret = unzGoToFirstFile(pkg); EditorProgress p("ltask","Loading Export Templates",fc); print_line("BEGIN IMPORT"); fc=0; while(ret==UNZ_OK) { //get filename unz_file_info info; char fname[16384]; ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); String file=fname; Vector data; data.resize(info.uncompressed_size); //read ret = unzOpenCurrentFile(pkg); ret = unzReadCurrentFile(pkg,data.ptr(),data.size()); unzCloseCurrentFile(pkg); print_line(fname); //for(int i=0;i<512;i++) { // print_line(itos(data[i])); //} file=file.get_file(); p.step("Importing: "+file,fc); print_line("IMPORT "+file); FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_settings_path()+"/templates/"+file,FileAccess::WRITE); ERR_CONTINUE(!f); f->store_buffer(data.ptr(),data.size()); memdelete(f); ret = unzGoToNextFile(pkg); fc++; } unzClose(pkg); } break; default: { //save scene? if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { _save_scene(p_file); } } break; } } void EditorNode::push_item(Object *p_object,const String& p_property) { if (!p_object) { property_editor->edit(NULL); scene_tree_dock->set_selected(NULL); return; } uint32_t id = p_object->get_instance_ID(); if (id!=editor_history.get_current()) { if (p_property=="") editor_history.add_object(id); else editor_history.add_object(id,p_property); } _edit_current(); } void EditorNode::_property_editor_forward() { if (editor_history.next()) _edit_current(); } void EditorNode::_property_editor_back() { if (editor_history.previous()) _edit_current(); } void EditorNode::_imported(Node *p_node) { Node *scene = edited_scene; set_edited_scene(p_node); if (scene) { String path = scene->get_filename(); p_node->set_filename(path); memdelete(scene); } } void EditorNode::_hide_top_editors() { if (editor_plugin_over) editor_plugin_over->make_visible(false); editor_plugin_over=NULL; } void EditorNode::_edit_current() { uint32_t current = editor_history.get_current(); Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL; this->current=current_obj; editor_path->update_path(); if (!current_obj) { scene_tree_dock->set_selected(NULL); property_editor->edit( NULL ); object_menu->set_disabled(true); return; } object_menu->set_disabled(true); if (current_obj->is_type("Resource")) { Resource *current_res = current_obj->cast_to(); ERR_FAIL_COND(!current_res); scene_tree_dock->set_selected(NULL); property_editor->edit( current_res ); object_menu->set_disabled(false); resources_dock->add_resource(Ref(current_res)); top_pallete->set_current_tab(1); } if (current_obj->is_type("Node")) { Node * current_node = current_obj->cast_to(); ERR_FAIL_COND(!current_node); ERR_FAIL_COND(!current_node->is_inside_scene()); property_editor->edit( current_node ); scene_tree_dock->set_selected(current_node); object_menu->get_popup()->clear(); top_pallete->set_current_tab(0); } /* Take care of PLUGIN EDITOR */ EditorPlugin *main_plugin = editor_data.get_editor(current_obj); if (main_plugin) { if (main_plugin!=editor_plugin_screen) { // update screen main_plugin if (editor_plugin_screen) editor_plugin_screen->make_visible(false); editor_plugin_screen=main_plugin; editor_plugin_screen->edit(current_obj); editor_plugin_screen->make_visible(true); for(int i=0;iset_current_tab(i); break; } } } else { editor_plugin_screen->edit(current_obj); } } EditorPlugin *sub_plugin = editor_data.get_subeditor(current_obj); if (sub_plugin) { if (editor_plugin_over) editor_plugin_over->make_visible(false); editor_plugin_over=sub_plugin; editor_plugin_over->edit(current_obj); editor_plugin_over->make_visible(true); } else if (editor_plugin_over) { editor_plugin_over->make_visible(false); editor_plugin_over=NULL; } /* if (!plugin || plugin->has_main_screen()) { // remove the OVER plugin if exists if (editor_plugin_over) editor_plugin_over->make_visible(false); editor_plugin_over=NULL; } */ /* Take care of OBJECT MENU */ object_menu->set_disabled(false); PopupMenu *p=object_menu->get_popup(); p->clear(); p->add_item("Copy Params",OBJECT_COPY_PARAMS); p->add_item("Set Params",OBJECT_PASTE_PARAMS); p->add_separator(); p->add_icon_item(gui_base->get_icon("Help","EditorIcons"),"Class Reference",OBJECT_REQUEST_HELP); List methods; current_obj->get_method_list(&methods); if (!methods.empty()) { bool found=false; List::Element *I=methods.front(); int i=0; while(I) { if (I->get().flags&METHOD_FLAG_EDITOR) { if (!found) { p->add_separator(); found=true; } p->add_item(I->get().name.capitalize(),OBJECT_METHOD_BASE+i); } i++; I=I->next(); } } //p->add_separator(); //p->add_item("All Methods",OBJECT_CALL_METHOD); _update_keying(); } void EditorNode::_resource_selected(const RES& p_res,const String& p_property) { if (p_res.is_null()) return; RES r=p_res; push_item(r.operator->(),p_property); } void EditorNode::_run(bool p_current,const String& p_custom) { if (editor_run.get_status()==EditorRun::STATUS_PLAY) { play_button->set_pressed(!_playing_edited); play_scene_button->set_pressed(_playing_edited); return; } play_button->set_pressed(false); pause_button->set_pressed(false); play_scene_button->set_pressed(false); String current_filename; String run_filename; String args; if (p_current || (edited_scene && p_custom==edited_scene->get_filename())) { Node *scene = edited_scene; if (!scene) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("No scene to run exists."); accept->popup_centered(Size2(300,70));; return; } if (scene->get_filename()=="") { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Scene has never been saved. Save before running!"); accept->popup_centered(Size2(300,70));; return; } bool autosave = EDITOR_DEF("run/auto_save_before_running",true); if (autosave) { _menu_option(FILE_SAVE_SCENE); } if (run_settings_dialog->get_run_mode()==RunSettingsDialog::RUN_LOCAL_SCENE) { run_filename=scene->get_filename(); } else { args=run_settings_dialog->get_custom_arguments(); current_filename=scene->get_filename(); } } else if (p_custom!="") { run_filename=p_custom; } if (run_filename=="") { //evidently, run the scene run_filename=GLOBAL_DEF("application/main_scene",""); if (run_filename=="") { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("No main scene has ever been defined.\nSelect one from \"Project Settings\" under the 'application' category."); accept->popup_centered(Size2(300,100));; return; } } if (bool(EDITOR_DEF("run/auto_save_before_running",true))) { if (unsaved_cache) { Node *scene = edited_scene; if (scene) { //only autosave if there is a scene obviously if (scene->get_filename()=="") { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Current scene was never saved, please save scene before running."); accept->popup_centered(Size2(300,70));; return; } _save_scene(scene->get_filename()); } } editor_data.save_editor_external_data(); } List breakpoints; editor_data.get_editor_breakpoints(&breakpoints); Error error = editor_run.run(run_filename,args,breakpoints,current_filename); if (error!=OK) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Could not start subprocess!"); accept->popup_centered(Size2(300,70));; return; } emit_signal("play_pressed"); if (p_current) { play_scene_button->set_pressed(true); } else { play_button->set_pressed(true); } _playing_edited=p_current; } void EditorNode::_cleanup_scene() { Node *scene = edited_scene; editor_selection->clear(); editor_data.clear_editor_states(); editor_history.clear(); _hide_top_editors(); animation_editor->cleanup(); resources_dock->cleanup(); property_editor->edit(NULL); scene_import_metadata.unref(); set_edited_scene(NULL); if (scene) { if (scene->get_filename()!="") { previous_scenes.push_back(scene->get_filename()); } memdelete(scene); } editor_data.get_undo_redo().clear_history(); saved_version=editor_data.get_undo_redo().get_version(); run_settings_dialog->set_run_mode(0); run_settings_dialog->set_custom_arguments("-l $scene"); List > cached; ResourceCache::get_cached_resources(&cached); for(List >::Element *E=cached.front();E;E=E->next()) { String path = E->get()->get_path(); if (path.is_resource_file()) { ERR_PRINT(("Stray resource not cleaned:"+path).utf8().get_data()); } } } void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { current_option=(MenuOptions)p_option; switch( p_option ) { case FILE_NEW_SCENE: { if (!p_confirmed) { confirmation->get_ok()->set_text("Yes"); //confirmation->get_cancel()->show(); confirmation->set_text("Start a New Scene? (Current will be lost)"); confirmation->popup_centered(Size2(300,70)); break; } _cleanup_scene(); } break; case FILE_OPEN_SCENE: { //print_tree(); file->set_mode(FileDialog::MODE_OPEN_FILE); //not for now? List extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); file->clear_filters(); for(int i=0;iadd_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); } //file->set_current_path(current_path); Node *scene = edited_scene; if (scene) { file->set_current_path(scene->get_filename()); }; file->set_title("Open Scene"); file->popup_centered_ratio(); } break; case FILE_QUICK_OPEN_SCENE: { quick_open->popup("PackedScene"); quick_open->set_title("Quick Open Scene.."); } break; case FILE_QUICK_OPEN_SCRIPT: { quick_open->popup("Script"); quick_open->set_title("Quick Open Script.."); } break; case FILE_OPEN_PREV: { if (previous_scenes.empty()) break; opening_prev=true; open_request(previous_scenes.back()->get()); } break; #ifdef OLD_SCENE_FORMAT_ENABLED case FILE_OPEN_OLD_SCENE: { //print_tree(); file->set_mode(FileDialog::MODE_OPEN_FILE); //not for now? file->clear_filters(); file->add_filter("*.xml"); //file->set_current_path(current_path); Node *scene = edited_scene; if (scene) { file->set_current_path(scene->get_filename()); }; file->set_title("Open Scene"); file->popup_centered_ratio(); } break; #endif case FILE_SAVE_SCENE: { Node *scene = edited_scene; if (scene && scene->get_filename()!="") { _save_scene(scene->get_filename()); return; }; // fallthrough to save_as }; case FILE_SAVE_AS_SCENE: { Node *scene = edited_scene; if (!scene) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a tree root."); accept->popup_centered(Size2(300,70));; break; } file->set_mode(FileDialog::MODE_SAVE_FILE); bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool()); List extensions; Ref sd = memnew( PackedScene ); ResourceSaver::get_recognized_extensions(sd,&extensions); file->clear_filters(); for(int i=0;iadd_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); } //file->set_current_path(current_path); if (scene->get_filename()!="") { file->set_current_path(scene->get_filename()); if (extensions.size()) { String ext=scene->get_filename().extension().to_lower(); if (extensions.find(ext)==NULL) { file->set_current_path(scene->get_filename().replacen("."+ext,"."+extensions.front()->get())); } } } else { String existing; if (extensions.size()) { existing="new_scene."+extensions.front()->get().to_lower(); } file->set_current_path(existing); } file->popup_centered_ratio(); file->set_title("Save Scene As.."); } break; case FILE_DUMP_STRINGS: { Node *scene = edited_scene; if (!scene) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a tree root."); accept->popup_centered(Size2(300,70));; break; } String cpath; if (scene->get_filename()!="") { cpath = scene->get_filename(); String fn = cpath.substr(0,cpath.length() - cpath.extension().size()); String ext=cpath.extension(); cpath=fn+".pot"; } else { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Please save the scene first."); accept->popup_centered(Size2(300,70));; break; } bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool()); file->set_current_path(cpath); file->set_title("Save Translatable Strings"); file->popup_centered_ratio(); } break; case FILE_SAVE_SUBSCENE: { Node *scene = edited_scene; if (!scene) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a scene."); accept->popup_centered(Size2(300,70));; break; } List selection = editor_selection->get_selected_node_list(); if (selection.size()!=1) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation requieres a single selected node."); accept->popup_centered(Size2(300,70));; break; } Node *tocopy = selection.front()->get(); if (tocopy!=edited_scene && tocopy->get_filename()!="") { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done on instanced scenes."); accept->popup_centered(Size2(300,70));; break; } file->set_mode(FileDialog::MODE_SAVE_FILE); List extensions; Ref sd = memnew( PackedScene ); ResourceSaver::get_recognized_extensions(sd,&extensions); file->clear_filters(); for(int i=0;iadd_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); } String existing; if (extensions.size()) { existing="new_scene."+extensions.front()->get().to_lower(); } file->set_current_path(existing); file->popup_centered_ratio(); file->set_title("Save Sub-Scene As.."); } break; case FILE_SAVE_OPTIMIZED: { Node *scene = edited_scene; #if 0 if (!scene) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a tree root."); accept->popup_centered(Size2(300,70));; break; } //file->set_current_path(current_path); String cpath; if (scene->get_filename()!="") { cpath = scene->get_filename(); String fn = cpath.substr(0,cpath.length() - cpath.extension().size()); String ext=cpath.extension(); cpath=fn+".optimized.scn"; optimized_save->set_optimized_scene(cpath); optimized_save->popup_centered(Size2(500,143)); } else { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Please save the scene first."); accept->popup_centered(Size2(300,70));; break; } #endif } break; case FILE_EXPORT_PROJECT: { project_export_settings->popup_centered_ratio(); /* String target = export_db->get_current_platform(); Ref exporter = export_db->get_exporter(target); if (exporter.is_null()) { accept->set_text("No exporter for platform '"+target+"' yet."); accept->popup_centered(Size2(300,70));; return; } String extension = exporter->get_binary_extension(); print_line("for target: "+target+" extension: "+extension); file_export_password->set_editable( exporter->requieres_password(file_export_check->is_pressed())); file_export->clear_filters(); if (extension!="") { file_export->add_filter("*."+extension); } file_export->popup_centered_ratio();*/ } break; case FILE_EXPORT_MESH_LIBRARY: { if (!edited_scene) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a scene."); accept->popup_centered(Size2(300,70));; break; } List extensions; Ref ml( memnew( MeshLibrary) ); ResourceSaver::get_recognized_extensions(ml,&extensions); file_export_lib->clear_filters(); for(List::Element *E=extensions.front();E;E=E->next()) { file_export_lib->add_filter("*."+E->get()); } file_export_lib->popup_centered_ratio(); file_export_lib->set_title("Export Mesh Library"); } break; case FILE_EXPORT_TILESET: { List extensions; Ref ml( memnew( TileSet) ); ResourceSaver::get_recognized_extensions(ml,&extensions); file_export_lib->clear_filters(); for(List::Element *E=extensions.front();E;E=E->next()) { file_export_lib->add_filter("*."+E->get()); } file_export_lib->popup_centered_ratio(); file_export_lib->set_title("Export Tile Set"); } break; case SETTINGS_EXPORT_PREFERENCES: { //project_export_settings->popup_centered_ratio(); } break; case FILE_IMPORT_SUBSCENE: { //import_subscene->popup_centered_ratio(); if (!edited_scene) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a selected node."); accept->popup_centered(Size2(300,70));; break; } scene_tree_dock->import_subscene(); } break; case FILE_QUIT: { if (!p_confirmed) { confirmation->get_ok()->set_text("Quit"); //confirmation->get_cancel()->show(); confirmation->set_text("Exit the Editor?"); confirmation->popup_centered(Size2(300,70)); break; } get_scene()->quit(); } break; case FILE_EXTERNAL_OPEN_SCENE: { if (unsaved_cache && !p_confirmed) { confirmation->get_ok()->set_text("Open"); //confirmation->get_cancel()->show(); confirmation->set_text("Current scene not saved. Open anyway?"); confirmation->popup_centered(Size2(300,70)); break; } bool oprev=opening_prev; Error err = load_scene(external_file); if (err == OK && oprev) { previous_scenes.pop_back(); opening_prev=false; } } break; case EDIT_UNDO: { if (OS::get_singleton()->get_mouse_button_state()) break; // can't undo while mouse buttons are pressed String action = editor_data.get_undo_redo().get_current_action_name(); if (action!="") log->add_message("UNDO: "+action); editor_data.get_undo_redo().undo(); } break; case EDIT_REDO: { if (OS::get_singleton()->get_mouse_button_state()) break; // can't redo while mouse buttons are pressed editor_data.get_undo_redo().redo(); String action = editor_data.get_undo_redo().get_current_action_name(); if (action!="") log->add_message("REDO: "+action); } break; #if 0 case NODE_EXTERNAL_INSTANCE: { if (!edited_scene) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a selected node."); accept->popup_centered(Size2(300,70));; break; } Node *parent = scene_tree_editor->get_selected(); if (!parent) { current_option=-1; //confirmation->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("This operation can't be done without a selected node."); accept->popup_centered(Size2(300,70));; break; } Node*instanced_scene=SceneLoader::load(external_file,true); if (!instanced_scene) { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text(String("Error loading scene from ")+external_file); accept->popup_centered(Size2(300,70));; return; } instanced_scene->generate_instance_state(); instanced_scene->set_filename( Globals::get_singleton()->localize_path(external_file) ); editor_data.get_undo_redo().create_action("Instance Scene"); editor_data.get_undo_redo().add_do_method(parent,"add_child",instanced_scene); editor_data.get_undo_redo().add_do_method(instanced_scene,"set_owner",edited_scene); editor_data.get_undo_redo().add_do_reference(instanced_scene); editor_data.get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene); editor_data.get_undo_redo().commit_action(); // parent->add_child(instanced_scene); // instanced_scene->set_owner(edited_scene); _last_instanced_scene=instanced_scene; } break; #endif case OBJECT_REQUEST_HELP: { if (current) { _editor_select(3); emit_signal("request_help",current->get_type()); } } break; case OBJECT_COPY_PARAMS: { editor_data.apply_changes_in_editors();; if (current) editor_data.copy_object_params(current); } break; case OBJECT_PASTE_PARAMS: { editor_data.apply_changes_in_editors();; if (current) editor_data.paste_object_params(current); editor_data.get_undo_redo().clear_history(); } break; case OBJECT_CALL_METHOD: { editor_data.apply_changes_in_editors();; call_dialog->set_object(current); call_dialog->popup_centered_ratio(); } break; case RUN_PLAY: { _run(false); } break; case RUN_PLAY_CUSTOM_SCENE: { quick_run->popup("PackedScene",true); quick_run->set_title("Quick Run Scene.."); } break; case RUN_PAUSE: { emit_signal("pause_pressed"); } break; case RUN_STOP: { if (editor_run.get_status()==EditorRun::STATUS_STOP) break; editor_run.stop(); play_button->set_pressed(false); play_scene_button->set_pressed(false); pause_button->set_pressed(false); emit_signal("stop_pressed"); } break; case RUN_PLAY_SCENE: { _run(true); } break; case RUN_SCENE_SETTINGS: { run_settings_dialog->popup_run_settings(); } break; case RUN_SETTINGS: { project_settings->popup_project_settings(); } break; case RUN_FILE_SERVER: { //file_server bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER)); if (ischecked) { file_server->stop(); fileserver_menu->set_icon(gui_base->get_icon("FileServer","EditorIcons")); fileserver_menu->get_popup()->set_item_text( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Enable File Server"); } else { file_server->start(); fileserver_menu->set_icon(gui_base->get_icon("FileServerActive","EditorIcons")); fileserver_menu->get_popup()->set_item_text( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Disable File Server"); } fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),!ischecked); } break; case RUN_DEPLOY_DUMB_CLIENTS: { bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS)); fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked); } break; case SETTINGS_UPDATE_ALWAYS: { update_menu->get_popup()->set_item_checked(0,true); update_menu->get_popup()->set_item_checked(1,false); OS::get_singleton()->set_low_processor_usage_mode(false); } break; case SETTINGS_UPDATE_CHANGES: { update_menu->get_popup()->set_item_checked(0,false); update_menu->get_popup()->set_item_checked(1,true); OS::get_singleton()->set_low_processor_usage_mode(true); } break; case SETTINGS_PREFERENCES: { settings_config_dialog->popup_edit_settings(); } break; case SETTINGS_IMPORT: { import_settings->popup_import_settings(); } break; case SETTINGS_OPTIMIZED_PRESETS: { //optimized_presets->popup_centered_ratio(); } break; case SETTINGS_SHOW_ANIMATION: { animation_panel_make_visible( ! animation_panel->is_visible() ); } break; case SETTINGS_LOAD_EXPORT_TEMPLATES: { file_templates->popup_centered_ratio(); } break; case SETTINGS_ABOUT: { about->popup_centered(Size2(500,130)); } break; case SOURCES_REIMPORT: { reimport_dialog->popup_reimport(); } break; case DEPENDENCY_UPDATE_LOCAL: { /* List > cached; ResourceCache::get_cached_resources(&cached); for(List >::Element *E=cached.front();E;E=E->next()) { if (!E->get()->can_reload_from_file()) 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(); } } sources_button->get_popup()->set_item_disabled(sources_button->get_popup()->get_item_index(DEPENDENCY_UPDATE_LOCAL),true); if (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("DependencyOk","EditorIcons")); else sources_button->set_icon(gui_base->get_icon("DependencyChanged","EditorIcons")); */ } break; case DEPENDENCY_UPDATE_IMPORTED: { /* bool editing_changed = _find_editing_changed_scene(get_edited_scene()); import_reload_fn=""; if (editing_changed) { if (unsaved_cache && !bool(EDITOR_DEF("import/ask_save_before_reimport",false))) { if (!p_confirmed) { confirmation->get_ok()->set_text("Open"); //confirmation->get_cancel()->show(); confirmation->set_text("Current scene changed, save and re-import ?"); confirmation->popup_centered(Size2(300,70)); break; } } Node *scene = get_edited_scene(); if (scene->get_filename()=="") { current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); accept->set_text("Can't import if edited scene was not saved."); //i dont think this code will ever run accept->popup_centered(Size2(300,70));; break; } import_reload_fn = scene->get_filename(); _save_scene(import_reload_fn); _cleanup_scene(); } */ } break; default: { if (p_option>=OBJECT_METHOD_BASE) { ERR_FAIL_COND(!current); int idx=p_option-OBJECT_METHOD_BASE; List methods; current->get_method_list(&methods); ERR_FAIL_INDEX( idx, methods.size() ); String name=methods[idx].name; if (current) current->call(name); } else if (p_option>=IMPORT_PLUGIN_BASE) { Ref p = editor_import_export->get_import_plugin(p_option-IMPORT_PLUGIN_BASE); if (p.is_valid()) { p->import_dialog(); } } } } } Control* EditorNode::get_viewport() { return viewport; } void EditorNode::_editor_select(int p_which) { static bool selecting=false; if (selecting) return; selecting=true; ERR_FAIL_INDEX(p_which,editor_table.size()); main_editor_tabs->set_current_tab(p_which); selecting=false; EditorPlugin *new_editor = editor_table[p_which]; ERR_FAIL_COND(!new_editor); if (editor_plugin_screen==new_editor) return; if (editor_plugin_screen) { editor_plugin_screen->make_visible(false); } editor_plugin_screen=new_editor; editor_plugin_screen->make_visible(true); editor_plugin_screen->selected_notify(); } void EditorNode::add_editor_plugin(EditorPlugin *p_editor) { if (p_editor->has_main_screen()) { singleton->main_editor_tabs->add_tab(p_editor->get_name()); singleton->editor_table.push_back(p_editor); } singleton->editor_data.add_editor_plugin( p_editor ); singleton->add_child(p_editor); } void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) { if (p_editor->has_main_screen()) { for(int i=0;imain_editor_tabs->get_tab_count();i++) { if (p_editor->get_name()==singleton->main_editor_tabs->get_tab_title(i)) { singleton->main_editor_tabs->remove_tab(i); break; } } singleton->main_editor_tabs->add_tab(p_editor->get_name()); singleton->editor_table.erase(p_editor); } singleton->remove_child(p_editor); singleton->editor_data.remove_editor_plugin( p_editor ); } void EditorNode::set_edited_scene(Node *p_scene) { if (edited_scene) { if (edited_scene->get_parent()==scene_root) scene_root->remove_child(edited_scene); animation_editor->set_root(NULL); } edited_scene=p_scene; if (edited_scene && edited_scene->cast_to()) edited_scene->cast_to()->show(); //show popups scene_tree_dock->set_edited_scene(edited_scene); if (edited_scene) { if (p_scene->get_parent()!=scene_root) scene_root->add_child(p_scene); animation_editor->set_root(p_scene); } } void EditorNode::_fetch_translatable_strings(const Object *p_object,Set& strings) { List tstrings; p_object->get_translatable_strings(&tstrings); for(List::Element *E=tstrings.front();E;E=E->next()) strings.insert(E->get()); const Node * node = p_object->cast_to(); if (!node) return; Ref