1/* GTK - The GIMP Toolkit
2 * Copyright (C) 2012 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19
20#include "gtkdialog.h"
21#include "gtkdialogprivate.h"
22#include "gtkbutton.h"
23#include "gtkbox.h"
24#include "gtkprivate.h"
25#include "gtkintl.h"
26#include "gtksettings.h"
27
28#include "gtkcolorchooserprivate.h"
29#include "gtkcolorchooserdialog.h"
30#include "gtkcolorchooserwidget.h"
31
32/**
33 * GtkColorChooserDialog:
34 *
35 * A dialog for choosing a color.
36 *
37 * ![An example GtkColorChooserDialog](colorchooser.png)
38 *
39 * `GtkColorChooserDialog` implements the [iface@Gtk.ColorChooser] interface
40 * and does not provide much API of its own.
41 *
42 * To create a `GtkColorChooserDialog`, use [ctor@Gtk.ColorChooserDialog.new].
43 *
44 * To change the initially selected color, use
45 * [method@Gtk.ColorChooser.set_rgba]. To get the selected color use
46 * [method@Gtk.ColorChooser.get_rgba].
47 */
48
49typedef struct _GtkColorChooserDialogClass GtkColorChooserDialogClass;
50
51struct _GtkColorChooserDialog
52{
53 GtkDialog parent_instance;
54
55 GtkWidget *chooser;
56};
57
58struct _GtkColorChooserDialogClass
59{
60 GtkDialogClass parent_class;
61};
62
63enum
64{
65 PROP_ZERO,
66 PROP_RGBA,
67 PROP_USE_ALPHA,
68 PROP_SHOW_EDITOR
69};
70
71static void gtk_color_chooser_dialog_iface_init (GtkColorChooserInterface *iface);
72
73G_DEFINE_TYPE_WITH_CODE (GtkColorChooserDialog, gtk_color_chooser_dialog, GTK_TYPE_DIALOG,
74 G_IMPLEMENT_INTERFACE (GTK_TYPE_COLOR_CHOOSER,
75 gtk_color_chooser_dialog_iface_init))
76
77static void
78propagate_notify (GObject *o,
79 GParamSpec *pspec,
80 GtkColorChooserDialog *cc)
81{
82 g_object_notify (G_OBJECT (cc), property_name: pspec->name);
83}
84
85static void
86save_color (GtkColorChooserDialog *dialog)
87{
88 GdkRGBA color;
89
90 /* This causes the color chooser widget to save the
91 * selected and custom colors to GSettings.
92 */
93 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (dialog), color: &color);
94 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (dialog), color: &color);
95}
96
97static void
98color_activated_cb (GtkColorChooser *chooser,
99 GdkRGBA *color,
100 GtkDialog *dialog)
101{
102 save_color (GTK_COLOR_CHOOSER_DIALOG (dialog));
103 gtk_dialog_response (dialog, response_id: GTK_RESPONSE_OK);
104}
105
106static void
107gtk_color_chooser_dialog_response (GtkDialog *dialog,
108 int response_id,
109 gpointer user_data)
110{
111 if (response_id == GTK_RESPONSE_OK)
112 save_color (GTK_COLOR_CHOOSER_DIALOG (dialog));
113}
114
115static void
116gtk_color_chooser_dialog_init (GtkColorChooserDialog *cc)
117{
118 gtk_widget_init_template (GTK_WIDGET (cc));
119 gtk_dialog_set_use_header_bar_from_setting (GTK_DIALOG (cc));
120
121 g_signal_connect (cc, "response",
122 G_CALLBACK (gtk_color_chooser_dialog_response), NULL);
123}
124
125static void
126gtk_color_chooser_dialog_unmap (GtkWidget *widget)
127{
128 GTK_WIDGET_CLASS (gtk_color_chooser_dialog_parent_class)->unmap (widget);
129
130 /* We never want the dialog to come up with the editor,
131 * even if it was showing the editor the last time it was used.
132 */
133 g_object_set (object: widget, first_property_name: "show-editor", FALSE, NULL);
134}
135
136static void
137gtk_color_chooser_dialog_get_property (GObject *object,
138 guint prop_id,
139 GValue *value,
140 GParamSpec *pspec)
141{
142 GtkColorChooserDialog *cc = GTK_COLOR_CHOOSER_DIALOG (object);
143
144 switch (prop_id)
145 {
146 case PROP_RGBA:
147 {
148 GdkRGBA color;
149
150 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (cc), color: &color);
151 g_value_set_boxed (value, v_boxed: &color);
152 }
153 break;
154 case PROP_USE_ALPHA:
155 g_value_set_boolean (value, v_boolean: gtk_color_chooser_get_use_alpha (GTK_COLOR_CHOOSER (cc->chooser)));
156 break;
157 case PROP_SHOW_EDITOR:
158 {
159 gboolean show_editor;
160 g_object_get (object: cc->chooser, first_property_name: "show-editor", &show_editor, NULL);
161 g_value_set_boolean (value, v_boolean: show_editor);
162 }
163 break;
164 default:
165 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
166 break;
167 }
168}
169
170static void
171gtk_color_chooser_dialog_set_property (GObject *object,
172 guint prop_id,
173 const GValue *value,
174 GParamSpec *pspec)
175{
176 GtkColorChooserDialog *cc = GTK_COLOR_CHOOSER_DIALOG (object);
177
178 switch (prop_id)
179 {
180 case PROP_RGBA:
181 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (cc), color: g_value_get_boxed (value));
182 break;
183 case PROP_USE_ALPHA:
184 if (gtk_color_chooser_get_use_alpha (GTK_COLOR_CHOOSER (cc->chooser)) != g_value_get_boolean (value))
185 {
186 gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (cc->chooser), use_alpha: g_value_get_boolean (value));
187 g_object_notify_by_pspec (object, pspec);
188 }
189 break;
190 case PROP_SHOW_EDITOR:
191 g_object_set (object: cc->chooser,
192 first_property_name: "show-editor", g_value_get_boolean (value),
193 NULL);
194 break;
195 default:
196 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
197 break;
198 }
199}
200
201static void
202gtk_color_chooser_dialog_dispose (GObject *object)
203{
204 GtkColorChooserDialog *cc = GTK_COLOR_CHOOSER_DIALOG (object);
205
206 g_clear_pointer (&cc->chooser, gtk_widget_unparent);
207
208 G_OBJECT_CLASS (gtk_color_chooser_dialog_parent_class)->dispose (object);
209}
210
211static void
212gtk_color_chooser_dialog_class_init (GtkColorChooserDialogClass *class)
213{
214 GObjectClass *object_class = G_OBJECT_CLASS (class);
215 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
216
217 object_class->dispose = gtk_color_chooser_dialog_dispose;
218 object_class->get_property = gtk_color_chooser_dialog_get_property;
219 object_class->set_property = gtk_color_chooser_dialog_set_property;
220
221 widget_class->unmap = gtk_color_chooser_dialog_unmap;
222
223 g_object_class_override_property (oclass: object_class, property_id: PROP_RGBA, name: "rgba");
224 g_object_class_override_property (oclass: object_class, property_id: PROP_USE_ALPHA, name: "use-alpha");
225 g_object_class_install_property (oclass: object_class, property_id: PROP_SHOW_EDITOR,
226 pspec: g_param_spec_boolean (name: "show-editor", P_("Show editor"), P_("Show editor"),
227 FALSE, GTK_PARAM_READWRITE));
228
229 /* Bind class to template
230 */
231 gtk_widget_class_set_template_from_resource (widget_class,
232 resource_name: "/org/gtk/libgtk/ui/gtkcolorchooserdialog.ui");
233 gtk_widget_class_bind_template_child (widget_class, GtkColorChooserDialog, chooser);
234 gtk_widget_class_bind_template_callback (widget_class, propagate_notify);
235 gtk_widget_class_bind_template_callback (widget_class, color_activated_cb);
236}
237
238static void
239gtk_color_chooser_dialog_get_rgba (GtkColorChooser *chooser,
240 GdkRGBA *color)
241{
242 GtkColorChooserDialog *cc = GTK_COLOR_CHOOSER_DIALOG (chooser);
243
244 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (cc->chooser), color);
245}
246
247static void
248gtk_color_chooser_dialog_set_rgba (GtkColorChooser *chooser,
249 const GdkRGBA *color)
250{
251 GtkColorChooserDialog *cc = GTK_COLOR_CHOOSER_DIALOG (chooser);
252
253 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (cc->chooser), color);
254}
255
256static void
257gtk_color_chooser_dialog_add_palette (GtkColorChooser *chooser,
258 GtkOrientation orientation,
259 int colors_per_line,
260 int n_colors,
261 GdkRGBA *colors)
262{
263 GtkColorChooserDialog *cc = GTK_COLOR_CHOOSER_DIALOG (chooser);
264
265 gtk_color_chooser_add_palette (GTK_COLOR_CHOOSER (cc->chooser),
266 orientation, colors_per_line, n_colors, colors);
267}
268
269static void
270gtk_color_chooser_dialog_iface_init (GtkColorChooserInterface *iface)
271{
272 iface->get_rgba = gtk_color_chooser_dialog_get_rgba;
273 iface->set_rgba = gtk_color_chooser_dialog_set_rgba;
274 iface->add_palette = gtk_color_chooser_dialog_add_palette;
275}
276
277/**
278 * gtk_color_chooser_dialog_new:
279 * @title: (nullable): Title of the dialog
280 * @parent: (nullable): Transient parent of the dialog
281 *
282 * Creates a new `GtkColorChooserDialog`.
283 *
284 * Returns: a new `GtkColorChooserDialog`
285 */
286GtkWidget *
287gtk_color_chooser_dialog_new (const char *title,
288 GtkWindow *parent)
289{
290 return g_object_new (GTK_TYPE_COLOR_CHOOSER_DIALOG,
291 first_property_name: "title", title,
292 "transient-for", parent,
293 NULL);
294}
295

source code of gtk/gtk/gtkcolorchooserdialog.c