Merge pull request #111118 from YeldhamDev/godots_new_groove

Add a new editor theme
This commit is contained in:
Thaddeus Crews 2025-10-30 13:51:36 -05:00
commit 8afb2e5976
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
27 changed files with 4887 additions and 2381 deletions

View file

@ -1107,6 +1107,9 @@
<member name="interface/theme/border_size" type="int" setter="" getter="">
The border size to use for interface elements (in pixels).
</member>
<member name="interface/theme/color_preset" type="String" setter="" getter="">
The editor color preset to use.
</member>
<member name="interface/theme/contrast" type="float" setter="" getter="">
The contrast factor to use when deriving the editor theme's base color (see [member interface/theme/base_color]). When using a positive values, the derived colors will be [i]darker[/i] than the base color. This contrast factor can be set to a negative value, which will make the derived colors [i]brighter[/i] than the base color. Negative contrast rates often look better for light themes.
</member>
@ -1119,6 +1122,12 @@
<member name="interface/theme/draw_extra_borders" type="bool" setter="" getter="">
If [code]true[/code], draws additional borders around interactive UI elements in the editor. This is automatically enabled when using the [b]Black (OLED)[/b] theme preset, as this theme preset uses a fully black background.
</member>
<member name="interface/theme/draw_relationship_lines" type="int" setter="" getter="">
What relationship lines to draw in the editor's [Tree]-based GUIs (such as the Scene tree dock).
- [b]None[/b] will make it so that no relationship lines are drawn.
- [b]Selected Only[/b] will only draw them for selected items.
- [b]All[/b] will always draw them for all items.
</member>
<member name="interface/theme/follow_system_theme" type="bool" setter="" getter="">
If [code]true[/code], the editor theme preset will attempt to automatically match the system theme.
</member>
@ -1132,15 +1141,15 @@
The saturation to use for editor icons. Higher values result in more vibrant colors.
[b]Note:[/b] The default editor icon saturation was increased by 30% in Godot 4.0 and later. To get Godot 3.x's icon saturation back, set [member interface/theme/icon_saturation] to [code]0.77[/code].
</member>
<member name="interface/theme/preset" type="String" setter="" getter="">
The editor theme preset to use.
</member>
<member name="interface/theme/relationship_line_opacity" type="float" setter="" getter="">
The opacity to use when drawing relationship lines in the editor's [Tree]-based GUIs (such as the Scene tree dock).
</member>
<member name="interface/theme/spacing_preset" type="String" setter="" getter="">
The editor theme spacing preset to use. See also [member interface/theme/base_spacing] and [member interface/theme/additional_spacing].
</member>
<member name="interface/theme/style" type="String" setter="" getter="">
The editor theme style to use.
</member>
<member name="interface/theme/use_system_accent_color" type="bool" setter="" getter="">
If [code]true[/code], set accent color based on system settings.
[b]Note:[/b] This setting is only effective on Windows, MacOS, and Android.

View file

