summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--editor/editor_node.cpp65
-rw-r--r--editor/project_manager.cpp273
-rw-r--r--editor/project_manager.h16
-rw-r--r--editor/project_manager/quick_settings_dialog.cpp306
-rw-r--r--editor/project_manager/quick_settings_dialog.h87
5 files changed, 574 insertions, 173 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 579b526b5e..3691172c18 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -498,40 +498,43 @@ void EditorNode::_update_theme(bool p_skip_creation) {
update_preview_themes(CanvasItemEditor::THEME_PREVIEW_EDITOR);
}
- gui_base->add_theme_style_override("panel", theme->get_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
- main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, theme->get_constant(SNAME("window_border_margin"), EditorStringName(Editor)));
- main_vbox->add_theme_constant_override("separation", theme->get_constant(SNAME("top_bar_separation"), EditorStringName(Editor)));
-
- scene_root_parent->add_theme_style_override("panel", theme->get_stylebox(SNAME("Content"), EditorStringName(EditorStyles)));
- bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
- main_menu->add_theme_style_override("hover", theme->get_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles)));
- distraction_free->set_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons)));
- bottom_panel_raise->set_icon(theme->get_icon(SNAME("ExpandBottomDock"), EditorStringName(EditorIcons)));
-
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), theme->get_icon(SNAME("HelpSearch"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_DOCS), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_QA), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_REPORT_A_BUG), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), theme->get_icon(SNAME("ActionCopy"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SUGGEST_A_FEATURE), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SEND_DOCS_FEEDBACK), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_COMMUNITY), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), theme->get_icon(SNAME("Godot"), EditorStringName(EditorIcons)));
- help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), theme->get_icon(SNAME("Heart"), EditorStringName(EditorIcons)));
+ // Update styles.
+ {
+ gui_base->add_theme_style_override("panel", theme->get_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
+ main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, theme->get_constant(SNAME("window_border_margin"), EditorStringName(Editor)));
+ main_vbox->add_theme_constant_override("separation", theme->get_constant(SNAME("top_bar_separation"), EditorStringName(Editor)));
- if (EditorDebuggerNode::get_singleton()->is_visible()) {
- bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles)));
- }
+ scene_root_parent->add_theme_style_override("panel", theme->get_stylebox(SNAME("Content"), EditorStringName(EditorStyles)));
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
+ main_menu->add_theme_style_override("hover", theme->get_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles)));
+ distraction_free->set_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons)));
+ bottom_panel_raise->set_icon(theme->get_icon(SNAME("ExpandBottomDock"), EditorStringName(EditorIcons)));
+
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), theme->get_icon(SNAME("HelpSearch"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_DOCS), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_QA), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_REPORT_A_BUG), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), theme->get_icon(SNAME("ActionCopy"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SUGGEST_A_FEATURE), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SEND_DOCS_FEEDBACK), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_COMMUNITY), theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), theme->get_icon(SNAME("Godot"), EditorStringName(EditorIcons)));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), theme->get_icon(SNAME("Heart"), EditorStringName(EditorIcons)));
+
+ if (EditorDebuggerNode::get_singleton()->is_visible()) {
+ bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles)));
+ }
- for (int i = 0; i < main_editor_buttons.size(); i++) {
- Button *tb = main_editor_buttons[i];
- EditorPlugin *p_editor = editor_table[i];
- Ref<Texture2D> icon = p_editor->get_icon();
+ for (int i = 0; i < main_editor_buttons.size(); i++) {
+ Button *tb = main_editor_buttons[i];
+ EditorPlugin *p_editor = editor_table[i];
+ Ref<Texture2D> icon = p_editor->get_icon();
- if (icon.is_valid()) {
- tb->set_icon(icon);
- } else if (theme->has_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
- tb->set_icon(theme->get_icon(p_editor->get_name(), EditorStringName(EditorIcons)));
+ if (icon.is_valid()) {
+ tb->set_icon(icon);
+ } else if (theme->has_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
+ tb->set_icon(theme->get_icon(p_editor->get_name(), EditorStringName(EditorIcons)));
+ }
}
}
}
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 4c01df3997..c9234cc071 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -38,7 +38,6 @@
#include "core/io/stream_peer_tls.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
-#include "core/string/translation.h"
#include "core/version.h"
#include "editor/editor_about.h"
#include "editor/editor_settings.h"
@@ -48,6 +47,7 @@
#include "editor/project_manager/project_dialog.h"
#include "editor/project_manager/project_list.h"
#include "editor/project_manager/project_tag.h"
+#include "editor/project_manager/quick_settings_dialog.h"
#include "editor/themes/editor_icons.h"
#include "editor/themes/editor_scale.h"
#include "editor/themes/editor_theme_manager.h"
@@ -63,6 +63,7 @@
#include "scene/gui/separator.h"
#include "scene/gui/texture_rect.h"
#include "scene/main/window.h"
+#include "scene/theme/theme_db.h"
#include "servers/display_server.h"
#include "servers/navigation_server_3d.h"
#include "servers/physics_server_2d.h"
@@ -77,64 +78,9 @@ void ProjectManager::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
Engine::get_singleton()->set_editor_hint(false);
- } break;
-
- case NOTIFICATION_THEME_CHANGED: {
- const int top_bar_separation = get_theme_constant(SNAME("top_bar_separation"), EditorStringName(Editor));
- root_container->add_theme_constant_override("margin_left", top_bar_separation);
- root_container->add_theme_constant_override("margin_top", top_bar_separation);
- root_container->add_theme_constant_override("margin_bottom", top_bar_separation);
- root_container->add_theme_constant_override("margin_right", top_bar_separation);
- main_vbox->add_theme_constant_override("separation", top_bar_separation);
-
- background_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
- main_view_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer")));
-
- title_bar_logo->set_icon(get_editor_theme_icon(SNAME("TitleBarLogo")));
-
- _set_main_view_icon(MAIN_VIEW_PROJECTS, get_editor_theme_icon(SNAME("ProjectList")));
- _set_main_view_icon(MAIN_VIEW_ASSETLIB, get_editor_theme_icon(SNAME("AssetLib")));
-
- // Project list.
- {
- loading_label->add_theme_font_override("font", get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
- search_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("search_panel"), SNAME("ProjectManager")));
-
- // Top bar.
- search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- language_btn->set_icon(get_editor_theme_icon(SNAME("Environment")));
-
- // Sidebar.
- create_btn->set_icon(get_editor_theme_icon(SNAME("Add")));
- import_btn->set_icon(get_editor_theme_icon(SNAME("Load")));
- scan_btn->set_icon(get_editor_theme_icon(SNAME("Search")));
- open_btn->set_icon(get_editor_theme_icon(SNAME("Edit")));
- run_btn->set_icon(get_editor_theme_icon(SNAME("Play")));
- rename_btn->set_icon(get_editor_theme_icon(SNAME("Rename")));
- manage_tags_btn->set_icon(get_editor_theme_icon("Script"));
- erase_btn->set_icon(get_editor_theme_icon(SNAME("Remove")));
- erase_missing_btn->set_icon(get_editor_theme_icon(SNAME("Clear")));
- create_tag_btn->set_icon(get_editor_theme_icon("Add"));
-
- tag_error->add_theme_color_override("font_color", get_theme_color("error_color", EditorStringName(Editor)));
- tag_edit_error->add_theme_color_override("font_color", get_theme_color("error_color", EditorStringName(Editor)));
-
- create_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- import_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- scan_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- open_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- run_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- rename_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- manage_tags_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- erase_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- erase_missing_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
- }
- // Asset library popup.
- if (asset_library) {
- // Removes extra border margins.
- asset_library->add_theme_style_override("panel", memnew(StyleBoxEmpty));
- }
+ // Theme has already been created in the constructor, so we can skip that step.
+ _update_theme(true);
} break;
case NOTIFICATION_READY: {
@@ -161,6 +107,12 @@ void ProjectManager::_notification(int p_what) {
case NOTIFICATION_WM_ABOUT: {
_show_about();
} break;
+
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ if (EditorThemeManager::is_generated_theme_outdated()) {
+ _update_theme();
+ }
+ } break;
}
}
@@ -221,7 +173,94 @@ void ProjectManager::_update_size_limits() {
// We try to set it to half the screen resolution, but no smaller than the minimum window size.
Size2 half_screen_rect = (screen_rect.size * EDSCALE) / 2;
Size2 maximum_popup_size = MAX(half_screen_rect, minimum_size);
- language_btn->get_popup()->set_max_size(maximum_popup_size);
+ quick_settings_dialog->update_size_limits(maximum_popup_size);
+ }
+}
+
+void ProjectManager::_update_theme(bool p_skip_creation) {
+ if (!p_skip_creation) {
+ theme = EditorThemeManager::generate_theme(theme);
+ DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor)));
+ }
+
+ List<Ref<Theme>> editor_themes;
+ editor_themes.push_back(theme);
+ editor_themes.push_back(ThemeDB::get_singleton()->get_default_theme());
+
+ ThemeContext *node_tc = ThemeDB::get_singleton()->get_theme_context(this);
+ if (node_tc) {
+ node_tc->set_themes(editor_themes);
+ } else {
+ ThemeDB::get_singleton()->create_theme_context(this, editor_themes);
+ }
+
+ Window *owner_window = get_window();
+ if (owner_window) {
+ ThemeContext *window_tc = ThemeDB::get_singleton()->get_theme_context(owner_window);
+ if (window_tc) {
+ window_tc->set_themes(editor_themes);
+ } else {
+ ThemeDB::get_singleton()->create_theme_context(owner_window, editor_themes);
+ }
+ }
+
+ // Update styles.
+ {
+ const int top_bar_separation = get_theme_constant(SNAME("top_bar_separation"), EditorStringName(Editor));
+ root_container->add_theme_constant_override("margin_left", top_bar_separation);
+ root_container->add_theme_constant_override("margin_top", top_bar_separation);
+ root_container->add_theme_constant_override("margin_bottom", top_bar_separation);
+ root_container->add_theme_constant_override("margin_right", top_bar_separation);
+ main_vbox->add_theme_constant_override("separation", top_bar_separation);
+
+ background_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
+ main_view_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer")));
+
+ title_bar_logo->set_icon(get_editor_theme_icon(SNAME("TitleBarLogo")));
+
+ _set_main_view_icon(MAIN_VIEW_PROJECTS, get_editor_theme_icon(SNAME("ProjectList")));
+ _set_main_view_icon(MAIN_VIEW_ASSETLIB, get_editor_theme_icon(SNAME("AssetLib")));
+
+ // Project list.
+ {
+ loading_label->add_theme_font_override("font", get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
+ search_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("search_panel"), SNAME("ProjectManager")));
+
+ // Top bar.
+ search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
+ quick_settings_button->set_icon(get_editor_theme_icon(SNAME("Tools")));
+
+ // Sidebar.
+ create_btn->set_icon(get_editor_theme_icon(SNAME("Add")));
+ import_btn->set_icon(get_editor_theme_icon(SNAME("Load")));
+ scan_btn->set_icon(get_editor_theme_icon(SNAME("Search")));
+ open_btn->set_icon(get_editor_theme_icon(SNAME("Edit")));
+ run_btn->set_icon(get_editor_theme_icon(SNAME("Play")));
+ rename_btn->set_icon(get_editor_theme_icon(SNAME("Rename")));
+ manage_tags_btn->set_icon(get_editor_theme_icon("Script"));
+ erase_btn->set_icon(get_editor_theme_icon(SNAME("Remove")));
+ erase_missing_btn->set_icon(get_editor_theme_icon(SNAME("Clear")));
+ create_tag_btn->set_icon(get_editor_theme_icon("Add"));
+
+ tag_error->add_theme_color_override("font_color", get_theme_color("error_color", EditorStringName(Editor)));
+ tag_edit_error->add_theme_color_override("font_color", get_theme_color("error_color", EditorStringName(Editor)));
+
+ create_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ import_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ scan_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ open_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ run_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ rename_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ manage_tags_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ erase_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ erase_missing_btn->add_theme_constant_override("h_separation", get_theme_constant(SNAME("sidebar_button_icon_separation"), SNAME("ProjectManager")));
+ }
+
+ // Asset library popup.
+ if (asset_library) {
+ // Removes extra border margins.
+ asset_library->add_theme_style_override("panel", memnew(StyleBoxEmpty));
+ }
}
}
@@ -350,16 +389,24 @@ void ProjectManager::_open_asset_library_confirmed() {
_select_main_view(MAIN_VIEW_ASSETLIB);
}
-// Quick settings.
+void ProjectManager::_dim_window() {
+ // This method must be called before calling `get_tree()->quit()`.
+ // Otherwise, its effect won't be visible
-void ProjectManager::_language_selected(int p_id) {
- String lang = language_btn->get_item_metadata(p_id);
- EditorSettings::get_singleton()->set("interface/editor/editor_language", lang);
+ // Dim the project manager window while it's quitting to make it clearer that it's busy.
+ // No transition is applied, as the effect needs to be visible immediately
+ float c = 0.5f;
+ Color dim_color = Color(c, c, c);
+ set_modulate(dim_color);
+}
- restart_required_dialog->popup_centered();
+// Quick settings.
+
+void ProjectManager::_show_quick_settings() {
+ quick_settings_dialog->popup_centered(Size2(600, 200) * EDSCALE);
}
-void ProjectManager::_restart_confirm() {
+void ProjectManager::_restart_confirmed() {
List<String> args = OS::get_singleton()->get_cmdline_args();
Error err = OS::get_singleton()->create_instance(args);
ERR_FAIL_COND(err);
@@ -368,17 +415,6 @@ void ProjectManager::_restart_confirm() {
get_tree()->quit();
}
-void ProjectManager::_dim_window() {
- // This method must be called before calling `get_tree()->quit()`.
- // Otherwise, its effect won't be visible
-
- // Dim the project manager window while it's quitting to make it clearer that it's busy.
- // No transition is applied, as the effect needs to be visible immediately
- float c = 0.5f;
- Color dim_color = Color(c, c, c);
- set_modulate(dim_color);
-}
-
// Footer.
void ProjectManager::_version_button_pressed() {
@@ -1048,10 +1084,9 @@ ProjectManager::ProjectManager() {
Window::set_root_layout_direction(pm_root_dir);
EditorThemeManager::initialize();
- Ref<Theme> theme = EditorThemeManager::generate_theme();
+ theme = EditorThemeManager::generate_theme();
DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor)));
- set_theme(theme);
set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
_build_icon_type_cache(theme);
@@ -1075,67 +1110,36 @@ ProjectManager::ProjectManager() {
title_bar = memnew(HBoxContainer);
main_vbox->add_child(title_bar);
+ HBoxContainer *left_hbox = memnew(HBoxContainer);
+ left_hbox->set_alignment(BoxContainer::ALIGNMENT_BEGIN);
+ left_hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ left_hbox->set_stretch_ratio(1.0);
+ title_bar->add_child(left_hbox);
+
title_bar_logo = memnew(Button);
title_bar_logo->set_flat(true);
- title_bar->add_child(title_bar_logo);
+ left_hbox->add_child(title_bar_logo);
title_bar_logo->connect("pressed", callable_mp(this, &ProjectManager::_show_about));
- HBoxContainer *left_spacer = memnew(HBoxContainer);
- left_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS);
- left_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- title_bar->add_child(left_spacer);
-
main_view_toggles = memnew(HBoxContainer);
+ main_view_toggles->set_alignment(BoxContainer::ALIGNMENT_CENTER);
+ main_view_toggles->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ main_view_toggles->set_stretch_ratio(2.0);
title_bar->add_child(main_view_toggles);
main_view_toggles_group.instantiate();
- Control *right_spacer = memnew(Control);
- right_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS);
- right_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- title_bar->add_child(right_spacer);
-
- quick_settings_hbox = memnew(HBoxContainer);
- title_bar->add_child(quick_settings_hbox);
- }
-
- // Quick settings.
- {
- language_btn = memnew(OptionButton);
- language_btn->set_focus_mode(Control::FOCUS_NONE);
- language_btn->set_fit_to_longest_item(false);
- language_btn->set_flat(true);
- language_btn->connect("item_selected", callable_mp(this, &ProjectManager::_language_selected));
-#ifdef ANDROID_ENABLED
- // The language selection dropdown doesn't work on Android (as the setting isn't saved), see GH-60353.
- // Also, the dropdown it spawns is very tall and can't be scrolled without a hardware mouse.
- language_btn->hide();
-#endif
-
- Vector<String> editor_languages;
- List<PropertyInfo> editor_settings_properties;
- EditorSettings::get_singleton()->get_property_list(&editor_settings_properties);
- for (const PropertyInfo &pi : editor_settings_properties) {
- if (pi.name == "interface/editor/editor_language") {
- editor_languages = pi.hint_string.split(",");
- break;
- }
- }
-
- String current_lang = EDITOR_GET("interface/editor/editor_language");
- language_btn->set_text(current_lang);
-
- for (int i = 0; i < editor_languages.size(); i++) {
- const String &lang = editor_languages[i];
- String lang_name = TranslationServer::get_singleton()->get_locale_name(lang);
- language_btn->add_item(vformat("[%s] %s", lang, lang_name), i);
- language_btn->set_item_metadata(i, lang);
- if (current_lang == lang) {
- language_btn->select(i);
- }
- }
-
- quick_settings_hbox->add_child(language_btn);
+ HBoxContainer *right_hbox = memnew(HBoxContainer);
+ right_hbox->set_alignment(BoxContainer::ALIGNMENT_END);
+ right_hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ right_hbox->set_stretch_ratio(1.0);
+ title_bar->add_child(right_hbox);
+
+ quick_settings_button = memnew(Button);
+ quick_settings_button->set_flat(true);
+ quick_settings_button->set_text(TTR("Settings"));
+ right_hbox->add_child(quick_settings_button);
+ quick_settings_button->connect("pressed", callable_mp(this, &ProjectManager::_show_quick_settings));
}
main_view_container = memnew(PanelContainer);
@@ -1305,12 +1309,9 @@ ProjectManager::ProjectManager() {
// Dialogs.
{
- restart_required_dialog = memnew(ConfirmationDialog);
- restart_required_dialog->set_ok_button_text(TTR("Restart Now"));
- restart_required_dialog->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_restart_confirm));
- restart_required_dialog->set_cancel_button_text(TTR("Continue"));
- restart_required_dialog->set_text(TTR("Settings changed!\nThe project manager must be restarted for changes to take effect."));
- add_child(restart_required_dialog);
+ quick_settings_dialog = memnew(QuickSettingsDialog);
+ add_child(quick_settings_dialog);
+ quick_settings_dialog->connect("restart_required", callable_mp(this, &ProjectManager::_restart_confirmed));
scan_dir = memnew(EditorFileDialog);
scan_dir->set_previews_enabled(false);
diff --git a/editor/project_manager.h b/editor/project_manager.h
index f3f443968c..16c7bd9dac 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -46,6 +46,7 @@ class OptionButton;
class PanelContainer;
class ProjectDialog;
class ProjectList;
+class QuickSettingsDialog;
class RichTextLabel;
class TabContainer;
class VBoxContainer;
@@ -66,7 +67,10 @@ class ProjectManager : public Control {
// Main layout.
+ Ref<Theme> theme;
+
void _update_size_limits();
+ void _update_theme(bool p_skip_creation = false);
MarginContainer *root_container = nullptr;
Panel *background_panel = nullptr;
@@ -75,7 +79,7 @@ class ProjectManager : public Control {
HBoxContainer *title_bar = nullptr;
Button *title_bar_logo = nullptr;
HBoxContainer *main_view_toggles = nullptr;
- HBoxContainer *quick_settings_hbox = nullptr;
+ Button *quick_settings_button = nullptr;
enum MainViewTab {
MAIN_VIEW_PROJECTS,
@@ -105,14 +109,14 @@ class ProjectManager : public Control {
void _suggest_asset_library();
void _open_asset_library_confirmed();
+ void _dim_window();
+
// Quick settings.
- OptionButton *language_btn = nullptr;
- ConfirmationDialog *restart_required_dialog = nullptr;
+ QuickSettingsDialog *quick_settings_dialog = nullptr;
- void _language_selected(int p_id);
- void _restart_confirm();
- void _dim_window();
+ void _show_quick_settings();
+ void _restart_confirmed();
// Footer.
diff --git a/editor/project_manager/quick_settings_dialog.cpp b/editor/project_manager/quick_settings_dialog.cpp
new file mode 100644
index 0000000000..255b15f7f6
--- /dev/null
+++ b/editor/project_manager/quick_settings_dialog.cpp
@@ -0,0 +1,306 @@
+/**************************************************************************/
+/* quick_settings_dialog.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "quick_settings_dialog.h"
+
+#include "core/config/project_settings.h"
+#include "core/string/translation.h"
+#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
+#include "editor/themes/editor_scale.h"
+#include "scene/gui/box_container.h"
+#include "scene/gui/button.h"
+#include "scene/gui/label.h"
+#include "scene/gui/margin_container.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/panel_container.h"
+
+void QuickSettingsDialog::_fetch_setting_values() {
+ editor_languages.clear();
+ editor_themes.clear();
+ editor_scales.clear();
+ editor_network_modes.clear();
+
+ {
+ List<PropertyInfo> editor_settings_properties;
+ EditorSettings::get_singleton()->get_property_list(&editor_settings_properties);
+
+ for (const PropertyInfo &pi : editor_settings_properties) {
+ if (pi.name == "interface/editor/editor_language") {
+ editor_languages = pi.hint_string.split(",");
+ } else if (pi.name == "interface/theme/preset") {
+ editor_themes = pi.hint_string.split(",");
+ } else if (pi.name == "interface/editor/display_scale") {
+ editor_scales = pi.hint_string.split(",");
+ } else if (pi.name == "network/connection/network_mode") {
+ editor_network_modes = pi.hint_string.split(",");
+ }
+ }
+ }
+}
+
+void QuickSettingsDialog::_update_current_values() {
+ // Language options.
+ {
+ const String current_lang = EDITOR_GET("interface/editor/editor_language");
+
+ for (int i = 0; i < editor_languages.size(); i++) {
+ const String &lang_value = editor_languages[i];
+ if (current_lang == lang_value) {
+ language_option_button->set_text(current_lang);
+ language_option_button->select(i);
+ }
+ }
+ }
+
+ // Theme options.
+ {
+ const String current_theme = EDITOR_GET("interface/theme/preset");
+
+ for (int i = 0; i < editor_themes.size(); i++) {
+ const String &theme_value = editor_themes[i];
+ if (current_theme == theme_value) {
+ theme_option_button->set_text(current_theme);
+ theme_option_button->select(i);
+
+ custom_theme_label->set_visible(current_theme == "Custom");
+ }
+ }
+ }
+
+ // Scale options.
+ {
+ const int current_scale = EDITOR_GET("interface/editor/display_scale");
+
+ for (int i = 0; i < editor_scales.size(); i++) {
+ const String &scale_value = editor_scales[i];
+ if (current_scale == i) {
+ scale_option_button->set_text(scale_value);
+ scale_option_button->select(i);
+ }
+ }
+ }
+
+ // Network mode options.
+ {
+ const int current_network_mode = EDITOR_GET("network/connection/network_mode");
+
+ for (int i = 0; i < editor_network_modes.size(); i++) {
+ const String &network_mode_value = editor_network_modes[i];
+ if (current_network_mode == i) {
+ network_mode_option_button->set_text(network_mode_value);
+ network_mode_option_button->select(i);
+ }
+ }
+ }
+}
+
+void QuickSettingsDialog::_add_setting_control(const String &p_text, Control *p_control) {
+ HBoxContainer *container = memnew(HBoxContainer);
+ settings_list->add_child(container);
+
+ Label *label = memnew(Label(p_text));
+ label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ container->add_child(label);
+
+ p_control->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ p_control->set_stretch_ratio(2.0);
+ container->add_child(p_control);
+}
+
+void QuickSettingsDialog::_language_selected(int p_id) {
+ const String selected_language = language_option_button->get_item_metadata(p_id);
+ _set_setting_value("interface/editor/editor_language", selected_language, true);
+}
+
+void QuickSettingsDialog::_theme_selected(int p_id) {
+ const String selected_theme = theme_option_button->get_item_text(p_id);
+ _set_setting_value("interface/theme/preset", selected_theme);
+
+ custom_theme_label->set_visible(selected_theme == "Custom");
+}
+
+void QuickSettingsDialog::_scale_selected(int p_id) {
+ _set_setting_value("interface/editor/display_scale", p_id, true);
+}
+
+void QuickSettingsDialog::_network_mode_selected(int p_id) {
+ _set_setting_value("network/connection/network_mode", p_id);
+}
+
+void QuickSettingsDialog::_set_setting_value(const String &p_setting, const Variant &p_value, bool p_restart_required) {
+ EditorSettings::get_singleton()->set(p_setting, p_value);
+ EditorSettings::get_singleton()->notify_changes();
+ EditorSettings::get_singleton()->save();
+
+ if (p_restart_required) {
+ restart_required_label->show();
+
+ if (!restart_required_button) {
+ restart_required_button = add_button(TTR("Restart Now"), !GLOBAL_GET("gui/common/swap_cancel_ok"));
+ restart_required_button->connect("pressed", callable_mp(this, &QuickSettingsDialog::_request_restart));
+ }
+ }
+}
+
+void QuickSettingsDialog::_request_restart() {
+ emit_signal("restart_required");
+}
+
+void QuickSettingsDialog::update_size_limits(const Size2 &p_max_popup_size) {
+ language_option_button->get_popup()->set_max_size(p_max_popup_size);
+}
+
+void QuickSettingsDialog::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED: {
+ settings_list_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
+
+ restart_required_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
+ custom_theme_label->add_theme_color_override("font_color", get_theme_color(SNAME("font_placeholder_color"), EditorStringName(Editor)));
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (is_visible()) {
+ _update_current_values();
+ }
+ } break;
+ }
+}
+
+void QuickSettingsDialog::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("restart_required"));
+}
+
+QuickSettingsDialog::QuickSettingsDialog() {
+ set_title(TTR("Quick Settings"));
+ set_ok_button_text(TTR("Close"));
+
+ VBoxContainer *main_vbox = memnew(VBoxContainer);
+ add_child(main_vbox);
+ main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
+
+ // Settings grid.
+ {
+ _fetch_setting_values();
+
+ settings_list_panel = memnew(PanelContainer);
+ main_vbox->add_child(settings_list_panel);
+
+ settings_list = memnew(VBoxContainer);
+ settings_list_panel->add_child(settings_list);
+
+ // Language options.
+ {
+ language_option_button = memnew(OptionButton);
+ language_option_button->set_fit_to_longest_item(false);
+ language_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_language_selected));
+
+ for (int i = 0; i < editor_languages.size(); i++) {
+ const String &lang_value = editor_languages[i];
+ String lang_name = TranslationServer::get_singleton()->get_locale_name(lang_value);
+ language_option_button->add_item(vformat("[%s] %s", lang_value, lang_name), i);
+ language_option_button->set_item_metadata(i, lang_value);
+ }
+
+ _add_setting_control(TTR("Language"), language_option_button);
+ }
+
+ // Theme options.
+ {
+ theme_option_button = memnew(OptionButton);
+ theme_option_button->set_fit_to_longest_item(false);
+ theme_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_theme_selected));
+
+ for (int i = 0; i < editor_themes.size(); i++) {
+ const String &theme_value = editor_themes[i];
+ theme_option_button->add_item(theme_value, i);
+ }
+
+ _add_setting_control(TTR("Interface Theme"), theme_option_button);
+
+ custom_theme_label = memnew(Label(TTR("Custom preset can be further configured in the editor.")));
+ custom_theme_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
+ custom_theme_label->set_custom_minimum_size(Size2(220, 0) * EDSCALE);
+ custom_theme_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD);
+ custom_theme_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ custom_theme_label->set_stretch_ratio(2.0);
+ custom_theme_label->hide();
+ settings_list->add_child(custom_theme_label);
+ }
+
+ // Scale options.
+ {
+ scale_option_button = memnew(OptionButton);
+ scale_option_button->set_fit_to_longest_item(false);
+ scale_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_scale_selected));
+
+ for (int i = 0; i < editor_scales.size(); i++) {
+ const String &scale_value = editor_scales[i];
+ scale_option_button->add_item(scale_value, i);
+ }
+
+ _add_setting_control(TTR("Display Scale"), scale_option_button);
+ }
+
+ // Network mode options.
+ {
+ network_mode_option_button = memnew(OptionButton);
+ network_mode_option_button->set_fit_to_longest_item(false);
+ network_mode_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_network_mode_selected));
+
+ for (int i = 0; i < editor_network_modes.size(); i++) {
+ const String &network_mode_value = editor_network_modes[i];
+ network_mode_option_button->add_item(network_mode_value, i);
+ }
+
+ _add_setting_control(TTR("Network Mode"), network_mode_option_button);
+ }
+
+ _update_current_values();
+
+#ifdef ANDROID_ENABLED
+ // The language selection dropdown doesn't work on Android (as the setting isn't saved), see GH-60353.
+ // Also, the dropdown it spawns is very tall and can't be scrolled without a hardware mouse.
+ language_option_button->hide();
+ scale_option_button->hide();
+#endif
+ }
+
+ // Restart required panel.
+ {
+ restart_required_label = memnew(Label(TTR("Settings changed! The project manager must be restarted for changes to take effect.")));
+ restart_required_label->set_custom_minimum_size(Size2(560, 0) * EDSCALE);
+ restart_required_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD);
+ restart_required_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ restart_required_label->hide();
+ main_vbox->add_child(restart_required_label);
+ }
+}
diff --git a/editor/project_manager/quick_settings_dialog.h b/editor/project_manager/quick_settings_dialog.h
new file mode 100644
index 0000000000..c4c4e601c9
--- /dev/null
+++ b/editor/project_manager/quick_settings_dialog.h
@@ -0,0 +1,87 @@
+/**************************************************************************/
+/* quick_settings_dialog.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef QUICK_SETTINGS_DIALOG_H
+#define QUICK_SETTINGS_DIALOG_H
+
+#include "scene/gui/dialogs.h"
+
+class Button;
+class Label;
+class MarginContainer;
+class OptionButton;
+class PanelContainer;
+class VBoxContainer;
+
+class QuickSettingsDialog : public AcceptDialog {
+ GDCLASS(QuickSettingsDialog, AcceptDialog);
+
+ Vector<String> editor_languages;
+ Vector<String> editor_themes;
+ Vector<String> editor_scales;
+ Vector<String> editor_network_modes;
+
+ void _fetch_setting_values();
+ void _update_current_values();
+
+ PanelContainer *settings_list_panel = nullptr;
+ VBoxContainer *settings_list = nullptr;
+
+ void _add_setting_control(const String &p_text, Control *p_control);
+
+ OptionButton *language_option_button = nullptr;
+ OptionButton *theme_option_button = nullptr;
+ OptionButton *scale_option_button = nullptr;
+ OptionButton *network_mode_option_button = nullptr;
+
+ Label *custom_theme_label = nullptr;
+
+ void _language_selected(int p_id);
+ void _theme_selected(int p_id);
+ void _scale_selected(int p_id);
+ void _network_mode_selected(int p_id);
+ void _set_setting_value(const String &p_setting, const Variant &p_value, bool p_restart_required = false);
+
+ Label *restart_required_label = nullptr;
+ Button *restart_required_button = nullptr;
+
+ void _request_restart();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void update_size_limits(const Size2 &p_max_popup_size);
+
+ QuickSettingsDialog();
+};
+
+#endif // QUICK_SETTINGS_DIALOG_H