diff options
author | Jamie Murphy <hello@itsjamie.dev> | 2023-03-21 18:43:08 -0700 |
---|---|---|
committer | Jamie Murphy <hello@itsjamie.dev> | 2023-03-26 23:25:13 -0700 |
commit | 672278979eaa357b7f1473b6f05692048297e32b (patch) | |
tree | 61e4a7f6fa3e1c1b2ecb91f26ef059dc663b8d2e | |
parent | a5747ded170475278df5b44a1149258268f8f722 (diff) | |
download | gnome-control-center-wip/jamie/accent-colours.tar.gz |
background: Implement accent colourswip/jamie/accent-colours
Adds a row to toggle the system accent colour
-rw-r--r-- | panels/background/cc-accent-color.c | 146 | ||||
-rw-r--r-- | panels/background/cc-accent-color.h | 33 | ||||
-rw-r--r-- | panels/background/cc-background-panel.c | 165 | ||||
-rw-r--r-- | panels/background/cc-background-panel.ui | 18 | ||||
-rw-r--r-- | panels/background/meson.build | 1 | ||||
-rw-r--r-- | panels/background/preview.css | 23 | ||||
-rw-r--r-- | shell/cc-application.c | 2 |
7 files changed, 362 insertions, 26 deletions
diff --git a/panels/background/cc-accent-color.c b/panels/background/cc-accent-color.c new file mode 100644 index 000000000..78b576d3e --- /dev/null +++ b/panels/background/cc-accent-color.c @@ -0,0 +1,146 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2023 Jamie Murphy <jmurphy@gnome.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <config.h> + +#include "cc-accent-color.h" + +#define INTERFACE_PATH_ID "org.gnome.desktop.interface" + +struct _CcAccentColor +{ + GtkWidget parent_instance; + + AdwAccentColor color; +}; + +enum +{ + PROP_0, + PROP_ACCENT_COLOR, + N_PROPS +}; + +static GParamSpec *props[N_PROPS]; + +G_DEFINE_FINAL_TYPE (CcAccentColor, cc_accent_color, GTK_TYPE_WIDGET) + +static void +cc_accent_color_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + CcAccentColor *self = CC_ACCENT_COLOR (object); + + switch (prop_id) + { + case PROP_ACCENT_COLOR: + g_value_set_enum (value, self->color); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +cc_accent_color_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CcAccentColor *self = CC_ACCENT_COLOR (object); + + switch (prop_id) + { + case PROP_ACCENT_COLOR: + self->color = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +cc_accent_color_snapshot (GtkWidget *widget, + GtkSnapshot *snapshot) +{ + CcAccentColor *self = CC_ACCENT_COLOR (widget); + AdwStyleManager *style_manager = adw_style_manager_get_default (); + gboolean is_dark = adw_style_manager_get_dark (style_manager); + GdkRGBA color = { 0, 0, 0, 0 }; + GtkAllocation allocation; + + gtk_widget_get_allocation (widget, &allocation); + + if (is_dark) + adw_accent_color_to_rgba (self->color, NULL, &color); + else + adw_accent_color_to_rgba (self->color, &color, NULL); + + gtk_snapshot_save (snapshot); + + gtk_snapshot_append_color (snapshot, &color, + &GRAPHENE_RECT_INIT (0.0f, 0.0f, + allocation.width, allocation.height)); + + gtk_snapshot_restore (snapshot); +} + +static void +cc_accent_color_class_init (CcAccentColorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->get_property = cc_accent_color_get_property; + object_class->set_property = cc_accent_color_set_property; + widget_class->snapshot = cc_accent_color_snapshot; + + props[PROP_ACCENT_COLOR] = + g_param_spec_enum ("accent-color", "", "", + ADW_TYPE_ACCENT_COLOR, ADW_ACCENT_COLOR_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPS, props); + gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT); +} + +static void +cc_accent_color_init (CcAccentColor *self) +{ +} + +GtkWidget * +cc_accent_color_new (AdwAccentColor color) +{ + return g_object_new (CC_TYPE_ACCENT_COLOR, + "accent-color", color, + NULL); +} + +AdwAccentColor * +cc_accent_color_get_accent_color (CcAccentColor *self) +{ + g_return_val_if_fail (CC_IS_ACCENT_COLOR (self), NULL); + + return &self->color; +} diff --git a/panels/background/cc-accent-color.h b/panels/background/cc-accent-color.h new file mode 100644 index 000000000..e873d8e7e --- /dev/null +++ b/panels/background/cc-accent-color.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2023 Jamie Murphy <jmurphy@gnome.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include <adwaita.h> + +G_BEGIN_DECLS + +#define CC_TYPE_ACCENT_COLOR (cc_accent_color_get_type ()) +G_DECLARE_FINAL_TYPE (CcAccentColor, cc_accent_color, CC, ACCENT_COLOR, GtkWidget) + +GtkWidget * cc_accent_color_new (AdwAccentColor color); + +AdwAccentColor * cc_accent_color_get_accent_color (CcAccentColor *self); + +G_END_DECLS diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c index 12f1e64d1..da956e48c 100644 --- a/panels/background/cc-background-panel.c +++ b/panels/background/cc-background-panel.c @@ -29,6 +29,7 @@ #include "cc-background-panel.h" +#include "cc-accent-color.h" #include "cc-background-chooser.h" #include "cc-background-item.h" #include "cc-background-preview.h" @@ -46,6 +47,7 @@ #define INTERFACE_PATH_ID "org.gnome.desktop.interface" #define INTERFACE_COLOR_SCHEME_KEY "color-scheme" +#define INTERFACE_ACCENT_COLOR_KEY "accent-color" struct _CcBackgroundPanel { @@ -61,6 +63,7 @@ struct _CcBackgroundPanel CcBackgroundItem *current_background; + GtkWidget *accent_box; CcBackgroundChooser *background_chooser; CcBackgroundPreview *default_preview; CcBackgroundPreview *dark_preview; @@ -83,7 +86,135 @@ load_custom_css (CcBackgroundPanel *self) } static void -reload_color_scheme_toggles (CcBackgroundPanel *self) +transition_screen (CcBackgroundPanel *self) +{ + g_autoptr (GError) error = NULL; + + if (!self->proxy) + return; + + g_dbus_proxy_call_sync (self->proxy, + "ScreenTransition", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + + if (error) + g_warning ("Couldn't transition screen: %s", error->message); +} + +static void +on_accent_color_toggled_cb (CcBackgroundPanel *self, + GtkToggleButton *toggle) +{ + CcAccentColor *accent_color_widget = CC_ACCENT_COLOR (gtk_widget_get_first_child (GTK_WIDGET (toggle))); + AdwAccentColor accent_color_from_key; + AdwAccentColor accent_color = *cc_accent_color_get_accent_color (accent_color_widget); + + /* There's no equivalent in GDesktopAccentColor */ + g_assert (accent_color != ADW_ACCENT_COLOR_DEFAULT); + + accent_color_from_key = g_settings_get_enum (self->interface_settings, + INTERFACE_ACCENT_COLOR_KEY) + 1; + + /* Don't unnecessarily set the key again */ + if (accent_color == accent_color_from_key) + return; + + transition_screen (self); + + g_settings_set_enum (self->interface_settings, + INTERFACE_ACCENT_COLOR_KEY, + accent_color - 1); + +} + +/* Adapted from adw-inspector-page.c */ +static char * +get_color_tooltip (AdwAccentColor color) +{ + switch (color) { + case ADW_ACCENT_COLOR_DEFAULT: + return g_strdup (_("Default")); + case ADW_ACCENT_COLOR_BLUE: + return g_strdup (_("Blue")); + case ADW_ACCENT_COLOR_TEAL: + return g_strdup (_("Teal")); + case ADW_ACCENT_COLOR_GREEN: + return g_strdup (_("Green")); + case ADW_ACCENT_COLOR_YELLOW: + return g_strdup (_("Yellow")); + case ADW_ACCENT_COLOR_ORANGE: + return g_strdup (_("Orange")); + case ADW_ACCENT_COLOR_RED: + return g_strdup (_("Red")); + case ADW_ACCENT_COLOR_PINK: + return g_strdup (_("Pink")); + case ADW_ACCENT_COLOR_PURPLE: + return g_strdup (_("Purple")); + case ADW_ACCENT_COLOR_BROWN: + return g_strdup (_("Brown")); + case ADW_ACCENT_COLOR_SLATE: + return g_strdup (_("Slate")); + default: + g_assert_not_reached (); + } +} + +static void +setup_accent_color_toggles (CcBackgroundPanel *self) +{ + AdwAccentColor accent_color = g_settings_get_enum (self->interface_settings, INTERFACE_ACCENT_COLOR_KEY) + 1; + AdwAccentColor i; + + for (i = ADW_ACCENT_COLOR_BLUE; i <= ADW_ACCENT_COLOR_SLATE; i++) + { + GtkWidget *button = GTK_WIDGET (gtk_toggle_button_new ()); + GtkWidget *color_widget = cc_accent_color_new (i); + GtkToggleButton *grouping_button = GTK_TOGGLE_BUTTON (gtk_widget_get_first_child (self->accent_box)); + + gtk_widget_set_tooltip_text (button, get_color_tooltip (i)); + gtk_widget_add_css_class (button, "accent-button"); + gtk_widget_set_overflow (color_widget, GTK_OVERFLOW_HIDDEN); + gtk_button_set_child (GTK_BUTTON (button), color_widget); + g_signal_connect_object (button, "toggled", + G_CALLBACK (on_accent_color_toggled_cb), + self, + G_CONNECT_SWAPPED); + + if (grouping_button != NULL) + gtk_toggle_button_set_group (GTK_TOGGLE_BUTTON (button), grouping_button); + + if (i == accent_color) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + + gtk_box_append (GTK_BOX (self->accent_box), button); + } +} + +static void +reload_accent_color_toggles (CcBackgroundPanel *self) +{ + AdwAccentColor accent_color = g_settings_get_enum (self->interface_settings, INTERFACE_ACCENT_COLOR_KEY) + 1; + GtkWidget *child; + + for (child = gtk_widget_get_first_child (self->accent_box); + child; + child = gtk_widget_get_next_sibling (child)) { + CcAccentColor *accent_color_widget = CC_ACCENT_COLOR (gtk_widget_get_first_child (child)); + AdwAccentColor *child_color = cc_accent_color_get_accent_color (accent_color_widget); + + if (*child_color == accent_color) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (child), TRUE); + else + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (child), FALSE); + } +} + +static void +reload_color_scheme (CcBackgroundPanel *self) { GDesktopColorScheme scheme; @@ -105,26 +236,6 @@ reload_color_scheme_toggles (CcBackgroundPanel *self) } static void -transition_screen (CcBackgroundPanel *self) -{ - g_autoptr (GError) error = NULL; - - if (!self->proxy) - return; - - g_dbus_proxy_call_sync (self->proxy, - "ScreenTransition", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - - if (error) - g_warning ("Couldn't transition screen: %s", error->message); -} - -static void set_color_scheme (CcBackgroundPanel *self, GDesktopColorScheme color_scheme) { @@ -386,6 +497,7 @@ cc_background_panel_class_init (CcBackgroundPanelClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-panel.ui"); + gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, accent_box); gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, background_chooser); gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, default_preview); gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, dark_preview); @@ -429,11 +541,18 @@ cc_background_panel_init (CcBackgroundPanel *panel) g_signal_connect_object (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel, G_CONNECT_SWAPPED); /* Interface settings */ - reload_color_scheme_toggles (panel); + setup_accent_color_toggles (panel); + reload_color_scheme (panel); + + g_signal_connect_object (panel->interface_settings, + "changed::" INTERFACE_ACCENT_COLOR_KEY, + G_CALLBACK (reload_accent_color_toggles), + panel, + G_CONNECT_SWAPPED); g_signal_connect_object (panel->interface_settings, "changed::" INTERFACE_COLOR_SCHEME_KEY, - G_CALLBACK (reload_color_scheme_toggles), + G_CALLBACK (reload_color_scheme), panel, G_CONNECT_SWAPPED); diff --git a/panels/background/cc-background-panel.ui b/panels/background/cc-background-panel.ui index 33a86385e..9cac71a8b 100644 --- a/panels/background/cc-background-panel.ui +++ b/panels/background/cc-background-panel.ui @@ -90,6 +90,24 @@ </object> </child> + <child> + <object class="AdwPreferencesRow"> + <property name="activatable">False</property> + <property name="focusable">False</property> + <child> + <object class="GtkBox" id="accent_box"> + <property name="spacing">12</property> + <property name="margin-start">12</property> + <property name="margin-end">12</property> + <property name="margin-top">12</property> + <property name="margin-bottom">12</property> + <property name="hexpand">True</property> + <property name="halign">center</property> + </object> + </child> + </object> + </child> + </object> </child> diff --git a/panels/background/meson.build b/panels/background/meson.build index 69af0cfea..bc89ea2a1 100644 --- a/panels/background/meson.build +++ b/panels/background/meson.build @@ -62,6 +62,7 @@ sources = common_sources + files( 'bg-recent-source.c', 'bg-source.c', 'bg-wallpapers-source.c', + 'cc-accent-color.c', 'cc-background-chooser.c', 'cc-background-item.c', 'cc-background-paintable.c', diff --git a/panels/background/preview.css b/panels/background/preview.css index e9497348b..8fa47ec47 100644 --- a/panels/background/preview.css +++ b/panels/background/preview.css @@ -49,15 +49,15 @@ background-preview .window.front.dark .header-bar { } .background-preview-button:checked { - box-shadow: 0 0 0 3px @accent_color; + box-shadow: 0 0 0 3px @accent_bg_color; } .background-preview-button:focus:focus-visible { - box-shadow: 0 0 0 3px alpha(@accent_color, .3); + box-shadow: 0 0 0 3px alpha(@accent_bg_color, .3); } .background-preview-button:checked:focus:focus-visible { - box-shadow: 0 0 0 3px @accent_color, 0 0 0 6px alpha(@accent_color, .3); + box-shadow: 0 0 0 3px @accent_bg_color, 0 0 0 6px alpha(@accent_bg_color, .3); } .background-flowbox > flowboxchild { @@ -94,3 +94,20 @@ flowboxchild:selected .selected-check { min-height: 0; margin: 6px; } + +.accent-button { + border-radius: 9999px; + padding: 3px; + background: transparent; + min-width: 24px; + min-height: 24px; +} + +.accent-button:checked { + box-shadow: 0 0 0 3px @accent_bg_color; +} + +.accent-button > widget { + border-radius: 9999px; +} + diff --git a/shell/cc-application.c b/shell/cc-application.c index 2ae0fbe2d..d4226380f 100644 --- a/shell/cc-application.c +++ b/shell/cc-application.c @@ -252,6 +252,8 @@ cc_application_startup (GApplication *application) gtk_style_context_add_provider_for_display (gdk_display_get_default (), GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + adw_style_manager_set_follow_system_accent_color (adw_style_manager_get_default (), TRUE); } static void |