diff options
| author | Matthias Clasen <mclasen@redhat.com> | 2022-10-22 21:48:22 -0400 |
|---|---|---|
| committer | Matthias Clasen <mclasen@redhat.com> | 2022-10-22 23:53:13 -0400 |
| commit | b665a955586de44eaed69132db602a270804e6d2 (patch) | |
| tree | 3cf68418f0606b752ad2846b26ba409c33d3d407 | |
| parent | 799fb41937950e32cace797c142ac66e290b192b (diff) | |
| download | gtk+-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.h | 26 | ||||
| -rw-r--r-- | gtk/gtkcolorchooserdialog.c | 130 |
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; +} |
