From 2d5eafd014e44edc493daeed6e4fdc9b43438b6e Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Wed, 3 Apr 2024 00:10:27 +0200 Subject: [PATCH 1/2] macos: Add skeleton for color picker --- gtk/gtkcolorpicker.c | 9 ++- gtk/gtkcolorpickerquartz.c | 108 ++++++++++++++++++++++++++++++ gtk/gtkcolorpickerquartzprivate.h | 36 ++++++++++ gtk/meson.build | 1 + 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 gtk/gtkcolorpickerquartz.c create mode 100644 gtk/gtkcolorpickerquartzprivate.h diff --git a/gtk/gtkcolorpicker.c b/gtk/gtkcolorpicker.c index 2c1b62b2fb..a924b6c8fd 100644 --- a/gtk/gtkcolorpicker.c +++ b/gtk/gtkcolorpicker.c @@ -22,6 +22,10 @@ #include "gtkcolorpickershellprivate.h" #include "gtkcolorpickerkwinprivate.h" +#ifdef __APPLE__ +#include "gtkcolorpickerquartzprivate.h" +#endif + #ifdef G_OS_WIN32 #include "gtkcolorpickerwin32private.h" #endif @@ -58,13 +62,16 @@ gtk_color_picker_new (void) { GtkColorPicker *picker = NULL; -#if defined (G_OS_UNIX) +#if defined (G_OS_UNIX) && !defined(__APPLE__) if (!picker) picker = gtk_color_picker_portal_new (); if (!picker) picker = gtk_color_picker_shell_new (); if (!picker) picker = gtk_color_picker_kwin_new (); +#elif defined (__APPLE__) + if (!picker) + picker = gtk_color_picker_quartz_new (); #elif defined (G_OS_WIN32) if (!picker) picker = gtk_color_picker_win32_new (); diff --git a/gtk/gtkcolorpickerquartz.c b/gtk/gtkcolorpickerquartz.c new file mode 100644 index 0000000000..6f3e34bdf3 --- /dev/null +++ b/gtk/gtkcolorpickerquartz.c @@ -0,0 +1,108 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2024 the GTK team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkcolorpickerquartzprivate.h" + +struct _GtkColorPickerQuartz +{ + GObject parent_instance; +}; + +struct _GtkColorPickerQuartzClass +{ + GObjectClass parent_class; +}; + +static GInitableIface *initable_parent_iface; +static void gtk_color_picker_quartz_initable_iface_init (GInitableIface *iface); +static void gtk_color_picker_quartz_iface_init (GtkColorPickerInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GtkColorPickerQuartz, gtk_color_picker_quartz, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gtk_color_picker_quartz_initable_iface_init) + G_IMPLEMENT_INTERFACE (GTK_TYPE_COLOR_PICKER, gtk_color_picker_quartz_iface_init)) + +static gboolean +gtk_color_picker_quartz_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ +// GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (initable); + + return TRUE; +} + +static void +gtk_color_picker_quartz_initable_iface_init (GInitableIface *iface) +{ + initable_parent_iface = g_type_interface_peek_parent (iface); + iface->init = gtk_color_picker_quartz_initable_init; +} + +static void +gtk_color_picker_quartz_init (GtkColorPickerQuartz *picker) +{ +} + +static void +gtk_color_picker_quartz_finalize (GObject *object) +{ +// GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (object); + + G_OBJECT_CLASS (gtk_color_picker_quartz_parent_class)->finalize (object); +} + +static void +gtk_color_picker_quartz_class_init (GtkColorPickerQuartzClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = gtk_color_picker_quartz_finalize; +} + +GtkColorPicker * +gtk_color_picker_quartz_new (void) +{ + return GTK_COLOR_PICKER (g_initable_new (GTK_TYPE_COLOR_PICKER_QUARTZ, NULL, NULL, NULL)); +} + + +static void +gtk_color_picker_quartz_pick (GtkColorPicker *cp, + GAsyncReadyCallback callback, + gpointer user_data) +{ +// GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (cp); +} + +static GdkRGBA * +gtk_color_picker_quartz_pick_finish (GtkColorPicker *cp, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, cp), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +gtk_color_picker_quartz_iface_init (GtkColorPickerInterface *iface) +{ + iface->pick = gtk_color_picker_quartz_pick; + iface->pick_finish = gtk_color_picker_quartz_pick_finish; +} diff --git a/gtk/gtkcolorpickerquartzprivate.h b/gtk/gtkcolorpickerquartzprivate.h new file mode 100644 index 0000000000..d200933b71 --- /dev/null +++ b/gtk/gtkcolorpickerquartzprivate.h @@ -0,0 +1,36 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2024 the GTK team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#pragma once + + +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + + +#define GTK_TYPE_COLOR_PICKER_QUARTZ gtk_color_picker_quartz_get_type () +G_DECLARE_FINAL_TYPE (GtkColorPickerQuartz, gtk_color_picker_quartz, GTK, COLOR_PICKER_QUARTZ, GObject) + +GDK_AVAILABLE_IN_ALL +GtkColorPicker * gtk_color_picker_quartz_new (void); + +G_END_DECLS diff --git a/gtk/meson.build b/gtk/meson.build index 436a167ff0..1591a36c9e 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -725,6 +725,7 @@ if macos_enabled 'gtksearchenginequartz.c', 'gtkapplication-quartz.c', 'gtkapplication-quartz-menu.c', + 'gtkcolorpickerquartz.c', 'gtkfilechoosernativequartz.c', 'gtkimcontextquartz.c', 'gtkquartz.c', From c835ca41e02697088b6f53a4b1eacd8e54e064f5 Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Wed, 3 Apr 2024 21:00:17 +0200 Subject: [PATCH 2/2] macos: Pick color with NSColorSampler NSColorSampler is the easiest way to pick a color. It does require macOS 10.15+ to work. --- gtk/gtkcolorpickerquartz.c | 52 +++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/gtk/gtkcolorpickerquartz.c b/gtk/gtkcolorpickerquartz.c index 6f3e34bdf3..fe4a3372f1 100644 --- a/gtk/gtkcolorpickerquartz.c +++ b/gtk/gtkcolorpickerquartz.c @@ -17,11 +17,18 @@ #include "config.h" +#include + #include "gtkcolorpickerquartzprivate.h" +#include + struct _GtkColorPickerQuartz { GObject parent_instance; + + NSColorSampler *sampler; + GTask *task; }; struct _GtkColorPickerQuartzClass @@ -42,7 +49,9 @@ gtk_color_picker_quartz_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { -// GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (initable); + GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (initable); + + picker->sampler = [[NSColorSampler alloc] init]; return TRUE; } @@ -62,7 +71,14 @@ gtk_color_picker_quartz_init (GtkColorPickerQuartz *picker) static void gtk_color_picker_quartz_finalize (GObject *object) { -// GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (object); + GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (object); + + g_clear_object (&picker->task); + if (picker->sampler != NULL) + { + [picker->sampler release]; + picker->sampler = NULL; + } G_OBJECT_CLASS (gtk_color_picker_quartz_parent_class)->finalize (object); } @@ -87,7 +103,37 @@ gtk_color_picker_quartz_pick (GtkColorPicker *cp, GAsyncReadyCallback callback, gpointer user_data) { -// GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (cp); + GtkColorPickerQuartz *picker = GTK_COLOR_PICKER_QUARTZ (cp); + + if (picker->task) + return; + + picker->task = g_task_new (picker, NULL, callback, user_data); + + [picker->sampler showSamplerWithSelectionHandler:^(NSColor *selectedColor) { + if (selectedColor == NULL) + { + g_task_return_new_error (picker->task, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "No color received"); + } + else + { + GdkRGBA rgba = (GdkRGBA){ + [selectedColor redComponent], + [selectedColor greenComponent], + [selectedColor blueComponent], + [selectedColor alphaComponent], + }; + + g_task_return_pointer (picker->task, + gdk_rgba_copy (&rgba), + (GDestroyNotify) gdk_rgba_free); + } + + g_clear_object (&picker->task); + }]; } static GdkRGBA *