@ -47,6 +47,7 @@
#include "scene/gui/separator.h"
#include "scene/main/timer.h"
#include "scene/resources/font.h"
#include "scene/resources/style_box_flat.h"
#include "servers/audio/audio_server.h"
void EditorAudioBus::_update_visible_channels() {
@ -87,10 +88,11 @@ void EditorAudioBus::_notification(int p_what) {
disabled_vu = get_editor_theme_icon(SNAME("BusVuFrozen"));
Color solo_color = EditorThemeManager::is_dark_theme() ? Color(1.0, 0.89, 0.22) : Color(1.9, 1.74, 0.83);
Color mute_color = EditorThemeManager::is_dark_theme() ? Color(1.0, 0.16, 0.16) : Color(2.35, 1.03, 1.03);
Color bypass_color = EditorThemeManager::is_dark_theme() ? Color(0.13, 0.8, 1.0) : Color(1.03, 2.04, 2.35);
float darkening_factor = EditorThemeManager::is_dark_theme() ? 0.15 : 0.65;
bool dark_icon_and_font = EditorThemeManager::is_dark_icon_and_font();
Color solo_color = dark_icon_and_font ? Color(1.0, 0.89, 0.22) : Color(1.9, 1.74, 0.83);
Color mute_color = dark_icon_and_font ? Color(1.0, 0.16, 0.16) : Color(2.35, 1.03, 1.03);
Color bypass_color = dark_icon_and_font ? Color(0.13, 0.8, 1.0) : Color(1.03, 2.04, 2.35);
float darkening_factor = dark_icon_and_font ? 0.15 : 0.65;
Color solo_color_darkened = solo_color.darkened(darkening_factor);
Color mute_color_darkened = mute_color.darkened(darkening_factor);
Color bypass_color_darkened = bypass_color.darkened(darkening_factor);

View file

@ -236,8 +236,8 @@ void FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (has_custom_color) {
subdirectory_item->set_icon_modulate(0, editor_is_dark_theme ? custom_color : custom_color * ITEM_COLOR_SCALE);
subdirectory_item->set_custom_bg_color(0, Color(custom_color, editor_is_dark_theme ? ITEM_ALPHA_MIN : ITEM_ALPHA_MAX));
subdirectory_item->set_icon_modulate(0, editor_is_dark_icon_and_font ? custom_color : custom_color * ITEM_COLOR_SCALE);
subdirectory_item->set_custom_bg_color(0, Color(custom_color, editor_is_dark_icon_and_font ? ITEM_ALPHA_MIN : ITEM_ALPHA_MAX));
} else {
TreeItem *parent = subdirectory_item->get_parent();
if (parent) {
@ -630,9 +630,9 @@ void FileSystemDock::_notification(int p_what) {
// Update editor dark theme & always show folders states from editor settings, redraw if needed.
bool do_redraw = false;
bool new_editor_is_dark_theme = EditorThemeManager::is_dark_theme();
if (new_editor_is_dark_theme != editor_is_dark_theme) {
editor_is_dark_theme = new_editor_is_dark_theme;
bool new_editor_is_dark_icon_and_font = EditorThemeManager::is_dark_icon_and_font();
if (new_editor_is_dark_icon_and_font != editor_is_dark_icon_and_font) {
editor_is_dark_icon_and_font = new_editor_is_dark_icon_and_font;
do_redraw = true;
}
@ -1080,7 +1080,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->set_item_metadata(-1, bd);
files->set_item_selectable(-1, false);
if (!editor_is_dark_theme && inherited_folder_color != default_folder_color) {
if (!editor_is_dark_icon_and_font && inherited_folder_color != default_folder_color) {
files->set_item_icon_modulate(-1, inherited_folder_color * ITEM_COLOR_SCALE);
} else {
files->set_item_icon_modulate(-1, inherited_folder_color);
@ -1098,7 +1098,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->add_item(dname, folder_icon, true);
files->set_item_metadata(-1, dpath);
Color this_folder_color = has_custom_color ? folder_colors[assigned_folder_colors[dpath]] : inherited_folder_color;
if (!editor_is_dark_theme && this_folder_color != default_folder_color) {
if (!editor_is_dark_icon_and_font && this_folder_color != default_folder_color) {
this_folder_color *= ITEM_COLOR_SCALE;
}
files->set_item_icon_modulate(-1, this_folder_color);
@ -3393,7 +3393,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, const Vect
for (const KeyValue<String, Color> &E : folder_colors) {
folder_colors_menu->add_icon_item(get_editor_theme_icon(SNAME("Folder")), E.key.capitalize());
folder_colors_menu->set_item_icon_modulate(-1, editor_is_dark_theme ? E.value : E.value * 2);
folder_colors_menu->set_item_icon_modulate(-1, editor_is_dark_icon_and_font ? E.value : E.value * 2);
folder_colors_menu->set_item_metadata(-1, E.key);
}
}
@ -4226,7 +4226,7 @@ FileSystemDock::FileSystemDock() {
assigned_folder_colors = ProjectSettings::get_singleton()->get_setting("file_customization/folder_colors");
editor_is_dark_theme = EditorThemeManager::is_dark_theme();
editor_is_dark_icon_and_font = EditorThemeManager::is_dark_icon_and_font();
VBoxContainer *main_vb = memnew(VBoxContainer);
add_child(main_vb);

View file

@ -211,7 +211,7 @@ private:
bool always_show_folders = false;
int thumbnail_size_setting = 0;
bool editor_is_dark_theme = false;
bool editor_is_dark_icon_and_font = false;
class FileOrFolder {
public:

View file

@ -1096,8 +1096,8 @@ void EditorNode::_update_update_spinner() {
// as this feature should only be enabled for troubleshooting purposes.
// 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 = EditorThemeManager::is_dark_theme();
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)));
const bool dark_icon_and_font = EditorThemeManager::is_dark_icon_and_font();
update_spinner->set_self_modulate(theme->get_color(SNAME("error_color"), EditorStringName(Editor)) * (dark_icon_and_font ? Color(1.1, 1.1, 1.1) : Color(4.25, 4.25, 4.25)));
} else {
update_spinner->set_tooltip_text(TTRC("Spins when the editor window redraws."));
update_spinner->set_self_modulate(Color(1, 1, 1));

View file

@ -38,7 +38,7 @@
#include "scene/gui/tree.h"
#include "servers/display/display_server.h"
void EditorDirDialog::_update_dir(const Color &p_default_folder_color, const Dictionary &p_assigned_folder_colors, const HashMap<String, Color> &p_folder_colors, bool p_is_dark_theme, TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) {
void EditorDirDialog::_update_dir(const Color &p_default_folder_color, const Dictionary &p_assigned_folder_colors, const HashMap<String, Color> &p_folder_colors, bool p_is_dark_icon_and_font, TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) {
updating = true;
const String path = p_dir->get_path();
@ -58,8 +58,8 @@ void EditorDirDialog::_update_dir(const Color &p_default_folder_color, const Dic
if (p_assigned_folder_colors.has(path)) {
const Color &folder_color = p_folder_colors[p_assigned_folder_colors[path]];
p_item->set_icon_modulate(0, p_is_dark_theme ? folder_color : folder_color * FileSystemDock::ITEM_COLOR_SCALE);
p_item->set_custom_bg_color(0, Color(folder_color, p_is_dark_theme ? FileSystemDock::ITEM_ALPHA_MIN : FileSystemDock::ITEM_ALPHA_MAX));
p_item->set_icon_modulate(0, p_is_dark_icon_and_font ? folder_color : folder_color * FileSystemDock::ITEM_COLOR_SCALE);
p_item->set_custom_bg_color(0, Color(folder_color, p_is_dark_icon_and_font ? FileSystemDock::ITEM_ALPHA_MIN : FileSystemDock::ITEM_ALPHA_MAX));
} else {
TreeItem *parent_item = p_item->get_parent();
Color parent_bg_color = parent_item->get_custom_bg_color(0);
@ -79,7 +79,7 @@ void EditorDirDialog::_update_dir(const Color &p_default_folder_color, const Dic
updating = false;
for (int i = 0; i < p_dir->get_subdir_count(); i++) {
TreeItem *ti = tree->create_item(p_item);
_update_dir(p_default_folder_color, p_assigned_folder_colors, p_folder_colors, p_is_dark_theme, ti, p_dir->get_subdir(i));
_update_dir(p_default_folder_color, p_assigned_folder_colors, p_folder_colors, p_is_dark_icon_and_font, ti, p_dir->get_subdir(i));
}
}
@ -107,7 +107,7 @@ void EditorDirDialog::reload(const String &p_path) {
tree->clear();
TreeItem *root = tree->create_item();
_update_dir(tree->get_theme_color(SNAME("folder_icon_color"), SNAME("FileDialog")), FileSystemDock::get_singleton()->get_assigned_folder_colors(), FileSystemDock::get_singleton()->get_folder_colors(), EditorThemeManager::is_dark_theme(), root, EditorFileSystem::get_singleton()->get_filesystem(), p_path);
_update_dir(tree->get_theme_color(SNAME("folder_icon_color"), SNAME("FileDialog")), FileSystemDock::get_singleton()->get_assigned_folder_colors(), FileSystemDock::get_singleton()->get_folder_colors(), EditorThemeManager::is_dark_icon_and_font(), root, EditorFileSystem::get_singleton()->get_filesystem(), p_path);
_item_collapsed(root);
new_dir_path.clear();
must_reload = false;

View file

@ -52,7 +52,7 @@ class EditorDirDialog : public ConfirmationDialog {
void _item_collapsed(Object *p_item);
void _item_activated();
void _update_dir(const Color &p_default_folder_color, const Dictionary &p_assigned_folder_colors, const HashMap<String, Color> &p_folder_colors, bool p_is_dark_theme, TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path = String());
void _update_dir(const Color &p_default_folder_color, const Dictionary &p_assigned_folder_colors, const HashMap<String, Color> &p_folder_colors, bool p_is_dark_icon_and_font, TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path = String());
void _make_dir();
void _make_dir_confirm(const String &p_path, const String &p_base_dir);

View file

@ -208,9 +208,8 @@ EditorObjectSelector::EditorObjectSelector(EditorSelectionHistory *p_history) {
history = p_history;
MarginContainer *main_mc = memnew(MarginContainer);
main_mc->set_theme_type_variation("ObjectSelectorMargin");
main_mc->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
main_mc->add_theme_constant_override("margin_left", 4 * EDSCALE);
main_mc->add_theme_constant_override("margin_right", 6 * EDSCALE);
add_child(main_mc);
HBoxContainer *main_hb = memnew(HBoxContainer);

View file

@ -1978,6 +1978,8 @@ void EditorInspectorSection::_notification(int p_what) {
bg_color = theme_cache.prop_subsection;
bg_color.a /= level;
vbox->add_theme_constant_override("separation", theme_cache.vertical_separation);
} break;
case NOTIFICATION_SORT_CHILDREN: {
@ -3551,7 +3553,7 @@ void EditorInspector::initialize_section_theme(EditorInspectorSection::ThemeCach
}
p_cache.horizontal_separation = p_control->get_theme_constant(SNAME("h_separation"), SNAME("EditorInspectorSection"));
p_cache.vertical_separation = p_control->get_theme_constant(SNAME("v_separation"), SNAME("Tree"));
p_cache.vertical_separation = p_control->get_theme_constant(SNAME("v_separation"), SNAME("EditorInspector"));
p_cache.inspector_margin = p_control->get_theme_constant(SNAME("inspector_margin"), EditorStringName(Editor));
p_cache.indent_size = p_control->get_theme_constant(SNAME("indent_size"), SNAME("EditorInspectorSection"));
p_cache.key_padding_size = int(EDITOR_GET("interface/theme/base_spacing")) * 2;
@ -3590,7 +3592,7 @@ void EditorInspector::initialize_category_theme(EditorInspectorCategory::ThemeCa
}
p_cache.horizontal_separation = p_control->get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
p_cache.vertical_separation = p_control->get_theme_constant(SNAME("v_separation"), SNAME("Tree"));
p_cache.vertical_separation = p_control->get_theme_constant(SNAME("v_separation"), SNAME("EditorInspector"));
p_cache.class_icon_size = p_control->get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
p_cache.font_color = p_control->get_theme_color(SceneStringName(font_color), SNAME("Tree"));
@ -3805,8 +3807,7 @@ void EditorInspector::_add_section_in_tree(EditorInspectorSection *p_section, VB
}
if (!container) {
container = memnew(VBoxContainer);
int separation = get_theme_constant(SNAME("v_separation"), SNAME("EditorInspector"));
container->add_theme_constant_override("separation", separation);
container->add_theme_constant_override("separation", theme_cache.vertical_separation);
p_current_vbox->add_child(container);
}
container->add_child(p_section);
@ -4208,6 +4209,7 @@ void EditorInspector::update_tree() {
// Recreate the category vbox if it was reset.
if (category_vbox == nullptr) {
category_vbox = memnew(VBoxContainer);
category_vbox->add_theme_constant_override("separation", theme_cache.vertical_separation);
category_vbox->hide();
main_vbox->add_child(category_vbox);
}

View file

@ -232,7 +232,7 @@ void ProjectManager::_update_theme(bool p_skip_creation) {
main_vbox->add_theme_constant_override("separation", top_bar_separation);
background_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox("Background", EditorStringName(EditorStyles)));
main_view_container->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), "TabContainer"));
main_view_container->add_theme_style_override(SceneStringName(panel), get_theme_stylebox("panel_container", "ProjectManager"));
title_bar_logo->set_button_icon(get_editor_theme_icon("TitleBarLogo"));

View file

@ -59,7 +59,7 @@ void QuickSettingsDialog::_fetch_setting_values() {
#ifndef ANDROID_ENABLED
editor_languages = pi.hint_string.split(";", false);
#endif
} else if (pi.name == "interface/theme/preset") {
} else if (pi.name == "interface/theme/color_preset") {
editor_themes = pi.hint_string.split(",");
} else if (pi.name == "interface/editor/display_scale") {
editor_scales = pi.hint_string.split(",");
@ -93,7 +93,7 @@ void QuickSettingsDialog::_update_current_values() {
// Theme options.
{
const String current_theme = EDITOR_GET("interface/theme/preset");
const String current_theme = EDITOR_GET("interface/theme/color_preset");
for (int i = 0; i < editor_themes.size(); i++) {
const String &theme_value = editor_themes[i];
@ -185,7 +185,7 @@ void QuickSettingsDialog::_language_selected(int p_id) {
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);
_set_setting_value("interface/theme/color_preset", selected_theme);
custom_theme_label->set_visible(selected_theme == "Custom");
}
@ -241,7 +241,7 @@ void QuickSettingsDialog::update_size_limits(const Size2 &p_max_popup_size) {
void QuickSettingsDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
settings_list_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
settings_list_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("quick_settings_panel"), SNAME("ProjectManager")));
restart_required_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
custom_theme_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("font_placeholder_color"), EditorStringName(Editor)));
@ -307,7 +307,7 @@ QuickSettingsDialog::QuickSettingsDialog() {
theme_option_button->add_item(theme_value, i);
}
_add_setting_control(TTRC("Interface Theme"), theme_option_button);
_add_setting_control(TTRC("Color Preset"), theme_option_button);
custom_theme_label = memnew(Label(TTRC("Custom preset can be further configured in the editor.")));
custom_theme_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);

View file

@ -1125,12 +1125,8 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
window_wrapper = p_wrapper;
embedded_process = p_embedded_process;
// Add some margin to the sides for better aesthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
MarginContainer *toolbar_margin = memnew(MarginContainer);
toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE);
toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE);
toolbar_margin->set_theme_type_variation("MainToolBarMargin");
add_child(toolbar_margin);
HBoxContainer *main_menu_hbox = memnew(HBoxContainer);

View file

@ -370,7 +370,7 @@ void TileSetEditor::_notification(int p_what) {
source_sort_button->set_button_icon(get_editor_theme_icon(SNAME("Sort")));
sources_advanced_menu_button->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
missing_texture_texture = get_editor_theme_icon(SNAME("TileSet"));
expanded_area->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), "Tree"));
expanded_area->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("expand_panel"), SNAME("TileSetEditor")));
_update_sources_list();
} break;

View file

@ -55,7 +55,7 @@ void BoneMapperButton::fetch_textures() {
set_offset(SIDE_BOTTOM, 0);
// Hack to avoid handle color darkening...
set_modulate(EditorThemeManager::is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25));
set_modulate(EditorThemeManager::is_dark_icon_and_font() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25));
circle = memnew(TextureRect);
circle->set_texture(get_editor_theme_icon(SNAME("BoneMapperHandleCircle")));

View file

@ -9597,12 +9597,8 @@ Node3DEditor::Node3DEditor() {
snap_key_enabled = false;
tool_mode = TOOL_MODE_SELECT;
// Add some margin to the sides for better aesthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
MarginContainer *toolbar_margin = memnew(MarginContainer);
toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE);
toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE);
toolbar_margin->set_theme_type_variation("MainToolBarMargin");
vbc->add_child(toolbar_margin);
// A fluid container for all toolbars.

View file

@ -4245,7 +4245,7 @@ void CanvasItemEditor::_update_editor_settings() {
// to distinguish from the other key icons at the top. On a light theme,
// the icon will be dark, so we need to lighten it before blending it
// with the red color.
const Color key_auto_color = EditorThemeManager::is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25);
const Color key_auto_color = EditorThemeManager::is_dark_icon_and_font() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25);
key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
animation_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
@ -5439,12 +5439,8 @@ CanvasItemEditor::CanvasItemEditor() {
SceneTreeDock::get_singleton()->connect("node_created", callable_mp(this, &CanvasItemEditor::_adjust_new_node_position));
SceneTreeDock::get_singleton()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position));
// Add some margin to the sides for better aesthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
MarginContainer *toolbar_margin = memnew(MarginContainer);
toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE);
toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE);
toolbar_margin->set_theme_type_variation("MainToolBarMargin");
add_child(toolbar_margin);
// A fluid container for all toolbars.

