From 512182f1475fe54833056e534320832a0bb2156a Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Wed, 6 Sep 2023 16:11:05 +0200 Subject: [PATCH] Add theme contexts to various parts of the editor This change defines additional theme contexts for editor branches to prevent theme leaking between the default theme, the project theme, and the editor theme. - Both editor window and EditorNode define an editor-specific context with the editor theme and the default theme. - The 2D viewport defines a project-specific context with the project theme and the default theme. - Theme editor preview tabs define the default-only context with the default theme. Additionally, the default theme context now only includes the project theme for running projects (both export and debug). This prevents the project theme from leaking into the editor. This commit also does a little clean up on the theming aspects of the EditorNode. --- editor/editor_node.cpp | 279 ++++++++++++------------ editor/editor_node.h | 3 +- editor/editor_resource_preview.cpp | 4 +- editor/plugins/script_editor_plugin.cpp | 10 +- editor/plugins/theme_editor_plugin.cpp | 2 +- editor/plugins/theme_editor_preview.cpp | 13 +- editor/plugins/theme_editor_preview.h | 1 + scene/theme/theme_db.cpp | 18 ++ scene/theme/theme_db.h | 1 + 9 files changed, 181 insertions(+), 150 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 1f59b74a95b..6f14a4568a2 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -63,6 +63,7 @@ #include "scene/resources/image_texture.h" #include "scene/resources/packed_scene.h" #include "scene/resources/portable_compressed_texture.h" +#include "scene/theme/theme_db.h" #include "servers/display_server.h" #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" @@ -454,6 +455,85 @@ void EditorNode::_select_default_main_screen_plugin() { editor_select(-1); } +void EditorNode::_update_theme(bool p_skip_creation) { + if (!p_skip_creation) { + theme = create_custom_theme(theme); + DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor))); + } + + List> 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 *window = get_window(); + if (window) { + ThemeContext *window_tc = ThemeDB::get_singleton()->get_theme_context(window); + if (window_tc) { + window_tc->set_themes(editor_themes); + } else { + ThemeDB::get_singleton()->create_theme_context(window, editor_themes); + } + } + + 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))); + prev_scene->set_icon(theme->get_icon(SNAME("PrevScene"), EditorStringName(EditorIcons))); + distraction_free->set_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons))); + bottom_panel_raise->set_icon(theme->get_icon(SNAME("ExpandBottomDock"), EditorStringName(EditorIcons))); + + if (gui_base->is_layout_rtl()) { + dock_tab_move_left->set_icon(theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons))); + dock_tab_move_right->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); + } else { + dock_tab_move_left->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); + dock_tab_move_right->set_icon(theme->get_icon(SNAME("Forward"), 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))); + + for (int i = 0; i < main_editor_buttons.size(); i++) { + main_editor_buttons.write[i]->add_theme_font_override("font", theme->get_font(SNAME("main_button_font"), EditorStringName(EditorFonts))); + main_editor_buttons.write[i]->add_theme_font_size_override("font_size", theme->get_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts))); + } + + 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 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))); + } + } +} + void EditorNode::_notification(int p_what) { switch (p_what) { case NOTIFICATION_PROCESS: { @@ -487,7 +567,7 @@ void EditorNode::_notification(int p_what) { // Update the icon itself only when the spinner is visible. if (EDITOR_GET("interface/editor/show_update_spinner")) { - update_spinner->set_icon(gui_base->get_editor_theme_icon("Progress" + itos(update_spinner_step + 1))); + update_spinner->set_icon(theme->get_icon("Progress" + itos(update_spinner_step + 1), EditorStringName(EditorIcons))); } } @@ -507,9 +587,11 @@ void EditorNode::_notification(int p_what) { if (window) { // Handle macOS fullscreen and extend-to-title changes. window->connect("titlebar_changed", callable_mp(this, &EditorNode::_titlebar_resized)); - window->set_theme(theme); } + // Theme has already been created in the constructor, so we can skip that step. + _update_theme(true); + OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); get_tree()->get_root()->set_as_audio_listener_3d(false); get_tree()->get_root()->set_as_audio_listener_2d(false); @@ -524,6 +606,7 @@ void EditorNode::_notification(int p_what) { command_palette->register_shortcuts_as_command(); MessageQueue::get_singleton()->push_callable(callable_mp(this, &EditorNode::_begin_first_scan)); + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; @@ -585,6 +668,12 @@ void EditorNode::_notification(int p_what) { _titlebar_resized(); + // Set up a theme context for the 2D preview viewport using the project theme. + List> preview_themes; + preview_themes.push_back(ThemeDB::get_singleton()->get_project_theme()); + preview_themes.push_back(ThemeDB::get_singleton()->get_default_theme()); + ThemeDB::get_singleton()->create_theme_context(scene_root, preview_themes); + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; @@ -632,73 +721,14 @@ void EditorNode::_notification(int p_what) { EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/scale_gizmo_handles"); if (theme_changed) { - theme = create_custom_theme(theme_base->get_theme()); - DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor))); - - theme_base->set_theme(theme); - gui_base->set_theme(theme); - get_window()->set_theme(theme); - - gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles))); - main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, gui_base->get_theme_constant(SNAME("window_border_margin"), EditorStringName(Editor))); - main_vbox->add_theme_constant_override("separation", gui_base->get_theme_constant(SNAME("top_bar_separation"), EditorStringName(Editor))); - scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), EditorStringName(EditorStyles))); - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); - main_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles))); + _update_theme(); } scene_tabs->update_scene_tabs(); recent_scenes->reset_size(); - // Update debugger area. - if (EditorDebuggerNode::get_singleton()->is_visible()) { - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))); - } - - // Update icons. - for (int i = 0; i < singleton->main_editor_buttons.size(); i++) { - Button *tb = singleton->main_editor_buttons[i]; - EditorPlugin *p_editor = singleton->editor_table[i]; - Ref icon = p_editor->get_icon(); - - if (icon.is_valid()) { - tb->set_icon(icon); - } else if (singleton->gui_base->has_theme_icon(p_editor->get_name(), EditorStringName(EditorIcons))) { - tb->set_icon(singleton->gui_base->get_editor_theme_icon(p_editor->get_name())); - } - } - _build_icon_type_cache(); - prev_scene->set_icon(gui_base->get_editor_theme_icon(SNAME("PrevScene"))); - distraction_free->set_icon(gui_base->get_editor_theme_icon(SNAME("DistractionFree"))); - - bottom_panel_raise->set_icon(gui_base->get_editor_theme_icon(SNAME("ExpandBottomDock"))); - - if (gui_base->is_layout_rtl()) { - dock_tab_move_left->set_icon(theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons))); - dock_tab_move_right->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); - } else { - dock_tab_move_left->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); - dock_tab_move_right->set_icon(theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons))); - } - - help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), gui_base->get_editor_theme_icon(SNAME("HelpSearch"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_DOCS), gui_base->get_editor_theme_icon(SNAME("ExternalLink"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_QA), gui_base->get_editor_theme_icon(SNAME("ExternalLink"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_REPORT_A_BUG), gui_base->get_editor_theme_icon(SNAME("ExternalLink"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), gui_base->get_editor_theme_icon(SNAME("ActionCopy"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_SUGGEST_A_FEATURE), gui_base->get_editor_theme_icon(SNAME("ExternalLink"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_SEND_DOCS_FEEDBACK), gui_base->get_editor_theme_icon(SNAME("ExternalLink"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_COMMUNITY), gui_base->get_editor_theme_icon(SNAME("ExternalLink"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), gui_base->get_editor_theme_icon(SNAME("Godot"))); - help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), gui_base->get_editor_theme_icon(SNAME("Heart"))); - - for (int i = 0; i < main_editor_buttons.size(); i++) { - main_editor_buttons.write[i]->add_theme_font_override("font", gui_base->get_theme_font(SNAME("main_button_font"), EditorStringName(EditorFonts))); - main_editor_buttons.write[i]->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts))); - } - HashSet updated_textfile_extensions; bool extensions_match = true; const Vector textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); @@ -735,8 +765,7 @@ void EditorNode::_update_update_spinner() { // Make the icon modulate color overbright because icons are not completely white on a dark theme. // On a light theme, icons are dark, so we need to modulate them with an even brighter color. const bool dark_theme = EditorSettings::get_singleton()->is_dark_theme(); - update_spinner->set_self_modulate( - gui_base->get_theme_color(SNAME("error_color"), EditorStringName(Editor)) * (dark_theme ? Color(1.1, 1.1, 1.1) : Color(4.25, 4.25, 4.25))); + update_spinner->set_self_modulate(theme->get_color(SNAME("error_color"), EditorStringName(Editor)) * (dark_theme ? Color(1.1, 1.1, 1.1) : Color(4.25, 4.25, 4.25))); } else { update_spinner->set_tooltip_text(TTR("Spins when the editor window redraws.")); update_spinner->set_self_modulate(Color(1, 1, 1)); @@ -3131,12 +3160,12 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed tb->set_icon(icon); // Make sure the control is updated if the icon is reimported. icon->connect_changed(callable_mp((Control *)tb, &Control::update_minimum_size)); - } else if (singleton->gui_base->has_theme_icon(p_editor->get_name(), EditorStringName(EditorIcons))) { - tb->set_icon(singleton->gui_base->get_editor_theme_icon(p_editor->get_name())); + } else if (singleton->theme->has_icon(p_editor->get_name(), EditorStringName(EditorIcons))) { + tb->set_icon(singleton->theme->get_icon(p_editor->get_name(), EditorStringName(EditorIcons))); } - tb->add_theme_font_override("font", singleton->gui_base->get_theme_font(SNAME("main_button_font"), EditorStringName(EditorFonts))); - tb->add_theme_font_size_override("font_size", singleton->gui_base->get_theme_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts))); + tb->add_theme_font_override("font", singleton->theme->get_font(SNAME("main_button_font"), EditorStringName(EditorFonts))); + tb->add_theme_font_size_override("font_size", singleton->theme->get_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts))); singleton->main_editor_buttons.push_back(tb); singleton->main_editor_button_hb->add_child(tb); @@ -4067,14 +4096,14 @@ void EditorNode::notify_all_debug_sessions_exited() { void EditorNode::add_io_error(const String &p_error) { DEV_ASSERT(Thread::get_caller_id() == Thread::get_main_id()); - singleton->load_errors->add_image(singleton->gui_base->get_editor_theme_icon(SNAME("Error"))); + singleton->load_errors->add_image(singleton->theme->get_icon(SNAME("Error"), EditorStringName(EditorIcons))); singleton->load_errors->add_text(p_error + "\n"); EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5); } void EditorNode::add_io_warning(const String &p_warning) { DEV_ASSERT(Thread::get_caller_id() == Thread::get_main_id()); - singleton->load_errors->add_image(singleton->gui_base->get_editor_theme_icon(SNAME("Warning"))); + singleton->load_errors->add_image(singleton->theme->get_icon(SNAME("Warning"), EditorStringName(EditorIcons))); singleton->load_errors->add_text(p_warning + "\n"); EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5); } @@ -4212,8 +4241,8 @@ Ref EditorNode::_get_class_or_script_icon(const String &p_class, cons // scripts extending other scripts and for built-in classes. String script_class_name = p_script->get_language()->get_global_class_name(p_script->get_path()); String base_type = ScriptServer::get_global_class_native_base(script_class_name); - if (gui_base && gui_base->has_theme_icon(base_type, EditorStringName(EditorIcons))) { - return gui_base->get_editor_theme_icon(base_type); + if (theme.is_valid() && theme->has_icon(base_type, EditorStringName(EditorIcons))) { + return theme->get_icon(base_type, EditorStringName(EditorIcons)); } } } @@ -4236,22 +4265,22 @@ Ref EditorNode::_get_class_or_script_icon(const String &p_class, cons // Look up the class name or the fallback name in the editor theme. // This is only relevant for built-in classes. - if (gui_base) { - if (gui_base->has_theme_icon(p_class, EditorStringName(EditorIcons))) { - return gui_base->get_editor_theme_icon(p_class); + if (theme.is_valid()) { + if (theme->has_icon(p_class, EditorStringName(EditorIcons))) { + return theme->get_icon(p_class, EditorStringName(EditorIcons)); } - if (!p_fallback.is_empty() && gui_base->has_theme_icon(p_fallback, EditorStringName(EditorIcons))) { - return gui_base->get_editor_theme_icon(p_fallback); + if (!p_fallback.is_empty() && theme->has_icon(p_fallback, EditorStringName(EditorIcons))) { + return theme->get_icon(p_fallback, EditorStringName(EditorIcons)); } // If the fallback is empty or wasn't found, use the default fallback. if (ClassDB::class_exists(p_class)) { bool instantiable = !ClassDB::is_virtual(p_class) && ClassDB::can_instantiate(p_class); if (ClassDB::is_parent_class(p_class, SNAME("Node"))) { - return gui_base->get_editor_theme_icon(instantiable ? "Node" : "NodeDisabled"); + return theme->get_icon(instantiable ? "Node" : "NodeDisabled", EditorStringName(EditorIcons)); } else { - return gui_base->get_editor_theme_icon(instantiable ? "Object" : "ObjectDisabled"); + return theme->get_icon(instantiable ? "Object" : "ObjectDisabled", EditorStringName(EditorIcons)); } } } @@ -4464,12 +4493,12 @@ Ref EditorNode::_file_dialog_get_icon(const String &p_path) { void EditorNode::_build_icon_type_cache() { List tl; - theme_base->get_theme()->get_icon_list(EditorStringName(EditorIcons), &tl); + theme->get_icon_list(EditorStringName(EditorIcons), &tl); for (const StringName &E : tl) { if (!ClassDB::class_exists(E)) { continue; } - icon_type_cache[E] = theme_base->get_theme()->get_icon(E, EditorStringName(EditorIcons)); + icon_type_cache[E] = theme->get_icon(E, EditorStringName(EditorIcons)); } } @@ -4728,7 +4757,7 @@ void EditorNode::_dock_select_draw() { Color used = Color(0.6, 0.6, 0.6, 0.8); Color used_selected = Color(0.8, 0.8, 0.8, 0.8); - Color tab_selected = theme_base->get_theme_color(SNAME("mono_color"), EditorStringName(Editor)); + Color tab_selected = theme->get_color(SNAME("mono_color"), EditorStringName(Editor)); Color unused = used; unused.a = 0.4; Color unusable = unused; @@ -5666,9 +5695,9 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { } if (EditorDebuggerNode::get_singleton() == bottom_panel_items[p_idx].control) { // This is the debug panel which uses tabs, so the top section should be smaller. - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))); + bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))); } else { - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); + bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); } center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE); center_split->set_collapsed(false); @@ -5677,7 +5706,7 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { } bottom_panel_raise->show(); } else { - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); + bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); bottom_panel_items[p_idx].button->set_pressed(false); bottom_panel_items[p_idx].control->set_visible(false); center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); @@ -5766,7 +5795,7 @@ Variant EditorNode::drag_resource(const Ref &p_res, Control *p_from) { { // TODO: make proper previews - Ref texture = gui_base->get_editor_theme_icon(SNAME("FileBigThumb")); + Ref texture = theme->get_icon(SNAME("FileBigThumb"), EditorStringName(EditorIcons)); Ref img = texture->get_image(); img = img->duplicate(); img->resize(48, 48); // meh @@ -5816,10 +5845,10 @@ Variant EditorNode::drag_files_and_dirs(const Vector &p_paths, Control * if (p_paths[i].ends_with("/")) { label->set_text(p_paths[i].substr(0, p_paths[i].length() - 1).get_file()); - icon->set_texture(gui_base->get_editor_theme_icon(SNAME("Folder"))); + icon->set_texture(theme->get_icon(SNAME("Folder"), EditorStringName(EditorIcons))); } else { label->set_text(p_paths[i].get_file()); - icon->set_texture(gui_base->get_editor_theme_icon(SNAME("File"))); + icon->set_texture(theme->get_icon(SNAME("File"), EditorStringName(EditorIcons))); } icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); icon->set_size(Size2(16, 16)); @@ -6875,32 +6904,22 @@ EditorNode::EditorNode() { textfile_extensions.insert(E); } - theme_base = memnew(Control); - add_child(theme_base); - theme_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - - gui_base = memnew(Panel); - theme_base->add_child(gui_base); - gui_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - - theme_base->set_theme(theme); - gui_base->set_theme(theme); - gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles))); - resource_preview = memnew(EditorResourcePreview); add_child(resource_preview); progress_dialog = memnew(ProgressDialog); progress_dialog->set_unparent_when_invisible(true); + gui_base = memnew(Panel); + add_child(gui_base); + // Take up all screen. + gui_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); gui_base->set_anchor(SIDE_RIGHT, Control::ANCHOR_END); gui_base->set_anchor(SIDE_BOTTOM, Control::ANCHOR_END); gui_base->set_end(Point2(0, 0)); main_vbox = memnew(VBoxContainer); gui_base->add_child(main_vbox); - main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, gui_base->get_theme_constant(SNAME("window_border_margin"), EditorStringName(Editor))); - main_vbox->add_theme_constant_override("separation", gui_base->get_theme_constant(SNAME("top_bar_separation"), EditorStringName(Editor))); title_bar = memnew(EditorTitleBar); main_vbox->add_child(title_bar); @@ -6978,11 +6997,6 @@ EditorNode::EditorNode() { HBoxContainer *dock_hb = memnew(HBoxContainer); dock_tab_move_left = memnew(Button); dock_tab_move_left->set_flat(true); - if (gui_base->is_layout_rtl()) { - dock_tab_move_left->set_icon(theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons))); - } else { - dock_tab_move_left->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); - } dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE); dock_tab_move_left->connect("pressed", callable_mp(this, &EditorNode::_dock_move_left)); dock_hb->add_child(dock_tab_move_left); @@ -6995,11 +7009,6 @@ EditorNode::EditorNode() { dock_tab_move_right = memnew(Button); dock_tab_move_right->set_flat(true); - if (gui_base->is_layout_rtl()) { - dock_tab_move_right->set_icon(theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); - } else { - dock_tab_move_right->set_icon(theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons))); - } dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE); dock_tab_move_right->connect("pressed", callable_mp(this, &EditorNode::_dock_move_right)); @@ -7065,14 +7074,13 @@ EditorNode::EditorNode() { ED_SHORTCUT_OVERRIDE("editor/distraction_free_mode", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::D); distraction_free->set_shortcut(ED_GET_SHORTCUT("editor/distraction_free_mode")); distraction_free->set_tooltip_text(TTR("Toggle distraction-free mode.")); - distraction_free->set_icon(gui_base->get_editor_theme_icon(SNAME("DistractionFree"))); distraction_free->set_toggle_mode(true); scene_tabs->add_extra_button(distraction_free); distraction_free->connect("pressed", callable_mp(this, &EditorNode::_toggle_distraction_free_mode)); scene_root_parent = memnew(PanelContainer); scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE); - scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), EditorStringName(EditorStyles))); + scene_root_parent->add_theme_style_override("panel", theme->get_stylebox(SNAME("Content"), EditorStringName(EditorStyles))); scene_root_parent->set_draw_behind_parent(true); srt->add_child(scene_root_parent); scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -7080,7 +7088,6 @@ EditorNode::EditorNode() { scene_root = memnew(SubViewport); scene_root->set_embedding_subwindows(true); scene_root->set_disable_3d(true); - scene_root->set_disable_input(true); scene_root->set_as_audio_listener_2d(true); @@ -7103,7 +7110,7 @@ EditorNode::EditorNode() { main_menu = memnew(MenuBar); title_bar->add_child(main_menu); - main_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles))); + main_menu->add_theme_style_override("hover", theme->get_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles))); main_menu->set_flat(true); main_menu->set_start_index(0); // Main menu, add to the start of global menu. main_menu->set_prefer_global_menu(global_menu); @@ -7116,7 +7123,6 @@ EditorNode::EditorNode() { prev_scene = memnew(Button); prev_scene->set_flat(true); - prev_scene->set_icon(gui_base->get_editor_theme_icon(SNAME("PrevScene"))); prev_scene->set_tooltip_text(TTR("Go to previously opened scene.")); prev_scene->set_disabled(true); prev_scene->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(FILE_OPEN_PREV)); @@ -7277,8 +7283,8 @@ EditorNode::EditorNode() { if (can_expand && global_menu) { project_title = memnew(Label); - project_title->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), EditorStringName(EditorFonts))); - project_title->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts))); + project_title->add_theme_font_override("font", theme->get_font(SNAME("bold"), EditorStringName(EditorFonts))); + project_title->add_theme_font_size_override("font_size", theme->get_font_size(SNAME("bold_size"), EditorStringName(EditorFonts))); project_title->set_focus_mode(Control::FOCUS_NONE); project_title->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); project_title->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); @@ -7354,22 +7360,22 @@ EditorNode::EditorNode() { ED_SHORTCUT_AND_COMMAND("editor/editor_help", TTR("Search Help"), Key::F1); ED_SHORTCUT_OVERRIDE("editor/editor_help", "macos", KeyModifierMask::ALT | Key::SPACE); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("HelpSearch")), ED_GET_SHORTCUT("editor/editor_help"), HELP_SEARCH); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("HelpSearch"), EditorStringName(EditorIcons)), ED_GET_SHORTCUT("editor/editor_help"), HELP_SEARCH); help_menu->add_separator(); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("ExternalLink")), ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTR("Online Documentation")), HELP_DOCS); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("ExternalLink")), ED_SHORTCUT_AND_COMMAND("editor/q&a", TTR("Questions & Answers")), HELP_QA); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("ExternalLink")), ED_SHORTCUT_AND_COMMAND("editor/report_a_bug", TTR("Report a Bug")), HELP_REPORT_A_BUG); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("ActionCopy")), ED_SHORTCUT_AND_COMMAND("editor/copy_system_info", TTR("Copy System Info")), HELP_COPY_SYSTEM_INFO); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTR("Online Documentation")), HELP_DOCS); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/q&a", TTR("Questions & Answers")), HELP_QA); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/report_a_bug", TTR("Report a Bug")), HELP_REPORT_A_BUG); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("ActionCopy"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/copy_system_info", TTR("Copy System Info")), HELP_COPY_SYSTEM_INFO); help_menu->set_item_tooltip(-1, TTR("Copies the system info as a single-line text into the clipboard.")); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("ExternalLink")), ED_SHORTCUT_AND_COMMAND("editor/suggest_a_feature", TTR("Suggest a Feature")), HELP_SUGGEST_A_FEATURE); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("ExternalLink")), ED_SHORTCUT_AND_COMMAND("editor/send_docs_feedback", TTR("Send Docs Feedback")), HELP_SEND_DOCS_FEEDBACK); - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("ExternalLink")), ED_SHORTCUT_AND_COMMAND("editor/community", TTR("Community")), HELP_COMMUNITY); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/suggest_a_feature", TTR("Suggest a Feature")), HELP_SUGGEST_A_FEATURE); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/send_docs_feedback", TTR("Send Docs Feedback")), HELP_SEND_DOCS_FEEDBACK); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("ExternalLink"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/community", TTR("Community")), HELP_COMMUNITY); help_menu->add_separator(); if (!global_menu || !OS::get_singleton()->has_feature("macos")) { // On macOS "Quit" and "About" options are in the "app" menu. - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("Godot")), ED_SHORTCUT_AND_COMMAND("editor/about", TTR("About Godot")), HELP_ABOUT); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("Godot"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/about", TTR("About Godot")), HELP_ABOUT); } - help_menu->add_icon_shortcut(gui_base->get_editor_theme_icon(SNAME("Heart")), ED_SHORTCUT_AND_COMMAND("editor/support_development", TTR("Support Godot Development")), HELP_SUPPORT_GODOT_DEVELOPMENT); + help_menu->add_icon_shortcut(theme->get_icon(SNAME("Heart"), EditorStringName(EditorIcons)), ED_SHORTCUT_AND_COMMAND("editor/support_development", TTR("Support Godot Development")), HELP_SUPPORT_GODOT_DEVELOPMENT); // Spacer to center 2D / 3D / Script buttons. Control *right_spacer = memnew(Control); @@ -7391,8 +7397,8 @@ EditorNode::EditorNode() { renderer->set_fit_to_longest_item(false); renderer->set_focus_mode(Control::FOCUS_NONE); renderer->connect("item_selected", callable_mp(this, &EditorNode::_renderer_selected)); - renderer->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), EditorStringName(EditorFonts))); - renderer->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts))); + renderer->add_theme_font_override("font", theme->get_font(SNAME("bold"), EditorStringName(EditorFonts))); + renderer->add_theme_font_size_override("font_size", theme->get_font_size(SNAME("bold_size"), EditorStringName(EditorFonts))); renderer->set_tooltip_text(TTR("Choose a renderer.")); right_menu_hb->add_child(renderer); @@ -7453,7 +7459,7 @@ EditorNode::EditorNode() { update_spinner = memnew(MenuButton); right_menu_hb->add_child(update_spinner); - update_spinner->set_icon(gui_base->get_editor_theme_icon(SNAME("Progress1"))); + update_spinner->set_icon(theme->get_icon(SNAME("Progress1"), EditorStringName(EditorIcons))); update_spinner->get_popup()->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option)); PopupMenu *p = update_spinner->get_popup(); p->add_radio_check_item(TTR("Update Continuously"), SETTINGS_UPDATE_CONTINUOUSLY); @@ -7536,7 +7542,7 @@ EditorNode::EditorNode() { // Bottom panels. bottom_panel = memnew(PanelContainer); - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); + bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); center_split->add_child(bottom_panel); center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); @@ -7581,14 +7587,11 @@ EditorNode::EditorNode() { bottom_panel_hb->add_child(h_spacer); bottom_panel_raise = memnew(Button); - bottom_panel_raise->set_flat(true); - bottom_panel_raise->set_icon(gui_base->get_editor_theme_icon(SNAME("ExpandBottomDock"))); - - bottom_panel_raise->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12)); - bottom_panel_hb->add_child(bottom_panel_raise); bottom_panel_raise->hide(); + bottom_panel_raise->set_flat(true); bottom_panel_raise->set_toggle_mode(true); + bottom_panel_raise->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12)); bottom_panel_raise->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_raise_toggled)); log = memnew(EditorLog); diff --git a/editor/editor_node.h b/editor/editor_node.h index 4a529afc50e..1119f6b896b 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -295,7 +295,6 @@ private: bool is_main_screen_editing = false; PanelContainer *scene_root_parent = nullptr; - Control *theme_base = nullptr; Control *gui_base = nullptr; VBoxContainer *main_vbox = nullptr; OptionButton *renderer = nullptr; @@ -525,6 +524,7 @@ private: static void _resource_saved(Ref p_resource, const String &p_path); static void _resource_loaded(Ref p_resource, const String &p_path); + void _update_theme(bool p_skip_creation = false); void _build_icon_type_cache(); void _enable_pending_addons(); @@ -867,7 +867,6 @@ public: Error export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only); Control *get_gui_base() { return gui_base; } - Control *get_theme_base() { return gui_base->get_parent_control(); } void save_scene_to_path(String p_file, bool p_with_preview = true) { if (p_with_preview) { diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index f6bd4e7001f..ac098a354d3 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -40,6 +40,7 @@ #include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_string_names.h" #include "scene/resources/image_texture.h" bool EditorResourcePreviewGenerator::handles(const String &p_type) const { @@ -341,7 +342,8 @@ void EditorResourcePreview::_thread() { void EditorResourcePreview::_update_thumbnail_sizes() { if (small_thumbnail_size == -1) { - small_thumbnail_size = EditorNode::get_singleton()->get_theme_base()->get_editor_theme_icon(SNAME("Object"))->get_width(); // Kind of a workaround to retrieve the default icon size + // Kind of a workaround to retrieve the default icon size. + small_thumbnail_size = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Object"), EditorStringName(EditorIcons))->get_width(); } } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 0c3decb7b4d..2fe607a08cb 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1612,6 +1612,8 @@ void ScriptEditor::_notification(int p_what) { case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_THEME_CHANGED: { + tab_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ScriptEditor"), EditorStringName(EditorStyles))); + help_search->set_icon(get_editor_theme_icon(SNAME("HelpSearch"))); site_search->set_icon(get_editor_theme_icon(SNAME("ExternalLink"))); @@ -1628,7 +1630,7 @@ void ScriptEditor::_notification(int p_what) { filter_scripts->set_right_icon(get_editor_theme_icon(SNAME("Search"))); filter_methods->set_right_icon(get_editor_theme_icon(SNAME("Search"))); - filename->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); + filename->add_theme_style_override("normal", get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); recent_scripts->reset_size(); @@ -1639,6 +1641,9 @@ void ScriptEditor::_notification(int p_what) { } break; case NOTIFICATION_READY: { + // Can't set own styles in NOTIFICATION_THEME_CHANGED, so for now this will do. + add_theme_style_override("panel", get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"))); + get_tree()->connect("tree_changed", callable_mp(this, &ScriptEditor::_tree_changed)); InspectorDock::get_singleton()->connect("request_help", callable_mp(this, &ScriptEditor::_help_class_open)); EditorNode::get_singleton()->connect("request_help_search", callable_mp(this, &ScriptEditor::_help_search)); @@ -4139,9 +4144,6 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { ScriptServer::edit_request_func = _open_script_request; - add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles))); - tab_container->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditor"), EditorStringName(EditorStyles))); - Ref json_syntax_highlighter; json_syntax_highlighter.instantiate(); register_syntax_highlighter(json_syntax_highlighter); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 5a1a50848f8..ffe6c01ef0c 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -1217,7 +1217,7 @@ void ThemeItemEditorDialog::_dialog_about_to_show() { import_default_theme_items->reset_item_tree(); import_editor_theme_items->set_edited_theme(edited_theme); - import_editor_theme_items->set_base_theme(EditorNode::get_singleton()->get_theme_base()->get_theme()); + import_editor_theme_items->set_base_theme(EditorNode::get_singleton()->get_editor_theme()); import_editor_theme_items->reset_item_tree(); import_other_theme_items->set_edited_theme(edited_theme); diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index 72127f74402..61bce0a89c3 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -202,8 +202,14 @@ void ThemeEditorPreview::_notification(int p_what) { } connect("visibility_changed", callable_mp(this, &ThemeEditorPreview::_preview_visibility_changed)); - [[fallthrough]]; - } + } break; + + case NOTIFICATION_READY: { + List> preview_themes; + preview_themes.push_back(ThemeDB::get_singleton()->get_default_theme()); + ThemeDB::get_singleton()->create_theme_context(preview_root, preview_themes); + } break; + case NOTIFICATION_THEME_CHANGED: { picker_button->set_icon(get_editor_theme_icon(SNAME("ColorPick"))); @@ -247,9 +253,8 @@ ThemeEditorPreview::ThemeEditorPreview() { preview_container = memnew(ScrollContainer); preview_body->add_child(preview_container); - MarginContainer *preview_root = memnew(MarginContainer); + preview_root = memnew(MarginContainer); preview_container->add_child(preview_root); - preview_root->set_theme(ThemeDB::get_singleton()->get_default_theme()); preview_root->set_clip_contents(true); preview_root->set_custom_minimum_size(Size2(450, 0) * EDSCALE); preview_root->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/plugins/theme_editor_preview.h b/editor/plugins/theme_editor_preview.h index bd9663904a4..ed888e6c148 100644 --- a/editor/plugins/theme_editor_preview.h +++ b/editor/plugins/theme_editor_preview.h @@ -44,6 +44,7 @@ class ThemeEditorPreview : public VBoxContainer { GDCLASS(ThemeEditorPreview, VBoxContainer); ScrollContainer *preview_container = nullptr; + MarginContainer *preview_root = nullptr; ColorRect *preview_bg = nullptr; MarginContainer *preview_overlay = nullptr; Control *picker_overlay = nullptr; diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp index f24569a02b8..92f3dec5e20 100644 --- a/scene/theme/theme_db.cpp +++ b/scene/theme/theme_db.cpp @@ -272,7 +272,17 @@ void ThemeDB::_init_default_theme_context() { default_theme_context = memnew(ThemeContext); List> themes; + + // Only add the project theme to the default context when running projects. + +#ifdef TOOLS_ENABLED + if (!Engine::get_singleton()->is_editor_hint()) { + themes.push_back(project_theme); + } +#else themes.push_back(project_theme); +#endif + themes.push_back(default_theme); default_theme_context->set_themes(themes); } @@ -289,6 +299,14 @@ void ThemeDB::_finalize_theme_contexts() { } } +ThemeContext *ThemeDB::get_theme_context(Node *p_node) const { + if (!theme_contexts.has(p_node)) { + return nullptr; + } + + return theme_contexts[p_node]; +} + ThemeContext *ThemeDB::get_default_theme_context() const { return default_theme_context; } diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h index b1e50e83421..40ae30ff81a 100644 --- a/scene/theme/theme_db.h +++ b/scene/theme/theme_db.h @@ -108,6 +108,7 @@ public: ThemeContext *create_theme_context(Node *p_node, List> &p_themes); void destroy_theme_context(Node *p_node); + ThemeContext *get_theme_context(Node *p_node) const; ThemeContext *get_default_theme_context() const; ThemeContext *get_nearest_theme_context(Node *p_for_node) const;