summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-10-22 21:48:22 -0400
committerMatthias Clasen <mclasen@redhat.com>2022-10-22 23:53:13 -0400
commitb665a955586de44eaed69132db602a270804e6d2 (patch)
tree3cf68418f0606b752ad2846b26ba409c33d3d407
parent799fb41937950e32cace797c142ac66e290b192b (diff)
downloadgtk+-b665a955586de44eaed69132db602a270804e6d2.tar.gz
wip: Add async api to choose a color
This is an experiment to replace explicit use of chooser dialogs with an async API.
-rw-r--r--gtk/gtkcolorchooser.h26
-rw-r--r--gtk/gtkcolorchooserdialog.c130
2 files changed, 156 insertions, 0 deletions
diff --git a/gtk/gtkcolorchooser.h b/gtk/gtkcolorchooser.h
index 7a97865b8d..97cb0ed364 100644
--- a/gtk/gtkcolorchooser.h
+++ b/gtk/gtkcolorchooser.h
@@ -83,6 +83,32 @@ void gtk_color_chooser_add_palette (GtkColorChooser *chooser,
int n_colors,
GdkRGBA *colors);
+
+typedef void (*GtkColorChooserPrepareCallback) (GtkColorChooser *chooser,
+ gpointer user_data);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_choose_color (GtkWindow *parent,
+ const char *title,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_choose_color_full (GtkWindow *parent,
+ const char *title,
+ GtkColorChooserPrepareCallback prepare,
+ gpointer prepare_data,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_choose_color_finish (GtkColorChooser *chooser,
+ GAsyncResult *result,
+ GdkRGBA *color,
+ GError **error);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorChooser, g_object_unref)
G_END_DECLS
diff --git a/gtk/gtkcolorchooserdialog.c b/gtk/gtkcolorchooserdialog.c
index 81ac261880..3dc6a61c79 100644
--- a/gtk/gtkcolorchooserdialog.c
+++ b/gtk/gtkcolorchooserdialog.c
@@ -291,3 +291,133 @@ gtk_color_chooser_dialog_new (const char *title,
"transient-for", parent,
NULL);
}
+
+static void
+cancelled_cb (GCancellable *cancellable,
+ GtkDialog *dialog)
+{
+ gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL);
+}
+
+static void
+response_cb (GtkDialog *dialog,
+ int response,
+ GTask *task)
+{
+ GCancellable *cancellable = g_task_get_cancellable (task);
+
+ if (cancellable)
+ g_signal_handlers_disconnect_by_func (cancellable, cancelled_cb, dialog);
+
+ if (response == GTK_RESPONSE_OK)
+ g_task_return_boolean (task, TRUE);
+ else
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled");
+
+ g_object_unref (task);
+ gtk_window_destroy (GTK_WINDOW (dialog));
+}
+
+/**
+ * gtk_choose_color:
+ * @parent: (nullable): parent window
+ * @title: title for the color chooser
+ * @cancellable: (nullable): a `GCancellable` to cancel the operation
+ * @callback: (scope async): callback to call when the action is complete
+ * @user_data: (closure callback): data to pass to @callback
+ *
+ * This function presents a color chooser to let the user
+ * pick a color.
+ *
+ * The @callback will be called when the dialog is closed.
+ * It should call [function@Gtk.choose_color_finish] to
+ * find out whether the operation was completed successfully,
+ * and to obtain the resulting color.
+ */
+void
+gtk_choose_color (GtkWindow *parent,
+ const char *title,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gtk_choose_color_full (parent, title, NULL, NULL, cancellable, callback, user_data);
+}
+
+/**
+ * gtk_choose_color_full:
+ * @parent: (nullable): parent window
+ * @title: title for the color chooser
+ * @prepare: (nullable) (scope call): callback to set up the color chooser
+ * @prepare_data: (closure prepare): data to pass to @prepare
+ * @cancellable: (nullable): a `GCancellable` to cancel the operation
+ * @callback: (scope async): callback to call when the action is complete
+ * @user_data: (closure callback): data to pass to @callback
+ *
+ * This function presents a color chooser to let the user
+ * pick a color.
+ *
+ * In addition to [function@Gtk.choose_color], this function takes
+ * a @prepare callback that lets you set up the color chooser according
+ * to your needs.
+ *
+ * The @callback will be called when the dialog is closed.
+ * It should call [function@Gtk.choose_color_finish] to
+ * find out whether the operation was completed successfully,
+ * and to obtain the resulting color.
+ */
+void
+gtk_choose_color_full (GtkWindow *parent,
+ const char *title,
+ GtkColorChooserPrepareCallback prepare,
+ gpointer prepare_data,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GtkWidget *dialog;
+ GTask *task;
+
+ dialog = gtk_color_chooser_dialog_new (title, parent);
+ if (prepare)
+ prepare (GTK_COLOR_CHOOSER (dialog), prepare);
+
+ if (cancellable)
+ g_signal_connect (cancellable, "cancelled", G_CALLBACK (cancelled_cb), dialog);
+
+ task = g_task_new (dialog, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gtk_choose_color_full);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (response_cb), task);
+
+ gtk_window_present (GTK_WINDOW (dialog));
+}
+
+/**
+ * gtk_choose_color_finish:
+ * @chooser: the `GtkColorChooser`
+ * @result: `GAsyncResult` that was passed to @callback
+ * @color: return location for the color
+ * @error: return location for an error
+ *
+ * Finishes a gtk_choose_color() or gtk_choose_color_full() call
+ * and returns the results.
+ *
+ * If this function returns `TRUE`, @color contains
+ * the color that was chosen.
+ *
+ * Returns: `TRUE` if the operation was successful
+ */
+gboolean
+gtk_choose_color_finish (GtkColorChooser *chooser,
+ GAsyncResult *result,
+ GdkRGBA *color,
+ GError **error)
+{
+ if (!g_task_propagate_boolean (G_TASK (result), error))
+ return FALSE;
+
+ gtk_color_chooser_get_rgba (chooser, color);
+
+ return TRUE;
+}