View file

@ -49,6 +49,7 @@
#include "editor/file_system/editor_paths.h"
#include "editor/inspector/editor_property_name_processor.h"
#include "editor/project_manager/engine_update_label.h"
#include "editor/themes/editor_theme_manager.h"
#include "editor/translations/editor_translation.h"
#include "main/main.h"
#include "modules/regex/regex.h"
@ -582,18 +583,20 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Theme
EDITOR_SETTING_BASIC(Variant::BOOL, PROPERTY_HINT_ENUM, "interface/theme/follow_system_theme", false, "")
EDITOR_SETTING_BASIC(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/preset", "Default", "Default,Breeze Dark,Godot 2,Gray,Light,Solarized (Dark),Solarized (Light),Black (OLED),Custom")
EDITOR_SETTING_BASIC(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/style", "Modern", "Modern,Classic")
EDITOR_SETTING_BASIC(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/color_preset", "Default", "Default,Breeze Dark,Godot 2,Godot 3,Gray,Light,Solarized (Dark),Solarized (Light),Black (OLED),Custom")
EDITOR_SETTING_BASIC(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/spacing_preset", "Default", "Compact,Default,Spacious,Custom")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/theme/icon_and_font_color", 0, "Auto,Dark,Light")
EDITOR_SETTING_BASIC(Variant::COLOR, PROPERTY_HINT_NONE, "interface/theme/base_color", Color(0.2, 0.23, 0.31), "")
EDITOR_SETTING_BASIC(Variant::COLOR, PROPERTY_HINT_NONE, "interface/theme/accent_color", Color(0.41, 0.61, 0.91), "")
EDITOR_SETTING_BASIC(Variant::COLOR, PROPERTY_HINT_NONE, "interface/theme/base_color", Color(0.14, 0.14, 0.14), "")
EDITOR_SETTING_BASIC(Variant::COLOR, PROPERTY_HINT_NONE, "interface/theme/accent_color", Color(0.34, 0.62, 1.0), "")
EDITOR_SETTING_BASIC(Variant::BOOL, PROPERTY_HINT_NONE, "interface/theme/use_system_accent_color", false, "")
EDITOR_SETTING_BASIC(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/theme/contrast", 0.3, "-1,1,0.01")
EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/theme/draw_extra_borders", false, "")
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/theme/icon_saturation", 1.0, "0,2,0.01")
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/theme/icon_saturation", 2.0, "0,2,0.01")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/theme/draw_relationship_lines", (int32_t)EditorThemeManager::RELATIONSHIP_SELECTED_ONLY, "None,Selected Only,All")
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/theme/relationship_line_opacity", 0.1, "0.00,1,0.01")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/theme/border_size", 0, "0,2,1")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/theme/corner_radius", 3, "0,6,1")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/theme/corner_radius", 4, "0,6,1")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/theme/base_spacing", 4, "0,8,1")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/theme/additional_spacing", 0, "0,8,1")
EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "interface/theme/custom_theme", "", "*.res,*.tres,*.theme", PROPERTY_USAGE_DEFAULT)
@ -1209,6 +1212,7 @@ const String EditorSettings::_get_project_metadata_path() const {
#ifndef DISABLE_DEPRECATED
void EditorSettings::_remove_deprecated_settings() {
erase("interface/theme/preset");
erase("network/connection/engine_version_update_mode");
erase("run/output/always_open_output_on_play");
erase("run/output/always_close_output_on_stop");

View file

@ -70,8 +70,8 @@ void EditorSettingsDialog::_settings_property_edited(const String &p_name) {
// Set theme presets to Custom when controlled settings change.
if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast" || full_name == "interface/theme/draw_extra_borders") {
EditorSettings::get_singleton()->set_manually("interface/theme/preset", "Custom");
if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast" || full_name == "interface/theme/draw_extra_borders" || full_name == "interface/theme/icon_saturation" || full_name == "interface/theme/draw_relationship_lines" || full_name == "interface/theme/corner_radius") {
EditorSettings::get_singleton()->set_manually("interface/theme/color_preset", "Custom");
} else if (full_name == "interface/theme/base_spacing" || full_name == "interface/theme/additional_spacing") {
EditorSettings::get_singleton()->set_manually("interface/theme/spacing_preset", "Custom");
} else if (full_name.begins_with("text_editor/theme/highlighting")) {

View file

@ -573,7 +573,7 @@ void VisualShaderGraphPlugin::update_theme() {
Ref<Font> label_bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_bold_msdf", EditorStringName(EditorFonts));
vs_msdf_fonts_theme->set_font(SceneStringName(font), "Label", label_font);
vs_msdf_fonts_theme->set_font(SceneStringName(font), "GraphNodeTitleLabel", label_bold_font);
if (!EditorThemeManager::is_dark_theme()) {
if (!EditorThemeManager::is_dark_icon_and_font()) {
// Override the color to white for light themes.
vs_msdf_fonts_theme->set_color(SceneStringName(font_color), "GraphNodeTitleLabel", Color(1, 1, 1));
}

View file

@ -39,8 +39,8 @@
#include "modules/svg/image_loader_svg.h"
void editor_configure_icons(bool p_dark_theme) {
if (p_dark_theme) {
void editor_configure_icons(bool p_dark_icon_and_font) {
if (p_dark_icon_and_font) {
ImageLoaderSVG::set_forced_color_map(HashMap<Color, Color>());
} else {
ImageLoaderSVG::set_forced_color_map(EditorColorMap::get_color_conversion_map());

View file

@ -32,7 +32,7 @@
#include "scene/resources/theme.h"
void editor_configure_icons(bool p_dark_theme);
void editor_configure_icons(bool p_dark_icon_and_font);
void editor_register_icons(const Ref<Theme> &p_theme, bool p_dark_theme, float p_icon_saturation, int p_thumb_size, float p_gizmo_handle_scale);
void editor_copy_icons(const Ref<Theme> &p_theme, const Ref<Theme> &p_old_theme);

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,10 @@
#pragma once
#include "editor/themes/editor_theme.h"
#include "scene/resources/style_box_flat.h"
class StyleBoxFlat;
class StyleBoxLine;
class StyleBoxTexture;
class EditorThemeManager {
static int benchmark_run;
@ -46,9 +49,11 @@ class EditorThemeManager {
LIGHT_COLOR,
};
public:
struct ThemeConfiguration {
// Basic properties.
String style;
String preset;
String spacing_preset;
@ -66,6 +71,7 @@ class EditorThemeManager {
int corner_radius = 3;
bool draw_extra_borders = false;
int draw_relationship_lines;
float relationship_line_opacity = 1.0;
int thumb_size = 16;
int class_icon_size = 16;
@ -73,12 +79,18 @@ class EditorThemeManager {
float gizmo_handle_scale = 1.0;
int color_picker_button_height = 28;
float subresource_hue_tint = 0.0;
float dragging_hover_wait_msec = 0;
float default_contrast = 1.0;
// Make sure to keep those in sync with the definitions in the editor settings.
const float default_icon_saturation = 2.0;
const int default_relationship_lines = RELATIONSHIP_SELECTED_ONLY;
const float default_contrast = 0.3;
const int default_corner_radius = 4;
// Generated properties.
bool dark_theme = false;
bool dark_icon_and_font = false;
int base_margin = 4;
int increased_margin = 4;
@ -89,6 +101,8 @@ class EditorThemeManager {
int forced_even_separation = 0;
Color mono_color;
Color mono_color_icon_and_font;
Color mono_color_inv;
Color dark_color_1;
Color dark_color_2;
Color dark_color_3;
@ -103,6 +117,7 @@ class EditorThemeManager {
Color extra_border_color_2;
Color font_color;
Color font_secondary_color;
Color font_focus_color;
Color font_hover_color;
Color font_pressed_color;
@ -113,11 +128,28 @@ class EditorThemeManager {
Color font_outline_color;
Color icon_normal_color;
Color icon_secondary_color;
Color icon_focus_color;
Color icon_hover_color;
Color icon_pressed_color;
Color icon_disabled_color;
Color surface_lowest_color;
Color surface_lower_color;
Color surface_low_color;
Color surface_base_color;
Color surface_high_color;
Color surface_higher_color;
Color surface_highest_color;
Color button_normal_color;
Color button_hover_color;
Color button_pressed_color;
Color button_disabled_color;
Color button_border_normal_color;
Color button_border_hover_color;
Color button_border_pressed_color;
Color shadow_color;
Color selection_color;
Color disabled_border_color;
@ -125,7 +157,9 @@ class EditorThemeManager {
Color separator_color;
Ref<StyleBoxFlat> base_style;
Ref<StyleBoxFlat> focus_style;
Ref<StyleBoxEmpty> base_empty_style;
Ref<StyleBoxEmpty> base_empty_wide_style;
Ref<StyleBoxFlat> button_style;
Ref<StyleBoxFlat> button_style_disabled;
@ -133,11 +167,15 @@ class EditorThemeManager {
Ref<StyleBoxFlat> button_style_pressed;
Ref<StyleBoxFlat> button_style_hover;
Ref<StyleBoxFlat> circle_style_focus;
Ref<StyleBoxFlat> flat_button;
Ref<StyleBoxFlat> flat_button_pressed;
Ref<StyleBoxFlat> flat_button_hover;
Ref<StyleBoxFlat> popup_style;
Ref<StyleBoxFlat> popup_border_style;
Ref<StyleBoxFlat> popup_panel_style;
Ref<StyleBoxFlat> window_style;
Ref<StyleBoxFlat> window_complex_style;
Ref<StyleBoxFlat> dialog_style;
Ref<StyleBoxFlat> panel_container_style;
Ref<StyleBoxFlat> content_panel_style;
@ -150,23 +188,32 @@ class EditorThemeManager {
uint32_t hash_icons();
};
enum RelationshipLinesMode {
RELATIONSHIP_NONE,
RELATIONSHIP_SELECTED_ONLY,
RELATIONSHIP_ALL,
};
private:
static Ref<EditorTheme> _create_base_theme(const Ref<EditorTheme> &p_old_theme = nullptr);
static ThemeConfiguration _create_theme_config(const Ref<EditorTheme> &p_theme);
static void _create_shared_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_standard_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_editor_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_text_editor_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_visual_shader_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _reset_dirty_flag();
public:
static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, int p_corner_width = 0);
static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1);
static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true);
static Ref<StyleBoxLine> make_line_stylebox(Color p_color, int p_thickness = 1, float p_grow_begin = 1, float p_grow_end = 1, bool p_vertical = false);
static Ref<EditorTheme> generate_theme(const Ref<EditorTheme> &p_old_theme = nullptr);
static bool is_generated_theme_outdated();
static bool is_dark_theme();
static bool is_dark_icon_and_font();
static void initialize();
static void finalize();

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
/**************************************************************************/
/* theme_classic.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. */
/**************************************************************************/
#pragma once
#include "editor/themes/editor_theme_manager.h"
class ThemeClassic {
public:
static void populate_shared_styles(const Ref<EditorTheme> &p_theme, EditorThemeManager::ThemeConfiguration &p_config);
static void populate_standard_styles(const Ref<EditorTheme> &p_theme, EditorThemeManager::ThemeConfiguration &p_config);
static void populate_editor_styles(const Ref<EditorTheme> &p_theme, EditorThemeManager::ThemeConfiguration &p_config);
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
/**************************************************************************/
/* theme_modern.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. */
/**************************************************************************/
#pragma once
#include "editor/themes/editor_theme_manager.h"
class ThemeModern {
public:
static void populate_shared_styles(const Ref<EditorTheme> &p_theme, EditorThemeManager::ThemeConfiguration &p_config);
static void populate_standard_styles(const Ref<EditorTheme> &p_theme, EditorThemeManager::ThemeConfiguration &p_config);
static void populate_editor_styles(const Ref<EditorTheme> &p_theme, EditorThemeManager::ThemeConfiguration &p_config);
};