summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_about.cpp2
-rw-r--r--editor/editor_export.cpp14
-rw-r--r--editor/editor_export.h4
-rw-r--r--editor/editor_file_dialog.cpp25
-rw-r--r--editor/editor_file_system.cpp6
-rw-r--r--editor/editor_file_system.h2
-rw-r--r--editor/editor_folding.cpp175
-rw-r--r--editor/editor_folding.h25
-rw-r--r--editor/editor_inspector.cpp108
-rw-r--r--editor/editor_inspector.h18
-rw-r--r--editor/editor_node.cpp35
-rw-r--r--editor/editor_node.h7
-rw-r--r--editor/editor_properties.cpp6
-rw-r--r--editor/editor_settings.cpp4
-rw-r--r--editor/filesystem_dock.cpp14
-rw-r--r--editor/filesystem_dock.h2
-rw-r--r--editor/import_dock.cpp51
-rw-r--r--editor/import_dock.h1
-rw-r--r--editor/inspector_dock.cpp1
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.cpp2
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.h2
-rw-r--r--editor/plugins/gi_probe_editor_plugin.cpp2
-rw-r--r--editor/plugins/gi_probe_editor_plugin.h2
-rw-r--r--editor/plugins/item_list_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp10
-rw-r--r--editor/plugins/script_text_editor.cpp2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp81
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp22
-rw-r--r--editor/plugins/text_editor.cpp2
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp57
-rw-r--r--editor/plugins/tile_set_editor_plugin.h8
-rw-r--r--editor/progress_dialog.cpp6
-rw-r--r--editor/project_export.cpp79
-rw-r--r--editor/project_export.h2
-rw-r--r--editor/scene_tree_dock.cpp65
-rw-r--r--editor/scene_tree_dock.h4
-rw-r--r--editor/scene_tree_editor.cpp7
37 files changed, 709 insertions, 146 deletions
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index cdf0e4b829..2f2840192a 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -47,7 +47,9 @@ void EditorAbout::_notification(int p_what) {
Control *base = EditorNode::get_singleton()->get_gui_base();
Ref<Font> font = base->get_font("source", "EditorFonts");
_tpl_text->add_font_override("normal_font", font);
+ _tpl_text->add_constant_override("line_separation", 6 * EDSCALE);
_license_text->add_font_override("normal_font", font);
+ _license_text->add_constant_override("line_separation", 6 * EDSCALE);
_logo->set_texture(base->get_icon("Logo", "EditorIcons"));
} break;
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 1a6188862f..218063566a 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -144,6 +144,17 @@ String EditorExportPreset::get_include_filter() const {
return include_filter;
}
+void EditorExportPreset::set_export_path(const String &p_path) {
+
+ export_path = p_path;
+ EditorExport::singleton->save_presets();
+}
+
+String EditorExportPreset::get_export_path() const {
+
+ return export_path;
+}
+
void EditorExportPreset::set_exclude_filter(const String &p_exclude) {
exclude_filter = p_exclude;
@@ -213,6 +224,7 @@ String EditorExportPreset::get_custom_features() const {
EditorExportPreset::EditorExportPreset() {
+ export_path = "";
export_filter = EXPORT_ALL_RESOURCES;
runnable = false;
}
@@ -1034,6 +1046,7 @@ void EditorExport::_save() {
}
config->set_value(section, "include_filter", preset->get_include_filter());
config->set_value(section, "exclude_filter", preset->get_exclude_filter());
+ config->set_value(section, "export_path", preset->get_export_path());
config->set_value(section, "patch_list", preset->get_patches());
String option_section = "preset." + itos(i) + ".options";
@@ -1189,6 +1202,7 @@ void EditorExport::load_config() {
preset->set_include_filter(config->get_value(section, "include_filter"));
preset->set_exclude_filter(config->get_value(section, "exclude_filter"));
+ preset->set_export_path(config->get_value(section, "export_path", ""));
Vector<String> patch_list = config->get_value(section, "patch_list");
diff --git a/editor/editor_export.h b/editor/editor_export.h
index b4ee5b89e7..d1165fd042 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -57,6 +57,7 @@ private:
ExportFilter export_filter;
String include_filter;
String exclude_filter;
+ String export_path;
String exporter;
Set<String> selected_files;
@@ -114,6 +115,9 @@ public:
void set_custom_features(const String &p_custom_features);
String get_custom_features() const;
+ void set_export_path(const String &p_path);
+ String get_export_path() const;
+
const List<PropertyInfo> &get_properties() const { return properties; }
EditorExportPreset();
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index f425d0a995..438d7ea306 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -1135,14 +1135,10 @@ void EditorFileDialog::_update_drives() {
}
void EditorFileDialog::_favorite_selected(int p_idx) {
-
- Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
- ERR_FAIL_INDEX(p_idx, favorited.size());
-
- dir_access->change_dir(favorited[p_idx]);
+ dir_access->change_dir(favorites->get_item_metadata(p_idx));
file->set_text("");
- invalidate();
update_dir();
+ invalidate();
_push_history();
}
@@ -1192,7 +1188,7 @@ void EditorFileDialog::_update_favorites() {
bool res = access == ACCESS_RESOURCES;
String current = get_current_dir();
- Ref<Texture> star = get_icon("Favorites", "EditorIcons");
+ Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons");
favorites->clear();
favorite->set_pressed(false);
@@ -1203,16 +1199,23 @@ void EditorFileDialog::_update_favorites() {
if (cres != res)
continue;
String name = favorited[i];
-
- bool setthis = name == current;
+ bool setthis = false;
if (res && name == "res://") {
+ if (name == current)
+ setthis = true;
name = "/";
+ } else if (name.ends_with("/")) {
+ if (name == current)
+ setthis = true;
+ name = name.substr(0, name.length() - 1);
+ name = name.get_file();
+
+ favorites->add_item(name, folder_icon);
} else {
- name = name.get_file() + "/";
+ continue; // We don't handle favorite files here
}
- favorites->add_item(name, star);
favorites->set_item_metadata(favorites->get_item_count() - 1, favorited[i]);
if (setthis) {
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index d73bf86f64..a99c9656ba 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1305,11 +1305,6 @@ void EditorFileSystem::_save_late_updated_files() {
}
}
-void EditorFileSystem::_resource_saved(const String &p_path) {
-
- EditorFileSystem::get_singleton()->update_file(p_path);
-}
-
Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) {
List<String> deps;
@@ -1772,7 +1767,6 @@ EditorFileSystem::EditorFileSystem() {
abort_scan = false;
scanning_changes = false;
scanning_changes_done = false;
- ResourceSaver::set_save_callback(_resource_saved);
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (da->change_dir("res://.import") != OK) {
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index 47077425a1..f6eef2a152 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -204,8 +204,6 @@ class EditorFileSystem : public Node {
bool _update_scan_actions();
- static void _resource_saved(const String &p_path);
-
void _update_extensions();
void _reimport_file(const String &p_file);
diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp
new file mode 100644
index 0000000000..eec4438f96
--- /dev/null
+++ b/editor/editor_folding.cpp
@@ -0,0 +1,175 @@
+#include "editor_folding.h"
+
+#include "core/os/file_access.h"
+#include "editor_settings.h"
+
+PoolVector<String> EditorFolding::_get_unfolds(const Object *p_object) {
+
+ PoolVector<String> sections;
+ sections.resize(p_object->editor_get_section_folding().size());
+ if (sections.size()) {
+ PoolVector<String>::Write w = sections.write();
+ int idx = 0;
+ for (const Set<String>::Element *E = p_object->editor_get_section_folding().front(); E; E = E->next()) {
+ w[idx++] = E->get();
+ }
+ }
+
+ return sections;
+}
+
+void EditorFolding::save_resource_folding(const RES &p_resource, const String &p_path) {
+ Ref<ConfigFile> config;
+ config.instance();
+ PoolVector<String> unfolds = _get_unfolds(p_resource.ptr());
+ config->set_value("folding", "sections_unfolded", unfolds);
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+ config->save(file);
+}
+
+void EditorFolding::_set_unfolds(Object *p_object, const PoolVector<String> &p_unfolds) {
+
+ int uc = p_unfolds.size();
+ PoolVector<String>::Read r = p_unfolds.read();
+ p_object->editor_clear_section_folding();
+ for (int i = 0; i < uc; i++) {
+ p_object->editor_set_section_unfold(r[i], true);
+ }
+}
+
+void EditorFolding::load_resource_folding(RES p_resource, const String &p_path) {
+
+ Ref<ConfigFile> config;
+ config.instance();
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+
+ if (config->load(file) != OK) {
+ return;
+ }
+
+ PoolVector<String> unfolds;
+
+ if (config->has_section_key("folding", "sections_unfolded")) {
+ unfolds = config->get_value("folding", "sections_unfolded");
+ }
+ _set_unfolds(p_resource.ptr(), unfolds);
+}
+
+void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Set<RES> &resources) {
+ if (p_root != p_node) {
+ if (!p_node->get_owner()) {
+ return; //not owned, bye
+ }
+ if (p_node->get_owner() != p_root && !p_root->is_editable_instance(p_node)) {
+ return;
+ }
+ }
+
+ PoolVector<String> unfolds = _get_unfolds(p_node);
+
+ if (unfolds.size()) {
+ p_folds.push_back(p_root->get_path_to(p_node));
+ p_folds.push_back(unfolds);
+ }
+
+ List<PropertyInfo> plist;
+ p_node->get_property_list(&plist);
+ for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ if (E->get().type == Variant::OBJECT) {
+ RES res = p_node->get(E->get().name);
+ if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
+
+ PoolVector<String> res_unfolds = _get_unfolds(res.ptr());
+ resource_folds.push_back(res->get_path());
+ resource_folds.push_back(res_unfolds);
+ resources.insert(res);
+ }
+ }
+ }
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _fill_folds(p_root, p_node->get_child(i), p_folds, resource_folds, resources);
+ }
+}
+void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path) {
+
+ Ref<ConfigFile> config;
+ config.instance();
+
+ Array unfolds, res_unfolds;
+ Set<RES> resources;
+ _fill_folds(p_scene, p_scene, unfolds, res_unfolds, resources);
+
+ config->set_value("folding", "node_unfolds", unfolds);
+ config->set_value("folding", "resource_unfolds", res_unfolds);
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+ config->save(file);
+}
+void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) {
+
+ Ref<ConfigFile> config;
+ config.instance();
+
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+
+ if (config->load(file) != OK) {
+ return;
+ }
+
+ Array unfolds;
+ if (config->has_section_key("folding", "node_unfolds")) {
+ unfolds = config->get_value("folding", "node_unfolds");
+ }
+ Array res_unfolds;
+ if (config->has_section_key("folding", "resource_unfolds")) {
+ res_unfolds = config->get_value("folding", "resource_unfolds");
+ }
+
+ ERR_FAIL_COND(unfolds.size() & 1);
+ ERR_FAIL_COND(res_unfolds.size() & 1);
+
+ for (int i = 0; i < unfolds.size(); i += 2) {
+ NodePath path = unfolds[i];
+ PoolVector<String> un = unfolds[i + 1];
+ Node *node = p_scene->get_node(path);
+ if (!node) {
+ continue;
+ }
+ _set_unfolds(node, un);
+ }
+
+ for (int i = 0; i < res_unfolds.size(); i += 2) {
+ String path = res_unfolds[i];
+ RES res;
+ if (ResourceCache::has(path)) {
+ res = RES(ResourceCache::get(path));
+ }
+ if (res.is_null()) {
+ continue;
+ }
+
+ PoolVector<String> unfolds = res_unfolds[i + 1];
+ _set_unfolds(res.ptr(), unfolds);
+ }
+}
+
+bool EditorFolding::has_folding_data(const String &p_path) {
+ String path = EditorSettings::get_singleton()->get_project_settings_dir();
+ String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+ file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+ return FileAccess::exists(file);
+}
+
+EditorFolding::EditorFolding() {
+}
diff --git a/editor/editor_folding.h b/editor/editor_folding.h
new file mode 100644
index 0000000000..cfd4b5466d
--- /dev/null
+++ b/editor/editor_folding.h
@@ -0,0 +1,25 @@
+#ifndef EDITOR_FOLDING_H
+#define EDITOR_FOLDING_H
+
+#include "scene/main/node.h"
+
+class EditorFolding {
+
+ PoolVector<String> _get_unfolds(const Object *p_object);
+ void _set_unfolds(Object *p_object, const PoolVector<String> &p_unfolds);
+
+ void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Set<RES> &resources);
+
+public:
+ void save_resource_folding(const RES &p_resource, const String &p_path);
+ void load_resource_folding(RES p_resource, const String &p_path);
+
+ void save_scene_folding(const Node *p_scene, const String &p_path);
+ void load_scene_folding(Node *p_scene, const String &p_path);
+
+ bool has_folding_data(const String &p_path);
+
+ EditorFolding();
+};
+
+#endif // EDITOR_FOLDING_H
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index a90f15004a..1230588016 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -36,6 +36,50 @@
#include "multi_node_edit.h"
#include "scene/resources/packed_scene.h"
+EditorDefaultClassValueCache *EditorDefaultClassValueCache::singleton = NULL;
+
+EditorDefaultClassValueCache *EditorDefaultClassValueCache::get_singleton() {
+ return singleton;
+}
+
+Variant EditorDefaultClassValueCache::get_default_value(const StringName &p_class, const StringName &p_property) {
+
+ if (!default_values.has(p_class)) {
+
+ default_values[p_class] = Map<StringName, Variant>();
+
+ if (ClassDB::can_instance(p_class)) {
+
+ Object *c = ClassDB::instance(p_class);
+ List<PropertyInfo> plist;
+ c->get_property_list(&plist);
+ for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ if (E->get().usage & PROPERTY_USAGE_EDITOR) {
+
+ Variant v = c->get(E->get().name);
+ default_values[p_class][E->get().name] = v;
+ }
+ }
+ memdelete(c);
+ }
+ }
+
+ if (!default_values.has(p_class)) {
+ return Variant();
+ }
+
+ if (!default_values[p_class].has(p_property)) {
+ return Variant();
+ }
+
+ return default_values[p_class][p_property];
+}
+
+EditorDefaultClassValueCache::EditorDefaultClassValueCache() {
+ ERR_FAIL_COND(singleton != NULL);
+ singleton = this;
+}
+
Size2 EditorProperty::get_minimum_size() const {
Size2 ms;
@@ -458,6 +502,12 @@ void EditorProperty::update_reload_status() {
bool has_reload = false;
+ if (EditorDefaultClassValueCache::get_singleton()) {
+ Variant default_value = EditorDefaultClassValueCache::get_singleton()->get_default_value(object->get_class_name(), property);
+ if (default_value != Variant() && default_value != object->get(property)) {
+ has_reload = true;
+ }
+ }
if (_is_instanced_node_with_original_property_different()) {
has_reload = true;
}
@@ -651,6 +701,7 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
Variant rev = object->call("property_get_revert", property);
emit_signal("property_changed", property, rev);
update_property();
+ return;
}
if (!object->get_script().is_null()) {
@@ -659,6 +710,16 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
if (scr->get_property_default_value(property, orig_value)) {
emit_signal("property_changed", property, orig_value);
update_property();
+ return;
+ }
+ }
+
+ if (EditorDefaultClassValueCache::get_singleton()) {
+ Variant default_value = EditorDefaultClassValueCache::get_singleton()->get_default_value(object->get_class_name(), property);
+ if (default_value != Variant()) {
+ emit_signal("property_changed", property, default_value);
+ update_property();
+ return;
}
}
}
@@ -738,9 +799,9 @@ Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
tooltip_text = p_text;
EditorHelpBit *help_bit = memnew(EditorHelpBit);
help_bit->add_style_override("panel", get_stylebox("panel", "TooltipPanel"));
- help_bit->get_rich_text()->set_fixed_size_to_width(300);
+ help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE);
- String text = TTR("Property: ") + "[u][b]" + p_text.get_slice("::", 0) + "[/b][/u]\n";
+ String text = TTR("Property:") + " [u][b]" + p_text.get_slice("::", 0) + "[/b][/u]\n";
text += p_text.get_slice("::", 1).strip_edges();
help_bit->set_text(text);
help_bit->call_deferred("set_text", text); //hack so it uses proper theme once inside scene
@@ -960,7 +1021,7 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons
tooltip_text = p_text;
EditorHelpBit *help_bit = memnew(EditorHelpBit);
help_bit->add_style_override("panel", get_stylebox("panel", "TooltipPanel"));
- help_bit->get_rich_text()->set_fixed_size_to_width(300);
+ help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE);
String text = "[u][b]" + p_text.get_slice("::", 0) + "[/b][/u]\n";
text += p_text.get_slice("::", 1).strip_edges();
@@ -1370,6 +1431,28 @@ void EditorInspector::update_tree() {
// TreeItem *current_category = NULL;
+ bool unfold_if_edited = false;
+
+ if (use_folding && auto_unfold_edited && get_tree()->get_edited_scene_root()) {
+ String path;
+ Node *node = Object::cast_to<Node>(object);
+ if (node) {
+ path = get_tree()->get_edited_scene_root()->get_filename();
+ }
+ Resource *res = Object::cast_to<Resource>(object);
+ if (res) {
+ if (res->get_path().is_resource_file()) {
+ path = res->get_path();
+ } else if (res->get_path().begins_with("res://")) { //internal resource
+ path = get_tree()->get_edited_scene_root()->get_filename();
+ }
+ }
+
+ if (!EditorNode::get_singleton()->get_editor_folding().has_folding_data(path)) {
+ unfold_if_edited = true;
+ }
+ }
+
String filter = search_box ? search_box->get_text() : "";
String group;
String group_base;
@@ -1380,6 +1463,8 @@ void EditorInspector::update_tree() {
object->get_property_list(&plist, true);
HashMap<String, VBoxContainer *> item_path;
+ Map<VBoxContainer *, EditorInspectorSection *> section_map;
+
item_path[""] = main_vbox;
Color sscolor = get_color("prop_subsection", "Editor");
@@ -1542,7 +1627,9 @@ void EditorInspector::update_tree() {
c.a /= level;
section->setup(acc_path, path_name, object, c, use_folding);
- item_path[acc_path] = section->get_vbox();
+ VBoxContainer *vb = section->get_vbox();
+ item_path[acc_path] = vb;
+ section_map[vb] = section;
}
current_vbox = item_path[acc_path];
level = (MIN(level + 1, 4));
@@ -1685,6 +1772,13 @@ void EditorInspector::update_tree() {
if (current_selected && ep->property == current_selected) {
ep->select(current_focusable);
}
+
+ if (unfold_if_edited && ep->can_revert_to_default()) {
+ //if edited and there is a parent section, unfold it.
+ if (current_vbox && section_map.has(current_vbox)) {
+ section_map[current_vbox]->unfold();
+ }
+ }
}
}
@@ -2181,6 +2275,10 @@ String EditorInspector::get_object_class() const {
return object_class;
}
+void EditorInspector::set_auto_unfold_edited(bool p_enable) {
+ auto_unfold_edited = p_enable;
+}
+
void EditorInspector::_bind_methods() {
ClassDB::bind_method("_property_changed", &EditorInspector::_property_changed, DEFVAL(false));
@@ -2205,6 +2303,7 @@ void EditorInspector::_bind_methods() {
ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "res"), PropertyInfo(Variant::STRING, "prop")));
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property")));
+ ADD_SIGNAL(MethodInfo("property_toggled", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::BOOL, "checked")));
ADD_SIGNAL(MethodInfo("restart_requested"));
}
@@ -2236,6 +2335,7 @@ EditorInspector::EditorInspector() {
set_process(true);
property_focusable = -1;
use_sub_inspector_bg = false;
+ auto_unfold_edited = false;
get_v_scrollbar()->connect("value_changed", this, "_vscroll_changed");
update_scroll_request = -1;
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index dccbdb9a73..350debcb7b 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -37,6 +37,20 @@
class UndoRedo;
+class EditorDefaultClassValueCache : public Object {
+ GDCLASS(EditorDefaultClassValueCache, Object)
+
+ Map<StringName, Map<StringName, Variant> > default_values;
+
+ static EditorDefaultClassValueCache *singleton;
+
+public:
+ static EditorDefaultClassValueCache *get_singleton();
+
+ Variant get_default_value(const StringName &p_class, const StringName &p_property);
+ EditorDefaultClassValueCache();
+};
+
class EditorProperty : public Container {
GDCLASS(EditorProperty, Container)
@@ -152,6 +166,8 @@ public:
void set_draw_top_bg(bool p_draw) { draw_top_bg = p_draw; }
+ bool can_revert_to_default() const { return can_revert; }
+
EditorProperty();
};
@@ -271,6 +287,7 @@ class EditorInspector : public ScrollContainer {
bool read_only;
bool keying;
bool use_sub_inspector_bg;
+ bool auto_unfold_edited;
float refresh_countdown;
bool update_tree_pending;
@@ -365,6 +382,7 @@ public:
String get_object_class() const;
void set_use_sub_inspector_bg(bool p_enable);
+ void set_auto_unfold_edited(bool p_enable);
EditorInspector();
};
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index d01543198a..e9ce2cb8ae 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1061,6 +1061,9 @@ void EditorNode::_save_scene(String p_file, int idx) {
set_current_version(editor_data.get_undo_redo().get_version());
else
editor_data.set_edited_scene_version(0, idx);
+
+ editor_folding.save_scene_folding(scene, p_file);
+
_update_title();
_update_scene_tabs();
} else {
@@ -2907,6 +2910,8 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
_update_scene_tabs();
_add_to_recent_scenes(lpath);
+ editor_folding.load_scene_folding(new_scene, lpath);
+
prev_scene->set_disabled(previous_scenes.size() == 0);
opening_prev = false;
@@ -4544,6 +4549,19 @@ void EditorNode::_video_driver_selected(int p_which) {
_update_video_driver_color();
}
+void EditorNode::_resource_saved(RES p_resource, const String &p_path) {
+ if (EditorFileSystem::get_singleton()) {
+ EditorFileSystem::get_singleton()->update_file(p_path);
+ }
+
+ singleton->editor_folding.save_resource_folding(p_resource, p_path);
+}
+
+void EditorNode::_resource_loaded(RES p_resource, const String &p_path) {
+
+ singleton->editor_folding.load_resource_folding(p_resource, p_path);
+}
+
void EditorNode::_bind_methods() {
ClassDB::bind_method("_menu_option", &EditorNode::_menu_option);
@@ -4733,6 +4751,8 @@ EditorNode::EditorNode() {
ResourceLoader::set_timestamp_on_load(true);
ResourceSaver::set_timestamp_on_save(true);
+ default_value_cache = memnew(EditorDefaultClassValueCache);
+
{ //register importers at the beginning, so dialogs are created with the right extensions
Ref<ResourceImporterTexture> import_texture;
import_texture.instance();
@@ -4844,6 +4864,7 @@ EditorNode::EditorNode() {
EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true);
EDITOR_DEF_RST("interface/inspector/capitalize_properties", true);
EDITOR_DEF_RST("interface/inspector/disable_folding", false);
+ EDITOR_DEF_RST("interface/inspector/auto_unfold_edited", true);
EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true);
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
@@ -4983,7 +5004,7 @@ EditorNode::EditorNode() {
dock_select_rect_over = -1;
dock_popup_selected = -1;
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
- dock_slot[i]->set_custom_minimum_size(Size2(230, 220) * EDSCALE);
+ dock_slot[i]->set_custom_minimum_size(Size2(170, 0) * EDSCALE);
dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
dock_slot[i]->set_popup(dock_select_popup);
dock_slot[i]->connect("pre_popup_pressed", this, "_dock_pre_popup", varray(i));
@@ -5499,8 +5520,8 @@ EditorNode::EditorNode() {
right_r_vsplit->hide();
// Add some offsets to left_r and main hsplits to make LEFT_R and RIGHT_L docks wider than minsize
- left_r_hsplit->set_split_offset(40 * EDSCALE);
- main_hsplit->set_split_offset(-40 * EDSCALE);
+ left_r_hsplit->set_split_offset(70 * EDSCALE);
+ main_hsplit->set_split_offset(-70 * EDSCALE);
// Define corresponding default layout
@@ -5515,8 +5536,8 @@ EditorNode::EditorNode() {
for (int i = 0; i < vsplits.size(); i++)
default_layout->set_value(docks_section, "dock_split_" + itos(i + 1), 0);
default_layout->set_value(docks_section, "dock_hsplit_1", 0);
- default_layout->set_value(docks_section, "dock_hsplit_2", 40 * EDSCALE);
- default_layout->set_value(docks_section, "dock_hsplit_3", -40 * EDSCALE);
+ default_layout->set_value(docks_section, "dock_hsplit_2", 70 * EDSCALE);
+ default_layout->set_value(docks_section, "dock_hsplit_3", -70 * EDSCALE);
default_layout->set_value(docks_section, "dock_hsplit_4", 0);
_update_layouts_menu();
@@ -5829,6 +5850,9 @@ EditorNode::EditorNode() {
print_handler.userdata = this;
add_print_handler(&print_handler);
+ ResourceSaver::set_save_callback(_resource_saved);
+ ResourceLoader::set_load_callback(_resource_loaded);
+
#ifdef OSX_ENABLED
ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_ALT | KEY_1);
ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2);
@@ -5857,6 +5881,7 @@ EditorNode::~EditorNode() {
memdelete(editor_plugins_force_input_forwarding);
memdelete(file_server);
memdelete(progress_hb);
+ memdelete(default_value_cache);
EditorSettings::destroy();
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 0096748ed1..33af473de3 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -38,6 +38,7 @@
#include "editor/editor_about.h"
#include "editor/editor_data.h"
#include "editor/editor_export.h"
+#include "editor/editor_folding.h"
#include "editor/editor_inspector.h"
#include "editor/editor_log.h"
#include "editor/editor_name_dialog.h"
@@ -271,6 +272,7 @@ private:
Ref<Theme> theme;
+ EditorDefaultClassValueCache *default_value_cache;
PopupMenu *recent_scenes;
SceneTreeDock *scene_tree_dock;
InspectorDock *inspector_dock;
@@ -385,6 +387,7 @@ private:
EditorSelection *editor_selection;
ProjectExportDialog *project_export;
EditorResourcePreview *resource_preview;
+ EditorFolding editor_folding;
EditorFileServer *file_server;
@@ -600,6 +603,9 @@ private:
PrintHandlerList print_handler;
static void _print_handler(void *p_this, const String &p_string, bool p_error);
+ static void _resource_saved(RES p_resource, const String &p_path);
+ static void _resource_loaded(RES p_resource, const String &p_path);
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -690,6 +696,7 @@ public:
void set_current_scene(int p_idx);
static EditorData &get_editor_data() { return singleton->editor_data; }
+ static EditorFolding &get_editor_folding() { return singleton->editor_folding; }
EditorHistory *get_editor_history() { return &editor_history; }
static VSplitContainer *get_top_split() { return singleton->top_split; }
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 96d482f47e..5148c12160 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -1860,6 +1860,12 @@ void EditorPropertyNodePath::update_property() {
Node *target_node = base_node->get_node(p);
ERR_FAIL_COND(!target_node);
+ if (String(target_node->get_name()).find("@") != -1) {
+ assign->set_icon(Ref<Texture>());
+ assign->set_text(p);
+ return;
+ }
+
assign->set_text(target_node->get_name());
assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node"));
}
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 1e97920f7e..34c273fbae 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -357,7 +357,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/theme/color_theme", "Adaptive");
hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Adaptive,Default,Custom");
- _initial_set("text_editor/theme/line_spacing", 4);
+ _initial_set("text_editor/theme/line_spacing", 6);
_initial_set("text_editor/theme/selection_color", Color::html("40808080"));
_load_default_text_editor_theme();
@@ -410,7 +410,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/completion/add_type_hints", false);
_initial_set("docks/scene_tree/start_create_dialog_fully_expanded", false);
- _initial_set("docks/scene_tree/draw_relationship_lines", false);
+ _initial_set("docks/scene_tree/draw_relationship_lines", true);
_initial_set("docks/scene_tree/relationship_line_color", Color::html("464646"));
_initial_set("editors/grid_map/pick_distance", 5000.0);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 26bc43c540..2136211faa 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -225,7 +225,7 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool
updating_tree = false;
}
-void FileSystemDock::_update_display_mode() {
+void FileSystemDock::_update_display_mode(bool p_force) {
// Compute the new display mode
DisplayMode new_display_mode;
if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) {
@@ -234,7 +234,7 @@ void FileSystemDock::_update_display_mode() {
new_display_mode = DISPLAY_MODE_SPLIT;
}
- if (new_display_mode != display_mode || old_display_mode_setting != display_mode_setting) {
+ if (p_force || new_display_mode != display_mode || old_display_mode_setting != display_mode_setting) {
display_mode = new_display_mode;
old_display_mode_setting = display_mode_setting;
button_toggle_display_mode->set_pressed(display_mode_setting == DISPLAY_MODE_SETTING_SPLIT ? true : false);
@@ -352,6 +352,11 @@ void FileSystemDock::_notification(int p_what) {
tree->set_drop_mode_flags(0);
} break;
+ case NOTIFICATION_THEME_CHANGED: {
+ if (is_visible_in_tree()) {
+ _update_display_mode(true);
+ }
+ } break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
// Update icons
String ei = "EditorIcons";
@@ -360,6 +365,11 @@ void FileSystemDock::_notification(int p_what) {
button_tree->set_icon(get_icon("Filesystem", ei));
button_hist_next->set_icon(get_icon("Forward", ei));
button_hist_prev->set_icon(get_icon("Back", ei));
+ if (button_file_list_display_mode->is_pressed()) {
+ button_file_list_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons"));
+ } else {
+ button_file_list_display_mode->set_icon(get_icon("FileList", "EditorIcons"));
+ }
tree_search_box->set_right_icon(get_icon("Search", ei));
tree_search_box->set_clear_button_enabled(true);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index d964515572..2aa79b1ddd 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -268,7 +268,7 @@ private:
void _file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata);
void _tree_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata);
- void _update_display_mode();
+ void _update_display_mode(bool p_force = false);
Vector<String> _tree_get_selected(bool remove_self_inclusion = true);
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 31eb193461..2e68609a56 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -38,11 +38,17 @@ public:
List<PropertyInfo> properties;
Ref<ResourceImporter> importer;
Vector<String> paths;
+ Set<StringName> checked;
+ bool checking;
bool _set(const StringName &p_name, const Variant &p_value) {
if (values.has(p_name)) {
values[p_name] = p_value;
+ if (checking) {
+ checked.insert(p_name);
+ _change_notify(String(p_name).utf8().get_data());
+ }
return true;
}
@@ -63,13 +69,24 @@ public:
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
if (!importer->get_option_visibility(E->get().name, values))
continue;
- p_list->push_back(E->get());
+ PropertyInfo pi = E->get();
+ if (checking) {
+ pi.usage |= PROPERTY_USAGE_CHECKABLE;
+ if (checked.has(E->get().name)) {
+ pi.usage |= PROPERTY_USAGE_CHECKED;
+ }
+ }
+ p_list->push_back(pi);
}
}
void update() {
_change_notify();
}
+
+ ImportDockParameters() {
+ checking = false;
+ }
};
void ImportDock::set_edit_path(const String &p_path) {
@@ -125,6 +142,8 @@ void ImportDock::_update_options(const Ref<ConfigFile> &p_config) {
params->properties.clear();
params->values.clear();
+ params->checking = false;
+ params->checked.clear();
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
@@ -205,6 +224,8 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
params->properties.clear();
params->values.clear();
+ params->checking = true;
+ params->checked.clear();
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
@@ -360,11 +381,21 @@ void ImportDock::_reimport() {
Error err = config->load(params->paths[i] + ".import");
ERR_CONTINUE(err != OK);
- config->set_value("remap", "importer", params->importer->get_importer_name());
- config->erase_section("params");
+ if (params->checking) {
+ //update only what edited (checkboxes)
+ for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
+ if (params->checked.has(E->get().name)) {
+ config->set_value("params", E->get().name, params->values[E->get().name]);
+ }
+ }
+ } else {
+ //override entirely
+ config->set_value("remap", "importer", params->importer->get_importer_name());
+ config->erase_section("params");
- for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
- config->set_value("params", E->get().name, params->values[E->get().name]);
+ for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
+ config->set_value("params", E->get().name, params->values[E->get().name]);
+ }
}
config->save(params->paths[i] + ".import");
@@ -388,11 +419,20 @@ void ImportDock::_notification(int p_what) {
} break;
}
}
+
+void ImportDock::_property_toggled(const StringName &p_prop, bool p_checked) {
+ if (p_checked) {
+ params->checked.insert(p_prop);
+ } else {
+ params->checked.erase(p_prop);
+ }
+}
void ImportDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_reimport"), &ImportDock::_reimport);
ClassDB::bind_method(D_METHOD("_preset_selected"), &ImportDock::_preset_selected);
ClassDB::bind_method(D_METHOD("_importer_selected"), &ImportDock::_importer_selected);
+ ClassDB::bind_method(D_METHOD("_property_toggled"), &ImportDock::_property_toggled);
}
void ImportDock::initialize_import_options() const {
@@ -423,6 +463,7 @@ ImportDock::ImportDock() {
import_opts = memnew(EditorInspector);
add_child(import_opts);
import_opts->set_v_size_flags(SIZE_EXPAND_FILL);
+ import_opts->connect("property_toggled", this, "_property_toggled");
hb = memnew(HBoxContainer);
add_child(hb);
diff --git a/editor/import_dock.h b/editor/import_dock.h
index 41c7298d9a..632fd39700 100644
--- a/editor/import_dock.h
+++ b/editor/import_dock.h
@@ -60,6 +60,7 @@ class ImportDock : public VBoxContainer {
void _importer_selected(int i_idx);
void _update_options(const Ref<ConfigFile> &p_config = Ref<ConfigFile>());
+ void _property_toggled(const StringName &p_prop, bool p_checked);
void _reimport();
enum {
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 750fca2852..2a8885c0a4 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -593,6 +593,7 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
inspector->set_undo_redo(&editor_data->get_undo_redo());
inspector->set_use_filter(true); // TODO: check me
+ inspector->set_auto_unfold_edited(bool(EDITOR_GET("interface/inspector/auto_unfold_edited")));
inspector->connect("resource_selected", this, "_resource_selected");
inspector->connect("property_keyed", this, "_property_keyed");
diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp
index e65a697857..40e3bb5be2 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.cpp
+++ b/editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -108,7 +108,7 @@ void BakedLightmapEditorPlugin::_bind_methods() {
BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) {
editor = p_node;
- bake = memnew(Button);
+ bake = memnew(ToolButton);
bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
bake->set_text(TTR("Bake Lightmaps"));
bake->hide();
diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/baked_lightmap_editor_plugin.h
index a32b573851..8d3b5b1dd6 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.h
+++ b/editor/plugins/baked_lightmap_editor_plugin.h
@@ -42,7 +42,7 @@ class BakedLightmapEditorPlugin : public EditorPlugin {
BakedLightmap *lightmap;
- Button *bake;
+ ToolButton *bake;
EditorNode *editor;
static EditorProgress *tmp_progress;
diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp
index 06da64b181..5fc5cad1ef 100644
--- a/editor/plugins/gi_probe_editor_plugin.cpp
+++ b/editor/plugins/gi_probe_editor_plugin.cpp
@@ -90,7 +90,7 @@ void GIProbeEditorPlugin::_bind_methods() {
GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) {
editor = p_node;
- bake = memnew(Button);
+ bake = memnew(ToolButton);
bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
bake->set_text(TTR("Bake GI Probe"));
bake->hide();
diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h
index 017e9bd743..1b3b63f227 100644
--- a/editor/plugins/gi_probe_editor_plugin.h
+++ b/editor/plugins/gi_probe_editor_plugin.h
@@ -42,7 +42,7 @@ class GIProbeEditorPlugin : public EditorPlugin {
GIProbe *gi_probe;
- Button *bake;
+ ToolButton *bake;
EditorNode *editor;
static EditorProgress *tmp_progress;
diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp
index 186e66f980..8df40232b0 100644
--- a/editor/plugins/item_list_editor_plugin.cpp
+++ b/editor/plugins/item_list_editor_plugin.cpp
@@ -350,8 +350,6 @@ ItemListEditor::ItemListEditor() {
selected_idx = -1;
- add_child(memnew(VSeparator));
-
toolbar_button = memnew(ToolButton);
toolbar_button->set_text(TTR("Items"));
add_child(toolbar_button);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 080d3ff894..ac69cc0df1 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -490,7 +490,7 @@ void ScriptEditor::_open_recent_script(int p_idx) {
edit(text_file, true);
return;
}
- // if it's a path then its most likely a deleted file not help
+ // if it's a path then it's most likely a deleted file not help
} else if (path.find("::") != -1) {
// built-in script
Ref<Script> script = ResourceLoader::load(path);
@@ -1363,7 +1363,9 @@ void ScriptEditor::_notification(int p_what) {
if (is_visible()) {
find_in_files_button->show();
} else {
- find_in_files->hide();
+ if (find_in_files->is_visible_in_tree()) {
+ editor->hide_bottom_panel();
+ }
find_in_files_button->hide();
}
@@ -2806,8 +2808,7 @@ void ScriptEditor::_start_find_in_files(bool with_replace) {
find_in_files->set_with_replace(with_replace);
find_in_files->start_search();
- find_in_files_button->set_pressed(true);
- find_in_files->show();
+ editor->make_bottom_panel_item_visible(find_in_files);
}
void ScriptEditor::_on_find_in_files_modified_files(PoolStringArray paths) {
@@ -3174,7 +3175,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
add_child(find_in_files_dialog);
find_in_files = memnew(FindInFilesPanel);
find_in_files_button = editor->add_bottom_panel_item(TTR("Search Results"), find_in_files);
- find_in_files_button->set_tooltip(TTR("Search in files"));
find_in_files->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
find_in_files->connect(FindInFilesPanel::SIGNAL_RESULT_SELECTED, this, "_on_find_in_files_result_selected");
find_in_files->connect(FindInFilesPanel::SIGNAL_FILES_MODIFIED, this, "_on_find_in_files_modified_files");
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 362b8543d4..27f5910d94 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -179,7 +179,7 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->add_color_override("search_result_border_color", search_result_border_color);
text_edit->add_color_override("symbol_color", symbol_color);
- text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
+ text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6));
colors_cache.symbol_color = symbol_color;
colors_cache.keyword_color = keyword_color;
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 0dda95832c..ab89d170da 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -952,8 +952,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b->is_pressed()) {
int mod = _get_key_modifier(b);
- if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) {
- set_freelook_active(true);
+ if (!orthogonal) {
+ if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) {
+ set_freelook_active(true);
+ }
}
} else {
set_freelook_active(false);
@@ -1134,7 +1136,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (clicked) {
_select_clicked(clicked_wants_append, true);
- //clickd processing was deferred
+ // Processing was deferred.
clicked = 0;
}
@@ -1241,7 +1243,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (!clicked_includes_current) {
_select_clicked(clicked_wants_append, true);
- //clickd processing was deferred
+ // Processing was deferred.
}
_compute_edit(_edit.mouse_pos);
@@ -1339,7 +1341,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
List<Node *> &selection = editor_selection->get_selected_node_list();
- bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW
+ // Disable local transformation for TRANSFORM_VIEW
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
float snap = 0;
if (_edit.snap || spatial_editor->is_snap_enabled()) {
@@ -1468,7 +1471,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
List<Node *> &selection = editor_selection->get_selected_node_list();
- bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW
+ // Disable local transformation for TRANSFORM_VIEW
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
float snap = 0;
if (_edit.snap || spatial_editor->is_snap_enabled()) {
@@ -1643,6 +1647,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
nav_mode = NAVIGATION_ZOOM;
} else if (freelook_active) {
nav_mode = NAVIGATION_LOOK;
+ } else if (orthogonal) {
+ nav_mode = NAVIGATION_PAN;
}
} else if (m->get_button_mask() & BUTTON_MASK_MIDDLE) {
@@ -1793,7 +1799,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (ED_IS_SHORTCUT("spatial_editor/focus_selection", p_event)) {
_menu_option(VIEW_CENTER_TO_SELECTION);
}
- if (ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) {
+ // Orthgonal mode doesn't work in freelook.
+ if (!freelook_active && ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) {
_menu_option(orthogonal ? VIEW_PERSPECTIVE : VIEW_ORTHOGONAL);
_update_name();
}
@@ -1823,7 +1830,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
set_message(TTR("Animation Key Inserted."));
}
- if (ED_IS_SHORTCUT("spatial_editor/freelook_toggle", p_event)) {
+ // Freelook doesn't work in orthogonal mode.
+ if (!orthogonal && ED_IS_SHORTCUT("spatial_editor/freelook_toggle", p_event)) {
set_freelook_active(!is_freelook_active());
} else if (k->get_scancode() == KEY_ESCAPE) {
@@ -1911,37 +1919,38 @@ void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, con
void SpatialEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
- // Freelook only works properly in perspective.
- // It could technically work in ortho, but it's terrible for a user due to FOV being a fixed width.
- if (!orthogonal) {
- real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
- real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
- bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
-
- // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
- Transform prev_camera_transform = to_camera_transform(cursor);
+ if (orthogonal) {
+ _nav_pan(p_event, p_relative);
+ return;
+ }
- if (invert_y_axis) {
- cursor.x_rot -= p_relative.y * radians_per_pixel;
- } else {
- cursor.x_rot += p_relative.y * radians_per_pixel;
- }
- cursor.y_rot += p_relative.x * radians_per_pixel;
- if (cursor.x_rot > Math_PI / 2.0)
- cursor.x_rot = Math_PI / 2.0;
- if (cursor.x_rot < -Math_PI / 2.0)
- cursor.x_rot = -Math_PI / 2.0;
+ real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
+ real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
+ bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
- // Look is like the opposite of Orbit: the focus point rotates around the camera
- Transform camera_transform = to_camera_transform(cursor);
- Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
- Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0));
- Vector3 diff = prev_pos - pos;
- cursor.pos += diff;
+ // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
+ Transform prev_camera_transform = to_camera_transform(cursor);
- name = "";
- _update_name();
+ if (invert_y_axis) {
+ cursor.x_rot -= p_relative.y * radians_per_pixel;
+ } else {
+ cursor.x_rot += p_relative.y * radians_per_pixel;
}
+ cursor.y_rot += p_relative.x * radians_per_pixel;
+ if (cursor.x_rot > Math_PI / 2.0)
+ cursor.x_rot = Math_PI / 2.0;
+ if (cursor.x_rot < -Math_PI / 2.0)
+ cursor.x_rot = -Math_PI / 2.0;
+
+ // Look is like the opposite of Orbit: the focus point rotates around the camera
+ Transform camera_transform = to_camera_transform(cursor);
+ Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 diff = prev_pos - pos;
+ cursor.pos += diff;
+
+ name = "";
+ _update_name();
}
void SpatialEditorViewport::set_freelook_active(bool active_now) {
@@ -3495,7 +3504,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT);
preview_camera = memnew(CheckBox);
- preview_camera->set_position(Point2(10 * EDSCALE, 15 * EDSCALE + view_menu->get_size().height));
+ preview_camera->set_position(Point2(10, 38) * EDSCALE); // Below the 'view_menu' MenuButton.
preview_camera->set_text(TTR("Preview"));
surface->add_child(preview_camera);
preview_camera->hide();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 30246147c2..40781908fd 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -548,7 +548,6 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
} else {
hide();
- //set_physics_process(false);
}
}
@@ -816,16 +815,26 @@ SpriteFramesEditor::SpriteFramesEditor() {
void SpriteFramesEditorPlugin::edit(Object *p_object) {
frames_editor->set_undo_redo(&get_undo_redo());
- SpriteFrames *s = Object::cast_to<SpriteFrames>(p_object);
- if (!s)
- return;
+
+ SpriteFrames *s;
+ AnimatedSprite *animated_sprite = Object::cast_to<AnimatedSprite>(p_object);
+ if (animated_sprite) {
+ s = *animated_sprite->get_sprite_frames();
+ } else {
+ s = Object::cast_to<SpriteFrames>(p_object);
+ }
frames_editor->edit(s);
}
bool SpriteFramesEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("SpriteFrames");
+ AnimatedSprite *animated_sprite = Object::cast_to<AnimatedSprite>(p_object);
+ if (animated_sprite && *animated_sprite->get_sprite_frames()) {
+ return true;
+ } else {
+ return p_object->is_class("SpriteFrames");
+ }
}
void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
@@ -833,14 +842,11 @@ void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
editor->make_bottom_panel_item_visible(frames_editor);
- //frames_editor->set_process(true);
} else {
button->hide();
if (frames_editor->is_visible_in_tree())
editor->hide_bottom_panel();
-
- //frames_editor->set_process(false);
}
}
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 4ff7046a35..1a43b16f3e 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -131,7 +131,7 @@ void TextEditor::_load_theme_settings() {
text_edit->add_color_override("search_result_border_color", search_result_border_color);
text_edit->add_color_override("symbol_color", symbol_color);
- text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
+ text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6));
colors_cache.font_color = text_color;
colors_cache.symbol_color = symbol_color;
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 9988d82fb8..7936b2a1e7 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -483,6 +483,11 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
//---------------
helper = memnew(TilesetEditorContext(this));
tile_names_opacity = 0;
+
+ // config scale
+ max_scale = 10.0f;
+ min_scale = 0.1f;
+ scale_ratio = 1.2f;
}
TileSetEditor::~TileSetEditor() {
@@ -972,6 +977,15 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
+
+ // Mouse Wheel Event
+ const int _mouse_button_index = mb->get_button_index();
+ if (_mouse_button_index == BUTTON_WHEEL_UP && mb->get_control()) {
+ _zoom_in();
+
+ } else if (_mouse_button_index == BUTTON_WHEEL_DOWN && mb->get_control()) {
+ _zoom_out();
+ }
}
// Drag Middle Mouse
if (mm.is_valid()) {
@@ -1448,23 +1462,11 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
}
}
} else if (p_tool == ZOOM_OUT) {
- float scale = workspace->get_scale().x;
- if (scale > 0.1) {
- scale /= 2;
- workspace->set_scale(Vector2(scale, scale));
- workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
- workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
- }
+ _zoom_out();
} else if (p_tool == ZOOM_1) {
- workspace->set_scale(Vector2(1, 1));
- workspace_container->set_custom_minimum_size(workspace->get_rect().size);
- workspace_overlay->set_custom_minimum_size(workspace->get_rect().size);
+ _reset_zoom();
} else if (p_tool == ZOOM_IN) {
- float scale = workspace->get_scale().x;
- scale *= 2;
- workspace->set_scale(Vector2(scale, scale));
- workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
- workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
+ _zoom_in();
} else if (p_tool == TOOL_SELECT) {
if (creating_shape) {
// Cancel Creation
@@ -1503,6 +1505,31 @@ void TileSetEditor::_set_snap_sep(Vector2 p_val) {
workspace->update();
}
+void TileSetEditor::_zoom_in() {
+ float scale = workspace->get_scale().x;
+ if (scale < max_scale) {
+ scale *= scale_ratio;
+ workspace->set_scale(Vector2(scale, scale));
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
+ }
+}
+void TileSetEditor::_zoom_out() {
+
+ float scale = workspace->get_scale().x;
+ if (scale > min_scale) {
+ scale /= scale_ratio;
+ workspace->set_scale(Vector2(scale, scale));
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
+ }
+}
+void TileSetEditor::_reset_zoom() {
+ workspace->set_scale(Vector2(1, 1));
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size);
+}
+
void TileSetEditor::draw_highlight_current_tile() {
if (get_current_tile() >= 0) {
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 23bf68b90f..bd8a2ddb98 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -141,6 +141,10 @@ class TileSetEditor : public Control {
EditMode edit_mode;
int current_tile;
+ float max_scale;
+ float min_scale;
+ float scale_ratio;
+
void update_texture_list();
void update_texture_list_icon();
@@ -178,6 +182,10 @@ private:
void _set_snap_off(Vector2 p_val);
void _set_snap_sep(Vector2 p_val);
+ void _zoom_in();
+ void _zoom_out();
+ void _reset_zoom();
+
void draw_highlight_current_tile();
void draw_highlight_subtile(Vector2 coord, const Vector<Vector2> &other_highlighted = Vector<Vector2>());
void draw_tile_subdivision(int p_id, Color p_color) const;
diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp
index 29a780961e..4a98aa411d 100644
--- a/editor/progress_dialog.cpp
+++ b/editor/progress_dialog.cpp
@@ -39,7 +39,7 @@ void BackgroundProgress::_add_task(const String &p_task, const String &p_label,
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(tasks.has(p_task));
- Task t;
+ BackgroundProgress::Task t;
t.hb = memnew(HBoxContainer);
Label *l = memnew(Label);
l->set_text(p_label + " ");
@@ -112,7 +112,7 @@ void BackgroundProgress::add_task(const String &p_task, const String &p_label, i
void BackgroundProgress::task_step(const String &p_task, int p_step) {
//this code is weird, but it prevents deadlock.
- bool no_updates;
+ bool no_updates = true;
{
_THREAD_SAFE_METHOD_
no_updates = updates.empty();
@@ -167,7 +167,7 @@ void ProgressDialog::_popup() {
void ProgressDialog::add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
ERR_FAIL_COND(tasks.has(p_task));
- Task t;
+ ProgressDialog::Task t;
t.vb = memnew(VBoxContainer);
VBoxContainer *vb2 = memnew(VBoxContainer);
t.vb->add_margin_child(p_label, vb2);
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 3ec49e187f..d2dccdb425 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -50,6 +50,7 @@ void ProjectExportDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
+ duplicate_preset->set_icon(get_icon("Duplicate", "EditorIcons"));
delete_preset->set_icon(get_icon("Remove", "EditorIcons"));
connect("confirmed", this, "_export_pck_zip");
custom_feature_display->get_parent_control()->add_style_override("panel", get_stylebox("bg", "Tree"));
@@ -58,6 +59,7 @@ void ProjectExportDialog::_notification(int p_what) {
EditorSettings::get_singleton()->set("interface/dialogs/export_bounds", get_rect());
} break;
case NOTIFICATION_THEME_CHANGED: {
+ duplicate_preset->set_icon(get_icon("Duplicate", "EditorIcons"));
delete_preset->set_icon(get_icon("Remove", "EditorIcons"));
Control *panel = custom_feature_display->get_parent_control();
if (panel)
@@ -171,6 +173,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
runnable->set_disabled(true);
parameters->edit(NULL);
presets->unselect_all();
+ duplicate_preset->set_disabled(true);
delete_preset->set_disabled(true);
sections->hide();
patches->clear();
@@ -188,6 +191,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
sections->show();
name->set_editable(true);
+ duplicate_preset->set_disabled(false);
delete_preset->set_disabled(false);
name->set_text(current->get_name());
runnable->set_disabled(false);
@@ -428,6 +432,61 @@ void ProjectExportDialog::_name_changed(const String &p_string) {
_update_presets();
}
+void ProjectExportDialog::_duplicate_preset() {
+
+ Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current());
+ if (current.is_null())
+ return;
+
+ Ref<EditorExportPreset> preset = current->get_platform()->create_preset();
+ ERR_FAIL_COND(!preset.is_valid());
+
+ String name = current->get_name() + "" + itos(1);
+ bool make_runnable = true;
+ int attempt = 2;
+ while (true) {
+
+ bool valid = true;
+
+ for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
+ Ref<EditorExportPreset> p = EditorExport::get_singleton()->get_export_preset(i);
+ if (p->get_platform() == preset->get_platform() && p->is_runnable()) {
+ make_runnable = false;
+ }
+ if (p->get_name() == name) {
+ valid = false;
+ break;
+ }
+ }
+
+ if (valid)
+ break;
+
+ attempt++;
+ name = current->get_name() + " " + itos(attempt);
+ }
+
+ preset->set_name(name);
+ if (make_runnable)
+ preset->set_runnable(make_runnable);
+ preset->set_export_filter(current->get_export_filter());
+ preset->set_include_filter(current->get_include_filter());
+ preset->set_exclude_filter(current->get_exclude_filter());
+ Vector<String> list = current->get_patches();
+ for (int i = 0; i < list.size(); i++) {
+ preset->add_patch(list[i]);
+ }
+ preset->set_custom_features(current->get_custom_features());
+
+ for (const List<PropertyInfo>::Element *E = current->get_properties().front(); E; E = E->next()) {
+ preset->set(E->get().name, current->get(E->get().name));
+ }
+
+ EditorExport::get_singleton()->add_export_preset(preset);
+ _update_presets();
+ _edit_preset(EditorExport::get_singleton()->get_export_preset_count() - 1);
+}
+
void ProjectExportDialog::_delete_preset() {
Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current());
@@ -745,12 +804,16 @@ void ProjectExportDialog::_export_project() {
export_project->set_access(FileDialog::ACCESS_FILESYSTEM);
export_project->clear_filters();
- String extension = platform->get_binary_extension(current);
- if (extension != String()) {
- export_project->add_filter("*." + extension + " ; " + platform->get_name() + " Export");
- export_project->set_current_file(default_filename + "." + extension);
+ if (current->get_export_path() != "") {
+ export_project->set_current_path(current->get_export_path());
} else {
- export_project->set_current_file(default_filename);
+ String extension = platform->get_binary_extension(current);
+ if (extension != String()) {
+ export_project->add_filter("*." + extension + " ; " + platform->get_name() + " Export");
+ export_project->set_current_file(default_filename + "." + extension);
+ } else {
+ export_project->set_current_file(default_filename);
+ }
}
// Ensure that signal is connected if previous attempt left it disconnected with _validate_export_path
@@ -772,6 +835,7 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
ERR_FAIL_COND(current.is_null());
Ref<EditorExportPlatform> platform = current->get_platform();
ERR_FAIL_COND(platform.is_null());
+ current->set_export_path(p_path);
Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0);
if (err != OK) {
@@ -789,6 +853,7 @@ void ProjectExportDialog::_bind_methods() {
ClassDB::bind_method("_update_parameters", &ProjectExportDialog::_update_parameters);
ClassDB::bind_method("_runnable_pressed", &ProjectExportDialog::_runnable_pressed);
ClassDB::bind_method("_name_changed", &ProjectExportDialog::_name_changed);
+ ClassDB::bind_method("_duplicate_preset", &ProjectExportDialog::_duplicate_preset);
ClassDB::bind_method("_delete_preset", &ProjectExportDialog::_delete_preset);
ClassDB::bind_method("_delete_preset_confirm", &ProjectExportDialog::_delete_preset_confirm);
ClassDB::bind_method("get_drag_data_fw", &ProjectExportDialog::get_drag_data_fw);
@@ -842,6 +907,9 @@ ProjectExportDialog::ProjectExportDialog() {
presets->set_drag_forwarding(this);
mc->add_child(presets);
presets->connect("item_selected", this, "_edit_preset");
+ duplicate_preset = memnew(ToolButton);
+ preset_hb->add_child(duplicate_preset);
+ duplicate_preset->connect("pressed", this, "_duplicate_preset");
delete_preset = memnew(ToolButton);
preset_hb->add_child(delete_preset);
delete_preset->connect("pressed", this, "_delete_preset");
@@ -949,6 +1017,7 @@ ProjectExportDialog::ProjectExportDialog() {
//disable by default
name->set_editable(false);
runnable->set_disabled(true);
+ duplicate_preset->set_disabled(true);
delete_preset->set_disabled(true);
sections->hide();
parameters->edit(NULL);
diff --git a/editor/project_export.h b/editor/project_export.h
index 552c6d7faf..a4bca843a8 100644
--- a/editor/project_export.h
+++ b/editor/project_export.h
@@ -61,6 +61,7 @@ private:
TabContainer *sections;
MenuButton *add_preset;
+ Button *duplicate_preset;
Button *delete_preset;
ItemList *presets;
@@ -108,6 +109,7 @@ private:
void _name_changed(const String &p_string);
void _add_preset(int p_platform);
void _edit_preset(int p_index);
+ void _duplicate_preset();
void _delete_preset();
void _delete_preset_confirm();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 45c20121da..fe438236c9 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -53,6 +53,13 @@ void SceneTreeDock::_nodes_drag_begin() {
}
}
+void SceneTreeDock::_quick_open() {
+ Vector<String> files = quick_open->get_selected_files();
+ for (int i = 0; i < files.size(); i++) {
+ instance(files[i]);
+ }
+}
+
void SceneTreeDock::_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> mb = p_event;
@@ -319,16 +326,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
- file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
- List<String> extensions;
- ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
- file->clear_filters();
- for (int i = 0; i < extensions.size(); i++) {
-
- file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
- }
-
- file->popup_centered_ratio();
+ quick_open->popup_dialog("PackedScene", true);
+ quick_open->set_title(TTR("Instance Child Scene"));
} break;
case TOOL_REPLACE: {
@@ -359,15 +358,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
ScriptLanguage *l = ScriptServer::get_language(i);
if (l->get_type() == existing->get_class()) {
String name = l->get_global_class_name(existing->get_path());
- if (ScriptServer::is_global_class(name)) {
- if (EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) {
- inherits = editor->get_editor_data().script_class_get_base(name);
- } else if (l->can_inherit_from_file()) {
- inherits = "\"" + existing->get_path() + "\"";
- }
- } else {
+ if (ScriptServer::is_global_class(name) && EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) {
+ inherits = name;
+ } else if (l->can_inherit_from_file()) {
inherits = "\"" + existing->get_path() + "\"";
}
+ break;
}
}
}
@@ -1307,6 +1303,13 @@ bool SceneTreeDock::_validate_no_foreign() {
return false;
}
+ // When edited_scene inherits from another one the root Node will be the parent Scene,
+ // we don't want to consider that Node a foreign one otherwise we would not be able to
+ // delete it
+ if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) {
+ continue;
+ }
+
if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) {
accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
@@ -1497,6 +1500,7 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
editor_data->get_undo_redo().commit_action();
editor->push_item(p_script.operator->());
+ _update_script_button();
}
void SceneTreeDock::_toggle_editable_children() {
@@ -1612,17 +1616,17 @@ void SceneTreeDock::_delete_confirm() {
void SceneTreeDock::_update_script_button() {
if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 1) {
- button_create_script->show();
Node *n = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()[0];
if (n->get_script().is_null()) {
- button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
- button_create_script->set_tooltip(TTR("Attach a new or existing script for the selected node."));
+ button_create_script->show();
+ button_clear_script->hide();
} else {
- button_create_script->set_icon(get_icon("ScriptExtend", "EditorIcons"));
- button_create_script->set_tooltip(TTR("Extend the selected node's script with a new or existing script."));
+ button_create_script->hide();
+ button_clear_script->show();
}
} else {
- button_create_script->hide();
+ button_create_script->show();
+ button_clear_script->hide();
}
}
@@ -2067,9 +2071,12 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
existing_script = selected->get_script();
}
- menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
+ if (!existing_script.is_valid()) {
+ menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
+ }
if (selection.size() > 1 || existing_script.is_valid()) {
menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_ATTACH_SCRIPT);
}
menu->add_separator();
@@ -2296,6 +2303,7 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_new_scene_from"), &SceneTreeDock::_new_scene_from);
ClassDB::bind_method(D_METHOD("_nodes_dragged"), &SceneTreeDock::_nodes_dragged);
ClassDB::bind_method(D_METHOD("_files_dropped"), &SceneTreeDock::_files_dropped);
+ ClassDB::bind_method(D_METHOD("_quick_open"), &SceneTreeDock::_quick_open);
ClassDB::bind_method(D_METHOD("_script_dropped"), &SceneTreeDock::_script_dropped);
ClassDB::bind_method(D_METHOD("_tree_rmb"), &SceneTreeDock::_tree_rmb);
ClassDB::bind_method(D_METHOD("_filter_changed"), &SceneTreeDock::_filter_changed);
@@ -2332,6 +2340,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/instance_scene", TTR("Instance Child Scene"));
ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
+ ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
ED_SHORTCUT("scene_tree/clear_script", TTR("Clear Script"));
ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KEY_MASK_CMD | KEY_UP);
ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN);
@@ -2363,10 +2372,12 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
filter->set_h_size_flags(SIZE_EXPAND_FILL);
filter->set_placeholder(TTR("Filter nodes"));
filter_hbc->add_child(filter);
+ filter->add_constant_override("minimum_spaces", 0);
filter->connect("text_changed", this, "_filter_changed");
tb = memnew(ToolButton);
tb->connect("pressed", this, "_tool_selected", make_binds(TOOL_ATTACH_SCRIPT, false));
+ tb->set_tooltip(TTR("Attach a new or existing script for the selected node."));
tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script"));
filter_hbc->add_child(tb);
tb->hide();
@@ -2445,9 +2456,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
accept = memnew(AcceptDialog);
add_child(accept);
- file = memnew(EditorFileDialog);
- add_child(file);
- file->connect("file_selected", this, "instance");
+ quick_open = memnew(EditorQuickOpen);
+ add_child(quick_open);
+ quick_open->connect("quick_open", this, "_quick_open");
set_process_unhandled_key_input(true);
delete_dialog = memnew(ConfirmationDialog);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index eea34a3ec5..3939f4f361 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -36,6 +36,7 @@
#include "editor/editor_data.h"
#include "editor/editor_sub_scene.h"
#include "editor/groups_editor.h"
+#include "editor/quick_open.h"
#include "editor/rename_dialog.h"
#include "editor/reparent_dialog.h"
#include "editor/script_create_dialog.h"
@@ -125,7 +126,7 @@ class SceneTreeDock : public VBoxContainer {
ConfirmationDialog *editable_instance_remove_dialog;
ReparentDialog *reparent_dialog;
- EditorFileDialog *file;
+ EditorQuickOpen *quick_open;
EditorSubScene *import_subscene_dialog;
EditorFileDialog *new_scene_from_dialog;
@@ -194,6 +195,7 @@ class SceneTreeDock : public VBoxContainer {
void _nodes_dragged(Array p_nodes, NodePath p_to, int p_type);
void _files_dropped(Vector<String> p_files, NodePath p_to, int p_type);
void _script_dropped(String p_file, NodePath p_to);
+ void _quick_open();
void _tree_rmb(const Vector2 &p_menu_pos);
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 848e4def6d..6614e24df7 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -665,6 +665,13 @@ void SceneTreeEditor::_renamed() {
Node *n = get_node(np);
ERR_FAIL_COND(!n);
+ // Empty node names are not allowed, so resets it to previous text and show warning
+ if (which->get_text(0).strip_edges().empty()) {
+ which->set_text(0, n->get_name());
+ EditorNode::get_singleton()->show_warning(TTR("No name provided"));
+ return;
+ }
+
String new_name = which->get_text(0);
if (!Node::_validate_node_name(new_name)) {