summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Murphy <hello@itsjamie.dev>2023-03-21 18:43:08 -0700
committerJamie Murphy <hello@itsjamie.dev>2023-03-26 23:25:13 -0700
commit672278979eaa357b7f1473b6f05692048297e32b (patch)
tree61e4a7f6fa3e1c1b2ecb91f26ef059dc663b8d2e
parenta5747ded170475278df5b44a1149258268f8f722 (diff)
downloadgnome-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.c146
-rw-r--r--panels/background/cc-accent-color.h33
-rw-r--r--panels/background/cc-background-panel.c165
-rw-r--r--panels/background/cc-background-panel.ui18
-rw-r--r--panels/background/meson.build1
-rw-r--r--panels/background/preview.css23
-rw-r--r--shell/cc-application.c2
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