diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/create_dialog.cpp | 49 | ||||
-rw-r--r-- | editor/editor_file_system.cpp | 104 | ||||
-rw-r--r-- | editor/editor_file_system.h | 14 | ||||
-rw-r--r-- | editor/editor_node.cpp | 38 | ||||
-rw-r--r-- | editor/editor_node.h | 4 | ||||
-rw-r--r-- | editor/editor_properties.cpp | 2 | ||||
-rw-r--r-- | editor/icons/icon_expand_bottom_dock.svg | 70 | ||||
-rw-r--r-- | editor/icons/icon_shrink_bottom_dock.svg | 71 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 1 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 121 | ||||
-rw-r--r-- | editor/scene_tree_dock.h | 19 |
12 files changed, 478 insertions, 17 deletions
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index a8cbf52cd2..6b2a072e20 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -243,6 +243,18 @@ void CreateDialog::_update_search() { _parse_fs(EditorFileSystem::get_singleton()->get_filesystem()); */ + List<StringName> global_classes; + ScriptServer::get_global_class_list(&global_classes); + + Map<String, List<String> > global_class_map; + for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { + String base = ScriptServer::get_global_class_base(E->get()); + if (!global_class_map.has(base)) { + global_class_map[base] = List<String>(); + } + global_class_map[base].push_back(E->get()); + } + HashMap<String, TreeItem *> types; TreeItem *root = search_options->create_item(); @@ -293,6 +305,32 @@ void CreateDialog::_update_search() { add_type(I->get(), types, root, &to_select); } + if (global_class_map.has(type) && ClassDB::is_parent_class(type, base_type)) { + for (List<String>::Element *J = global_class_map[type].front(); J; J = J->next()) { + bool show = search_box->get_text().is_subsequence_ofi(J->get()); + + if (!show) + continue; + + if (!types.has(type)) + add_type(type, types, root, &to_select); + + TreeItem *ti; + if (types.has(type)) + ti = types[type]; + else + ti = search_options->get_root(); + + TreeItem *item = search_options->create_item(ti); + item->set_metadata(0, J->get()); + item->set_text(0, J->get() + " (" + ScriptServer::get_global_class_path(J->get()).get_file() + ")"); + item->set_icon(0, _get_editor_icon(type)); + if (!to_select || J->get() == search_box->get_text()) { + to_select = item; + } + } + } + if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) { //there are custom types based on this... cool. @@ -444,6 +482,17 @@ Object *CreateDialog::instance_selected() { custom = md; if (custom != String()) { + + if (ScriptServer::is_global_class(custom)) { + RES script = ResourceLoader::load(ScriptServer::get_global_class_path(custom)); + ERR_FAIL_COND_V(!script.is_valid(), NULL); + + Object *obj = ClassDB::instance(ScriptServer::get_global_class_base(custom)); + ERR_FAIL_COND_V(!obj, NULL); + + obj->set_script(script.get_ref_ptr()); + return obj; + } return EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom); } else { return ClassDB::instance(selected->get_text(0)); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index d8ae1da72e..d8ab41fa05 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -125,6 +125,14 @@ bool EditorFileSystemDirectory::get_file_import_is_valid(int p_idx) const { return files[p_idx]->import_valid; } +String EditorFileSystemDirectory::get_file_script_class_name(int p_idx) const { + return files[p_idx]->script_class_name; +} + +String EditorFileSystemDirectory::get_file_script_class_extends(int p_idx) const { + return files[p_idx]->script_class_extends; +} + StringName EditorFileSystemDirectory::get_file_type(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, files.size(), ""); @@ -149,6 +157,8 @@ void EditorFileSystemDirectory::_bind_methods() { ClassDB::bind_method(D_METHOD("get_file", "idx"), &EditorFileSystemDirectory::get_file); ClassDB::bind_method(D_METHOD("get_file_path", "idx"), &EditorFileSystemDirectory::get_file_path); ClassDB::bind_method(D_METHOD("get_file_type", "idx"), &EditorFileSystemDirectory::get_file_type); + ClassDB::bind_method(D_METHOD("get_file_script_class_name", "idx"), &EditorFileSystemDirectory::get_file_script_class_name); + ClassDB::bind_method(D_METHOD("get_file_script_class_extends", "idx"), &EditorFileSystemDirectory::get_file_script_class_extends); ClassDB::bind_method(D_METHOD("get_file_import_is_valid", "idx"), &EditorFileSystemDirectory::get_file_import_is_valid); ClassDB::bind_method(D_METHOD("get_name"), &EditorFileSystemDirectory::get_name); ClassDB::bind_method(D_METHOD("get_path"), &EditorFileSystemDirectory::get_path); @@ -189,7 +199,7 @@ void EditorFileSystem::_scan_filesystem() { String project = ProjectSettings::get_singleton()->get_resource_path(); - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache3"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4"); FileAccess *f = FileAccess::open(fscache, FileAccess::READ); if (f) { @@ -209,7 +219,7 @@ void EditorFileSystem::_scan_filesystem() { } else { Vector<String> split = l.split("::"); - ERR_CONTINUE(split.size() != 6); + ERR_CONTINUE(split.size() != 7); String name = split[0]; String file; @@ -221,8 +231,10 @@ void EditorFileSystem::_scan_filesystem() { fc.modification_time = split[2].to_int64(); fc.import_modification_time = split[3].to_int64(); fc.import_valid = split[4].to_int64() != 0; + fc.script_class_name = split[5].get_slice("<>", 0); + fc.script_class_extends = split[5].get_slice("<>", 1); - String deps = split[5].strip_edges(); + String deps = split[6].strip_edges(); if (deps.length()) { Vector<String> dp = deps.split("<>"); for (int i = 0; i < dp.size(); i++) { @@ -239,7 +251,7 @@ void EditorFileSystem::_scan_filesystem() { memdelete(f); } - String update_cache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update3"); + String update_cache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4"); if (FileAccess::exists(update_cache)) { { @@ -287,7 +299,7 @@ void EditorFileSystem::_scan_filesystem() { } void EditorFileSystem::_save_filesystem_cache() { - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache3"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4"); FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE); if (f == NULL) { @@ -563,6 +575,7 @@ void EditorFileSystem::scan() { scanning = false; emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); + _queue_update_script_classes(); } else { @@ -706,6 +719,9 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess fi->modified_time = fc->modification_time; fi->import_modified_time = fc->import_modification_time; fi->import_valid = fc->import_valid; + fi->script_class_name = fc->script_class_name; + fi->script_class_extends = fc->script_class_extends; + if (fc->type == String()) { fi->type = ResourceLoader::get_resource_type(path); //there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?) @@ -715,6 +731,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess } else { fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path); + fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends); fi->modified_time = 0; fi->import_modified_time = 0; fi->import_valid = ResourceLoader::is_import_valid(path); @@ -734,9 +751,12 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess fi->deps = fc->deps; fi->import_modified_time = 0; fi->import_valid = true; + fi->script_class_name = fc->script_class_name; + fi->script_class_extends = fc->script_class_extends; } else { //new or modified time fi->type = ResourceLoader::get_resource_type(path); + fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends); fi->deps = _get_dependencies(path); fi->modified_time = mt; fi->import_modified_time = 0; @@ -835,6 +855,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const fi->modified_time = FileAccess::get_modified_time(path); fi->import_modified_time = 0; fi->type = ResourceLoader::get_resource_type(path); + fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends); fi->import_valid = ResourceLoader::is_import_valid(path); { @@ -1044,6 +1065,7 @@ void EditorFileSystem::_notification(int p_what) { if (_update_scan_actions()) emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); + _queue_update_script_classes(); } } else if (!scanning) { @@ -1059,6 +1081,7 @@ void EditorFileSystem::_notification(int p_what) { _update_scan_actions(); emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); + _queue_update_script_classes(); } } } break; @@ -1087,7 +1110,7 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir, for (int i = 0; i < p_dir->files.size(); i++) { - String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid); + String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends; s += "::"; for (int j = 0; j < p_dir->files[i]->deps.size(); j++) { @@ -1268,7 +1291,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p void EditorFileSystem::_save_late_updated_files() { //files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update3"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4"); FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE); for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) { f->store_line(E->get()); @@ -1293,6 +1316,67 @@ Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) { return ret; } +String EditorFileSystem::_get_global_script_class(const String &p_type, const String &p_path, String *r_extends) const { + + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + if (ScriptServer::get_language(i)->handles_global_class_type(p_type)) { + String global_name; + String extends; + + global_name = ScriptServer::get_language(i)->get_global_class_name(p_path, &extends); + *r_extends = extends; + return global_name; + } + } + *r_extends = String(); + return String(); +} + +void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) { + int filecount = p_dir->files.size(); + const EditorFileSystemDirectory::FileInfo *const *files = p_dir->files.ptr(); + for (int i = 0; i < filecount; i++) { + if (files[i]->script_class_name == String()) { + continue; + } + + String lang; + for (int j = 0; j < ScriptServer::get_language_count(); j++) { + if (ScriptServer::get_language(j)->handles_global_class_type(files[i]->type)) { + lang = ScriptServer::get_language(j)->get_name(); + } + } + + ScriptServer::add_global_class(files[i]->script_class_name, files[i]->script_class_extends, lang, p_dir->get_file_path(i)); + } + for (int i = 0; i < p_dir->get_subdir_count(); i++) { + _scan_script_classes(p_dir->get_subdir(i)); + } +} + +void EditorFileSystem::update_script_classes() { + + if (!update_script_classes_queued) + return; + + update_script_classes_queued = false; + ScriptServer::global_classes_clear(); + if (get_filesystem()) { + _scan_script_classes(get_filesystem()); + } + + ScriptServer::save_global_classes(); +} + +void EditorFileSystem::_queue_update_script_classes() { + if (update_script_classes_queued) { + return; + } + + update_script_classes_queued = true; + call_deferred("update_script_classes"); +} + void EditorFileSystem::update_file(const String &p_file) { EditorFileSystemDirectory *fs = NULL; @@ -1311,7 +1395,9 @@ void EditorFileSystem::update_file(const String &p_file) { memdelete(fs->files[cpos]); fs->files.remove(cpos); } + call_deferred("emit_signal", "filesystem_changed"); //update later + _queue_update_script_classes(); return; } @@ -1351,6 +1437,7 @@ void EditorFileSystem::update_file(const String &p_file) { } fs->files[cpos]->type = type; + fs->files[cpos]->script_class_name = _get_global_script_class(type, p_file, &fs->files[cpos]->script_class_extends); fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file); fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); @@ -1359,6 +1446,7 @@ void EditorFileSystem::update_file(const String &p_file) { EditorResourcePreview::get_singleton()->check_for_invalidation(p_file); call_deferred("emit_signal", "filesystem_changed"); //update later + _queue_update_script_classes(); } void EditorFileSystem::_reimport_file(const String &p_file) { @@ -1611,6 +1699,7 @@ void EditorFileSystem::_bind_methods() { ClassDB::bind_method(D_METHOD("update_file", "path"), &EditorFileSystem::update_file); ClassDB::bind_method(D_METHOD("get_filesystem_path", "path"), &EditorFileSystem::get_filesystem_path); ClassDB::bind_method(D_METHOD("get_file_type", "path"), &EditorFileSystem::get_file_type); + ClassDB::bind_method(D_METHOD("update_script_classes"), &EditorFileSystem::update_script_classes); ADD_SIGNAL(MethodInfo("filesystem_changed")); ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist"))); @@ -1664,6 +1753,7 @@ EditorFileSystem::EditorFileSystem() { memdelete(da); scan_total = 0; + update_script_classes_queued = false; } EditorFileSystem::~EditorFileSystem() { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index a587d2879a..1aa35f4782 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -58,6 +58,8 @@ class EditorFileSystemDirectory : public Object { bool import_valid; Vector<String> deps; bool verified; //used for checking changes + String script_class_name; + String script_class_extends; }; struct FileInfoSort { @@ -86,6 +88,8 @@ public: StringName get_file_type(int p_idx) const; Vector<String> get_file_deps(int p_idx) const; bool get_file_import_is_valid(int p_idx) const; + String get_file_script_class_name(int p_idx) const; //used for scripts + String get_file_script_class_extends(int p_idx) const; //used for scripts EditorFileSystemDirectory *get_parent(); @@ -157,6 +161,8 @@ class EditorFileSystem : public Node { uint64_t import_modification_time; Vector<String> deps; bool import_valid; + String script_class_name; + String script_class_extends; }; HashMap<String, FileCache> file_cache; @@ -215,6 +221,12 @@ class EditorFileSystem : public Node { } }; + void _scan_script_classes(EditorFileSystemDirectory *p_dir); + volatile bool update_script_classes_queued; + void _queue_update_script_classes(); + + String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends) const; + protected: void _notification(int p_what); static void _bind_methods(); @@ -237,6 +249,8 @@ public: void reimport_files(const Vector<String> &p_files); + void update_script_classes(); + EditorFileSystem(); ~EditorFileSystem(); }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 72adb9aa47..70bc090bc4 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3861,7 +3861,7 @@ ToolButton *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) { tb->set_focus_mode(Control::FOCUS_NONE); bottom_panel_vb->add_child(p_item); bottom_panel_hb->raise(); - bottom_panel_hb->add_child(tb); + bottom_panel_hb_editors->add_child(tb); p_item->set_v_size_flags(Control::SIZE_EXPAND_FILL); p_item->hide(); BottomPanelItem bpi; @@ -3925,7 +3925,7 @@ void EditorNode::remove_bottom_panel_item(Control *p_item) { _bottom_panel_switch(false, 0); } bottom_panel_vb->remove_child(bottom_panel_items[i].control); - bottom_panel_hb->remove_child(bottom_panel_items[i].button); + bottom_panel_hb_editors->remove_child(bottom_panel_items[i].button); memdelete(bottom_panel_items[i].button); bottom_panel_items.remove(i); break; @@ -3955,6 +3955,11 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { } center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE); center_split->set_collapsed(false); + if (bottom_panel_raise->is_pressed()) { + top_split->hide(); + } + bottom_panel_raise->show(); + } else { bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer")); for (int i = 0; i < bottom_panel_items.size(); i++) { @@ -3964,6 +3969,10 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { } center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); center_split->set_collapsed(true); + bottom_panel_raise->hide(); + if (bottom_panel_raise->is_pressed()) { + top_split->show(); + } } } @@ -4373,6 +4382,17 @@ Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversio return ret; } +void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) { + + if (p_pressed) { + top_split->hide(); + bottom_panel_raise->set_icon(gui_base->get_icon("ShrinkBottomDock", "EditorIcons")); + } else { + top_split->show(); + bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons")); + } +} + void EditorNode::_bind_methods() { ClassDB::bind_method("_menu_option", &EditorNode::_menu_option); @@ -4441,6 +4461,7 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout); ClassDB::bind_method(D_METHOD("_resources_reimported"), &EditorNode::_resources_reimported); + ClassDB::bind_method(D_METHOD("_bottom_panel_raise_toggled"), &EditorNode::_bottom_panel_raise_toggled); ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("pause_pressed")); @@ -5269,6 +5290,19 @@ EditorNode::EditorNode() { bottom_panel_hb = memnew(HBoxContainer); bottom_panel_vb->add_child(bottom_panel_hb); + bottom_panel_hb_editors = memnew(HBoxContainer); + bottom_panel_hb_editors->set_h_size_flags(Control::SIZE_EXPAND_FILL); + bottom_panel_hb->add_child(bottom_panel_hb_editors); + bottom_panel_raise = memnew(ToolButton); + bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons")); + + bottom_panel_raise->set_shortcut(ED_SHORTCUT("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KEY_MASK_SHIFT | KEY_F12)); + + bottom_panel_hb->add_child(bottom_panel_raise); + bottom_panel_raise->hide(); + bottom_panel_raise->set_toggle_mode(true); + bottom_panel_raise->connect("toggled", this, "_bottom_panel_raise_toggled"); + log = memnew(EditorLog); ToolButton *output_button = add_bottom_panel_item(TTR("Output"), log); log->set_tool_button(output_button); diff --git a/editor/editor_node.h b/editor/editor_node.h index a5f975784c..7aa060fe14 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -377,7 +377,11 @@ private: PanelContainer *bottom_panel; HBoxContainer *bottom_panel_hb; + HBoxContainer *bottom_panel_hb_editors; VBoxContainer *bottom_panel_vb; + ToolButton *bottom_panel_raise; + + void _bottom_panel_raise_toggled(bool); EditorInterface *editor_interface; diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index fefadde64e..1f45902008 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2004,7 +2004,7 @@ void EditorPropertyResource::_sub_inspector_object_id_selected(int p_id) { void EditorPropertyResource::_open_editor_pressed() { RES res = get_edited_object()->get(get_edited_property()); if (res.is_valid()) { - EditorNode::get_singleton()->edit_item(res.ptr()); + EditorNode::get_singleton()->edit_resource(res.ptr()); } } diff --git a/editor/icons/icon_expand_bottom_dock.svg b/editor/icons/icon_expand_bottom_dock.svg new file mode 100644 index 0000000000..5a1760f377 --- /dev/null +++ b/editor/icons/icon_expand_bottom_dock.svg @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg6" + sodipodi:docname="icon_expand_bottom_dock.svg" + inkscape:version="0.92.3 (2405546, 2018-03-11)"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1853" + inkscape:window-height="1016" + id="namedview8" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="9.4509357" + inkscape:cy="6.016355" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg6" /> + <path + style="fill:#e0e0e0" + d="M 4.2130251,4.516057 0.6774912,8.0515909 H 3.2131761 V 13.025308 H 5.2130155 V 8.0515909 H 7.7487004 L 4.2131665,4.516057 Z" + id="path829" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccccc" /> + <path + inkscape:connector-curvature="0" + id="path831" + d="M 11.907306,4.6119359 8.3717718,8.1474698 h 2.5356852 v 4.9737172 h 1.999839 V 8.1474698 h 2.535685 L 11.907447,4.6119359 Z" + style="fill:#e0e0e0" + sodipodi:nodetypes="ccccccccc" /> + <rect + style="fill:#e0e0e0;fill-opacity:1" + id="rect855" + width="14" + height="1.8305085" + x="1.2881356" + y="1.3700738" /> +</svg> diff --git a/editor/icons/icon_shrink_bottom_dock.svg b/editor/icons/icon_shrink_bottom_dock.svg new file mode 100644 index 0000000000..c1e8c1bfdb --- /dev/null +++ b/editor/icons/icon_shrink_bottom_dock.svg @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg6" + sodipodi:docname="icon_shrink_bottom_dock.svg" + inkscape:version="0.92.3 (2405546, 2018-03-11)"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1853" + inkscape:window-height="1016" + id="namedview8" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="9.4509357" + inkscape:cy="6.016355" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg6" /> + <path + style="fill:#e0e0e0" + d="M 11.907447,9.9752038 15.442981,6.4396699 H 12.907296 V 1.4659528 h -1.999839 l 0,4.9737171 -2.5356852,0 3.5355342,3.5355339 z" + id="path829" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccccc" /> + <path + inkscape:connector-curvature="0" + id="path831" + d="M 4.2131662,9.8793249 7.7487004,6.343791 H 5.2130152 V 1.3700738 H 3.2131762 V 6.343791 h -2.535685 l 3.535534,3.5355339 z" + style="fill:#e0e0e0" + sodipodi:nodetypes="ccccccccc" /> + <rect + style="fill:#e0e0e0;fill-opacity:1" + id="rect855" + width="14" + height="1.8305085" + x="-14.832336" + y="-13.121187" + transform="scale(-1)" /> +</svg> diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index aa4673f41e..876da7f61a 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1872,6 +1872,7 @@ void ScriptEditor::save_all_scripts() { } _update_script_names(); + EditorFileSystem::get_singleton()->update_script_classes(); } void ScriptEditor::apply_scripts() const { diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index ab9c5777ea..9a351c26fa 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -157,7 +157,7 @@ void VisualShaderEditor::_update_graph() { vsnode->connect("changed", this, "_node_changed", varray(vsnode->get_instance_id()), CONNECT_DEFERRED); }*/ - node->set_offset(position * EDSCALE); + node->set_offset(position); node->set_title(vsnode->get_caption()); node->set_name(itos(nodes[n_i])); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 77ee65879b..2ffaa0ca12 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -551,6 +551,32 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { reparent_dialog->set_current(nodeset); } break; + case TOOL_MAKE_ROOT: { + + List<Node *> nodes = editor_selection->get_selected_node_list(); + ERR_FAIL_COND(nodes.size() != 1); + + Node *node = nodes.front()->get(); + Node *root = get_tree()->get_edited_scene_root(); + + if (node == root) + return; + + editor_data->get_undo_redo().create_action("Make node as Root"); + _node_replace_owner(root, node, node, MODE_DO); + editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node); + editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", node); + editor_data->get_undo_redo().add_do_method(node, "set_filename", root->get_filename()); + + editor_data->get_undo_redo().add_undo_method(node, "set_filename", String()); + editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", root); + editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node); + _node_replace_owner(root, node, root, MODE_UNDO); + editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree"); + editor_data->get_undo_redo().add_undo_method(scene_tree, "update_tree"); + editor_data->get_undo_redo().add_undo_reference(root); + editor_data->get_undo_redo().commit_action(); + } break; case TOOL_MULTI_EDIT: { Node *root = EditorNode::get_singleton()->get_edited_scene(); @@ -757,6 +783,26 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } } break; + case TOOL_CREATE_2D_SCENE: + case TOOL_CREATE_3D_SCENE: + case TOOL_CREATE_USER_INTERFACE: { + + Node *new_node; + switch (p_tool) { + case TOOL_CREATE_2D_SCENE: new_node = memnew(Node2D); break; + case TOOL_CREATE_3D_SCENE: new_node = memnew(Spatial); break; + case TOOL_CREATE_USER_INTERFACE: new_node = memnew(Control); break; + } + + editor_data->get_undo_redo().create_action("New Scene Root"); + editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", new_node); + editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree"); + editor_data->get_undo_redo().add_do_reference(new_node); + editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL); + editor_data->get_undo_redo().commit_action(); + + } break; + default: { if (p_tool >= EDIT_SUBRESOURCE_BASE) { @@ -803,6 +849,35 @@ void SceneTreeDock::_notification(int p_what) { EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", this, "_selection_changed"); + create_root_dialog->add_child(memnew(Label(TTR("Create Root Node:")))); + + Button *button_2d = memnew(Button); + create_root_dialog->add_child(button_2d); + + button_2d->set_text(TTR("2D Scene")); + button_2d->set_icon(get_icon("Node2D", "EditorIcons")); + button_2d->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_2D_SCENE, false)); + + Button *button_3d = memnew(Button); + create_root_dialog->add_child(button_3d); + button_3d->set_text(TTR("3D Scene")); + button_3d->set_icon(get_icon("Spatial", "EditorIcons")); + button_3d->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_3D_SCENE, false)); + + Button *button_ui = memnew(Button); + create_root_dialog->add_child(button_ui); + button_ui->set_text(TTR("User Interface")); + button_ui->set_icon(get_icon("Control", "EditorIcons")); + button_ui->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_USER_INTERFACE, false)); + + Button *button_custom = memnew(Button); + create_root_dialog->add_child(button_custom); + button_custom->set_text(TTR("Custom Node")); + button_custom->set_icon(get_icon("Add", "EditorIcons")); + button_custom->connect("pressed", this, "_tool_selected", make_binds(TOOL_NEW, false)); + + create_root_dialog->add_spacer(); + } break; case NOTIFICATION_ENTER_TREE: { @@ -820,21 +895,49 @@ void SceneTreeDock::_notification(int p_what) { filter->add_icon_override("right_icon", get_icon("Search", "EditorIcons")); } break; + case NOTIFICATION_PROCESS: { + + bool show_create_root = bool(EDITOR_GET("interface/editors/show_scene_tree_root_selection")) && get_tree()->get_edited_scene_root() == NULL; + + if (show_create_root != create_root_dialog->is_visible_in_tree()) { + if (show_create_root) { + create_root_dialog->show(); + scene_tree->hide(); + } else { + create_root_dialog->hide(); + scene_tree->show(); + } + } + + } break; } } -void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root) { +void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode) { if (p_base != p_node) { if (p_node->get_owner() == p_base) { UndoRedo *undo_redo = &editor_data->get_undo_redo(); - undo_redo->add_do_method(p_node, "set_owner", p_root); - undo_redo->add_undo_method(p_node, "set_owner", p_base); + switch (p_mode) { + case MODE_BIDI: { + undo_redo->add_do_method(p_node, "set_owner", p_root); + undo_redo->add_undo_method(p_node, "set_owner", p_base); + + } break; + case MODE_DO: { + undo_redo->add_do_method(p_node, "set_owner", p_root); + + } break; + case MODE_UNDO: { + undo_redo->add_undo_method(p_node, "set_owner", p_root); + + } break; + } } } for (int i = 0; i < p_node->get_child_count(); i++) { - _node_replace_owner(p_base, p_node->get_child(i), p_root); + _node_replace_owner(p_base, p_node->get_child(i), p_root, p_mode); } } @@ -1904,6 +2007,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT); if (selection.size() == 1) { + + menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT); menu->add_separator(); menu->add_icon_shortcut(get_icon("Blend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE); menu->add_icon_shortcut(get_icon("CreateNewSceneFrom", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM); @@ -2090,6 +2195,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN); ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KEY_MASK_CMD | KEY_D); ED_SHORTCUT("scene_tree/reparent", TTR("Reparent")); + ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root")); ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene")); ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene")); ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD | KEY_C); @@ -2153,6 +2259,10 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel remote_tree = NULL; button_hb->hide(); + create_root_dialog = memnew(VBoxContainer); + vbc->add_child(create_root_dialog); + create_root_dialog->hide(); + scene_tree = memnew(SceneTreeEditor(false, true, true)); vbc->add_child(scene_tree); @@ -2227,4 +2337,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel add_child(clear_inherit_confirm); set_process_input(true); + set_process(true); + + EDITOR_DEF("interface/editors/show_scene_tree_root_selection", true); } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 17deab25de..fd74611bde 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -68,6 +68,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_MOVE_DOWN, TOOL_DUPLICATE, TOOL_REPARENT, + TOOL_MAKE_ROOT, TOOL_NEW_SCENE_FROM, TOOL_MERGE_FROM_SCENE, TOOL_MULTI_EDIT, @@ -80,7 +81,12 @@ class SceneTreeDock : public VBoxContainer { TOOL_SCENE_OPEN, TOOL_SCENE_CLEAR_INHERITANCE, TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM, - TOOL_SCENE_OPEN_INHERITED + TOOL_SCENE_OPEN_INHERITED, + + TOOL_CREATE_2D_SCENE, + TOOL_CREATE_3D_SCENE, + TOOL_CREATE_USER_INTERFACE, + }; enum { @@ -134,13 +140,22 @@ class SceneTreeDock : public VBoxContainer { Node *edited_scene; EditorNode *editor; + VBoxContainer *create_root_dialog; + void _add_children_to_popup(Object *p_obj, int p_depth); void _node_reparent(NodePath p_path, bool p_keep_global_xform); void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform); void _set_owners(Node *p_owner, const Array &p_nodes); - void _node_replace_owner(Node *p_base, Node *p_node, Node *p_root); + + enum ReplaceOwnerMode { + MODE_BIDI, + MODE_DO, + MODE_UNDO + }; + + void _node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode = MODE_BIDI); void _load_request(const String &p_path); void _script_open_request(const Ref<Script> &p_script); |