Compare commits

...

5 Commits

Author SHA1 Message Date
Matthias Clasen
2c42750efd colorchoicebutton: Revise API 2022-10-23 22:10:58 -04:00
Matthias Clasen
ab833951db colorchoice: Revise API 2022-10-23 22:10:58 -04:00
Matthias Clasen
aa5041e65c Add GtkColorChoiceButton
This is a new color button implementation
built around GtkColorChoice.
2022-10-23 17:20:20 -04:00
Matthias Clasen
4022786847 Add GtkColorChoice
Add an async API for picking a color, together with
an object to own it. This is meant to replace direct
use of GtkColorChooserDialog.
2022-10-23 17:18:29 -04:00
Matthias Clasen
029bb9ad18 Add GtkColorChooserWindow
This commit introduces a private GtkColorChooserWindow
which is a copy of GtkColorChooserDialog with the dialog
bits redone.

When GtkColorChooserDialog is dropped, the color chooser
window can be renamed (and made public, if desired).

We want to get rid of GtkDialog. This is a step in that direction.
2022-10-23 17:18:24 -04:00
9 changed files with 1087 additions and 0 deletions

View File

@@ -79,6 +79,8 @@
#include <gtk/gtkcenterlayout.h>
#include <gtk/gtkcheckbutton.h>
#include <gtk/gtkcolorbutton.h>
#include <gtk/gtkcolorchoice.h>
#include <gtk/gtkcolorchoicebutton.h>
#include <gtk/gtkcolorchooser.h>
#include <gtk/gtkcolorchooserdialog.h>
#include <gtk/gtkcolorchooserwidget.h>

195
gtk/gtkcolorchoice.c Normal file
View File

@@ -0,0 +1,195 @@
/*
* GTK - The GIMP Toolkit
* Copyright (C) 2022 Red Hat, Inc.
* All rights reserved.
*
* This Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkcolorchoice.h"
#include "gtkcolorchooserwindowprivate.h"
#include "gtkcolorchooser.h"
#include "gtkbutton.h"
/* {{{ GObject implementation */
struct _GtkColorChoice
{
GObject parent_instance;
GtkWindow *parent;
char *title;
gboolean use_alpha;
GTask *task;
GtkColorChooserWindow *window;
};
G_DEFINE_TYPE (GtkColorChoice, gtk_color_choice, G_TYPE_OBJECT)
static void
gtk_color_choice_init (GtkColorChoice *self)
{
}
static void
gtk_color_choice_finalize (GObject *object)
{
GtkColorChoice *self = GTK_COLOR_CHOICE (object);
g_assert (self->task == NULL);
g_assert (self->window == NULL);
g_free (self->title);
G_OBJECT_CLASS (gtk_color_choice_parent_class)->finalize (object);
}
static void
gtk_color_choice_class_init (GtkColorChoiceClass *class)
{
G_OBJECT_CLASS (class)->finalize = gtk_color_choice_finalize;
}
/* }}} */
/* {{{ Public API */
/* {{{ Constructor */
GtkColorChoice *
gtk_color_choice_new (GtkWindow *parent,
const char *title,
gboolean use_alpha)
{
GtkColorChoice *self;
self = g_object_new (GTK_TYPE_COLOR_CHOICE, NULL);
self->parent = parent;
self->title = g_strdup (title);
self->use_alpha = use_alpha;
return self;
}
/* }}} */
/* {{{ Async API */
enum
{
RESPONSE_OK,
RESPONSE_CANCEL
};
static void response_cb (GtkColorChoice *self,
int response);
static void
cancelled_cb (GCancellable *cancellable,
GtkColorChoice *self)
{
response_cb (self, RESPONSE_CANCEL);
}
static void
response_cb (GtkColorChoice *self,
int response)
{
GCancellable *cancellable;
g_assert (self->window != NULL);
g_assert (self->task != NULL);
cancellable = g_task_get_cancellable (self->task);
if (cancellable)
g_signal_handlers_disconnect_by_func (cancellable, cancelled_cb, self);
if (response == RESPONSE_OK)
{
GdkRGBA color;
gtk_color_chooser_window_save_color (GTK_COLOR_CHOOSER_WINDOW (self->window));
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->window), &color);
g_task_return_pointer (self->task, gdk_rgba_copy (&color), (GDestroyNotify) gdk_rgba_free);
}
else
g_task_return_new_error (self->task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled");
g_clear_pointer ((GtkWindow **)&self->window, gtk_window_destroy);
g_clear_object (&self->task);
}
static void
ok_button_clicked (GtkButton *button,
GtkColorChoice *self)
{
response_cb (self, RESPONSE_OK);
}
static void
cancel_button_clicked (GtkButton *button,
GtkColorChoice *self)
{
response_cb (self, RESPONSE_CANCEL);
}
void
gtk_color_choice_choose (GtkColorChoice *self,
const GdkRGBA *initial_color,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GtkColorChooserWindow *window;
GTask *task;
g_return_if_fail (GTK_IS_COLOR_CHOICE (self));
window = GTK_COLOR_CHOOSER_WINDOW (gtk_color_chooser_window_new (self->title, self->parent));
gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (window), self->use_alpha);
if (initial_color)
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (window), initial_color);
if (cancellable)
g_signal_connect (cancellable, "cancelled", G_CALLBACK (cancelled_cb), self);
g_signal_connect (gtk_color_chooser_window_get_ok_button (window), "clicked",
G_CALLBACK (ok_button_clicked), self);
g_signal_connect (gtk_color_chooser_window_get_cancel_button (window), "clicked",
G_CALLBACK (cancel_button_clicked), self);
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, gtk_color_choice_choose);
self->window = window;
self->task = task;
gtk_window_present (GTK_WINDOW (window));
}
GdkRGBA *
gtk_color_choice_choose_finish (GtkColorChoice *self,
GAsyncResult *result,
GError **error)
{
return g_task_propagate_pointer (G_TASK (result), error);
}
/* }}} */
/* }}} */
/* vim:set foldmethod=marker expandtab: */

