diff options
Diffstat (limited to 'tools/editor/editor_node.cpp')
-rw-r--r-- | tools/editor/editor_node.cpp | 411 |
1 files changed, 379 insertions, 32 deletions
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index b0a2c568de..63684dcc93 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -93,7 +93,7 @@ #include "plugins/light_occluder_2d_editor_plugin.h" #include "plugins/color_ramp_editor_plugin.h" #include "plugins/collision_shape_2d_editor_plugin.h" - +#include "os/input.h" // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" @@ -459,17 +459,74 @@ void EditorNode::open_resource(const String& p_type) { current_option=RESOURCE_LOAD; } -void EditorNode::save_resource(const Ref<Resource>& p_resource) { +void EditorNode::save_resource_in_path(const Ref<Resource>& p_resource,const String& p_path) { - 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); + editor_data.apply_changes_in_editors(); + 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; + + String path = Globals::get_singleton()->localize_path(p_path); + Error err = ResourceSaver::save(path,p_resource,flg|ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); + + if (err!=OK) { + accept->set_text("Error saving resource!"); + accept->popup_centered_minsize(); + return; + } +// EditorFileSystem::get_singleton()->update_file(path,p_resource->get_type()); + + ((Resource*)p_resource.ptr())->set_path(path); + emit_signal("resource_saved",p_resource); + +} + +void EditorNode::save_resource(const Ref<Resource>& p_resource) { + + if (p_resource->get_path().is_resource_file()) { + save_resource_in_path(p_resource,p_resource->get_path()); + } else { + save_resource_as(p_resource); + } } void EditorNode::save_resource_as(const Ref<Resource>& p_resource) { - resources_dock->save_resource_as(p_resource); + file->set_mode(EditorFileDialog::MODE_SAVE_FILE); + bool relpaths = (p_resource->has_meta("__editor_relpaths__") && p_resource->get_meta("__editor_relpaths__").operator bool()); + + List<String> extensions; + Ref<PackedScene> sd = memnew( PackedScene ); + ResourceSaver::get_recognized_extensions(p_resource,&extensions); + file->clear_filters(); + for(int i=0;i<extensions.size();i++) { + + file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + //file->set_current_path(current_path); + if (p_resource->get_path()!="") { + file->set_current_path(p_resource->get_path()); + if (extensions.size()) { + String ext=p_resource->get_path().extension().to_lower(); + if (extensions.find(ext)==NULL) { + file->set_current_path(p_resource->get_path().replacen("."+ext,"."+extensions.front()->get())); + } + } + } else { + + String existing; + if (extensions.size()) { + existing="new_"+p_resource->get_type().to_lower()+"."+extensions.front()->get().to_lower(); + } + file->set_current_path(existing); + + } + file->popup_centered_ratio(); + file->set_title("Save Resource As.."); } @@ -1049,7 +1106,7 @@ void EditorNode::_dialog_action(String p_file) { push_item(res.operator->() ); - } break; + } break; case FILE_OPEN_SCENE: { @@ -1320,7 +1377,20 @@ void EditorNode::_dialog_action(String p_file) { unzClose(pkg); } break; + case RESOURCE_SAVE: + case RESOURCE_SAVE_AS: { + + uint32_t current = editor_history.get_current(); + Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL; + + ERR_FAIL_COND(!current_obj->cast_to<Resource>()) + + RES current_res = RES(current_obj->cast_to<Resource>()); + + save_resource_in_path(current_res,p_file); + + } break; default: { //save scene? @@ -1358,6 +1428,67 @@ void EditorNode::push_item(Object *p_object,const String& p_property) { } +void EditorNode::_select_history(int p_idx) { + + //push it to the top, it is not correct, but it's more useful + ObjectID id=editor_history.get_history_obj(p_idx); + Object* obj=ObjectDB::get_instance(id); + if (!obj) + return; + push_item(obj); +} + +void EditorNode::_prepare_history() { + + int history_to = MAX(0,editor_history.get_history_len()-25); + + editor_history_menu->get_popup()->clear(); + + Ref<Texture> base_icon = gui_base->get_icon("Object","EditorIcons"); + Set<ObjectID> already; + for(int i=editor_history.get_history_len()-1;i>=history_to;i--) { + + + ObjectID id=editor_history.get_history_obj(i); + Object* obj=ObjectDB::get_instance(id); + if (!obj || already.has(id)) { + if (history_to>0) { + history_to--; + } + continue; + } + + already.insert(id); + + Ref<Texture> icon = gui_base->get_icon("Object","EditorIcons"); + if (gui_base->has_icon(obj->get_type(),"EditorIcons")) + icon=gui_base->get_icon(obj->get_type(),"EditorIcons"); + else + icon=base_icon; + + String text; + if (obj->cast_to<Resource>()) { + Resource *r=obj->cast_to<Resource>(); + if (r->get_path().is_resource_file()) + text=r->get_path().get_file(); + else if (r->get_name()!=String()) { + text=r->get_name(); + } else { + text=r->get_type(); + } + } else if (obj->cast_to<Node>()) { + text=obj->cast_to<Node>()->get_name(); + } else { + text=obj->get_type(); + } + + if (i==editor_history.get_history_pos()) { + text="["+text+"]"; + } + editor_history_menu->get_popup()->add_icon_item(icon,text,i); + } +} + void EditorNode::_property_editor_forward() { if (editor_history.next()) @@ -1402,6 +1533,9 @@ void EditorNode::_edit_current() { uint32_t current = editor_history.get_current(); Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL; + property_back->set_disabled( editor_history.is_at_begining() ); + property_forward->set_disabled( editor_history.is_at_end() ); + this->current=current_obj; editor_path->update_path(); @@ -1416,7 +1550,10 @@ void EditorNode::_edit_current() { object_menu->set_disabled(true); - if (current_obj->is_type("Resource")) { + bool is_resource = current_obj->is_type("Resource"); + resource_save_button->set_disabled(!is_resource); + + if (is_resource) { Resource *current_res = current_obj->cast_to<Resource>(); @@ -1425,12 +1562,11 @@ void EditorNode::_edit_current() { property_editor->edit( current_res ); object_menu->set_disabled(false); - resources_dock->add_resource(Ref<Resource>(current_res)); - //top_pallete->set_current_tab(1); - } + //resources_dock->add_resource(Ref<Resource>(current_res)); - if (current_obj->is_type("Node")) { + //top_pallete->set_current_tab(1); + } else if (current_obj->is_type("Node")) { Node * current_node = current_obj->cast_to<Node>(); ERR_FAIL_COND(!current_node); @@ -1445,6 +1581,12 @@ void EditorNode::_edit_current() { //top_pallete->set_current_tab(0); + } else { + + property_editor->edit( current_obj ); + //scene_tree_dock->set_selected(current_node); + //object_menu->get_popup()->clear(); + } /* Take care of PLUGIN EDITOR */ @@ -1517,7 +1659,13 @@ void EditorNode::_edit_current() { p->add_item("Copy Params",OBJECT_COPY_PARAMS); p->add_item("Set Params",OBJECT_PASTE_PARAMS); p->add_separator(); - p->add_item("Make Resources Unique",OBJECT_UNIQUE_RESOURCES); + p->add_item("Paste Resource",RESOURCE_PASTE); + if (is_resource) { + p->add_item("Copy Resource",RESOURCE_COPY); + p->add_item("Make Built-In",RESOURCE_UNREF); + } + p->add_separator(); + p->add_item("Make Sub-Resources Unique",OBJECT_UNIQUE_RESOURCES); p->add_separator(); p->add_icon_item(gui_base->get_icon("Help","EditorIcons"),"Class Reference",OBJECT_REQUEST_HELP); List<MethodInfo> methods; @@ -1550,6 +1698,20 @@ void EditorNode::_edit_current() { _update_keying(); } +void EditorNode::_resource_created() { + + Object *c = create_dialog->instance_selected(); + + ERR_FAIL_COND(!c); + Resource *r = c->cast_to<Resource>(); + ERR_FAIL_COND(!r); + + REF res( r ); + + push_item(c); + +} + void EditorNode::_resource_selected(const RES& p_res,const String& p_property) { @@ -1762,6 +1924,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { int idx = editor_data.add_edited_scene(-1); _scene_tab_changed(idx); + editor_data.clear_editor_states(); //_cleanup_scene(); @@ -1804,6 +1967,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { quick_open->set_title("Quick Open Script.."); } break; + case FILE_QUICK_OPEN_FILE: { + + + quick_open->popup("Resource",false,true); + quick_open->set_title("Quick Search File.."); + + } break; case FILE_RUN_SCRIPT: { file_script->popup_centered_ratio(); @@ -2266,7 +2436,70 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } break; #endif - + case RESOURCE_NEW: { + + create_dialog->popup_centered_ratio(); + } break; + case RESOURCE_LOAD: { + + open_resource(); + } break; + case RESOURCE_SAVE: { + + + uint32_t current = editor_history.get_current(); + Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL; + + ERR_FAIL_COND(!current_obj->cast_to<Resource>()) + + RES current_res = RES(current_obj->cast_to<Resource>()); + + save_resource(current_res); + + } break; + case RESOURCE_SAVE_AS: { + + uint32_t current = editor_history.get_current(); + Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL; + + ERR_FAIL_COND(!current_obj->cast_to<Resource>()) + + RES current_res = RES(current_obj->cast_to<Resource>()); + + save_resource_as(current_res); + + } break; + case RESOURCE_UNREF: { + + uint32_t current = editor_history.get_current(); + Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL; + + ERR_FAIL_COND(!current_obj->cast_to<Resource>()) + + RES current_res = RES(current_obj->cast_to<Resource>()); + current_res->set_path(""); + _edit_current(); + } break; + case RESOURCE_COPY: { + + uint32_t current = editor_history.get_current(); + Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL; + + ERR_FAIL_COND(!current_obj->cast_to<Resource>()) + + RES current_res = RES(current_obj->cast_to<Resource>()); + + EditorSettings::get_singleton()->set_resource_clipboard(current_res); + + } break; + case RESOURCE_PASTE: { + + RES r = EditorSettings::get_singleton()->get_resource_clipboard(); + if (r.is_valid()) { + push_item(EditorSettings::get_singleton()->get_resource_clipboard().ptr(),String()); + } + + } break; case OBJECT_REQUEST_HELP: { if (current) { @@ -3050,7 +3283,21 @@ void EditorNode::set_current_scene(int p_idx) { } -Error EditorNode::load_scene(const String& p_scene) { +bool EditorNode::is_scene_open(const String& p_path) { + + for(int i=0;i<editor_data.get_edited_scene_count();i++) { + if (editor_data.get_scene_path(i)==p_path) + return true; + } + + return false; +} + +void EditorNode::fix_dependencies(const String& p_for_file) { + dependency_fixer->edit(p_for_file); +} + +Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) { if (!is_inside_tree()) { defer_load_scene = p_scene; @@ -3096,6 +3343,8 @@ Error EditorNode::load_scene(const String& p_scene) { //_cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded. + dependency_errors.clear(); + Ref<PackedScene> sdata = ResourceLoader::load(lpath,"",true); if (!sdata.is_valid()) { @@ -3113,6 +3362,35 @@ Error EditorNode::load_scene(const String& p_scene) { return ERR_FILE_NOT_FOUND; } + if (!p_ignore_broken_deps && dependency_errors.has(lpath)) { + + current_option=-1; + Vector<String> errors; + for(Set<String>::Element *E=dependency_errors[lpath].front();E;E=E->next()) { + + errors.push_back(E->get()); + } + dependency_error->show(lpath,errors); + opening_prev=false; + + if (prev!=-1) { + set_current_scene(prev); + editor_data.remove_scene(idx); + } + return ERR_FILE_MISSING_DEPENDENCIES; + } + + dependency_errors.erase(lpath); //at least not self path + + for (Map<String,Set<String> >::Element *E=dependency_errors.front();E;E=E->next()) { + + String txt="Scene '"+E->key()+"' has broken dependencies:\n"; + for(Set<String>::Element *F=E->get().front();F;F=F->next()) { + txt+="\t"+F->get()+"\n"; + } + add_io_error(txt); + } + sdata->set_path(lpath,true); //take over path Node*new_scene=sdata->instance(true); @@ -3408,9 +3686,12 @@ void EditorNode::hide_animation_player_editors() { void EditorNode::_quick_opened(const String& p_resource) { - print_line("quick_opened"); - if (quick_open->get_base_type()=="PackedScene") { + if (current_option==FILE_QUICK_OPEN_FILE) { + scenes_dock->open(p_resource); + return; + } + if (quick_open->get_base_type()=="PackedScene") { open_request(p_resource); } else { load_resource(p_resource); @@ -3595,6 +3876,8 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("_quick_opened",&EditorNode::_quick_opened); ObjectTypeDB::bind_method("_quick_run",&EditorNode::_quick_run); + ObjectTypeDB::bind_method("_resource_created",&EditorNode::_resource_created); + ObjectTypeDB::bind_method("_import_action",&EditorNode::_import_action); //ObjectTypeDB::bind_method("_import",&EditorNode::_import); // ObjectTypeDB::bind_method("_import_conflicts_solved",&EditorNode::_import_conflicts_solved); @@ -3624,6 +3907,8 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("_set_main_scene_state",&EditorNode::_set_main_scene_state); ObjectTypeDB::bind_method("_update_scene_tabs",&EditorNode::_update_scene_tabs); + ObjectTypeDB::bind_method("_prepare_history",&EditorNode::_prepare_history); + ObjectTypeDB::bind_method("_select_history",&EditorNode::_select_history); ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin); @@ -4105,6 +4390,14 @@ EditorNode::EditorNode() { EditorHelp::generate_doc(); //before any editor classes are crated + if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) { + //only if no touchscreen ui hint, set emulation + InputDefault *id = Input::get_singleton()->cast_to<InputDefault>(); + if (id) + id->set_emulate_touch(false); //just disable just in case + } + + singleton=this; last_checked_version=0; changing_scene=false; @@ -4120,6 +4413,7 @@ EditorNode::EditorNode() { ResourceLoader::set_abort_on_missing_resources(false); FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("file_dialog/show_hidden_files")); ResourceLoader::set_error_notify_func(this,_load_error_notify); + ResourceLoader::set_dependency_error_notify_func(this,_dependency_error_report); ResourceLoader::set_timestamp_on_load(true); ResourceSaver::set_timestamp_on_save(true); @@ -4493,6 +4787,7 @@ EditorNode::EditorNode() { p->add_separator(); p->add_item("Quick Open Scene..",FILE_QUICK_OPEN_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_O); p->add_item("Quick Open Script..",FILE_QUICK_OPEN_SCRIPT,KEY_MASK_ALT+KEY_MASK_CMD+KEY_O); + p->add_item("Quick Search File..",FILE_QUICK_OPEN_FILE,KEY_MASK_ALT+KEY_MASK_CMD+KEY_P); p->add_separator(); PopupMenu *pm_export = memnew(PopupMenu ); @@ -4735,13 +5030,14 @@ EditorNode::EditorNode() { scene_tree_dock->set_name("Scene"); //top_pallete->add_child(scene_tree_dock); dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock); - +#if 0 resources_dock = memnew( ResourcesDock(this) ); resources_dock->set_name("Resources"); //top_pallete->add_child(resources_dock); dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(resources_dock); //top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); - +#endif + dock_slot[DOCK_SLOT_RIGHT_BL]->hide(); /*Control *editor_spacer = memnew( Control ); editor_spacer->set_custom_minimum_size(Size2(260,200)); editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -4766,27 +5062,40 @@ EditorNode::EditorNode() { dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(prop_editor_base); HBoxContainer *prop_editor_hb = memnew( HBoxContainer ); - prop_editor_base->add_child(prop_editor_hb); - editor_path = memnew( EditorPath(&editor_history) ); - editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); - prop_editor_hb->add_child(editor_path); - - property_editor = memnew( PropertyEditor ); - property_editor->set_autoclear(true); - property_editor->set_show_categories(true); - property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - - property_editor->hide_top_label(); - prop_editor_base->add_child( property_editor ); - property_editor->set_undo_redo(&editor_data.get_undo_redo()); + prop_editor_base->add_child(prop_editor_hb); + resource_new_button = memnew( ToolButton ); + resource_new_button->set_tooltip("Create a new resource in memory and edit it"); + resource_new_button->set_icon(gui_base->get_icon("New","EditorIcons")); + prop_editor_hb->add_child(resource_new_button); + resource_new_button->connect("pressed",this,"_menu_option",varray(RESOURCE_NEW)); + resource_new_button->set_focus_mode(Control::FOCUS_NONE); + + resource_load_button = memnew( ToolButton ); + resource_load_button->set_tooltip("Load an existing resource from disk and edit it"); + resource_load_button->set_icon(gui_base->get_icon("Load","EditorIcons")); + prop_editor_hb->add_child(resource_load_button); + resource_load_button->connect("pressed",this,"_menu_option",varray(RESOURCE_LOAD)); + resource_load_button->set_focus_mode(Control::FOCUS_NONE); + + resource_save_button = memnew( MenuButton ); + resource_save_button->set_tooltip("Save the currently edited resource"); + resource_save_button->set_icon(gui_base->get_icon("Save","EditorIcons")); + prop_editor_hb->add_child(resource_save_button); + resource_save_button->get_popup()->add_item("Save",RESOURCE_SAVE); + resource_save_button->get_popup()->add_item("Save As..",RESOURCE_SAVE_AS); + resource_save_button->get_popup()->connect("item_pressed",this,"_menu_option"); + resource_save_button->set_focus_mode(Control::FOCUS_NONE); + resource_save_button->set_disabled(true); + + prop_editor_hb->add_spacer(); - property_back = memnew( ToolButton ); property_back->set_icon( gui_base->get_icon("Back","EditorIcons") ); property_back->set_flat(true); property_back->set_tooltip("Go to the previous edited object in history."); + property_back->set_disabled(true); prop_editor_hb->add_child( property_back ); @@ -4794,14 +5103,48 @@ EditorNode::EditorNode() { property_forward->set_icon( gui_base->get_icon("Forward","EditorIcons") ); property_forward->set_flat(true); property_forward->set_tooltip("Go to the next edited object in history."); + property_forward->set_disabled(true); prop_editor_hb->add_child( property_forward ); + + editor_history_menu = memnew( MenuButton ); + editor_history_menu->set_icon( gui_base->get_icon("History","EditorIcons")); + prop_editor_hb->add_child(editor_history_menu); + editor_history_menu->connect("about_to_show",this,"_prepare_history"); + editor_history_menu->get_popup()->connect("item_pressed",this,"_select_history"); + + + prop_editor_hb = memnew( HBoxContainer ); //again... + + prop_editor_base->add_child(prop_editor_hb); + editor_path = memnew( EditorPath(&editor_history) ); + editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); + prop_editor_hb->add_child(editor_path); + + object_menu = memnew( MenuButton ); object_menu->set_icon(gui_base->get_icon("Tools","EditorIcons")); prop_editor_hb->add_child( object_menu ); object_menu->set_tooltip("Object properties."); + create_dialog = memnew( CreateDialog ); + gui_base->add_child(create_dialog); + create_dialog->set_base_type("Resource"); + create_dialog->connect("create",this,"_resource_created"); + + + property_editor = memnew( PropertyEditor ); + property_editor->set_autoclear(true); + property_editor->set_show_categories(true); + property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + property_editor->set_use_doc_hints(true); + + property_editor->hide_top_label(); + + prop_editor_base->add_child( property_editor ); + property_editor->set_undo_redo(&editor_data.get_undo_redo()); + scenes_dock = memnew( ScenesDock(this) ); scenes_dock->set_name("FileSystem"); @@ -4929,7 +5272,11 @@ EditorNode::EditorNode() { + dependency_error = memnew( DependencyErrorDialog ); + gui_base->add_child(dependency_error); + dependency_fixer = memnew( DependencyEditor ); + gui_base->add_child( dependency_fixer ); settings_config_dialog = memnew( EditorSettingsDialog ); gui_base->add_child(settings_config_dialog); |