app, themes: merge the Gray and Default themes and add theme color scheme concept.

Until now, we were following a similar concept of color schemes as what most OS
are doing. For instance, Freedesktop recently introduced a tri-state color
scheme of "Prefer Light", "Prefer Dark" and "Default", the latter being either
whatever the software prefers (e.g. we prefer either Dark or Gray for graphics
software usually) or what the system prefers. See #8675.

Until now, with GTK, we only had a boolean "prefer dark" setting through the
"gtk-application-prefer-dark-theme" settings. There is not even a "prefer
light".

Nevertheless for graphics application, there is clearly a third case (fourth if
we added a "follow system color preferences" which we don't implement for now):
gray mode and in particular middle gray. Having a middle gray UI is often
considered a necessity when working on colors in order to protect our perception
of color from being influenced by surrounding UI.
To fill this need, we were proposing a Default vs. a Gray theme in GIMP, but
this was a bit confusing and felt illogical, as discussed on IRC some time ago.
Also depending on whether you chose "prefer dark" or not for the gray theme,
this one was itself 2 themes, which made things odd and harder to work on.

Instead this commit:

- adds a color scheme concept in GIMP with 3 variants so far: light, gray and
  dark. A possible fourth (future) variant might be to follow the system
  preference (do all OS provide such a queriable option?).
- Our Gray theme is merged into Default (as the gray color scheme variant).
- Custom themes can add the following CSS files: gimp-light.css, gimp-gray.css,
  gimp-dark.css which are the base file for their respective scheme. gimp.css is
  still used as a fallback though it is not necessary (our own Default theme
  does not provide a gimp.css anymore). Custom themes don't have to provide all
  3 variants. A theme can just provide one or 2 variants if it only wants to
  support 1 or 2 use cases.
This commit is contained in:
Jehan 2024-01-25 18:16:15 +01:00
parent e741920d8e
commit c32e803679
12 changed files with 162 additions and 31 deletions

View File

@ -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 */

View File

@ -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__ */

View File

@ -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);

View File

@ -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;

View File

@ -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."

View File

@ -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",

View File

@ -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);

View File

@ -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
{

View File

@ -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");

View File

@ -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'
]

View File

@ -3,7 +3,6 @@ subdir('Darker')
subdir('Compact')
themes = [
'Gray',
'System',
]