diff --git a/data/darktableconfig.xml.in b/data/darktableconfig.xml.in index e85ea9c18c09..70c004caca59 100644 --- a/data/darktableconfig.xml.in +++ b/data/darktableconfig.xml.in @@ -40,6 +40,37 @@ false modify theme with user tweaks + + themes/rounded-header + bool + false + use rounded module's header + + + themes/focused-module-border + bool + false + use small border around module + + + themes/expanded-module-border + bool + false + use small border around module + + + themes/colored-accent + int + 0 + use colored accent for some UI elements + + + themes/condensed + bool + false + condensed panels' controls + use condensed panels' controls in all views + accel/prefer_focused bool @@ -161,13 +192,6 @@ marker shape the shape of the slider marker - - themes/condensed - bool - false - condensed panels' controls - use condensed panels' controls in all views - darkroom/ui/auto_module_name_update bool diff --git a/data/themes/chunk-blue-accent-color.css b/data/themes/chunk-blue-accent-color.css new file mode 100644 index 000000000000..177951cf11e0 --- /dev/null +++ b/data/themes/chunk-blue-accent-color.css @@ -0,0 +1,4 @@ + +@define-color active_module_icon_fg @accent_blue; + +@import url("chunk-colored-accent.css"); diff --git a/data/themes/chunk-blue-expanded-module-border.css b/data/themes/chunk-blue-expanded-module-border.css new file mode 100644 index 000000000000..d23696709e91 --- /dev/null +++ b/data/themes/chunk-blue-expanded-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_expanded_border_color @accent_blue; + +@import url("chunk-expanded-module-border.css"); diff --git a/data/themes/chunk-blue-focused-module-border.css b/data/themes/chunk-blue-focused-module-border.css new file mode 100644 index 000000000000..bc4c11a56a56 --- /dev/null +++ b/data/themes/chunk-blue-focused-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_focus_border_color @accent_blue; + +@import url("chunk-focused-module-border.css"); diff --git a/data/themes/chunk-colored-accent.css b/data/themes/chunk-colored-accent.css new file mode 100644 index 000000000000..a5a81bc896dd --- /dev/null +++ b/data/themes/chunk-colored-accent.css @@ -0,0 +1,19 @@ + +#right #module-header > button:first-child:checked, +#right #basics-header-box > button:first-child:checked +{ + color: @active_module_icon_fg; +} + +#right #module-header > button:first-child:hover, +#right #basics-header-box > button:first-child:hover +{ + background-color: black; +} + +#right > box:last-child #module-header +{ + background-color: @bg_color; + border-radius: 0px; + margin-right: 0.9em; +} diff --git a/data/themes/chunk-condensed.css b/data/themes/chunk-condensed.css index 6f9de17696ea..9117dd805bc4 100644 --- a/data/themes/chunk-condensed.css +++ b/data/themes/chunk-condensed.css @@ -34,3 +34,12 @@ min-height: 12px; font-size: 0.95em; } + +#left #module-header, +#right #module-header, +#right #basics-header-box +{ + border-radius: 0px; + margin: 0px; + padding: 4px; +} diff --git a/data/themes/chunk-dark-expanded-module-border.css b/data/themes/chunk-dark-expanded-module-border.css new file mode 100644 index 000000000000..64c92262f3b2 --- /dev/null +++ b/data/themes/chunk-dark-expanded-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_expanded_border_color shade(@plugin_bg_color, 0.5); + +@import url("chunk-expanded-module-border.css"); diff --git a/data/themes/chunk-dark-focused-module-border.css b/data/themes/chunk-dark-focused-module-border.css new file mode 100644 index 000000000000..3ee897714f76 --- /dev/null +++ b/data/themes/chunk-dark-focused-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_focus_border_color shade(@plugin_bg_color, 0.5); + +@import url("chunk-focused-module-border.css"); diff --git a/data/themes/chunk-expanded-module-border.css b/data/themes/chunk-expanded-module-border.css new file mode 100644 index 000000000000..7e0574c896c7 --- /dev/null +++ b/data/themes/chunk-expanded-module-border.css @@ -0,0 +1,13 @@ + +/* ensure space for border is reserved for all modules */ +#iop-expander +{ + border: 0.1em solid @plugin_bg_color; + margin: 0.2em 0.2em 0 0.2em; +} + +/* border for expanded modules */ +#iop-expander.dt_module_expanded +{ + border: 0.1em solid @plugin_expanded_border_color; +} diff --git a/data/themes/chunk-focused-module-border.css b/data/themes/chunk-focused-module-border.css new file mode 100644 index 000000000000..7eb2392e802a --- /dev/null +++ b/data/themes/chunk-focused-module-border.css @@ -0,0 +1,13 @@ + +/* ensure space for border is reserved for all modules */ +#iop-expander +{ + border: 0.1em solid @plugin_bg_color; + margin: 0.2em 0.2em 0 0.2em; +} + +/* border for focused modules */ +#iop-expander.dt_module_expanded.dt_module_focus +{ + border: 0.1em solid @plugin_focus_border_color; +} diff --git a/data/themes/chunk-green-accent-color.css b/data/themes/chunk-green-accent-color.css new file mode 100644 index 000000000000..01568ac3d50d --- /dev/null +++ b/data/themes/chunk-green-accent-color.css @@ -0,0 +1,4 @@ + +@define-color active_module_icon_fg @accent_green; + +@import url("chunk-colored-accent.css"); diff --git a/data/themes/chunk-green-expanded-module-border.css b/data/themes/chunk-green-expanded-module-border.css new file mode 100644 index 000000000000..1435ed5dd129 --- /dev/null +++ b/data/themes/chunk-green-expanded-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_expanded_border_color @accent_green; + +@import url("chunk-expanded-module-border.css"); diff --git a/data/themes/chunk-green-focused-module-border.css b/data/themes/chunk-green-focused-module-border.css new file mode 100644 index 000000000000..3f1acebb747b --- /dev/null +++ b/data/themes/chunk-green-focused-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_focus_border_color @accent_green; + +@import url("chunk-focused-module-border.css"); diff --git a/data/themes/chunk-light-expanded-module-border.css b/data/themes/chunk-light-expanded-module-border.css new file mode 100644 index 000000000000..02c23d9bca28 --- /dev/null +++ b/data/themes/chunk-light-expanded-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_expanded_border_color shade(@plugin_bg_color, 2.0); + +@import url("chunk-expanded-module-border.css"); diff --git a/data/themes/chunk-light-focused-module-border.css b/data/themes/chunk-light-focused-module-border.css new file mode 100644 index 000000000000..e7501146a32a --- /dev/null +++ b/data/themes/chunk-light-focused-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_focus_border_color shade(@plugin_bg_color, 2.0); + +@import url("chunk-focused-module-border.css"); diff --git a/data/themes/chunk-orange-accent-color.css b/data/themes/chunk-orange-accent-color.css new file mode 100644 index 000000000000..8e20ba1aa258 --- /dev/null +++ b/data/themes/chunk-orange-accent-color.css @@ -0,0 +1,4 @@ + +@define-color active_module_icon_fg @accent_orange; + +@import url("chunk-colored-accent.css"); diff --git a/data/themes/chunk-orange-expanded-module-border.css b/data/themes/chunk-orange-expanded-module-border.css new file mode 100644 index 000000000000..f7f61ad14acd --- /dev/null +++ b/data/themes/chunk-orange-expanded-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_expanded_border_color @accent_orange; + +@import url("chunk-expanded-module-border.css"); diff --git a/data/themes/chunk-orange-focused-module-border.css b/data/themes/chunk-orange-focused-module-border.css new file mode 100644 index 000000000000..982e148ac2b1 --- /dev/null +++ b/data/themes/chunk-orange-focused-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_focus_border_color @accent_orange; + +@import url("chunk-focused-module-border.css"); diff --git a/data/themes/chunk-rounded-header.css b/data/themes/chunk-rounded-header.css new file mode 100644 index 000000000000..93e335499598 --- /dev/null +++ b/data/themes/chunk-rounded-header.css @@ -0,0 +1,28 @@ + +@define-color header_color shade(@plugin_bg_color, 0.8); +@define-color header_color_bg shade(@plugin_bg_color, 1.1); + +#left #module-header, +#right #module-header, +#right #basics-header-box +{ + background-color: @header_color; + border-radius: 0px; +} + +#left #module-header +{ + border-top-right-radius: 15px; +} + +#right #module-header, +#right #basics-header-box +{ + border-top-left-radius: 15px; +} + +#iop-expander, +.dt_module_expanded +{ + background-color: @header_color_bg; +} diff --git a/data/themes/chunk-yellow-accent-color.css b/data/themes/chunk-yellow-accent-color.css new file mode 100644 index 000000000000..8072c4c7c674 --- /dev/null +++ b/data/themes/chunk-yellow-accent-color.css @@ -0,0 +1,4 @@ + +@define-color active_module_icon_fg @accent_yellow; + +@import url("chunk-colored-accent.css"); diff --git a/data/themes/chunk-yellow-expanded-module-border.css b/data/themes/chunk-yellow-expanded-module-border.css new file mode 100644 index 000000000000..b7a9a454a2d8 --- /dev/null +++ b/data/themes/chunk-yellow-expanded-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_expanded_border_color @accent_yellow; + +@import url("chunk-expanded-module-border.css"); diff --git a/data/themes/chunk-yellow-focused-module-border.css b/data/themes/chunk-yellow-focused-module-border.css new file mode 100644 index 000000000000..efed863b9662 --- /dev/null +++ b/data/themes/chunk-yellow-focused-module-border.css @@ -0,0 +1,4 @@ + +@define-color plugin_focus_border_color @accent_yellow; + +@import url("chunk-focused-module-border.css"); diff --git a/data/themes/darktable.css b/data/themes/darktable.css index 1398aa88773c..06c9fa5eafae 100644 --- a/data/themes/darktable.css +++ b/data/themes/darktable.css @@ -231,6 +231,12 @@ Why that? Just because it's a developer choice and most classes use underscore i @define-color colorlabel_yellow rgb(255,180,0); @define-color colorlabel_purple rgb(230,0,230); +/* pastel colors for the variants (module borders and active module) */ +@define-color accent_green #C1E1C5; +@define-color accent_blue #9FBFE2; +@define-color accent_yellow #E6E6A1; +@define-color accent_orange #E6C2A1; + /* Reset GTK defaults - Otherwise dt inherits Adwaita default theme dark */ * { @@ -1339,6 +1345,13 @@ filechooser row:hover .sidebar-icon padding: 0.14em 0.84em; } +#theme-variant +{ + margin-left: 2em; + padding-left: 0.5em; + min-height: 1.5em; +} + /*-------------------- - Quick access tab - --------------------*/ diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 32fc10563c8b..2e83b35b48dd 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -3709,6 +3709,67 @@ void dt_gui_load_theme(const char *theme) _add_theme_import(&themecss, datadir, "themes", "chunk-condensed.css"); } + // chunk-rounded-header + + if(dt_conf_get_bool("themes/rounded-header")) + { + _add_theme_import(&themecss, datadir, "themes", "chunk-rounded-header.css"); + } + + // chunk-colored-accent + + int index = dt_conf_get_int("themes/accent-color"); + + if(index > 0) + { + const char *colors[] = + { + "none", + "green", + "blue", + "yellow", + "orange" + }; + + char *chunk = g_strdup_printf + ("chunk-%s-accent-color.css", + colors[index]); + _add_theme_import(&themecss, datadir, "themes", chunk); + g_free(chunk); + } + + // focused module border + + const char *border_colors[] = + { + "none", + "light", + "dark", + "green", + "blue", + "yellow", + "orange"}; + + index = dt_conf_get_int("themes/focused-module-border"); + + if (index > 0) + { + char *chunk = g_strdup_printf("chunk-%s-focused-module-border.css", + border_colors[index]); + _add_theme_import(&themecss, datadir, "themes", chunk); + g_free(chunk); + } + + index = dt_conf_get_int("themes/expanded-module-border"); + + if (index > 0) + { + char *chunk = g_strdup_printf("chunk-%s-expanded-module-border.css", + border_colors[index]); + _add_theme_import(&themecss, datadir, "themes", chunk); + g_free(chunk); + } + // load any OS specific themes tweak file to fix some platform specific issues #ifdef __APPLE__ diff --git a/src/gui/preferences.c b/src/gui/preferences.c index ef3f89ab8ecd..1025dc210765 100644 --- a/src/gui/preferences.c +++ b/src/gui/preferences.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2010-2025 darktable developers. + Copyright (C) 2010-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -205,6 +205,51 @@ static void use_sys_font_callback(GtkWidget *widget, reload_ui_last_theme(); } +static void use_rounded_header_callback(GtkWidget *widget, + gpointer user_data) +{ + dt_conf_set_bool("themes/rounded-header", + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); + + reload_ui_last_theme(); +} + +static void use_condensed_control_callback(GtkWidget *widget, + gpointer user_data) +{ + dt_conf_set_bool("themes/condensed", + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); + + reload_ui_last_theme(); +} + +static void use_accent_color_callback(GtkWidget *widget, + gpointer user_data) +{ + const int selected = dt_bauhaus_combobox_get(widget); + + dt_conf_set_int("themes/accent-color", selected); + reload_ui_last_theme(); +} + +static void use_focused_module_border_callback(GtkWidget *widget, + gpointer user_data) +{ + const int selected = dt_bauhaus_combobox_get(widget); + + dt_conf_set_int("themes/focused-module-border", selected); + reload_ui_last_theme(); +} + +static void use_expanded_module_border_callback(GtkWidget *widget, + gpointer user_data) +{ + const int selected = dt_bauhaus_combobox_get(widget); + + dt_conf_set_int("themes/expanded-module-border", selected); + reload_ui_last_theme(); +} + static void save_usercss(GtkTextBuffer *buffer) { // get file locations @@ -413,6 +458,115 @@ static void init_tab_general(GtkWidget *dialog, G_CALLBACK(theme_callback), 0); gtk_widget_set_tooltip_text(widget, _("set the theme for the user interface")); + // theme variants + + // condensed controls + GtkWidget *t_condensed = gtk_check_button_new(); + label = gtk_label_new(_("condensed module controls")); + gtk_widget_set_name(label, "theme-variant"); + gtk_widget_set_halign(label, GTK_ALIGN_START); + labelev = gtk_event_box_new(); + gtk_widget_add_events(labelev, GDK_BUTTON_PRESS_MASK); + gtk_container_add(GTK_CONTAINER(labelev), label); + gtk_grid_attach(GTK_GRID(grid), labelev, 0, line++, 1, 1); + gtk_grid_attach_next_to(GTK_GRID(grid), t_condensed, labelev, GTK_POS_RIGHT, 1, 1); + gtk_widget_set_tooltip_text(t_condensed, _("use condensed module controls")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_condensed), + dt_conf_get_bool("themes/condensed")); + g_signal_connect(G_OBJECT(t_condensed), "toggled", + G_CALLBACK(use_condensed_control_callback), + (gpointer)t_condensed); + + // rounded header + GtkWidget *t_rounded = gtk_check_button_new(); + label = gtk_label_new(_("rounded module headers")); + gtk_widget_set_name(label, "theme-variant"); + gtk_widget_set_halign(label, GTK_ALIGN_START); + labelev = gtk_event_box_new(); + gtk_widget_add_events(labelev, GDK_BUTTON_PRESS_MASK); + gtk_container_add(GTK_CONTAINER(labelev), label); + gtk_grid_attach(GTK_GRID(grid), labelev, 0, line++, 1, 1); + gtk_grid_attach_next_to(GTK_GRID(grid), t_rounded, labelev, GTK_POS_RIGHT, 1, 1); + gtk_widget_set_tooltip_text(t_rounded, _("use rounded module headers variant")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_rounded), + dt_conf_get_bool("themes/rounded-header")); + g_signal_connect(G_OBJECT(t_rounded), "toggled", + G_CALLBACK(use_rounded_header_callback), (gpointer)t_rounded); + + // focused module border + label = gtk_label_new(_("focused module border")); + gtk_widget_set_name(label, "theme-variant"); + gtk_widget_set_halign(label, GTK_ALIGN_START); + widget = dt_bauhaus_combobox_new(NULL); + dt_bauhaus_combobox_set_selected_text_align(widget, DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + + labelev = gtk_event_box_new(); + gtk_widget_add_events(labelev, GDK_BUTTON_PRESS_MASK); + gtk_container_add(GTK_CONTAINER(labelev), label); + gtk_grid_attach(GTK_GRID(grid), labelev, 0, line++, 1, 1); + gtk_grid_attach_next_to(GTK_GRID(grid), widget, labelev, GTK_POS_RIGHT, 1, 1); + dt_bauhaus_combobox_add_aligned(widget, _("none"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("light"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("dark"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("green"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("blue"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("yellow"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("orange"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_set(widget, dt_conf_get_int("themes/focused-module-border")); + g_signal_connect(G_OBJECT(widget), "value-changed", + G_CALLBACK(use_focused_module_border_callback), 0); + gtk_widget_set_tooltip_text(widget, + _("set the focused module border color")); + + // expanded module border + label = gtk_label_new(_("expanded module border")); + gtk_widget_set_name(label, "theme-variant"); + gtk_widget_set_halign(label, GTK_ALIGN_START); + widget = dt_bauhaus_combobox_new(NULL); + dt_bauhaus_combobox_set_selected_text_align(widget, DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + + labelev = gtk_event_box_new(); + gtk_widget_add_events(labelev, GDK_BUTTON_PRESS_MASK); + gtk_container_add(GTK_CONTAINER(labelev), label); + gtk_grid_attach(GTK_GRID(grid), labelev, 0, line++, 1, 1); + gtk_grid_attach_next_to(GTK_GRID(grid), widget, labelev, GTK_POS_RIGHT, 1, 1); + dt_bauhaus_combobox_add_aligned(widget, _("none"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("light"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("dark"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("green"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("blue"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("yellow"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("orange"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_set(widget, dt_conf_get_int("themes/expanded-module-border")); + g_signal_connect(G_OBJECT(widget), "value-changed", + G_CALLBACK(use_expanded_module_border_callback), 0); + gtk_widget_set_tooltip_text(widget, + _("set the expanded module border color")); + + // accent color + label = gtk_label_new(_("accent color")); + gtk_widget_set_name(label, "theme-variant"); + gtk_widget_set_halign(label, GTK_ALIGN_START); + widget = dt_bauhaus_combobox_new(NULL); + dt_bauhaus_combobox_set_selected_text_align(widget, DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + + labelev = gtk_event_box_new(); + gtk_widget_add_events(labelev, GDK_BUTTON_PRESS_MASK); + gtk_container_add(GTK_CONTAINER(labelev), label); + gtk_grid_attach(GTK_GRID(grid), labelev, 0, line++, 1, 1); + gtk_grid_attach_next_to(GTK_GRID(grid), widget, labelev, GTK_POS_RIGHT, 1, 1); + dt_bauhaus_combobox_add_aligned(widget, _("none"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("green"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("blue"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("yellow"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_add_aligned(widget, _("orange"), DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); + dt_bauhaus_combobox_set + (widget, dt_conf_get_int("themes/accent-color")); + g_signal_connect(G_OBJECT(widget), "value-changed", + G_CALLBACK(use_accent_color_callback), 0); + gtk_widget_set_tooltip_text(widget, + _("set the theme accent color for the interface")); + //Font size check and spin buttons GtkWidget *usesysfont = gtk_check_button_new(); GtkWidget *fontsize = gtk_spin_button_new_with_range(5.0f, 30.0f, 0.2f);