summaryrefslogtreecommitdiffstats
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_node.cpp37
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/editor_properties.cpp11
-rw-r--r--editor/editor_properties.h2
-rw-r--r--editor/editor_resource_picker.cpp34
-rw-r--r--editor/editor_resource_picker.h2
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/gui/editor_file_dialog.cpp44
-rw-r--r--editor/plugins/editor_context_menu_plugin.cpp22
-rw-r--r--editor/plugins/editor_context_menu_plugin.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp56
-rw-r--r--editor/plugins/node_3d_editor_plugin.h2
-rw-r--r--editor/plugins/theme_editor_plugin.cpp78
-rw-r--r--editor/plugins/theme_editor_plugin.h1
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp5
-rw-r--r--editor/project_settings_editor.cpp6
16 files changed, 156 insertions, 149 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 2853ebc499..d88fb134f1 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1983,7 +1983,7 @@ void EditorNode::try_autosave() {
editor_data.save_editor_external_data();
}
-void EditorNode::restart_editor() {
+void EditorNode::restart_editor(bool p_goto_project_manager) {
exiting = true;
if (project_run_bar->is_playing()) {
@@ -1991,22 +1991,25 @@ void EditorNode::restart_editor() {
}
String to_reopen;
- if (get_tree()->get_edited_scene_root()) {
+ if (!p_goto_project_manager && get_tree()->get_edited_scene_root()) {
to_reopen = get_tree()->get_edited_scene_root()->get_scene_file_path();
}
_exit_editor(EXIT_SUCCESS);
List<String> args;
-
for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_TOOL)) {
args.push_back(a);
}
- args.push_back("--path");
- args.push_back(ProjectSettings::get_singleton()->get_resource_path());
+ if (p_goto_project_manager) {
+ args.push_back("--project-manager");
+ } else {
+ args.push_back("--path");
+ args.push_back(ProjectSettings::get_singleton()->get_resource_path());
- args.push_back("-e");
+ args.push_back("-e");
+ }
if (!to_reopen.is_empty()) {
args.push_back(to_reopen);
@@ -2387,7 +2390,7 @@ void EditorNode::hide_unused_editors(const Object *p_editing_owner) {
// This is to sweep properties that were removed from the inspector.
List<ObjectID> to_remove;
for (KeyValue<ObjectID, HashSet<EditorPlugin *>> &kv : active_plugins) {
- const Object *context = ObjectDB::get_instance(kv.key);
+ Object *context = ObjectDB::get_instance(kv.key);
if (context) {
// In case of self-owning plugins, they are disabled here if they can auto hide.
const EditorPlugin *self_owning = Object::cast_to<EditorPlugin>(context);
@@ -2396,7 +2399,7 @@ void EditorNode::hide_unused_editors(const Object *p_editing_owner) {
}
}
- if (!context) {
+ if (!context || context->call(SNAME("_should_stop_editing"))) {
to_remove.push_back(kv.key);
for (EditorPlugin *plugin : kv.value) {
if (plugin->can_auto_hide()) {
@@ -3402,23 +3405,7 @@ void EditorNode::_discard_changes(const String &p_str) {
} break;
case RUN_PROJECT_MANAGER: {
- project_run_bar->stop_playing();
- _exit_editor(EXIT_SUCCESS);
- String exec = OS::get_singleton()->get_executable_path();
-
- List<String> args;
- for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_TOOL)) {
- args.push_back(a);
- }
-
- String exec_base_dir = exec.get_base_dir();
- if (!exec_base_dir.is_empty()) {
- args.push_back("--path");
- args.push_back(exec_base_dir);
- }
- args.push_back("--project-manager");
-
- OS::get_singleton()->set_restart_on_exit(true, args);
+ restart_editor(true);
} break;
case RELOAD_CURRENT_PROJECT: {
restart_editor();
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 55caed4bb4..696caf857c 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -926,7 +926,7 @@ public:
void save_scene_list(const HashSet<String> &p_scene_paths);
void save_before_run();
void try_autosave();
- void restart_editor();
+ void restart_editor(bool p_goto_project_manager = false);
void unload_editor_addons();
void dim_editor(bool p_dimming);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 897e7835fd..c5a35e466c 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -3179,6 +3179,10 @@ void EditorPropertyResource::_update_preferred_shader() {
}
}
+bool EditorPropertyResource::_should_stop_editing() const {
+ return !resource_picker->is_toggle_pressed();
+}
+
void EditorPropertyResource::_viewport_selected(const NodePath &p_path) {
Node *to_node = get_node(p_path);
if (!Object::cast_to<Viewport>(to_node)) {
@@ -3353,13 +3357,18 @@ void EditorPropertyResource::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_EXIT_TREE: {
const EditorInspector *ei = get_parent_inspector();
- if (ei && !ei->is_main_editor_inspector()) {
+ const EditorInspector *main_ei = InspectorDock::get_inspector_singleton();
+ if (ei && main_ei && ei != main_ei && !main_ei->is_ancestor_of(ei)) {
fold_resource();
}
} break;
}
}
+void EditorPropertyResource::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_should_stop_editing"), &EditorPropertyResource::_should_stop_editing);
+}
+
EditorPropertyResource::EditorPropertyResource() {
use_sub_inspector = bool(EDITOR_GET("interface/inspector/open_resources_in_current_inspector"));
has_borders = true;
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 2ec78cdb44..004630da3e 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -683,10 +683,12 @@ class EditorPropertyResource : public EditorProperty {
void _open_editor_pressed();
void _update_preferred_shader();
+ bool _should_stop_editing() const;
protected:
virtual void _set_read_only(bool p_read_only) override;
void _notification(int p_what);
+ static void _bind_methods();
public:
virtual void update_property() override;
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index e4ae2a6202..0f0287718c 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -132,6 +132,11 @@ void EditorResourcePicker::_resource_selected() {
emit_signal(SNAME("resource_selected"), edited_resource, false);
}
+void EditorResourcePicker::_resource_changed() {
+ emit_signal(SNAME("resource_changed"), edited_resource);
+ _update_resource();
+}
+
void EditorResourcePicker::_file_selected(const String &p_path) {
Ref<Resource> loaded_resource = ResourceLoader::load(p_path);
ERR_FAIL_COND_MSG(loaded_resource.is_null(), "Cannot load resource from path '" + p_path + "'.");
@@ -167,8 +172,7 @@ void EditorResourcePicker::_file_selected(const String &p_path) {
}
edited_resource = loaded_resource;
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
}
void EditorResourcePicker::_resource_saved(Object *p_resource) {
@@ -353,8 +357,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
case OBJ_MENU_CLEAR: {
edited_resource = Ref<Resource>();
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
} break;
case OBJ_MENU_MAKE_UNIQUE: {
@@ -366,8 +369,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
ERR_FAIL_COND(unique_resource.is_null()); // duplicate() may fail.
edited_resource = unique_resource;
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
} break;
case OBJ_MENU_MAKE_UNIQUE_RECURSIVE: {
@@ -432,9 +434,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
_edit_menu_cbk(OBJ_MENU_MAKE_UNIQUE);
return;
}
-
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
} break;
case OBJ_MENU_SHOW_IN_FILE_SYSTEM: {
@@ -453,8 +453,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
ERR_FAIL_INDEX(to_type, conversions.size());
edited_resource = conversions[to_type]->convert(edited_resource);
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
break;
}
@@ -481,8 +480,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
// Prevent freeing of the object until the end of the update of the resource (GH-88286).
Ref<Resource> old_edited_resource = edited_resource;
edited_resource = Ref<Resource>(resp);
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
} break;
}
}
@@ -778,8 +776,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
}
edited_resource = dropped_resource;
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
}
}
@@ -952,6 +949,10 @@ void EditorResourcePicker::set_toggle_pressed(bool p_pressed) {
assign_button->set_pressed(p_pressed);
}
+bool EditorResourcePicker::is_toggle_pressed() const {
+ return assign_button->is_pressed();
+}
+
void EditorResourcePicker::set_editable(bool p_editable) {
editable = p_editable;
assign_button->set_disabled(!editable && !edited_resource.is_valid());
@@ -1046,8 +1047,7 @@ void EditorResourcePicker::_duplicate_selected_resources() {
if (meta.size() == 1) { // Root.
edited_resource = unique_resource;
- emit_signal(SNAME("resource_changed"), edited_resource);
- _update_resource();
+ _resource_changed();
} else {
Array parent_meta = item->get_parent()->get_metadata(0);
Ref<Resource> parent = parent_meta[0];
diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h
index c39d9af764..0a32dea3ed 100644
--- a/editor/editor_resource_picker.h
+++ b/editor/editor_resource_picker.h
@@ -86,6 +86,7 @@ class EditorResourcePicker : public HBoxContainer {
void _update_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj);
void _resource_selected();
+ void _resource_changed();
void _file_selected(const String &p_path);
void _resource_saved(Object *p_resource);
@@ -134,6 +135,7 @@ public:
void set_toggle_mode(bool p_enable);
bool is_toggle_mode() const;
void set_toggle_pressed(bool p_pressed);
+ bool is_toggle_pressed() const;
void set_editable(bool p_editable);
bool is_editable() const;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index ceaffb64c4..ee06f08a2d 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -221,7 +221,6 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
const VariantContainer *v = props.getptr(p_name);
if (!v) {
- WARN_PRINT("EditorSettings::_get - Property not found: " + String(p_name));
return false;
}
r_ret = v->variant;
diff --git a/editor/gui/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp
index a63c3f7848..77d0ba7a60 100644
--- a/editor/gui/editor_file_dialog.cpp
+++ b/editor/gui/editor_file_dialog.cpp
@@ -1580,7 +1580,7 @@ void EditorFileDialog::_favorite_move_down() {
}
void EditorFileDialog::_update_favorites() {
- bool res = (access == ACCESS_RESOURCES);
+ bool access_resources = (access == ACCESS_RESOURCES);
String current = get_current_dir();
favorites->clear();
@@ -1596,8 +1596,11 @@ void EditorFileDialog::_update_favorites() {
for (int i = 0; i < favorited.size(); i++) {
String name = favorited[i];
- bool cres = name.begins_with("res://");
- if (cres != res || !name.ends_with("/")) {
+ if (access_resources != name.begins_with("res://")) {
+ continue;
+ }
+
+ if (!name.ends_with("/")) {
continue;
}
@@ -1609,7 +1612,7 @@ void EditorFileDialog::_update_favorites() {
}
// Compute favorite display text.
- if (res && name == "res://") {
+ if (access_resources && name == "res://") {
if (name == current) {
current_favorite = favorited_paths.size();
}
@@ -1620,7 +1623,7 @@ void EditorFileDialog::_update_favorites() {
if (name == current || name == current + "/") {
current_favorite = favorited_paths.size();
}
- name = name.substr(0, name.length() - 1);
+ name = name.trim_suffix("/");
name = name.get_file();
favorited_paths.append(favorited[i]);
favorited_names.append(name);
@@ -1647,7 +1650,7 @@ void EditorFileDialog::_update_favorites() {
}
void EditorFileDialog::_favorite_pressed() {
- bool res = (access == ACCESS_RESOURCES);
+ bool access_resources = (access == ACCESS_RESOURCES);
String cd = get_current_dir();
if (!cd.ends_with("/")) {
@@ -1657,13 +1660,12 @@ void EditorFileDialog::_favorite_pressed() {
Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
bool found = false;
- for (int i = 0; i < favorited.size(); i++) {
- bool cres = favorited[i].begins_with("res://");
- if (cres != res) {
+ for (const String &name : favorited) {
+ if (access_resources != name.begins_with("res://")) {
continue;
}
- if (favorited[i] == cd) {
+ if (name == cd) {
found = true;
break;
}
@@ -1683,31 +1685,30 @@ void EditorFileDialog::_favorite_pressed() {
void EditorFileDialog::_update_recent() {
recent->clear();
- bool res = (access == ACCESS_RESOURCES);
+ bool access_resources = (access == ACCESS_RESOURCES);
Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs();
Vector<String> recentd_paths;
Vector<String> recentd_names;
+ bool modified = false;
for (int i = 0; i < recentd.size(); i++) {
- bool cres = recentd[i].begins_with("res://");
- if (cres != res) {
+ String name = recentd[i];
+ if (access_resources != name.begins_with("res://")) {
continue;
}
- if (!dir_access->dir_exists(recentd[i])) {
+ if (!dir_access->dir_exists(name)) {
// Remove invalid directory from the list of Recent directories.
recentd.remove_at(i--);
+ modified = true;
continue;
}
// Compute recent directory display text.
- String name = recentd[i];
- if (res && name == "res://") {
+ if (access_resources && name == "res://") {
name = "/";
} else {
- if (name.ends_with("/")) {
- name = name.substr(0, name.length() - 1);
- }
+ name = name.trim_suffix("/");
name = name.get_file();
}
recentd_paths.append(recentd[i]);
@@ -1721,7 +1722,10 @@ void EditorFileDialog::_update_recent() {
recent->set_item_metadata(-1, recentd_paths[i]);
recent->set_item_icon_modulate(-1, get_dir_icon_color(recentd_paths[i]));
}
- EditorSettings::get_singleton()->set_recent_dirs(recentd);
+
+ if (modified) {
+ EditorSettings::get_singleton()->set_recent_dirs(recentd);
+ }
}
void EditorFileDialog::_recent_selected(int p_idx) {
diff --git a/editor/plugins/editor_context_menu_plugin.cpp b/editor/plugins/editor_context_menu_plugin.cpp
index 0648327fab..b635816bd9 100644
--- a/editor/plugins/editor_context_menu_plugin.cpp
+++ b/editor/plugins/editor_context_menu_plugin.cpp
@@ -67,10 +67,21 @@ void EditorContextMenuPlugin::add_context_menu_item_from_shortcut(const String &
context_menu_items.insert(p_name, item);
}
+void EditorContextMenuPlugin::add_context_submenu_item(const String &p_name, PopupMenu *p_menu, const Ref<Texture2D> &p_texture) {
+ ERR_FAIL_NULL(p_menu);
+
+ ContextMenuItem item;
+ item.item_name = p_name;
+ item.icon = p_texture;
+ item.submenu = p_menu;
+ context_menu_items.insert(p_name, item);
+}
+
void EditorContextMenuPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_menu_shortcut", "shortcut", "callback"), &EditorContextMenuPlugin::add_menu_shortcut);
ClassDB::bind_method(D_METHOD("add_context_menu_item", "name", "callback", "icon"), &EditorContextMenuPlugin::add_context_menu_item, DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("add_context_menu_item_from_shortcut", "name", "shortcut", "icon"), &EditorContextMenuPlugin::add_context_menu_item_from_shortcut, DEFVAL(Ref<Texture2D>()));
+ ClassDB::bind_method(D_METHOD("add_context_submenu_item", "name", "menu", "icon"), &EditorContextMenuPlugin::add_context_submenu_item, DEFVAL(Ref<Texture2D>()));
GDVIRTUAL_BIND(_popup_menu, "paths");
@@ -117,12 +128,17 @@ void EditorContextMenuPluginManager::add_options_from_plugins(PopupMenu *p_popup
EditorContextMenuPlugin::ContextMenuItem &item = E.value;
item.id = id;
- if (item.icon.is_valid()) {
- p_popup->add_icon_item(item.icon, item.item_name, id);
- p_popup->set_item_icon_max_width(-1, icon_size);
+ if (item.submenu) {
+ p_popup->add_submenu_node_item(item.item_name, item.submenu, id);
} else {
p_popup->add_item(item.item_name, id);
}
+
+ if (item.icon.is_valid()) {
+ p_popup->set_item_icon(-1, item.icon);
+ p_popup->set_item_icon_max_width(-1, icon_size);
+ }
+
if (item.shortcut.is_valid()) {
p_popup->set_item_shortcut(-1, item.shortcut, true);
}
diff --git a/editor/plugins/editor_context_menu_plugin.h b/editor/plugins/editor_context_menu_plugin.h
index 0232d254ba..86c67dedda 100644
--- a/editor/plugins/editor_context_menu_plugin.h
+++ b/editor/plugins/editor_context_menu_plugin.h
@@ -65,6 +65,7 @@ public:
Callable callable;
Ref<Texture2D> icon;
Ref<Shortcut> shortcut;
+ PopupMenu *submenu = nullptr;
};
HashMap<String, ContextMenuItem> context_menu_items;
HashMap<Ref<Shortcut>, Callable> context_menu_shortcuts;
@@ -80,6 +81,7 @@ public:
void add_menu_shortcut(const Ref<Shortcut> &p_shortcut, const Callable &p_callable);
void add_context_menu_item(const String &p_name, const Callable &p_callable, const Ref<Texture2D> &p_texture);
void add_context_menu_item_from_shortcut(const String &p_name, const Ref<Shortcut> &p_shortcut, const Ref<Texture2D> &p_texture);
+ void add_context_submenu_item(const String &p_name, PopupMenu *p_menu, const Ref<Texture2D> &p_texture);
};
VARIANT_ENUM_CAST(EditorContextMenuPlugin::ContextMenuSlot);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index fe7301975f..0cf194b7fe 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -4255,8 +4255,31 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
ray_params.to = world_pos + world_ray * camera->get_far();
PhysicsDirectSpaceState3D::RayResult result;
- if (ss->intersect_ray(ray_params, result)) {
- return result.position;
+ if (ss->intersect_ray(ray_params, result) && preview_node->get_child_count() > 0) {
+ // Calculate an offset for the `preview_node` such that the its bounding box is on top of and touching the contact surface's plane.
+
+ // Use the Gram-Schmidt process to get an orthonormal Basis aligned with the surface normal.
+ const Vector3 bb_basis_x = result.normal;
+ Vector3 bb_basis_y = Vector3(0, 1, 0);
+ bb_basis_y = bb_basis_y - bb_basis_y.project(bb_basis_x);
+ if (bb_basis_y.is_zero_approx()) {
+ bb_basis_y = Vector3(0, 0, 1);
+ bb_basis_y = bb_basis_y - bb_basis_y.project(bb_basis_x);
+ }
+ bb_basis_y = bb_basis_y.normalized();
+ const Vector3 bb_basis_z = bb_basis_x.cross(bb_basis_y);
+ const Basis bb_basis = Basis(bb_basis_x, bb_basis_y, bb_basis_z);
+
+ // This normal-aligned Basis allows us to create an AABB that can fit on the surface plane as snugly as possible.
+ const Transform3D bb_transform = Transform3D(bb_basis, preview_node->get_transform().origin);
+ const AABB preview_node_bb = _calculate_spatial_bounds(preview_node, true, &bb_transform);
+ // The x-axis's alignment with the surface normal also makes it trivial to get the distance from `preview_node`'s origin at (0, 0, 0) to the correct AABB face.
+ const float offset_distance = -preview_node_bb.position.x;
+
+ // `result_offset` is in global space.
+ const Vector3 result_offset = result.position + result.normal * offset_distance;
+
+ return result_offset;
}
const bool is_orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL;
@@ -4284,18 +4307,21 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
return world_pos + world_ray * FALLBACK_DISTANCE;
}
-AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, const Node3D *p_top_level_parent) {
+AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_omit_top_level, const Transform3D *p_bounds_orientation) {
AABB bounds;
- if (!p_top_level_parent) {
- p_top_level_parent = p_parent;
+ Transform3D bounds_orientation;
+ if (p_bounds_orientation) {
+ bounds_orientation = *p_bounds_orientation;
+ } else {
+ bounds_orientation = p_parent->get_global_transform();
}
if (!p_parent) {
return AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4));
}
- Transform3D xform_to_top_level_parent_space = p_top_level_parent->get_global_transform().affine_inverse() * p_parent->get_global_transform();
+ const Transform3D xform_to_top_level_parent_space = bounds_orientation.affine_inverse() * p_parent->get_global_transform();
const VisualInstance3D *visual_instance = Object::cast_to<VisualInstance3D>(p_parent);
if (visual_instance) {
@@ -4306,9 +4332,9 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, con
bounds = xform_to_top_level_parent_space.xform(bounds);
for (int i = 0; i < p_parent->get_child_count(); i++) {
- Node3D *child = Object::cast_to<Node3D>(p_parent->get_child(i));
- if (child) {
- AABB child_bounds = _calculate_spatial_bounds(child, p_top_level_parent);
+ const Node3D *child = Object::cast_to<Node3D>(p_parent->get_child(i));
+ if (child && !(p_omit_top_level && child->is_set_as_top_level())) {
+ const AABB child_bounds = _calculate_spatial_bounds(child, p_omit_top_level, &bounds_orientation);
bounds.merge_with(child_bounds);
}
}
@@ -4359,6 +4385,10 @@ void Node3DEditorViewport::_create_preview_node(const Vector<String> &files) con
if (instance) {
instance = _sanitize_preview_node(instance);
preview_node->add_child(instance);
+ Node3D *node_3d = Object::cast_to<Node3D>(instance);
+ if (node_3d) {
+ node_3d->set_as_top_level(false);
+ }
}
add_preview = true;
}
@@ -4579,8 +4609,12 @@ bool Node3DEditorViewport::_create_instance(Node *p_parent, const String &p_path
}
Transform3D new_tf = node3d->get_transform();
- new_tf.origin = parent_tf.affine_inverse().xform(preview_node_pos + node3d->get_position());
- new_tf.basis = parent_tf.affine_inverse().basis * new_tf.basis;
+ if (node3d->is_set_as_top_level()) {
+ new_tf.origin += preview_node_pos;
+ } else {
+ new_tf.origin = parent_tf.affine_inverse().xform(preview_node_pos + node3d->get_position());
+ new_tf.basis = parent_tf.affine_inverse().basis * new_tf.basis;
+ }
undo_redo->add_do_method(instantiated_scene, "set_transform", new_tf);
}
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index c7e6420875..a8cade36fd 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -472,7 +472,7 @@ private:
Point2 _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const;
Vector3 _get_instance_position(const Point2 &p_pos) const;
- static AABB _calculate_spatial_bounds(const Node3D *p_parent, const Node3D *p_top_level_parent = nullptr);
+ static AABB _calculate_spatial_bounds(const Node3D *p_parent, bool p_omit_top_level = false, const Transform3D *p_bounds_orientation = nullptr);
Node *_sanitize_preview_node(Node *p_node) const;
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 8f646a7621..cc488ff340 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -3596,6 +3596,13 @@ void ThemeEditor::_theme_close_button_cbk() {
}
}
+void ThemeEditor::_scene_closed(const String &p_path) {
+ if (theme.is_valid() && theme->is_built_in() && theme->get_path().get_slice("::", 0) == p_path) {
+ theme = Ref<Theme>();
+ EditorNode::get_singleton()->hide_unused_editors(plugin);
+ }
+}
+
void ThemeEditor::_add_preview_button_cbk() {
preview_scene_dialog->popup_file_dialog();
}
@@ -3679,7 +3686,10 @@ void ThemeEditor::_preview_control_picked(String p_class_name) {
void ThemeEditor::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_READY: {
+ EditorNode::get_singleton()->connect("scene_closed", callable_mp(this, &ThemeEditor::_scene_closed));
+ } break;
+
case NOTIFICATION_THEME_CHANGED: {
preview_tabs->add_theme_style_override("tab_selected", get_theme_stylebox(SNAME("ThemeEditorPreviewFG"), EditorStringName(EditorStyles)));
preview_tabs->add_theme_style_override("tab_unselected", get_theme_stylebox(SNAME("ThemeEditorPreviewBG"), EditorStringName(EditorStyles)));
@@ -3807,71 +3817,7 @@ void ThemeEditorPlugin::make_visible(bool p_visible) {
}
bool ThemeEditorPlugin::can_auto_hide() const {
- Ref<Theme> edited_theme = theme_editor->theme;
- if (edited_theme.is_null()) {
- return true;
- }
-
- Ref<Resource> edited_resource = Ref<Resource>(InspectorDock::get_inspector_singleton()->get_next_edited_object());
- if (edited_resource.is_null()) {
- return true;
- }
-
- // Don't hide if edited resource used by this theme.
- Ref<StyleBox> sbox = edited_resource;
- if (sbox.is_valid()) {
- List<StringName> type_list;
- edited_theme->get_stylebox_type_list(&type_list);
-
- for (const StringName &E : type_list) {
- List<StringName> list;
- edited_theme->get_stylebox_list(E, &list);
-
- for (const StringName &F : list) {
- if (edited_theme->get_stylebox(F, E) == sbox) {
- return false;
- }
- }
- }
- return true;
- }
-
- Ref<Texture2D> tex = edited_resource;
- if (tex.is_valid()) {
- List<StringName> type_list;
- edited_theme->get_icon_type_list(&type_list);
-
- for (const StringName &E : type_list) {
- List<StringName> list;
- edited_theme->get_icon_list(E, &list);
-
- for (const StringName &F : list) {
- if (edited_theme->get_icon(F, E) == tex) {
- return false;
- }
- }
- }
- return true;
- }
-
- Ref<Font> fnt = edited_resource;
- if (fnt.is_valid()) {
- List<StringName> type_list;
- edited_theme->get_font_type_list(&type_list);
-
- for (const StringName &E : type_list) {
- List<StringName> list;
- edited_theme->get_font_list(E, &list);
-
- for (const StringName &F : list) {
- if (edited_theme->get_font(F, E) == fnt) {
- return false;
- }
- }
- }
- return true;
- }
- return true;
+ return theme_editor->theme.is_null();
}
ThemeEditorPlugin::ThemeEditorPlugin() {
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index 1d009637b7..39dc8d154b 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -445,6 +445,7 @@ class ThemeEditor : public VBoxContainer {
void _theme_save_button_cbk(bool p_save_as);
void _theme_edit_button_cbk();
void _theme_close_button_cbk();
+ void _scene_closed(const String &p_path);
void _add_preview_button_cbk();
void _preview_scene_dialog_cbk(const String &p_path);
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 12b9761fd2..c6921699a4 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -874,6 +874,11 @@ void GenericTilePolygonEditor::_notification(int p_what) {
button_expand->set_pressed_no_signal(false);
}
} break;
+
+ case NOTIFICATION_READY: {
+ get_parent()->connect(SceneStringName(tree_exited), callable_mp(TileSetEditor::get_singleton(), &TileSetEditor::remove_expanded_editor));
+ } break;
+
case NOTIFICATION_THEME_CHANGED: {
button_expand->set_icon(get_editor_theme_icon(SNAME("DistractionFree")));
button_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate")));
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 418f4e4932..f973367bed 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -104,7 +104,8 @@ void ProjectSettingsEditor::_update_advanced(bool p_is_advanced) {
}
void ProjectSettingsEditor::_advanced_toggled(bool p_button_pressed) {
- EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", p_button_pressed);
+ EditorSettings::get_singleton()->set("_project_settings_advanced_mode", p_button_pressed);
+ EditorSettings::get_singleton()->save();
_update_advanced(p_button_pressed);
}
@@ -768,8 +769,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
set_ok_button_text(TTR("Close"));
set_hide_on_ok(true);
- bool use_advanced = EditorSettings::get_singleton()->get_project_metadata("project_settings", "advanced_mode", false);
-
+ bool use_advanced = EDITOR_DEF("_project_settings_advanced_mode", false);
if (use_advanced) {
advanced->set_pressed(true);
}