52
gtk/gtkcolorchoice.h Normal file
View File

@@ -0,0 +1,52 @@
/* GTK - The GIMP Toolkit
*
* Copyright (C) 2022 Red Hat, Inc.
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gdk/gdk.h>
#include <gtk/gtkwindow.h>
G_BEGIN_DECLS
#define GTK_TYPE_COLOR_CHOICE (gtk_color_choice_get_type ())
GDK_AVAILABLE_IN_4_10
G_DECLARE_FINAL_TYPE (GtkColorChoice, gtk_color_choice, GTK, COLOR_CHOICE, GObject)
GDK_AVAILABLE_IN_4_10
GtkColorChoice * gtk_color_choice_new (GtkWindow *parent,
const char *title,
gboolean use_alpha);
GDK_AVAILABLE_IN_4_10
void gtk_color_choice_choose (GtkColorChoice *choice,
const GdkRGBA *initial_color,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_4_10
GdkRGBA * gtk_color_choice_choose_finish (GtkColorChoice *self,
GAsyncResult *result,
GError **error);
G_END_DECLS

409
gtk/gtkcolorchoicebutton.c Normal file
View File

@@ -0,0 +1,409 @@
/*
* GTK - The GIMP Toolkit
* Copyright (C) 2022 Red Hat, Inc.
* All rights reserved.
*
* This Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkcolorchoicebutton.h"
#include "gtkcolorchoice.h"
#include "gtkbinlayout.h"
#include "gtkbutton.h"
#include "gtkcolorswatchprivate.h"
#include "gtkdragsource.h"
#include "gtkdroptarget.h"
#include <glib/gi18n-lib.h>
//#include "gtkmain.h"
#include "gtkprivate.h"
//#include "gtksnapshot.h"
#include "gtkwidgetprivate.h"
static gboolean drop (GtkDropTarget *dest,
const GValue *value,
double x,
double y,
GtkColorChoiceButton *self);
static GdkContentProvider *
drag_prepare (GtkDragSource *source,
double x,
double y,
GtkColorChoiceButton *self);
static void button_clicked (GtkColorChoiceButton *self);
/* {{{ GObject implementation */
struct _GtkColorChoiceButton
{
GtkWidget parent_instance;
GdkRGBA color;
gboolean use_alpha;
char *title;
GtkWidget *button;
GtkWidget *swatch;
GtkColorChoice *choice;
};
/* Properties */
enum
{
PROP_COLOR = 1,
PROP_USE_ALPHA,
PROP_TITLE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES];
G_DEFINE_TYPE (GtkColorChoiceButton, gtk_color_choice_button, GTK_TYPE_WIDGET)
static void
gtk_color_choice_button_init (GtkColorChoiceButton *self)
{
PangoLayout *layout;
PangoRectangle rect;
GtkDragSource *source;
GtkDropTarget *dest;
self->use_alpha = TRUE;
self->title = g_strdup ("");
self->button = gtk_button_new ();
g_signal_connect_swapped (self->button, "clicked", G_CALLBACK (button_clicked), self);
gtk_widget_set_parent (self->button, GTK_WIDGET (self));
self->swatch = g_object_new (GTK_TYPE_COLOR_SWATCH,
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
"selectable", FALSE,
"has-menu", FALSE,
"can-drag", FALSE,
NULL);
gtk_widget_set_can_focus (self->swatch, FALSE);
gtk_widget_remove_css_class (self->swatch, "activatable");
layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "Black");
pango_layout_get_pixel_extents (layout, NULL, &rect);
g_object_unref (layout);
gtk_widget_set_size_request (self->swatch, rect.width, rect.height);
gtk_button_set_child (GTK_BUTTON (self->button), self->swatch);
dest = gtk_drop_target_new (GDK_TYPE_RGBA, GDK_ACTION_COPY);
g_signal_connect (dest, "drop", G_CALLBACK (drop), self);
gtk_widget_add_controller (GTK_WIDGET (self->button), GTK_EVENT_CONTROLLER (dest));
source = gtk_drag_source_new ();
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare), self);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (source),
GTK_PHASE_CAPTURE);
gtk_widget_add_controller (self->button, GTK_EVENT_CONTROLLER (source));
gtk_widget_add_css_class (self->button, "color");
}
static void
gtk_color_choice_button_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
GtkColorChoiceButton *self = GTK_COLOR_CHOICE_BUTTON (object);
switch (param_id)
{
case PROP_COLOR:
gtk_color_choice_button_set_color (self, g_value_get_boxed (value));
break;
case PROP_USE_ALPHA:
gtk_color_choice_button_set_use_alpha (self, g_value_get_boolean (value));
break;
case PROP_TITLE:
gtk_color_choice_button_set_title (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
gtk_color_choice_button_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
{
GtkColorChoiceButton *self = GTK_COLOR_CHOICE_BUTTON (object);
switch (param_id)
{
case PROP_COLOR:
g_value_set_boxed (value, &self->color);
break;
case PROP_USE_ALPHA:
g_value_set_boolean (value, self->use_alpha);
break;
case PROP_TITLE:
g_value_set_string (value, self->title);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
gtk_color_choice_button_dispose (GObject *object)
{
GtkColorChoiceButton *self = GTK_COLOR_CHOICE_BUTTON (object);
g_clear_pointer (&self->button, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_color_choice_button_parent_class)->dispose (object);
}
static void
gtk_color_choice_button_finalize (GObject *object)
{
GtkColorChoiceButton *self = GTK_COLOR_CHOICE_BUTTON (object);
g_free (self->title);
G_OBJECT_CLASS (gtk_color_choice_button_parent_class)->finalize (object);
}
static void
gtk_color_choice_button_class_init (GtkColorChoiceButtonClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->get_property = gtk_color_choice_button_get_property;
object_class->set_property = gtk_color_choice_button_set_property;
object_class->dispose = gtk_color_choice_button_dispose;
object_class->finalize = gtk_color_choice_button_finalize;
widget_class->grab_focus = gtk_widget_grab_focus_child;
widget_class->focus = gtk_widget_focus_child;
properties[PROP_COLOR] =
g_param_spec_boxed ("color", NULL, NULL,
GDK_TYPE_RGBA,
G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS);
properties[PROP_USE_ALPHA] =
g_param_spec_boolean ("use-alpha", NULL, NULL,
TRUE,
G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS);
properties[PROP_TITLE] =
g_param_spec_string ("title", NULL, NULL,
"",
G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, "colorbutton");
}
/* }}} */
/* {{{ Private API, callbacks */
static guint
scale_round (double value,
double scale)
{
value = floor (value * scale + 0.5);
value = CLAMP (value, 0, scale);
return (guint)value;
}
static char *
accessible_color_name (const GdkRGBA *color)
{
if (color->alpha < 1.0)
return g_strdup_printf (_("Red %d%%, Green %d%%, Blue %d%%, Alpha %d%%"),
scale_round (color->red, 100),
scale_round (color->green, 100),
scale_round (color->blue, 100),
scale_round (color->alpha, 100));
else
return g_strdup_printf (_("Red %d%%, Green %d%%, Blue %d%%"),
scale_round (color->red, 100),
scale_round (color->green, 100),
scale_round (color->blue, 100));
}
static gboolean
drop (GtkDropTarget *dest,
const GValue *value,
double x,
double y,
GtkColorChoiceButton *self)
{
GdkRGBA *color = g_value_get_boxed (value);
gtk_color_choice_button_set_color (self, color);
return TRUE;
}
static GdkContentProvider *
drag_prepare (GtkDragSource *source,
double x,
double y,
GtkColorChoiceButton *self)
{
return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &self->color);
}
static void
color_chosen (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkColorChoice *choice = GTK_COLOR_CHOICE (source);
GtkColorChoiceButton *self = data;
GdkRGBA *color;
GError *error = NULL;
color = gtk_color_choice_choose_finish (choice, result, &error);
if (color)
{
gtk_color_choice_button_set_color (self, color);
gdk_rgba_free (color);
}
else
{
g_print ("%s\n", error->message);
g_error_free (error);
}
}
static void
button_clicked (GtkColorChoiceButton *self)
{
GtkRoot *root;
GtkWindow *parent = NULL;
GtkColorChoice *choice;
root = gtk_widget_get_root (GTK_WIDGET (self));
if (GTK_IS_WINDOW (root))
parent = GTK_WINDOW (root);
choice = gtk_color_choice_new (parent, self->title, self->use_alpha);
gtk_color_choice_choose (choice, &self->color, NULL, color_chosen, self);
g_object_unref (choice);
}
/* }}} */
/* {{{ Public API */
/* {{{ Constructor */
GtkColorChoiceButton *
gtk_color_choice_button_new (void)
{
return g_object_new (GTK_TYPE_COLOR_CHOICE_BUTTON, NULL);
}
/* }}} */
/* {{{ Setters and Getters */
void
gtk_color_choice_button_set_color (GtkColorChoiceButton *self,
const GdkRGBA *color)
{
char *text;
g_return_if_fail (GTK_IS_COLOR_CHOICE_BUTTON (self));
g_return_if_fail (color != NULL);
if (gdk_rgba_equal (&self->color, color))
return;
self->color = *color;
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (self->swatch), color);
text = accessible_color_name (color);
gtk_accessible_update_property (GTK_ACCESSIBLE (self->swatch),
GTK_ACCESSIBLE_PROPERTY_LABEL, text,
-1);
g_free (text);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLOR]);
}
const GdkRGBA *
gtk_color_choice_button_get_color (GtkColorChoiceButton *self)
{
g_return_val_if_fail (GTK_IS_COLOR_CHOICE_BUTTON (self), NULL);
return &self->color;
}
void
gtk_color_choice_button_set_use_alpha (GtkColorChoiceButton *self,
gboolean use_alpha)
{
g_return_if_fail (GTK_IS_COLOR_CHOICE_BUTTON (self));
if (self->use_alpha == use_alpha)
return;
self->use_alpha = use_alpha;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USE_ALPHA]);
}
gboolean
gtk_color_choice_button_get_use_alpha (GtkColorChoiceButton *self)
{
g_return_val_if_fail (GTK_IS_COLOR_CHOICE_BUTTON (self), TRUE);
return self->use_alpha;
}
void
gtk_color_choice_button_set_title (GtkColorChoiceButton *self,
const char *title)
{
char *new_title;
g_return_if_fail (GTK_IS_COLOR_CHOICE_BUTTON (self));
g_return_if_fail (title != NULL);
if (g_str_equal (self->title, title))
return;
new_title = g_strdup (title);
g_free (self->title);
self->title = new_title;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TITLE]);
}
/* }}} */
/* }}} */
/* vim:set foldmethod=marker expandtab: */

