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 | |
49 | typedef struct _GtkColorChooserDialogClass GtkColorChooserDialogClass; |
50 | |
51 | struct _GtkColorChooserDialog |
52 | { |
53 | GtkDialog parent_instance; |
54 | |
55 | GtkWidget *chooser; |
56 | }; |
57 | |
58 | struct _GtkColorChooserDialogClass |
59 | { |
60 | GtkDialogClass parent_class; |
61 | }; |
62 | |
63 | enum |
64 | { |
65 | PROP_ZERO, |
66 | PROP_RGBA, |
67 | PROP_USE_ALPHA, |
68 | PROP_SHOW_EDITOR |
69 | }; |
70 | |
71 | static void gtk_color_chooser_dialog_iface_init (GtkColorChooserInterface *iface); |
72 | |
73 | G_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 | |
77 | static void |
78 | propagate_notify (GObject *o, |
79 | GParamSpec *pspec, |
80 | GtkColorChooserDialog *cc) |
81 | { |
82 | g_object_notify (G_OBJECT (cc), property_name: pspec->name); |
83 | } |
84 | |
85 | static void |
86 | save_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 | |
97 | static void |
98 | color_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 | |
106 | static void |
107 | gtk_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 | |
115 | static void |
116 | gtk_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 | |
125 | static void |
126 | gtk_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 | |
136 | static void |
137 | gtk_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 | |
170 | static void |
171 | gtk_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 | |
201 | static void |
202 | gtk_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 | |
211 | static void |
212 | gtk_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 | |
238 | static void |
239 | gtk_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 | |
247 | static void |
248 | gtk_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 | |
256 | static void |
257 | gtk_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 | |
269 | static void |
270 | gtk_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 | */ |
286 | GtkWidget * |
287 | gtk_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 | |