summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/create_dialog.cpp49
-rw-r--r--editor/editor_file_system.cpp104
-rw-r--r--editor/editor_file_system.h14
-rw-r--r--editor/editor_node.cpp38
-rw-r--r--editor/editor_node.h4
-rw-r--r--editor/editor_properties.cpp2
-rw-r--r--editor/icons/icon_expand_bottom_dock.svg70
-rw-r--r--editor/icons/icon_shrink_bottom_dock.svg71
-rw-r--r--editor/plugins/script_editor_plugin.cpp1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp2
-rw-r--r--editor/scene_tree_dock.cpp121
-rw-r--r--editor/scene_tree_dock.h19
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);