diff --git a/app/config/config-enums.c b/app/config/config-enums.c index 313b5fcd58..fbd72fb89a 100644 --- a/app/config/config-enums.c +++ b/app/config/config-enums.c @@ -387,6 +387,37 @@ gimp_zoom_quality_get_type (void) return type; } +GType +gimp_theme_scheme_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_THEME_LIGHT, "GIMP_THEME_LIGHT", "light" }, + { GIMP_THEME_GRAY, "GIMP_THEME_GRAY", "gray" }, + { GIMP_THEME_DARK, "GIMP_THEME_DARK", "dark" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_THEME_LIGHT, NC_("theme-scheme", "Light Colors"), NULL }, + { GIMP_THEME_GRAY, NC_("theme-scheme", "Middle Gray"), NULL }, + { GIMP_THEME_DARK, NC_("theme-scheme", "Dark Colors"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpThemeScheme", values); + gimp_type_set_translation_context (type, "theme-scheme"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + /* Generated data ends here */ diff --git a/app/config/config-enums.h b/app/config/config-enums.h index 73bc899c6a..e06d90fbd4 100644 --- a/app/config/config-enums.h +++ b/app/config/config-enums.h @@ -164,5 +164,19 @@ typedef enum GIMP_ZOOM_QUALITY_HIGH /*< desc="High" >*/ } GimpZoomQuality; +#define GIMP_TYPE_THEME_SCHEME (gimp_theme_scheme_get_type ()) + +GType gimp_theme_scheme_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_THEME_LIGHT, /*< desc="Light Colors" >*/ + GIMP_THEME_GRAY, /*< desc="Middle Gray" >*/ + GIMP_THEME_DARK, /*< desc="Dark Colors" >*/ + /* TODO: it might be interesting eventually to add a GIMP_THEME_SYSTEM + * following up the system-wide color scheme preference. See #8675. + */ +} GimpThemeScheme; + #endif /* __CONFIG_ENUMS_H__ */ diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c index a362ec420e..a3eb0d92f3 100644 --- a/app/config/gimpguiconfig.c +++ b/app/config/gimpguiconfig.c @@ -70,7 +70,7 @@ enum PROP_TOOLBOX_GROUPS, PROP_THEME_PATH, PROP_THEME, - PROP_PREFER_DARK_THEME, + PROP_THEME_SCHEME, PROP_OVERRIDE_THEME_ICON_SIZE, PROP_CUSTOM_ICON_SIZE, PROP_ICON_THEME_PATH, @@ -315,11 +315,12 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass) THEME_BLURB, GIMP_CONFIG_DEFAULT_THEME, GIMP_PARAM_STATIC_STRINGS); - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PREFER_DARK_THEME, - "prefer-dark-theme", - "Prefer Dark Theme", - THEME_BLURB, - TRUE, + GIMP_CONFIG_PROP_ENUM (object_class, PROP_THEME_SCHEME, + "theme-color-scheme", + "Theme's Color Scheme", + THEME_SCHEME_BLURB, + GIMP_TYPE_THEME_SCHEME, + GIMP_THEME_DARK, GIMP_PARAM_STATIC_STRINGS); GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_OVERRIDE_THEME_ICON_SIZE, "override-theme-icon-size", @@ -683,8 +684,8 @@ gimp_gui_config_set_property (GObject *object, g_free (gui_config->theme); gui_config->theme = g_value_dup_string (value); break; - case PROP_PREFER_DARK_THEME: - gui_config->prefer_dark_theme = g_value_get_boolean (value); + case PROP_THEME_SCHEME: + gui_config->theme_scheme = g_value_get_enum (value); break; case PROP_OVERRIDE_THEME_ICON_SIZE: gui_config->override_icon_size = g_value_get_boolean (value); @@ -865,8 +866,8 @@ gimp_gui_config_get_property (GObject *object, case PROP_THEME: g_value_set_string (value, gui_config->theme); break; - case PROP_PREFER_DARK_THEME: - g_value_set_boolean (value, gui_config->prefer_dark_theme); + case PROP_THEME_SCHEME: + g_value_set_enum (value, gui_config->theme_scheme); break; case PROP_OVERRIDE_THEME_ICON_SIZE: g_value_set_boolean (value, gui_config->override_icon_size); diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h index 9ad7ec6030..e71d61fad5 100644 --- a/app/config/gimpguiconfig.h +++ b/app/config/gimpguiconfig.h @@ -64,7 +64,7 @@ struct _GimpGuiConfig gboolean toolbox_groups; gchar *theme_path; gchar *theme; - gboolean prefer_dark_theme; + GimpThemeScheme theme_scheme; gchar *icon_theme_path; gchar *icon_theme; gboolean prefer_symbolic_icons; diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h index de39f998eb..4361821e26 100644 --- a/app/config/gimprc-blurbs.h +++ b/app/config/gimprc-blurbs.h @@ -546,6 +546,9 @@ _("Sets the folder for temporary storage. Files will appear here " \ #define THEME_BLURB \ _("The name of the theme to use.") +#define THEME_SCHEME_BLURB \ +_("Chooses the color scheme variant of the theme.") + #define THEME_PATH_BLURB \ "Sets the theme search path." diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c index 75f3769fc3..4f89ad7e57 100644 --- a/app/dialogs/preferences-dialog.c +++ b/app/dialogs/preferences-dialog.c @@ -2115,9 +2115,10 @@ prefs_dialog_new (Gimp *gimp, G_CALLBACK (prefs_theme_select_callback), gimp); - prefs_check_button_add (object, "prefer-dark-theme", - _("Use dark theme variant if available"), - GTK_BOX (vbox2)); + grid = prefs_grid_new (GTK_CONTAINER (vbox2)); + button = prefs_enum_combo_box_add (object, "theme-color-scheme", 0, 0, + _("Color scheme variant (if available)"), + GTK_GRID (grid), 0, NULL); /* Override icon sizes. */ button = prefs_check_button_add (object, "override-theme-icon-size", diff --git a/app/gui/themes.c b/app/gui/themes.c index 950b27a6dd..1132744dc1 100644 --- a/app/gui/themes.c +++ b/app/gui/themes.c @@ -92,7 +92,7 @@ themes_init (Gimp *gimp) g_signal_connect (config, "notify::theme", G_CALLBACK (themes_theme_change_notify), gimp); - g_signal_connect (config, "notify::prefer-dark-theme", + g_signal_connect (config, "notify::theme-color-scheme", G_CALLBACK (themes_theme_change_notify), gimp); g_signal_connect (config, "notify::prefer-symbolic-icons", @@ -237,10 +237,12 @@ themes_apply_theme (Gimp *gimp, GFile *theme_css; GOutputStream *output; GError *error = NULL; + gboolean prefer_dark_theme; g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (GIMP_IS_GUI_CONFIG (config)); + prefer_dark_theme = (config->theme_scheme != GIMP_THEME_LIGHT); theme_css = gimp_directory_file ("theme.css", NULL); if (gimp->be_verbose) @@ -263,11 +265,79 @@ themes_apply_theme (Gimp *gimp, if (theme_dir) { - css_files = g_slist_prepend (css_files, g_file_get_child (theme_dir, - "gimp.css")); - if (config->prefer_dark_theme) - css_files = g_slist_prepend (css_files, g_file_get_child (theme_dir, - "gimp-dark.css")); + GFile *file = NULL; + GFile *fallback; + GFile *light; + GFile *gray; + GFile *dark; + + fallback = g_file_get_child (theme_dir, "gimp.css"); + if (! g_file_query_exists (fallback, NULL)) + g_clear_object (&fallback); + + light = g_file_get_child (theme_dir, "gimp-light.css"); + if (! g_file_query_exists (light, NULL)) + g_clear_object (&light); + + gray = g_file_get_child (theme_dir, "gimp-gray.css"); + if (! g_file_query_exists (gray, NULL)) + g_clear_object (&gray); + + dark = g_file_get_child (theme_dir, "gimp-dark.css"); + if (! g_file_query_exists (dark, NULL)) + g_clear_object (&dark); + + switch (config->theme_scheme) + { + case GIMP_THEME_LIGHT: + if (light != NULL) + file = g_object_ref (light); + else if (fallback != NULL) + file = g_object_ref (fallback); + else if (gray != NULL) + file = g_object_ref (gray); + else if (dark != NULL) + file = g_object_ref (dark); + break; + case GIMP_THEME_GRAY: + if (gray != NULL) + file = g_object_ref (gray); + else if (fallback != NULL) + file = g_object_ref (fallback); + else if (dark != NULL) + file = g_object_ref (dark); + else if (light != NULL) + file = g_object_ref (light); + break; + case GIMP_THEME_DARK: + if (dark != NULL) + file = g_object_ref (dark); + else if (fallback != NULL) + file = g_object_ref (fallback); + else if (gray != NULL) + file = g_object_ref (gray); + else if (light != NULL) + file = g_object_ref (light); + break; + } + + if (file != NULL) + { + prefer_dark_theme = (file == dark || file == gray); + css_files = g_slist_prepend (css_files, file); + } + else + { + gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR, + _("Invalid theme: directory '%s' contains neither " + "gimp-dark.css, gimp-gray.css, gimp-light.css nor gimp.css."), + gimp_file_get_utf8_name (theme_dir)); + } + + g_clear_object (&fallback); + g_clear_object (&light); + g_clear_object (&gray); + g_clear_object (&dark); } else { @@ -276,18 +346,30 @@ themes_apply_theme (Gimp *gimp, tmp = g_build_filename (gimp_data_directory (), "themes", "Default", "gimp.css", NULL); - css_files = g_slist_prepend ( - css_files, g_file_new_for_path (tmp)); + css_files = g_slist_prepend (css_files, g_file_new_for_path (tmp)); g_free (tmp); - if (config->prefer_dark_theme) + switch (config->theme_scheme) { + case GIMP_THEME_LIGHT: + tmp = g_build_filename (gimp_data_directory (), + "themes", "Default", "gimp-light.css", + NULL); + break; + case GIMP_THEME_GRAY: + tmp = g_build_filename (gimp_data_directory (), + "themes", "Default", "gimp-gray.css", + NULL); + break; + case GIMP_THEME_DARK: tmp = g_build_filename (gimp_data_directory (), "themes", "Default", "gimp-dark.css", NULL); - css_files = g_slist_prepend (css_files, g_file_new_for_path (tmp)); - g_free (tmp); + break; } + + css_files = g_slist_prepend (css_files, g_file_new_for_path (tmp)); + g_free (tmp); } css_files = g_slist_prepend ( @@ -338,7 +420,7 @@ themes_apply_theme (Gimp *gimp, "\n" "%s", config->prefer_symbolic_icons ? "symbolic" : "regular", - config->prefer_dark_theme ? "/* prefer-dark-theme */\n" : ""); + prefer_dark_theme ? "/* prefer-dark-theme */\n" : ""); } if (! error && config->override_icon_size) @@ -455,7 +537,7 @@ themes_theme_change_notify (GimpGuiConfig *config, GError *error = NULL; g_object_set (gtk_settings_get_for_screen (gdk_screen_get_default ()), - "gtk-application-prefer-dark-theme", config->prefer_dark_theme, + "gtk-application-prefer-dark-theme", config->theme_scheme != GIMP_THEME_LIGHT, NULL); themes_apply_theme (gimp, config); diff --git a/app/widgets/gimpwidgets-utils.c b/app/widgets/gimpwidgets-utils.c index e7298eaf97..b4ba8fb39a 100644 --- a/app/widgets/gimpwidgets-utils.c +++ b/app/widgets/gimpwidgets-utils.c @@ -2642,7 +2642,7 @@ gimp_window_set_title_bar_theme (Gimp *gimp, GimpGuiConfig *config; config = GIMP_GUI_CONFIG (gimp->config); - use_dark_mode = config->prefer_dark_theme; + use_dark_mode = (config->theme_scheme != GIMP_THEME_LIGHT); } else { diff --git a/themes/Gray/gimp.css b/themes/Default/gimp-gray.css similarity index 98% rename from themes/Gray/gimp.css rename to themes/Default/gimp-gray.css index 6bdd2639af..f70d65b987 100644 --- a/themes/Gray/gimp.css +++ b/themes/Default/gimp-gray.css @@ -66,4 +66,4 @@ @define-color ruler-color rgba(100,100,100,0.3); -@import url("../Default/common-light.css"); +@import url("common-light.css"); diff --git a/themes/Default/gimp.css b/themes/Default/gimp-light.css similarity index 100% rename from themes/Default/gimp.css rename to themes/Default/gimp-light.css diff --git a/themes/Default/meson.build b/themes/Default/meson.build index 8c2a46a794..d612fafc8e 100644 --- a/themes/Default/meson.build +++ b/themes/Default/meson.build @@ -1,7 +1,7 @@ subdir('ui') files = [ - 'gimp.css', 'gimp-dark.css', + 'gimp-light.css', 'gimp-gray.css', 'gimp-dark.css', 'common.css', 'common-dark.css', 'common-light.css' ] diff --git a/themes/meson.build b/themes/meson.build index 94b1963518..3fd57c6a5f 100644 --- a/themes/meson.build +++ b/themes/meson.build @@ -3,7 +3,6 @@ subdir('Darker') subdir('Compact') themes = [ - 'Gray', 'System', ]