diff options
Diffstat (limited to 'editor/editor_themes.cpp')
-rw-r--r-- | editor/editor_themes.cpp | 1138 |
1 files changed, 674 insertions, 464 deletions
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 4bd4e073d7..17b5eb3314 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -32,7 +32,6 @@ #include "core/error/error_macros.h" #include "core/io/resource_loader.h" -#include "core/variant/dictionary.h" #include "editor/editor_fonts.h" #include "editor/editor_icons.gen.h" #include "editor/editor_scale.h" @@ -43,27 +42,169 @@ #include "modules/svg/image_loader_svg.h" #endif +HashMap<Color, Color> EditorColorMap::color_conversion_map; +HashSet<StringName> EditorColorMap::color_conversion_exceptions; + +void EditorColorMap::add_conversion_color_pair(const String p_from_color, const String p_to_color) { + color_conversion_map[Color::html(p_from_color)] = Color::html(p_to_color); +} + +void EditorColorMap::add_conversion_exception(const StringName p_icon_name) { + color_conversion_exceptions.insert(p_icon_name); +} + +void EditorColorMap::create() { + // Some of the colors below are listed for completeness sake. + // This can be a basis for proper palette validation later. + + // Convert: FROM TO + add_conversion_color_pair("#478cbf", "#478cbf"); // Godot Blue + add_conversion_color_pair("#414042", "#414042"); // Godot Gray + + add_conversion_color_pair("#ffffff", "#414141"); // Pure white + add_conversion_color_pair("#000000", "#bfbfbf"); // Pure black + // Keep pure RGB colors as is, but list them for explicitly. + add_conversion_color_pair("#ff0000", "#ff0000"); // Pure red + add_conversion_color_pair("#00ff00", "#00ff00"); // Pure green + add_conversion_color_pair("#0000ff", "#0000ff"); // Pure blue + + // GUI Colors + add_conversion_color_pair("#e0e0e0", "#5a5a5a"); // Common icon color + add_conversion_color_pair("#fefefe", "#fefefe"); // Forced light color + add_conversion_color_pair("#808080", "#808080"); // GUI disabled color + add_conversion_color_pair("#b3b3b3", "#363636"); // GUI disabled light color + add_conversion_color_pair("#699ce8", "#699ce8"); // GUI highlight color + add_conversion_color_pair("#f9f9f9", "#606060"); // Scrollbar grabber highlight color + + add_conversion_color_pair("#c38ef1", "#a85de9"); // Animation + add_conversion_color_pair("#fc7f7f", "#cd3838"); // Spatial + add_conversion_color_pair("#8da5f3", "#3d64dd"); // 2D + add_conversion_color_pair("#4b70ea", "#1a3eac"); // 2D Dark + add_conversion_color_pair("#8eef97", "#2fa139"); // Control + + add_conversion_color_pair("#5fb2ff", "#0079f0"); // Selection (blue) + add_conversion_color_pair("#003e7a", "#2b74bb"); // Selection (darker blue) + add_conversion_color_pair("#f7f5cf", "#615f3a"); // Gizmo (yellow) + + // Rainbow + add_conversion_color_pair("#ff4545", "#ff2929"); // Red + add_conversion_color_pair("#ffe345", "#ffe337"); // Yellow + add_conversion_color_pair("#80ff45", "#74ff34"); // Green + add_conversion_color_pair("#45ffa2", "#2cff98"); // Aqua + add_conversion_color_pair("#45d7ff", "#22ccff"); // Blue + add_conversion_color_pair("#8045ff", "#702aff"); // Purple + add_conversion_color_pair("#ff4596", "#ff2781"); // Pink + + // Audio gradients + add_conversion_color_pair("#e1da5b", "#d6cf4b"); // Yellow + + add_conversion_color_pair("#62aeff", "#1678e0"); // Frozen gradient top + add_conversion_color_pair("#75d1e6", "#41acc5"); // Frozen gradient middle + add_conversion_color_pair("#84ffee", "#49ccba"); // Frozen gradient bottom + + add_conversion_color_pair("#f70000", "#c91616"); // Color track red + add_conversion_color_pair("#eec315", "#d58c0b"); // Color track orange + add_conversion_color_pair("#dbee15", "#b7d10a"); // Color track yellow + add_conversion_color_pair("#288027", "#218309"); // Color track green + + // Resource groups + add_conversion_color_pair("#ffca5f", "#fea900"); // Mesh resource (orange) + add_conversion_color_pair("#2998ff", "#68b6ff"); // Shape resource (blue) + add_conversion_color_pair("#a2d2ff", "#4998e3"); // Shape resource (light blue) + + // Animation editor tracks + // The property track icon color is set by the common icon color. + add_conversion_color_pair("#ea7940", "#bd5e2c"); // 3D Position track + add_conversion_color_pair("#ff2b88", "#bd165f"); // 3D Rotation track + add_conversion_color_pair("#eac840", "#bd9d1f"); // 3D Scale track + add_conversion_color_pair("#3cf34e", "#16a827"); // Call Method track + add_conversion_color_pair("#2877f6", "#236be6"); // Bezier Curve track + add_conversion_color_pair("#eae440", "#9f9722"); // Audio Playback track + add_conversion_color_pair("#a448f0", "#9853ce"); // Animation Playback track + add_conversion_color_pair("#5ad5c4", "#0a9c88"); // Blend Shape track + + // Control layouts + add_conversion_color_pair("#d6d6d6", "#474747"); // Highlighted part + add_conversion_color_pair("#474747", "#d6d6d6"); // Background part + add_conversion_color_pair("#919191", "#6e6e6e"); // Border part + + // TileSet editor icons + add_conversion_color_pair("#fce00e", "#aa8d24"); // New Single Tile + add_conversion_color_pair("#0e71fc", "#0350bd"); // New Autotile + add_conversion_color_pair("#c6ced4", "#828f9b"); // New Atlas + + // Visual script + add_conversion_color_pair("#41ecad", "#25e3a0"); // VisualScript variant + add_conversion_color_pair("#6f91f0", "#6d8eeb"); // VisualScript bool + add_conversion_color_pair("#5abbef", "#4fb2e9"); // VisualScript int + add_conversion_color_pair("#35d4f4", "#27ccf0"); // VisualScript float + add_conversion_color_pair("#4593ec", "#4690e7"); // VisualScript String + add_conversion_color_pair("#ac73f1", "#ad76ee"); // VisualScript Vector2 + add_conversion_color_pair("#f1738f", "#ee758e"); // VisualScript Rect2 + add_conversion_color_pair("#de66f0", "#dc6aed"); // VisualScript Vector3 + add_conversion_color_pair("#b9ec41", "#96ce1a"); // VisualScript Transform2D + add_conversion_color_pair("#f74949", "#f77070"); // VisualScript Plane + add_conversion_color_pair("#ec418e", "#ec69a3"); // VisualScript Quat + add_conversion_color_pair("#ee5677", "#ee7991"); // VisualScript AABB + add_conversion_color_pair("#e1ec41", "#b2bb19"); // VisualScript Basis + add_conversion_color_pair("#f68f45", "#f49047"); // VisualScript Transform + add_conversion_color_pair("#417aec", "#6993ec"); // VisualScript NodePath + add_conversion_color_pair("#41ec80", "#2ce573"); // VisualScript RID + add_conversion_color_pair("#55f3e3", "#12d5c3"); // VisualScript Object + add_conversion_color_pair("#54ed9e", "#57e99f"); // VisualScript Dictionary + // Visual shaders + add_conversion_color_pair("#77ce57", "#67c046"); // Vector funcs + add_conversion_color_pair("#ea686c", "#d95256"); // Vector transforms + add_conversion_color_pair("#eac968", "#d9b64f"); // Textures and cubemaps + add_conversion_color_pair("#cf68ea", "#c050dd"); // Functions and expressions + + // These icons should not be converted. + add_conversion_exception("EditorPivot"); + add_conversion_exception("EditorHandle"); + add_conversion_exception("Editor3DHandle"); + add_conversion_exception("EditorBoneHandle"); + add_conversion_exception("Godot"); + add_conversion_exception("Sky"); + add_conversion_exception("EditorControlAnchor"); + add_conversion_exception("DefaultProjectIcon"); + add_conversion_exception("GuiChecked"); + add_conversion_exception("GuiRadioChecked"); + add_conversion_exception("GuiIndeterminate"); + add_conversion_exception("GuiCloseCustomizable"); + add_conversion_exception("GuiGraphNodePort"); + add_conversion_exception("GuiResizer"); + add_conversion_exception("ZoomMore"); + add_conversion_exception("ZoomLess"); + add_conversion_exception("ZoomReset"); + add_conversion_exception("LockViewport"); + add_conversion_exception("GroupViewport"); + add_conversion_exception("StatusError"); + add_conversion_exception("StatusSuccess"); + add_conversion_exception("StatusWarning"); + add_conversion_exception("OverbrightIndicator"); + add_conversion_exception("GuiMiniCheckerboard"); + + /// Code Editor. + add_conversion_exception("GuiTab"); + add_conversion_exception("GuiSpace"); + add_conversion_exception("CodeFoldedRightArrow"); + add_conversion_exception("CodeFoldDownArrow"); + add_conversion_exception("TextEditorPlay"); + add_conversion_exception("Breakpoint"); +} + 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) { Ref<StyleBoxTexture> style(memnew(StyleBoxTexture)); style->set_texture(p_texture); - style->set_margin_size(SIDE_LEFT, p_left * EDSCALE); - style->set_margin_size(SIDE_RIGHT, p_right * EDSCALE); - style->set_margin_size(SIDE_BOTTOM, p_bottom * EDSCALE); - style->set_margin_size(SIDE_TOP, p_top * EDSCALE); - style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); - style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); - style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE); - style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE); + style->set_margin_size_individual(p_left * EDSCALE, p_top * EDSCALE, p_right * EDSCALE, p_bottom * EDSCALE); + style->set_default_margin_individual(p_margin_left * EDSCALE, p_margin_top * EDSCALE, p_margin_right * EDSCALE, p_margin_bottom * EDSCALE); style->set_draw_center(p_draw_center); return style; } 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) { Ref<StyleBoxEmpty> style(memnew(StyleBoxEmpty)); - style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); - style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); - style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE); - style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE); + style->set_default_margin_individual(p_margin_left * EDSCALE, p_margin_top * EDSCALE, p_margin_right * EDSCALE, p_margin_bottom * EDSCALE); return style; } @@ -71,12 +212,11 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); style->set_bg_color(p_color); // Adjust level of detail based on the corners' effective sizes. - style->set_corner_detail(Math::ceil(1.5 * p_corner_width * EDSCALE)); - style->set_corner_radius_all(p_corner_width); - style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); - style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); - style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE); - style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE); + style->set_corner_detail(Math::ceil(0.8 * p_corner_width * EDSCALE)); + style->set_corner_radius_all(p_corner_width * EDSCALE); + style->set_default_margin_individual(p_margin_left * EDSCALE, p_margin_top * EDSCALE, p_margin_right * EDSCALE, p_margin_bottom * EDSCALE); + // Work around issue about antialiased edges being blurrier (GH-35279). + style->set_anti_aliased(false); return style; } @@ -90,31 +230,9 @@ static Ref<StyleBoxLine> make_line_stylebox(Color p_color, int p_thickness = 1, return style; } -static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, bool p_flip_x = false) { - if (!p_flip_y && !p_flip_x) { - return p_texture; - } - - Ref<ImageTexture> texture(memnew(ImageTexture)); - Ref<Image> img = p_texture->get_image(); - ERR_FAIL_NULL_V(img, Ref<Texture2D>()); - img = img->duplicate(); - - if (p_flip_y) { - img->flip_y(); - } - if (p_flip_x) { - img->flip_x(); - } - - texture->create_from_image(img); - return texture; -} - #ifdef MODULE_SVG_ENABLED // See also `generate_icon()` in `scene/resources/default_theme.cpp`. -static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0, Dictionary p_convert_colors = Dictionary()) { - Ref<ImageTexture> icon = memnew(ImageTexture); +static Ref<ImageTexture> editor_generate_icon(int p_index, float p_scale, float p_saturation, const HashMap<Color, Color> &p_convert_colors = HashMap<Color, Color>()) { Ref<Image> img = memnew(Image); // Upsample icon generation only if the editor scale isn't an integer multiplier. @@ -122,180 +240,61 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, // with integer editor scales. const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale); ImageLoaderSVG img_loader; - img_loader.set_replace_colors(p_convert_colors); - img_loader.create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color); + img_loader.create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_colors); if (p_saturation != 1.0) { img->adjust_bcs(1.0, 1.0, p_saturation); } - icon->create_from_image(img); // in this case filter really helps - return icon; + return ImageTexture::create_from_image(img); } #endif -#ifndef ADD_CONVERT_COLOR -#define ADD_CONVERT_COLOR(dictionary, old_color, new_color) dictionary[Color::html(old_color)] = Color::html(new_color) -#endif - -void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false, float p_icon_saturation = 1.0) { +void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, float p_icon_saturation, int p_thumb_size, bool p_only_thumbs = false) { #ifdef MODULE_SVG_ENABLED - // The default icon theme is designed to be used for a dark theme. - // This dictionary stores Color values to convert to other colors - // for better readability on a light theme. - // Godot Color values are used to avoid the ambiguity of strings - // (where "#ffffff", "fff", and "white" are all equivalent). - Dictionary dark_icon_color_dictionary; - - // The names of the icons to never convert, even if one of their colors - // are contained in the dictionary above. - Set<StringName> exceptions; - - // Some of the colors below are listed for completeness sake. - // This can be a basis for proper palette validation later. + // Before we register the icons, we adjust their colors and saturation. + // Most icons follow the standard rules for color conversion to follow the editor + // theme's polarity (dark/light). We also adjust the saturation for most icons, + // following the editor setting. + // Some icons are excluded from this conversion, and instead use the configured + // accent color to replace their innate accent color to match the editor theme. + // And then some icons are completely excluded from the conversion. + + // Standard color conversion map. + HashMap<Color, Color> color_conversion_map; + // Icons by default are set up for the dark theme, so if the theme is light, + // we apply the dark-to-light color conversion map. if (!p_dark_theme) { - // Convert color: FROM TO - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#478cbf", "#478cbf"); // Godot Blue - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#414042", "#414042"); // Godot Gray - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#414141"); // Pure white - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#000000", "#bfbfbf"); // Pure black - // Keep pure RGB colors as is, but list them for explicitly. - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff0000", "#ff0000"); // Pure red - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#00ff00", "#00ff00"); // Pure green - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#0000ff", "#0000ff"); // Pure blue - - // GUI Colors - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#5a5a5a"); // Common icon color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fefefe", "#fefefe"); // Forced light color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#808080", "#808080"); // GUI disabled color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b3b3b3", "#363636"); // GUI disabled light color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#699ce8", "#699ce8"); // GUI highlight color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f9f9f9", "#606060"); // Scrollbar grabber highlight color - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c38ef1", "#a85de9"); // Animation - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc7f7f", "#cd3838"); // Spatial - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8da5f3", "#3d64dd"); // 2D - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#4b70ea", "#1a3eac"); // 2D Dark - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8eef97", "#2fa139"); // Control - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fb2ff", "#0079f0"); // Selection (blue) - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#003e7a", "#2b74bb"); // Selection (darker blue) - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f7f5cf", "#615f3a"); // Gizmo (yellow) - - // Rainbow - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff4545", "#ff2929"); // Red - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffe345", "#ffe337"); // Yellow - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#80ff45", "#74ff34"); // Green - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#45ffa2", "#2cff98"); // Aqua - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#45d7ff", "#22ccff"); // Blue - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8045ff", "#702aff"); // Purple - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff4596", "#ff2781"); // Pink - - // Audio gradients - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1da5b", "#d6cf4b"); // Yellow - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#62aeff", "#1678e0"); // Frozen gradient top - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#75d1e6", "#41acc5"); // Frozen gradient middle - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffee", "#49ccba"); // Frozen gradient bottom - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f70000", "#c91616"); // Color track red - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eec315", "#d58c0b"); // Color track orange - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#dbee15", "#b7d10a"); // Color track yellow - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#288027", "#218309"); // Color track green - - // Resource groups - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffca5f", "#fea900"); // Mesh resource (orange) - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#2998ff", "#68b6ff"); // Shape resource (blue) - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a2d2ff", "#4998e3"); // Shape resource (light blue) - - // Animation editor tracks - // The property track icon color is set by the common icon color. - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea7940", "#bd5e2c"); // 3D Position track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff2b88", "#bd165f"); // 3D Rotation track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eac840", "#bd9d1f"); // 3D Scale track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#3cf34e", "#16a827"); // Call Method track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#2877f6", "#236be6"); // Bezier Curve track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eae440", "#9f9722"); // Audio Playback track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a448f0", "#9853ce"); // Animation Playback track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5ad5c4", "#0a9c88"); // Blend Shape track - - // Control layouts - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#d6d6d6", "#474747"); // Highlighted part - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#474747", "#d6d6d6"); // Background part - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#919191", "#6e6e6e"); // Border part - - // TileSet editor icons - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fce00e", "#aa8d24"); // New Single Tile - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#0e71fc", "#0350bd"); // New Autotile - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c6ced4", "#828f9b"); // New Atlas - - // Visual script - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#41ecad", "#25e3a0"); // VisualScript variant - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#6f91f0", "#6d8eeb"); // VisualScript bool - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5abbef", "#4fb2e9"); // VisualScript int - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#35d4f4", "#27ccf0"); // VisualScript float - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#4593ec", "#4690e7"); // VisualScript String - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ac73f1", "#ad76ee"); // VisualScript Vector2 - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f1738f", "#ee758e"); // VisualScript Rect2 - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#de66f0", "#dc6aed"); // VisualScript Vector3 - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b9ec41", "#96ce1a"); // VisualScript Transform2D - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f74949", "#f77070"); // VisualScript Plane - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ec418e", "#ec69a3"); // VisualScript Quat - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ee5677", "#ee7991"); // VisualScript AABB - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1ec41", "#b2bb19"); // VisualScript Basis - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f68f45", "#f49047"); // VisualScript Transform - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#417aec", "#6993ec"); // VisualScript NodePath - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#41ec80", "#2ce573"); // VisualScript RID - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#55f3e3", "#12d5c3"); // VisualScript Object - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#54ed9e", "#57e99f"); // VisualScript Dictionary - // Visual shaders - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#77ce57", "#67c046"); // Vector funcs - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea686c", "#d95256"); // Vector transforms - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eac968", "#d9b64f"); // Textures and cubemaps - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cf68ea", "#c050dd"); // Functions and expressions - - exceptions.insert("EditorPivot"); - exceptions.insert("EditorHandle"); - exceptions.insert("Editor3DHandle"); - exceptions.insert("EditorBoneHandle"); - exceptions.insert("Godot"); - exceptions.insert("Sky"); - exceptions.insert("EditorControlAnchor"); - exceptions.insert("DefaultProjectIcon"); - exceptions.insert("GuiChecked"); - exceptions.insert("GuiRadioChecked"); - exceptions.insert("GuiIndeterminate"); - exceptions.insert("GuiCloseCustomizable"); - exceptions.insert("GuiGraphNodePort"); - exceptions.insert("GuiResizer"); - exceptions.insert("ZoomMore"); - exceptions.insert("ZoomLess"); - exceptions.insert("ZoomReset"); - exceptions.insert("LockViewport"); - exceptions.insert("GroupViewport"); - exceptions.insert("StatusError"); - exceptions.insert("StatusSuccess"); - exceptions.insert("StatusWarning"); - exceptions.insert("OverbrightIndicator"); - exceptions.insert("GuiMiniCheckerboard"); + for (KeyValue<Color, Color> &E : EditorColorMap::get_color_conversion_map()) { + color_conversion_map[E.key] = E.value; + } } - - // These ones should be converted even if we are using a dark theme. + // These colors should be converted even if we are using a dark theme. const Color error_color = p_theme->get_color(SNAME("error_color"), SNAME("Editor")); const Color success_color = p_theme->get_color(SNAME("success_color"), SNAME("Editor")); const Color warning_color = p_theme->get_color(SNAME("warning_color"), SNAME("Editor")); - dark_icon_color_dictionary[Color::html("#ff5f5f")] = error_color; - dark_icon_color_dictionary[Color::html("#5fff97")] = success_color; - dark_icon_color_dictionary[Color::html("#ffdd65")] = warning_color; + color_conversion_map[Color::html("#ff5f5f")] = error_color; + color_conversion_map[Color::html("#5fff97")] = success_color; + color_conversion_map[Color::html("#ffdd65")] = warning_color; + + // The names of the icons to exclude from the standard color conversion. + HashSet<StringName> conversion_exceptions = EditorColorMap::get_color_conversion_exceptions(); + + // The names of the icons to exclude when adjusting for saturation. + HashSet<StringName> saturation_exceptions; + saturation_exceptions.insert("DefaultProjectIcon"); + saturation_exceptions.insert("Godot"); + saturation_exceptions.insert("Logo"); - // Use the accent color for some icons (checkbox, radio, toggle, etc.). - Dictionary accent_color_icon_color_dictionary; - Set<StringName> accent_color_icons; + // Accent color conversion map. + // It is used on some icons (checkbox, radio, toggle, etc.), regardless of the dark + // or light mode. + HashMap<Color, Color> accent_color_map; + HashSet<StringName> accent_color_icons; const Color accent_color = p_theme->get_color(SNAME("accent_color"), SNAME("Editor")); - accent_color_icon_color_dictionary[Color::html("699ce8")] = accent_color; + accent_color_map[Color::html("699ce8")] = accent_color; if (accent_color.get_luminance() > 0.75) { - accent_color_icon_color_dictionary[Color::html("ffffff")] = Color(0.2, 0.2, 0.2); + accent_color_map[Color::html("ffffff")] = Color(0.2, 0.2, 0.2); } accent_color_icons.insert("GuiChecked"); @@ -311,16 +310,18 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = Ref<ImageTexture> icon; if (accent_color_icons.has(editor_icons_names[i])) { - icon = editor_generate_icon(i, true, EDSCALE, 1.0, accent_color_icon_color_dictionary); + icon = editor_generate_icon(i, EDSCALE, 1.0, accent_color_map); } else { float saturation = p_icon_saturation; - - if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0 || strcmp(editor_icons_names[i], "Godot") == 0 || strcmp(editor_icons_names[i], "Logo") == 0) { + if (saturation_exceptions.has(editor_icons_names[i])) { saturation = 1.0; } - const int is_exception = exceptions.has(editor_icons_names[i]); - icon = editor_generate_icon(i, !is_exception, EDSCALE, saturation, dark_icon_color_dictionary); + if (conversion_exceptions.has(editor_icons_names[i])) { + icon = editor_generate_icon(i, EDSCALE, saturation); + } else { + icon = editor_generate_icon(i, EDSCALE, saturation, color_conversion_map); + } } p_theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), icon); @@ -328,14 +329,27 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = } // Generate thumbnail icons with the given thumbnail size. - // We don't need filtering when generating at one of the default resolutions. - const bool force_filter = p_thumb_size != 64 && p_thumb_size != 32; + // See editor\icons\editor_icons_builders.py for the code that determines which icons are thumbnails. if (p_thumb_size >= 64) { const float scale = (float)p_thumb_size / 64.0 * EDSCALE; for (int i = 0; i < editor_bg_thumbs_count; i++) { const int index = editor_bg_thumbs_indices[i]; - const int is_exception = exceptions.has(editor_icons_names[index]); - const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter, dark_icon_color_dictionary); + Ref<ImageTexture> icon; + + if (accent_color_icons.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, 1.0, accent_color_map); + } else { + float saturation = p_icon_saturation; + if (saturation_exceptions.has(editor_icons_names[index])) { + saturation = 1.0; + } + + if (conversion_exceptions.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, saturation); + } else { + icon = editor_generate_icon(index, scale, saturation, color_conversion_map); + } + } p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon); } @@ -343,8 +357,22 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = const float scale = (float)p_thumb_size / 32.0 * EDSCALE; for (int i = 0; i < editor_md_thumbs_count; i++) { const int index = editor_md_thumbs_indices[i]; - const bool is_exception = exceptions.has(editor_icons_names[index]); - const Ref<ImageTexture> icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter, dark_icon_color_dictionary); + Ref<ImageTexture> icon; + + if (accent_color_icons.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, 1.0, accent_color_map); + } else { + float saturation = p_icon_saturation; + if (saturation_exceptions.has(editor_icons_names[index])) { + saturation = 1.0; + } + + if (conversion_exceptions.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, saturation); + } else { + icon = editor_generate_icon(index, scale, saturation, color_conversion_map); + } + } p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon); } @@ -393,8 +421,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { preset_accent_color = Color(0.53, 0.67, 0.89); preset_base_color = Color(0.24, 0.23, 0.27); preset_contrast = default_contrast; - } else if (preset == "Grey") { - preset_accent_color = Color(0.72, 0.89, 1.00); + } else if (preset == "Gray") { + preset_accent_color = Color(0.44, 0.73, 0.98); preset_base_color = Color(0.24, 0.24, 0.24); preset_contrast = default_contrast; } else if (preset == "Light") { @@ -434,6 +462,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Colors bool dark_theme = EditorSettings::get_singleton()->is_dark_theme(); +#ifdef MODULE_SVG_ENABLED + if (dark_theme) { + ImageLoaderSVG::set_forced_color_map(HashMap<Color, Color>()); + } else { + ImageLoaderSVG::set_forced_color_map(EditorColorMap::get_color_conversion_map()); + } +#endif + // Ensure base colors are in the 0..1 luminance range to avoid 8-bit integer overflow or text rendering issues. // Some places in the editor use 8-bit integer colors. const Color dark_color_1 = base_color.lerp(Color(0, 0, 0, 1), contrast).clamp(); @@ -451,6 +487,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color font_color = mono_color.lerp(base_color, 0.25); const Color font_hover_color = mono_color.lerp(base_color, 0.125); const Color font_focus_color = mono_color.lerp(base_color, 0.125); + const Color font_hover_pressed_color = font_hover_color.lerp(accent_color, 0.74); const Color font_disabled_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.3); const Color font_readonly_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.65); const Color font_placeholder_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.6); @@ -462,6 +499,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color icon_hover_color = icon_normal_color * (dark_theme ? 1.15 : 1.45); icon_hover_color.a = 1.0; Color icon_focus_color = icon_hover_color; + Color icon_disabled_color = Color(icon_normal_color, 0.4); // Make the pressed icon 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. Color icon_pressed_color = accent_color * (dark_theme ? 1.15 : 3.5); @@ -471,9 +509,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color highlight_color = Color(accent_color.r, accent_color.g, accent_color.b, 0.275); const Color disabled_highlight_color = highlight_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); - float prev_icon_saturation = theme->has_color(SNAME("icon_saturation"), SNAME("Editor")) ? theme->get_color(SNAME("icon_saturation"), SNAME("Editor")).r : 1.0; - - theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); // can't save single float in theme, so using color + // Can't save single float in theme, so using Color. + theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); theme->set_color("accent_color", "Editor", accent_color); theme->set_color("highlight_color", "Editor", highlight_color); theme->set_color("disabled_highlight_color", "Editor", disabled_highlight_color); @@ -489,6 +526,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("axis_x_color", "Editor", Color(0.96, 0.20, 0.32)); theme->set_color("axis_y_color", "Editor", Color(0.53, 0.84, 0.01)); theme->set_color("axis_z_color", "Editor", Color(0.16, 0.55, 0.96)); + theme->set_color("axis_w_color", "Editor", Color(0.55, 0.55, 0.55)); const float prop_color_saturation = accent_color.get_s() * 0.75; const float prop_color_value = accent_color.get_v(); @@ -509,11 +547,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color warning_color = Color(1, 0.87, 0.4); Color error_color = Color(1, 0.47, 0.42); Color property_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.5); - Color readonly_color = property_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); - Color readonly_warning_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); + Color readonly_color = property_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.25); + Color readonly_warning_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.25); if (!dark_theme) { - // Darken some colors to be readable on a light background + // Darken some colors to be readable on a light background. success_color = success_color.lerp(mono_color, 0.35); warning_color = warning_color.lerp(mono_color, 0.35); error_color = error_color.lerp(mono_color, 0.25); @@ -526,31 +564,53 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("readonly_color", "Editor", readonly_color); if (!dark_theme) { - theme->set_color("vulkan_color", "Editor", Color::hex(0xad1128ff)); + theme->set_color("highend_color", "Editor", Color::hex(0xad1128ff)); } else { - theme->set_color("vulkan_color", "Editor", Color(1.0, 0.0, 0.0)); + theme->set_color("highend_color", "Editor", Color(1.0, 0.0, 0.0)); } const int thumb_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); theme->set_constant("scale", "Editor", EDSCALE); theme->set_constant("thumb_size", "Editor", thumb_size); theme->set_constant("dark_theme", "Editor", dark_theme); + theme->set_constant("color_picker_button_height", "Editor", 28 * EDSCALE); + + // Register editor icons. + // If the settings are comparable to the old theme, then just copy them over. + // Otherwise, regenerate them. Also check if we need to regenerate "thumb" icons. + bool keep_old_icons = false; + bool regenerate_thumb_icons = true; + if (p_theme != nullptr) { + // We check editor scale, theme dark/light mode, icon saturation, and accent color. + + // That doesn't really work as expected, since theme constants are integers, and scales are floats. + // So this check will never work when changing between 100-199% values. + const float prev_scale = (float)p_theme->get_constant(SNAME("scale"), SNAME("Editor")); + const bool prev_dark_theme = (bool)p_theme->get_constant(SNAME("dark_theme"), SNAME("Editor")); + const Color prev_accent_color = p_theme->get_color(SNAME("accent_color"), SNAME("Editor")); + const float prev_icon_saturation = p_theme->get_color(SNAME("icon_saturation"), SNAME("Editor")).r; + + keep_old_icons = (Math::is_equal_approx(prev_scale, EDSCALE) && + prev_dark_theme == dark_theme && + prev_accent_color == accent_color && + prev_icon_saturation == icon_saturation); + + const double prev_thumb_size = (double)p_theme->get_constant(SNAME("thumb_size"), SNAME("Editor")); + + regenerate_thumb_icons = !Math::is_equal_approx(prev_thumb_size, thumb_size); + } - // Register icons + font - - // The editor scale, icon color (dark_theme bool), icon saturation, and accent color has not changed, so we do not regenerate the icons. - if (p_theme != nullptr && fabs(p_theme->get_constant(SNAME("scale"), SNAME("Editor")) - EDSCALE) < 0.00001 && (bool)p_theme->get_constant(SNAME("dark_theme"), SNAME("Editor")) == dark_theme && prev_icon_saturation == icon_saturation && p_theme->get_color(SNAME("accent_color"), SNAME("Editor")) == accent_color) { - // Register already generated icons. + if (keep_old_icons) { for (int i = 0; i < editor_icons_count; i++) { theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), p_theme->get_icon(editor_icons_names[i], SNAME("EditorIcons"))); } } else { - editor_register_and_generate_icons(theme, dark_theme, thumb_size, false, icon_saturation); + editor_register_and_generate_icons(theme, dark_theme, icon_saturation, thumb_size, false); } - // Thumbnail size has changed, so we regenerate the medium sizes - if (p_theme != nullptr && fabs((double)p_theme->get_constant(SNAME("thumb_size"), SNAME("Editor")) - thumb_size) > 0.00001) { - editor_register_and_generate_icons(p_theme, dark_theme, thumb_size, true); + if (regenerate_thumb_icons) { + editor_register_and_generate_icons(theme, dark_theme, icon_saturation, thumb_size, true); } + // Register editor fonts. editor_register_fonts(theme); // Ensure borders are visible when using an editor scale below 100%. @@ -562,11 +622,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Styleboxes // This is the most commonly used stylebox, variations should be made as duplicate of this Ref<StyleBoxFlat> style_default = make_flat_stylebox(base_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size, corner_width); - // Work around issue about antialiased edges being blurrier (GH-35279). - style_default->set_anti_aliased(false); style_default->set_border_width_all(border_width); style_default->set_border_color(base_color); - style_default->set_draw_center(true); // Button and widgets const float extra_spacing = EDITOR_GET("interface/theme/additional_spacing"); @@ -574,10 +631,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Vector2 widget_default_margin = Vector2(extra_spacing + 6, extra_spacing + default_margin_size + 1) * EDSCALE; Ref<StyleBoxFlat> style_widget = style_default->duplicate(); - style_widget->set_default_margin(SIDE_LEFT, widget_default_margin.x); - style_widget->set_default_margin(SIDE_TOP, widget_default_margin.y); - style_widget->set_default_margin(SIDE_RIGHT, widget_default_margin.x); - style_widget->set_default_margin(SIDE_BOTTOM, widget_default_margin.y); + style_widget->set_default_margin_individual(widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y); style_widget->set_bg_color(dark_color_1); style_widget->set_border_color(dark_color_2); @@ -600,14 +654,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Style for windows, popups, etc.. Ref<StyleBoxFlat> style_popup = style_default->duplicate(); const int popup_margin_size = default_margin_size * EDSCALE * 3; - style_popup->set_default_margin(SIDE_LEFT, popup_margin_size); - style_popup->set_default_margin(SIDE_TOP, popup_margin_size); - style_popup->set_default_margin(SIDE_RIGHT, popup_margin_size); - style_popup->set_default_margin(SIDE_BOTTOM, popup_margin_size); + style_popup->set_default_margin_all(popup_margin_size); style_popup->set_border_color(contrast_color_1); const Color shadow_color = Color(0, 0, 0, dark_theme ? 0.3 : 0.1); style_popup->set_shadow_color(shadow_color); style_popup->set_shadow_size(4 * EDSCALE); + // Popups are separate windows by default in the editor. Windows currently don't support per-pixel transparency + // in 4.0, and even if it was, it may not always work in practice (e.g. running with compositing disabled). + style_popup->set_corner_radius_all(0); Ref<StyleBoxLine> style_popup_separator(memnew(StyleBoxLine)); style_popup_separator->set_color(separator_color); @@ -629,40 +683,41 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // TabBar - Ref<StyleBoxFlat> style_tab_selected = style_widget->duplicate(); + Ref<StyleBoxFlat> style_tab_base = style_widget->duplicate(); - // Add a highlight line at the top of the selected tab. - style_tab_selected->set_border_width_all(0); - style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE)); - // Make the highlight line prominent, but not too prominent as to not be distracting. - style_tab_selected->set_border_color(dark_color_2.lerp(accent_color, 0.75)); + style_tab_base->set_border_width_all(0); // Don't round the top corners to avoid creating a small blank space between the tabs and the main panel. // This also makes the top highlight look better. - style_tab_selected->set_corner_radius_all(0); + style_tab_base->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + style_tab_base->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); + + // When using a border width greater than 0, visually line up the left of the selected tab with the underlying panel. + style_tab_base->set_expand_margin_size(SIDE_LEFT, -border_width); - // Prevent visible artifacts and cover the top-left rounded corner of the panel below the tab if selected - // We can't prevent them with both rounded corners and non-zero border width, though - style_tab_selected->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width); + style_tab_base->set_default_margin(SIDE_LEFT, widget_default_margin.x + 5 * EDSCALE); + style_tab_base->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 5 * EDSCALE); + style_tab_base->set_default_margin(SIDE_BOTTOM, widget_default_margin.y); + style_tab_base->set_default_margin(SIDE_TOP, widget_default_margin.y); + + Ref<StyleBoxFlat> style_tab_selected = style_tab_base->duplicate(); - style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE); - style_tab_selected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE); - style_tab_selected->set_default_margin(SIDE_BOTTOM, widget_default_margin.y); - style_tab_selected->set_default_margin(SIDE_TOP, widget_default_margin.y); style_tab_selected->set_bg_color(base_color); + // Add a highlight line at the top of the selected tab. + style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE)); + // Make the highlight line prominent, but not too prominent as to not be distracting. + Color tab_highlight = dark_color_2.lerp(accent_color, 0.75); + style_tab_selected->set_border_color(tab_highlight); + style_tab_selected->set_corner_radius_all(0); - Ref<StyleBoxFlat> style_tab_unselected = style_tab_selected->duplicate(); - style_tab_unselected->set_bg_color(dark_color_1); + Ref<StyleBoxFlat> style_tab_unselected = style_tab_base->duplicate(); style_tab_unselected->set_expand_margin_size(SIDE_BOTTOM, 0); + style_tab_unselected->set_bg_color(dark_color_1); // Add some spacing between unselected tabs to make them easier to distinguish from each other style_tab_unselected->set_border_color(Color(0, 0, 0, 0)); - style_tab_unselected->set_border_width(SIDE_LEFT, Math::round(1 * EDSCALE)); - style_tab_unselected->set_border_width(SIDE_RIGHT, Math::round(1 * EDSCALE)); - style_tab_unselected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE); - style_tab_unselected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE); - Ref<StyleBoxFlat> style_tab_disabled = style_tab_selected->duplicate(); - style_tab_disabled->set_bg_color(disabled_bg_color); + Ref<StyleBoxFlat> style_tab_disabled = style_tab_base->duplicate(); style_tab_disabled->set_expand_margin_size(SIDE_BOTTOM, 0); + style_tab_disabled->set_bg_color(disabled_bg_color); style_tab_disabled->set_border_color(disabled_bg_color); // Editor background @@ -689,12 +744,45 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_canvas_editor_info->set_expand_margin_size_all(4 * EDSCALE); theme->set_stylebox("CanvasItemInfoOverlay", "EditorStyles", style_canvas_editor_info); + // 2D and 3D contextual toolbar. + // Use a custom stylebox to make contextual menu items stand out from the rest. + // This helps with editor usability as contextual menu items change when selecting nodes, + // even though it may not be immediately obvious at first. + Ref<StyleBoxFlat> toolbar_stylebox = memnew(StyleBoxFlat); + toolbar_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1)); + toolbar_stylebox->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE); + toolbar_stylebox->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE); + toolbar_stylebox->set_anti_aliased(false); + // Add an underline to the StyleBox, but prevent its minimum vertical size from changing. + toolbar_stylebox->set_border_color(accent_color); + toolbar_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); + toolbar_stylebox->set_default_margin(SIDE_BOTTOM, 0); + theme->set_stylebox("ContextualToolbar", "EditorStyles", toolbar_stylebox); + // Script Editor theme->set_stylebox("ScriptEditorPanel", "EditorStyles", make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size)); theme->set_stylebox("ScriptEditor", "EditorStyles", make_empty_stylebox(0, 0, 0, 0)); - // Play button group - theme->set_stylebox("PlayButtonPanel", "EditorStyles", style_empty); + // Launch Pad and Play buttons + Ref<StyleBoxFlat> style_launch_pad = make_flat_stylebox(dark_color_1, 2 * EDSCALE, 0, 2 * EDSCALE, 0, corner_width); + style_launch_pad->set_corner_radius_all(corner_radius * EDSCALE); + theme->set_stylebox("LaunchPadNormal", "EditorStyles", style_launch_pad); + Ref<StyleBoxFlat> style_launch_pad_movie = style_launch_pad->duplicate(); + style_launch_pad_movie->set_bg_color(accent_color * Color(1, 1, 1, 0.1)); + style_launch_pad_movie->set_border_color(accent_color); + style_launch_pad_movie->set_border_width_all(Math::round(2 * EDSCALE)); + theme->set_stylebox("LaunchPadMovieMode", "EditorStyles", style_launch_pad_movie); + + theme->set_stylebox("MovieWriterButtonNormal", "EditorStyles", make_empty_stylebox(0, 0, 0, 0)); + Ref<StyleBoxFlat> style_write_movie_button = style_widget_pressed->duplicate(); + style_write_movie_button->set_bg_color(accent_color); + style_write_movie_button->set_corner_radius_all(corner_radius * EDSCALE); + style_write_movie_button->set_default_margin(SIDE_TOP, 0); + style_write_movie_button->set_default_margin(SIDE_BOTTOM, 0); + style_write_movie_button->set_default_margin(SIDE_LEFT, 0); + style_write_movie_button->set_default_margin(SIDE_RIGHT, 0); + style_write_movie_button->set_expand_margin_size(SIDE_RIGHT, 2 * EDSCALE); + theme->set_stylebox("MovieWriterButtonPressed", "EditorStyles", style_write_movie_button); theme->set_stylebox("normal", "MenuButton", style_menu); theme->set_stylebox("hover", "MenuButton", style_widget_hover); @@ -704,6 +792,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color", "MenuButton", font_color); theme->set_color("font_hover_color", "MenuButton", font_hover_color); + theme->set_color("font_hover_pressed_color", "MenuButton", font_hover_pressed_color); theme->set_color("font_focus_color", "MenuButton", font_focus_color); theme->set_stylebox("MenuHover", "EditorStyles", style_widget_hover); @@ -717,20 +806,43 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color", "Button", font_color); theme->set_color("font_hover_color", "Button", font_hover_color); + theme->set_color("font_hover_pressed_color", "Button", font_hover_pressed_color); theme->set_color("font_focus_color", "Button", font_focus_color); theme->set_color("font_pressed_color", "Button", accent_color); theme->set_color("font_disabled_color", "Button", font_disabled_color); + theme->set_color("icon_normal_color", "Button", icon_normal_color); theme->set_color("icon_hover_color", "Button", icon_hover_color); theme->set_color("icon_focus_color", "Button", icon_focus_color); theme->set_color("icon_pressed_color", "Button", icon_pressed_color); + theme->set_color("icon_disabled_color", "Button", icon_disabled_color); + + const float ACTION_BUTTON_EXTRA_MARGIN = 32 * EDSCALE; + + theme->set_type_variation("InspectorActionButton", "Button"); + Color color_inspector_action = dark_color_1.lerp(mono_color, 0.12); + color_inspector_action.a = 0.5; + Ref<StyleBoxFlat> style_inspector_action = style_widget->duplicate(); + style_inspector_action->set_bg_color(color_inspector_action); + style_inspector_action->set_default_margin(SIDE_RIGHT, ACTION_BUTTON_EXTRA_MARGIN); + theme->set_stylebox("normal", "InspectorActionButton", style_inspector_action); + style_inspector_action = style_widget_hover->duplicate(); + style_inspector_action->set_default_margin(SIDE_RIGHT, ACTION_BUTTON_EXTRA_MARGIN); + theme->set_stylebox("hover", "InspectorActionButton", style_inspector_action); + style_inspector_action = style_widget_pressed->duplicate(); + style_inspector_action->set_default_margin(SIDE_RIGHT, ACTION_BUTTON_EXTRA_MARGIN); + theme->set_stylebox("pressed", "InspectorActionButton", style_inspector_action); + style_inspector_action = style_widget_disabled->duplicate(); + style_inspector_action->set_default_margin(SIDE_RIGHT, ACTION_BUTTON_EXTRA_MARGIN); + theme->set_stylebox("disabled", "InspectorActionButton", style_inspector_action); + theme->set_constant("h_separation", "InspectorActionButton", ACTION_BUTTON_EXTRA_MARGIN); // Variation for Editor Log filter buttons theme->set_type_variation("EditorLogFilterButton", "Button"); // When pressed, don't tint the icons with the accent color, just leave them normal. theme->set_color("icon_pressed_color", "EditorLogFilterButton", icon_normal_color); // When unpressed, dim the icons. - theme->set_color("icon_normal_color", "EditorLogFilterButton", font_disabled_color); + theme->set_color("icon_normal_color", "EditorLogFilterButton", icon_disabled_color); // When pressed, add a small bottom border to the buttons to better show their active state, // similar to active tabs. Ref<StyleBoxFlat> editor_log_button_pressed = style_widget_pressed->duplicate(); @@ -738,69 +850,110 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { editor_log_button_pressed->set_border_color(accent_color); theme->set_stylebox("pressed", "EditorLogFilterButton", editor_log_button_pressed); - // OptionButton - theme->set_stylebox("focus", "OptionButton", style_widget_focus); + // MenuBar + theme->set_stylebox("normal", "MenuBar", style_widget); + theme->set_stylebox("hover", "MenuBar", style_widget_hover); + theme->set_stylebox("pressed", "MenuBar", style_widget_pressed); + theme->set_stylebox("focus", "MenuBar", style_widget_focus); + theme->set_stylebox("disabled", "MenuBar", style_widget_disabled); + + theme->set_color("font_color", "MenuBar", font_color); + theme->set_color("font_hover_color", "MenuBar", font_hover_color); + theme->set_color("font_hover_pressed_color", "MenuBar", font_hover_pressed_color); + theme->set_color("font_focus_color", "MenuBar", font_focus_color); + theme->set_color("font_pressed_color", "MenuBar", accent_color); + theme->set_color("font_disabled_color", "MenuBar", font_disabled_color); + + theme->set_color("icon_normal_color", "MenuBar", icon_normal_color); + theme->set_color("icon_hover_color", "MenuBar", icon_hover_color); + theme->set_color("icon_focus_color", "MenuBar", icon_focus_color); + theme->set_color("icon_pressed_color", "MenuBar", icon_pressed_color); + theme->set_color("icon_disabled_color", "MenuBar", icon_disabled_color); + // OptionButton + Ref<StyleBoxFlat> style_option_button_focus = style_widget_focus->duplicate(); + Ref<StyleBoxFlat> style_option_button_normal = style_widget->duplicate(); + Ref<StyleBoxFlat> style_option_button_hover = style_widget_hover->duplicate(); + Ref<StyleBoxFlat> style_option_button_pressed = style_widget_pressed->duplicate(); + Ref<StyleBoxFlat> style_option_button_disabled = style_widget_disabled->duplicate(); + + style_option_button_focus->set_default_margin(SIDE_RIGHT, 4 * EDSCALE); + style_option_button_normal->set_default_margin(SIDE_RIGHT, 4 * EDSCALE); + style_option_button_hover->set_default_margin(SIDE_RIGHT, 4 * EDSCALE); + style_option_button_pressed->set_default_margin(SIDE_RIGHT, 4 * EDSCALE); + style_option_button_disabled->set_default_margin(SIDE_RIGHT, 4 * EDSCALE); + + theme->set_stylebox("focus", "OptionButton", style_option_button_focus); theme->set_stylebox("normal", "OptionButton", style_widget); theme->set_stylebox("hover", "OptionButton", style_widget_hover); theme->set_stylebox("pressed", "OptionButton", style_widget_pressed); theme->set_stylebox("disabled", "OptionButton", style_widget_disabled); - theme->set_stylebox("normal_mirrored", "OptionButton", style_widget); - theme->set_stylebox("hover_mirrored", "OptionButton", style_widget_hover); - theme->set_stylebox("pressed_mirrored", "OptionButton", style_widget_pressed); - theme->set_stylebox("disabled_mirrored", "OptionButton", style_widget_disabled); + theme->set_stylebox("normal_mirrored", "OptionButton", style_option_button_normal); + theme->set_stylebox("hover_mirrored", "OptionButton", style_option_button_hover); + theme->set_stylebox("pressed_mirrored", "OptionButton", style_option_button_pressed); + theme->set_stylebox("disabled_mirrored", "OptionButton", style_option_button_disabled); theme->set_color("font_color", "OptionButton", font_color); theme->set_color("font_hover_color", "OptionButton", font_hover_color); + theme->set_color("font_hover_pressed_color", "OptionButton", font_hover_pressed_color); theme->set_color("font_focus_color", "OptionButton", font_focus_color); theme->set_color("font_pressed_color", "OptionButton", accent_color); theme->set_color("font_disabled_color", "OptionButton", font_disabled_color); + + theme->set_color("icon_normal_color", "OptionButton", icon_normal_color); theme->set_color("icon_hover_color", "OptionButton", icon_hover_color); theme->set_color("icon_focus_color", "OptionButton", icon_focus_color); + theme->set_color("icon_pressed_color", "OptionButton", icon_pressed_color); + theme->set_color("icon_disabled_color", "OptionButton", icon_disabled_color); + theme->set_icon("arrow", "OptionButton", theme->get_icon(SNAME("GuiOptionArrow"), SNAME("EditorIcons"))); theme->set_constant("arrow_margin", "OptionButton", widget_default_margin.x - 2 * EDSCALE); theme->set_constant("modulate_arrow", "OptionButton", true); - theme->set_constant("hseparation", "OptionButton", 4 * EDSCALE); + theme->set_constant("h_separation", "OptionButton", 4 * EDSCALE); // CheckButton theme->set_stylebox("normal", "CheckButton", style_menu); theme->set_stylebox("pressed", "CheckButton", style_menu); theme->set_stylebox("disabled", "CheckButton", style_menu); theme->set_stylebox("hover", "CheckButton", style_menu); + theme->set_stylebox("hover_pressed", "CheckButton", style_menu); - theme->set_icon("on", "CheckButton", theme->get_icon(SNAME("GuiToggleOn"), SNAME("EditorIcons"))); - theme->set_icon("on_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabled"), SNAME("EditorIcons"))); - theme->set_icon("off", "CheckButton", theme->get_icon(SNAME("GuiToggleOff"), SNAME("EditorIcons"))); - theme->set_icon("off_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabled"), SNAME("EditorIcons"))); + theme->set_icon("checked", "CheckButton", theme->get_icon(SNAME("GuiToggleOn"), SNAME("EditorIcons"))); + theme->set_icon("checked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabled"), SNAME("EditorIcons"))); + theme->set_icon("unchecked", "CheckButton", theme->get_icon(SNAME("GuiToggleOff"), SNAME("EditorIcons"))); + theme->set_icon("unchecked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabled"), SNAME("EditorIcons"))); - theme->set_icon("on_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnMirrored"), SNAME("EditorIcons"))); - theme->set_icon("on_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), SNAME("EditorIcons"))); - theme->set_icon("off_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffMirrored"), SNAME("EditorIcons"))); - theme->set_icon("off_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), SNAME("EditorIcons"))); + theme->set_icon("checked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnMirrored"), SNAME("EditorIcons"))); + theme->set_icon("checked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), SNAME("EditorIcons"))); + theme->set_icon("unchecked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffMirrored"), SNAME("EditorIcons"))); + theme->set_icon("unchecked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), SNAME("EditorIcons"))); theme->set_color("font_color", "CheckButton", font_color); theme->set_color("font_hover_color", "CheckButton", font_hover_color); + theme->set_color("font_hover_pressed_color", "CheckButton", font_hover_pressed_color); theme->set_color("font_focus_color", "CheckButton", font_focus_color); theme->set_color("font_pressed_color", "CheckButton", accent_color); theme->set_color("font_disabled_color", "CheckButton", font_disabled_color); + + theme->set_color("icon_normal_color", "CheckButton", icon_normal_color); theme->set_color("icon_hover_color", "CheckButton", icon_hover_color); theme->set_color("icon_focus_color", "CheckButton", icon_focus_color); + theme->set_color("icon_pressed_color", "CheckButton", icon_pressed_color); + theme->set_color("icon_disabled_color", "CheckButton", icon_disabled_color); - theme->set_constant("hseparation", "CheckButton", 8 * EDSCALE); - theme->set_constant("check_vadjust", "CheckButton", 0 * EDSCALE); + theme->set_constant("h_separation", "CheckButton", 8 * EDSCALE); + theme->set_constant("check_v_offset", "CheckButton", 0 * EDSCALE); // Checkbox Ref<StyleBoxFlat> sb_checkbox = style_menu->duplicate(); - sb_checkbox->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE); - sb_checkbox->set_default_margin(SIDE_RIGHT, default_margin_size * EDSCALE); - sb_checkbox->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE); - sb_checkbox->set_default_margin(SIDE_BOTTOM, default_margin_size * EDSCALE); + sb_checkbox->set_default_margin_all(default_margin_size * EDSCALE); theme->set_stylebox("normal", "CheckBox", sb_checkbox); theme->set_stylebox("pressed", "CheckBox", sb_checkbox); theme->set_stylebox("disabled", "CheckBox", sb_checkbox); theme->set_stylebox("hover", "CheckBox", sb_checkbox); + theme->set_stylebox("hover_pressed", "CheckBox", sb_checkbox); theme->set_icon("checked", "CheckBox", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); theme->set_icon("unchecked", "CheckBox", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); theme->set_icon("radio_checked", "CheckBox", theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons"))); @@ -812,30 +965,31 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color", "CheckBox", font_color); theme->set_color("font_hover_color", "CheckBox", font_hover_color); + theme->set_color("font_hover_pressed_color", "CheckBox", font_hover_pressed_color); theme->set_color("font_focus_color", "CheckBox", font_focus_color); theme->set_color("font_pressed_color", "CheckBox", accent_color); theme->set_color("font_disabled_color", "CheckBox", font_disabled_color); + + theme->set_color("icon_normal_color", "CheckBox", icon_normal_color); theme->set_color("icon_hover_color", "CheckBox", icon_hover_color); theme->set_color("icon_focus_color", "CheckBox", icon_focus_color); + theme->set_color("icon_pressed_color", "CheckBox", icon_pressed_color); + theme->set_color("icon_disabled_color", "CheckBox", icon_disabled_color); - theme->set_constant("hseparation", "CheckBox", 8 * EDSCALE); - theme->set_constant("check_vadjust", "CheckBox", 0 * EDSCALE); + theme->set_constant("h_separation", "CheckBox", 8 * EDSCALE); + theme->set_constant("check_v_offset", "CheckBox", 0 * EDSCALE); // PopupDialog theme->set_stylebox("panel", "PopupDialog", style_popup); // PopupMenu - const int popup_menu_margin_size = default_margin_size * 1.5 * EDSCALE; Ref<StyleBoxFlat> style_popup_menu = style_popup->duplicate(); // Use 1 pixel for the sides, since if 0 is used, the highlight of hovered items is drawn // on top of the popup border. This causes a 'gap' in the panel border when an item is highlighted, // and it looks weird. 1px solves this. - style_popup_menu->set_default_margin(SIDE_LEFT, 1 * EDSCALE); - style_popup_menu->set_default_margin(SIDE_TOP, popup_menu_margin_size); - style_popup_menu->set_default_margin(SIDE_RIGHT, 1 * EDSCALE); - style_popup_menu->set_default_margin(SIDE_BOTTOM, popup_menu_margin_size); + style_popup_menu->set_default_margin_individual(EDSCALE, 2 * EDSCALE, EDSCALE, 2 * EDSCALE); // Always display a border for PopupMenus so they can be distinguished from their background. - style_popup_menu->set_border_width_all(1 * EDSCALE); + style_popup_menu->set_border_width_all(EDSCALE); style_popup_menu->set_border_color(dark_color_2); theme->set_stylebox("panel", "PopupMenu", style_popup_menu); @@ -867,15 +1021,16 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityXray"), SNAME("EditorIcons"))); - // Force the vseparation to be even so that the spacing on top and bottom is even. + // Force the v_separation to be even so that the spacing on top and bottom is even. // If the vsep is odd and cannot be split into 2 even groups (of pixels), then it will be lopsided. - // We add 2 to the vsep to give it some extra spacing which looks a bit more modern (see Windows, for example) - int vsep_base = extra_spacing + default_margin_size + 2; - int force_even_vsep = vsep_base + (vsep_base % 2); - theme->set_constant("vseparation", "PopupMenu", force_even_vsep * EDSCALE); - theme->set_constant("item_start_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); - theme->set_constant("item_end_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); - + // We add 2 to the vsep to give it some extra spacing which looks a bit more modern (see Windows, for example). + const int vsep_base = extra_spacing + default_margin_size + 6; + const int force_even_vsep = vsep_base + (vsep_base % 2); + theme->set_constant("v_separation", "PopupMenu", force_even_vsep * EDSCALE); + theme->set_constant("item_start_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); + theme->set_constant("item_end_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); + + // Sub-inspectors for (int i = 0; i < 16; i++) { Color si_base_color = accent_color; @@ -883,52 +1038,51 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { si_base_color.set_hsv(Math::fmod(float(si_base_color.get_h() + hue_rotate), float(1.0)), si_base_color.get_s(), si_base_color.get_v()); si_base_color = accent_color.lerp(si_base_color, float(EDITOR_GET("docks/property_editor/subresource_hue_tint"))); - Ref<StyleBoxFlat> sub_inspector_bg; - - sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(si_base_color, 0.08), 2, 0, 2, 2); - - sub_inspector_bg->set_border_width(SIDE_LEFT, 2); - sub_inspector_bg->set_border_width(SIDE_RIGHT, 2); - sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2); - sub_inspector_bg->set_border_width(SIDE_TOP, 2); - sub_inspector_bg->set_default_margin(SIDE_LEFT, 3); - sub_inspector_bg->set_default_margin(SIDE_RIGHT, 3); - sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 10); - sub_inspector_bg->set_default_margin(SIDE_TOP, 5); + // Sub-inspector background. + Ref<StyleBoxFlat> sub_inspector_bg = style_default->duplicate(); + sub_inspector_bg->set_bg_color(dark_color_1.lerp(si_base_color, 0.08)); + sub_inspector_bg->set_border_width_all(2 * EDSCALE); sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); - sub_inspector_bg->set_draw_center(true); + sub_inspector_bg->set_default_margin_all(4 * EDSCALE); + sub_inspector_bg->set_corner_radius(CORNER_TOP_LEFT, 0); + sub_inspector_bg->set_corner_radius(CORNER_TOP_RIGHT, 0); theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg); - Ref<StyleBoxFlat> bg_color; - bg_color.instantiate(); - bg_color->set_bg_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); - bg_color->set_border_width_all(0); - - Ref<StyleBoxFlat> bg_color_selected; - bg_color_selected.instantiate(); - bg_color_selected->set_border_width_all(0); - bg_color_selected->set_bg_color(si_base_color * Color(0.8, 0.8, 0.8, 0.8)); + // EditorProperty background while it has a sub-inspector open. + Ref<StyleBoxFlat> bg_color = make_flat_stylebox(si_base_color * Color(0.7, 0.7, 0.7, 0.8), 0, 0, 0, 0, corner_radius); + bg_color->set_anti_aliased(false); + bg_color->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + bg_color->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color); - theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), "Editor", bg_color_selected); } theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); - theme->set_constant("sub_inspector_font_offset", "Editor", 4 * EDSCALE); // EditorSpinSlider. theme->set_color("label_color", "EditorSpinSlider", font_color); theme->set_color("read_only_label_color", "EditorSpinSlider", font_readonly_color); + Ref<StyleBoxFlat> editor_spin_label_bg = style_default->duplicate(); + editor_spin_label_bg->set_bg_color(dark_color_3); + editor_spin_label_bg->set_border_width_all(0); + theme->set_stylebox("label_bg", "EditorSpinSlider", editor_spin_label_bg); + + // EditorProperty Ref<StyleBoxFlat> style_property_bg = style_default->duplicate(); style_property_bg->set_bg_color(highlight_color); style_property_bg->set_border_width_all(0); + Ref<StyleBoxFlat> style_property_child_bg = style_default->duplicate(); + style_property_child_bg->set_bg_color(dark_color_2); + style_property_child_bg->set_border_width_all(0); + theme->set_constant("font_offset", "EditorProperty", 8 * EDSCALE); theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); - theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); + theme->set_stylebox("child_bg", "EditorProperty", style_property_child_bg); + theme->set_constant("v_separation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); theme->set_color("warning_color", "EditorProperty", warning_color); theme->set_color("property_color", "EditorProperty", property_color); theme->set_color("readonly_color", "EditorProperty", readonly_color); @@ -940,6 +1094,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_property_group_note->set_bg_color(property_group_note_color); theme->set_stylebox("bg_group_note", "EditorProperty", style_property_group_note); + // EditorInspectorSection Color inspector_section_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.35); theme->set_color("font_color", "EditorInspectorSection", inspector_section_color); @@ -956,7 +1111,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Make Trees easier to distinguish from other controls by using a darker background color. style_tree_bg->set_bg_color(dark_color_1.lerp(dark_color_2, 0.5)); style_tree_bg->set_border_color(dark_color_3); - theme->set_stylebox("bg", "Tree", style_tree_bg); + theme->set_stylebox("panel", "Tree", style_tree_bg); // Tree theme->set_icon("checked", "Tree", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); @@ -967,7 +1122,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("arrow_collapsed_mirrored", "Tree", theme->get_icon(SNAME("GuiTreeArrowLeft"), SNAME("EditorIcons"))); theme->set_icon("updown", "Tree", theme->get_icon(SNAME("GuiTreeUpdown"), SNAME("EditorIcons"))); theme->set_icon("select_arrow", "Tree", theme->get_icon(SNAME("GuiDropdown"), SNAME("EditorIcons"))); - theme->set_stylebox("bg_focus", "Tree", style_widget_focus); + theme->set_stylebox("focus", "Tree", style_widget_focus); theme->set_stylebox("custom_button", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_hover", "Tree", style_widget); @@ -976,8 +1131,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_selected_color", "Tree", mono_color); theme->set_color("title_button_color", "Tree", font_color); theme->set_color("drop_position_color", "Tree", accent_color); - theme->set_constant("vseparation", "Tree", widget_default_margin.y - EDSCALE); - theme->set_constant("hseparation", "Tree", 6 * EDSCALE); + theme->set_constant("v_separation", "Tree", widget_default_margin.y - EDSCALE); + theme->set_constant("h_separation", "Tree", 6 * EDSCALE); theme->set_constant("guide_width", "Tree", border_width); theme->set_constant("item_margin", "Tree", 3 * default_margin_size * EDSCALE); theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE); @@ -1042,11 +1197,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("prop_subsection", "Editor", prop_subsection_color); theme->set_color("drop_position_color", "Tree", accent_color); + // EditorInspectorCategory Ref<StyleBoxFlat> category_bg = style_default->duplicate(); - // Make Trees easier to distinguish from other controls by using a darker background color. category_bg->set_bg_color(prop_category_color); category_bg->set_border_color(prop_category_color); - theme->set_stylebox("prop_category_style", "Editor", category_bg); + theme->set_stylebox("bg", "EditorInspectorCategory", category_bg); // ItemList Ref<StyleBoxFlat> style_itemlist_bg = style_default->duplicate(); @@ -1058,38 +1213,43 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_itemlist_cursor->set_draw_center(false); style_itemlist_cursor->set_border_width_all(border_width); style_itemlist_cursor->set_border_color(highlight_color); + theme->set_stylebox("panel", "ItemList", style_itemlist_bg); + theme->set_stylebox("focus", "ItemList", style_widget_focus); theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor); theme->set_stylebox("cursor_unfocused", "ItemList", style_itemlist_cursor); theme->set_stylebox("selected_focus", "ItemList", style_tree_focus); theme->set_stylebox("selected", "ItemList", style_tree_selected); - theme->set_stylebox("bg_focus", "ItemList", style_widget_focus); - theme->set_stylebox("bg", "ItemList", style_itemlist_bg); theme->set_color("font_color", "ItemList", font_color); theme->set_color("font_selected_color", "ItemList", mono_color); theme->set_color("guide_color", "ItemList", guide_color); - theme->set_constant("vseparation", "ItemList", widget_default_margin.y - EDSCALE); - theme->set_constant("hseparation", "ItemList", 6 * EDSCALE); + theme->set_constant("v_separation", "ItemList", force_even_vsep * 0.5 * EDSCALE); + theme->set_constant("h_separation", "ItemList", 6 * EDSCALE); theme->set_constant("icon_margin", "ItemList", 6 * EDSCALE); theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); // TabBar & TabContainer + Ref<StyleBoxFlat> style_tabbar_background = make_flat_stylebox(dark_color_1, 0, 0, 0, 0, corner_radius * EDSCALE); + style_tabbar_background->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + style_tabbar_background->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); + theme->set_stylebox("tabbar_background", "TabContainer", style_tabbar_background); + theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected); theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); theme->set_stylebox("tab_selected", "TabBar", style_tab_selected); theme->set_stylebox("tab_unselected", "TabBar", style_tab_unselected); theme->set_stylebox("tab_disabled", "TabBar", style_tab_disabled); + theme->set_stylebox("button_pressed", "TabBar", style_menu); + theme->set_stylebox("button_highlight", "TabBar", style_menu); theme->set_color("font_selected_color", "TabContainer", font_color); theme->set_color("font_unselected_color", "TabContainer", font_disabled_color); theme->set_color("font_selected_color", "TabBar", font_color); theme->set_color("font_unselected_color", "TabBar", font_disabled_color); + theme->set_color("drop_mark_color", "TabContainer", tab_highlight); + theme->set_color("drop_mark_color", "TabBar", tab_highlight); theme->set_icon("menu", "TabContainer", theme->get_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons"))); theme->set_icon("menu_highlight", "TabContainer", theme->get_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected); - theme->set_stylebox("SceneTabBG", "EditorStyles", style_tab_unselected); theme->set_icon("close", "TabBar", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); - theme->set_stylebox("button_pressed", "TabBar", style_menu); - theme->set_stylebox("button_highlight", "TabBar", style_menu); theme->set_icon("increment", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons"))); theme->set_icon("decrement", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeft"), SNAME("EditorIcons"))); theme->set_icon("increment", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons"))); @@ -1098,37 +1258,41 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("decrement_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); theme->set_icon("increment_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons"))); theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); - theme->set_constant("hseparation", "TabBar", 4 * EDSCALE); + theme->set_icon("drop_mark", "TabContainer", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons"))); + theme->set_icon("drop_mark", "TabBar", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons"))); + theme->set_constant("side_margin", "TabContainer", 0); + theme->set_constant("h_separation", "TabBar", 4 * EDSCALE); - // Content of each tab + // Content of each tab. Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); style_content_panel->set_border_color(dark_color_3); style_content_panel->set_border_width_all(border_width); - // compensate the border - style_content_panel->set_default_margin(SIDE_TOP, (2 + margin_size_extra) * EDSCALE); - style_content_panel->set_default_margin(SIDE_RIGHT, margin_size_extra * EDSCALE); - style_content_panel->set_default_margin(SIDE_BOTTOM, margin_size_extra * EDSCALE); - style_content_panel->set_default_margin(SIDE_LEFT, margin_size_extra * EDSCALE); - // Display border to visually split the body of the container from its possible backgrounds. - style_content_panel->set_border_width(Side::SIDE_TOP, Math::round(2 * EDSCALE)); - style_content_panel->set_border_color(dark_color_2); + style_content_panel->set_border_width(Side::SIDE_TOP, 0); + style_content_panel->set_corner_radius(CORNER_TOP_LEFT, 0); + style_content_panel->set_corner_radius(CORNER_TOP_RIGHT, 0); + // Compensate for the border. + style_content_panel->set_default_margin_individual(margin_size_extra * EDSCALE, (2 + margin_size_extra) * EDSCALE, margin_size_extra * EDSCALE, margin_size_extra * EDSCALE); theme->set_stylebox("panel", "TabContainer", style_content_panel); - // These styleboxes can be used on tabs against the base color background (e.g. nested tabs). + // Bottom panel. + Ref<StyleBoxFlat> style_bottom_panel = style_content_panel->duplicate(); + style_bottom_panel->set_corner_radius_all(corner_radius * EDSCALE); + theme->set_stylebox("BottomPanel", "EditorStyles", style_bottom_panel); + + // TabContainerOdd can be used on tabs against the base color background (e.g. nested tabs). + theme->set_type_variation("TabContainerOdd", "TabContainer"); + Ref<StyleBoxFlat> style_tab_selected_odd = style_tab_selected->duplicate(); style_tab_selected_odd->set_bg_color(disabled_bg_color); - theme->set_stylebox("tab_selected_odd", "TabContainer", style_tab_selected_odd); + theme->set_stylebox("tab_selected", "TabContainerOdd", style_tab_selected_odd); Ref<StyleBoxFlat> style_content_panel_odd = style_content_panel->duplicate(); style_content_panel_odd->set_bg_color(disabled_bg_color); - theme->set_stylebox("panel_odd", "TabContainer", style_content_panel_odd); + theme->set_stylebox("panel", "TabContainerOdd", style_content_panel_odd); // This stylebox is used in 3d and 2d viewports (no borders). Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate(); - style_content_panel_vp->set_default_margin(SIDE_LEFT, border_width * 2); - style_content_panel_vp->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE); - style_content_panel_vp->set_default_margin(SIDE_RIGHT, border_width * 2); - style_content_panel_vp->set_default_margin(SIDE_BOTTOM, border_width * 2); + style_content_panel_vp->set_default_margin_individual(border_width * 2, default_margin_size * EDSCALE, border_width * 2, border_width * 2); theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp); // This stylebox is used by preview tabs in the Theme Editor. @@ -1177,7 +1341,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("focus", "LineEdit", style_widget_focus); theme->set_stylebox("read_only", "LineEdit", style_line_edit_disabled); theme->set_icon("clear", "LineEdit", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); - theme->set_color("read_only", "LineEdit", font_disabled_color); theme->set_color("font_color", "LineEdit", font_color); theme->set_color("font_selected_color", "LineEdit", mono_color); theme->set_color("font_uneditable_color", "LineEdit", font_readonly_color); @@ -1191,7 +1354,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("normal", "TextEdit", style_line_edit); theme->set_stylebox("focus", "TextEdit", style_widget_focus); theme->set_stylebox("read_only", "TextEdit", style_line_edit_disabled); - theme->set_constant("side_margin", "TabContainer", 0); theme->set_icon("tab", "TextEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); theme->set_icon("space", "TextEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); theme->set_color("font_color", "TextEdit", font_color); @@ -1201,30 +1363,17 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("selection_color", "TextEdit", selection_color); theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); - // CodeEdit - theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts"))); - theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts"))); - theme->set_stylebox("normal", "CodeEdit", style_widget); - theme->set_stylebox("focus", "CodeEdit", style_widget_hover); - theme->set_stylebox("read_only", "CodeEdit", style_widget_disabled); - theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); - theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); - theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); - theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons"))); - theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); - - // H/VSplitContainer - theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon(SNAME("GuiVsplitBg"), SNAME("EditorIcons")), 1, 1, 1, 1)); - theme->set_stylebox("bg", "HSplitContainer", make_stylebox(theme->get_icon(SNAME("GuiHsplitBg"), SNAME("EditorIcons")), 1, 1, 1, 1)); - + theme->set_icon("h_grabber", "SplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); + theme->set_icon("v_grabber", "SplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); theme->set_constant("separation", "HSplitContainer", default_margin_size * 2 * EDSCALE); theme->set_constant("separation", "VSplitContainer", default_margin_size * 2 * EDSCALE); + theme->set_constant("minimum_grab_thickness", "HSplitContainer", 6 * EDSCALE); + theme->set_constant("minimum_grab_thickness", "VSplitContainer", 6 * EDSCALE); + // Containers theme->set_constant("separation", "BoxContainer", default_margin_size * EDSCALE); theme->set_constant("separation", "HBoxContainer", default_margin_size * EDSCALE); @@ -1233,14 +1382,21 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("margin_top", "MarginContainer", 0); theme->set_constant("margin_right", "MarginContainer", 0); theme->set_constant("margin_bottom", "MarginContainer", 0); - theme->set_constant("hseparation", "GridContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "GridContainer", default_margin_size * EDSCALE); - theme->set_constant("hseparation", "FlowContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "FlowContainer", default_margin_size * EDSCALE); - theme->set_constant("hseparation", "HFlowContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "HFlowContainer", default_margin_size * EDSCALE); - theme->set_constant("hseparation", "VFlowContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "VFlowContainer", default_margin_size * EDSCALE); + theme->set_constant("h_separation", "GridContainer", default_margin_size * EDSCALE); + theme->set_constant("v_separation", "GridContainer", default_margin_size * EDSCALE); + theme->set_constant("h_separation", "FlowContainer", default_margin_size * EDSCALE); + theme->set_constant("v_separation", "FlowContainer", default_margin_size * EDSCALE); + theme->set_constant("h_separation", "HFlowContainer", default_margin_size * EDSCALE); + theme->set_constant("v_separation", "HFlowContainer", default_margin_size * EDSCALE); + theme->set_constant("h_separation", "VFlowContainer", default_margin_size * EDSCALE); + theme->set_constant("v_separation", "VFlowContainer", default_margin_size * EDSCALE); + + // Custom theme type for MarginContainer with 4px margins. + theme->set_type_variation("MarginContainer4px", "MarginContainer"); + theme->set_constant("margin_left", "MarginContainer4px", 4 * EDSCALE); + theme->set_constant("margin_top", "MarginContainer4px", 4 * EDSCALE); + theme->set_constant("margin_right", "MarginContainer4px", 4 * EDSCALE); + theme->set_constant("margin_bottom", "MarginContainer4px", 4 * EDSCALE); // Window @@ -1260,8 +1416,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("title_color", "Window", font_color); theme->set_icon("close", "Window", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); theme->set_icon("close_pressed", "Window", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); - theme->set_constant("close_h_ofs", "Window", 22 * EDSCALE); - theme->set_constant("close_v_ofs", "Window", 20 * EDSCALE); + theme->set_constant("close_h_offset", "Window", 22 * EDSCALE); + theme->set_constant("close_v_offset", "Window", 20 * EDSCALE); theme->set_constant("title_height", "Window", 24 * EDSCALE); theme->set_constant("resize_margin", "Window", 4 * EDSCALE); theme->set_font("title_font", "Window", theme->get_font(SNAME("title"), SNAME("EditorFonts"))); @@ -1277,6 +1433,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // AcceptDialog theme->set_stylebox("panel", "AcceptDialog", style_window_title); + theme->set_constant("buttons_separation", "AcceptDialog", 8 * EDSCALE); // HScrollBar Ref<Texture2D> empty_icon = memnew(ImageTexture); @@ -1314,6 +1471,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("slider", "HSlider", make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); theme->set_stylebox("grabber_area_highlight", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2)); + theme->set_constant("grabber_offset", "HSlider", 0); // VSlider theme->set_icon("grabber", "VSlider", theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons"))); @@ -1321,6 +1479,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("slider", "VSlider", make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); theme->set_stylebox("grabber_area_highlight", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0)); + theme->set_constant("grabber_offset", "VSlider", 0); // RichTextLabel theme->set_color("default_color", "RichTextLabel", font_color); @@ -1345,8 +1504,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("code_color", "EditorHelp", accent_color.lerp(mono_color, 0.6)); theme->set_color("kbd_color", "EditorHelp", accent_color.lerp(property_color, 0.6)); theme->set_constant("line_separation", "EditorHelp", Math::round(6 * EDSCALE)); - theme->set_constant("table_hseparation", "EditorHelp", 16 * EDSCALE); - theme->set_constant("table_vseparation", "EditorHelp", 6 * EDSCALE); + theme->set_constant("table_h_separation", "EditorHelp", 16 * EDSCALE); + theme->set_constant("table_v_separation", "EditorHelp", 6 * EDSCALE); // Panel theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4, corner_width)); @@ -1365,33 +1524,44 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("focus", "LinkButton", style_empty); theme->set_color("font_color", "LinkButton", font_color); theme->set_color("font_hover_color", "LinkButton", font_hover_color); + theme->set_color("font_hover_pressed_color", "LinkButton", font_hover_pressed_color); theme->set_color("font_focus_color", "LinkButton", font_focus_color); theme->set_color("font_pressed_color", "LinkButton", accent_color); theme->set_color("font_disabled_color", "LinkButton", font_disabled_color); - // TooltipPanel + // TooltipPanel + TooltipLabel + // TooltipPanel is also used for custom tooltips, while TooltipLabel + // is only relevant for default tooltips. Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate(); style_tooltip->set_shadow_size(0); - style_tooltip->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE * 0.5); - style_tooltip->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE * 0.5); - style_tooltip->set_default_margin(SIDE_RIGHT, default_margin_size * EDSCALE * 0.5); - style_tooltip->set_default_margin(SIDE_BOTTOM, default_margin_size * EDSCALE * 0.5); + style_tooltip->set_default_margin_all(default_margin_size * EDSCALE * 0.5); style_tooltip->set_bg_color(dark_color_3 * Color(0.8, 0.8, 0.8, 0.9)); style_tooltip->set_border_width_all(0); theme->set_color("font_color", "TooltipLabel", font_hover_color); - theme->set_color("font_color_shadow", "TooltipLabel", Color(0, 0, 0, 0)); + theme->set_color("font_shadow_color", "TooltipLabel", Color(0, 0, 0, 0)); theme->set_stylebox("panel", "TooltipPanel", style_tooltip); // PopupPanel theme->set_stylebox("panel", "PopupPanel", style_popup); + Ref<StyleBoxFlat> control_editor_popup_style = style_popup->duplicate(); + control_editor_popup_style->set_shadow_size(0); + control_editor_popup_style->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE); + control_editor_popup_style->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE); + control_editor_popup_style->set_default_margin(SIDE_RIGHT, default_margin_size * EDSCALE); + control_editor_popup_style->set_default_margin(SIDE_BOTTOM, default_margin_size * EDSCALE); + control_editor_popup_style->set_border_width_all(0); + + theme->set_stylebox("panel", "ControlEditorPopupPanel", control_editor_popup_style); + theme->set_type_variation("ControlEditorPopupPanel", "PopupPanel"); + // SpinBox theme->set_icon("updown", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdown"), SNAME("EditorIcons"))); theme->set_icon("updown_disabled", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), SNAME("EditorIcons"))); // ProgressBar - theme->set_stylebox("bg", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), SNAME("EditorIcons")), 4, 4, 4, 4, 0, 0, 0, 0)); - theme->set_stylebox("fg", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 1, 2, 1)); + theme->set_stylebox("background", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), SNAME("EditorIcons")), 4, 4, 4, 4, 0, 0, 0, 0)); + theme->set_stylebox("fill", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 1, 2, 1)); theme->set_color("font_color", "ProgressBar", font_color); // GraphEdit @@ -1412,8 +1582,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("snap", "GraphEdit", theme->get_icon(SNAME("SnapGrid"), SNAME("EditorIcons"))); theme->set_icon("minimap", "GraphEdit", theme->get_icon(SNAME("GridMinimap"), SNAME("EditorIcons"))); theme->set_icon("layout", "GraphEdit", theme->get_icon(SNAME("GridLayout"), SNAME("EditorIcons"))); - theme->set_constant("bezier_len_pos", "GraphEdit", 80 * EDSCALE); - theme->set_constant("bezier_len_neg", "GraphEdit", 160 * EDSCALE); // GraphEditMinimap Ref<StyleBoxFlat> style_minimap_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); @@ -1433,35 +1601,42 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_minimap_node = make_flat_stylebox(Color(0, 0, 0), 0, 0, 0, 0); } style_minimap_camera->set_border_width_all(1); - style_minimap_node->set_corner_radius_all(1); theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera); theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node); - Ref<Texture2D> minimap_resizer_icon = theme->get_icon(SNAME("GuiResizer"), SNAME("EditorIcons")); Color minimap_resizer_color; if (dark_theme) { minimap_resizer_color = Color(1, 1, 1, 0.65); } else { minimap_resizer_color = Color(0, 0, 0, 0.65); } - theme->set_icon("resizer", "GraphEditMinimap", flip_icon(minimap_resizer_icon, true, true)); + theme->set_icon("resizer", "GraphEditMinimap", theme->get_icon(SNAME("GuiResizerTopLeft"), SNAME("EditorIcons"))); theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color); // GraphNode - const int gn_margin_side = 28; + const int gn_margin_side = 2; + const int gn_margin_bottom = 2; + + // StateMachine + const int sm_margin_side = 10; + + Color graphnode_bg = dark_color_3; + if (!dark_theme) { + graphnode_bg = prop_section_color; + } - Ref<StyleBoxFlat> graphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), gn_margin_side, 24, gn_margin_side, 5, corner_width); + Ref<StyleBoxFlat> graphsb = make_flat_stylebox(graphnode_bg.lerp(style_tree_bg->get_bg_color(), 0.3), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width); graphsb->set_border_width_all(border_width); - graphsb->set_border_color(dark_color_3); - Ref<StyleBoxFlat> graphsbselected = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.9), gn_margin_side, 24, gn_margin_side, 5, corner_width); + graphsb->set_border_color(graphnode_bg); + Ref<StyleBoxFlat> graphsbselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 1), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width); graphsbselected->set_border_width_all(2 * EDSCALE + border_width); - graphsbselected->set_border_color(Color(accent_color.r, accent_color.g, accent_color.b, 0.9)); - Ref<StyleBoxFlat> graphsbcomment = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.3), gn_margin_side, 24, gn_margin_side, 5, corner_width); + graphsbselected->set_border_color(Color(accent_color.r, accent_color.g, accent_color.b, 0.6)); + Ref<StyleBoxFlat> graphsbcomment = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.3), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width); graphsbcomment->set_border_width_all(border_width); - graphsbcomment->set_border_color(dark_color_3); - Ref<StyleBoxFlat> graphsbcommentselected = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.4), gn_margin_side, 24, gn_margin_side, 5, corner_width); + graphsbcomment->set_border_color(graphnode_bg); + Ref<StyleBoxFlat> graphsbcommentselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.4), gn_margin_side, 24, gn_margin_side, gn_margin_bottom, corner_width); graphsbcommentselected->set_border_width_all(border_width); - graphsbcommentselected->set_border_color(dark_color_3); + graphsbcommentselected->set_border_color(graphnode_bg); Ref<StyleBoxFlat> graphsbbreakpoint = graphsbselected->duplicate(); graphsbbreakpoint->set_draw_center(false); graphsbbreakpoint->set_border_color(warning_color); @@ -1470,10 +1645,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { graphsbposition->set_draw_center(false); graphsbposition->set_border_color(error_color); graphsbposition->set_shadow_color(error_color * Color(1.0, 1.0, 1.0, 0.2)); - Ref<StyleBoxFlat> smgraphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), gn_margin_side, 24, gn_margin_side, 5, corner_width); + Ref<StyleBoxEmpty> graphsbslot = make_empty_stylebox(12, 0, 12, 0); + Ref<StyleBoxFlat> smgraphsb = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), sm_margin_side, 24, sm_margin_side, gn_margin_bottom, corner_width); smgraphsb->set_border_width_all(border_width); - smgraphsb->set_border_color(dark_color_3); - Ref<StyleBoxFlat> smgraphsbselected = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.9), gn_margin_side, 24, gn_margin_side, 5, corner_width); + smgraphsb->set_border_color(graphnode_bg); + Ref<StyleBoxFlat> smgraphsbselected = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.9), sm_margin_side, 24, sm_margin_side, gn_margin_bottom, corner_width); smgraphsbselected->set_border_width_all(2 * EDSCALE + border_width); smgraphsbselected->set_border_color(Color(accent_color.r, accent_color.g, accent_color.b, 0.9)); smgraphsbselected->set_shadow_size(8 * EDSCALE); @@ -1484,25 +1660,31 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { graphsbcomment->set_border_width(SIDE_TOP, 24 * EDSCALE); graphsbcommentselected->set_border_width(SIDE_TOP, 24 * EDSCALE); + graphsb->set_corner_detail(corner_radius * EDSCALE); + graphsbselected->set_corner_detail(corner_radius * EDSCALE); + graphsbcomment->set_corner_detail(corner_radius * EDSCALE); + graphsbcommentselected->set_corner_detail(corner_radius * EDSCALE); + theme->set_stylebox("frame", "GraphNode", graphsb); - theme->set_stylebox("selectedframe", "GraphNode", graphsbselected); + theme->set_stylebox("selected_frame", "GraphNode", graphsbselected); theme->set_stylebox("comment", "GraphNode", graphsbcomment); - theme->set_stylebox("commentfocus", "GraphNode", graphsbcommentselected); + theme->set_stylebox("comment_focus", "GraphNode", graphsbcommentselected); theme->set_stylebox("breakpoint", "GraphNode", graphsbbreakpoint); theme->set_stylebox("position", "GraphNode", graphsbposition); + theme->set_stylebox("slot", "GraphNode", graphsbslot); theme->set_stylebox("state_machine_frame", "GraphNode", smgraphsb); - theme->set_stylebox("state_machine_selectedframe", "GraphNode", smgraphsbselected); - - Color default_node_color = dark_color_1.inverted(); - theme->set_color("title_color", "GraphNode", default_node_color); - default_node_color.a = 0.7; - theme->set_color("close_color", "GraphNode", default_node_color); - theme->set_color("resizer_color", "GraphNode", default_node_color); - - theme->set_constant("port_offset", "GraphNode", 14 * EDSCALE); - theme->set_constant("title_h_offset", "GraphNode", -16 * EDSCALE); - theme->set_constant("title_offset", "GraphNode", 20 * EDSCALE); - theme->set_constant("close_h_offset", "GraphNode", 20 * EDSCALE); + theme->set_stylebox("state_machine_selected_frame", "GraphNode", smgraphsbselected); + + Color node_decoration_color = dark_color_1.inverted(); + theme->set_color("title_color", "GraphNode", node_decoration_color); + node_decoration_color.a = 0.7; + theme->set_color("close_color", "GraphNode", node_decoration_color); + theme->set_color("resizer_color", "GraphNode", node_decoration_color); + + theme->set_constant("port_offset", "GraphNode", 0); + theme->set_constant("title_h_offset", "GraphNode", 12 * EDSCALE); + theme->set_constant("title_offset", "GraphNode", 21 * EDSCALE); + theme->set_constant("close_h_offset", "GraphNode", -2 * EDSCALE); theme->set_constant("close_offset", "GraphNode", 20 * EDSCALE); theme->set_constant("separation", "GraphNode", 1 * EDSCALE); @@ -1510,8 +1692,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("resizer", "GraphNode", theme->get_icon(SNAME("GuiResizer"), SNAME("EditorIcons"))); theme->set_icon("port", "GraphNode", theme->get_icon(SNAME("GuiGraphNodePort"), SNAME("EditorIcons"))); + theme->set_font("title_font", "GraphNode", theme->get_font(SNAME("main_bold_msdf"), SNAME("EditorFonts"))); + // GridContainer - theme->set_constant("vseparation", "GridContainer", Math::round(widget_default_margin.y - 2 * EDSCALE)); + theme->set_constant("v_separation", "GridContainer", Math::round(widget_default_margin.y - 2 * EDSCALE)); // FileDialog theme->set_icon("folder", "FileDialog", theme->get_icon(SNAME("Folder"), SNAME("EditorIcons"))); @@ -1522,7 +1706,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); // Use a different color for folder icons to make them easier to distinguish from files. // On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color. - theme->set_color("folder_icon_modulate", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7)); + theme->set_color("folder_icon_color", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7)); theme->set_color("files_disabled", "FileDialog", font_disabled_color); // ColorPicker @@ -1532,6 +1716,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE); theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE); theme->set_icon("screen_picker", "ColorPicker", theme->get_icon(SNAME("ColorPick"), SNAME("EditorIcons"))); + theme->set_icon("shape_circle", "ColorPicker", theme->get_icon(SNAME("PickerShapeCircle"), SNAME("EditorIcons"))); + theme->set_icon("shape_rect", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangle"), SNAME("EditorIcons"))); + theme->set_icon("shape_rect_wheel", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangleWheel"), SNAME("EditorIcons"))); theme->set_icon("add_preset", "ColorPicker", theme->get_icon(SNAME("Add"), SNAME("EditorIcons"))); theme->set_icon("sample_bg", "ColorPicker", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); @@ -1543,7 +1730,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // ColorPresetButton Ref<StyleBoxFlat> preset_sb = make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2); - preset_sb->set_anti_aliased(false); theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb); theme->set_icon("preset_bg", "ColorPresetButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); theme->set_icon("overbright_indicator", "ColorPresetButton", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); @@ -1574,7 +1760,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("preview_picker_label", "ThemeEditor", theme_preview_picker_label_sb); // Dictionary editor add item. - theme->set_stylebox("DictionaryAddItem", "EditorStyles", make_flat_stylebox(prop_subsection_color, 4, 4, 4, 4, corner_radius)); + // Expand to the left and right by 4px to compensate for the dictionary editor margins. + Ref<StyleBoxFlat> style_dictionary_add_item = make_flat_stylebox(prop_subsection_color, 0, 4, 0, 4, corner_radius); + style_dictionary_add_item->set_expand_margin_size(SIDE_LEFT, 4 * EDSCALE); + style_dictionary_add_item->set_expand_margin_size(SIDE_RIGHT, 4 * EDSCALE); + theme->set_stylebox("DictionaryAddItem", "EditorStyles", style_dictionary_add_item); + + Ref<StyleBoxEmpty> vshader_label_style = make_empty_stylebox(2, 1, 2, 1); + theme->set_stylebox("label_style", "VShaderEditor", vshader_label_style); // adaptive script theme constants // for comments and elements with lower relevance @@ -1583,19 +1776,16 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const float mono_value = mono_color.r; const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.07); const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.14); - const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.7); - - // editor main color - const Color main_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0.02, 0.5, 1.0); + const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.27); - const Color symbol_color = Color(0.34, 0.57, 1.0).lerp(mono_color, dark_theme ? 0.5 : 0.3); - const Color keyword_color = Color(1.0, 0.44, 0.52); - const Color control_flow_keyword_color = dark_theme ? Color(1.0, 0.55, 0.8) : Color(0.8, 0.4, 0.6); - const Color basetype_color = dark_theme ? Color(0.26, 1.0, 0.76) : Color(0.0, 0.76, 0.38); - const Color type_color = basetype_color.lerp(mono_color, dark_theme ? 0.4 : 0.3); - const Color usertype_color = basetype_color.lerp(mono_color, dark_theme ? 0.7 : 0.5); - const Color comment_color = dim_color; - const Color string_color = (dark_theme ? Color(1.0, 0.85, 0.26) : Color(1.0, 0.82, 0.09)).lerp(mono_color, dark_theme ? 0.5 : 0.3); + const Color symbol_color = dark_theme ? Color(0.67, 0.79, 1) : Color(0, 0, 0.61); + const Color keyword_color = dark_theme ? Color(1.0, 0.44, 0.52) : Color(0.9, 0.135, 0.51); + const Color control_flow_keyword_color = dark_theme ? Color(1.0, 0.55, 0.8) : Color(0.743, 0.12, 0.8); + const Color base_type_color = dark_theme ? Color(0.26, 1.0, 0.76) : Color(0, 0.6, 0.2); + const Color engine_type_color = dark_theme ? Color(0.56, 1, 0.86) : Color(0.11, 0.55, 0.4); + const Color user_type_color = dark_theme ? Color(0.78, 1, 0.93) : Color(0.18, 0.45, 0.4); + const Color comment_color = dark_theme ? dim_color : Color(0.08, 0.08, 0.08, 0.5); + const Color string_color = dark_theme ? Color(1, 0.93, 0.63) : Color(0.6, 0.42, 0); // Use the brightest background color on a light theme (which generally uses a negative contrast rate). const Color te_background_color = dark_theme ? background_color : dark_color_3; @@ -1604,27 +1794,28 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color completion_existing_color = alpha2; // Same opacity as the scroll grabber editor icon. const Color completion_scroll_color = Color(mono_value, mono_value, mono_value, 0.29); + const Color completion_scroll_hovered_color = Color(mono_value, mono_value, mono_value, 0.4); const Color completion_font_color = font_color; const Color text_color = font_color; const Color line_number_color = dim_color; - const Color safe_line_number_color = dim_color * Color(1, 1.2, 1, 1.5); + const Color safe_line_number_color = dark_theme ? (dim_color * Color(1, 1.2, 1, 1.5)) : Color(0, 0.4, 0, 0.75); const Color caret_color = mono_color; const Color caret_background_color = mono_color.inverted(); - const Color text_selected_color = dark_color_3; - const Color brace_mismatch_color = error_color; + const Color text_selected_color = Color(0, 0, 0, 0); + const Color brace_mismatch_color = dark_theme ? error_color : Color(1, 0.08, 0, 1); const Color current_line_color = alpha1; const Color line_length_guideline_color = dark_theme ? base_color : background_color; const Color word_highlighted_color = alpha1; - const Color number_color = basetype_color.lerp(mono_color, dark_theme ? 0.5 : 0.3); - const Color function_color = main_color; - const Color member_variable_color = main_color.lerp(mono_color, 0.6); + const Color number_color = dark_theme ? Color(0.63, 1, 0.88) : Color(0, 0.55, 0.28, 1); + const Color function_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0, 0.225, 0.9, 1); + const Color member_variable_color = dark_theme ? Color(0.34, 0.7, 1.0).lerp(mono_color, 0.6) : Color(0, 0.4, 0.68, 1); const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3); const Color bookmark_color = Color(0.08, 0.49, 0.98); - const Color breakpoint_color = error_color; + const Color breakpoint_color = dark_theme ? error_color : Color(1, 0.27, 0.2, 1); const Color executing_line_color = Color(0.98, 0.89, 0.27); const Color code_folding_color = alpha3; const Color search_result_color = alpha1; - const Color search_result_border_color = Color(0.41, 0.61, 0.91, 0.38); + const Color search_result_border_color = dark_theme ? Color(0.41, 0.61, 0.91, 0.38) : Color(0, 0.4, 1, 0.38); EditorSettings *setting = EditorSettings::get_singleton(); String text_editor_color_theme = setting->get("text_editor/theme/color_theme"); @@ -1632,9 +1823,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { setting->set_initial_value("text_editor/theme/highlighting/symbol_color", symbol_color, true); setting->set_initial_value("text_editor/theme/highlighting/keyword_color", keyword_color, true); setting->set_initial_value("text_editor/theme/highlighting/control_flow_keyword_color", control_flow_keyword_color, true); - setting->set_initial_value("text_editor/theme/highlighting/base_type_color", basetype_color, true); - setting->set_initial_value("text_editor/theme/highlighting/engine_type_color", type_color, true); - setting->set_initial_value("text_editor/theme/highlighting/user_type_color", usertype_color, true); + setting->set_initial_value("text_editor/theme/highlighting/base_type_color", base_type_color, true); + setting->set_initial_value("text_editor/theme/highlighting/engine_type_color", engine_type_color, true); + setting->set_initial_value("text_editor/theme/highlighting/user_type_color", user_type_color, true); setting->set_initial_value("text_editor/theme/highlighting/comment_color", comment_color, true); setting->set_initial_value("text_editor/theme/highlighting/string_color", string_color, true); setting->set_initial_value("text_editor/theme/highlighting/background_color", te_background_color, true); @@ -1642,6 +1833,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { setting->set_initial_value("text_editor/theme/highlighting/completion_selected_color", completion_selected_color, true); setting->set_initial_value("text_editor/theme/highlighting/completion_existing_color", completion_existing_color, true); setting->set_initial_value("text_editor/theme/highlighting/completion_scroll_color", completion_scroll_color, true); + setting->set_initial_value("text_editor/theme/highlighting/completion_scroll_hovered_color", completion_scroll_hovered_color, true); setting->set_initial_value("text_editor/theme/highlighting/completion_font_color", completion_font_color, true); setting->set_initial_value("text_editor/theme/highlighting/text_color", text_color, true); setting->set_initial_value("text_editor/theme/highlighting/line_number_color", line_number_color, true); @@ -1669,11 +1861,29 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { } // Now theme is loaded, apply it to CodeEdit. - theme->set_color("background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/background_color")); + theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts"))); + theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts"))); + + Ref<StyleBoxFlat> code_edit_stylebox = make_flat_stylebox(EDITOR_GET("text_editor/theme/highlighting/background_color"), widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y, corner_radius); + theme->set_stylebox("normal", "CodeEdit", code_edit_stylebox); + theme->set_stylebox("read_only", "CodeEdit", code_edit_stylebox); + theme->set_stylebox("focus", "CodeEdit", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); + + theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); + theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); + theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), SNAME("EditorIcons"))); + theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("CodeFoldDownArrow"), SNAME("EditorIcons"))); + theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), SNAME("EditorIcons"))); + theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons"))); + + theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); + + theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0)); theme->set_color("completion_background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_background_color")); theme->set_color("completion_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_selected_color")); theme->set_color("completion_existing_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_existing_color")); theme->set_color("completion_scroll_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_scroll_color")); + theme->set_color("completion_scroll_hovered_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_scroll_hovered_color")); theme->set_color("completion_font_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_font_color")); theme->set_color("font_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/text_color")); theme->set_color("line_number_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/line_number_color")); @@ -1697,7 +1907,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<Theme> create_custom_theme(const Ref<Theme> p_theme) { Ref<Theme> theme = create_editor_theme(p_theme); - const String custom_theme_path = EditorSettings::get_singleton()->get("interface/theme/custom_theme"); + const String custom_theme_path = EDITOR_GET("interface/theme/custom_theme"); if (!custom_theme_path.is_empty()) { Ref<Theme> custom_theme = ResourceLoader::load(custom_theme_path); if (custom_theme.is_valid()) { @@ -1708,14 +1918,14 @@ Ref<Theme> create_custom_theme(const Ref<Theme> p_theme) { return theme; } -Ref<ImageTexture> create_unscaled_default_project_icon() { -#ifdef MODULE_SVG_ENABLED +/** + * Returns the SVG code for the default project icon. + */ +String get_default_project_icon() { for (int i = 0; i < editor_icons_count; i++) { - // ESCALE should never affect size of the icon if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0) { - return editor_generate_icon(i, false, 1.0); + return String(editor_icons_sources[i]); } } -#endif - return Ref<ImageTexture>(memnew(ImageTexture)); + return String(); } |