From b41d6ecf8cc300d2abac58b76ee3d70ac85851e0 Mon Sep 17 00:00:00 2001 From: kobewi Date: Mon, 21 Nov 2022 20:07:15 +0100 Subject: [PATCH] Allow to override editor settings per project --- core/config/project_settings.cpp | 26 ++++- core/config/project_settings.h | 9 ++ doc/classes/EditorProperty.xml | 5 + editor/editor_inspector.cpp | 14 ++- editor/editor_inspector.h | 2 + editor/editor_node.cpp | 15 +++ editor/editor_node.h | 4 + editor/editor_sectioned_inspector.cpp | 2 + editor/editor_settings.cpp | 7 +- editor/editor_settings_dialog.cpp | 121 +++++++++++++++++++++ editor/editor_settings_dialog.h | 42 +++++++ editor/export/editor_export_platform.cpp | 6 +- editor/gui/editor_spin_slider.cpp | 2 +- editor/plugins/node_3d_editor_plugin.cpp | 2 +- editor/project_settings_editor.cpp | 48 +++++++- editor/project_settings_editor.h | 7 ++ editor/themes/editor_theme_manager.cpp | 2 +- main/main.cpp | 5 +- modules/gltf/register_types.cpp | 2 +- platform/linuxbsd/export/export_plugin.cpp | 2 +- platform/macos/export/export_plugin.cpp | 2 +- platform/windows/export/export_plugin.cpp | 2 +- 22 files changed, 306 insertions(+), 21 deletions(-) diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index bd4762bd144..f1f33eb07c7 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -482,6 +482,18 @@ void ProjectSettings::_get_property_list(List *p_list) const { pi.name = base.name; pi.usage = base.flags; p_list->push_back(pi); +#ifdef TOOLS_ENABLED + } else if (base.name.begins_with(EDITOR_SETTING_OVERRIDE_PREFIX)) { + PropertyInfo info(base.type, base.name, PROPERTY_HINT_NONE, "", base.flags); + + const PropertyInfo *pi = editor_settings_info.getptr(base.name.trim_prefix(EDITOR_SETTING_OVERRIDE_PREFIX)); + if (pi) { + info.usage = pi->usage; + info.hint = pi->hint; + info.hint_string = pi->hint_string; + } + p_list->push_back(info); +#endif } else { p_list->push_back(PropertyInfo(base.type, base.name, PROPERTY_HINT_NONE, "", base.flags)); } @@ -1263,7 +1275,7 @@ bool ProjectSettings::is_project_loaded() const { } bool ProjectSettings::_property_can_revert(const StringName &p_name) const { - return props.has(p_name); + return props.has(p_name) && !String(p_name).begins_with(EDITOR_SETTING_OVERRIDE_PREFIX); } bool ProjectSettings::_property_get_revert(const StringName &p_name, Variant &r_property) const { @@ -1449,6 +1461,18 @@ void ProjectSettings::get_argument_options(const StringName &p_function, int p_i } #endif +void ProjectSettings::set_editor_setting_override(const String &p_setting, const Variant &p_value) { + set_setting(EDITOR_SETTING_OVERRIDE_PREFIX + p_setting, p_value); +} + +bool ProjectSettings::has_editor_setting_override(const String &p_setting) const { + return has_setting(EDITOR_SETTING_OVERRIDE_PREFIX + p_setting); +} + +Variant ProjectSettings::get_editor_setting_override(const String &p_setting) const { + return get_setting(EDITOR_SETTING_OVERRIDE_PREFIX + p_setting); +} + void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting); ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 58caa67cc8a..cf82d03c610 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -49,6 +49,7 @@ class ProjectSettings : public Object { public: typedef HashMap CustomMap; static inline const String PROJECT_DATA_DIR_NAME_SUFFIX = "godot"; + static inline const String EDITOR_SETTING_OVERRIDE_PREFIX = "editor_overrides/"; // Properties that are not for built in values begin from this value, so builtin ones are displayed first. constexpr static const int32_t NO_BUILTIN_ORDER_BASE = 1 << 16; @@ -153,6 +154,10 @@ protected: public: static const int CONFIG_VERSION = 5; +#ifdef TOOLS_ENABLED + HashMap editor_settings_info; +#endif + void set_setting(const String &p_setting, const Variant &p_value); Variant get_setting(const String &p_setting, const Variant &p_default_value = Variant()) const; TypedArray get_global_class_list(); @@ -229,6 +234,10 @@ public: virtual void get_argument_options(const StringName &p_function, int p_idx, List *r_options) const override; #endif + void set_editor_setting_override(const String &p_setting, const Variant &p_value); + bool has_editor_setting_override(const String &p_setting) const; + Variant get_editor_setting_override(const String &p_setting) const; + ProjectSettings(); ProjectSettings(const String &p_path); ~ProjectSettings(); diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml index 19f73c1a1de..e34d613e775 100644 --- a/doc/classes/EditorProperty.xml +++ b/doc/classes/EditorProperty.xml @@ -204,6 +204,11 @@ Emit it if you want to key a property with a single value. + + + Emitted when a setting override for the current project is requested. + + diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index d52e513c7f6..a8449a347c9 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1296,6 +1296,9 @@ void EditorProperty::menu_option(int p_option) { case MENU_COPY_PROPERTY_PATH: { DisplayServer::get_singleton()->clipboard_set(property_path); } break; + case MENU_OVERRIDE_FOR_PROJECT: { + emit_signal(SNAME("property_overridden")); + } break; case MENU_FAVORITE_PROPERTY: { emit_signal(SNAME("property_favorited"), property, !favorited); queue_redraw(); @@ -1396,6 +1399,7 @@ void EditorProperty::_bind_methods() { ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING_NAME, "property"))); ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "checked"))); + ADD_SIGNAL(MethodInfo("property_overridden")); ADD_SIGNAL(MethodInfo("property_favorited", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "favorited"))); ADD_SIGNAL(MethodInfo("property_pinned", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "pinned"))); ADD_SIGNAL(MethodInfo("property_can_revert_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "can_revert"))); @@ -1462,10 +1466,13 @@ void EditorProperty::_update_popup() { } menu->set_item_tooltip(menu->get_item_index(MENU_PIN_VALUE), TTR("Pinning a value forces it to be saved even if it's equal to the default.")); } - if (deletable || can_revert) { + if (deletable || can_revert || can_override) { menu->add_separator(); + if (can_override) { + menu->add_icon_item(get_editor_theme_icon(SNAME("Override")), TTRC("Override for Project"), MENU_OVERRIDE_FOR_PROJECT); + } if (deletable) { - menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Property"), MENU_PIN_VALUE); + menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Property"), MENU_DELETE); } if (can_revert) { menu->add_icon_item(get_editor_theme_icon(SNAME("Reload")), TTR("Revert Value"), MENU_REVERT_VALUE); @@ -4924,6 +4931,9 @@ void EditorInspector::_property_deleted(const String &p_path) { undo_redo->commit_action(); } + if (restart_request_props.has(p_path)) { + emit_signal(SNAME("restart_requested")); + } emit_signal(SNAME("property_deleted"), p_path); } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 2cdbe875a5f..0fb7ffdf6c2 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -65,6 +65,7 @@ public: MENU_COPY_VALUE, MENU_PASTE_VALUE, MENU_COPY_PROPERTY_PATH, + MENU_OVERRIDE_FOR_PROJECT, MENU_FAVORITE_PROPERTY, MENU_PIN_VALUE, MENU_DELETE, @@ -147,6 +148,7 @@ private: protected: bool has_borders = false; + bool can_override = false; void _notification(int p_what); static void _bind_methods(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6188eeeecb9..7f109aefbba 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -770,6 +770,12 @@ void EditorNode::_notification(int p_what) { EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorNode::_execute_upgrades), CONNECT_ONE_SHOT); EditorFileSystem::get_singleton()->scan(); } + + if (settings_overrides_changed) { + EditorSettings::get_singleton()->notify_changes(); + EditorSettings::get_singleton()->emit_signal(SNAME("settings_changed")); + settings_overrides_changed = false; + } } break; case NOTIFICATION_ENTER_TREE: { @@ -7368,6 +7374,15 @@ GameViewPluginBase *get_game_view_plugin() { } #endif +void EditorNode::open_setting_override(const String &p_property) { + editor_settings_dialog->hide(); + project_settings_editor->popup_for_override(p_property); +} + +void EditorNode::notify_settings_overrides_changed() { + settings_overrides_changed = true; +} + EditorNode::EditorNode() { DEV_ASSERT(!singleton); singleton = this; diff --git a/editor/editor_node.h b/editor/editor_node.h index 163075d0d27..7b494c73147 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -448,6 +448,7 @@ private: bool convert_old = false; bool immediate_dialog_confirmed = false; bool restoring_scenes = false; + bool settings_overrides_changed = false; bool unsaved_cache = true; bool requested_first_scan = false; @@ -977,6 +978,9 @@ public: void restart_editor(bool p_goto_project_manager = false); void unload_editor_addons(); + void open_setting_override(const String &p_property); + void notify_settings_overrides_changed(); + void dim_editor(bool p_dimming); bool is_editor_dimmed() const; diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 29eeb18b5ae..5c60ba9990e 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -141,6 +141,7 @@ public: void SectionedInspector::_bind_methods() { ClassDB::bind_method("update_category_list", &SectionedInspector::update_category_list); + ADD_SIGNAL(MethodInfo("category_changed", PropertyInfo(Variant::STRING, "new_category"))); } void SectionedInspector::_section_selected() { @@ -152,6 +153,7 @@ void SectionedInspector::_section_selected() { filter->set_section(selected_category, sections->get_selected()->get_first_child() == nullptr); inspector->set_property_prefix(selected_category + "/"); inspector->set_v_scroll(0); + emit_signal(SNAME("category_changed"), selected_category); } void SectionedInspector::set_current_section(const String &p_section) { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 332e866bc10..d07d15355f2 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -1347,7 +1347,7 @@ fail: } void EditorSettings::setup_language() { - String lang = get("interface/editor/editor_language"); + String lang = _EDITOR_GET("interface/editor/editor_language"); if (lang == "en") { TranslationServer::get_singleton()->set_locale(lang); @@ -1460,6 +1460,9 @@ void EditorSettings::set_setting(const String &p_setting, const Variant &p_value Variant EditorSettings::get_setting(const String &p_setting) const { _THREAD_SAFE_METHOD_ + if (ProjectSettings::get_singleton()->has_editor_setting_override(p_setting)) { + return ProjectSettings::get_singleton()->get_editor_setting_override(p_setting); + } return get(p_setting); } @@ -1534,7 +1537,7 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re Variant _EDITOR_GET(const String &p_setting) { ERR_FAIL_COND_V(!EditorSettings::get_singleton() || !EditorSettings::get_singleton()->has_setting(p_setting), Variant()); - return EditorSettings::get_singleton()->get(p_setting); + return EditorSettings::get_singleton()->get_setting(p_setting); } bool EditorSettings::_property_can_revert(const StringName &p_name) const { diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 08c6f2c78a0..f678f497fae 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -30,6 +30,7 @@ #include "editor_settings_dialog.h" +#include "core/config/project_settings.h" #include "core/input/input_map.h" #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" @@ -44,6 +45,7 @@ #include "editor/event_listener_line_edit.h" #include "editor/input_event_configuration_dialog.h" #include "editor/plugins/node_3d_editor_plugin.h" +#include "editor/project_settings_editor.h" #include "editor/themes/editor_scale.h" #include "editor/themes/editor_theme_manager.h" #include "scene/gui/check_button.h" @@ -239,6 +241,8 @@ void EditorSettingsDialog::_notification(int p_what) { } break; case NOTIFICATION_READY: { + EditorSettingsPropertyWrapper::restart_request_callback = callable_mp(this, &EditorSettingsDialog::_editor_restart_request); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_method_notify_callback(EditorDebuggerNode::_methods_changed, nullptr); undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_property_notify_callback(EditorDebuggerNode::_properties_changed, nullptr); @@ -1009,4 +1013,121 @@ EditorSettingsDialog::EditorSettingsDialog() { add_child(timer); EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &EditorSettingsDialog::_settings_changed)); set_ok_button_text(TTRC("Close")); + + Ref plugin; + plugin.instantiate(); + plugin->inspector = inspector; + EditorInspector::add_inspector_plugin(plugin); +} + +void EditorSettingsPropertyWrapper::_update_override() { + // Don't allow overriding theme properties, because it causes problems. Overriding Project Manager settings makes no sense. + // TODO: Find a better way to define exception prefixes (if the list happens to grow). + if (property.begins_with("interface/theme") || property.begins_with("project_manager")) { + can_override = false; + return; + } + + const bool has_override = ProjectSettings::get_singleton()->has_editor_setting_override(property); + if (has_override) { + const Variant override_value = EDITOR_GET(property); + override_label->set_text(vformat(TTR("Overridden in project: %s"), override_value)); + // In case the text is too long and trimmed. + override_label->set_tooltip_text(override_value); + } + override_info->set_visible(has_override); + can_override = !has_override; +} + +void EditorSettingsPropertyWrapper::_create_override() { + ProjectSettings::get_singleton()->set_editor_setting_override(property, EDITOR_GET(property)); + ProjectSettings::get_singleton()->save(); + _update_override(); +} + +void EditorSettingsPropertyWrapper::_remove_override() { + ProjectSettings::get_singleton()->set_editor_setting_override(property, Variant()); + ProjectSettings::get_singleton()->save(); + EditorSettings::get_singleton()->mark_setting_changed(property); + EditorNode::get_singleton()->notify_settings_overrides_changed(); + _update_override(); + + if (requires_restart) { + restart_request_callback.call(); + } +} + +void EditorSettingsPropertyWrapper::_notification(int p_what) { + if (p_what == NOTIFICATION_THEME_CHANGED) { + goto_button->set_button_icon(get_editor_theme_icon(SNAME("MethodOverride"))); + remove_button->set_button_icon(get_editor_theme_icon(SNAME("Close"))); + } +} + +void EditorSettingsPropertyWrapper::update_property() { + editor_property->update_property(); +} + +void EditorSettingsPropertyWrapper::setup(const String &p_property, EditorProperty *p_editor_property, bool p_requires_restart) { + requires_restart = p_requires_restart; + + property = p_property; + container = memnew(VBoxContainer); + + editor_property = p_editor_property; + editor_property->set_h_size_flags(SIZE_EXPAND_FILL); + container->add_child(editor_property); + + override_info = memnew(HBoxContainer); + override_info->hide(); + container->add_child(override_info); + + override_label = memnew(Label); + override_label->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); + override_label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); + override_label->set_mouse_filter(MOUSE_FILTER_STOP); // For tooltip. + override_label->set_h_size_flags(SIZE_EXPAND_FILL); + override_info->add_child(override_label); + + goto_button = memnew(Button); + goto_button->set_tooltip_text(TTRC("Go to the override in the Project Settings.")); + override_info->add_child(goto_button); + goto_button->connect(SceneStringName(pressed), callable_mp(EditorNode::get_singleton(), &EditorNode::open_setting_override).bind(property), CONNECT_DEFERRED); + + remove_button = memnew(Button); + remove_button->set_tooltip_text(TTRC("Remove this override.")); + override_info->add_child(remove_button); + remove_button->connect(SceneStringName(pressed), callable_mp(this, &EditorSettingsPropertyWrapper::_remove_override)); + + add_child(container); + _update_override(); + + connect(SNAME("property_overridden"), callable_mp(this, &EditorSettingsPropertyWrapper::_create_override)); + editor_property->connect("property_changed", callable_mp((EditorProperty *)this, &EditorProperty::emit_changed)); +} + +bool EditorSettingsInspectorPlugin::can_handle(Object *p_object) { + return p_object->is_class("SectionedInspectorFilter") && p_object != current_object; +} + +bool EditorSettingsInspectorPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField p_usage, const bool p_wide) { + if (!p_object->is_class("SectionedInspectorFilter")) { + return false; + } + + const String property = inspector->get_full_item_path(p_path); + if (!EditorSettings::get_singleton()->has_setting(property)) { + return false; + } + current_object = p_object; + + EditorSettingsPropertyWrapper *editor = memnew(EditorSettingsPropertyWrapper); + EditorProperty *real_property = inspector->get_inspector()->instantiate_property_editor(p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide); + real_property->set_object_and_property(p_object, p_path); + real_property->set_name_split_ratio(0.0); + editor->setup(property, real_property, bool(p_usage & PROPERTY_USAGE_RESTART_IF_CHANGED)); + + add_property_editor(p_path, editor); + current_object = nullptr; + return true; } diff --git a/editor/editor_settings_dialog.h b/editor/editor_settings_dialog.h index b4fb94fcb4b..dd438b77880 100644 --- a/editor/editor_settings_dialog.h +++ b/editor/editor_settings_dialog.h @@ -30,6 +30,7 @@ #pragma once +#include "editor/editor_inspector.h" #include "scene/gui/dialogs.h" class CheckButton; @@ -137,3 +138,44 @@ public: EditorSettingsDialog(); }; + +class EditorSettingsPropertyWrapper : public EditorProperty { + GDCLASS(EditorSettingsPropertyWrapper, EditorProperty); + + String property; + EditorProperty *editor_property = nullptr; + + BoxContainer *container = nullptr; + + HBoxContainer *override_info = nullptr; + Label *override_label = nullptr; + Button *goto_button = nullptr; + Button *remove_button = nullptr; + + bool requires_restart = false; + + void _update_override(); + void _create_override(); + void _remove_override(); + +protected: + void _notification(int p_what); + +public: + static inline Callable restart_request_callback; + + virtual void update_property() override; + void setup(const String &p_property, EditorProperty *p_editor_property, bool p_requires_restart); +}; + +class EditorSettingsInspectorPlugin : public EditorInspectorPlugin { + GDCLASS(EditorSettingsInspectorPlugin, EditorInspectorPlugin); + + Object *current_object = nullptr; + +public: + SectionedInspector *inspector = nullptr; + + virtual bool can_handle(Object *p_object) override; + virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField p_usage, const bool p_wide = false) override; +}; diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index 8f877056b68..cfd35bf73c6 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -2330,7 +2330,7 @@ bool EditorExportPlatform::can_export(const Ref &p_preset, S } Error EditorExportPlatform::ssh_run_on_remote(const String &p_host, const String &p_port, const Vector &p_ssh_args, const String &p_cmd_args, String *r_out, int p_port_fwd) const { - String ssh_path = EditorSettings::get_singleton()->get("export/ssh/ssh"); + String ssh_path = EDITOR_GET("export/ssh/ssh"); if (ssh_path.is_empty()) { ssh_path = "ssh"; } @@ -2387,7 +2387,7 @@ Error EditorExportPlatform::ssh_run_on_remote(const String &p_host, const String } Error EditorExportPlatform::ssh_run_on_remote_no_wait(const String &p_host, const String &p_port, const Vector &p_ssh_args, const String &p_cmd_args, OS::ProcessID *r_pid, int p_port_fwd) const { - String ssh_path = EditorSettings::get_singleton()->get("export/ssh/ssh"); + String ssh_path = EDITOR_GET("export/ssh/ssh"); if (ssh_path.is_empty()) { ssh_path = "ssh"; } @@ -2424,7 +2424,7 @@ Error EditorExportPlatform::ssh_run_on_remote_no_wait(const String &p_host, cons } Error EditorExportPlatform::ssh_push_to_remote(const String &p_host, const String &p_port, const Vector &p_scp_args, const String &p_src_file, const String &p_dst_file) const { - String scp_path = EditorSettings::get_singleton()->get("export/ssh/scp"); + String scp_path = EDITOR_GET("export/ssh/scp"); if (scp_path.is_empty()) { scp_path = "scp"; } diff --git a/editor/gui/editor_spin_slider.cpp b/editor/gui/editor_spin_slider.cpp index fddbadfa2d7..81d7250b115 100644 --- a/editor/gui/editor_spin_slider.cpp +++ b/editor/gui/editor_spin_slider.cpp @@ -453,7 +453,7 @@ void EditorSpinSlider::_draw_spin_slider() { void EditorSpinSlider::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - grabbing_spinner_speed = EditorSettings::get_singleton()->get("interface/inspector/float_drag_speed"); + grabbing_spinner_speed = EDITOR_GET("interface/inspector/float_drag_speed"); _update_value_input_stylebox(); } break; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 12afa4de4c2..806968b3eed 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -236,7 +236,7 @@ void ViewportNavigationControl::_update_navigation() { real_t speed_multiplier = MIN(delta.length() / (get_size().x * 100.0), 3.0); real_t speed = viewport->freelook_speed * speed_multiplier; - const Node3DEditorViewport::FreelookNavigationScheme navigation_scheme = (Node3DEditorViewport::FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int(); + const Node3DEditorViewport::FreelookNavigationScheme navigation_scheme = (Node3DEditorViewport::FreelookNavigationScheme)EDITOR_GET("editors/3d/freelook/freelook_navigation_scheme").operator int(); Vector3 forward; if (navigation_scheme == Node3DEditorViewport::FreelookNavigationScheme::FREELOOK_FULLY_AXIS_LOCKED) { diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 7bb6a72182d..649933077fb 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -74,6 +74,12 @@ void ProjectSettingsEditor::popup_project_settings(bool p_clear_filter) { _focus_current_search_box(); } +void ProjectSettingsEditor::popup_for_override(const String &p_override) { + popup_project_settings(); + tab_container->set_current_tab(0); + general_settings_inspector->set_current_section(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX + p_override.get_slicec('/', 0)); +} + void ProjectSettingsEditor::queue_save() { settings_changed = true; timer->start(); @@ -84,6 +90,10 @@ void ProjectSettingsEditor::_save() { if (ps) { ps->save(); } + if (pending_override_notify) { + pending_override_notify = false; + EditorNode::get_singleton()->notify_settings_overrides_changed(); + } } void ProjectSettingsEditor::set_plugins_page() { @@ -104,6 +114,11 @@ void ProjectSettingsEditor::init_autoloads() { } void ProjectSettingsEditor::_setting_edited(const String &p_name) { + const String full_name = general_settings_inspector->get_full_item_path(p_name); + if (full_name.begins_with(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX)) { + EditorSettings::get_singleton()->mark_setting_changed(full_name.trim_prefix(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX)); + pending_override_notify = true; + } queue_save(); } @@ -111,6 +126,21 @@ void ProjectSettingsEditor::_update_advanced(bool p_is_advanced) { custom_properties->set_visible(p_is_advanced); } +void ProjectSettingsEditor::_on_category_changed(const String &p_new_category) { + general_settings_inspector->get_inspector()->set_use_deletable_properties(p_new_category.begins_with(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX)); +} + +void ProjectSettingsEditor::_on_editor_override_deleted(const String &p_setting) { + const String full_name = general_settings_inspector->get_full_item_path(p_setting); + ERR_FAIL_COND(!full_name.begins_with(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX)); + + ProjectSettings::get_singleton()->set_setting(full_name, Variant()); + EditorSettings::get_singleton()->mark_setting_changed(full_name.trim_prefix(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX)); + pending_override_notify = true; + _save(); + general_settings_inspector->update_category_list(); +} + void ProjectSettingsEditor::_advanced_toggled(bool p_button_pressed) { EditorSettings::get_singleton()->set("_project_settings_advanced_mode", p_button_pressed); EditorSettings::get_singleton()->save(); @@ -224,7 +254,7 @@ void ProjectSettingsEditor::_update_property_box() { } if (ps->has_setting(setting)) { - del_button->set_disabled(ps->is_builtin_setting(setting)); + del_button->set_disabled(ps->is_builtin_setting(setting) || setting.begins_with(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX)); _select_type(ps->get_setting(setting).get_type()); } else { if (ps->has_setting(name)) { @@ -233,7 +263,7 @@ void ProjectSettingsEditor::_update_property_box() { type_box->select(0); } - if (feature_invalid) { + if (feature_invalid || name.begins_with(ProjectSettings::EDITOR_SETTING_OVERRIDE_PREFIX)) { return; } @@ -611,7 +641,17 @@ void ProjectSettingsEditor::_update_theme() { void ProjectSettingsEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { - if (!is_visible()) { + if (is_visible()) { + HashMap editor_settings_info; + + List infos; + EditorSettings::get_singleton()->get_property_list(&infos); + + for (const PropertyInfo &pi : infos) { + editor_settings_info[pi.name] = pi; + } + ProjectSettings::get_singleton()->editor_settings_info = editor_settings_info; + } else { EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "project_settings", Rect2(get_position(), get_size())); if (settings_changed) { timer->stop(); @@ -712,10 +752,12 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { general_settings_inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL); general_settings_inspector->register_search_box(search_box); general_settings_inspector->register_advanced_toggle(advanced); + general_settings_inspector->connect("category_changed", callable_mp(this, &ProjectSettingsEditor::_on_category_changed)); general_settings_inspector->get_inspector()->set_use_filter(true); general_settings_inspector->get_inspector()->set_mark_unsaved(false); general_settings_inspector->get_inspector()->connect("property_selected", callable_mp(this, &ProjectSettingsEditor::_setting_selected)); general_settings_inspector->get_inspector()->connect("property_edited", callable_mp(this, &ProjectSettingsEditor::_setting_edited)); + general_settings_inspector->get_inspector()->connect("property_deleted", callable_mp(this, &ProjectSettingsEditor::_on_editor_override_deleted)); general_settings_inspector->get_inspector()->connect("restart_requested", callable_mp(this, &ProjectSettingsEditor::_editor_restart_request)); general_editor->add_child(general_settings_inspector); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index b5ae6c50357..35d50c41aed 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -90,6 +90,10 @@ class ProjectSettingsEditor : public AcceptDialog { EditorData *data = nullptr; bool settings_changed = false; + bool pending_override_notify = false; + + void _on_category_changed(const String &p_new_category); + void _on_editor_override_deleted(const String &p_setting); void _advanced_toggled(bool p_button_pressed); void _update_advanced(bool p_is_advanced); @@ -131,7 +135,10 @@ protected: public: static ProjectSettingsEditor *get_singleton() { return singleton; } + void popup_project_settings(bool p_clear_filter = false); + void popup_for_override(const String &p_override); + void set_plugins_page(); void set_general_page(const String &p_category); void update_plugins(); diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index 3c7bc41938e..484ab1203ec 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -2733,7 +2733,7 @@ void EditorThemeManager::_generate_text_editor_defaults(ThemeConfiguration &p_co } void EditorThemeManager::_populate_text_editor_styles(const Ref &p_theme, ThemeConfiguration &p_config) { - String text_editor_color_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); + String text_editor_color_theme = EDITOR_GET("text_editor/theme/color_theme"); if (text_editor_color_theme == "Default") { _generate_text_editor_defaults(p_config); } else if (text_editor_color_theme == "Godot 2") { diff --git a/main/main.cpp b/main/main.cpp index c47984641ab..22b3ce4589c 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -4433,13 +4433,12 @@ int Main::start() { #ifdef TOOLS_ENABLED if (editor) { - bool editor_embed_subwindows = EditorSettings::get_singleton()->get_setting( - "interface/editor/single_window_mode"); + bool editor_embed_subwindows = EDITOR_GET("interface/editor/single_window_mode"); if (editor_embed_subwindows) { sml->get_root()->set_embedding_subwindows(true); } - restore_editor_window_layout = EditorSettings::get_singleton()->get_setting("interface/editor/editor_screen").operator int() == EditorSettings::InitialScreen::INITIAL_SCREEN_AUTO; + restore_editor_window_layout = EDITOR_GET("interface/editor/editor_screen").operator int() == EditorSettings::InitialScreen::INITIAL_SCREEN_AUTO; } #endif diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index 38c5b874c81..49dca319808 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -61,7 +61,7 @@ static void _editor_init() { String blender_path = EDITOR_GET("filesystem/import/blender/blender_path"); if (blender_path.is_empty() && EditorSettings::get_singleton()->has_setting("filesystem/import/blender/blender3_path")) { - blender_path = EditorSettings::get_singleton()->get("filesystem/import/blender/blender3_path"); + blender_path = EDITOR_GET("filesystem/import/blender/blender3_path"); if (!blender_path.is_empty()) { #if defined(MACOS_ENABLED) diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp index ae6eecf0493..757d148e7b5 100644 --- a/platform/linuxbsd/export/export_plugin.cpp +++ b/platform/linuxbsd/export/export_plugin.cpp @@ -526,7 +526,7 @@ Error EditorExportPlatformLinuxBSD::run(const Ref &p_preset, } const bool use_remote = p_debug_flags.has_flag(DEBUG_FLAG_REMOTE_DEBUG) || p_debug_flags.has_flag(DEBUG_FLAG_DUMB_CLIENT); - int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port"); + int dbg_port = EDITOR_GET("network/debug/remote_port"); print_line("Creating temporary directory..."); ep.step(TTR("Creating temporary directory..."), 2); diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index 06b9e7a440d..5d2a6b49d4a 100644 --- a/platform/macos/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -2636,7 +2636,7 @@ Error EditorExportPlatformMacOS::run(const Ref &p_preset, in } const bool use_remote = p_debug_flags.has_flag(DEBUG_FLAG_REMOTE_DEBUG) || p_debug_flags.has_flag(DEBUG_FLAG_DUMB_CLIENT); - int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port"); + int dbg_port = EDITOR_GET("network/debug/remote_port"); print_line("Creating temporary directory..."); ep.step(TTR("Creating temporary directory..."), 2); diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index 6b311850e1d..356f61d60b6 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -1104,7 +1104,7 @@ Error EditorExportPlatformWindows::run(const Ref &p_preset, } const bool use_remote = p_debug_flags.has_flag(DEBUG_FLAG_REMOTE_DEBUG) || p_debug_flags.has_flag(DEBUG_FLAG_DUMB_CLIENT); - int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port"); + int dbg_port = EDITOR_GET("network/debug/remote_port"); print_line("Creating temporary directory..."); ep.step(TTR("Creating temporary directory..."), 2);