diff --git a/editor/icons/Camera3DDarkBackground.svg b/editor/icons/Camera3DDarkBackground.svg
new file mode 100644
index 00000000000..1f0e771a037
--- /dev/null
+++ b/editor/icons/Camera3DDarkBackground.svg
@@ -0,0 +1 @@
+
diff --git a/editor/icons/GuiTabMenuHlDarkBackground.svg b/editor/icons/GuiTabMenuHlDarkBackground.svg
new file mode 100644
index 00000000000..ab995aec2b8
--- /dev/null
+++ b/editor/icons/GuiTabMenuHlDarkBackground.svg
@@ -0,0 +1 @@
+
diff --git a/editor/scene/3d/node_3d_editor_plugin.cpp b/editor/scene/3d/node_3d_editor_plugin.cpp
index 858901d37b0..416b516d080 100644
--- a/editor/scene/3d/node_3d_editor_plugin.cpp
+++ b/editor/scene/3d/node_3d_editor_plugin.cpp
@@ -3135,6 +3135,16 @@ void Node3DEditorViewport::_project_settings_changed() {
viewport->set_anisotropic_filtering_level(anisotropic_filtering_level);
}
+static void override_label_colors(Control *p_control) {
+ p_control->begin_bulk_theme_override();
+ p_control->add_theme_color_override(SceneStringName(font_color), p_control->get_theme_color(SNAME("font_dark_background_color"), EditorStringName(Editor)));
+ p_control->add_theme_color_override("font_hover_color", p_control->get_theme_color(SNAME("font_dark_background_hover_color"), EditorStringName(Editor)));
+ p_control->add_theme_color_override("font_focus_color", p_control->get_theme_color(SNAME("font_dark_background_focus_color"), EditorStringName(Editor)));
+ p_control->add_theme_color_override("font_pressed_color", p_control->get_theme_color(SNAME("font_dark_background_pressed_color"), EditorStringName(Editor)));
+ p_control->add_theme_color_override("font_hover_pressed_color", p_control->get_theme_color(SNAME("font_dark_background_hover_pressed_color"), EditorStringName(Editor)));
+ p_control->end_bulk_theme_override();
+}
+
static void override_button_stylebox(Button *p_button, const Ref p_stylebox) {
p_button->begin_bulk_theme_override();
p_button->add_theme_style_override(CoreStringName(normal), p_stylebox);
@@ -3542,21 +3552,25 @@ void Node3DEditorViewport::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
_update_centered_labels();
- view_display_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
- preview_camera->set_button_icon(get_editor_theme_icon(SNAME("Camera3D")));
+ view_display_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHlDarkBackground")));
+ preview_camera->set_button_icon(get_editor_theme_icon(SNAME("Camera3DDarkBackground")));
Control *gui_base = EditorNode::get_singleton()->get_gui_base();
const Ref &information_3d_stylebox = gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles));
override_button_stylebox(view_display_menu, information_3d_stylebox);
+ override_label_colors(view_display_menu);
override_button_stylebox(translation_preview_button, information_3d_stylebox);
+ override_label_colors(translation_preview_button);
override_button_stylebox(preview_camera, information_3d_stylebox);
+ override_label_colors(preview_camera);
- frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
- frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
- frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color_dark_background"), EditorStringName(Editor)));
+ frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color_dark_background"), EditorStringName(Editor)));
+ frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color_dark_background"), EditorStringName(Editor)));
info_panel->add_theme_style_override(SceneStringName(panel), information_3d_stylebox);
+ override_label_colors(info_label);
frame_time_panel->add_theme_style_override(SceneStringName(panel), information_3d_stylebox);
// Set a minimum width to prevent the width from changing all the time
@@ -3614,7 +3628,7 @@ static void draw_indicator_bar(Control &p_surface, real_t p_fill, const Ref &p_theme, Edito
p_config.success_color = Color(0.45, 0.95, 0.5);
p_config.warning_color = Color(1, 0.87, 0.4);
p_config.error_color = Color(1, 0.47, 0.42);
+
+ // Keep dark theme colors accessible for use in the frame time gradient in the 3D editor.
+ // This frame time gradient is used to colorize text for a dark background, so it should keep using bright colors
+ // even when using a light theme.
+ p_theme->set_color("success_color_dark_background", EditorStringName(Editor), p_config.success_color);
+ p_theme->set_color("warning_color_dark_background", EditorStringName(Editor), p_config.warning_color);
+ p_theme->set_color("error_color_dark_background", EditorStringName(Editor), p_config.error_color);
+
if (!p_config.dark_icon_and_font) {
// Darken some colors to be readable on a light background.
p_config.success_color = p_config.success_color.lerp(p_config.mono_color_font, 0.35);
@@ -110,6 +118,22 @@ void ThemeClassic::populate_shared_styles(const Ref &p_theme, Edito
p_config.font_placeholder_color = Color(p_config.mono_color_font.r, p_config.mono_color_font.g, p_config.mono_color_font.b, 0.5);
p_config.font_outline_color = Color(0, 0, 0, 0);
+ // Colors designed for dark backgrounds, even when using a light theme.
+ // This is used for 3D editor overlay texts.
+ if (p_config.dark_theme) {
+ p_config.font_dark_background_color = p_config.font_color;
+ p_config.font_dark_background_focus_color = p_config.font_focus_color;
+ p_config.font_dark_background_hover_color = p_config.font_hover_color;
+ p_config.font_dark_background_pressed_color = p_config.font_pressed_color;
+ p_config.font_dark_background_hover_pressed_color = p_config.font_hover_pressed_color;
+ } else {
+ p_config.font_dark_background_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.75);
+ p_config.font_dark_background_focus_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.25);
+ p_config.font_dark_background_hover_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.25);
+ p_config.font_dark_background_pressed_color = p_config.font_dark_background_color.lerp(p_config.accent_color, 0.74);
+ p_config.font_dark_background_hover_pressed_color = p_config.font_dark_background_color.lerp(p_config.accent_color, 0.5);
+ }
+
p_theme->set_color(SceneStringName(font_color), EditorStringName(Editor), p_config.font_color);
p_theme->set_color("font_focus_color", EditorStringName(Editor), p_config.font_focus_color);
p_theme->set_color("font_hover_color", EditorStringName(Editor), p_config.font_hover_color);
@@ -119,6 +143,13 @@ void ThemeClassic::populate_shared_styles(const Ref &p_theme, Edito
p_theme->set_color("font_readonly_color", EditorStringName(Editor), p_config.font_readonly_color);
p_theme->set_color("font_placeholder_color", EditorStringName(Editor), p_config.font_placeholder_color);
p_theme->set_color("font_outline_color", EditorStringName(Editor), p_config.font_outline_color);
+
+ p_theme->set_color("font_dark_background_color", EditorStringName(Editor), p_config.font_dark_background_color);
+ p_theme->set_color("font_dark_background_focus_color", EditorStringName(Editor), p_config.font_dark_background_focus_color);
+ p_theme->set_color("font_dark_background_hover_color", EditorStringName(Editor), p_config.font_dark_background_hover_color);
+ p_theme->set_color("font_dark_background_pressed_color", EditorStringName(Editor), p_config.font_dark_background_pressed_color);
+ p_theme->set_color("font_dark_background_hover_pressed_color", EditorStringName(Editor), p_config.font_dark_background_hover_pressed_color);
+
#ifndef DISABLE_DEPRECATED // Used before 4.3.
p_theme->set_color("readonly_font_color", EditorStringName(Editor), p_config.font_readonly_color);
p_theme->set_color("disabled_font_color", EditorStringName(Editor), p_config.font_disabled_color);
@@ -1558,7 +1589,14 @@ void ThemeClassic::populate_editor_styles(const Ref &p_theme, Edito
// 3D/Spatial editor.
Ref style_info_3d_viewport = p_config.base_style->duplicate();
- style_info_3d_viewport->set_bg_color(style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5));
+ Color bg_color = style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5);
+ if (!p_config.dark_theme) {
+ // Always use a dark background for the 3D viewport, even in light themes.
+ // This is displayed as an overlay of the 3D scene, whose appearance doesn't change with the editor theme.
+ // On top of that, dark overlays are more readable than light overlays.
+ bg_color.invert();
+ }
+ style_info_3d_viewport->set_bg_color(bg_color);
style_info_3d_viewport->set_border_width_all(0);
p_theme->set_stylebox("Information3dViewport", EditorStringName(EditorStyles), style_info_3d_viewport);
diff --git a/editor/themes/theme_modern.cpp b/editor/themes/theme_modern.cpp
index f6f76c0a71c..4c2872ab1bf 100644
--- a/editor/themes/theme_modern.cpp
+++ b/editor/themes/theme_modern.cpp
@@ -79,6 +79,14 @@ void ThemeModern::populate_shared_styles(const Ref &p_theme, Editor
p_config.success_color = Color(0.45, 0.95, 0.5);
p_config.warning_color = Color(0.83, 0.78, 0.62);
p_config.error_color = Color(1, 0.47, 0.42);
+
+ // Keep dark theme colors accessible for use in the frame time gradient in the 3D editor.
+ // This frame time gradient is used to colorize text for a dark background, so it should keep using bright colors
+ // even when using a light theme.
+ p_theme->set_color("success_color_dark_background", EditorStringName(Editor), p_config.success_color);
+ p_theme->set_color("warning_color_dark_background", EditorStringName(Editor), p_config.warning_color);
+ p_theme->set_color("error_color_dark_background", EditorStringName(Editor), p_config.error_color);
+
if (!p_config.dark_icon_and_font) {
// Darken some colors to be readable on a light background.
p_config.success_color = p_config.success_color.lerp(p_config.mono_color_font, 0.35);
@@ -122,6 +130,22 @@ void ThemeModern::populate_shared_styles(const Ref &p_theme, Editor
p_config.font_placeholder_color = p_config.font_disabled_color;
p_config.font_outline_color = Color(1, 1, 1, 0);
+ // Colors designed for dark backgrounds, even when using a light theme.
+ // This is used for 3D editor overlay texts.
+ if (p_config.dark_theme) {
+ p_config.font_dark_background_color = p_config.font_color;
+ p_config.font_dark_background_focus_color = p_config.font_focus_color;
+ p_config.font_dark_background_hover_color = p_config.font_hover_color;
+ p_config.font_dark_background_pressed_color = p_config.font_pressed_color;
+ p_config.font_dark_background_hover_pressed_color = p_config.font_hover_pressed_color;
+ } else {
+ p_config.font_dark_background_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.75);
+ p_config.font_dark_background_focus_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.25);
+ p_config.font_dark_background_hover_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.25);
+ p_config.font_dark_background_pressed_color = p_config.font_dark_background_color.lerp(p_config.accent_color, 0.74);
+ p_config.font_dark_background_hover_pressed_color = p_config.font_dark_background_color.lerp(p_config.accent_color, 0.5);
+ }
+
p_theme->set_color(SceneStringName(font_color), EditorStringName(Editor), p_config.font_color);
p_theme->set_color("font_focus_color", EditorStringName(Editor), p_config.font_focus_color);
p_theme->set_color("font_hover_color", EditorStringName(Editor), p_config.font_hover_color);
@@ -131,6 +155,13 @@ void ThemeModern::populate_shared_styles(const Ref &p_theme, Editor
p_theme->set_color("font_readonly_color", EditorStringName(Editor), p_config.font_readonly_color);
p_theme->set_color("font_placeholder_color", EditorStringName(Editor), p_config.font_placeholder_color);
p_theme->set_color("font_outline_color", EditorStringName(Editor), p_config.font_outline_color);
+
+ p_theme->set_color("font_dark_background_color", EditorStringName(Editor), p_config.font_dark_background_color);
+ p_theme->set_color("font_dark_background_focus_color", EditorStringName(Editor), p_config.font_dark_background_focus_color);
+ p_theme->set_color("font_dark_background_hover_color", EditorStringName(Editor), p_config.font_dark_background_hover_color);
+ p_theme->set_color("font_dark_background_pressed_color", EditorStringName(Editor), p_config.font_dark_background_pressed_color);
+ p_theme->set_color("font_dark_background_hover_pressed_color", EditorStringName(Editor), p_config.font_dark_background_hover_pressed_color);
+
#ifndef DISABLE_DEPRECATED // Used before 4.3.
p_theme->set_color("readonly_font_color", EditorStringName(Editor), p_config.font_readonly_color);
p_theme->set_color("disabled_font_color", EditorStringName(Editor), p_config.font_disabled_color);
@@ -1552,7 +1583,14 @@ void ThemeModern::populate_editor_styles(const Ref &p_theme, Editor
// 3D/Spatial editor.
Ref style_info_3d_viewport = p_config.base_style->duplicate();
- style_info_3d_viewport->set_bg_color(p_config.dark_color_2);
+ Color bg_color = style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5);
+ if (!p_config.dark_theme) {
+ // Always use a dark background for the 3D viewport, even in light themes.
+ // This is displayed as an overlay of the 3D scene, whose appearance doesn't change with the editor theme.
+ // On top of that, dark overlays are more readable than light overlays.
+ bg_color.invert();
+ }
+ style_info_3d_viewport->set_bg_color(bg_color);
style_info_3d_viewport->set_content_margin_individual(p_config.base_margin * 2 * EDSCALE, p_config.base_margin * 1.5 * EDSCALE, p_config.base_margin * 2 * EDSCALE, p_config.base_margin * 1.5 * EDSCALE);
p_theme->set_stylebox("Information3dViewport", EditorStringName(EditorStyles), style_info_3d_viewport);