1 /*
2 * GTK - The GIMP Toolkit
3 * Copyright (C) 1998, 1999 Red Hat, Inc.
4 * All rights reserved.
5 *
6 * This Library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with the Gnome Library; see the file COPYING.LIB. If not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21 /* Color picker button for GNOME
22 *
23 * Author: Federico Mena <federico@nuclecu.unam.mx>
24 *
25 * Modified by the GTK+ Team and others 2003. See the AUTHORS
26 * file for a list of people on the GTK+ Team. See the ChangeLog
27 * files for a list of changes. These files are distributed with
28 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 */
30
31 #include "config.h"
32
33 #include "gtkcolorbutton.h"
34 #include "gdk/gdkkeysyms.h"
35 #include "gdk-pixbuf/gdk-pixbuf.h"
36 #include "gtkbutton.h"
37 #include "gtkmain.h"
38 #include "gtkalignment.h"
39 #include "gtkcolorsel.h"
40 #include "gtkcolorseldialog.h"
41 #include "gtkdnd.h"
42 #include "gtkdrawingarea.h"
43 #include "gtkframe.h"
44 #include "gtkmarshalers.h"
45 #include "gtkprivate.h"
46 #include "gtkintl.h"
47 #include "gtkalias.h"
48
49 /* Size of checks and gray levels for alpha compositing checkerboard */
50 #define CHECK_SIZE 4
51 #define CHECK_DARK (1.0 / 3.0)
52 #define CHECK_LIGHT (2.0 / 3.0)
53
54 #define GTK_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_COLOR_BUTTON, GtkColorButtonPrivate))
55
56 struct _GtkColorButtonPrivate
57 {
58 GtkWidget *draw_area; /* Widget where we draw the color sample */
59 GtkWidget *cs_dialog; /* Color selection dialog */
60
61 gchar *title; /* Title for the color selection window */
62
63 GdkColor color;
64 guint16 alpha;
65
66 guint use_alpha : 1; /* Use alpha or not */
67 };
68
69 /* Properties */
70 enum
71 {
72 PROP_0,
73 PROP_USE_ALPHA,
74 PROP_TITLE,
75 PROP_COLOR,
76 PROP_ALPHA
77 };
78
79 /* Signals */
80 enum
81 {
82 COLOR_SET,
83 LAST_SIGNAL
84 };
85
86 /* gobject signals */
87 static void gtk_color_button_finalize (GObject *object);
88 static void gtk_color_button_set_property (GObject *object,
89 guint param_id,
90 const GValue *value,
91 GParamSpec *pspec);
92 static void gtk_color_button_get_property (GObject *object,
93 guint param_id,
94 GValue *value,
95 GParamSpec *pspec);
96
97 /* gtkwidget signals */
98 static void gtk_color_button_state_changed (GtkWidget *widget,
99 GtkStateType previous_state);
100
101 /* gtkbutton signals */
102 static void gtk_color_button_clicked (GtkButton *button);
103
104 /* source side drag signals */
105 static void gtk_color_button_drag_begin (GtkWidget *widget,
106 GdkDragContext *context,
107 gpointer data);
108 static void gtk_color_button_drag_data_get (GtkWidget *widget,
109 GdkDragContext *context,
110 GtkSelectionData *selection_data,
111 guint info,
112 guint time,
113 GtkColorButton *color_button);
114
115 /* target side drag signals */
116 static void gtk_color_button_drag_data_received (GtkWidget *widget,
117 GdkDragContext *context,
118 gint x,
119 gint y,
120 GtkSelectionData *selection_data,
121 guint info,
122 guint32 time,
123 GtkColorButton *color_button);
124
125
126 static guint color_button_signals[LAST_SIGNAL] = { 0 };
127
128 static const GtkTargetEntry drop_types[] = { { "application/x-color", 0, 0 } };
129
G_DEFINE_TYPE(GtkColorButton,gtk_color_button,GTK_TYPE_BUTTON)130 G_DEFINE_TYPE (GtkColorButton, gtk_color_button, GTK_TYPE_BUTTON)
131
132 static void
133 gtk_color_button_class_init (GtkColorButtonClass *klass)
134 {
135 GObjectClass *gobject_class;
136 GtkWidgetClass *widget_class;
137 GtkButtonClass *button_class;
138
139 gobject_class = G_OBJECT_CLASS (klass);
140 widget_class = GTK_WIDGET_CLASS (klass);
141 button_class = GTK_BUTTON_CLASS (klass);
142
143 gobject_class->get_property = gtk_color_button_get_property;
144 gobject_class->set_property = gtk_color_button_set_property;
145 gobject_class->finalize = gtk_color_button_finalize;
146 widget_class->state_changed = gtk_color_button_state_changed;
147 button_class->clicked = gtk_color_button_clicked;
148 klass->color_set = NULL;
149
150 /**
151 * GtkColorButton:use-alpha:
152 *
153 * If this property is set to %TRUE, the color swatch on the button is rendered against a
154 * checkerboard background to show its opacity and the opacity slider is displayed in the
155 * color selection dialog.
156 *
157 * Since: 2.4
158 */
159 g_object_class_install_property (gobject_class,
160 PROP_USE_ALPHA,
161 g_param_spec_boolean ("use-alpha", P_("Use alpha"),
162 P_("Whether or not to give the color an alpha value"),
163 FALSE,
164 GTK_PARAM_READWRITE));
165
166 /**
167 * GtkColorButton:title:
168 *
169 * The title of the color selection dialog
170 *
171 * Since: 2.4
172 */
173 g_object_class_install_property (gobject_class,
174 PROP_TITLE,
175 g_param_spec_string ("title",
176 P_("Title"),
177 P_("The title of the color selection dialog"),
178 _("Pick a Color"),
179 GTK_PARAM_READWRITE));
180
181 /**
182 * GtkColorButton:color:
183 *
184 * The selected color.
185 *
186 * Since: 2.4
187 */
188 g_object_class_install_property (gobject_class,
189 PROP_COLOR,
190 g_param_spec_boxed ("color",
191 P_("Current Color"),
192 P_("The selected color"),
193 GDK_TYPE_COLOR,
194 GTK_PARAM_READWRITE));
195
196 /**
197 * GtkColorButton:alpha:
198 *
199 * The selected opacity value (0 fully transparent, 65535 fully opaque).
200 *
201 * Since: 2.4
202 */
203 g_object_class_install_property (gobject_class,
204 PROP_ALPHA,
205 g_param_spec_uint ("alpha",
206 P_("Current Alpha"),
207 P_("The selected opacity value (0 fully transparent, 65535 fully opaque)"),
208 0, 65535, 65535,
209 GTK_PARAM_READWRITE));
210
211 /**
212 * GtkColorButton::color-set:
213 * @widget: the object which received the signal.
214 *
215 * The ::color-set signal is emitted when the user selects a color.
216 * When handling this signal, use gtk_color_button_get_color() and
217 * gtk_color_button_get_alpha() to find out which color was just selected.
218 *
219 * Note that this signal is only emitted when the <emphasis>user</emphasis>
220 * changes the color. If you need to react to programmatic color changes
221 * as well, use the notify::color signal.
222 *
223 * Since: 2.4
224 */
225 color_button_signals[COLOR_SET] = g_signal_new (I_("color-set"),
226 G_TYPE_FROM_CLASS (gobject_class),
227 G_SIGNAL_RUN_FIRST,
228 G_STRUCT_OFFSET (GtkColorButtonClass, color_set),
229 NULL, NULL,
230 _gtk_marshal_VOID__VOID,
231 G_TYPE_NONE, 0);
232
233 g_type_class_add_private (gobject_class, sizeof (GtkColorButtonPrivate));
234 }
235
236 static gboolean
gtk_color_button_has_alpha(GtkColorButton * color_button)237 gtk_color_button_has_alpha (GtkColorButton *color_button)
238 {
239 return color_button->priv->use_alpha &&
240 color_button->priv->alpha < 65535;
241 }
242
243 static cairo_pattern_t *
gtk_color_button_get_checkered(void)244 gtk_color_button_get_checkered (void)
245 {
246 /* need to respect pixman's stride being a multiple of 4 */
247 static unsigned char data[8] = { 0xFF, 0x00, 0x00, 0x00,
248 0x00, 0xFF, 0x00, 0x00 };
249 static cairo_surface_t *checkered = NULL;
250 cairo_pattern_t *pattern;
251
252 if (checkered == NULL)
253 {
254 checkered = cairo_image_surface_create_for_data (data,
255 CAIRO_FORMAT_A8,
256 2, 2, 4);
257 }
258
259 pattern = cairo_pattern_create_for_surface (checkered);
260 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
261 cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
262
263 return pattern;
264 }
265
266 /* Handle exposure events for the color picker's drawing area */
267 static gint
expose_event(GtkWidget * widget,GdkEventExpose * event,gpointer data)268 expose_event (GtkWidget *widget,
269 GdkEventExpose *event,
270 gpointer data)
271 {
272 GtkColorButton *color_button = GTK_COLOR_BUTTON (data);
273 GtkAllocation allocation;
274 cairo_pattern_t *checkered;
275 cairo_t *cr;
276
277 cr = gdk_cairo_create (event->window);
278
279 gtk_widget_get_allocation (widget, &allocation);
280 gdk_cairo_rectangle (cr, &allocation);
281 cairo_clip (cr);
282
283 if (gtk_color_button_has_alpha (color_button))
284 {
285 cairo_save (cr);
286
287 cairo_set_source_rgb (cr, CHECK_DARK, CHECK_DARK, CHECK_DARK);
288 cairo_paint (cr);
289
290 cairo_set_source_rgb (cr, CHECK_LIGHT, CHECK_LIGHT, CHECK_LIGHT);
291 cairo_scale (cr, CHECK_SIZE, CHECK_SIZE);
292
293 checkered = gtk_color_button_get_checkered ();
294 cairo_mask (cr, checkered);
295 cairo_pattern_destroy (checkered);
296
297 cairo_restore (cr);
298
299 cairo_set_source_rgba (cr,
300 color_button->priv->color.red / 65535.,
301 color_button->priv->color.green / 65535.,
302 color_button->priv->color.blue / 65535.,
303 color_button->priv->alpha / 65535.);
304 }
305 else
306 {
307 gdk_cairo_set_source_color (cr, &color_button->priv->color);
308 }
309
310 cairo_paint (cr);
311
312 if (!gtk_widget_is_sensitive (GTK_WIDGET (color_button)))
313 {
314 gdk_cairo_set_source_color (cr, >K_WIDGET(color_button)->style->bg[GTK_STATE_INSENSITIVE]);
315 checkered = gtk_color_button_get_checkered ();
316 cairo_mask (cr, checkered);
317 cairo_pattern_destroy (checkered);
318 }
319
320 cairo_destroy (cr);
321
322 return FALSE;
323 }
324
325 static void
gtk_color_button_state_changed(GtkWidget * widget,GtkStateType previous_state)326 gtk_color_button_state_changed (GtkWidget *widget,
327 GtkStateType previous_state)
328 {
329 gtk_widget_queue_draw (widget);
330 }
331
332 static void
gtk_color_button_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * selection_data,guint info,guint32 time,GtkColorButton * color_button)333 gtk_color_button_drag_data_received (GtkWidget *widget,
334 GdkDragContext *context,
335 gint x,
336 gint y,
337 GtkSelectionData *selection_data,
338 guint info,
339 guint32 time,
340 GtkColorButton *color_button)
341 {
342 guint16 *dropped;
343
344 if (selection_data->length < 0)
345 return;
346
347 /* We accept drops with the wrong format, since the KDE color
348 * chooser incorrectly drops application/x-color with format 8.
349 */
350 if (selection_data->length != 8)
351 {
352 g_warning (_("Received invalid color data\n"));
353 return;
354 }
355
356
357 dropped = (guint16 *)selection_data->data;
358
359 color_button->priv->color.red = dropped[0];
360 color_button->priv->color.green = dropped[1];
361 color_button->priv->color.blue = dropped[2];
362 color_button->priv->alpha = dropped[3];
363
364 gtk_widget_queue_draw (color_button->priv->draw_area);
365
366 g_signal_emit (color_button, color_button_signals[COLOR_SET], 0);
367
368 g_object_freeze_notify (G_OBJECT (color_button));
369 g_object_notify (G_OBJECT (color_button), "color");
370 g_object_notify (G_OBJECT (color_button), "alpha");
371 g_object_thaw_notify (G_OBJECT (color_button));
372 }
373
374 static void
set_color_icon(GdkDragContext * context,GdkColor * color)375 set_color_icon (GdkDragContext *context,
376 GdkColor *color)
377 {
378 GdkPixbuf *pixbuf;
379 guint32 pixel;
380
381 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
382 8, 48, 32);
383
384 pixel = ((color->red & 0xff00) << 16) |
385 ((color->green & 0xff00) << 8) |
386 (color->blue & 0xff00);
387
388 gdk_pixbuf_fill (pixbuf, pixel);
389
390 gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
391 g_object_unref (pixbuf);
392 }
393
394 static void
gtk_color_button_drag_begin(GtkWidget * widget,GdkDragContext * context,gpointer data)395 gtk_color_button_drag_begin (GtkWidget *widget,
396 GdkDragContext *context,
397 gpointer data)
398 {
399 GtkColorButton *color_button = data;
400
401 set_color_icon (context, &color_button->priv->color);
402 }
403
404 static void
gtk_color_button_drag_data_get(GtkWidget * widget,GdkDragContext * context,GtkSelectionData * selection_data,guint info,guint time,GtkColorButton * color_button)405 gtk_color_button_drag_data_get (GtkWidget *widget,
406 GdkDragContext *context,
407 GtkSelectionData *selection_data,
408 guint info,
409 guint time,
410 GtkColorButton *color_button)
411 {
412 guint16 dropped[4];
413
414 dropped[0] = color_button->priv->color.red;
415 dropped[1] = color_button->priv->color.green;
416 dropped[2] = color_button->priv->color.blue;
417 dropped[3] = color_button->priv->alpha;
418
419 gtk_selection_data_set (selection_data, selection_data->target,
420 16, (guchar *)dropped, 8);
421 }
422
423 static void
gtk_color_button_init(GtkColorButton * color_button)424 gtk_color_button_init (GtkColorButton *color_button)
425 {
426 GtkWidget *alignment;
427 GtkWidget *frame;
428 PangoLayout *layout;
429 PangoRectangle rect;
430
431 /* Create the widgets */
432 color_button->priv = GTK_COLOR_BUTTON_GET_PRIVATE (color_button);
433
434 gtk_widget_push_composite_child ();
435
436 alignment = gtk_alignment_new (0.5, 0.5, 0.5, 1.0);
437 gtk_container_set_border_width (GTK_CONTAINER (alignment), 1);
438 gtk_container_add (GTK_CONTAINER (color_button), alignment);
439 gtk_widget_show (alignment);
440
441 frame = gtk_frame_new (NULL);
442 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
443 gtk_container_add (GTK_CONTAINER (alignment), frame);
444 gtk_widget_show (frame);
445
446 /* Just some widget we can hook to expose-event on */
447 color_button->priv->draw_area = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
448
449 layout = gtk_widget_create_pango_layout (GTK_WIDGET (color_button), "Black");
450 pango_layout_get_pixel_extents (layout, NULL, &rect);
451 g_object_unref (layout);
452
453 gtk_widget_set_size_request (color_button->priv->draw_area, rect.width - 2, rect.height - 2);
454 g_signal_connect (color_button->priv->draw_area, "expose-event",
455 G_CALLBACK (expose_event), color_button);
456 gtk_container_add (GTK_CONTAINER (frame), color_button->priv->draw_area);
457 gtk_widget_show (color_button->priv->draw_area);
458
459 color_button->priv->title = g_strdup (_("Pick a Color")); /* default title */
460
461 /* Start with opaque black, alpha disabled */
462
463 color_button->priv->color.red = 0;
464 color_button->priv->color.green = 0;
465 color_button->priv->color.blue = 0;
466 color_button->priv->alpha = 65535;
467 color_button->priv->use_alpha = FALSE;
468
469 gtk_drag_dest_set (GTK_WIDGET (color_button),
470 GTK_DEST_DEFAULT_MOTION |
471 GTK_DEST_DEFAULT_HIGHLIGHT |
472 GTK_DEST_DEFAULT_DROP,
473 drop_types, 1, GDK_ACTION_COPY);
474 gtk_drag_source_set (GTK_WIDGET(color_button),
475 GDK_BUTTON1_MASK|GDK_BUTTON3_MASK,
476 drop_types, 1,
477 GDK_ACTION_COPY);
478 g_signal_connect (color_button, "drag-begin",
479 G_CALLBACK (gtk_color_button_drag_begin), color_button);
480 g_signal_connect (color_button, "drag-data-received",
481 G_CALLBACK (gtk_color_button_drag_data_received), color_button);
482 g_signal_connect (color_button, "drag-data-get",
483 G_CALLBACK (gtk_color_button_drag_data_get), color_button);
484
485 gtk_widget_pop_composite_child ();
486 }
487
488 static void
gtk_color_button_finalize(GObject * object)489 gtk_color_button_finalize (GObject *object)
490 {
491 GtkColorButton *color_button = GTK_COLOR_BUTTON (object);
492
493 if (color_button->priv->cs_dialog != NULL)
494 gtk_widget_destroy (color_button->priv->cs_dialog);
495 color_button->priv->cs_dialog = NULL;
496
497 g_free (color_button->priv->title);
498 color_button->priv->title = NULL;
499
500 G_OBJECT_CLASS (gtk_color_button_parent_class)->finalize (object);
501 }
502
503
504 /**
505 * gtk_color_button_new:
506 *
507 * Creates a new color button. This returns a widget in the form of
508 * a small button containing a swatch representing the current selected
509 * color. When the button is clicked, a color-selection dialog will open,
510 * allowing the user to select a color. The swatch will be updated to reflect
511 * the new color when the user finishes.
512 *
513 * Returns: a new color button.
514 *
515 * Since: 2.4
516 */
517 GtkWidget *
gtk_color_button_new(void)518 gtk_color_button_new (void)
519 {
520 return g_object_new (GTK_TYPE_COLOR_BUTTON, NULL);
521 }
522
523 /**
524 * gtk_color_button_new_with_color:
525 * @color: A #GdkColor to set the current color with.
526 *
527 * Creates a new color button.
528 *
529 * Returns: a new color button.
530 *
531 * Since: 2.4
532 */
533 GtkWidget *
gtk_color_button_new_with_color(const GdkColor * color)534 gtk_color_button_new_with_color (const GdkColor *color)
535 {
536 return g_object_new (GTK_TYPE_COLOR_BUTTON, "color", color, NULL);
537 }
538
539 static void
dialog_ok_clicked(GtkWidget * widget,gpointer data)540 dialog_ok_clicked (GtkWidget *widget,
541 gpointer data)
542 {
543 GtkColorButton *color_button = GTK_COLOR_BUTTON (data);
544 GtkColorSelection *color_selection;
545
546 color_selection = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (color_button->priv->cs_dialog)->colorsel);
547
548 gtk_color_selection_get_current_color (color_selection, &color_button->priv->color);
549 color_button->priv->alpha = gtk_color_selection_get_current_alpha (color_selection);
550
551 gtk_widget_hide (color_button->priv->cs_dialog);
552
553 gtk_widget_queue_draw (color_button->priv->draw_area);
554
555 g_signal_emit (color_button, color_button_signals[COLOR_SET], 0);
556
557 g_object_freeze_notify (G_OBJECT (color_button));
558 g_object_notify (G_OBJECT (color_button), "color");
559 g_object_notify (G_OBJECT (color_button), "alpha");
560 g_object_thaw_notify (G_OBJECT (color_button));
561 }
562
563 static gboolean
dialog_destroy(GtkWidget * widget,gpointer data)564 dialog_destroy (GtkWidget *widget,
565 gpointer data)
566 {
567 GtkColorButton *color_button = GTK_COLOR_BUTTON (data);
568
569 color_button->priv->cs_dialog = NULL;
570
571 return FALSE;
572 }
573
574 static void
dialog_cancel_clicked(GtkWidget * widget,gpointer data)575 dialog_cancel_clicked (GtkWidget *widget,
576 gpointer data)
577 {
578 GtkColorButton *color_button = GTK_COLOR_BUTTON (data);
579
580 gtk_widget_hide (color_button->priv->cs_dialog);
581 }
582
583 static void
gtk_color_button_clicked(GtkButton * button)584 gtk_color_button_clicked (GtkButton *button)
585 {
586 GtkColorButton *color_button = GTK_COLOR_BUTTON (button);
587 GtkColorSelectionDialog *color_dialog;
588
589 /* if dialog already exists, make sure it's shown and raised */
590 if (!color_button->priv->cs_dialog)
591 {
592 /* Create the dialog and connects its buttons */
593 GtkWidget *parent;
594
595 parent = gtk_widget_get_toplevel (GTK_WIDGET (color_button));
596
597 color_button->priv->cs_dialog = gtk_color_selection_dialog_new (color_button->priv->title);
598
599 color_dialog = GTK_COLOR_SELECTION_DIALOG (color_button->priv->cs_dialog);
600
601 if (gtk_widget_is_toplevel (parent) && GTK_IS_WINDOW (parent))
602 {
603 if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (color_dialog)))
604 gtk_window_set_transient_for (GTK_WINDOW (color_dialog), GTK_WINDOW (parent));
605
606 gtk_window_set_modal (GTK_WINDOW (color_dialog),
607 gtk_window_get_modal (GTK_WINDOW (parent)));
608 }
609
610 g_signal_connect (color_dialog->ok_button, "clicked",
611 G_CALLBACK (dialog_ok_clicked), color_button);
612 g_signal_connect (color_dialog->cancel_button, "clicked",
613 G_CALLBACK (dialog_cancel_clicked), color_button);
614 g_signal_connect (color_dialog, "destroy",
615 G_CALLBACK (dialog_destroy), color_button);
616 }
617
618 color_dialog = GTK_COLOR_SELECTION_DIALOG (color_button->priv->cs_dialog);
619
620 gtk_color_selection_set_has_opacity_control (GTK_COLOR_SELECTION (color_dialog->colorsel),
621 color_button->priv->use_alpha);
622
623 gtk_color_selection_set_previous_color (GTK_COLOR_SELECTION (color_dialog->colorsel),
624 &color_button->priv->color);
625 gtk_color_selection_set_previous_alpha (GTK_COLOR_SELECTION (color_dialog->colorsel),
626 color_button->priv->alpha);
627
628 gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (color_dialog->colorsel),
629 &color_button->priv->color);
630 gtk_color_selection_set_current_alpha (GTK_COLOR_SELECTION (color_dialog->colorsel),
631 color_button->priv->alpha);
632
633 gtk_window_present (GTK_WINDOW (color_button->priv->cs_dialog));
634 }
635
636 /**
637 * gtk_color_button_set_color:
638 * @color_button: a #GtkColorButton.
639 * @color: A #GdkColor to set the current color with.
640 *
641 * Sets the current color to be @color.
642 *
643 * Since: 2.4
644 **/
645 void
gtk_color_button_set_color(GtkColorButton * color_button,const GdkColor * color)646 gtk_color_button_set_color (GtkColorButton *color_button,
647 const GdkColor *color)
648 {
649 g_return_if_fail (GTK_IS_COLOR_BUTTON (color_button));
650 g_return_if_fail (color != NULL);
651
652 color_button->priv->color.red = color->red;
653 color_button->priv->color.green = color->green;
654 color_button->priv->color.blue = color->blue;
655
656 gtk_widget_queue_draw (color_button->priv->draw_area);
657
658 g_object_notify (G_OBJECT (color_button), "color");
659 }
660
661
662 /**
663 * gtk_color_button_set_alpha:
664 * @color_button: a #GtkColorButton.
665 * @alpha: an integer between 0 and 65535.
666 *
667 * Sets the current opacity to be @alpha.
668 *
669 * Since: 2.4
670 **/
671 void
gtk_color_button_set_alpha(GtkColorButton * color_button,guint16 alpha)672 gtk_color_button_set_alpha (GtkColorButton *color_button,
673 guint16 alpha)
674 {
675 g_return_if_fail (GTK_IS_COLOR_BUTTON (color_button));
676
677 color_button->priv->alpha = alpha;
678
679 gtk_widget_queue_draw (color_button->priv->draw_area);
680
681 g_object_notify (G_OBJECT (color_button), "alpha");
682 }
683
684 /**
685 * gtk_color_button_get_color:
686 * @color_button: a #GtkColorButton.
687 * @color: (out): a #GdkColor to fill in with the current color.
688 *
689 * Sets @color to be the current color in the #GtkColorButton widget.
690 *
691 * Since: 2.4
692 **/
693 void
gtk_color_button_get_color(GtkColorButton * color_button,GdkColor * color)694 gtk_color_button_get_color (GtkColorButton *color_button,
695 GdkColor *color)
696 {
697 g_return_if_fail (GTK_IS_COLOR_BUTTON (color_button));
698
699 color->red = color_button->priv->color.red;
700 color->green = color_button->priv->color.green;
701 color->blue = color_button->priv->color.blue;
702 }
703
704 /**
705 * gtk_color_button_get_alpha:
706 * @color_button: a #GtkColorButton.
707 *
708 * Returns the current alpha value.
709 *
710 * Return value: an integer between 0 and 65535.
711 *
712 * Since: 2.4
713 **/
714 guint16
gtk_color_button_get_alpha(GtkColorButton * color_button)715 gtk_color_button_get_alpha (GtkColorButton *color_button)
716 {
717 g_return_val_if_fail (GTK_IS_COLOR_BUTTON (color_button), 0);
718
719 return color_button->priv->alpha;
720 }
721
722 /**
723 * gtk_color_button_set_use_alpha:
724 * @color_button: a #GtkColorButton.
725 * @use_alpha: %TRUE if color button should use alpha channel, %FALSE if not.
726 *
727 * Sets whether or not the color button should use the alpha channel.
728 *
729 * Since: 2.4
730 */
731 void
gtk_color_button_set_use_alpha(GtkColorButton * color_button,gboolean use_alpha)732 gtk_color_button_set_use_alpha (GtkColorButton *color_button,
733 gboolean use_alpha)
734 {
735 g_return_if_fail (GTK_IS_COLOR_BUTTON (color_button));
736
737 use_alpha = (use_alpha != FALSE);
738
739 if (color_button->priv->use_alpha != use_alpha)
740 {
741 color_button->priv->use_alpha = use_alpha;
742
743 gtk_widget_queue_draw (color_button->priv->draw_area);
744
745 g_object_notify (G_OBJECT (color_button), "use-alpha");
746 }
747 }
748
749 /**
750 * gtk_color_button_get_use_alpha:
751 * @color_button: a #GtkColorButton.
752 *
753 * Does the color selection dialog use the alpha channel?
754 *
755 * Returns: %TRUE if the color sample uses alpha channel, %FALSE if not.
756 *
757 * Since: 2.4
758 */
759 gboolean
gtk_color_button_get_use_alpha(GtkColorButton * color_button)760 gtk_color_button_get_use_alpha (GtkColorButton *color_button)
761 {
762 g_return_val_if_fail (GTK_IS_COLOR_BUTTON (color_button), FALSE);
763
764 return color_button->priv->use_alpha;
765 }
766
767
768 /**
769 * gtk_color_button_set_title:
770 * @color_button: a #GtkColorButton
771 * @title: String containing new window title.
772 *
773 * Sets the title for the color selection dialog.
774 *
775 * Since: 2.4
776 */
777 void
gtk_color_button_set_title(GtkColorButton * color_button,const gchar * title)778 gtk_color_button_set_title (GtkColorButton *color_button,
779 const gchar *title)
780 {
781 gchar *old_title;
782
783 g_return_if_fail (GTK_IS_COLOR_BUTTON (color_button));
784
785 old_title = color_button->priv->title;
786 color_button->priv->title = g_strdup (title);
787 g_free (old_title);
788
789 if (color_button->priv->cs_dialog)
790 gtk_window_set_title (GTK_WINDOW (color_button->priv->cs_dialog),
791 color_button->priv->title);
792
793 g_object_notify (G_OBJECT (color_button), "title");
794 }
795
796 /**
797 * gtk_color_button_get_title:
798 * @color_button: a #GtkColorButton
799 *
800 * Gets the title of the color selection dialog.
801 *
802 * Returns: An internal string, do not free the return value
803 *
804 * Since: 2.4
805 */
806 const gchar *
gtk_color_button_get_title(GtkColorButton * color_button)807 gtk_color_button_get_title (GtkColorButton *color_button)
808 {
809 g_return_val_if_fail (GTK_IS_COLOR_BUTTON (color_button), NULL);
810
811 return color_button->priv->title;
812 }
813
814 static void
gtk_color_button_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)815 gtk_color_button_set_property (GObject *object,
816 guint param_id,
817 const GValue *value,
818 GParamSpec *pspec)
819 {
820 GtkColorButton *color_button = GTK_COLOR_BUTTON (object);
821
822 switch (param_id)
823 {
824 case PROP_USE_ALPHA:
825 gtk_color_button_set_use_alpha (color_button, g_value_get_boolean (value));
826 break;
827 case PROP_TITLE:
828 gtk_color_button_set_title (color_button, g_value_get_string (value));
829 break;
830 case PROP_COLOR:
831 gtk_color_button_set_color (color_button, g_value_get_boxed (value));
832 break;
833 case PROP_ALPHA:
834 gtk_color_button_set_alpha (color_button, g_value_get_uint (value));
835 break;
836 default:
837 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
838 break;
839 }
840 }
841
842 static void
gtk_color_button_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)843 gtk_color_button_get_property (GObject *object,
844 guint param_id,
845 GValue *value,
846 GParamSpec *pspec)
847 {
848 GtkColorButton *color_button = GTK_COLOR_BUTTON (object);
849 GdkColor color;
850
851 switch (param_id)
852 {
853 case PROP_USE_ALPHA:
854 g_value_set_boolean (value, gtk_color_button_get_use_alpha (color_button));
855 break;
856 case PROP_TITLE:
857 g_value_set_string (value, gtk_color_button_get_title (color_button));
858 break;
859 case PROP_COLOR:
860 gtk_color_button_get_color (color_button, &color);
861 g_value_set_boxed (value, &color);
862 break;
863 case PROP_ALPHA:
864 g_value_set_uint (value, gtk_color_button_get_alpha (color_button));
865 break;
866 default:
867 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
868 break;
869 }
870 }
871
872 #define __GTK_COLOR_BUTTON_C__
873 #include "gtkaliasdef.c"
874