View File

@@ -0,0 +1,60 @@
/*
* GTK - The GIMP Toolkit
* Copyright (C) 2022 Red Hat, Inc.
* All rights reserved.
*
* This Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_COLOR_CHOICE_BUTTON (gtk_color_choice_button_get_type ())
GDK_AVAILABLE_IN_4_10
G_DECLARE_FINAL_TYPE (GtkColorChoiceButton, gtk_color_choice_button, GTK, COLOR_CHOICE_BUTTON, GtkWidget)
GDK_AVAILABLE_IN_4_10
GtkColorChoiceButton *
gtk_color_choice_button_new (void);
GDK_AVAILABLE_IN_4_10
void gtk_color_choice_button_set_color (GtkColorChoiceButton *self,
const GdkRGBA *color);
GDK_AVAILABLE_IN_4_10
const GdkRGBA * gtk_color_choice_button_get_color (GtkColorChoiceButton *self);
GDK_AVAILABLE_IN_4_10
void gtk_color_choice_button_set_use_alpha (GtkColorChoiceButton *self,
gboolean use_alpha);
GDK_AVAILABLE_IN_4_10
gboolean gtk_color_choice_button_get_use_alpha (GtkColorChoiceButton *self);
GDK_AVAILABLE_IN_4_10
void gtk_color_choice_button_set_title (GtkColorChoiceButton *self,
const char *title);
GDK_AVAILABLE_IN_4_10
const char * gtk_color_choice_button_get_title (GtkColorChoiceButton *self);
G_END_DECLS

278
gtk/gtkcolorchooserwindow.c Normal file
View File

@@ -0,0 +1,278 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2012 Red Hat, Inc.
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkwindow.h"
#include "gtkwindowprivate.h"
#include "gtkbutton.h"
#include "gtkbox.h"
#include "gtkprivate.h"
#include "gtksettings.h"
#include "gtkcolorchooserprivate.h"
#include "gtkcolorchooserwindowprivate.h"
#include "gtkcolorchooserwidget.h"
/*
* GtkColorChooserWindow:
*
* A window for choosing a color.
*
* ![An example GtkColorChooserWindow](colorchooser.png)
*
* `GtkColorChooserWindow` implements the [iface@Gtk.ColorChooser] interface
* and does not provide much API of its own.
*
* To create a `GtkColorChooserWindow`, use [ctor@Gtk.ColorChooserWindow.new].
*
* To change the initially selected color, use
* [method@Gtk.ColorChooser.set_rgba]. To get the selected color use
* [method@Gtk.ColorChooser.get_rgba].
*/
struct _GtkColorChooserWindow
{
GtkWindow parent_instance;
GtkWidget *chooser;
GtkWidget *ok_button;
GtkWidget *cancel_button;
};
enum
{
PROP_RGBA = 1,
PROP_USE_ALPHA,
PROP_SHOW_EDITOR
};
static void gtk_color_chooser_window_iface_init (GtkColorChooserInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkColorChooserWindow, gtk_color_chooser_window, GTK_TYPE_WINDOW,
G_IMPLEMENT_INTERFACE (GTK_TYPE_COLOR_CHOOSER,
gtk_color_chooser_window_iface_init))
static void
propagate_notify (GObject *o,
GParamSpec *pspec,
GtkColorChooserWindow *self)
{
g_object_notify (G_OBJECT (self), pspec->name);
}
static void
color_activated_cb (GtkColorChooser *chooser,
GdkRGBA *color,
GtkColorChooserWindow *window)
{
g_signal_emit_by_name (window->ok_button, "clicked");
}
static void
gtk_color_chooser_window_init (GtkColorChooserWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
gtk_color_chooser_window_unmap (GtkWidget *widget)
{
GTK_WIDGET_CLASS (gtk_color_chooser_window_parent_class)->unmap (widget);
/* We never want the window to come up with the editor,
* even if it was showing the editor the last time it was used.
*/
g_object_set (widget, "show-editor", FALSE, NULL);
}
static void
gtk_color_chooser_window_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkColorChooserWindow *self = GTK_COLOR_CHOOSER_WINDOW (object);
switch (prop_id)
{
case PROP_RGBA:
{
GdkRGBA color;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self), &color);
g_value_set_boxed (value, &color);
}
break;
case PROP_USE_ALPHA:
g_value_set_boolean (value, gtk_color_chooser_get_use_alpha (GTK_COLOR_CHOOSER (self->chooser)));
break;
case PROP_SHOW_EDITOR:
{
gboolean show_editor;
g_object_get (self->chooser, "show-editor", &show_editor, NULL);
g_value_set_boolean (value, show_editor);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_color_chooser_window_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkColorChooserWindow *self = GTK_COLOR_CHOOSER_WINDOW (object);
switch (prop_id)
{
case PROP_RGBA:
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self), g_value_get_boxed (value));
break;
case PROP_USE_ALPHA:
if (gtk_color_chooser_get_use_alpha (GTK_COLOR_CHOOSER (self->chooser)) != g_value_get_boolean (value))
{
gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (self->chooser), g_value_get_boolean (value));
g_object_notify_by_pspec (object, pspec);
}
break;
case PROP_SHOW_EDITOR:
g_object_set (self->chooser,
"show-editor", g_value_get_boolean (value),
NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_color_chooser_window_dispose (GObject *object)
{
GtkColorChooserWindow *self = GTK_COLOR_CHOOSER_WINDOW (object);
g_clear_pointer (&self->chooser, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_color_chooser_window_parent_class)->dispose (object);
}
static void
gtk_color_chooser_window_class_init (GtkColorChooserWindowClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = gtk_color_chooser_window_dispose;
object_class->get_property = gtk_color_chooser_window_get_property;
object_class->set_property = gtk_color_chooser_window_set_property;
widget_class->unmap = gtk_color_chooser_window_unmap;
g_object_class_override_property (object_class, PROP_RGBA, "rgba");
g_object_class_override_property (object_class, PROP_USE_ALPHA, "use-alpha");
g_object_class_install_property (object_class, PROP_SHOW_EDITOR,
g_param_spec_boolean ("show-editor", NULL, NULL,
FALSE, GTK_PARAM_READWRITE));
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/libgtk/ui/gtkcolorchooserwindow.ui");
gtk_widget_class_bind_template_child (widget_class, GtkColorChooserWindow, chooser);
gtk_widget_class_bind_template_child (widget_class, GtkColorChooserWindow, ok_button);
gtk_widget_class_bind_template_child (widget_class, GtkColorChooserWindow, cancel_button);
gtk_widget_class_bind_template_callback (widget_class, propagate_notify);
gtk_widget_class_bind_template_callback (widget_class, color_activated_cb);
}
static void
gtk_color_chooser_window_get_rgba (GtkColorChooser *chooser,
GdkRGBA *color)
{
GtkColorChooserWindow *self = GTK_COLOR_CHOOSER_WINDOW (chooser);
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->chooser), color);
}
static void
gtk_color_chooser_window_set_rgba (GtkColorChooser *chooser,
const GdkRGBA *color)
{
GtkColorChooserWindow *self = GTK_COLOR_CHOOSER_WINDOW (chooser);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->chooser), color);
}
static void
gtk_color_chooser_window_add_palette (GtkColorChooser *chooser,
GtkOrientation orientation,
int colors_per_line,
int n_colors,
GdkRGBA *colors)
{
GtkColorChooserWindow *self = GTK_COLOR_CHOOSER_WINDOW (chooser);
gtk_color_chooser_add_palette (GTK_COLOR_CHOOSER (self->chooser),
orientation, colors_per_line, n_colors, colors);
}
static void
gtk_color_chooser_window_iface_init (GtkColorChooserInterface *iface)
{
iface->get_rgba = gtk_color_chooser_window_get_rgba;
iface->set_rgba = gtk_color_chooser_window_set_rgba;
iface->add_palette = gtk_color_chooser_window_add_palette;
}
GtkWidget *
gtk_color_chooser_window_new (const char *title,
GtkWindow *parent)
{
return g_object_new (GTK_TYPE_COLOR_CHOOSER_WINDOW,
"title", title,
"transient-for", parent,
"modal", TRUE,
NULL);
}
void
gtk_color_chooser_window_save_color (GtkColorChooserWindow *self)
{
GdkRGBA color;
/* This causes the color chooser widget to save the
* selected and custom colors to GSettings.
*/
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self), &color);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self), &color);
}
GtkWidget *
gtk_color_chooser_window_get_ok_button (GtkColorChooserWindow *self)
{
return self->ok_button;
}
GtkWidget *
gtk_color_chooser_window_get_cancel_button (GtkColorChooserWindow *self)
{
return self->cancel_button;
}

