diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 69319d1d4959..f29b85167374 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -334,7 +334,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { } } - Color dc = get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)); + Color dc = get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)); Ref remove = get_editor_theme_icon(SNAME("Remove")); float remove_hpos = limit - hsep - remove->get_width(); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 404bfdbd7c95..3c704b34733a 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1921,7 +1921,7 @@ void AnimationTrackEdit::_notification(int p_what) { Color linecolor = color; linecolor.a = 0.2; - Color dc = get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)); + Color dc = get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)); // NAMES AND ICONS // diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 228019881577..da0182b17615 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -306,7 +306,7 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type)); if (!instantiable) { - r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + r_item->set_custom_color(0, search_options->get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); } HashMap::Iterator class_doc = EditorHelp::get_doc_data()->class_list.find(p_type); diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp index 0677064f28ef..3d10b7949eb8 100644 --- a/editor/editor_build_profile.cpp +++ b/editor/editor_build_profile.cpp @@ -601,7 +601,7 @@ void EditorBuildProfileManager::_fill_classes_from(TreeItem *p_parent, const Str bool disabled = edited->is_class_disabled(p_class); if (disabled) { - class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + class_item->set_custom_color(0, class_list->get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); } class_item->set_text(0, text); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 8c64ce1c70c4..aa44ea380b89 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -503,7 +503,7 @@ void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const S bool disabled_editor = edited->is_class_editor_disabled(p_class); bool disabled_properties = edited->has_class_properties_disabled(p_class); if (disabled) { - class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + class_item->set_custom_color(0, class_list->get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); } else if (disabled_editor && disabled_properties) { text += " " + TTR("(Editor Disabled, Properties Disabled)"); } else if (disabled_properties) { diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index 40c26689b81f..b200154ec8c0 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -698,5 +698,5 @@ EditorHelpSearch::Runner::Runner(Control *p_icon_service, Tree *p_results_tree, results_tree(p_results_tree), term((p_search_flags & SEARCH_CASE_SENSITIVE) == 0 ? p_term.strip_edges().to_lower() : p_term.strip_edges()), search_flags(p_search_flags), - disabled_color(ui_service->get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))) { + disabled_color(ui_service->get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))) { } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index b7704da063dc..a3530fc9abdd 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1357,7 +1357,7 @@ void EditorInspectorSection::_notification(int p_what) { Ref light_font = get_theme_font(SNAME("main"), EditorStringName(EditorFonts)); int light_font_size = get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts)); - Color light_font_color = get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor)); + Color light_font_color = get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)); // Can we fit the long version of the revertable count text? num_revertable_str = vformat(TTRN("(%d change)", "(%d changes)", revertable_properties.size()), revertable_properties.size()); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 528bc0a758d3..521477d4706e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5978,6 +5978,7 @@ void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) { void EditorNode::_update_renderer_color() { String rendering_method = renderer->get_selected_metadata(); + // TODO: Use theme colors instead of hardcoded values. if (rendering_method == "forward_plus") { renderer->add_theme_color_override("font_color", Color::hex(0x5d8c3fff)); } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 16f808367f99..f237649c5dee 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -992,12 +992,12 @@ void EditorPropertyLayersGrid::_notification(int p_what) { const int bsize = (grid_size.height * 80 / 100) / 2; const int h = bsize * 2 + 1; - Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), EditorStringName(Editor)); + Color color = get_theme_color(read_only ? SNAME("highlight_disabled_color") : SNAME("highlight_color"), EditorStringName(Editor)); - Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), EditorStringName(Editor)); + Color text_color = get_theme_color(read_only ? SNAME("font_disabled_color") : SNAME("font_color"), EditorStringName(Editor)); text_color.a *= 0.5; - Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), EditorStringName(Editor)); + Color text_color_on = get_theme_color(read_only ? SNAME("font_disabled_color") : SNAME("font_hover_color"), EditorStringName(Editor)); text_color_on.a *= 0.7; const int vofs = (grid_size.height - h) / 2; @@ -2073,7 +2073,7 @@ void EditorPropertyQuaternion::_notification(int p_what) { euler[i]->add_theme_color_override("label_color", colors[i]); } edit_button->set_icon(get_editor_theme_icon(SNAME("Edit"))); - euler_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("property_color"), EditorStringName(Editor))); + euler_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("property_color"), SNAME("EditorProperty"))); warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning"))); warning->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), EditorStringName(Editor))); } break; diff --git a/editor/export/export_template_manager.cpp b/editor/export/export_template_manager.cpp index f470d4f3fd43..69ad076f8a0b 100644 --- a/editor/export/export_template_manager.cpp +++ b/editor/export/export_template_manager.cpp @@ -758,7 +758,7 @@ void ExportTemplateManager::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { current_value->add_theme_font_override("font", get_theme_font(SNAME("main"), EditorStringName(EditorFonts))); current_missing_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), EditorStringName(Editor))); - current_installed_label->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + current_installed_label->add_theme_color_override("font_color", get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); mirror_options_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); } break; diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index a47fdbf222cb..63bd87e6cc00 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -824,7 +824,7 @@ void ProjectExportDialog::_setup_item_for_file_mode(TreeItem *p_item, EditorExpo p_item->set_cell_mode(1, TreeItem::CELL_MODE_STRING); p_item->set_editable(1, false); p_item->set_selectable(1, false); - p_item->set_custom_color(1, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + p_item->set_custom_color(1, get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); } else { p_item->set_checked(0, true); p_item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index 7e6f06bf776a..7a9df26fa7f8 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -235,7 +235,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->add_button(0, get_editor_theme_icon(SNAME("Script")), BUTTON_SCRIPT); } else { //has no script (or script is a custom type) - _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + _set_item_custom_color(item, get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); item->set_selectable(0, false); if (!scr.is_null()) { // make sure to mark the script if a custom type @@ -267,7 +267,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->set_selectable(0, marked_selectable); _set_item_custom_color(item, get_theme_color(SNAME("accent_color"), EditorStringName(Editor))); } else if (!p_node->can_process()) { - _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + _set_item_custom_color(item, get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); } else if (!marked_selectable && !marked_children_selectable) { Node *node = p_node; while (node) { @@ -492,7 +492,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (!valid) { - _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + _set_item_custom_color(item, get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); item->set_selectable(0, false); } } @@ -718,7 +718,7 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select } p_parent->set_selectable(0, true); } else if (keep_for_children) { - p_parent->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + p_parent->set_custom_color(0, get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); p_parent->set_selectable(0, false); p_parent->deselect(0); } diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 950a75c22144..20129556860a 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -417,7 +417,6 @@ void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asse void EditorAssetLibraryItemDownload::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("AssetLib"))); status->add_theme_color_override("font_color", get_theme_color(SNAME("status_color"), SNAME("AssetLib"))); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 145ecf65bc65..8c3fe82f36f4 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -852,10 +852,9 @@ bool ThemeItemImportTree::has_selected_items() const { void ThemeItemImportTree::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { select_icons_warning_icon->set_texture(get_editor_theme_icon(SNAME("StatusWarning"))); - select_icons_warning->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + select_icons_warning->add_theme_color_override("font_color", get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); import_items_filter->set_right_icon(get_editor_theme_icon(SNAME("Search"))); @@ -2470,7 +2469,7 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_rename_cancel_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_canceled).bind(p_data_type, p_item_name, item_name_container)); item_rename_cancel_button->hide(); } else { - item_name->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), EditorStringName(Editor))); + item_name->add_theme_color_override("font_color", get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); Button *item_override_button = memnew(Button); item_override_button->set_icon(get_editor_theme_icon(SNAME("Add"))); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 8e65ad3b8e11..e3710adc836d 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -735,7 +735,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { tile_data_editors["probability"] = tile_data_probability_editor; } - Color disabled_color = get_theme_color("disabled_font_color", EditorStringName(Editor)); + Color disabled_color = get_theme_color("font_disabled_color", EditorStringName(Editor)); // --- Physics --- ADD_TILE_DATA_EDITOR_GROUP(TTR("Physics")); diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index 5a67531f861c..f243da3c1837 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -84,213 +84,20 @@ Ref make_line_stylebox(Color p_color, int p_thickness = 1, float p return style; } -static void populate_editor_theme(const Ref &theme, const Ref &p_old_theme) { - // Controls may rely on the scale for their internal drawing logic. - theme->set_default_base_scale(EDSCALE); +// Theme generation and population routines. - // Theme settings - Color accent_color = EDITOR_GET("interface/theme/accent_color"); - Color base_color = EDITOR_GET("interface/theme/base_color"); - float contrast = EDITOR_GET("interface/theme/contrast"); - bool increase_scrollbar_touch_area = EDITOR_GET("interface/touchscreen/increase_scrollbar_touch_area"); - const float gizmo_handle_scale = EDITOR_GET("interface/touchscreen/scale_gizmo_handles"); - bool draw_extra_borders = EDITOR_GET("interface/theme/draw_extra_borders"); - float icon_saturation = EDITOR_GET("interface/theme/icon_saturation"); - float relationship_line_opacity = EDITOR_GET("interface/theme/relationship_line_opacity"); +Ref EditorThemeManager::_create_base_theme(const Ref &p_old_theme) { + OS::get_singleton()->benchmark_begin_measure("EditorTheme", "Create Base Theme"); - String preset = EDITOR_GET("interface/theme/preset"); + Ref theme = memnew(EditorTheme); + ThemeConfiguration config = _create_theme_config(theme); + _create_shared_styles(theme, config); - int border_size = EDITOR_GET("interface/theme/border_size"); - int corner_radius = EDITOR_GET("interface/theme/corner_radius"); - - Color preset_accent_color; - Color preset_base_color; - float preset_contrast = 0; - bool preset_draw_extra_borders = false; - - const float default_contrast = 0.3; - - // Please use alphabetical order if you're adding a new theme here - // (after "Custom") - - if (preset == "Custom") { - accent_color = EDITOR_GET("interface/theme/accent_color"); - base_color = EDITOR_GET("interface/theme/base_color"); - contrast = EDITOR_GET("interface/theme/contrast"); - } else if (preset == "Breeze Dark") { - preset_accent_color = Color(0.26, 0.76, 1.00); - preset_base_color = Color(0.24, 0.26, 0.28); - preset_contrast = default_contrast; - } else if (preset == "Godot 2") { - 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 == "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") { - preset_accent_color = Color(0.18, 0.50, 1.00); - preset_base_color = Color(0.9, 0.9, 0.9); - // A negative contrast rate looks better for light themes, since it better follows the natural order of UI "elevation". - preset_contrast = -0.06; - } else if (preset == "Solarized (Dark)") { - preset_accent_color = Color(0.15, 0.55, 0.82); - preset_base_color = Color(0.04, 0.23, 0.27); - preset_contrast = default_contrast; - } else if (preset == "Solarized (Light)") { - preset_accent_color = Color(0.15, 0.55, 0.82); - preset_base_color = Color(0.89, 0.86, 0.79); - // A negative contrast rate looks better for light themes, since it better follows the natural order of UI "elevation". - preset_contrast = -0.06; - } else if (preset == "Black (OLED)") { - preset_accent_color = Color(0.45, 0.75, 1.0); - preset_base_color = Color(0, 0, 0); - // The contrast rate value is irrelevant on a fully black theme. - preset_contrast = 0.0; - preset_draw_extra_borders = true; - } else { // Default - preset_accent_color = Color(0.44, 0.73, 0.98); - preset_base_color = Color(0.21, 0.24, 0.29); - preset_contrast = default_contrast; - } - - if (preset != "Custom") { - accent_color = preset_accent_color; - base_color = preset_base_color; - contrast = preset_contrast; - draw_extra_borders = preset_draw_extra_borders; - EditorSettings::get_singleton()->set_initial_value("interface/theme/accent_color", accent_color); - EditorSettings::get_singleton()->set_initial_value("interface/theme/base_color", base_color); - EditorSettings::get_singleton()->set_initial_value("interface/theme/contrast", contrast); - EditorSettings::get_singleton()->set_initial_value("interface/theme/draw_extra_borders", draw_extra_borders); - } - - EditorSettings::get_singleton()->set_manually("interface/theme/preset", preset); - EditorSettings::get_singleton()->set_manually("interface/theme/accent_color", accent_color); - EditorSettings::get_singleton()->set_manually("interface/theme/base_color", base_color); - EditorSettings::get_singleton()->set_manually("interface/theme/contrast", contrast); - EditorSettings::get_singleton()->set_manually("interface/theme/draw_extra_borders", draw_extra_borders); - - // Colors - bool dark_theme = EditorSettings::get_singleton()->is_dark_theme(); - - // 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(); - const Color dark_color_2 = base_color.lerp(Color(0, 0, 0, 1), contrast * 1.5).clamp(); - const Color dark_color_3 = base_color.lerp(Color(0, 0, 0, 1), contrast * 2).clamp(); - - // Only used when the Draw Extra Borders editor setting is enabled. - const Color extra_border_color_1 = Color(0.5, 0.5, 0.5); - const Color extra_border_color_2 = dark_theme ? Color(0.3, 0.3, 0.3) : Color(0.7, 0.7, 0.7); - - const Color background_color = dark_color_2; - - // White (dark theme) or black (light theme), will be used to generate the rest of the colors - const Color mono_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0); - - const Color contrast_color_1 = base_color.lerp(mono_color, MAX(contrast, default_contrast)); - const Color contrast_color_2 = base_color.lerp(mono_color, MAX(contrast * 1.5, default_contrast * 1.5)); - - 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.35); - 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); - const Color font_outline_color = Color(0, 0, 0, 0); - const Color selection_color = accent_color * Color(1, 1, 1, 0.4); - const Color disabled_color = mono_color.inverted().lerp(base_color, 0.7); - const Color disabled_bg_color = mono_color.inverted().lerp(base_color, 0.9); - - const Color icon_normal_color = Color(1, 1, 1); - 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); - icon_pressed_color.a = 1.0; - - const Color separator_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.1); - 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); - - // Can't save single float in theme, so using Color. - theme->set_color("icon_saturation", EditorStringName(Editor), Color(icon_saturation, icon_saturation, icon_saturation)); - theme->set_color("accent_color", EditorStringName(Editor), accent_color); - theme->set_color("highlight_color", EditorStringName(Editor), highlight_color); - theme->set_color("disabled_highlight_color", EditorStringName(Editor), disabled_highlight_color); - theme->set_color("base_color", EditorStringName(Editor), base_color); - theme->set_color("dark_color_1", EditorStringName(Editor), dark_color_1); - theme->set_color("dark_color_2", EditorStringName(Editor), dark_color_2); - theme->set_color("dark_color_3", EditorStringName(Editor), dark_color_3); - theme->set_color("contrast_color_1", EditorStringName(Editor), contrast_color_1); - theme->set_color("contrast_color_2", EditorStringName(Editor), contrast_color_2); - theme->set_color("box_selection_fill_color", EditorStringName(Editor), accent_color * Color(1, 1, 1, 0.3)); - theme->set_color("box_selection_stroke_color", EditorStringName(Editor), accent_color * Color(1, 1, 1, 0.8)); - - theme->set_color("axis_x_color", EditorStringName(Editor), Color(0.96, 0.20, 0.32)); - theme->set_color("axis_y_color", EditorStringName(Editor), Color(0.53, 0.84, 0.01)); - theme->set_color("axis_z_color", EditorStringName(Editor), Color(0.16, 0.55, 0.96)); - theme->set_color("axis_w_color", EditorStringName(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(); - - theme->set_color("property_color_x", EditorStringName(Editor), Color().from_hsv(0.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); - theme->set_color("property_color_y", EditorStringName(Editor), Color().from_hsv(1.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); - theme->set_color("property_color_z", EditorStringName(Editor), Color().from_hsv(2.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); - theme->set_color("property_color_w", EditorStringName(Editor), Color().from_hsv(1.5 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); - - theme->set_color("font_color", EditorStringName(Editor), font_color); - theme->set_color("highlighted_font_color", EditorStringName(Editor), font_hover_color); - theme->set_color("disabled_font_color", EditorStringName(Editor), font_disabled_color); - theme->set_color("readonly_font_color", EditorStringName(Editor), font_readonly_color); - - theme->set_color("mono_color", EditorStringName(Editor), mono_color); - - Color success_color = Color(0.45, 0.95, 0.5); - 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.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. - 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); - } - - theme->set_color("success_color", EditorStringName(Editor), success_color); - theme->set_color("warning_color", EditorStringName(Editor), warning_color); - theme->set_color("error_color", EditorStringName(Editor), error_color); - theme->set_color("property_color", EditorStringName(Editor), property_color); - theme->set_color("readonly_color", EditorStringName(Editor), readonly_color); - - if (!dark_theme) { - theme->set_color("highend_color", EditorStringName(Editor), Color::hex(0xad1128ff)); - } else { - theme->set_color("highend_color", EditorStringName(Editor), Color(1.0, 0.0, 0.0)); - } - - const int thumb_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); - theme->set_constant("scale", EditorStringName(Editor), EDSCALE); - theme->set_constant("thumb_size", EditorStringName(Editor), thumb_size); - theme->set_constant("class_icon_size", EditorStringName(Editor), 16 * EDSCALE); - theme->set_constant("dark_theme", EditorStringName(Editor), dark_theme); - theme->set_constant("color_picker_button_height", EditorStringName(Editor), 28 * EDSCALE); - theme->set_constant("gizmo_handle_scale", EditorStringName(Editor), gizmo_handle_scale); - theme->set_constant("window_border_margin", EditorStringName(Editor), 8); - theme->set_constant("top_bar_separation", EditorStringName(Editor), 8 * EDSCALE); + // FIXME: Make the comparison more robust and fix imprecision issues by hashing affecting values. + // TODO: Refactor the icons check into their respective file, and add a similar check for fonts. // Register editor icons. - // If the settings are comparable to the old theme, then just copy them over. + // If settings are comparable to the old theme, then just copy existing icons over. // Otherwise, regenerate them. Also check if we need to regenerate "thumb" icons. bool keep_old_icons = false; bool regenerate_thumb_icons = true; @@ -306,1610 +113,2040 @@ static void populate_editor_theme(const Ref &theme, const Ref &p_o const float prev_gizmo_handle_scale = (float)p_old_theme->get_constant(SNAME("gizmo_handle_scale"), EditorStringName(Editor)); keep_old_icons = (Math::is_equal_approx(prev_scale, EDSCALE) && - Math::is_equal_approx(prev_gizmo_handle_scale, gizmo_handle_scale) && - prev_dark_theme == dark_theme && - prev_accent_color == accent_color && - prev_icon_saturation == icon_saturation); + Math::is_equal_approx(prev_gizmo_handle_scale, config.gizmo_handle_scale) && + prev_dark_theme == config.dark_theme && + prev_accent_color == config.accent_color && + prev_icon_saturation == config.icon_saturation); const double prev_thumb_size = (double)p_old_theme->get_constant(SNAME("thumb_size"), EditorStringName(Editor)); - regenerate_thumb_icons = !Math::is_equal_approx(prev_thumb_size, thumb_size); + regenerate_thumb_icons = !Math::is_equal_approx(prev_thumb_size, config.thumb_size); } - editor_configure_icons(dark_theme); + // External functions, see editor_icons.cpp. + editor_configure_icons(config.dark_theme); if (keep_old_icons) { editor_copy_icons(theme, p_old_theme); } else { - editor_register_icons(theme, dark_theme, icon_saturation, thumb_size, false); + editor_register_icons(theme, config.dark_theme, config.icon_saturation, config.thumb_size, false); } if (regenerate_thumb_icons) { - editor_register_icons(theme, dark_theme, icon_saturation, thumb_size, true); + editor_register_icons(theme, config.dark_theme, config.icon_saturation, config.thumb_size, true); } - // Register editor fonts. + // External function, see editor_fonts.cpp. editor_register_fonts(theme); - // Ensure borders are visible when using an editor scale below 100%. - const int border_width = CLAMP(border_size, 0, 2) * MAX(1, EDSCALE); - const int corner_width = CLAMP(corner_radius, 0, 6); - const int default_margin_size = 4; - const int margin_size_extra = default_margin_size + CLAMP(border_size, 0, 2); - - // Styleboxes - // This is the most commonly used stylebox, variations should be made as duplicate of this - Ref style_default = make_flat_stylebox(base_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size, corner_width); - style_default->set_border_width_all(border_width); - style_default->set_border_color(base_color); - - // Button and widgets - const float extra_spacing = EDITOR_GET("interface/theme/additional_spacing"); - - const Vector2 widget_default_margin = Vector2(extra_spacing + 6, extra_spacing + default_margin_size + 1) * EDSCALE; - - Ref style_widget = style_default->duplicate(); - style_widget->set_content_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); - if (draw_extra_borders) { - style_widget->set_border_width_all(Math::round(EDSCALE)); - style_widget->set_border_color(extra_border_color_1); - } else { - style_widget->set_border_color(dark_color_2); - } - - Ref style_widget_disabled = style_widget->duplicate(); - if (draw_extra_borders) { - style_widget_disabled->set_border_color(extra_border_color_2); - } else { - style_widget_disabled->set_border_color(disabled_color); - } - style_widget_disabled->set_bg_color(disabled_bg_color); - - Ref style_widget_focus = style_widget->duplicate(); - style_widget_focus->set_draw_center(false); - style_widget_focus->set_border_width_all(Math::round(2 * MAX(1, EDSCALE))); - style_widget_focus->set_border_color(accent_color); - - Ref style_widget_pressed = style_widget->duplicate(); - style_widget_pressed->set_bg_color(dark_color_1.darkened(0.125)); - - Ref style_widget_hover = style_widget->duplicate(); - style_widget_hover->set_bg_color(mono_color * Color(1, 1, 1, 0.11)); - if (draw_extra_borders) { - style_widget_hover->set_border_color(extra_border_color_1); - } else { - style_widget_hover->set_border_color(mono_color * Color(1, 1, 1, 0.05)); - } - - // Style for windows, popups, etc.. - Ref style_popup = style_default->duplicate(); - const int popup_margin_size = default_margin_size * EDSCALE * 3; - style_popup->set_content_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 style_popup_separator(memnew(StyleBoxLine)); - style_popup_separator->set_color(separator_color); - style_popup_separator->set_grow_begin(popup_margin_size - MAX(Math::round(EDSCALE), border_width)); - style_popup_separator->set_grow_end(popup_margin_size - MAX(Math::round(EDSCALE), border_width)); - style_popup_separator->set_thickness(MAX(Math::round(EDSCALE), border_width)); - - Ref style_popup_labeled_separator_left(memnew(StyleBoxLine)); - style_popup_labeled_separator_left->set_grow_begin(popup_margin_size - MAX(Math::round(EDSCALE), border_width)); - style_popup_labeled_separator_left->set_color(separator_color); - style_popup_labeled_separator_left->set_thickness(MAX(Math::round(EDSCALE), border_width)); - - Ref style_popup_labeled_separator_right(memnew(StyleBoxLine)); - style_popup_labeled_separator_right->set_grow_end(popup_margin_size - MAX(Math::round(EDSCALE), border_width)); - style_popup_labeled_separator_right->set_color(separator_color); - style_popup_labeled_separator_right->set_thickness(MAX(Math::round(EDSCALE), border_width)); - - Ref style_empty = make_empty_stylebox(default_margin_size, default_margin_size, default_margin_size, default_margin_size); - - // TabBar - - Ref style_tab_base = style_widget->duplicate(); - - 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_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(SIDE_LEFT, -border_width); - - style_tab_base->set_content_margin(SIDE_LEFT, widget_default_margin.x + 5 * EDSCALE); - style_tab_base->set_content_margin(SIDE_RIGHT, widget_default_margin.x + 5 * EDSCALE); - style_tab_base->set_content_margin(SIDE_BOTTOM, widget_default_margin.y); - style_tab_base->set_content_margin(SIDE_TOP, widget_default_margin.y); - - Ref style_tab_selected = style_tab_base->duplicate(); - - 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 style_tab_hovered = style_tab_base->duplicate(); - - style_tab_hovered->set_bg_color(dark_color_1.lerp(base_color, 0.4)); - // Hovered tab has a subtle highlight between normal and selected states. - style_tab_hovered->set_corner_radius_all(0); - - Ref style_tab_unselected = style_tab_base->duplicate(); - style_tab_unselected->set_expand_margin(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)); - - Ref style_tab_disabled = style_tab_base->duplicate(); - style_tab_disabled->set_expand_margin(SIDE_BOTTOM, 0); - style_tab_disabled->set_bg_color(disabled_bg_color); - style_tab_disabled->set_border_color(disabled_bg_color); - - Ref style_tab_focus = style_widget_focus->duplicate(); - - // Editor background - Color background_color_opaque = background_color; - background_color_opaque.a = 1.0; - theme->set_color("background", EditorStringName(Editor), background_color_opaque); - theme->set_stylebox("Background", EditorStringName(EditorStyles), make_flat_stylebox(background_color_opaque, default_margin_size, default_margin_size, default_margin_size, default_margin_size)); - - // Focus - theme->set_stylebox("Focus", EditorStringName(EditorStyles), style_widget_focus); - // Use a less opaque color to be less distracting for the 2D and 3D editor viewports. - Ref style_widget_focus_viewport = style_widget_focus->duplicate(); - style_widget_focus_viewport->set_border_color(accent_color * Color(1, 1, 1, 0.5)); - theme->set_stylebox("FocusViewport", EditorStringName(EditorStyles), style_widget_focus_viewport); - - // Menu - Ref style_menu = style_widget->duplicate(); - style_menu->set_draw_center(false); - style_menu->set_border_width_all(0); - theme->set_stylebox("panel", "PanelContainer", style_menu); - theme->set_stylebox("MenuPanel", EditorStringName(EditorStyles), style_menu); - - // CanvasItem Editor - Ref style_canvas_editor_info = make_flat_stylebox(Color(0.0, 0.0, 0.0, 0.2)); - style_canvas_editor_info->set_expand_margin_all(4 * EDSCALE); - theme->set_stylebox("CanvasItemInfoOverlay", EditorStringName(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 toolbar_stylebox = memnew(StyleBoxFlat); - toolbar_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1)); - 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_content_margin(SIDE_BOTTOM, 0); - toolbar_stylebox->set_expand_margin_individual(4 * EDSCALE, 2 * EDSCALE, 4 * EDSCALE, 4 * EDSCALE); - theme->set_stylebox("ContextualToolbar", EditorStringName(EditorStyles), toolbar_stylebox); - - // Script Editor - theme->set_stylebox("ScriptEditorPanel", EditorStringName(EditorStyles), make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size)); - theme->set_stylebox("ScriptEditorPanelFloating", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); - - theme->set_stylebox("ScriptEditor", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); - - // Launch Pad and Play buttons - Ref 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", EditorStringName(EditorStyles), style_launch_pad); - Ref 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", EditorStringName(EditorStyles), style_launch_pad_movie); - - theme->set_stylebox("MovieWriterButtonNormal", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); - Ref 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_content_margin(SIDE_TOP, 0); - style_write_movie_button->set_content_margin(SIDE_BOTTOM, 0); - style_write_movie_button->set_content_margin(SIDE_LEFT, 0); - style_write_movie_button->set_content_margin(SIDE_RIGHT, 0); - style_write_movie_button->set_expand_margin(SIDE_RIGHT, 2 * EDSCALE); - theme->set_stylebox("MovieWriterButtonPressed", EditorStringName(EditorStyles), style_write_movie_button); - - // MenuButton - theme->set_stylebox("normal", "MenuButton", style_menu); - theme->set_stylebox("hover", "MenuButton", style_widget_hover); - theme->set_stylebox("pressed", "MenuButton", style_menu); - theme->set_stylebox("focus", "MenuButton", style_menu); - theme->set_stylebox("disabled", "MenuButton", style_menu); - - 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_color("font_outline_color", "MenuButton", font_outline_color); - - theme->set_constant("outline_size", "MenuButton", 0); - - theme->set_stylebox("MenuHover", EditorStringName(EditorStyles), style_widget_hover); - - // Buttons - theme->set_stylebox("normal", "Button", style_widget); - theme->set_stylebox("hover", "Button", style_widget_hover); - theme->set_stylebox("pressed", "Button", style_widget_pressed); - theme->set_stylebox("focus", "Button", style_widget_focus); - theme->set_stylebox("disabled", "Button", style_widget_disabled); - - 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("font_outline_color", "Button", font_outline_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); - - theme->set_constant("h_separation", "Button", 4 * EDSCALE); - theme->set_constant("outline_size", "Button", 0); - - // Flat button variations. - - Ref style_flat_button = make_empty_stylebox(); - for (int i = 0; i < 4; i++) { - style_flat_button->set_content_margin((Side)i, style_widget->get_margin((Side)i) + style_widget->get_border_width((Side)i)); - } - - Ref style_flat_button_pressed = style_widget_pressed->duplicate(); - Color flat_pressed_color = dark_color_1.lightened(0.24).lerp(accent_color, 0.2) * Color(0.8, 0.8, 0.8, 0.85); - if (dark_theme) { - flat_pressed_color = dark_color_1.lerp(accent_color, 0.12) * Color(0.6, 0.6, 0.6, 0.85); - } - style_flat_button_pressed->set_bg_color(flat_pressed_color); - - theme->set_stylebox("normal", "FlatButton", style_flat_button); - theme->set_stylebox("hover", "FlatButton", style_flat_button); - theme->set_stylebox("pressed", "FlatButton", style_flat_button_pressed); - theme->set_stylebox("disabled", "FlatButton", style_flat_button); - - theme->set_stylebox("normal", "FlatMenuButton", style_flat_button); - theme->set_stylebox("hover", "FlatMenuButton", style_flat_button); - theme->set_stylebox("pressed", "FlatMenuButton", style_flat_button_pressed); - theme->set_stylebox("disabled", "FlatMenuButton", style_flat_button); - - 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 style_inspector_action = style_widget->duplicate(); - style_inspector_action->set_bg_color(color_inspector_action); - style_inspector_action->set_content_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_content_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_content_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_content_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", icon_disabled_color); - // When pressed, add a small bottom border to the buttons to better show their active state, - // similar to active tabs. - - Ref editor_log_button_pressed = style_flat_button_pressed->duplicate(); - editor_log_button_pressed->set_border_width(SIDE_BOTTOM, 2 * EDSCALE); - editor_log_button_pressed->set_border_color(accent_color); - theme->set_stylebox("pressed", "EditorLogFilterButton", editor_log_button_pressed); - - // Buttons in material previews - const Color dim_light_color = icon_normal_color.darkened(0.24); - const Color dim_light_highlighted_color = icon_normal_color.darkened(0.18); - Ref sb_empty_borderless = make_empty_stylebox(); - - theme->set_type_variation("PreviewLightButton", "Button"); - // When pressed, don't use the accent color tint. When unpressed, dim the icon. - theme->set_color("icon_normal_color", "PreviewLightButton", dim_light_color); - theme->set_color("icon_focus_color", "PreviewLightButton", dim_light_color); - theme->set_color("icon_pressed_color", "PreviewLightButton", icon_normal_color); - theme->set_color("icon_hover_pressed_color", "PreviewLightButton", icon_normal_color); - // Unpressed icon is dim, so use a dim highlight. - theme->set_color("icon_hover_color", "PreviewLightButton", dim_light_highlighted_color); - - theme->set_stylebox("normal", "PreviewLightButton", sb_empty_borderless); - theme->set_stylebox("hover", "PreviewLightButton", sb_empty_borderless); - theme->set_stylebox("focus", "PreviewLightButton", sb_empty_borderless); - theme->set_stylebox("pressed", "PreviewLightButton", sb_empty_borderless); - - // ProjectTag - { - theme->set_type_variation("ProjectTag", "Button"); - - Ref tag = style_widget->duplicate(); - tag->set_bg_color(dark_theme ? tag->get_bg_color().lightened(0.2) : tag->get_bg_color().darkened(0.2)); - tag->set_corner_radius(CORNER_TOP_LEFT, 0); - tag->set_corner_radius(CORNER_BOTTOM_LEFT, 0); - tag->set_corner_radius(CORNER_TOP_RIGHT, 4); - tag->set_corner_radius(CORNER_BOTTOM_RIGHT, 4); - theme->set_stylebox("normal", "ProjectTag", tag); - - tag = style_widget_hover->duplicate(); - tag->set_corner_radius(CORNER_TOP_LEFT, 0); - tag->set_corner_radius(CORNER_BOTTOM_LEFT, 0); - tag->set_corner_radius(CORNER_TOP_RIGHT, 4); - tag->set_corner_radius(CORNER_BOTTOM_RIGHT, 4); - theme->set_stylebox("hover", "ProjectTag", tag); - - tag = style_widget_pressed->duplicate(); - tag->set_corner_radius(CORNER_TOP_LEFT, 0); - tag->set_corner_radius(CORNER_BOTTOM_LEFT, 0); - tag->set_corner_radius(CORNER_TOP_RIGHT, 4); - tag->set_corner_radius(CORNER_BOTTOM_RIGHT, 4); - theme->set_stylebox("pressed", "ProjectTag", tag); - } - - // 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("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("font_outline_color", "MenuBar", font_outline_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); - - theme->set_constant("h_separation", "MenuBar", 4 * EDSCALE); - theme->set_constant("outline_size", "MenuBar", 0); - - // OptionButton - Ref style_option_button_focus = style_widget_focus->duplicate(); - Ref style_option_button_normal = style_widget->duplicate(); - Ref style_option_button_hover = style_widget_hover->duplicate(); - Ref style_option_button_pressed = style_widget_pressed->duplicate(); - Ref style_option_button_disabled = style_widget_disabled->duplicate(); - - style_option_button_focus->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); - style_option_button_normal->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); - style_option_button_hover->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); - style_option_button_pressed->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); - style_option_button_disabled->set_content_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_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("font_outline_color", "OptionButton", font_outline_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"), EditorStringName(EditorIcons))); - theme->set_constant("arrow_margin", "OptionButton", widget_default_margin.x - 2 * EDSCALE); - theme->set_constant("modulate_arrow", "OptionButton", true); - theme->set_constant("h_separation", "OptionButton", 4 * EDSCALE); - theme->set_constant("outline_size", "OptionButton", 0); - - // 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("checked", "CheckButton", theme->get_icon(SNAME("GuiToggleOn"), EditorStringName(EditorIcons))); - theme->set_icon("checked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked", "CheckButton", theme->get_icon(SNAME("GuiToggleOff"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabled"), EditorStringName(EditorIcons))); - - theme->set_icon("checked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnMirrored"), EditorStringName(EditorIcons))); - theme->set_icon("checked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffMirrored"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), EditorStringName(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("font_outline_color", "CheckButton", font_outline_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("h_separation", "CheckButton", 8 * EDSCALE); - theme->set_constant("check_v_offset", "CheckButton", 0); - theme->set_constant("outline_size", "CheckButton", 0); - - // Checkbox - Ref sb_checkbox = style_menu->duplicate(); - sb_checkbox->set_content_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"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked", "CheckBox", theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); - theme->set_icon("radio_checked", "CheckBox", theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons))); - theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons))); - theme->set_icon("checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("radio_checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("radio_unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons))); - - 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("font_outline_color", "CheckBox", font_outline_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("h_separation", "CheckBox", 8 * EDSCALE); - theme->set_constant("check_v_offset", "CheckBox", 0); - theme->set_constant("outline_size", "CheckBox", 0); - - // PopupDialog - theme->set_stylebox("panel", "PopupDialog", style_popup); - - // PopupMenu - Ref 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_content_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(EDSCALE); - if (draw_extra_borders) { - style_popup_menu->set_border_color(extra_border_color_2); - } else { - style_popup_menu->set_border_color(dark_color_2); - } - theme->set_stylebox("panel", "PopupMenu", style_popup_menu); - - Ref style_menu_hover = style_widget_hover->duplicate(); - // Don't use rounded corners for hover highlights since the StyleBox touches the PopupMenu's edges. - style_menu_hover->set_corner_radius_all(0); - theme->set_stylebox("hover", "PopupMenu", style_menu_hover); - - theme->set_stylebox("separator", "PopupMenu", style_popup_separator); - theme->set_stylebox("labeled_separator_left", "PopupMenu", style_popup_labeled_separator_left); - theme->set_stylebox("labeled_separator_right", "PopupMenu", style_popup_labeled_separator_right); - - theme->set_color("font_color", "PopupMenu", font_color); - theme->set_color("font_hover_color", "PopupMenu", font_hover_color); - theme->set_color("font_accelerator_color", "PopupMenu", font_disabled_color); - theme->set_color("font_disabled_color", "PopupMenu", font_disabled_color); - theme->set_color("font_separator_color", "PopupMenu", font_disabled_color); - theme->set_color("font_outline_color", "PopupMenu", font_outline_color); - theme->set_icon("checked", "PopupMenu", theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked", "PopupMenu", theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); - theme->set_icon("radio_checked", "PopupMenu", theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons))); - theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons))); - theme->set_icon("checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("radio_checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("radio_unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("submenu", "PopupMenu", theme->get_icon(SNAME("ArrowRight"), EditorStringName(EditorIcons))); - theme->set_icon("submenu_mirrored", "PopupMenu", theme->get_icon(SNAME("ArrowLeft"), EditorStringName(EditorIcons))); - theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityHidden"), EditorStringName(EditorIcons))); - theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityVisible"), EditorStringName(EditorIcons))); - theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityXray"), EditorStringName(EditorIcons))); - - // 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). - 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("outline_size", "PopupMenu", 0); - 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; - - float hue_rotate = (i * 2 % 16) / 16.0; - 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"))); - - // Sub-inspector background. - Ref 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_content_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), EditorStringName(Editor), sub_inspector_bg); - - // EditorProperty background while it has a sub-inspector open. - Ref 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), EditorStringName(Editor), bg_color); - } - - theme->set_color("sub_inspector_property_color", EditorStringName(Editor), dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); - - // EditorSpinSlider. - theme->set_color("label_color", "EditorSpinSlider", font_color); - theme->set_color("read_only_label_color", "EditorSpinSlider", font_readonly_color); - - Ref 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 style_property_bg = style_default->duplicate(); - style_property_bg->set_bg_color(highlight_color); - style_property_bg->set_border_width_all(0); - - Ref 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(memnew(StyleBoxEmpty))); - 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); - theme->set_color("readonly_warning_color", "EditorProperty", readonly_warning_color); - - Ref style_property_group_note = style_default->duplicate(); - Color property_group_note_color = accent_color; - property_group_note_color.a = 0.1; - 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); - - Color inspector_indent_color = accent_color; - inspector_indent_color.a = 0.2; - Ref inspector_indent_style = make_flat_stylebox(inspector_indent_color, 2.0 * EDSCALE, 0, 2.0 * EDSCALE, 0); - theme->set_stylebox("indent_box", "EditorInspectorSection", inspector_indent_style); - theme->set_constant("indent_size", "EditorInspectorSection", 6.0 * EDSCALE); - - theme->set_constant("inspector_margin", EditorStringName(Editor), 12 * EDSCALE); - - // Tree & ItemList background - Ref style_tree_bg = style_default->duplicate(); - // 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)); - if (draw_extra_borders) { - style_tree_bg->set_border_width_all(Math::round(EDSCALE)); - style_tree_bg->set_border_color(extra_border_color_2); - } else { - style_tree_bg->set_border_color(dark_color_3); - } - - theme->set_stylebox("panel", "Tree", style_tree_bg); - theme->set_stylebox("panel", "EditorValidationPanel", style_tree_bg); - - // Tree - theme->set_icon("checked", "Tree", theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons))); - theme->set_icon("checked_disabled", "Tree", theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("indeterminate", "Tree", theme->get_icon(SNAME("GuiIndeterminate"), EditorStringName(EditorIcons))); - theme->set_icon("indeterminate_disabled", "Tree", theme->get_icon(SNAME("GuiIndeterminateDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked", "Tree", theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); - theme->set_icon("unchecked_disabled", "Tree", theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); - theme->set_icon("arrow", "Tree", theme->get_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons))); - theme->set_icon("arrow_collapsed", "Tree", theme->get_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons))); - theme->set_icon("arrow_collapsed_mirrored", "Tree", theme->get_icon(SNAME("GuiTreeArrowLeft"), EditorStringName(EditorIcons))); - theme->set_icon("updown", "Tree", theme->get_icon(SNAME("GuiTreeUpdown"), EditorStringName(EditorIcons))); - theme->set_icon("select_arrow", "Tree", theme->get_icon(SNAME("GuiDropdown"), EditorStringName(EditorIcons))); - 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); - theme->set_color("custom_button_font_highlight", "Tree", font_hover_color); - theme->set_color("font_color", "Tree", font_color); - theme->set_color("font_selected_color", "Tree", mono_color); - theme->set_color("font_disabled_color", "Tree", font_disabled_color); - theme->set_color("font_outline_color", "Tree", font_outline_color); - theme->set_color("title_button_color", "Tree", font_color); - theme->set_color("drop_position_color", "Tree", accent_color); - 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("inner_item_margin_bottom", "Tree", (default_margin_size + extra_spacing) * EDSCALE); - theme->set_constant("inner_item_margin_left", "Tree", (default_margin_size + extra_spacing) * EDSCALE); - theme->set_constant("inner_item_margin_right", "Tree", (default_margin_size + extra_spacing) * EDSCALE); - theme->set_constant("inner_item_margin_top", "Tree", (default_margin_size + extra_spacing) * EDSCALE); - theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE); - theme->set_constant("scroll_border", "Tree", 40 * EDSCALE); - theme->set_constant("scroll_speed", "Tree", 12); - theme->set_constant("outline_size", "Tree", 0); - theme->set_constant("scrollbar_margin_left", "Tree", 0); - theme->set_constant("scrollbar_margin_top", "Tree", 0); - theme->set_constant("scrollbar_margin_right", "Tree", 0); - theme->set_constant("scrollbar_margin_bottom", "Tree", 0); - theme->set_constant("scrollbar_h_separation", "Tree", 1 * EDSCALE); - theme->set_constant("scrollbar_v_separation", "Tree", 1 * EDSCALE); - - const Color guide_color = mono_color * Color(1, 1, 1, 0.05); - Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); - - theme->set_constant("draw_guides", "Tree", relationship_line_opacity < 0.01); - theme->set_color("guide_color", "Tree", guide_color); - - int relationship_line_width = 1; - Color parent_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.45, 0.0, 1.0)); - Color children_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.25, 0.0, 1.0)); - theme->set_constant("draw_relationship_lines", "Tree", relationship_line_opacity >= 0.01); - theme->set_constant("relationship_line_width", "Tree", relationship_line_width); - theme->set_constant("parent_hl_line_width", "Tree", relationship_line_width * 2); - theme->set_constant("children_hl_line_width", "Tree", relationship_line_width); - theme->set_constant("parent_hl_line_margin", "Tree", relationship_line_width * 3); - theme->set_color("relationship_line_color", "Tree", relationship_line_color); - theme->set_color("parent_hl_line_color", "Tree", parent_line_color); - theme->set_color("children_hl_line_color", "Tree", children_line_color); - - Ref style_tree_btn = style_default->duplicate(); - style_tree_btn->set_bg_color(highlight_color); - style_tree_btn->set_border_width_all(0); - theme->set_stylebox("button_pressed", "Tree", style_tree_btn); - - Ref style_tree_hover = style_default->duplicate(); - style_tree_hover->set_bg_color(highlight_color * Color(1, 1, 1, 0.4)); - style_tree_hover->set_border_width_all(0); - theme->set_stylebox("hover", "Tree", style_tree_hover); - - Ref style_tree_focus = style_default->duplicate(); - style_tree_focus->set_bg_color(highlight_color); - style_tree_focus->set_border_width_all(0); - theme->set_stylebox("selected_focus", "Tree", style_tree_focus); - - Ref style_tree_selected = style_tree_focus->duplicate(); - theme->set_stylebox("selected", "Tree", style_tree_selected); - - Ref style_tree_cursor = style_default->duplicate(); - style_tree_cursor->set_draw_center(false); - style_tree_cursor->set_border_width_all(MAX(1, border_width)); - style_tree_cursor->set_border_color(contrast_color_1); - - Ref style_tree_title = style_default->duplicate(); - style_tree_title->set_bg_color(dark_color_3); - style_tree_title->set_border_width_all(0); - theme->set_stylebox("cursor", "Tree", style_tree_cursor); - theme->set_stylebox("cursor_unfocused", "Tree", style_tree_cursor); - theme->set_stylebox("title_button_normal", "Tree", style_tree_title); - theme->set_stylebox("title_button_hover", "Tree", style_tree_title); - theme->set_stylebox("title_button_pressed", "Tree", style_tree_title); - - Color prop_category_color = dark_color_1.lerp(mono_color, 0.12); - Color prop_section_color = dark_color_1.lerp(mono_color, 0.09); - Color prop_subsection_color = dark_color_1.lerp(mono_color, 0.06); - theme->set_color("prop_category", EditorStringName(Editor), prop_category_color); - theme->set_color("prop_section", EditorStringName(Editor), prop_section_color); - theme->set_color("prop_subsection", EditorStringName(Editor), prop_subsection_color); - theme->set_color("drop_position_color", "Tree", accent_color); - - // EditorInspectorCategory - Ref category_bg = style_default->duplicate(); - category_bg->set_bg_color(prop_category_color); - category_bg->set_border_color(prop_category_color); - theme->set_stylebox("bg", "EditorInspectorCategory", category_bg); - - // ItemList - Ref style_itemlist_bg = style_default->duplicate(); - style_itemlist_bg->set_bg_color(dark_color_1); - - if (draw_extra_borders) { - style_itemlist_bg->set_border_width_all(Math::round(EDSCALE)); - style_itemlist_bg->set_border_color(extra_border_color_2); - } else { - style_itemlist_bg->set_border_width_all(border_width); - style_itemlist_bg->set_border_color(dark_color_3); - } - - Ref style_itemlist_cursor = style_default->duplicate(); - style_itemlist_cursor->set_draw_center(false); - style_itemlist_cursor->set_border_width_all(border_width); - style_itemlist_cursor->set_border_color(highlight_color); - - Ref style_itemlist_hover = style_tree_selected->duplicate(); - style_itemlist_hover->set_bg_color(highlight_color * Color(1, 1, 1, 0.3)); - style_itemlist_hover->set_border_width_all(0); - - 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("hovered", "ItemList", style_itemlist_hover); - theme->set_color("font_color", "ItemList", font_color); - theme->set_color("font_hovered_color", "ItemList", mono_color); - theme->set_color("font_selected_color", "ItemList", mono_color); - theme->set_color("font_outline_color", "ItemList", font_outline_color); - theme->set_color("guide_color", "ItemList", guide_color); - 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); - theme->set_constant("outline_size", "ItemList", 0); - - // TabBar & TabContainer - Ref 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_hovered", "TabContainer", style_tab_hovered); - theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); - theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); - theme->set_stylebox("tab_focus", "TabContainer", style_tab_focus); - theme->set_stylebox("tab_selected", "TabBar", style_tab_selected); - theme->set_stylebox("tab_hovered", "TabBar", style_tab_hovered); - theme->set_stylebox("tab_unselected", "TabBar", style_tab_unselected); - theme->set_stylebox("tab_disabled", "TabBar", style_tab_disabled); - theme->set_stylebox("tab_focus", "TabBar", style_tab_focus); - 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_hovered_color", "TabContainer", font_color); - theme->set_color("font_unselected_color", "TabContainer", font_disabled_color); - theme->set_color("font_outline_color", "TabContainer", font_outline_color); - theme->set_color("font_selected_color", "TabBar", font_color); - theme->set_color("font_hovered_color", "TabBar", font_color); - theme->set_color("font_unselected_color", "TabBar", font_disabled_color); - theme->set_color("font_outline_color", "TabBar", font_outline_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"), EditorStringName(EditorIcons))); - theme->set_icon("menu_highlight", "TabContainer", theme->get_icon(SNAME("GuiTabMenuHl"), EditorStringName(EditorIcons))); - theme->set_icon("close", "TabBar", theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons))); - theme->set_icon("increment", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRight"), EditorStringName(EditorIcons))); - theme->set_icon("decrement", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeft"), EditorStringName(EditorIcons))); - theme->set_icon("increment", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRight"), EditorStringName(EditorIcons))); - theme->set_icon("decrement", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeft"), EditorStringName(EditorIcons))); - theme->set_icon("increment_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRightHl"), EditorStringName(EditorIcons))); - theme->set_icon("decrement_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), EditorStringName(EditorIcons))); - theme->set_icon("increment_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRightHl"), EditorStringName(EditorIcons))); - theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), EditorStringName(EditorIcons))); - theme->set_icon("drop_mark", "TabContainer", theme->get_icon(SNAME("GuiTabDropMark"), EditorStringName(EditorIcons))); - theme->set_icon("drop_mark", "TabBar", theme->get_icon(SNAME("GuiTabDropMark"), EditorStringName(EditorIcons))); - theme->set_constant("side_margin", "TabContainer", 0); - theme->set_constant("outline_size", "TabContainer", 0); - theme->set_constant("h_separation", "TabBar", 4 * EDSCALE); - theme->set_constant("outline_size", "TabBar", 0); - - // Content of each tab. - Ref style_content_panel = style_default->duplicate(); - style_content_panel->set_border_color(dark_color_3); - style_content_panel->set_border_width_all(border_width); - 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_content_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); - - // Bottom panel. - Ref style_bottom_panel = style_content_panel->duplicate(); - style_bottom_panel->set_corner_radius_all(corner_radius * EDSCALE); - theme->set_stylebox("BottomPanel", EditorStringName(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 style_tab_selected_odd = style_tab_selected->duplicate(); - style_tab_selected_odd->set_bg_color(disabled_bg_color); - theme->set_stylebox("tab_selected", "TabContainerOdd", style_tab_selected_odd); - - Ref style_content_panel_odd = style_content_panel->duplicate(); - style_content_panel_odd->set_bg_color(disabled_bg_color); - theme->set_stylebox("panel", "TabContainerOdd", style_content_panel_odd); - - // This stylebox is used in 3d and 2d viewports (no borders). - Ref style_content_panel_vp = style_content_panel->duplicate(); - style_content_panel_vp->set_content_margin_individual(border_width * 2, default_margin_size * EDSCALE, border_width * 2, border_width * 2); - theme->set_stylebox("Content", EditorStringName(EditorStyles), style_content_panel_vp); - - // This stylebox is used by preview tabs in the Theme Editor. - Ref style_theme_preview_tab = style_tab_selected_odd->duplicate(); - style_theme_preview_tab->set_expand_margin(SIDE_BOTTOM, 5 * EDSCALE); - theme->set_stylebox("ThemeEditorPreviewFG", EditorStringName(EditorStyles), style_theme_preview_tab); - Ref style_theme_preview_bg_tab = style_tab_unselected->duplicate(); - style_theme_preview_bg_tab->set_expand_margin(SIDE_BOTTOM, 2 * EDSCALE); - theme->set_stylebox("ThemeEditorPreviewBG", EditorStringName(EditorStyles), style_theme_preview_bg_tab); - - Ref style_texture_region_bg = style_tree_bg->duplicate(); - style_texture_region_bg->set_content_margin_all(0); - theme->set_stylebox("TextureRegionPreviewBG", EditorStringName(EditorStyles), style_texture_region_bg); - theme->set_stylebox("TextureRegionPreviewFG", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); - - // Separators - theme->set_stylebox("separator", "HSeparator", make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width))); - theme->set_stylebox("separator", "VSeparator", make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width), 0, 0, true)); - - // Debugger - - Ref style_panel_debugger = style_content_panel->duplicate(); - style_panel_debugger->set_border_width(SIDE_BOTTOM, 0); - theme->set_stylebox("DebuggerPanel", EditorStringName(EditorStyles), style_panel_debugger); - - Ref style_panel_invisible_top = style_content_panel->duplicate(); - int stylebox_offset = theme->get_font(SNAME("tab_selected"), SNAME("TabContainer"))->get_height(theme->get_font_size(SNAME("tab_selected"), SNAME("TabContainer"))) + theme->get_stylebox(SNAME("tab_selected"), SNAME("TabContainer"))->get_minimum_size().height + theme->get_stylebox(SNAME("panel"), SNAME("TabContainer"))->get_content_margin(SIDE_TOP); - style_panel_invisible_top->set_expand_margin(SIDE_TOP, -stylebox_offset); - style_panel_invisible_top->set_content_margin(SIDE_TOP, 0); - theme->set_stylebox("BottomPanelDebuggerOverride", EditorStringName(EditorStyles), style_panel_invisible_top); - - // LineEdit - - Ref style_line_edit = style_widget->duplicate(); - // The original style_widget style has an extra 1 pixel offset that makes LineEdits not align with Buttons, - // so this compensates for that. - style_line_edit->set_content_margin(SIDE_TOP, style_line_edit->get_content_margin(SIDE_TOP) - 1 * EDSCALE); - - // Don't round the bottom corners to make the line look sharper. - style_line_edit->set_corner_radius(CORNER_BOTTOM_LEFT, 0); - style_line_edit->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); - - if (draw_extra_borders) { - style_line_edit->set_border_width_all(Math::round(EDSCALE)); - style_line_edit->set_border_color(extra_border_color_1); - } else { - // Add a bottom line to make LineEdits more visible, especially in sectioned inspectors - // such as the Project Settings. - style_line_edit->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); - style_line_edit->set_border_color(dark_color_2); - } - - Ref style_line_edit_disabled = style_line_edit->duplicate(); - style_line_edit_disabled->set_border_color(disabled_color); - style_line_edit_disabled->set_bg_color(disabled_bg_color); - - theme->set_stylebox("normal", "LineEdit", style_line_edit); - 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"), EditorStringName(EditorIcons))); - 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); - theme->set_color("font_placeholder_color", "LineEdit", font_placeholder_color); - theme->set_color("font_outline_color", "LineEdit", font_outline_color); - theme->set_color("caret_color", "LineEdit", font_color); - theme->set_color("selection_color", "LineEdit", selection_color); - theme->set_color("clear_button_color", "LineEdit", font_color); - theme->set_color("clear_button_color_pressed", "LineEdit", accent_color); - - theme->set_constant("minimum_character_width", "LineEdit", 4); - theme->set_constant("outline_size", "LineEdit", 0); - theme->set_constant("caret_width", "LineEdit", 1); - - // TextEdit - 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_icon("tab", "TextEdit", theme->get_icon(SNAME("GuiTab"), EditorStringName(EditorIcons))); - theme->set_icon("space", "TextEdit", theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons))); - theme->set_color("font_color", "TextEdit", font_color); - theme->set_color("font_readonly_color", "TextEdit", font_readonly_color); - theme->set_color("font_placeholder_color", "TextEdit", font_placeholder_color); - theme->set_color("font_outline_color", "TextEdit", font_outline_color); - theme->set_color("caret_color", "TextEdit", font_color); - theme->set_color("selection_color", "TextEdit", selection_color); - theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0)); - - theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); - theme->set_constant("outline_size", "TextEdit", 0); - theme->set_constant("caret_width", "TextEdit", 1); - - theme->set_icon("h_grabber", "SplitContainer", theme->get_icon(SNAME("GuiHsplitter"), EditorStringName(EditorIcons))); - theme->set_icon("v_grabber", "SplitContainer", theme->get_icon(SNAME("GuiVsplitter"), EditorStringName(EditorIcons))); - theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), EditorStringName(EditorIcons))); - theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), EditorStringName(EditorIcons))); - - theme->set_constant("separation", "SplitContainer", default_margin_size * 2 * EDSCALE); - 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", "SplitContainer", 6 * 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); - theme->set_constant("separation", "VBoxContainer", default_margin_size * EDSCALE); - theme->set_constant("margin_left", "MarginContainer", 0); - theme->set_constant("margin_top", "MarginContainer", 0); - theme->set_constant("margin_right", "MarginContainer", 0); - theme->set_constant("margin_bottom", "MarginContainer", 0); - 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 - - // Prevent corner artifacts between window title and body. - Ref style_window_title = style_default->duplicate(); - style_window_title->set_corner_radius(CORNER_TOP_LEFT, 0); - style_window_title->set_corner_radius(CORNER_TOP_RIGHT, 0); - // Prevent visible line between window title and body. - style_window_title->set_expand_margin(SIDE_BOTTOM, 2 * EDSCALE); - - Ref style_window = style_popup->duplicate(); - style_window->set_border_color(base_color); - style_window->set_border_width(SIDE_TOP, 24 * EDSCALE); - style_window->set_expand_margin(SIDE_TOP, 24 * EDSCALE); - theme->set_stylebox("embedded_border", "Window", style_window); - theme->set_stylebox("embedded_unfocused_border", "Window", style_window); - - theme->set_color("title_color", "Window", font_color); - theme->set_icon("close", "Window", theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons))); - theme->set_icon("close_pressed", "Window", theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons))); - 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"), EditorStringName(EditorFonts))); - theme->set_font_size("title_font_size", "Window", theme->get_font_size(SNAME("title_size"), EditorStringName(EditorFonts))); - - // Complex window (currently only Editor Settings and Project Settings) - Ref style_complex_window = style_window->duplicate(); - style_complex_window->set_bg_color(dark_color_2); - style_complex_window->set_border_color(dark_color_2); - theme->set_stylebox("panel", "EditorSettingsDialog", style_complex_window); - theme->set_stylebox("panel", "ProjectSettingsEditor", style_complex_window); - theme->set_stylebox("panel", "EditorAbout", style_complex_window); - - // AcceptDialog - theme->set_stylebox("panel", "AcceptDialog", style_window_title); - theme->set_constant("buttons_separation", "AcceptDialog", 8 * EDSCALE); - - // HScrollBar - Ref empty_icon = memnew(ImageTexture); - - if (increase_scrollbar_touch_area) { - theme->set_stylebox("scroll", "HScrollBar", make_line_stylebox(separator_color, 50)); - } else { - theme->set_stylebox("scroll", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, -5, 1, -5, 1)); - } - theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); - theme->set_stylebox("grabber", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); - theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); - theme->set_stylebox("grabber_pressed", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); - - theme->set_icon("increment", "HScrollBar", empty_icon); - theme->set_icon("increment_highlight", "HScrollBar", empty_icon); - theme->set_icon("increment_pressed", "HScrollBar", empty_icon); - theme->set_icon("decrement", "HScrollBar", empty_icon); - theme->set_icon("decrement_highlight", "HScrollBar", empty_icon); - theme->set_icon("decrement_pressed", "HScrollBar", empty_icon); - - // VScrollBar - if (increase_scrollbar_touch_area) { - theme->set_stylebox("scroll", "VScrollBar", make_line_stylebox(separator_color, 50, 1, 1, true)); - } else { - theme->set_stylebox("scroll", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, -5, 1, -5)); - } - theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); - theme->set_stylebox("grabber", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); - theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); - theme->set_stylebox("grabber_pressed", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); - - theme->set_icon("increment", "VScrollBar", empty_icon); - theme->set_icon("increment_highlight", "VScrollBar", empty_icon); - theme->set_icon("increment_pressed", "VScrollBar", empty_icon); - theme->set_icon("decrement", "VScrollBar", empty_icon); - theme->set_icon("decrement_highlight", "VScrollBar", empty_icon); - theme->set_icon("decrement_pressed", "VScrollBar", empty_icon); - - // HSlider - theme->set_icon("grabber_highlight", "HSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), EditorStringName(EditorIcons))); - theme->set_icon("grabber", "HSlider", theme->get_icon(SNAME("GuiSliderGrabber"), EditorStringName(EditorIcons))); - 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("center_grabber", "HSlider", 0); - theme->set_constant("grabber_offset", "HSlider", 0); - - // VSlider - theme->set_icon("grabber", "VSlider", theme->get_icon(SNAME("GuiSliderGrabber"), EditorStringName(EditorIcons))); - theme->set_icon("grabber_highlight", "VSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), EditorStringName(EditorIcons))); - 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("center_grabber", "VSlider", 0); - theme->set_constant("grabber_offset", "VSlider", 0); - - // RichTextLabel - theme->set_color("default_color", "RichTextLabel", font_color); - theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); - theme->set_color("font_outline_color", "RichTextLabel", font_outline_color); - theme->set_color("selection_color", "RichTextLabel", selection_color); - theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE); - theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE); - theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * EDSCALE); - theme->set_constant("outline_size", "RichTextLabel", 0); - theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox()); - theme->set_stylebox("normal", "RichTextLabel", style_tree_bg); - - // Editor help. - Ref style_editor_help = style_default->duplicate(); - style_editor_help->set_bg_color(dark_color_2); - style_editor_help->set_border_color(dark_color_3); - theme->set_stylebox("background", "EditorHelp", style_editor_help); - - theme->set_color("title_color", "EditorHelp", accent_color); - theme->set_color("headline_color", "EditorHelp", mono_color); - theme->set_color("text_color", "EditorHelp", font_color); - theme->set_color("comment_color", "EditorHelp", font_color * Color(1, 1, 1, 0.6)); - theme->set_color("symbol_color", "EditorHelp", font_color * Color(1, 1, 1, 0.6)); - theme->set_color("value_color", "EditorHelp", font_color * Color(1, 1, 1, 0.6)); - theme->set_color("qualifier_color", "EditorHelp", font_color * Color(1, 1, 1, 0.8)); - theme->set_color("type_color", "EditorHelp", accent_color.lerp(font_color, 0.5)); - theme->set_color("selection_color", "EditorHelp", selection_color); - theme->set_color("link_color", "EditorHelp", accent_color.lerp(mono_color, 0.8)); - 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_color("code_bg_color", "EditorHelp", dark_color_3); - theme->set_color("kbd_bg_color", "EditorHelp", dark_color_1); - theme->set_color("param_bg_color", "EditorHelp", dark_color_1); - theme->set_constant("line_separation", "EditorHelp", Math::round(6 * EDSCALE)); - theme->set_constant("table_h_separation", "EditorHelp", 16 * EDSCALE); - theme->set_constant("table_v_separation", "EditorHelp", 6 * EDSCALE); - theme->set_constant("text_highlight_h_padding", "EditorHelp", 1 * EDSCALE); - theme->set_constant("text_highlight_v_padding", "EditorHelp", 2 * EDSCALE); - - // Panel - theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4, corner_width)); - theme->set_stylebox("PanelForeground", EditorStringName(EditorStyles), style_default); - - // Label - theme->set_stylebox("normal", "Label", style_empty); - theme->set_color("font_color", "Label", font_color); - theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0)); - theme->set_color("font_outline_color", "Label", font_outline_color); - theme->set_constant("shadow_offset_x", "Label", 1 * EDSCALE); - theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE); - theme->set_constant("shadow_outline_size", "Label", 1 * EDSCALE); - theme->set_constant("line_spacing", "Label", 3 * EDSCALE); - theme->set_constant("outline_size", "Label", 0); - - // LinkButton - 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); - theme->set_color("font_outline_color", "LinkButton", font_outline_color); - - theme->set_constant("outline_size", "LinkButton", 0); - - theme->set_type_variation("HeaderSmallLink", "LinkButton"); - theme->set_font("font", "HeaderSmallLink", theme->get_font(SNAME("font"), SNAME("HeaderSmall"))); - theme->set_font_size("font_size", "HeaderSmallLink", theme->get_font_size(SNAME("font_size"), SNAME("HeaderSmall"))); - - // TooltipPanel + TooltipLabel - // TooltipPanel is also used for custom tooltips, while TooltipLabel - // is only relevant for default tooltips. - Ref style_tooltip = style_popup->duplicate(); - style_tooltip->set_shadow_size(0); - style_tooltip->set_content_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_shadow_color", "TooltipLabel", Color(0, 0, 0, 0)); - theme->set_stylebox("panel", "TooltipPanel", style_tooltip); - - // PopupPanel - theme->set_stylebox("panel", "PopupPanel", style_popup); - - Ref control_editor_popup_style = style_popup->duplicate(); - control_editor_popup_style->set_shadow_size(0); - control_editor_popup_style->set_content_margin(SIDE_LEFT, default_margin_size * EDSCALE); - control_editor_popup_style->set_content_margin(SIDE_TOP, default_margin_size * EDSCALE); - control_editor_popup_style->set_content_margin(SIDE_RIGHT, default_margin_size * EDSCALE); - control_editor_popup_style->set_content_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"), EditorStringName(EditorIcons))); - theme->set_icon("updown_disabled", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), EditorStringName(EditorIcons))); - - // ProgressBar - theme->set_stylebox("background", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), EditorStringName(EditorIcons)), 4, 4, 4, 4, 0, 0, 0, 0)); - theme->set_stylebox("fill", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 2, 1, 2, 1)); - theme->set_color("font_color", "ProgressBar", font_color); - theme->set_color("font_outline_color", "ProgressBar", font_outline_color); - theme->set_constant("outline_size", "ProgressBar", 0); - - // GraphEdit - theme->set_stylebox("panel", "GraphEdit", style_tree_bg); - Ref graph_toolbar_style = make_flat_stylebox(dark_color_1 * Color(1, 1, 1, 0.6), 4, 2, 4, 2, 3); - theme->set_stylebox("menu_panel", "GraphEdit", graph_toolbar_style); - - if (dark_theme) { - theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.1)); - theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.05)); - } else { - theme->set_color("grid_major", "GraphEdit", Color(0.0, 0.0, 0.0, 0.15)); - theme->set_color("grid_minor", "GraphEdit", Color(0.0, 0.0, 0.0, 0.07)); - } - theme->set_color("selection_fill", "GraphEdit", theme->get_color(SNAME("box_selection_fill_color"), EditorStringName(Editor))); - theme->set_color("selection_stroke", "GraphEdit", theme->get_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor))); - theme->set_color("activity", "GraphEdit", accent_color); - - theme->set_icon("zoom_out", "GraphEdit", theme->get_icon(SNAME("ZoomLess"), EditorStringName(EditorIcons))); - theme->set_icon("zoom_in", "GraphEdit", theme->get_icon(SNAME("ZoomMore"), EditorStringName(EditorIcons))); - theme->set_icon("zoom_reset", "GraphEdit", theme->get_icon(SNAME("ZoomReset"), EditorStringName(EditorIcons))); - theme->set_icon("grid_toggle", "GraphEdit", theme->get_icon(SNAME("GridToggle"), EditorStringName(EditorIcons))); - theme->set_icon("minimap_toggle", "GraphEdit", theme->get_icon(SNAME("GridMinimap"), EditorStringName(EditorIcons))); - theme->set_icon("snapping_toggle", "GraphEdit", theme->get_icon(SNAME("SnapGrid"), EditorStringName(EditorIcons))); - theme->set_icon("layout", "GraphEdit", theme->get_icon(SNAME("GridLayout"), EditorStringName(EditorIcons))); - - // GraphEditMinimap - Ref style_minimap_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); - style_minimap_bg->set_border_color(dark_color_3); - style_minimap_bg->set_border_width_all(1); - theme->set_stylebox("panel", "GraphEditMinimap", style_minimap_bg); - - Ref style_minimap_camera; - Ref style_minimap_node; - if (dark_theme) { - style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0); - style_minimap_camera->set_border_color(Color(0.65, 0.65, 0.65, 0.45)); - style_minimap_node = make_flat_stylebox(Color(1, 1, 1), 0, 0, 0, 0); - } else { - style_minimap_camera = make_flat_stylebox(Color(0.38, 0.38, 0.38, 0.2), 0, 0, 0, 0); - style_minimap_camera->set_border_color(Color(0.38, 0.38, 0.38, 0.45)); - 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_anti_aliased(false); - theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera); - theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node); - - 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", theme->get_icon(SNAME("GuiResizerTopLeft"), EditorStringName(EditorIcons))); - theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color); - - // GraphNode - - const int gn_margin_top = 2; - const int gn_margin_side = 2; - const int gn_margin_bottom = 2; - - Color graphnode_bg = dark_color_3; - if (!dark_theme) { - graphnode_bg = prop_section_color; - } - const Color graph_node_selected_border_color = graphnode_bg.lerp(accent_color, 0.275); - - const Color graphnode_frame_bg = graphnode_bg.lerp(style_tree_bg->get_bg_color(), 0.3); - - Ref graphn_sb_panel = make_flat_stylebox(graphnode_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, corner_width); - graphn_sb_panel->set_border_width_all(border_width); - graphn_sb_panel->set_border_color(graphnode_bg); - graphn_sb_panel->set_corner_radius_individual(0, 0, corner_radius * EDSCALE, corner_radius * EDSCALE); - graphn_sb_panel->set_expand_margin(SIDE_TOP, 17 * EDSCALE); - - Ref graphn_sb_panel_selected = make_flat_stylebox(graphnode_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, corner_width); - graphn_sb_panel_selected->set_border_width_all(2 * EDSCALE + border_width); - graphn_sb_panel_selected->set_border_color(graph_node_selected_border_color); - graphn_sb_panel_selected->set_corner_radius_individual(0, 0, corner_radius * EDSCALE, corner_radius * EDSCALE); - graphn_sb_panel_selected->set_expand_margin(SIDE_TOP, 17 * EDSCALE); - - const int gn_titlebar_margin_left = 12; - const int gn_titlebar_margin_right = 4; // The rest is for the close button. - Ref graphn_sb_titlebar = make_flat_stylebox(graphnode_bg, gn_titlebar_margin_left, gn_margin_top, gn_titlebar_margin_right, 0, corner_width); - graphn_sb_titlebar->set_expand_margin(SIDE_TOP, 2 * EDSCALE); - graphn_sb_titlebar->set_corner_radius_individual(corner_radius * EDSCALE, corner_radius * EDSCALE, 0, 0); - - Ref graphn_sb_titlebar_selected = make_flat_stylebox(graph_node_selected_border_color, gn_titlebar_margin_left, gn_margin_top, gn_titlebar_margin_right, 0, corner_width); - graphn_sb_titlebar_selected->set_corner_radius_individual(corner_radius * EDSCALE, corner_radius * EDSCALE, 0, 0); - graphn_sb_titlebar_selected->set_expand_margin(SIDE_TOP, 2 * EDSCALE); - Ref graphn_sb_slot = make_empty_stylebox(12, 0, 12, 0); - - theme->set_stylebox("panel", "GraphElement", graphn_sb_panel); - theme->set_stylebox("panel_selected", "GraphElement", graphn_sb_panel_selected); - theme->set_stylebox("titlebar", "GraphElement", graphn_sb_titlebar); - theme->set_stylebox("titlebar_selected", "GraphElement", graphn_sb_titlebar_selected); - - // GraphNode's title Label. - theme->set_type_variation("GraphNodeTitleLabel", "Label"); - - theme->set_stylebox("normal", "GraphNodeTitleLabel", make_empty_stylebox(0, 0, 0, 0)); - theme->set_color("font_color", "GraphNodeTitleLabel", font_color); - theme->set_constant("line_spacing", "GraphNodeTitleLabel", 3 * EDSCALE); - - Color graphnode_decoration_color = dark_color_1.inverted(); - - theme->set_color("resizer_color", "GraphElement", graphnode_decoration_color); - theme->set_icon("resizer", "GraphElement", theme->get_icon(SNAME("GuiResizer"), EditorStringName(EditorIcons))); - - // GraphNode. - theme->set_stylebox("panel", "GraphNode", graphn_sb_panel); - theme->set_stylebox("panel_selected", "GraphNode", graphn_sb_panel_selected); - theme->set_stylebox("titlebar", "GraphNode", graphn_sb_titlebar); - theme->set_stylebox("titlebar_selected", "GraphNode", graphn_sb_titlebar_selected); - theme->set_stylebox("slot", "GraphNode", graphn_sb_slot); - - theme->set_color("resizer_color", "GraphNode", graphnode_decoration_color); - - theme->set_constant("port_h_offset", "GraphNode", 0); - theme->set_constant("separation", "GraphNode", 1 * EDSCALE); - - Ref port_icon = theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons)); - // The true size is 24x24 This is necessary for sharp port icons at high zoom levels in GraphEdit (up to ~200%). - port_icon->set_size_override(Size2(12, 12)); - theme->set_icon("port", "GraphNode", port_icon); - - // StateMachine graph - theme->set_stylebox("panel", "GraphStateMachine", style_tree_bg); - theme->set_stylebox("error_panel", "GraphStateMachine", style_tree_bg); - theme->set_color("error_color", "GraphStateMachine", error_color); - - const int sm_margin_side = 10 * EDSCALE; - - Ref sm_node_style = make_flat_stylebox(dark_color_3 * Color(1, 1, 1, 0.7), sm_margin_side, 24 * EDSCALE, sm_margin_side, gn_margin_bottom, corner_width); - sm_node_style->set_border_width_all(border_width); - sm_node_style->set_border_color(graphnode_bg); - - Ref sm_node_selected_style = make_flat_stylebox(graphnode_bg * Color(1, 1, 1, 0.9), sm_margin_side, 24 * EDSCALE, sm_margin_side, gn_margin_bottom, corner_width); - sm_node_selected_style->set_border_width_all(2 * EDSCALE + border_width); - sm_node_selected_style->set_border_color(accent_color * Color(1, 1, 1, 0.9)); - sm_node_selected_style->set_shadow_size(8 * EDSCALE); - sm_node_selected_style->set_shadow_color(shadow_color); - - Ref sm_node_playing_style = sm_node_selected_style->duplicate(); - sm_node_playing_style->set_border_color(warning_color); - sm_node_playing_style->set_shadow_color(warning_color * Color(1, 1, 1, 0.2)); - - theme->set_stylebox("node_frame", "GraphStateMachine", sm_node_style); - theme->set_stylebox("node_frame_selected", "GraphStateMachine", sm_node_selected_style); - theme->set_stylebox("node_frame_playing", "GraphStateMachine", sm_node_playing_style); - - Ref sm_node_start_style = sm_node_style->duplicate(); - sm_node_start_style->set_border_width_all(1 * EDSCALE); - sm_node_start_style->set_border_color(success_color.lightened(0.24)); - theme->set_stylebox("node_frame_start", "GraphStateMachine", sm_node_start_style); - - Ref sm_node_end_style = sm_node_style->duplicate(); - sm_node_end_style->set_border_width_all(1 * EDSCALE); - sm_node_end_style->set_border_color(error_color); - theme->set_stylebox("node_frame_end", "GraphStateMachine", sm_node_end_style); - - theme->set_font("node_title_font", "GraphStateMachine", theme->get_font(SNAME("font"), SNAME("Label"))); - theme->set_font_size("node_title_font_size", "GraphStateMachine", theme->get_font_size(SNAME("font_size"), SNAME("Label"))); - theme->set_color("node_title_font_color", "GraphStateMachine", font_color); - - theme->set_color("transition_color", "GraphStateMachine", font_color); - theme->set_color("transition_disabled_color", "GraphStateMachine", font_color * Color(1, 1, 1, 0.2)); - theme->set_color("transition_icon_color", "GraphStateMachine", Color(1, 1, 1)); - theme->set_color("transition_icon_disabled_color", "GraphStateMachine", Color(1, 1, 1, 0.2)); - theme->set_color("highlight_color", "GraphStateMachine", accent_color); - theme->set_color("highlight_disabled_color", "GraphStateMachine", accent_color * Color(1, 1, 1, 0.6)); - theme->set_color("guideline_color", "GraphStateMachine", font_color * Color(1, 1, 1, 0.3)); - - theme->set_color("playback_color", "GraphStateMachine", font_color); - theme->set_color("playback_background_color", "GraphStateMachine", font_color * Color(1, 1, 1, 0.3)); - - // GridContainer - 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"), EditorStringName(EditorIcons))); - theme->set_icon("parent_folder", "FileDialog", theme->get_icon(SNAME("ArrowUp"), EditorStringName(EditorIcons))); - theme->set_icon("back_folder", "FileDialog", theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); - theme->set_icon("forward_folder", "FileDialog", theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons))); - theme->set_icon("reload", "FileDialog", theme->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); - theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon(SNAME("GuiVisibilityVisible"), EditorStringName(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_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 - theme->set_constant("margin", "ColorPicker", default_margin_size); - theme->set_constant("sv_width", "ColorPicker", 256 * EDSCALE); - theme->set_constant("sv_height", "ColorPicker", 256 * EDSCALE); - theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE); - theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE); - theme->set_constant("center_slider_grabbers", "ColorPicker", 1); - theme->set_icon("screen_picker", "ColorPicker", theme->get_icon(SNAME("ColorPick"), EditorStringName(EditorIcons))); - theme->set_icon("shape_circle", "ColorPicker", theme->get_icon(SNAME("PickerShapeCircle"), EditorStringName(EditorIcons))); - theme->set_icon("shape_rect", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangle"), EditorStringName(EditorIcons))); - theme->set_icon("shape_rect_wheel", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangleWheel"), EditorStringName(EditorIcons))); - theme->set_icon("add_preset", "ColorPicker", theme->get_icon(SNAME("Add"), EditorStringName(EditorIcons))); - theme->set_icon("sample_bg", "ColorPicker", theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons))); - theme->set_icon("sample_revert", "ColorPicker", theme->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); - theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons))); - theme->set_icon("bar_arrow", "ColorPicker", theme->get_icon(SNAME("ColorPickerBarArrow"), EditorStringName(EditorIcons))); - theme->set_icon("picker_cursor", "ColorPicker", theme->get_icon(SNAME("PickerCursor"), EditorStringName(EditorIcons))); - - // ColorPickerButton - theme->set_icon("bg", "ColorPickerButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons))); - - // ColorPresetButton - Ref preset_sb = make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2); - theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb); - theme->set_icon("preset_bg", "ColorPresetButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons))); - theme->set_icon("overbright_indicator", "ColorPresetButton", theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons))); - - // Information on 3D viewport - Ref style_info_3d_viewport = style_default->duplicate(); - style_info_3d_viewport->set_bg_color(style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5)); - style_info_3d_viewport->set_border_width_all(0); - theme->set_stylebox("Information3dViewport", EditorStringName(EditorStyles), style_info_3d_viewport); - - // Asset Library. - theme->set_stylebox("bg", "AssetLib", style_empty); - theme->set_stylebox("panel", "AssetLib", style_content_panel); - theme->set_color("status_color", "AssetLib", Color(0.5, 0.5, 0.5)); - theme->set_icon("dismiss", "AssetLib", theme->get_icon(SNAME("Close"), EditorStringName(EditorIcons))); - - // Theme editor. - theme->set_color("preview_picker_overlay_color", "ThemeEditor", Color(0.1, 0.1, 0.1, 0.25)); - Color theme_preview_picker_bg_color = accent_color; - theme_preview_picker_bg_color.a = 0.2; - Ref theme_preview_picker_sb = make_flat_stylebox(theme_preview_picker_bg_color, 0, 0, 0, 0); - theme_preview_picker_sb->set_border_color(accent_color); - theme_preview_picker_sb->set_border_width_all(1.0 * EDSCALE); - theme->set_stylebox("preview_picker_overlay", "ThemeEditor", theme_preview_picker_sb); - Color theme_preview_picker_label_bg_color = accent_color; - theme_preview_picker_label_bg_color.set_v(0.5); - Ref theme_preview_picker_label_sb = make_flat_stylebox(theme_preview_picker_label_bg_color, 4.0, 1.0, 4.0, 3.0); - theme->set_stylebox("preview_picker_label", "ThemeEditor", theme_preview_picker_label_sb); - - // Dictionary editor add item. - // Expand to the left and right by 4px to compensate for the dictionary editor margins. - Ref style_dictionary_add_item = make_flat_stylebox(prop_subsection_color, 0, 4, 0, 4, corner_radius); - style_dictionary_add_item->set_expand_margin(SIDE_LEFT, 4 * EDSCALE); - style_dictionary_add_item->set_expand_margin(SIDE_RIGHT, 4 * EDSCALE); - theme->set_stylebox("DictionaryAddItem", EditorStringName(EditorStyles), style_dictionary_add_item); - - Ref vshader_label_style = make_empty_stylebox(2, 1, 2, 1); - theme->set_stylebox("label_style", "VShaderEditor", vshader_label_style); - - // Project manager. - theme->set_stylebox("search_panel", "ProjectManager", style_tree_bg); - theme->set_constant("sidebar_button_icon_separation", "ProjectManager", int(6 * EDSCALE)); - - // adaptive script theme constants - // for comments and elements with lower relevance - const Color dim_color = Color(font_color, 0.5); - - 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.27); - - 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 doc_comment_color = dark_theme ? Color(0.6, 0.7, 0.8, 0.8) : Color(0.15, 0.15, 0.4, 0.7); - 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; - const Color completion_background_color = dark_theme ? base_color : background_color; - const Color completion_selected_color = alpha1; - 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 = 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 = 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 = 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 = 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 folded_code_region_color = Color(0.68, 0.46, 0.77, 0.2); - const Color search_result_color = alpha1; - 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"); - if (text_editor_color_theme == "Default") { - 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", 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/doc_comment_color", doc_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); - setting->set_initial_value("text_editor/theme/highlighting/completion_background_color", completion_background_color, true); - 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); - setting->set_initial_value("text_editor/theme/highlighting/safe_line_number_color", safe_line_number_color, true); - setting->set_initial_value("text_editor/theme/highlighting/caret_color", caret_color, true); - setting->set_initial_value("text_editor/theme/highlighting/caret_background_color", caret_background_color, true); - setting->set_initial_value("text_editor/theme/highlighting/text_selected_color", text_selected_color, true); - setting->set_initial_value("text_editor/theme/highlighting/selection_color", selection_color, true); - setting->set_initial_value("text_editor/theme/highlighting/brace_mismatch_color", brace_mismatch_color, true); - setting->set_initial_value("text_editor/theme/highlighting/current_line_color", current_line_color, true); - setting->set_initial_value("text_editor/theme/highlighting/line_length_guideline_color", line_length_guideline_color, true); - setting->set_initial_value("text_editor/theme/highlighting/word_highlighted_color", word_highlighted_color, true); - setting->set_initial_value("text_editor/theme/highlighting/number_color", number_color, true); - setting->set_initial_value("text_editor/theme/highlighting/function_color", function_color, true); - setting->set_initial_value("text_editor/theme/highlighting/member_variable_color", member_variable_color, true); - setting->set_initial_value("text_editor/theme/highlighting/mark_color", mark_color, true); - setting->set_initial_value("text_editor/theme/highlighting/bookmark_color", bookmark_color, true); - setting->set_initial_value("text_editor/theme/highlighting/breakpoint_color", breakpoint_color, true); - setting->set_initial_value("text_editor/theme/highlighting/executing_line_color", executing_line_color, true); - setting->set_initial_value("text_editor/theme/highlighting/code_folding_color", code_folding_color, true); - setting->set_initial_value("text_editor/theme/highlighting/folded_code_region_color", folded_code_region_color, true); - setting->set_initial_value("text_editor/theme/highlighting/search_result_color", search_result_color, true); - setting->set_initial_value("text_editor/theme/highlighting/search_result_border_color", search_result_border_color, true); - } else if (text_editor_color_theme == "Godot 2") { - setting->load_text_editor_theme(); - } - - // Now theme is loaded, apply it to CodeEdit. - theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), EditorStringName(EditorFonts))); - theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), EditorStringName(EditorFonts))); - - Ref 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(memnew(StyleBoxEmpty))); - - theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), EditorStringName(EditorIcons))); - theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons))); - theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), EditorStringName(EditorIcons))); - theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("CodeFoldDownArrow"), EditorStringName(EditorIcons))); - theme->set_icon("folded_code_region", "CodeEdit", theme->get_icon(SNAME("CodeRegionFoldedRightArrow"), EditorStringName(EditorIcons))); - theme->set_icon("can_fold_code_region", "CodeEdit", theme->get_icon(SNAME("CodeRegionFoldDownArrow"), EditorStringName(EditorIcons))); - theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), EditorStringName(EditorIcons))); - theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), EditorStringName(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("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")); - theme->set_color("caret_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/caret_color")); - theme->set_color("font_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/text_selected_color")); - theme->set_color("selection_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/selection_color")); - theme->set_color("brace_mismatch_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/brace_mismatch_color")); - theme->set_color("current_line_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/current_line_color")); - theme->set_color("line_length_guideline_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/line_length_guideline_color")); - theme->set_color("word_highlighted_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/word_highlighted_color")); - theme->set_color("bookmark_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/bookmark_color")); - theme->set_color("breakpoint_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/breakpoint_color")); - theme->set_color("executing_line_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/executing_line_color")); - theme->set_color("code_folding_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/code_folding_color")); - theme->set_color("folded_code_region_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/folded_code_region_color")); - theme->set_color("search_result_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_color")); - theme->set_color("search_result_border_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_border_color")); -} - -Ref EditorThemeManager::_create_base_theme(const Ref &p_old_theme) { - OS::get_singleton()->benchmark_begin_measure("EditorTheme", "Create Base Theme"); - - Ref theme = memnew(EditorTheme); - populate_editor_theme(theme, p_old_theme); + _populate_standard_styles(theme, config); + _populate_editor_styles(theme, config); + _populate_text_editor_styles(theme, config); OS::get_singleton()->benchmark_end_measure("EditorTheme", "Create Base Theme"); return theme; } +EditorThemeManager::ThemeConfiguration EditorThemeManager::_create_theme_config(const Ref &p_theme) { + ThemeConfiguration config; + + // Basic properties. + + config.preset = EDITOR_GET("interface/theme/preset"); + config.dark_theme = EditorSettings::get_singleton()->is_dark_theme(); + + config.base_color = EDITOR_GET("interface/theme/base_color"); + config.accent_color = EDITOR_GET("interface/theme/accent_color"); + config.contrast = EDITOR_GET("interface/theme/contrast"); + config.icon_saturation = EDITOR_GET("interface/theme/icon_saturation"); + + // Extra properties. + + config.extra_spacing = EDITOR_GET("interface/theme/additional_spacing"); + // Ensure borders are visible when using an editor scale below 100%. + config.border_width = CLAMP((int)EDITOR_GET("interface/theme/border_size"), 0, 2) * MAX(1, EDSCALE); + config.corner_radius = CLAMP((int)EDITOR_GET("interface/theme/corner_radius"), 0, 6); + + config.draw_extra_borders = EDITOR_GET("interface/theme/draw_extra_borders"); + config.relationship_line_opacity = EDITOR_GET("interface/theme/relationship_line_opacity"); + config.thumb_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); + config.class_icon_size = 16 * EDSCALE; + config.increase_scrollbar_touch_area = EDITOR_GET("interface/touchscreen/increase_scrollbar_touch_area"); + config.gizmo_handle_scale = EDITOR_GET("interface/touchscreen/scale_gizmo_handles"); + config.color_picker_button_height = 28 * EDSCALE; + + config.default_contrast = 0.3; // Make sure to keep this in sync with the editor settings definition. + + // Generated properties. + + config.base_margin = 4; + config.increased_margin = config.base_margin + config.extra_spacing; + config.popup_margin = config.base_margin * 3 * EDSCALE; + config.window_border_margin = config.base_margin * 2; + config.top_bar_separation = config.base_margin * 2 * EDSCALE; + // 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). + const int separation_base = config.increased_margin + 6; + config.forced_even_separation = separation_base + (separation_base % 2); + + if (config.preset != "Custom") { + Color preset_accent_color; + Color preset_base_color; + float preset_contrast = 0; + bool preset_draw_extra_borders = false; + + // Please use alphabetical order if you're adding a new theme here. + if (config.preset == "Breeze Dark") { + preset_accent_color = Color(0.26, 0.76, 1.00); + preset_base_color = Color(0.24, 0.26, 0.28); + preset_contrast = config.default_contrast; + } else if (config.preset == "Godot 2") { + preset_accent_color = Color(0.53, 0.67, 0.89); + preset_base_color = Color(0.24, 0.23, 0.27); + preset_contrast = config.default_contrast; + } else if (config.preset == "Gray") { + preset_accent_color = Color(0.44, 0.73, 0.98); + preset_base_color = Color(0.24, 0.24, 0.24); + preset_contrast = config.default_contrast; + } else if (config.preset == "Light") { + preset_accent_color = Color(0.18, 0.50, 1.00); + preset_base_color = Color(0.9, 0.9, 0.9); + // A negative contrast rate looks better for light themes, since it better follows the natural order of UI "elevation". + preset_contrast = -0.06; + } else if (config.preset == "Solarized (Dark)") { + preset_accent_color = Color(0.15, 0.55, 0.82); + preset_base_color = Color(0.04, 0.23, 0.27); + preset_contrast = config.default_contrast; + } else if (config.preset == "Solarized (Light)") { + preset_accent_color = Color(0.15, 0.55, 0.82); + preset_base_color = Color(0.89, 0.86, 0.79); + // A negative contrast rate looks better for light themes, since it better follows the natural order of UI "elevation". + preset_contrast = -0.06; + } else if (config.preset == "Black (OLED)") { + preset_accent_color = Color(0.45, 0.75, 1.0); + preset_base_color = Color(0, 0, 0); + // The contrast rate value is irrelevant on a fully black theme. + preset_contrast = 0.0; + preset_draw_extra_borders = true; + } else { // Default + preset_accent_color = Color(0.44, 0.73, 0.98); + preset_base_color = Color(0.21, 0.24, 0.29); + preset_contrast = config.default_contrast; + } + + config.accent_color = preset_accent_color; + config.base_color = preset_base_color; + config.contrast = preset_contrast; + config.draw_extra_borders = preset_draw_extra_borders; + + EditorSettings::get_singleton()->set_initial_value("interface/theme/accent_color", config.accent_color); + EditorSettings::get_singleton()->set_initial_value("interface/theme/base_color", config.base_color); + EditorSettings::get_singleton()->set_initial_value("interface/theme/contrast", config.contrast); + EditorSettings::get_singleton()->set_initial_value("interface/theme/draw_extra_borders", config.draw_extra_borders); + } + + // Enforce values in case they were adjusted or overridden. + EditorSettings::get_singleton()->set_manually("interface/theme/preset", config.preset); + EditorSettings::get_singleton()->set_manually("interface/theme/accent_color", config.accent_color); + EditorSettings::get_singleton()->set_manually("interface/theme/base_color", config.base_color); + EditorSettings::get_singleton()->set_manually("interface/theme/contrast", config.contrast); + EditorSettings::get_singleton()->set_manually("interface/theme/draw_extra_borders", config.draw_extra_borders); + + return config; +} + +void EditorThemeManager::_create_shared_styles(const Ref &p_theme, ThemeConfiguration &p_config) { + // Colors. + { + // Base colors. + + p_theme->set_color("base_color", EditorStringName(Editor), p_config.base_color); + p_theme->set_color("accent_color", EditorStringName(Editor), p_config.accent_color); + + // White (dark theme) or black (light theme), will be used to generate the rest of the colors + p_config.mono_color = p_config.dark_theme ? Color(1, 1, 1) : Color(0, 0, 0); + + // 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. + p_config.dark_color_1 = p_config.base_color.lerp(Color(0, 0, 0, 1), p_config.contrast).clamp(); + p_config.dark_color_2 = p_config.base_color.lerp(Color(0, 0, 0, 1), p_config.contrast * 1.5).clamp(); + p_config.dark_color_3 = p_config.base_color.lerp(Color(0, 0, 0, 1), p_config.contrast * 2).clamp(); + + p_config.contrast_color_1 = p_config.base_color.lerp(p_config.mono_color, MAX(p_config.contrast, p_config.default_contrast)); + p_config.contrast_color_2 = p_config.base_color.lerp(p_config.mono_color, MAX(p_config.contrast * 1.5, p_config.default_contrast * 1.5)); + + p_config.highlight_color = Color(p_config.accent_color.r, p_config.accent_color.g, p_config.accent_color.b, 0.275); + p_config.highlight_disabled_color = p_config.highlight_color.lerp(p_config.dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); + + p_config.success_color = Color(0.45, 0.95, 0.5); + p_config.warning_color = Color(1, 0.87, 0.4); + p_config.error_color = Color(1, 0.47, 0.42); + if (!p_config.dark_theme) { + // Darken some colors to be readable on a light background. + p_config.success_color = p_config.success_color.lerp(p_config.mono_color, 0.35); + p_config.warning_color = p_config.warning_color.lerp(p_config.mono_color, 0.35); + p_config.error_color = p_config.error_color.lerp(p_config.mono_color, 0.25); + } + + p_theme->set_color("mono_color", EditorStringName(Editor), p_config.mono_color); + p_theme->set_color("dark_color_1", EditorStringName(Editor), p_config.dark_color_1); + p_theme->set_color("dark_color_2", EditorStringName(Editor), p_config.dark_color_2); + p_theme->set_color("dark_color_3", EditorStringName(Editor), p_config.dark_color_3); + p_theme->set_color("contrast_color_1", EditorStringName(Editor), p_config.contrast_color_1); + p_theme->set_color("contrast_color_2", EditorStringName(Editor), p_config.contrast_color_2); + p_theme->set_color("highlight_color", EditorStringName(Editor), p_config.highlight_color); + p_theme->set_color("highlight_disabled_color", EditorStringName(Editor), p_config.highlight_disabled_color); + p_theme->set_color("success_color", EditorStringName(Editor), p_config.success_color); + p_theme->set_color("warning_color", EditorStringName(Editor), p_config.warning_color); + p_theme->set_color("error_color", EditorStringName(Editor), p_config.error_color); + + // Only used when the Draw Extra Borders editor setting is enabled. + p_config.extra_border_color_1 = Color(0.5, 0.5, 0.5); + p_config.extra_border_color_2 = p_config.dark_theme ? Color(0.3, 0.3, 0.3) : Color(0.7, 0.7, 0.7); + + p_theme->set_color("extra_border_color_1", EditorStringName(Editor), p_config.extra_border_color_1); + p_theme->set_color("extra_border_color_2", EditorStringName(Editor), p_config.extra_border_color_2); + + // Font colors. + + p_config.font_color = p_config.mono_color.lerp(p_config.base_color, 0.25); + p_config.font_focus_color = p_config.mono_color.lerp(p_config.base_color, 0.125); + p_config.font_hover_color = p_config.mono_color.lerp(p_config.base_color, 0.125); + p_config.font_pressed_color = p_config.accent_color; + p_config.font_hover_pressed_color = p_config.font_hover_color.lerp(p_config.accent_color, 0.74); + p_config.font_disabled_color = Color(p_config.mono_color.r, p_config.mono_color.g, p_config.mono_color.b, 0.35); + p_config.font_readonly_color = Color(p_config.mono_color.r, p_config.mono_color.g, p_config.mono_color.b, 0.65); + p_config.font_placeholder_color = Color(p_config.mono_color.r, p_config.mono_color.g, p_config.mono_color.b, 0.6); + p_config.font_outline_color = Color(0, 0, 0, 0); + + p_theme->set_color("font_color", EditorStringName(Editor), p_config.font_color); + p_theme->set_color("font_focus_color", EditorStringName(Editor), p_config.font_focus_color); + p_theme->set_color("font_hover_color", EditorStringName(Editor), p_config.font_hover_color); + p_theme->set_color("font_pressed_color", EditorStringName(Editor), p_config.font_pressed_color); + p_theme->set_color("font_hover_pressed_color", EditorStringName(Editor), p_config.font_hover_pressed_color); + p_theme->set_color("font_disabled_color", EditorStringName(Editor), p_config.font_disabled_color); + p_theme->set_color("font_readonly_color", EditorStringName(Editor), p_config.font_readonly_color); + p_theme->set_color("font_placeholder_color", EditorStringName(Editor), p_config.font_placeholder_color); + p_theme->set_color("font_outline_color", EditorStringName(Editor), p_config.font_outline_color); + + // Icon colors. + + p_config.icon_normal_color = Color(1, 1, 1); + p_config.icon_focus_color = p_config.icon_normal_color * (p_config.dark_theme ? 1.15 : 1.45); + p_config.icon_focus_color.a = 1.0; + p_config.icon_hover_color = p_config.icon_focus_color; + // 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. + p_config.icon_pressed_color = p_config.accent_color * (p_config.dark_theme ? 1.15 : 3.5); + p_config.icon_pressed_color.a = 1.0; + p_config.icon_disabled_color = Color(p_config.icon_normal_color, 0.4); + + p_theme->set_color("icon_normal_color", EditorStringName(Editor), p_config.icon_normal_color); + p_theme->set_color("icon_focus_color", EditorStringName(Editor), p_config.icon_focus_color); + p_theme->set_color("icon_hover_color", EditorStringName(Editor), p_config.icon_hover_color); + p_theme->set_color("icon_pressed_color", EditorStringName(Editor), p_config.icon_pressed_color); + p_theme->set_color("icon_disabled_color", EditorStringName(Editor), p_config.icon_disabled_color); + + // Additional GUI colors. + + p_config.shadow_color = Color(0, 0, 0, p_config.dark_theme ? 0.3 : 0.1); + p_config.selection_color = p_config.accent_color * Color(1, 1, 1, 0.4); + p_config.disabled_border_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.7); + p_config.disabled_bg_color = p_config.mono_color.inverted().lerp(p_config.base_color, 0.9); + p_config.separator_color = Color(p_config.mono_color.r, p_config.mono_color.g, p_config.mono_color.b, 0.1); + + p_theme->set_color("selection_color", EditorStringName(Editor), p_config.selection_color); + p_theme->set_color("disabled_border_color", EditorStringName(Editor), p_config.disabled_border_color); + p_theme->set_color("disabled_bg_color", EditorStringName(Editor), p_config.disabled_bg_color); + p_theme->set_color("separator_color", EditorStringName(Editor), p_config.separator_color); + + // Additional editor colors. + + p_theme->set_color("box_selection_fill_color", EditorStringName(Editor), p_config.accent_color * Color(1, 1, 1, 0.3)); + p_theme->set_color("box_selection_stroke_color", EditorStringName(Editor), p_config.accent_color * Color(1, 1, 1, 0.8)); + + p_theme->set_color("axis_x_color", EditorStringName(Editor), Color(0.96, 0.20, 0.32)); + p_theme->set_color("axis_y_color", EditorStringName(Editor), Color(0.53, 0.84, 0.01)); + p_theme->set_color("axis_z_color", EditorStringName(Editor), Color(0.16, 0.55, 0.96)); + p_theme->set_color("axis_w_color", EditorStringName(Editor), Color(0.55, 0.55, 0.55)); + + const float prop_color_saturation = p_config.accent_color.get_s() * 0.75; + const float prop_color_value = p_config.accent_color.get_v(); + + p_theme->set_color("property_color_x", EditorStringName(Editor), Color().from_hsv(0.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); + p_theme->set_color("property_color_y", EditorStringName(Editor), Color().from_hsv(1.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); + p_theme->set_color("property_color_z", EditorStringName(Editor), Color().from_hsv(2.0 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); + p_theme->set_color("property_color_w", EditorStringName(Editor), Color().from_hsv(1.5 / 3.0 + 0.05, prop_color_saturation, prop_color_value)); + + // Special colors for rendering methods. + + p_theme->set_color("forward_plus_color", EditorStringName(Editor), Color::hex(0x5d8c3fff)); + p_theme->set_color("mobile_color", EditorStringName(Editor), Color::hex(0xa5557dff)); + p_theme->set_color("gl_compatibility_color", EditorStringName(Editor), Color::hex(0x5586a4ff)); + + if (p_config.dark_theme) { + p_theme->set_color("highend_color", EditorStringName(Editor), Color(1.0, 0.0, 0.0)); + } else { + p_theme->set_color("highend_color", EditorStringName(Editor), Color::hex(0xad1128ff)); + } + } + + // Constants. + { + // Can't save single float in theme, so using Color. + p_theme->set_color("icon_saturation", EditorStringName(Editor), Color(p_config.icon_saturation, p_config.icon_saturation, p_config.icon_saturation)); + + // Controls may rely on the scale for their internal drawing logic. + p_theme->set_default_base_scale(EDSCALE); + p_theme->set_constant("scale", EditorStringName(Editor), EDSCALE); + + p_theme->set_constant("thumb_size", EditorStringName(Editor), p_config.thumb_size); + p_theme->set_constant("class_icon_size", EditorStringName(Editor), p_config.class_icon_size); + p_theme->set_constant("color_picker_button_height", EditorStringName(Editor), p_config.color_picker_button_height); + p_theme->set_constant("gizmo_handle_scale", EditorStringName(Editor), p_config.gizmo_handle_scale); + + p_theme->set_constant("base_margin", EditorStringName(Editor), p_config.base_margin); + p_theme->set_constant("increased_margin", EditorStringName(Editor), p_config.increased_margin); + p_theme->set_constant("window_border_margin", EditorStringName(Editor), p_config.window_border_margin); + p_theme->set_constant("top_bar_separation", EditorStringName(Editor), p_config.top_bar_separation); + + p_theme->set_constant("dark_theme", EditorStringName(Editor), p_config.dark_theme); + } + + // Styleboxes. + { + // This is the basic stylebox, used as a base for most other styleboxes (through `duplicate()`). + p_config.base_style = make_flat_stylebox(p_config.base_color, p_config.base_margin, p_config.base_margin, p_config.base_margin, p_config.base_margin, p_config.corner_radius); + p_config.base_style->set_border_width_all(p_config.border_width); + p_config.base_style->set_border_color(p_config.base_color); + + p_config.base_empty_style = make_empty_stylebox(p_config.base_margin, p_config.base_margin, p_config.base_margin, p_config.base_margin); + + // Button styles. + { + p_config.widget_margin = Vector2(p_config.increased_margin + 2, p_config.increased_margin + 1) * EDSCALE; + + p_config.button_style = p_config.base_style->duplicate(); + p_config.button_style->set_content_margin_individual(p_config.widget_margin.x, p_config.widget_margin.y, p_config.widget_margin.x, p_config.widget_margin.y); + p_config.button_style->set_bg_color(p_config.dark_color_1); + if (p_config.draw_extra_borders) { + p_config.button_style->set_border_width_all(Math::round(EDSCALE)); + p_config.button_style->set_border_color(p_config.extra_border_color_1); + } else { + p_config.button_style->set_border_color(p_config.dark_color_2); + } + + p_config.button_style_disabled = p_config.button_style->duplicate(); + p_config.button_style_disabled->set_bg_color(p_config.disabled_bg_color); + if (p_config.draw_extra_borders) { + p_config.button_style_disabled->set_border_color(p_config.extra_border_color_2); + } else { + p_config.button_style_disabled->set_border_color(p_config.disabled_border_color); + } + + p_config.button_style_focus = p_config.button_style->duplicate(); + p_config.button_style_focus->set_draw_center(false); + p_config.button_style_focus->set_border_width_all(Math::round(2 * MAX(1, EDSCALE))); + p_config.button_style_focus->set_border_color(p_config.accent_color); + + p_config.button_style_pressed = p_config.button_style->duplicate(); + p_config.button_style_pressed->set_bg_color(p_config.dark_color_1.darkened(0.125)); + + p_config.button_style_hover = p_config.button_style->duplicate(); + p_config.button_style_hover->set_bg_color(p_config.mono_color * Color(1, 1, 1, 0.11)); + if (p_config.draw_extra_borders) { + p_config.button_style_hover->set_border_color(p_config.extra_border_color_1); + } else { + p_config.button_style_hover->set_border_color(p_config.mono_color * Color(1, 1, 1, 0.05)); + } + } + + // Windows and popups. + { + p_config.popup_style = p_config.base_style->duplicate(); + p_config.popup_style->set_content_margin_all(p_config.popup_margin); + p_config.popup_style->set_border_color(p_config.contrast_color_1); + p_config.popup_style->set_shadow_color(p_config.shadow_color); + p_config.popup_style->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). + p_config.popup_style->set_corner_radius_all(0); + + p_config.window_style = p_config.popup_style->duplicate(); + p_config.window_style->set_border_color(p_config.base_color); + p_config.window_style->set_border_width(SIDE_TOP, 24 * EDSCALE); + p_config.window_style->set_expand_margin(SIDE_TOP, 24 * EDSCALE); + + // Prevent corner artifacts between window title and body. + p_config.dialog_style = p_config.base_style->duplicate(); + p_config.dialog_style->set_corner_radius(CORNER_TOP_LEFT, 0); + p_config.dialog_style->set_corner_radius(CORNER_TOP_RIGHT, 0); + // Prevent visible line between window title and body. + p_config.dialog_style->set_expand_margin(SIDE_BOTTOM, 2 * EDSCALE); + } + + // Panels. + { + p_config.panel_container_style = p_config.button_style->duplicate(); + p_config.panel_container_style->set_draw_center(false); + p_config.panel_container_style->set_border_width_all(0); + + // Content panel for tabs and similar containers. + + // Compensate for the border. + const int content_panel_margin = p_config.base_margin * EDSCALE + p_config.border_width; + + p_config.content_panel_style = p_config.base_style->duplicate(); + p_config.content_panel_style->set_border_color(p_config.dark_color_3); + p_config.content_panel_style->set_border_width_all(p_config.border_width); + p_config.content_panel_style->set_border_width(Side::SIDE_TOP, 0); + p_config.content_panel_style->set_corner_radius(CORNER_TOP_LEFT, 0); + p_config.content_panel_style->set_corner_radius(CORNER_TOP_RIGHT, 0); + p_config.content_panel_style->set_content_margin_individual(content_panel_margin, 2 * EDSCALE + content_panel_margin, content_panel_margin, content_panel_margin); + + // Trees and similarly inset panels. + + p_config.tree_panel_style = p_config.base_style->duplicate(); + // Make Trees easier to distinguish from other controls by using a darker background color. + p_config.tree_panel_style->set_bg_color(p_config.dark_color_1.lerp(p_config.dark_color_2, 0.5)); + if (p_config.draw_extra_borders) { + p_config.tree_panel_style->set_border_width_all(Math::round(EDSCALE)); + p_config.tree_panel_style->set_border_color(p_config.extra_border_color_2); + } else { + p_config.tree_panel_style->set_border_color(p_config.dark_color_3); + } + } + } +} + +void EditorThemeManager::_populate_standard_styles(const Ref &p_theme, ThemeConfiguration &p_config) { + // Panels. + { + // Panel. + p_theme->set_stylebox("panel", "Panel", make_flat_stylebox(p_config.dark_color_1, 6, 4, 6, 4, p_config.corner_radius)); + + // PanelContainer. + p_theme->set_stylebox("panel", "PanelContainer", p_config.panel_container_style); + + // TooltipPanel & TooltipLabel. + { + // TooltipPanel is also used for custom tooltips, while TooltipLabel + // is only relevant for default tooltips. + + p_theme->set_color("font_color", "TooltipLabel", p_config.font_hover_color); + p_theme->set_color("font_shadow_color", "TooltipLabel", Color(0, 0, 0, 0)); + + Ref style_tooltip = p_config.popup_style->duplicate(); + style_tooltip->set_shadow_size(0); + style_tooltip->set_content_margin_all(p_config.base_margin * EDSCALE * 0.5); + style_tooltip->set_bg_color(p_config.dark_color_3 * Color(0.8, 0.8, 0.8, 0.9)); + style_tooltip->set_border_width_all(0); + p_theme->set_stylebox("panel", "TooltipPanel", style_tooltip); + } + + // PopupPanel + p_theme->set_stylebox("panel", "PopupPanel", p_config.popup_style); + } + + // Buttons. + { + // Button. + + p_theme->set_stylebox("normal", "Button", p_config.button_style); + p_theme->set_stylebox("hover", "Button", p_config.button_style_hover); + p_theme->set_stylebox("pressed", "Button", p_config.button_style_pressed); + p_theme->set_stylebox("focus", "Button", p_config.button_style_focus); + p_theme->set_stylebox("disabled", "Button", p_config.button_style_disabled); + + p_theme->set_color("font_color", "Button", p_config.font_color); + p_theme->set_color("font_hover_color", "Button", p_config.font_hover_color); + p_theme->set_color("font_hover_pressed_color", "Button", p_config.font_hover_pressed_color); + p_theme->set_color("font_focus_color", "Button", p_config.font_focus_color); + p_theme->set_color("font_pressed_color", "Button", p_config.font_pressed_color); + p_theme->set_color("font_disabled_color", "Button", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "Button", p_config.font_outline_color); + + p_theme->set_color("icon_normal_color", "Button", p_config.icon_normal_color); + p_theme->set_color("icon_hover_color", "Button", p_config.icon_hover_color); + p_theme->set_color("icon_focus_color", "Button", p_config.icon_focus_color); + p_theme->set_color("icon_pressed_color", "Button", p_config.icon_pressed_color); + p_theme->set_color("icon_disabled_color", "Button", p_config.icon_disabled_color); + + p_theme->set_constant("h_separation", "Button", 4 * EDSCALE); + p_theme->set_constant("outline_size", "Button", 0); + + // MenuButton. + + p_theme->set_stylebox("normal", "MenuButton", p_config.panel_container_style); + p_theme->set_stylebox("hover", "MenuButton", p_config.button_style_hover); + p_theme->set_stylebox("pressed", "MenuButton", p_config.panel_container_style); + p_theme->set_stylebox("focus", "MenuButton", p_config.panel_container_style); + p_theme->set_stylebox("disabled", "MenuButton", p_config.panel_container_style); + + p_theme->set_color("font_color", "MenuButton", p_config.font_color); + p_theme->set_color("font_hover_color", "MenuButton", p_config.font_hover_color); + p_theme->set_color("font_hover_pressed_color", "MenuButton", p_config.font_hover_pressed_color); + p_theme->set_color("font_focus_color", "MenuButton", p_config.font_focus_color); + p_theme->set_color("font_outline_color", "MenuButton", p_config.font_outline_color); + + p_theme->set_constant("outline_size", "MenuButton", 0); + + // MenuBar. + + p_theme->set_stylebox("normal", "MenuBar", p_config.button_style); + p_theme->set_stylebox("hover", "MenuBar", p_config.button_style_hover); + p_theme->set_stylebox("pressed", "MenuBar", p_config.button_style_pressed); + p_theme->set_stylebox("disabled", "MenuBar", p_config.button_style_disabled); + + p_theme->set_color("font_color", "MenuBar", p_config.font_color); + p_theme->set_color("font_hover_color", "MenuBar", p_config.font_hover_color); + p_theme->set_color("font_hover_pressed_color", "MenuBar", p_config.font_hover_pressed_color); + p_theme->set_color("font_focus_color", "MenuBar", p_config.font_focus_color); + p_theme->set_color("font_pressed_color", "MenuBar", p_config.font_pressed_color); + p_theme->set_color("font_disabled_color", "MenuBar", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "MenuBar", p_config.font_outline_color); + + p_theme->set_color("icon_normal_color", "MenuBar", p_config.icon_normal_color); + p_theme->set_color("icon_hover_color", "MenuBar", p_config.icon_hover_color); + p_theme->set_color("icon_focus_color", "MenuBar", p_config.icon_focus_color); + p_theme->set_color("icon_pressed_color", "MenuBar", p_config.icon_pressed_color); + p_theme->set_color("icon_disabled_color", "MenuBar", p_config.icon_disabled_color); + + p_theme->set_constant("h_separation", "MenuBar", 4 * EDSCALE); + p_theme->set_constant("outline_size", "MenuBar", 0); + + // OptionButton. + { + Ref option_button_focus_style = p_config.button_style_focus->duplicate(); + Ref option_button_normal_style = p_config.button_style->duplicate(); + Ref option_button_hover_style = p_config.button_style_hover->duplicate(); + Ref option_button_pressed_style = p_config.button_style_pressed->duplicate(); + Ref option_button_disabled_style = p_config.button_style_disabled->duplicate(); + + option_button_focus_style->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); + option_button_normal_style->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); + option_button_hover_style->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); + option_button_pressed_style->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); + option_button_disabled_style->set_content_margin(SIDE_RIGHT, 4 * EDSCALE); + + p_theme->set_stylebox("focus", "OptionButton", option_button_focus_style); + p_theme->set_stylebox("normal", "OptionButton", p_config.button_style); + p_theme->set_stylebox("hover", "OptionButton", p_config.button_style_hover); + p_theme->set_stylebox("pressed", "OptionButton", p_config.button_style_pressed); + p_theme->set_stylebox("disabled", "OptionButton", p_config.button_style_disabled); + + p_theme->set_stylebox("normal_mirrored", "OptionButton", option_button_normal_style); + p_theme->set_stylebox("hover_mirrored", "OptionButton", option_button_hover_style); + p_theme->set_stylebox("pressed_mirrored", "OptionButton", option_button_pressed_style); + p_theme->set_stylebox("disabled_mirrored", "OptionButton", option_button_disabled_style); + + p_theme->set_color("font_color", "OptionButton", p_config.font_color); + p_theme->set_color("font_hover_color", "OptionButton", p_config.font_hover_color); + p_theme->set_color("font_hover_pressed_color", "OptionButton", p_config.font_hover_pressed_color); + p_theme->set_color("font_focus_color", "OptionButton", p_config.font_focus_color); + p_theme->set_color("font_pressed_color", "OptionButton", p_config.font_pressed_color); + p_theme->set_color("font_disabled_color", "OptionButton", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "OptionButton", p_config.font_outline_color); + + p_theme->set_color("icon_normal_color", "OptionButton", p_config.icon_normal_color); + p_theme->set_color("icon_hover_color", "OptionButton", p_config.icon_hover_color); + p_theme->set_color("icon_focus_color", "OptionButton", p_config.icon_focus_color); + p_theme->set_color("icon_pressed_color", "OptionButton", p_config.icon_pressed_color); + p_theme->set_color("icon_disabled_color", "OptionButton", p_config.icon_disabled_color); + + p_theme->set_icon("arrow", "OptionButton", p_theme->get_icon(SNAME("GuiOptionArrow"), EditorStringName(EditorIcons))); + p_theme->set_constant("arrow_margin", "OptionButton", p_config.widget_margin.x - 2 * EDSCALE); + p_theme->set_constant("modulate_arrow", "OptionButton", true); + p_theme->set_constant("h_separation", "OptionButton", 4 * EDSCALE); + p_theme->set_constant("outline_size", "OptionButton", 0); + } + + // CheckButton. + + p_theme->set_stylebox("normal", "CheckButton", p_config.panel_container_style); + p_theme->set_stylebox("pressed", "CheckButton", p_config.panel_container_style); + p_theme->set_stylebox("disabled", "CheckButton", p_config.panel_container_style); + p_theme->set_stylebox("hover", "CheckButton", p_config.panel_container_style); + p_theme->set_stylebox("hover_pressed", "CheckButton", p_config.panel_container_style); + + p_theme->set_icon("checked", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOn"), EditorStringName(EditorIcons))); + p_theme->set_icon("checked_disabled", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOnDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOff"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked_disabled", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOffDisabled"), EditorStringName(EditorIcons))); + + p_theme->set_icon("checked_mirrored", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOnMirrored"), EditorStringName(EditorIcons))); + p_theme->set_icon("checked_disabled_mirrored", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked_mirrored", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOffMirrored"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked_disabled_mirrored", "CheckButton", p_theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), EditorStringName(EditorIcons))); + + p_theme->set_color("font_color", "CheckButton", p_config.font_color); + p_theme->set_color("font_hover_color", "CheckButton", p_config.font_hover_color); + p_theme->set_color("font_hover_pressed_color", "CheckButton", p_config.font_hover_pressed_color); + p_theme->set_color("font_focus_color", "CheckButton", p_config.font_focus_color); + p_theme->set_color("font_pressed_color", "CheckButton", p_config.font_pressed_color); + p_theme->set_color("font_disabled_color", "CheckButton", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "CheckButton", p_config.font_outline_color); + + p_theme->set_color("icon_normal_color", "CheckButton", p_config.icon_normal_color); + p_theme->set_color("icon_hover_color", "CheckButton", p_config.icon_hover_color); + p_theme->set_color("icon_focus_color", "CheckButton", p_config.icon_focus_color); + p_theme->set_color("icon_pressed_color", "CheckButton", p_config.icon_pressed_color); + p_theme->set_color("icon_disabled_color", "CheckButton", p_config.icon_disabled_color); + + p_theme->set_constant("h_separation", "CheckButton", 8 * EDSCALE); + p_theme->set_constant("check_v_offset", "CheckButton", 0); + p_theme->set_constant("outline_size", "CheckButton", 0); + + // CheckBox. + { + Ref checkbox_style = p_config.panel_container_style->duplicate(); + checkbox_style->set_content_margin_all(p_config.base_margin * EDSCALE); + + p_theme->set_stylebox("normal", "CheckBox", checkbox_style); + p_theme->set_stylebox("pressed", "CheckBox", checkbox_style); + p_theme->set_stylebox("disabled", "CheckBox", checkbox_style); + p_theme->set_stylebox("hover", "CheckBox", checkbox_style); + p_theme->set_stylebox("hover_pressed", "CheckBox", checkbox_style); + p_theme->set_icon("checked", "CheckBox", p_theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked", "CheckBox", p_theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_checked", "CheckBox", p_theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_unchecked", "CheckBox", p_theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("checked_disabled", "CheckBox", p_theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked_disabled", "CheckBox", p_theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_checked_disabled", "CheckBox", p_theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_unchecked_disabled", "CheckBox", p_theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons))); + + p_theme->set_color("font_color", "CheckBox", p_config.font_color); + p_theme->set_color("font_hover_color", "CheckBox", p_config.font_hover_color); + p_theme->set_color("font_hover_pressed_color", "CheckBox", p_config.font_hover_pressed_color); + p_theme->set_color("font_focus_color", "CheckBox", p_config.font_focus_color); + p_theme->set_color("font_pressed_color", "CheckBox", p_config.font_pressed_color); + p_theme->set_color("font_disabled_color", "CheckBox", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "CheckBox", p_config.font_outline_color); + + p_theme->set_color("icon_normal_color", "CheckBox", p_config.icon_normal_color); + p_theme->set_color("icon_hover_color", "CheckBox", p_config.icon_hover_color); + p_theme->set_color("icon_focus_color", "CheckBox", p_config.icon_focus_color); + p_theme->set_color("icon_pressed_color", "CheckBox", p_config.icon_pressed_color); + p_theme->set_color("icon_disabled_color", "CheckBox", p_config.icon_disabled_color); + + p_theme->set_constant("h_separation", "CheckBox", 8 * EDSCALE); + p_theme->set_constant("check_v_offset", "CheckBox", 0); + p_theme->set_constant("outline_size", "CheckBox", 0); + } + + // LinkButton. + + p_theme->set_stylebox("focus", "LinkButton", p_config.base_empty_style); + p_theme->set_color("font_color", "LinkButton", p_config.font_color); + p_theme->set_color("font_hover_color", "LinkButton", p_config.font_hover_color); + p_theme->set_color("font_hover_pressed_color", "LinkButton", p_config.font_hover_pressed_color); + p_theme->set_color("font_focus_color", "LinkButton", p_config.font_focus_color); + p_theme->set_color("font_pressed_color", "LinkButton", p_config.font_pressed_color); + p_theme->set_color("font_disabled_color", "LinkButton", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "LinkButton", p_config.font_outline_color); + + p_theme->set_constant("outline_size", "LinkButton", 0); + } + + // Tree & ItemList. + { + Ref style_tree_focus = p_config.base_style->duplicate(); + style_tree_focus->set_bg_color(p_config.highlight_color); + style_tree_focus->set_border_width_all(0); + + Ref style_tree_selected = style_tree_focus->duplicate(); + + const Color guide_color = p_config.mono_color * Color(1, 1, 1, 0.05); + + // Tree. + { + p_theme->set_icon("checked", "Tree", p_theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("checked_disabled", "Tree", p_theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("indeterminate", "Tree", p_theme->get_icon(SNAME("GuiIndeterminate"), EditorStringName(EditorIcons))); + p_theme->set_icon("indeterminate_disabled", "Tree", p_theme->get_icon(SNAME("GuiIndeterminateDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked", "Tree", p_theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked_disabled", "Tree", p_theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("arrow", "Tree", p_theme->get_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons))); + p_theme->set_icon("arrow_collapsed", "Tree", p_theme->get_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons))); + p_theme->set_icon("arrow_collapsed_mirrored", "Tree", p_theme->get_icon(SNAME("GuiTreeArrowLeft"), EditorStringName(EditorIcons))); + p_theme->set_icon("updown", "Tree", p_theme->get_icon(SNAME("GuiTreeUpdown"), EditorStringName(EditorIcons))); + p_theme->set_icon("select_arrow", "Tree", p_theme->get_icon(SNAME("GuiDropdown"), EditorStringName(EditorIcons))); + + p_theme->set_stylebox("panel", "Tree", p_config.tree_panel_style); + p_theme->set_stylebox("focus", "Tree", p_config.button_style_focus); + p_theme->set_stylebox("custom_button", "Tree", make_empty_stylebox()); + p_theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); + p_theme->set_stylebox("custom_button_hover", "Tree", p_config.button_style); + + p_theme->set_color("custom_button_font_highlight", "Tree", p_config.font_hover_color); + p_theme->set_color("font_color", "Tree", p_config.font_color); + p_theme->set_color("font_selected_color", "Tree", p_config.mono_color); + p_theme->set_color("font_disabled_color", "Tree", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "Tree", p_config.font_outline_color); + p_theme->set_color("title_button_color", "Tree", p_config.font_color); + p_theme->set_color("drop_position_color", "Tree", p_config.accent_color); + + p_theme->set_constant("v_separation", "Tree", p_config.widget_margin.y - EDSCALE); + p_theme->set_constant("h_separation", "Tree", 6 * EDSCALE); + p_theme->set_constant("guide_width", "Tree", p_config.border_width); + p_theme->set_constant("item_margin", "Tree", 3 * p_config.base_margin * EDSCALE); + p_theme->set_constant("inner_item_margin_bottom", "Tree", p_config.increased_margin * EDSCALE); + p_theme->set_constant("inner_item_margin_left", "Tree", p_config.increased_margin * EDSCALE); + p_theme->set_constant("inner_item_margin_right", "Tree", p_config.increased_margin * EDSCALE); + p_theme->set_constant("inner_item_margin_top", "Tree", p_config.increased_margin * EDSCALE); + p_theme->set_constant("button_margin", "Tree", p_config.base_margin * EDSCALE); + p_theme->set_constant("scroll_border", "Tree", 40 * EDSCALE); + p_theme->set_constant("scroll_speed", "Tree", 12); + p_theme->set_constant("outline_size", "Tree", 0); + p_theme->set_constant("scrollbar_margin_left", "Tree", 0); + p_theme->set_constant("scrollbar_margin_top", "Tree", 0); + p_theme->set_constant("scrollbar_margin_right", "Tree", 0); + p_theme->set_constant("scrollbar_margin_bottom", "Tree", 0); + p_theme->set_constant("scrollbar_h_separation", "Tree", 1 * EDSCALE); + p_theme->set_constant("scrollbar_v_separation", "Tree", 1 * EDSCALE); + + Color relationship_line_color = p_config.mono_color * Color(1, 1, 1, p_config.relationship_line_opacity); + + p_theme->set_constant("draw_guides", "Tree", p_config.relationship_line_opacity < 0.01); + p_theme->set_color("guide_color", "Tree", guide_color); + + int relationship_line_width = 1; + Color parent_line_color = p_config.mono_color * Color(1, 1, 1, CLAMP(p_config.relationship_line_opacity + 0.45, 0.0, 1.0)); + Color children_line_color = p_config.mono_color * Color(1, 1, 1, CLAMP(p_config.relationship_line_opacity + 0.25, 0.0, 1.0)); + + p_theme->set_constant("draw_relationship_lines", "Tree", p_config.relationship_line_opacity >= 0.01); + p_theme->set_constant("relationship_line_width", "Tree", relationship_line_width); + p_theme->set_constant("parent_hl_line_width", "Tree", relationship_line_width * 2); + p_theme->set_constant("children_hl_line_width", "Tree", relationship_line_width); + p_theme->set_constant("parent_hl_line_margin", "Tree", relationship_line_width * 3); + p_theme->set_color("relationship_line_color", "Tree", relationship_line_color); + p_theme->set_color("parent_hl_line_color", "Tree", parent_line_color); + p_theme->set_color("children_hl_line_color", "Tree", children_line_color); + p_theme->set_color("drop_position_color", "Tree", p_config.accent_color); + + Ref style_tree_btn = p_config.base_style->duplicate(); + style_tree_btn->set_bg_color(p_config.highlight_color); + style_tree_btn->set_border_width_all(0); + p_theme->set_stylebox("button_pressed", "Tree", style_tree_btn); + + Ref style_tree_hover = p_config.base_style->duplicate(); + style_tree_hover->set_bg_color(p_config.highlight_color * Color(1, 1, 1, 0.4)); + style_tree_hover->set_border_width_all(0); + p_theme->set_stylebox("hover", "Tree", style_tree_hover); + + p_theme->set_stylebox("selected_focus", "Tree", style_tree_focus); + p_theme->set_stylebox("selected", "Tree", style_tree_selected); + + Ref style_tree_cursor = p_config.base_style->duplicate(); + style_tree_cursor->set_draw_center(false); + style_tree_cursor->set_border_width_all(MAX(1, p_config.border_width)); + style_tree_cursor->set_border_color(p_config.contrast_color_1); + + Ref style_tree_title = p_config.base_style->duplicate(); + style_tree_title->set_bg_color(p_config.dark_color_3); + style_tree_title->set_border_width_all(0); + p_theme->set_stylebox("cursor", "Tree", style_tree_cursor); + p_theme->set_stylebox("cursor_unfocused", "Tree", style_tree_cursor); + p_theme->set_stylebox("title_button_normal", "Tree", style_tree_title); + p_theme->set_stylebox("title_button_hover", "Tree", style_tree_title); + p_theme->set_stylebox("title_button_pressed", "Tree", style_tree_title); + } + + // ItemList. + { + Ref style_itemlist_bg = p_config.base_style->duplicate(); + style_itemlist_bg->set_bg_color(p_config.dark_color_1); + + if (p_config.draw_extra_borders) { + style_itemlist_bg->set_border_width_all(Math::round(EDSCALE)); + style_itemlist_bg->set_border_color(p_config.extra_border_color_2); + } else { + style_itemlist_bg->set_border_width_all(p_config.border_width); + style_itemlist_bg->set_border_color(p_config.dark_color_3); + } + + Ref style_itemlist_cursor = p_config.base_style->duplicate(); + style_itemlist_cursor->set_draw_center(false); + style_itemlist_cursor->set_border_width_all(p_config.border_width); + style_itemlist_cursor->set_border_color(p_config.highlight_color); + + Ref style_itemlist_hover = style_tree_selected->duplicate(); + style_itemlist_hover->set_bg_color(p_config.highlight_color * Color(1, 1, 1, 0.3)); + style_itemlist_hover->set_border_width_all(0); + + p_theme->set_stylebox("panel", "ItemList", style_itemlist_bg); + p_theme->set_stylebox("focus", "ItemList", p_config.button_style_focus); + p_theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor); + p_theme->set_stylebox("cursor_unfocused", "ItemList", style_itemlist_cursor); + p_theme->set_stylebox("selected_focus", "ItemList", style_tree_focus); + p_theme->set_stylebox("selected", "ItemList", style_tree_selected); + p_theme->set_stylebox("hovered", "ItemList", style_itemlist_hover); + p_theme->set_color("font_color", "ItemList", p_config.font_color); + p_theme->set_color("font_hovered_color", "ItemList", p_config.mono_color); + p_theme->set_color("font_selected_color", "ItemList", p_config.mono_color); + p_theme->set_color("font_outline_color", "ItemList", p_config.font_outline_color); + p_theme->set_color("guide_color", "ItemList", guide_color); + p_theme->set_constant("v_separation", "ItemList", p_config.forced_even_separation * 0.5 * EDSCALE); + p_theme->set_constant("h_separation", "ItemList", 6 * EDSCALE); + p_theme->set_constant("icon_margin", "ItemList", 6 * EDSCALE); + p_theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); + p_theme->set_constant("outline_size", "ItemList", 0); + } + } + + // TabBar & TabContainer. + { + Ref style_tab_base = p_config.button_style->duplicate(); + + 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_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(SIDE_LEFT, -p_config.border_width); + + style_tab_base->set_content_margin(SIDE_LEFT, p_config.widget_margin.x + 5 * EDSCALE); + style_tab_base->set_content_margin(SIDE_RIGHT, p_config.widget_margin.x + 5 * EDSCALE); + style_tab_base->set_content_margin(SIDE_BOTTOM, p_config.widget_margin.y); + style_tab_base->set_content_margin(SIDE_TOP, p_config.widget_margin.y); + + Ref style_tab_selected = style_tab_base->duplicate(); + + style_tab_selected->set_bg_color(p_config.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 = p_config.dark_color_2.lerp(p_config.accent_color, 0.75); + style_tab_selected->set_border_color(tab_highlight); + style_tab_selected->set_corner_radius_all(0); + + Ref style_tab_hovered = style_tab_base->duplicate(); + + style_tab_hovered->set_bg_color(p_config.dark_color_1.lerp(p_config.base_color, 0.4)); + // Hovered tab has a subtle highlight between normal and selected states. + style_tab_hovered->set_corner_radius_all(0); + + Ref style_tab_unselected = style_tab_base->duplicate(); + style_tab_unselected->set_expand_margin(SIDE_BOTTOM, 0); + style_tab_unselected->set_bg_color(p_config.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)); + + Ref style_tab_disabled = style_tab_base->duplicate(); + style_tab_disabled->set_expand_margin(SIDE_BOTTOM, 0); + style_tab_disabled->set_bg_color(p_config.disabled_bg_color); + style_tab_disabled->set_border_color(p_config.disabled_bg_color); + + Ref style_tab_focus = p_config.button_style_focus->duplicate(); + + Ref style_tabbar_background = make_flat_stylebox(p_config.dark_color_1, 0, 0, 0, 0, p_config.corner_radius * EDSCALE); + style_tabbar_background->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + style_tabbar_background->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); + p_theme->set_stylebox("tabbar_background", "TabContainer", style_tabbar_background); + p_theme->set_stylebox("panel", "TabContainer", p_config.content_panel_style); + + p_theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected); + p_theme->set_stylebox("tab_hovered", "TabContainer", style_tab_hovered); + p_theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); + p_theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); + p_theme->set_stylebox("tab_focus", "TabContainer", style_tab_focus); + p_theme->set_stylebox("tab_selected", "TabBar", style_tab_selected); + p_theme->set_stylebox("tab_hovered", "TabBar", style_tab_hovered); + p_theme->set_stylebox("tab_unselected", "TabBar", style_tab_unselected); + p_theme->set_stylebox("tab_disabled", "TabBar", style_tab_disabled); + p_theme->set_stylebox("tab_focus", "TabBar", style_tab_focus); + p_theme->set_stylebox("button_pressed", "TabBar", p_config.panel_container_style); + p_theme->set_stylebox("button_highlight", "TabBar", p_config.panel_container_style); + + p_theme->set_color("font_selected_color", "TabContainer", p_config.font_color); + p_theme->set_color("font_hovered_color", "TabContainer", p_config.font_color); + p_theme->set_color("font_unselected_color", "TabContainer", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "TabContainer", p_config.font_outline_color); + p_theme->set_color("font_selected_color", "TabBar", p_config.font_color); + p_theme->set_color("font_hovered_color", "TabBar", p_config.font_color); + p_theme->set_color("font_unselected_color", "TabBar", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "TabBar", p_config.font_outline_color); + p_theme->set_color("drop_mark_color", "TabContainer", tab_highlight); + p_theme->set_color("drop_mark_color", "TabBar", tab_highlight); + + p_theme->set_icon("menu", "TabContainer", p_theme->get_icon(SNAME("GuiTabMenu"), EditorStringName(EditorIcons))); + p_theme->set_icon("menu_highlight", "TabContainer", p_theme->get_icon(SNAME("GuiTabMenuHl"), EditorStringName(EditorIcons))); + p_theme->set_icon("close", "TabBar", p_theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons))); + p_theme->set_icon("increment", "TabContainer", p_theme->get_icon(SNAME("GuiScrollArrowRight"), EditorStringName(EditorIcons))); + p_theme->set_icon("decrement", "TabContainer", p_theme->get_icon(SNAME("GuiScrollArrowLeft"), EditorStringName(EditorIcons))); + p_theme->set_icon("increment", "TabBar", p_theme->get_icon(SNAME("GuiScrollArrowRight"), EditorStringName(EditorIcons))); + p_theme->set_icon("decrement", "TabBar", p_theme->get_icon(SNAME("GuiScrollArrowLeft"), EditorStringName(EditorIcons))); + p_theme->set_icon("increment_highlight", "TabBar", p_theme->get_icon(SNAME("GuiScrollArrowRightHl"), EditorStringName(EditorIcons))); + p_theme->set_icon("decrement_highlight", "TabBar", p_theme->get_icon(SNAME("GuiScrollArrowLeftHl"), EditorStringName(EditorIcons))); + p_theme->set_icon("increment_highlight", "TabContainer", p_theme->get_icon(SNAME("GuiScrollArrowRightHl"), EditorStringName(EditorIcons))); + p_theme->set_icon("decrement_highlight", "TabContainer", p_theme->get_icon(SNAME("GuiScrollArrowLeftHl"), EditorStringName(EditorIcons))); + p_theme->set_icon("drop_mark", "TabContainer", p_theme->get_icon(SNAME("GuiTabDropMark"), EditorStringName(EditorIcons))); + p_theme->set_icon("drop_mark", "TabBar", p_theme->get_icon(SNAME("GuiTabDropMark"), EditorStringName(EditorIcons))); + + p_theme->set_constant("side_margin", "TabContainer", 0); + p_theme->set_constant("outline_size", "TabContainer", 0); + p_theme->set_constant("h_separation", "TabBar", 4 * EDSCALE); + p_theme->set_constant("outline_size", "TabBar", 0); + } + + // Separators. + p_theme->set_stylebox("separator", "HSeparator", make_line_stylebox(p_config.separator_color, MAX(Math::round(EDSCALE), p_config.border_width))); + p_theme->set_stylebox("separator", "VSeparator", make_line_stylebox(p_config.separator_color, MAX(Math::round(EDSCALE), p_config.border_width), 0, 0, true)); + + // LineEdit & TextEdit. + { + Ref text_editor_style = p_config.button_style->duplicate(); + // The original button_style style has an extra 1 pixel offset that makes LineEdits not align with Buttons, + // so this compensates for that. + text_editor_style->set_content_margin(SIDE_TOP, text_editor_style->get_content_margin(SIDE_TOP) - 1 * EDSCALE); + + // Don't round the bottom corners to make the line look sharper. + text_editor_style->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + text_editor_style->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); + + if (p_config.draw_extra_borders) { + text_editor_style->set_border_width_all(Math::round(EDSCALE)); + text_editor_style->set_border_color(p_config.extra_border_color_1); + } else { + // Add a bottom line to make LineEdits more visible, especially in sectioned inspectors + // such as the Project Settings. + text_editor_style->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); + text_editor_style->set_border_color(p_config.dark_color_2); + } + + Ref text_editor_disabled_style = text_editor_style->duplicate(); + text_editor_disabled_style->set_border_color(p_config.disabled_border_color); + text_editor_disabled_style->set_bg_color(p_config.disabled_bg_color); + + // LineEdit. + + p_theme->set_stylebox("normal", "LineEdit", text_editor_style); + p_theme->set_stylebox("focus", "LineEdit", p_config.button_style_focus); + p_theme->set_stylebox("read_only", "LineEdit", text_editor_disabled_style); + + p_theme->set_icon("clear", "LineEdit", p_theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons))); + + p_theme->set_color("font_color", "LineEdit", p_config.font_color); + p_theme->set_color("font_selected_color", "LineEdit", p_config.mono_color); + p_theme->set_color("font_uneditable_color", "LineEdit", p_config.font_readonly_color); + p_theme->set_color("font_placeholder_color", "LineEdit", p_config.font_placeholder_color); + p_theme->set_color("font_outline_color", "LineEdit", p_config.font_outline_color); + p_theme->set_color("caret_color", "LineEdit", p_config.font_color); + p_theme->set_color("selection_color", "LineEdit", p_config.selection_color); + p_theme->set_color("clear_button_color", "LineEdit", p_config.font_color); + p_theme->set_color("clear_button_color_pressed", "LineEdit", p_config.accent_color); + + p_theme->set_constant("minimum_character_width", "LineEdit", 4); + p_theme->set_constant("outline_size", "LineEdit", 0); + p_theme->set_constant("caret_width", "LineEdit", 1); + + // TextEdit. + + p_theme->set_stylebox("normal", "TextEdit", text_editor_style); + p_theme->set_stylebox("focus", "TextEdit", p_config.button_style_focus); + p_theme->set_stylebox("read_only", "TextEdit", text_editor_disabled_style); + + p_theme->set_icon("tab", "TextEdit", p_theme->get_icon(SNAME("GuiTab"), EditorStringName(EditorIcons))); + p_theme->set_icon("space", "TextEdit", p_theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons))); + + p_theme->set_color("font_color", "TextEdit", p_config.font_color); + p_theme->set_color("font_readonly_color", "TextEdit", p_config.font_readonly_color); + p_theme->set_color("font_placeholder_color", "TextEdit", p_config.font_placeholder_color); + p_theme->set_color("font_outline_color", "TextEdit", p_config.font_outline_color); + p_theme->set_color("caret_color", "TextEdit", p_config.font_color); + p_theme->set_color("selection_color", "TextEdit", p_config.selection_color); + p_theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0)); + + p_theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); + p_theme->set_constant("outline_size", "TextEdit", 0); + p_theme->set_constant("caret_width", "TextEdit", 1); + } + + // Containers. + { + p_theme->set_constant("separation", "BoxContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("separation", "HBoxContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("separation", "VBoxContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("margin_left", "MarginContainer", 0); + p_theme->set_constant("margin_top", "MarginContainer", 0); + p_theme->set_constant("margin_right", "MarginContainer", 0); + p_theme->set_constant("margin_bottom", "MarginContainer", 0); + p_theme->set_constant("h_separation", "GridContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("v_separation", "GridContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("h_separation", "FlowContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("v_separation", "FlowContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("h_separation", "HFlowContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("v_separation", "HFlowContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("h_separation", "VFlowContainer", p_config.base_margin * EDSCALE); + p_theme->set_constant("v_separation", "VFlowContainer", p_config.base_margin * EDSCALE); + + // SplitContainer. + + p_theme->set_icon("h_grabber", "SplitContainer", p_theme->get_icon(SNAME("GuiHsplitter"), EditorStringName(EditorIcons))); + p_theme->set_icon("v_grabber", "SplitContainer", p_theme->get_icon(SNAME("GuiVsplitter"), EditorStringName(EditorIcons))); + p_theme->set_icon("grabber", "VSplitContainer", p_theme->get_icon(SNAME("GuiVsplitter"), EditorStringName(EditorIcons))); + p_theme->set_icon("grabber", "HSplitContainer", p_theme->get_icon(SNAME("GuiHsplitter"), EditorStringName(EditorIcons))); + + p_theme->set_constant("separation", "SplitContainer", p_config.base_margin * 2 * EDSCALE); + p_theme->set_constant("separation", "HSplitContainer", p_config.base_margin * 2 * EDSCALE); + p_theme->set_constant("separation", "VSplitContainer", p_config.base_margin * 2 * EDSCALE); + + p_theme->set_constant("minimum_grab_thickness", "SplitContainer", 6 * EDSCALE); + p_theme->set_constant("minimum_grab_thickness", "HSplitContainer", 6 * EDSCALE); + p_theme->set_constant("minimum_grab_thickness", "VSplitContainer", 6 * EDSCALE); + + // GridContainer. + p_theme->set_constant("v_separation", "GridContainer", Math::round(p_config.widget_margin.y - 2 * EDSCALE)); + } + + // Window and dialogs. + { + // Window. + + p_theme->set_stylebox("embedded_border", "Window", p_config.window_style); + p_theme->set_stylebox("embedded_unfocused_border", "Window", p_config.window_style); + + p_theme->set_color("title_color", "Window", p_config.font_color); + p_theme->set_icon("close", "Window", p_theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons))); + p_theme->set_icon("close_pressed", "Window", p_theme->get_icon(SNAME("GuiClose"), EditorStringName(EditorIcons))); + p_theme->set_constant("close_h_offset", "Window", 22 * EDSCALE); + p_theme->set_constant("close_v_offset", "Window", 20 * EDSCALE); + p_theme->set_constant("title_height", "Window", 24 * EDSCALE); + p_theme->set_constant("resize_margin", "Window", 4 * EDSCALE); + p_theme->set_font("title_font", "Window", p_theme->get_font(SNAME("title"), EditorStringName(EditorFonts))); + p_theme->set_font_size("title_font_size", "Window", p_theme->get_font_size(SNAME("title_size"), EditorStringName(EditorFonts))); + + // AcceptDialog. + p_theme->set_stylebox("panel", "AcceptDialog", p_config.dialog_style); + p_theme->set_constant("buttons_separation", "AcceptDialog", 8 * EDSCALE); + + // FileDialog. + p_theme->set_icon("folder", "FileDialog", p_theme->get_icon(SNAME("Folder"), EditorStringName(EditorIcons))); + p_theme->set_icon("parent_folder", "FileDialog", p_theme->get_icon(SNAME("ArrowUp"), EditorStringName(EditorIcons))); + p_theme->set_icon("back_folder", "FileDialog", p_theme->get_icon(SNAME("Back"), EditorStringName(EditorIcons))); + p_theme->set_icon("forward_folder", "FileDialog", p_theme->get_icon(SNAME("Forward"), EditorStringName(EditorIcons))); + p_theme->set_icon("reload", "FileDialog", p_theme->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); + p_theme->set_icon("toggle_hidden", "FileDialog", p_theme->get_icon(SNAME("GuiVisibilityVisible"), EditorStringName(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. + p_theme->set_color("folder_icon_color", "FileDialog", (p_config.dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(p_config.accent_color, 0.7)); + p_theme->set_color("files_disabled", "FileDialog", p_config.font_disabled_color); + + // PopupDialog. + p_theme->set_stylebox("panel", "PopupDialog", p_config.popup_style); + + // PopupMenu. + { + Ref style_popup_menu = p_config.popup_style->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_content_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(EDSCALE); + if (p_config.draw_extra_borders) { + style_popup_menu->set_border_color(p_config.extra_border_color_2); + } else { + style_popup_menu->set_border_color(p_config.dark_color_2); + } + p_theme->set_stylebox("panel", "PopupMenu", style_popup_menu); + + Ref style_menu_hover = p_config.button_style_hover->duplicate(); + // Don't use rounded corners for hover highlights since the StyleBox touches the PopupMenu's edges. + style_menu_hover->set_corner_radius_all(0); + p_theme->set_stylebox("hover", "PopupMenu", style_menu_hover); + + Ref style_popup_separator(memnew(StyleBoxLine)); + style_popup_separator->set_color(p_config.separator_color); + style_popup_separator->set_grow_begin(p_config.popup_margin - MAX(Math::round(EDSCALE), p_config.border_width)); + style_popup_separator->set_grow_end(p_config.popup_margin - MAX(Math::round(EDSCALE), p_config.border_width)); + style_popup_separator->set_thickness(MAX(Math::round(EDSCALE), p_config.border_width)); + + Ref style_popup_labeled_separator_left(memnew(StyleBoxLine)); + style_popup_labeled_separator_left->set_grow_begin(p_config.popup_margin - MAX(Math::round(EDSCALE), p_config.border_width)); + style_popup_labeled_separator_left->set_color(p_config.separator_color); + style_popup_labeled_separator_left->set_thickness(MAX(Math::round(EDSCALE), p_config.border_width)); + + Ref style_popup_labeled_separator_right(memnew(StyleBoxLine)); + style_popup_labeled_separator_right->set_grow_end(p_config.popup_margin - MAX(Math::round(EDSCALE), p_config.border_width)); + style_popup_labeled_separator_right->set_color(p_config.separator_color); + style_popup_labeled_separator_right->set_thickness(MAX(Math::round(EDSCALE), p_config.border_width)); + + p_theme->set_stylebox("separator", "PopupMenu", style_popup_separator); + p_theme->set_stylebox("labeled_separator_left", "PopupMenu", style_popup_labeled_separator_left); + p_theme->set_stylebox("labeled_separator_right", "PopupMenu", style_popup_labeled_separator_right); + + p_theme->set_color("font_color", "PopupMenu", p_config.font_color); + p_theme->set_color("font_hover_color", "PopupMenu", p_config.font_hover_color); + p_theme->set_color("font_accelerator_color", "PopupMenu", p_config.font_disabled_color); + p_theme->set_color("font_disabled_color", "PopupMenu", p_config.font_disabled_color); + p_theme->set_color("font_separator_color", "PopupMenu", p_config.font_disabled_color); + p_theme->set_color("font_outline_color", "PopupMenu", p_config.font_outline_color); + + p_theme->set_icon("checked", "PopupMenu", p_theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked", "PopupMenu", p_theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_checked", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_unchecked", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("checked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("unchecked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_checked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("radio_unchecked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("submenu", "PopupMenu", p_theme->get_icon(SNAME("ArrowRight"), EditorStringName(EditorIcons))); + p_theme->set_icon("submenu_mirrored", "PopupMenu", p_theme->get_icon(SNAME("ArrowLeft"), EditorStringName(EditorIcons))); + p_theme->set_icon("visibility_hidden", "PopupMenu", p_theme->get_icon(SNAME("GuiVisibilityHidden"), EditorStringName(EditorIcons))); + p_theme->set_icon("visibility_visible", "PopupMenu", p_theme->get_icon(SNAME("GuiVisibilityVisible"), EditorStringName(EditorIcons))); + p_theme->set_icon("visibility_xray", "PopupMenu", p_theme->get_icon(SNAME("GuiVisibilityXray"), EditorStringName(EditorIcons))); + + p_theme->set_constant("v_separation", "PopupMenu", p_config.forced_even_separation * EDSCALE); + p_theme->set_constant("outline_size", "PopupMenu", 0); + p_theme->set_constant("item_start_padding", "PopupMenu", p_config.base_margin * 1.5 * EDSCALE); + p_theme->set_constant("item_end_padding", "PopupMenu", p_config.base_margin * 1.5 * EDSCALE); + } + } + + // Sliders and scrollbars. + { + Ref empty_icon = memnew(ImageTexture); + + // HScrollBar. + + if (p_config.increase_scrollbar_touch_area) { + p_theme->set_stylebox("scroll", "HScrollBar", make_line_stylebox(p_config.separator_color, 50)); + } else { + p_theme->set_stylebox("scroll", "HScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, -5, 1, -5, 1)); + } + p_theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); + p_theme->set_stylebox("grabber", "HScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollGrabber"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); + p_theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollGrabberHl"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); + p_theme->set_stylebox("grabber_pressed", "HScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollGrabberPressed"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); + + p_theme->set_icon("increment", "HScrollBar", empty_icon); + p_theme->set_icon("increment_highlight", "HScrollBar", empty_icon); + p_theme->set_icon("increment_pressed", "HScrollBar", empty_icon); + p_theme->set_icon("decrement", "HScrollBar", empty_icon); + p_theme->set_icon("decrement_highlight", "HScrollBar", empty_icon); + p_theme->set_icon("decrement_pressed", "HScrollBar", empty_icon); + + // VScrollBar. + + if (p_config.increase_scrollbar_touch_area) { + p_theme->set_stylebox("scroll", "VScrollBar", make_line_stylebox(p_config.separator_color, 50, 1, 1, true)); + } else { + p_theme->set_stylebox("scroll", "VScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, -5, 1, -5)); + } + p_theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollBg"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); + p_theme->set_stylebox("grabber", "VScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollGrabber"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); + p_theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollGrabberHl"), EditorStringName(EditorIcons)), 5, 5, 5, 5, 1, 1, 1, 1)); + p_theme->set_stylebox("grabber_pressed", "VScrollBar", make_stylebox(p_theme->get_icon(SNAME("GuiScrollGrabberPressed"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 1, 1, 1, 1)); + + p_theme->set_icon("increment", "VScrollBar", empty_icon); + p_theme->set_icon("increment_highlight", "VScrollBar", empty_icon); + p_theme->set_icon("increment_pressed", "VScrollBar", empty_icon); + p_theme->set_icon("decrement", "VScrollBar", empty_icon); + p_theme->set_icon("decrement_highlight", "VScrollBar", empty_icon); + p_theme->set_icon("decrement_pressed", "VScrollBar", empty_icon); + + // HSlider. + p_theme->set_icon("grabber_highlight", "HSlider", p_theme->get_icon(SNAME("GuiSliderGrabberHl"), EditorStringName(EditorIcons))); + p_theme->set_icon("grabber", "HSlider", p_theme->get_icon(SNAME("GuiSliderGrabber"), EditorStringName(EditorIcons))); + p_theme->set_stylebox("slider", "HSlider", make_flat_stylebox(p_config.dark_color_3, 0, p_config.base_margin / 2, 0, p_config.base_margin / 2, p_config.corner_radius)); + p_theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(p_config.contrast_color_1, 0, p_config.base_margin / 2, 0, p_config.base_margin / 2, p_config.corner_radius)); + p_theme->set_stylebox("grabber_area_highlight", "HSlider", make_flat_stylebox(p_config.contrast_color_1, 0, p_config.base_margin / 2, 0, p_config.base_margin / 2)); + p_theme->set_constant("center_grabber", "HSlider", 0); + p_theme->set_constant("grabber_offset", "HSlider", 0); + + // VSlider. + p_theme->set_icon("grabber", "VSlider", p_theme->get_icon(SNAME("GuiSliderGrabber"), EditorStringName(EditorIcons))); + p_theme->set_icon("grabber_highlight", "VSlider", p_theme->get_icon(SNAME("GuiSliderGrabberHl"), EditorStringName(EditorIcons))); + p_theme->set_stylebox("slider", "VSlider", make_flat_stylebox(p_config.dark_color_3, p_config.base_margin / 2, 0, p_config.base_margin / 2, 0, p_config.corner_radius)); + p_theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(p_config.contrast_color_1, p_config.base_margin / 2, 0, p_config.base_margin / 2, 0, p_config.corner_radius)); + p_theme->set_stylebox("grabber_area_highlight", "VSlider", make_flat_stylebox(p_config.contrast_color_1, p_config.base_margin / 2, 0, p_config.base_margin / 2, 0)); + p_theme->set_constant("center_grabber", "VSlider", 0); + p_theme->set_constant("grabber_offset", "VSlider", 0); + } + + // Labels. + { + // RichTextLabel. + + p_theme->set_stylebox("normal", "RichTextLabel", p_config.tree_panel_style); + p_theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox()); + + p_theme->set_color("default_color", "RichTextLabel", p_config.font_color); + p_theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); + p_theme->set_color("font_outline_color", "RichTextLabel", p_config.font_outline_color); + p_theme->set_color("selection_color", "RichTextLabel", p_config.selection_color); + + p_theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE); + p_theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE); + p_theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * EDSCALE); + p_theme->set_constant("outline_size", "RichTextLabel", 0); + + // Label. + + p_theme->set_stylebox("normal", "Label", p_config.base_empty_style); + + p_theme->set_color("font_color", "Label", p_config.font_color); + p_theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0)); + p_theme->set_color("font_outline_color", "Label", p_config.font_outline_color); + + p_theme->set_constant("shadow_offset_x", "Label", 1 * EDSCALE); + p_theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE); + p_theme->set_constant("shadow_outline_size", "Label", 1 * EDSCALE); + p_theme->set_constant("line_spacing", "Label", 3 * EDSCALE); + p_theme->set_constant("outline_size", "Label", 0); + } + + // SpinBox. + p_theme->set_icon("updown", "SpinBox", p_theme->get_icon(SNAME("GuiSpinboxUpdown"), EditorStringName(EditorIcons))); + p_theme->set_icon("updown_disabled", "SpinBox", p_theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), EditorStringName(EditorIcons))); + + // ProgressBar. + p_theme->set_stylebox("background", "ProgressBar", make_stylebox(p_theme->get_icon(SNAME("GuiProgressBar"), EditorStringName(EditorIcons)), 4, 4, 4, 4, 0, 0, 0, 0)); + p_theme->set_stylebox("fill", "ProgressBar", make_stylebox(p_theme->get_icon(SNAME("GuiProgressFill"), EditorStringName(EditorIcons)), 6, 6, 6, 6, 2, 1, 2, 1)); + p_theme->set_color("font_color", "ProgressBar", p_config.font_color); + p_theme->set_color("font_outline_color", "ProgressBar", p_config.font_outline_color); + p_theme->set_constant("outline_size", "ProgressBar", 0); + + // GraphEdit and related nodes. + { + // GraphEdit. + + p_theme->set_stylebox("panel", "GraphEdit", p_config.tree_panel_style); + p_theme->set_stylebox("menu_panel", "GraphEdit", make_flat_stylebox(p_config.dark_color_1 * Color(1, 1, 1, 0.6), 4, 2, 4, 2, 3)); + + if (p_config.dark_theme) { + p_theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.1)); + p_theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.05)); + } else { + p_theme->set_color("grid_major", "GraphEdit", Color(0.0, 0.0, 0.0, 0.15)); + p_theme->set_color("grid_minor", "GraphEdit", Color(0.0, 0.0, 0.0, 0.07)); + } + p_theme->set_color("selection_fill", "GraphEdit", p_theme->get_color(SNAME("box_selection_fill_color"), EditorStringName(Editor))); + p_theme->set_color("selection_stroke", "GraphEdit", p_theme->get_color(SNAME("box_selection_stroke_color"), EditorStringName(Editor))); + p_theme->set_color("activity", "GraphEdit", p_config.accent_color); + + p_theme->set_icon("zoom_out", "GraphEdit", p_theme->get_icon(SNAME("ZoomLess"), EditorStringName(EditorIcons))); + p_theme->set_icon("zoom_in", "GraphEdit", p_theme->get_icon(SNAME("ZoomMore"), EditorStringName(EditorIcons))); + p_theme->set_icon("zoom_reset", "GraphEdit", p_theme->get_icon(SNAME("ZoomReset"), EditorStringName(EditorIcons))); + p_theme->set_icon("grid_toggle", "GraphEdit", p_theme->get_icon(SNAME("GridToggle"), EditorStringName(EditorIcons))); + p_theme->set_icon("minimap_toggle", "GraphEdit", p_theme->get_icon(SNAME("GridMinimap"), EditorStringName(EditorIcons))); + p_theme->set_icon("snapping_toggle", "GraphEdit", p_theme->get_icon(SNAME("SnapGrid"), EditorStringName(EditorIcons))); + p_theme->set_icon("layout", "GraphEdit", p_theme->get_icon(SNAME("GridLayout"), EditorStringName(EditorIcons))); + + // GraphEditMinimap. + { + Ref style_minimap_bg = make_flat_stylebox(p_config.dark_color_1, 0, 0, 0, 0); + style_minimap_bg->set_border_color(p_config.dark_color_3); + style_minimap_bg->set_border_width_all(1); + p_theme->set_stylebox("panel", "GraphEditMinimap", style_minimap_bg); + + Ref style_minimap_camera; + Ref style_minimap_node; + if (p_config.dark_theme) { + style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0); + style_minimap_camera->set_border_color(Color(0.65, 0.65, 0.65, 0.45)); + style_minimap_node = make_flat_stylebox(Color(1, 1, 1), 0, 0, 0, 0); + } else { + style_minimap_camera = make_flat_stylebox(Color(0.38, 0.38, 0.38, 0.2), 0, 0, 0, 0); + style_minimap_camera->set_border_color(Color(0.38, 0.38, 0.38, 0.45)); + 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_anti_aliased(false); + p_theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera); + p_theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node); + + const Color minimap_resizer_color = p_config.dark_theme ? Color(1, 1, 1, 0.65) : Color(0, 0, 0, 0.65); + p_theme->set_icon("resizer", "GraphEditMinimap", p_theme->get_icon(SNAME("GuiResizerTopLeft"), EditorStringName(EditorIcons))); + p_theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color); + } + + // GraphElement & GraphNode. + { + const int gn_margin_top = 2; + const int gn_margin_side = 2; + const int gn_margin_bottom = 2; + + const Color gn_bg_color = p_config.dark_theme ? p_config.dark_color_3 : p_config.dark_color_1.lerp(p_config.mono_color, 0.09); + const Color gn_selected_border_color = gn_bg_color.lerp(p_config.accent_color, 0.275); + const Color gn_frame_bg = gn_bg_color.lerp(p_config.tree_panel_style->get_bg_color(), 0.3); + + Ref gn_panel_style = make_flat_stylebox(gn_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, p_config.corner_radius); + gn_panel_style->set_border_width_all(p_config.border_width); + gn_panel_style->set_border_color(gn_bg_color); + gn_panel_style->set_corner_radius_individual(0, 0, p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE); + gn_panel_style->set_expand_margin(SIDE_TOP, 17 * EDSCALE); + + Ref gn_panel_selected_style = make_flat_stylebox(gn_frame_bg, gn_margin_side, gn_margin_top, gn_margin_side, gn_margin_bottom, p_config.corner_radius); + gn_panel_selected_style->set_border_width_all(2 * EDSCALE + p_config.border_width); + gn_panel_selected_style->set_border_color(gn_selected_border_color); + gn_panel_selected_style->set_corner_radius_individual(0, 0, p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE); + gn_panel_selected_style->set_expand_margin(SIDE_TOP, 17 * EDSCALE); + + const int gn_titlebar_margin_left = 12; + const int gn_titlebar_margin_right = 4; // The rest is for the close button. + + Ref gn_titlebar_style = make_flat_stylebox(gn_bg_color, gn_titlebar_margin_left, gn_margin_top, gn_titlebar_margin_right, 0, p_config.corner_radius); + gn_titlebar_style->set_expand_margin(SIDE_TOP, 2 * EDSCALE); + gn_titlebar_style->set_corner_radius_individual(p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE, 0, 0); + + Ref gn_titlebar_selected_style = make_flat_stylebox(gn_selected_border_color, gn_titlebar_margin_left, gn_margin_top, gn_titlebar_margin_right, 0, p_config.corner_radius); + gn_titlebar_selected_style->set_corner_radius_individual(p_config.corner_radius * EDSCALE, p_config.corner_radius * EDSCALE, 0, 0); + gn_titlebar_selected_style->set_expand_margin(SIDE_TOP, 2 * EDSCALE); + + Color gn_decoration_color = p_config.dark_color_1.inverted(); + + // GraphElement. + + p_theme->set_stylebox("panel", "GraphElement", gn_panel_style); + p_theme->set_stylebox("panel_selected", "GraphElement", gn_panel_selected_style); + p_theme->set_stylebox("titlebar", "GraphElement", gn_titlebar_style); + p_theme->set_stylebox("titlebar_selected", "GraphElement", gn_titlebar_selected_style); + + p_theme->set_color("resizer_color", "GraphElement", gn_decoration_color); + p_theme->set_icon("resizer", "GraphElement", p_theme->get_icon(SNAME("GuiResizer"), EditorStringName(EditorIcons))); + + // GraphNode. + + Ref gn_slot_style = make_empty_stylebox(12, 0, 12, 0); + + p_theme->set_stylebox("panel", "GraphNode", gn_panel_style); + p_theme->set_stylebox("panel_selected", "GraphNode", gn_panel_selected_style); + p_theme->set_stylebox("titlebar", "GraphNode", gn_titlebar_style); + p_theme->set_stylebox("titlebar_selected", "GraphNode", gn_titlebar_selected_style); + p_theme->set_stylebox("slot", "GraphNode", gn_slot_style); + + p_theme->set_color("resizer_color", "GraphNode", gn_decoration_color); + + p_theme->set_constant("port_h_offset", "GraphNode", 0); + p_theme->set_constant("separation", "GraphNode", 1 * EDSCALE); + + Ref port_icon = p_theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons)); + // The true size is 24x24 This is necessary for sharp port icons at high zoom levels in GraphEdit (up to ~200%). + port_icon->set_size_override(Size2(12, 12)); + p_theme->set_icon("port", "GraphNode", port_icon); + + // GraphNode's title Label. + p_theme->set_type_variation("GraphNodeTitleLabel", "Label"); + p_theme->set_stylebox("normal", "GraphNodeTitleLabel", make_empty_stylebox(0, 0, 0, 0)); + p_theme->set_color("font_color", "GraphNodeTitleLabel", p_config.font_color); + p_theme->set_constant("line_spacing", "GraphNodeTitleLabel", 3 * EDSCALE); + } + } + + // ColorPicker and related nodes. + { + // ColorPicker. + + p_theme->set_constant("margin", "ColorPicker", p_config.base_margin); + p_theme->set_constant("sv_width", "ColorPicker", 256 * EDSCALE); + p_theme->set_constant("sv_height", "ColorPicker", 256 * EDSCALE); + p_theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE); + p_theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE); + p_theme->set_constant("center_slider_grabbers", "ColorPicker", 1); + + p_theme->set_icon("screen_picker", "ColorPicker", p_theme->get_icon(SNAME("ColorPick"), EditorStringName(EditorIcons))); + p_theme->set_icon("shape_circle", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeCircle"), EditorStringName(EditorIcons))); + p_theme->set_icon("shape_rect", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeRectangle"), EditorStringName(EditorIcons))); + p_theme->set_icon("shape_rect_wheel", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeRectangleWheel"), EditorStringName(EditorIcons))); + p_theme->set_icon("add_preset", "ColorPicker", p_theme->get_icon(SNAME("Add"), EditorStringName(EditorIcons))); + p_theme->set_icon("sample_bg", "ColorPicker", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons))); + p_theme->set_icon("sample_revert", "ColorPicker", p_theme->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); + p_theme->set_icon("overbright_indicator", "ColorPicker", p_theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons))); + p_theme->set_icon("bar_arrow", "ColorPicker", p_theme->get_icon(SNAME("ColorPickerBarArrow"), EditorStringName(EditorIcons))); + p_theme->set_icon("picker_cursor", "ColorPicker", p_theme->get_icon(SNAME("PickerCursor"), EditorStringName(EditorIcons))); + + // ColorPickerButton. + p_theme->set_icon("bg", "ColorPickerButton", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons))); + + // ColorPresetButton. + p_theme->set_stylebox("preset_fg", "ColorPresetButton", make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2)); + p_theme->set_icon("preset_bg", "ColorPresetButton", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons))); + p_theme->set_icon("overbright_indicator", "ColorPresetButton", p_theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons))); + } +} + +void EditorThemeManager::_populate_editor_styles(const Ref &p_theme, ThemeConfiguration &p_config) { + // Project manager. + { + p_theme->set_stylebox("search_panel", "ProjectManager", p_config.tree_panel_style); + p_theme->set_constant("sidebar_button_icon_separation", "ProjectManager", int(6 * EDSCALE)); + + // ProjectTag. + { + p_theme->set_type_variation("ProjectTag", "Button"); + + Ref tag = p_config.button_style->duplicate(); + tag->set_bg_color(p_config.dark_theme ? tag->get_bg_color().lightened(0.2) : tag->get_bg_color().darkened(0.2)); + tag->set_corner_radius(CORNER_TOP_LEFT, 0); + tag->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + tag->set_corner_radius(CORNER_TOP_RIGHT, 4); + tag->set_corner_radius(CORNER_BOTTOM_RIGHT, 4); + p_theme->set_stylebox("normal", "ProjectTag", tag); + + tag = p_config.button_style_hover->duplicate(); + tag->set_corner_radius(CORNER_TOP_LEFT, 0); + tag->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + tag->set_corner_radius(CORNER_TOP_RIGHT, 4); + tag->set_corner_radius(CORNER_BOTTOM_RIGHT, 4); + p_theme->set_stylebox("hover", "ProjectTag", tag); + + tag = p_config.button_style_pressed->duplicate(); + tag->set_corner_radius(CORNER_TOP_LEFT, 0); + tag->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + tag->set_corner_radius(CORNER_TOP_RIGHT, 4); + tag->set_corner_radius(CORNER_BOTTOM_RIGHT, 4); + p_theme->set_stylebox("pressed", "ProjectTag", tag); + } + } + + // Editor and main screen. + { + // Editor background. + Color background_color_opaque = p_config.dark_color_2; + background_color_opaque.a = 1.0; + p_theme->set_color("background", EditorStringName(Editor), background_color_opaque); + p_theme->set_stylebox("Background", EditorStringName(EditorStyles), make_flat_stylebox(background_color_opaque, p_config.base_margin, p_config.base_margin, p_config.base_margin, p_config.base_margin)); + + p_theme->set_stylebox("PanelForeground", EditorStringName(EditorStyles), p_config.base_style); + + // Editor focus. + p_theme->set_stylebox("Focus", EditorStringName(EditorStyles), p_config.button_style_focus); + // Use a less opaque color to be less distracting for the 2D and 3D editor viewports. + Ref style_widget_focus_viewport = p_config.button_style_focus->duplicate(); + style_widget_focus_viewport->set_border_color(p_config.accent_color * Color(1, 1, 1, 0.5)); + p_theme->set_stylebox("FocusViewport", EditorStringName(EditorStyles), style_widget_focus_viewport); + + // This stylebox is used in 3d and 2d viewports (no borders). + Ref style_content_panel_vp = p_config.content_panel_style->duplicate(); + style_content_panel_vp->set_content_margin_individual(p_config.border_width * 2, p_config.base_margin * EDSCALE, p_config.border_width * 2, p_config.border_width * 2); + p_theme->set_stylebox("Content", EditorStringName(EditorStyles), style_content_panel_vp); + + // 2D/CanvasItem editor + Ref style_canvas_editor_info = make_flat_stylebox(Color(0.0, 0.0, 0.0, 0.2)); + style_canvas_editor_info->set_expand_margin_all(4 * EDSCALE); + p_theme->set_stylebox("CanvasItemInfoOverlay", EditorStringName(EditorStyles), style_canvas_editor_info); + + // 3D/Spatial editor. + Ref style_info_3d_viewport = p_config.base_style->duplicate(); + style_info_3d_viewport->set_bg_color(style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5)); + style_info_3d_viewport->set_border_width_all(0); + p_theme->set_stylebox("Information3dViewport", EditorStringName(EditorStyles), style_info_3d_viewport); + + // 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 toolbar_stylebox = memnew(StyleBoxFlat); + toolbar_stylebox->set_bg_color(p_config.accent_color * Color(1, 1, 1, 0.1)); + 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(p_config.accent_color); + toolbar_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); + toolbar_stylebox->set_content_margin(SIDE_BOTTOM, 0); + toolbar_stylebox->set_expand_margin_individual(4 * EDSCALE, 2 * EDSCALE, 4 * EDSCALE, 4 * EDSCALE); + p_theme->set_stylebox("ContextualToolbar", EditorStringName(EditorStyles), toolbar_stylebox); + + // Script editor. + p_theme->set_stylebox("ScriptEditorPanel", EditorStringName(EditorStyles), make_empty_stylebox(p_config.base_margin, 0, p_config.base_margin, p_config.base_margin)); + p_theme->set_stylebox("ScriptEditorPanelFloating", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); + p_theme->set_stylebox("ScriptEditor", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); + + // Bottom panel. + Ref style_bottom_panel = p_config.content_panel_style->duplicate(); + style_bottom_panel->set_corner_radius_all(p_config.corner_radius * EDSCALE); + p_theme->set_stylebox("BottomPanel", EditorStringName(EditorStyles), style_bottom_panel); + + // Main menu. + p_theme->set_stylebox("MenuHover", EditorStringName(EditorStyles), p_config.button_style_hover); + } + + // Editor GUI widgets. + { + // EditorSpinSlider. + p_theme->set_color("label_color", "EditorSpinSlider", p_config.font_color); + p_theme->set_color("read_only_label_color", "EditorSpinSlider", p_config.font_readonly_color); + + Ref editor_spin_label_bg = p_config.base_style->duplicate(); + editor_spin_label_bg->set_bg_color(p_config.dark_color_3); + editor_spin_label_bg->set_border_width_all(0); + p_theme->set_stylebox("label_bg", "EditorSpinSlider", editor_spin_label_bg); + + // Launch Pad and Play buttons + Ref style_launch_pad = make_flat_stylebox(p_config.dark_color_1, 2 * EDSCALE, 0, 2 * EDSCALE, 0, p_config.corner_radius); + style_launch_pad->set_corner_radius_all(p_config.corner_radius * EDSCALE); + p_theme->set_stylebox("LaunchPadNormal", EditorStringName(EditorStyles), style_launch_pad); + Ref style_launch_pad_movie = style_launch_pad->duplicate(); + style_launch_pad_movie->set_bg_color(p_config.accent_color * Color(1, 1, 1, 0.1)); + style_launch_pad_movie->set_border_color(p_config.accent_color); + style_launch_pad_movie->set_border_width_all(Math::round(2 * EDSCALE)); + p_theme->set_stylebox("LaunchPadMovieMode", EditorStringName(EditorStyles), style_launch_pad_movie); + + p_theme->set_stylebox("MovieWriterButtonNormal", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); + Ref style_write_movie_button = p_config.button_style_pressed->duplicate(); + style_write_movie_button->set_bg_color(p_config.accent_color); + style_write_movie_button->set_corner_radius_all(p_config.corner_radius * EDSCALE); + style_write_movie_button->set_content_margin(SIDE_TOP, 0); + style_write_movie_button->set_content_margin(SIDE_BOTTOM, 0); + style_write_movie_button->set_content_margin(SIDE_LEFT, 0); + style_write_movie_button->set_content_margin(SIDE_RIGHT, 0); + style_write_movie_button->set_expand_margin(SIDE_RIGHT, 2 * EDSCALE); + p_theme->set_stylebox("MovieWriterButtonPressed", EditorStringName(EditorStyles), style_write_movie_button); + } + + // Standard GUI variations. + { + // Custom theme type for MarginContainer with 4px margins. + p_theme->set_type_variation("MarginContainer4px", "MarginContainer"); + p_theme->set_constant("margin_left", "MarginContainer4px", 4 * EDSCALE); + p_theme->set_constant("margin_top", "MarginContainer4px", 4 * EDSCALE); + p_theme->set_constant("margin_right", "MarginContainer4px", 4 * EDSCALE); + p_theme->set_constant("margin_bottom", "MarginContainer4px", 4 * EDSCALE); + + // Header LinkButton variation. + p_theme->set_type_variation("HeaderSmallLink", "LinkButton"); + p_theme->set_font("font", "HeaderSmallLink", p_theme->get_font(SNAME("font"), SNAME("HeaderSmall"))); + p_theme->set_font_size("font_size", "HeaderSmallLink", p_theme->get_font_size(SNAME("font_size"), SNAME("HeaderSmall"))); + + // Flat button variations. + { + Ref style_flat_button = make_empty_stylebox(); + for (int i = 0; i < 4; i++) { + style_flat_button->set_content_margin((Side)i, p_config.button_style->get_margin((Side)i) + p_config.button_style->get_border_width((Side)i)); + } + + Ref style_flat_button_pressed = p_config.button_style_pressed->duplicate(); + Color flat_pressed_color = p_config.dark_color_1.lightened(0.24).lerp(p_config.accent_color, 0.2) * Color(0.8, 0.8, 0.8, 0.85); + if (p_config.dark_theme) { + flat_pressed_color = p_config.dark_color_1.lerp(p_config.accent_color, 0.12) * Color(0.6, 0.6, 0.6, 0.85); + } + style_flat_button_pressed->set_bg_color(flat_pressed_color); + + p_theme->set_stylebox("normal", "FlatButton", style_flat_button); + p_theme->set_stylebox("hover", "FlatButton", style_flat_button); + p_theme->set_stylebox("pressed", "FlatButton", style_flat_button_pressed); + p_theme->set_stylebox("disabled", "FlatButton", style_flat_button); + + p_theme->set_stylebox("normal", "FlatMenuButton", style_flat_button); + p_theme->set_stylebox("hover", "FlatMenuButton", style_flat_button); + p_theme->set_stylebox("pressed", "FlatMenuButton", style_flat_button_pressed); + p_theme->set_stylebox("disabled", "FlatMenuButton", style_flat_button); + + // Variation for Editor Log filter buttons. + + p_theme->set_type_variation("EditorLogFilterButton", "Button"); + // When pressed, don't tint the icons with the accent color, just leave them normal. + p_theme->set_color("icon_pressed_color", "EditorLogFilterButton", p_config.icon_normal_color); + // When unpressed, dim the icons. + p_theme->set_color("icon_normal_color", "EditorLogFilterButton", p_config.icon_disabled_color); + + // When pressed, add a small bottom border to the buttons to better show their active state, + // similar to active tabs. + Ref editor_log_button_pressed = style_flat_button_pressed->duplicate(); + editor_log_button_pressed->set_border_width(SIDE_BOTTOM, 2 * EDSCALE); + editor_log_button_pressed->set_border_color(p_config.accent_color); + p_theme->set_stylebox("pressed", "EditorLogFilterButton", editor_log_button_pressed); + } + + // Complex editor windows. + { + Ref style_complex_window = p_config.window_style->duplicate(); + style_complex_window->set_bg_color(p_config.dark_color_2); + style_complex_window->set_border_color(p_config.dark_color_2); + p_theme->set_stylebox("panel", "EditorSettingsDialog", style_complex_window); + p_theme->set_stylebox("panel", "ProjectSettingsEditor", style_complex_window); + p_theme->set_stylebox("panel", "EditorAbout", style_complex_window); + } + + // InspectorActionButton. + { + p_theme->set_type_variation("InspectorActionButton", "Button"); + + const float action_extra_margin = 32 * EDSCALE; + p_theme->set_constant("h_separation", "InspectorActionButton", action_extra_margin); + + Color color_inspector_action = p_config.dark_color_1.lerp(p_config.mono_color, 0.12); + color_inspector_action.a = 0.5; + Ref style_inspector_action = p_config.button_style->duplicate(); + style_inspector_action->set_bg_color(color_inspector_action); + style_inspector_action->set_content_margin(SIDE_RIGHT, action_extra_margin); + p_theme->set_stylebox("normal", "InspectorActionButton", style_inspector_action); + + style_inspector_action = p_config.button_style_hover->duplicate(); + style_inspector_action->set_content_margin(SIDE_RIGHT, action_extra_margin); + p_theme->set_stylebox("hover", "InspectorActionButton", style_inspector_action); + + style_inspector_action = p_config.button_style_pressed->duplicate(); + style_inspector_action->set_content_margin(SIDE_RIGHT, action_extra_margin); + p_theme->set_stylebox("pressed", "InspectorActionButton", style_inspector_action); + + style_inspector_action = p_config.button_style_disabled->duplicate(); + style_inspector_action->set_content_margin(SIDE_RIGHT, action_extra_margin); + p_theme->set_stylebox("disabled", "InspectorActionButton", style_inspector_action); + } + + // Buttons in material previews. + { + const Color dim_light_color = p_config.icon_normal_color.darkened(0.24); + const Color dim_light_highlighted_color = p_config.icon_normal_color.darkened(0.18); + Ref sb_empty_borderless = make_empty_stylebox(); + + p_theme->set_type_variation("PreviewLightButton", "Button"); + // When pressed, don't use the accent color tint. When unpressed, dim the icon. + p_theme->set_color("icon_normal_color", "PreviewLightButton", dim_light_color); + p_theme->set_color("icon_focus_color", "PreviewLightButton", dim_light_color); + p_theme->set_color("icon_pressed_color", "PreviewLightButton", p_config.icon_normal_color); + p_theme->set_color("icon_hover_pressed_color", "PreviewLightButton", p_config.icon_normal_color); + // Unpressed icon is dim, so use a dim highlight. + p_theme->set_color("icon_hover_color", "PreviewLightButton", dim_light_highlighted_color); + + p_theme->set_stylebox("normal", "PreviewLightButton", sb_empty_borderless); + p_theme->set_stylebox("hover", "PreviewLightButton", sb_empty_borderless); + p_theme->set_stylebox("focus", "PreviewLightButton", sb_empty_borderless); + p_theme->set_stylebox("pressed", "PreviewLightButton", sb_empty_borderless); + } + + // TabContainerOdd variation. + { + // Can be used on tabs against the base color background (e.g. nested tabs). + p_theme->set_type_variation("TabContainerOdd", "TabContainer"); + + Ref style_tab_selected_odd = p_theme->get_stylebox(SNAME("tab_selected"), SNAME("TabContainer"))->duplicate(); + style_tab_selected_odd->set_bg_color(p_config.disabled_bg_color); + p_theme->set_stylebox("tab_selected", "TabContainerOdd", style_tab_selected_odd); + + Ref style_content_panel_odd = p_config.content_panel_style->duplicate(); + style_content_panel_odd->set_bg_color(p_config.disabled_bg_color); + p_theme->set_stylebox("panel", "TabContainerOdd", style_content_panel_odd); + } + + // EditorValidationPanel. + p_theme->set_stylebox("panel", "EditorValidationPanel", p_config.tree_panel_style); + + // ControlEditor. + { + p_theme->set_type_variation("ControlEditorPopupPanel", "PopupPanel"); + + Ref control_editor_popup_style = p_config.popup_style->duplicate(); + control_editor_popup_style->set_shadow_size(0); + control_editor_popup_style->set_content_margin(SIDE_LEFT, p_config.base_margin * EDSCALE); + control_editor_popup_style->set_content_margin(SIDE_TOP, p_config.base_margin * EDSCALE); + control_editor_popup_style->set_content_margin(SIDE_RIGHT, p_config.base_margin * EDSCALE); + control_editor_popup_style->set_content_margin(SIDE_BOTTOM, p_config.base_margin * EDSCALE); + control_editor_popup_style->set_border_width_all(0); + + p_theme->set_stylebox("panel", "ControlEditorPopupPanel", control_editor_popup_style); + } + } + + // Editor inspector. + { + // Sub-inspectors. + for (int i = 0; i < 16; i++) { + Color si_base_color = p_config.accent_color; + + float hue_rotate = (i * 2 % 16) / 16.0; + 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 = p_config.accent_color.lerp(si_base_color, float(EDITOR_GET("docks/property_editor/subresource_hue_tint"))); + + // Sub-inspector background. + Ref sub_inspector_bg = p_config.base_style->duplicate(); + sub_inspector_bg->set_bg_color(p_config.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_content_margin_all(4 * EDSCALE); + sub_inspector_bg->set_corner_radius(CORNER_TOP_LEFT, 0); + sub_inspector_bg->set_corner_radius(CORNER_TOP_RIGHT, 0); + + p_theme->set_stylebox("sub_inspector_bg" + itos(i), EditorStringName(Editor), sub_inspector_bg); + + // EditorProperty background while it has a sub-inspector open. + Ref bg_color = make_flat_stylebox(si_base_color * Color(0.7, 0.7, 0.7, 0.8), 0, 0, 0, 0, p_config.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); + + p_theme->set_stylebox("sub_inspector_property_bg" + itos(i), EditorStringName(Editor), bg_color); + } + + p_theme->set_color("sub_inspector_property_color", EditorStringName(Editor), p_config.dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); + + // EditorProperty. + + Ref style_property_bg = p_config.base_style->duplicate(); + style_property_bg->set_bg_color(p_config.highlight_color); + style_property_bg->set_border_width_all(0); + + Ref style_property_child_bg = p_config.base_style->duplicate(); + style_property_child_bg->set_bg_color(p_config.dark_color_2); + style_property_child_bg->set_border_width_all(0); + + p_theme->set_stylebox("bg", "EditorProperty", Ref(memnew(StyleBoxEmpty))); + p_theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); + p_theme->set_stylebox("child_bg", "EditorProperty", style_property_child_bg); + p_theme->set_constant("font_offset", "EditorProperty", 8 * EDSCALE); + p_theme->set_constant("v_separation", "EditorProperty", p_config.increased_margin * EDSCALE); + + const Color property_color = p_config.font_color.lerp(Color(0.5, 0.5, 0.5), 0.5); + const Color readonly_color = property_color.lerp(p_config.dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.25); + const Color readonly_warning_color = p_config.error_color.lerp(p_config.dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.25); + + p_theme->set_color("property_color", "EditorProperty", property_color); + p_theme->set_color("readonly_color", "EditorProperty", readonly_color); + p_theme->set_color("warning_color", "EditorProperty", p_config.warning_color); + p_theme->set_color("readonly_warning_color", "EditorProperty", readonly_warning_color); + + Ref style_property_group_note = p_config.base_style->duplicate(); + Color property_group_note_color = p_config.accent_color; + property_group_note_color.a = 0.1; + style_property_group_note->set_bg_color(property_group_note_color); + p_theme->set_stylebox("bg_group_note", "EditorProperty", style_property_group_note); + + // EditorInspectorSection. + + Color inspector_section_color = p_config.font_color.lerp(Color(0.5, 0.5, 0.5), 0.35); + p_theme->set_color("font_color", "EditorInspectorSection", inspector_section_color); + + Color inspector_indent_color = p_config.accent_color; + inspector_indent_color.a = 0.2; + Ref inspector_indent_style = make_flat_stylebox(inspector_indent_color, 2.0 * EDSCALE, 0, 2.0 * EDSCALE, 0); + p_theme->set_stylebox("indent_box", "EditorInspectorSection", inspector_indent_style); + p_theme->set_constant("indent_size", "EditorInspectorSection", 6.0 * EDSCALE); + + Color prop_category_color = p_config.dark_color_1.lerp(p_config.mono_color, 0.12); + Color prop_section_color = p_config.dark_color_1.lerp(p_config.mono_color, 0.09); + Color prop_subsection_color = p_config.dark_color_1.lerp(p_config.mono_color, 0.06); + + p_theme->set_color("prop_category", EditorStringName(Editor), prop_category_color); + p_theme->set_color("prop_section", EditorStringName(Editor), prop_section_color); + p_theme->set_color("prop_subsection", EditorStringName(Editor), prop_subsection_color); + + // EditorInspectorCategory. + + Ref category_bg = p_config.base_style->duplicate(); + category_bg->set_bg_color(prop_category_color); + category_bg->set_border_color(prop_category_color); + p_theme->set_stylebox("bg", "EditorInspectorCategory", category_bg); + + p_theme->set_constant("inspector_margin", EditorStringName(Editor), 12 * EDSCALE); + + // Dictionary editor. + + // Expand to the left and right by 4px to compensate for the dictionary editor margins. + Ref style_dictionary_add_item = make_flat_stylebox(prop_subsection_color, 0, 4, 0, 4, p_config.corner_radius); + style_dictionary_add_item->set_expand_margin(SIDE_LEFT, 4 * EDSCALE); + style_dictionary_add_item->set_expand_margin(SIDE_RIGHT, 4 * EDSCALE); + p_theme->set_stylebox("DictionaryAddItem", EditorStringName(EditorStyles), style_dictionary_add_item); + } + + // Editor help. + { + Ref style_editor_help = p_config.base_style->duplicate(); + style_editor_help->set_bg_color(p_config.dark_color_2); + style_editor_help->set_border_color(p_config.dark_color_3); + p_theme->set_stylebox("background", "EditorHelp", style_editor_help); + + const Color kbd_color = p_config.font_color.lerp(Color(0.5, 0.5, 0.5), 0.5); + + p_theme->set_color("title_color", "EditorHelp", p_config.accent_color); + p_theme->set_color("headline_color", "EditorHelp", p_config.mono_color); + p_theme->set_color("text_color", "EditorHelp", p_config.font_color); + p_theme->set_color("comment_color", "EditorHelp", p_config.font_color * Color(1, 1, 1, 0.6)); + p_theme->set_color("symbol_color", "EditorHelp", p_config.font_color * Color(1, 1, 1, 0.6)); + p_theme->set_color("value_color", "EditorHelp", p_config.font_color * Color(1, 1, 1, 0.6)); + p_theme->set_color("qualifier_color", "EditorHelp", p_config.font_color * Color(1, 1, 1, 0.8)); + p_theme->set_color("type_color", "EditorHelp", p_config.accent_color.lerp(p_config.font_color, 0.5)); + p_theme->set_color("selection_color", "EditorHelp", p_config.selection_color); + p_theme->set_color("link_color", "EditorHelp", p_config.accent_color.lerp(p_config.mono_color, 0.8)); + p_theme->set_color("code_color", "EditorHelp", p_config.accent_color.lerp(p_config.mono_color, 0.6)); + p_theme->set_color("kbd_color", "EditorHelp", p_config.accent_color.lerp(kbd_color, 0.6)); + p_theme->set_color("code_bg_color", "EditorHelp", p_config.dark_color_3); + p_theme->set_color("kbd_bg_color", "EditorHelp", p_config.dark_color_1); + p_theme->set_color("param_bg_color", "EditorHelp", p_config.dark_color_1); + p_theme->set_constant("line_separation", "EditorHelp", Math::round(6 * EDSCALE)); + p_theme->set_constant("table_h_separation", "EditorHelp", 16 * EDSCALE); + p_theme->set_constant("table_v_separation", "EditorHelp", 6 * EDSCALE); + p_theme->set_constant("text_highlight_h_padding", "EditorHelp", 1 * EDSCALE); + p_theme->set_constant("text_highlight_v_padding", "EditorHelp", 2 * EDSCALE); + } + + // Asset Library. + p_theme->set_stylebox("bg", "AssetLib", p_config.base_empty_style); + p_theme->set_stylebox("panel", "AssetLib", p_config.content_panel_style); + p_theme->set_color("status_color", "AssetLib", Color(0.5, 0.5, 0.5)); // FIXME: Use a defined color instead. + p_theme->set_icon("dismiss", "AssetLib", p_theme->get_icon(SNAME("Close"), EditorStringName(EditorIcons))); + + // Debugger. + { + Ref debugger_panel_style = p_config.content_panel_style->duplicate(); + debugger_panel_style->set_border_width(SIDE_BOTTOM, 0); + p_theme->set_stylebox("DebuggerPanel", EditorStringName(EditorStyles), debugger_panel_style); + + // This pattern of get_font()->get_height(get_font_size()) is used quite a lot and is very verbose. + // FIXME: Introduce Theme::get_font_height() / Control::get_theme_font_height() / Window::get_theme_font_height(). + const int offset_i1 = p_theme->get_font(SNAME("tab_selected"), SNAME("TabContainer"))->get_height(p_theme->get_font_size(SNAME("tab_selected"), SNAME("TabContainer"))); + const int offset_i2 = p_theme->get_stylebox(SNAME("tab_selected"), SNAME("TabContainer"))->get_minimum_size().height; + const int offset_i3 = p_theme->get_stylebox(SNAME("panel"), SNAME("TabContainer"))->get_content_margin(SIDE_TOP); + const int invisible_top_offset = offset_i1 + offset_i2 + offset_i3; + + Ref invisible_top_panel_style = p_config.content_panel_style->duplicate(); + invisible_top_panel_style->set_expand_margin(SIDE_TOP, -invisible_top_offset); + invisible_top_panel_style->set_content_margin(SIDE_TOP, 0); + p_theme->set_stylebox("BottomPanelDebuggerOverride", EditorStringName(EditorStyles), invisible_top_panel_style); + } + + // Resource and node editors. + { + // TextureRegion editor. + Ref style_texture_region_bg = p_config.tree_panel_style->duplicate(); + style_texture_region_bg->set_content_margin_all(0); + p_theme->set_stylebox("TextureRegionPreviewBG", EditorStringName(EditorStyles), style_texture_region_bg); + p_theme->set_stylebox("TextureRegionPreviewFG", EditorStringName(EditorStyles), make_empty_stylebox(0, 0, 0, 0)); + + // Theme editor. + { + p_theme->set_color("preview_picker_overlay_color", "ThemeEditor", Color(0.1, 0.1, 0.1, 0.25)); + + Color theme_preview_picker_bg_color = p_config.accent_color; + theme_preview_picker_bg_color.a = 0.2; + Ref theme_preview_picker_sb = make_flat_stylebox(theme_preview_picker_bg_color, 0, 0, 0, 0); + theme_preview_picker_sb->set_border_color(p_config.accent_color); + theme_preview_picker_sb->set_border_width_all(1.0 * EDSCALE); + p_theme->set_stylebox("preview_picker_overlay", "ThemeEditor", theme_preview_picker_sb); + + Color theme_preview_picker_label_bg_color = p_config.accent_color; + theme_preview_picker_label_bg_color.set_v(0.5); + Ref theme_preview_picker_label_sb = make_flat_stylebox(theme_preview_picker_label_bg_color, 4.0, 1.0, 4.0, 3.0); + p_theme->set_stylebox("preview_picker_label", "ThemeEditor", theme_preview_picker_label_sb); + + Ref style_theme_preview_tab = p_theme->get_stylebox(SNAME("tab_selected"), SNAME("TabContainerOdd"))->duplicate(); + style_theme_preview_tab->set_expand_margin(SIDE_BOTTOM, 5 * EDSCALE); + p_theme->set_stylebox("ThemeEditorPreviewFG", EditorStringName(EditorStyles), style_theme_preview_tab); + + Ref style_theme_preview_bg_tab = p_theme->get_stylebox(SNAME("tab_unselected"), SNAME("TabContainer"))->duplicate(); + style_theme_preview_bg_tab->set_expand_margin(SIDE_BOTTOM, 2 * EDSCALE); + p_theme->set_stylebox("ThemeEditorPreviewBG", EditorStringName(EditorStyles), style_theme_preview_bg_tab); + } + + // VisualShader editor. + p_theme->set_stylebox("label_style", "VShaderEditor", make_empty_stylebox(2, 1, 2, 1)); + + // StateMachine graph. + { + p_theme->set_stylebox("panel", "GraphStateMachine", p_config.tree_panel_style); + p_theme->set_stylebox("error_panel", "GraphStateMachine", p_config.tree_panel_style); + p_theme->set_color("error_color", "GraphStateMachine", p_config.error_color); + + const int sm_margin_side = 10 * EDSCALE; + const int sm_margin_bottom = 2; + const Color sm_bg_color = p_config.dark_theme ? p_config.dark_color_3 : p_config.dark_color_1.lerp(p_config.mono_color, 0.09); + + Ref sm_node_style = make_flat_stylebox(p_config.dark_color_3 * Color(1, 1, 1, 0.7), sm_margin_side, 24 * EDSCALE, sm_margin_side, sm_margin_bottom, p_config.corner_radius); + sm_node_style->set_border_width_all(p_config.border_width); + sm_node_style->set_border_color(sm_bg_color); + + Ref sm_node_selected_style = make_flat_stylebox(sm_bg_color * Color(1, 1, 1, 0.9), sm_margin_side, 24 * EDSCALE, sm_margin_side, sm_margin_bottom, p_config.corner_radius); + sm_node_selected_style->set_border_width_all(2 * EDSCALE + p_config.border_width); + sm_node_selected_style->set_border_color(p_config.accent_color * Color(1, 1, 1, 0.9)); + sm_node_selected_style->set_shadow_size(8 * EDSCALE); + sm_node_selected_style->set_shadow_color(p_config.shadow_color); + + Ref sm_node_playing_style = sm_node_selected_style->duplicate(); + sm_node_playing_style->set_border_color(p_config.warning_color); + sm_node_playing_style->set_shadow_color(p_config.warning_color * Color(1, 1, 1, 0.2)); + + p_theme->set_stylebox("node_frame", "GraphStateMachine", sm_node_style); + p_theme->set_stylebox("node_frame_selected", "GraphStateMachine", sm_node_selected_style); + p_theme->set_stylebox("node_frame_playing", "GraphStateMachine", sm_node_playing_style); + + Ref sm_node_start_style = sm_node_style->duplicate(); + sm_node_start_style->set_border_width_all(1 * EDSCALE); + sm_node_start_style->set_border_color(p_config.success_color.lightened(0.24)); + p_theme->set_stylebox("node_frame_start", "GraphStateMachine", sm_node_start_style); + + Ref sm_node_end_style = sm_node_style->duplicate(); + sm_node_end_style->set_border_width_all(1 * EDSCALE); + sm_node_end_style->set_border_color(p_config.error_color); + p_theme->set_stylebox("node_frame_end", "GraphStateMachine", sm_node_end_style); + + p_theme->set_font("node_title_font", "GraphStateMachine", p_theme->get_font(SNAME("font"), SNAME("Label"))); + p_theme->set_font_size("node_title_font_size", "GraphStateMachine", p_theme->get_font_size(SNAME("font_size"), SNAME("Label"))); + p_theme->set_color("node_title_font_color", "GraphStateMachine", p_config.font_color); + + p_theme->set_color("transition_color", "GraphStateMachine", p_config.font_color); + p_theme->set_color("transition_disabled_color", "GraphStateMachine", p_config.font_color * Color(1, 1, 1, 0.2)); + p_theme->set_color("transition_icon_color", "GraphStateMachine", Color(1, 1, 1)); + p_theme->set_color("transition_icon_disabled_color", "GraphStateMachine", Color(1, 1, 1, 0.2)); + p_theme->set_color("highlight_color", "GraphStateMachine", p_config.accent_color); + p_theme->set_color("highlight_disabled_color", "GraphStateMachine", p_config.accent_color * Color(1, 1, 1, 0.6)); + p_theme->set_color("guideline_color", "GraphStateMachine", p_config.font_color * Color(1, 1, 1, 0.3)); + + p_theme->set_color("playback_color", "GraphStateMachine", p_config.font_color); + p_theme->set_color("playback_background_color", "GraphStateMachine", p_config.font_color * Color(1, 1, 1, 0.3)); + } + } +} + +void EditorThemeManager::_generate_text_editor_defaults(ThemeConfiguration &p_config) { + // Adaptive colors for comments and elements with lower relevance. + const Color dim_color = Color(p_config.font_color, 0.5); + const float mono_value = p_config.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.27); + + /* clang-format off */ + // Syntax highlight token colors. + const Color symbol_color = p_config.dark_theme ? Color(0.67, 0.79, 1) : Color(0, 0, 0.61); + const Color keyword_color = p_config.dark_theme ? Color(1.0, 0.44, 0.52) : Color(0.9, 0.135, 0.51); + const Color control_flow_keyword_color = p_config.dark_theme ? Color(1.0, 0.55, 0.8) : Color(0.743, 0.12, 0.8); + const Color base_type_color = p_config.dark_theme ? Color(0.26, 1.0, 0.76) : Color(0, 0.6, 0.2); + const Color engine_type_color = p_config.dark_theme ? Color(0.56, 1, 0.86) : Color(0.11, 0.55, 0.4); + const Color user_type_color = p_config.dark_theme ? Color(0.78, 1, 0.93) : Color(0.18, 0.45, 0.4); + const Color comment_color = p_config.dark_theme ? dim_color : Color(0.08, 0.08, 0.08, 0.5); + const Color doc_comment_color = p_config.dark_theme ? Color(0.6, 0.7, 0.8, 0.8) : Color(0.15, 0.15, 0.4, 0.7); + const Color string_color = p_config.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 = p_config.dark_theme ? p_config.dark_color_2 : p_config.dark_color_3; + const Color completion_background_color = p_config.dark_theme ? p_config.base_color : p_config.dark_color_2; + const Color completion_selected_color = alpha1; + 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 = p_config.font_color; + const Color text_color = p_config.font_color; + const Color line_number_color = dim_color; + const Color safe_line_number_color = p_config.dark_theme ? (dim_color * Color(1, 1.2, 1, 1.5)) : Color(0, 0.4, 0, 0.75); + const Color caret_color = p_config.mono_color; + const Color caret_background_color = p_config.mono_color.inverted(); + const Color text_selected_color = Color(0, 0, 0, 0); + const Color selection_color = p_config.selection_color; + const Color brace_mismatch_color = p_config.dark_theme ? p_config.error_color : Color(1, 0.08, 0, 1); + const Color current_line_color = alpha1; + const Color line_length_guideline_color = p_config.dark_theme ? p_config.base_color : p_config.dark_color_2; + const Color word_highlighted_color = alpha1; + const Color number_color = p_config.dark_theme ? Color(0.63, 1, 0.88) : Color(0, 0.55, 0.28, 1); + const Color function_color = p_config.dark_theme ? Color(0.34, 0.7, 1.0) : Color(0, 0.225, 0.9, 1); + const Color member_variable_color = p_config.dark_theme ? Color(0.34, 0.7, 1.0).lerp(p_config.mono_color, 0.6) : Color(0, 0.4, 0.68, 1); + const Color mark_color = Color(p_config.error_color.r, p_config.error_color.g, p_config.error_color.b, 0.3); + const Color bookmark_color = Color(0.08, 0.49, 0.98); + const Color breakpoint_color = p_config.dark_theme ? p_config.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 folded_code_region_color = Color(0.68, 0.46, 0.77, 0.2); + const Color search_result_color = alpha1; + const Color search_result_border_color = p_config.dark_theme ? Color(0.41, 0.61, 0.91, 0.38) : Color(0, 0.4, 1, 0.38); + /* clang-format on */ + + EditorSettings *setting = EditorSettings::get_singleton(); + + /* clang-format off */ + 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", 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/doc_comment_color", doc_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); + setting->set_initial_value("text_editor/theme/highlighting/completion_background_color", completion_background_color, true); + 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); + setting->set_initial_value("text_editor/theme/highlighting/safe_line_number_color", safe_line_number_color, true); + setting->set_initial_value("text_editor/theme/highlighting/caret_color", caret_color, true); + setting->set_initial_value("text_editor/theme/highlighting/caret_background_color", caret_background_color, true); + setting->set_initial_value("text_editor/theme/highlighting/text_selected_color", text_selected_color, true); + setting->set_initial_value("text_editor/theme/highlighting/selection_color", selection_color, true); + setting->set_initial_value("text_editor/theme/highlighting/brace_mismatch_color", brace_mismatch_color, true); + setting->set_initial_value("text_editor/theme/highlighting/current_line_color", current_line_color, true); + setting->set_initial_value("text_editor/theme/highlighting/line_length_guideline_color", line_length_guideline_color, true); + setting->set_initial_value("text_editor/theme/highlighting/word_highlighted_color", word_highlighted_color, true); + setting->set_initial_value("text_editor/theme/highlighting/number_color", number_color, true); + setting->set_initial_value("text_editor/theme/highlighting/function_color", function_color, true); + setting->set_initial_value("text_editor/theme/highlighting/member_variable_color", member_variable_color, true); + setting->set_initial_value("text_editor/theme/highlighting/mark_color", mark_color, true); + setting->set_initial_value("text_editor/theme/highlighting/bookmark_color", bookmark_color, true); + setting->set_initial_value("text_editor/theme/highlighting/breakpoint_color", breakpoint_color, true); + setting->set_initial_value("text_editor/theme/highlighting/executing_line_color", executing_line_color, true); + setting->set_initial_value("text_editor/theme/highlighting/code_folding_color", code_folding_color, true); + setting->set_initial_value("text_editor/theme/highlighting/folded_code_region_color", folded_code_region_color, true); + setting->set_initial_value("text_editor/theme/highlighting/search_result_color", search_result_color, true); + setting->set_initial_value("text_editor/theme/highlighting/search_result_border_color", search_result_border_color, true); + /* clang-format on */ +} + +void EditorThemeManager::_populate_text_editor_styles(const Ref &p_theme, ThemeConfiguration &p_config) { + String text_editor_color_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); + if (text_editor_color_theme == "Default") { + _generate_text_editor_defaults(p_config); + } else if (text_editor_color_theme == "Godot 2") { + EditorSettings::get_singleton()->load_text_editor_theme(); + } + + // Now theme is loaded, apply it to CodeEdit. + p_theme->set_font("font", "CodeEdit", p_theme->get_font(SNAME("source"), EditorStringName(EditorFonts))); + p_theme->set_font_size("font_size", "CodeEdit", p_theme->get_font_size(SNAME("source_size"), EditorStringName(EditorFonts))); + + /* clang-format off */ + p_theme->set_icon("tab", "CodeEdit", p_theme->get_icon(SNAME("GuiTab"), EditorStringName(EditorIcons))); + p_theme->set_icon("space", "CodeEdit", p_theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons))); + p_theme->set_icon("folded", "CodeEdit", p_theme->get_icon(SNAME("CodeFoldedRightArrow"), EditorStringName(EditorIcons))); + p_theme->set_icon("can_fold", "CodeEdit", p_theme->get_icon(SNAME("CodeFoldDownArrow"), EditorStringName(EditorIcons))); + p_theme->set_icon("folded_code_region", "CodeEdit", p_theme->get_icon(SNAME("CodeRegionFoldedRightArrow"), EditorStringName(EditorIcons))); + p_theme->set_icon("can_fold_code_region", "CodeEdit", p_theme->get_icon(SNAME("CodeRegionFoldDownArrow"), EditorStringName(EditorIcons))); + p_theme->set_icon("executing_line", "CodeEdit", p_theme->get_icon(SNAME("TextEditorPlay"), EditorStringName(EditorIcons))); + p_theme->set_icon("breakpoint", "CodeEdit", p_theme->get_icon(SNAME("Breakpoint"), EditorStringName(EditorIcons))); + /* clang-format on */ + + p_theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); + + const Color background_color = EDITOR_GET("text_editor/theme/highlighting/background_color"); + Ref code_edit_stylebox = make_flat_stylebox(background_color, p_config.widget_margin.x, p_config.widget_margin.y, p_config.widget_margin.x, p_config.widget_margin.y, p_config.corner_radius); + p_theme->set_stylebox("normal", "CodeEdit", code_edit_stylebox); + p_theme->set_stylebox("read_only", "CodeEdit", code_edit_stylebox); + p_theme->set_stylebox("focus", "CodeEdit", Ref(memnew(StyleBoxEmpty))); + + p_theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0)); // Unset any color, we use a stylebox. + + /* clang-format off */ + p_theme->set_color("completion_background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_background_color")); + p_theme->set_color("completion_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_selected_color")); + p_theme->set_color("completion_existing_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_existing_color")); + p_theme->set_color("completion_scroll_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_scroll_color")); + p_theme->set_color("completion_scroll_hovered_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_scroll_hovered_color")); + p_theme->set_color("font_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/text_color")); + p_theme->set_color("line_number_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/line_number_color")); + p_theme->set_color("caret_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/caret_color")); + p_theme->set_color("font_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/text_selected_color")); + p_theme->set_color("selection_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/selection_color")); + p_theme->set_color("brace_mismatch_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/brace_mismatch_color")); + p_theme->set_color("current_line_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/current_line_color")); + p_theme->set_color("line_length_guideline_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/line_length_guideline_color")); + p_theme->set_color("word_highlighted_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/word_highlighted_color")); + p_theme->set_color("bookmark_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/bookmark_color")); + p_theme->set_color("breakpoint_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/breakpoint_color")); + p_theme->set_color("executing_line_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/executing_line_color")); + p_theme->set_color("code_folding_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/code_folding_color")); + p_theme->set_color("folded_code_region_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/folded_code_region_color")); + p_theme->set_color("search_result_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_color")); + p_theme->set_color("search_result_border_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_border_color")); + /* clang-format on */ +} + +// Public interface for theme generation. + Ref EditorThemeManager::generate_theme(const Ref &p_old_theme) { OS::get_singleton()->benchmark_begin_measure("EditorTheme", "Generate Theme"); @@ -1933,17 +2170,16 @@ bool EditorThemeManager::is_generated_theme_outdated() { // without a restart, so there is no point regenerating the theme. // TODO: We can use this information more intelligently to do partial theme updates and speed things up. - return - EditorSettings::get_singleton()->check_changed_settings_in_group("interface/theme") || - EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/font") || - EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/main_font") || - EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/code_font") || - EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/theme") || - EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/help/help") || - EditorSettings::get_singleton()->check_changed_settings_in_group("filesystem/file_dialog/thumbnail_size") || - EditorSettings::get_singleton()->check_changed_settings_in_group("run/output/font_size") || - EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/increase_scrollbar_touch_area") || - EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/scale_gizmo_handles"); + return EditorSettings::get_singleton()->check_changed_settings_in_group("interface/theme") || + EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/font") || + EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/main_font") || + EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/code_font") || + EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/theme") || + EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/help/help") || + EditorSettings::get_singleton()->check_changed_settings_in_group("filesystem/file_dialog/thumbnail_size") || + EditorSettings::get_singleton()->check_changed_settings_in_group("run/output/font_size") || + EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/increase_scrollbar_touch_area") || + EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/scale_gizmo_handles"); } void EditorThemeManager::initialize() { diff --git a/editor/themes/editor_theme_manager.h b/editor/themes/editor_theme_manager.h index bd06aeba0d5a..71fab5b39f6c 100644 --- a/editor/themes/editor_theme_manager.h +++ b/editor/themes/editor_theme_manager.h @@ -31,11 +31,111 @@ #ifndef EDITOR_THEME_MANAGER_H #define EDITOR_THEME_MANAGER_H +#include "scene/resources/style_box_flat.h" #include "scene/resources/theme.h" class EditorThemeManager { + struct ThemeConfiguration { + // Basic properties. + + String preset; + bool dark_theme = false; + + Color base_color; + Color accent_color; + float contrast = 1.0; + float icon_saturation = 1.0; + + // Extra properties. + + float extra_spacing = 0.0; + int border_width = 0; + int corner_radius = 3; + + bool draw_extra_borders = false; + float relationship_line_opacity = 1.0; + int thumb_size = 16; + int class_icon_size = 16; + bool increase_scrollbar_touch_area = false; + float gizmo_handle_scale = 1.0; + int color_picker_button_height = 28; + + float default_contrast = 1.0; + + // Generated properties. + + int base_margin = 4; + int increased_margin = 4; + + int popup_margin = 12; + int window_border_margin = 8; + int top_bar_separation = 8; + int forced_even_separation = 0; + + Color mono_color; + Color dark_color_1; + Color dark_color_2; + Color dark_color_3; + Color contrast_color_1; + Color contrast_color_2; + Color highlight_color; + Color highlight_disabled_color; + Color success_color; + Color warning_color; + Color error_color; + Color extra_border_color_1; + Color extra_border_color_2; + + Color font_color; + Color font_focus_color; + Color font_hover_color; + Color font_pressed_color; + Color font_hover_pressed_color; + Color font_disabled_color; + Color font_readonly_color; + Color font_placeholder_color; + Color font_outline_color; + + Color icon_normal_color; + Color icon_focus_color; + Color icon_hover_color; + Color icon_pressed_color; + Color icon_disabled_color; + + Color shadow_color; + Color selection_color; + Color disabled_border_color; + Color disabled_bg_color; + Color separator_color; + + Ref base_style; + Ref base_empty_style; + + Ref button_style; + Ref button_style_disabled; + Ref button_style_focus; + Ref button_style_pressed; + Ref button_style_hover; + + Ref popup_style; + Ref window_style; + Ref dialog_style; + Ref panel_container_style; + Ref content_panel_style; + Ref tree_panel_style; + + Vector2 widget_margin; + }; static Ref _create_base_theme(const Ref &p_old_theme = nullptr); + static ThemeConfiguration _create_theme_config(const Ref &p_theme); + + static void _create_shared_styles(const Ref &p_theme, ThemeConfiguration &p_config); + static void _populate_standard_styles(const Ref &p_theme, ThemeConfiguration &p_config); + static void _populate_editor_styles(const Ref &p_theme, ThemeConfiguration &p_config); + + static void _generate_text_editor_defaults(ThemeConfiguration &p_config); + static void _populate_text_editor_styles(const Ref &p_theme, ThemeConfiguration &p_config); public: static Ref generate_theme(const Ref &p_old_theme = nullptr);