View File

@@ -0,0 +1,34 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2012 Red Hat, Inc.
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gtk/gtkwindow.h>
G_BEGIN_DECLS
#define GTK_TYPE_COLOR_CHOOSER_WINDOW (gtk_color_chooser_window_get_type ())
G_DECLARE_FINAL_TYPE (GtkColorChooserWindow, gtk_color_chooser_window, GTK, COLOR_CHOOSER_WINDOW, GtkWindow)
GtkWidget * gtk_color_chooser_window_new (const char *title,
GtkWindow *parent);
void gtk_color_chooser_window_save_color (GtkColorChooserWindow *self);
GtkWidget *gtk_color_chooser_window_get_ok_button (GtkColorChooserWindow *self);
GtkWidget *gtk_color_chooser_window_get_cancel_button (GtkColorChooserWindow *self);
G_END_DECLS

View File

@@ -183,9 +183,12 @@ gtk_public_sources = files([
'gtkcenterlayout.c',
'gtkcheckbutton.c',
'gtkcolorbutton.c',
'gtkcolorchoice.c',
'gtkcolorchoicebutton.c',
'gtkcolorchooser.c',
'gtkcolorchooserdialog.c',
'gtkcolorchooserwidget.c',
'gtkcolorchooserwindow.c',
'gtkcolorutils.c',
'gtkcolumnview.c',
'gtkcolumnviewcolumn.c',
@@ -439,6 +442,8 @@ gtk_public_headers = files([
'gtkcenterlayout.h',
'gtkcheckbutton.h',
'gtkcolorbutton.h',
'gtkcolorchoice.h',
'gtkcolorchoicebutton.h',
'gtkcolorchooser.h',
'gtkcolorchooserdialog.h',
'gtkcolorchooserwidget.h',

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk40">
<template class="GtkColorChooserWindow" parent="GtkWindow">
<property name="title" translatable="yes">Select a Color</property>
<property name="resizable">0</property>
<property name="default-widget">ok_button</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="show-title-buttons">0</property>
<child type="start">
<object class="GtkButton" id="cancel_button">
<property name="use-underline">1</property>
<property name="label" translatable="yes">_Cancel</property>
</object>
</child>
<child type="end">
<object class="GtkButton" id="ok_button">
<property name="label" translatable="yes">_Select</property>
<property name="use-underline">1</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">1</property>
<property name="spacing">2</property>
<property name="margin-start">5</property>
<property name="margin-end">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<child>
<object class="GtkColorChooserWidget" id="chooser">
<property name="margin-start">5</property>
<property name="margin-end">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="rgba">rgb(255,255,255)</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<signal name="color-activated" handler="color_activated_cb" swapped="no"/>
<signal name="notify::rgba" handler="propagate_notify" swapped="no"/>
<signal name="notify::show-editor" handler="propagate_notify" swapped="no"/>
</object>
</child>
</object>
</child>
</template>
</interface>