1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2000 Red Hat, Inc.
3 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include "gdkconfig.h"
30 #if defined (GDK_WINDOWING_X11)
33 #include "gdk/gdkkeysyms.h"
34 #include "gtkcolorsel.h"
36 #include "gtkwindow.h"
37 #include "gtkselection.h"
39 #include "gtkdrawingarea.h"
40 #include "gtksignal.h"
47 #include "gtkpixmap.h"
48 #include "gtkspinbutton.h"
50 #include "gtkhscale.h"
52 #include "gtkbutton.h"
53 #include "gtkhseparator.h"
74 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
76 struct _ColorSelectionPrivate
78 guint use_opacity : 1;
79 guint use_palette : 1;
81 guint default_set : 1;
83 /* The color dropper */
84 guint moving_dropper : 1;
86 gdouble color[COLORSEL_NUM_CHANNELS];
87 gdouble old_color[COLORSEL_NUM_CHANNELS];
89 GtkWidget *triangle_colorsel;
90 GtkWidget *hue_spinbutton;
91 GtkWidget *sat_spinbutton;
92 GtkWidget *val_spinbutton;
93 GtkWidget *red_spinbutton;
94 GtkWidget *green_spinbutton;
95 GtkWidget *blue_spinbutton;
96 GtkWidget *opacity_slider;
97 GtkWidget *opacity_label;
98 GtkWidget *opacity_entry;
99 GtkWidget *palette_frame;
100 GtkWidget *hex_entry;
102 /* The Palette code */
103 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
104 GtkWidget *last_palette;
106 /* The color_sample stuff */
107 GtkWidget *sample_area;
108 GtkWidget *old_sample;
109 GtkWidget *cur_sample;
114 static void gtk_color_selection_init (GtkColorSelection *colorsel);
115 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
116 static void gtk_color_selection_destroy (GtkObject *object);
117 static void update_color (GtkColorSelection *colorsel);
119 static gpointer parent_class = NULL;
120 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
123 /* The cursor for the dropper */
124 #define DROPPER_WIDTH 17
125 #define DROPPER_HEIGHT 17
126 #define DROPPER_X_HOT 2
127 #define DROPPER_Y_HOT 16
130 static char dropper_bits[] = {
131 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
132 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
133 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
134 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
137 static char dropper_mask[] = {
138 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
139 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
140 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
141 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
144 static GdkCursor *picker_cursor = NULL;
148 static char *picker[] = {
149 /* columns rows colors chars-per-pixel */
160 "#########################",
161 "#########################",
162 "#########################",
163 "#########################",
164 "#########################",
165 "################# #####",
166 "################ ####",
167 "################ +###",
168 "############# +###",
169 "############## ++###",
170 "#############+@ +++####",
171 "############+@@@ +######",
172 "###########+@@@ + +######",
173 "##########+@@@ ++#+######",
174 "#########+@@@ ++#########",
175 "########+@@@ ++##########",
176 "#######+@@@ ++###########",
177 "######+@@@ ++############",
178 "######+@@ ++#############",
179 "#####+@ ++##############",
180 "###### +++###############",
181 "#########################",
182 "#########################",
183 "#########################",
184 "#########################"
193 #define SAMPLE_WIDTH 64
194 #define SAMPLE_HEIGHT 28
196 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
197 static void color_sample_draw_samples (GtkColorSelection *colorsel);
200 color_sample_drag_begin (GtkWidget *widget,
201 GdkDragContext *context,
204 GtkColorSelection *colorsel = data;
205 ColorSelectionPrivate *priv;
212 priv = colorsel->private_data;
213 window = gtk_window_new (GTK_WINDOW_POPUP);
214 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
215 gtk_widget_set_usize (window, 48, 32);
216 gtk_widget_realize (window);
217 gtk_object_set_data_full (GTK_OBJECT (widget),
218 "gtk-color-selection-drag-window",
220 (GtkDestroyNotify) gtk_widget_destroy);
222 if (widget == priv->old_sample)
223 colsrc = priv->old_color;
225 colsrc = priv->color;
227 for (i=0, n = COLORSEL_RED; n <= COLORSEL_BLUE; n++)
229 colors[i++] = colsrc[n];
232 if (priv->use_opacity)
234 colors[i] = colsrc[COLORSEL_OPACITY];
237 bg.red = 0xffff * colors[0];
238 bg.green = 0xffff * colors[1];
239 bg.blue = 0xffff * colors[2];
241 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
242 gdk_window_set_background (window->window, &bg);
244 gtk_drag_set_icon_widget (context, window, -2, -2);
248 color_sample_drag_end (GtkWidget *widget,
249 GdkDragContext *context,
252 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
256 color_sample_drop_handle (GtkWidget *widget,
257 GdkDragContext *context,
260 GtkSelectionData *selection_data,
265 GtkColorSelection *colorsel = data;
266 ColorSelectionPrivate *priv;
269 priv = colorsel->private_data;
271 /* This is currently a guint16 array of the format:
278 if (selection_data->length < 0)
281 if ((selection_data->format != 16) ||
282 (selection_data->length != 8))
284 g_warning ("Received invalid color data\n");
288 vals = (guint16 *)selection_data->data;
290 if (widget == priv->cur_sample)
292 color[0] = (gdouble)vals[0] / 0xffff;
293 color[1] = (gdouble)vals[1] / 0xffff;
294 color[2] = (gdouble)vals[2] / 0xffff;
295 color[3] = (gdouble)vals[3] / 0xffff;
297 gtk_color_selection_set_color (colorsel, color);
302 color_sample_drag_handle (GtkWidget *widget,
303 GdkDragContext *context,
304 GtkSelectionData *selection_data,
309 GtkColorSelection *colorsel = data;
310 ColorSelectionPrivate *priv;
314 priv = colorsel->private_data;
316 if (widget == priv->old_sample)
317 colsrc = priv->old_color;
319 colsrc = priv->color;
321 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
322 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
323 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
324 vals[3] = priv->use_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
326 gtk_selection_data_set (selection_data,
327 gdk_atom_intern ("application/x-color", FALSE),
328 16, (guchar *)vals, 8);
331 /* which = 0 means draw old sample, which = 1 means draw new */
333 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
336 gint x, y, i, wid, heig, f, n, goff;
337 guchar c[3 * 2], cc[3 * 4], *cp = c;
340 ColorSelectionPrivate *priv;
342 g_return_if_fail (colorsel != NULL);
343 priv = colorsel->private_data;
345 g_return_if_fail (priv->sample_area != NULL);
346 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
351 da = priv->old_sample;
352 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
353 c[n] = (guchar) (255.0 * priv->old_color[i]);
358 da = priv->cur_sample;
359 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
360 c[n] = (guchar) (255.0 * priv->color[i]);
361 goff = priv->old_sample->allocation.width % 32;
364 wid = da->allocation.width;
365 heig = da->allocation.height;
367 buf = g_new(guchar, 3 * wid * heig);
371 for (n = 0; n < 3; n++)
373 c[n] = (guchar) (255.0 * priv->old_color[i]);
374 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
378 if (priv->use_opacity)
380 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
382 for (n = 0; n < 3; n++)
384 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
385 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
391 for (y = 0; y < heig; y++)
393 for (x = 0; x < wid; x++)
395 if (priv->use_opacity)
396 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
400 for (n = 0; n < 3; n++)
401 buf[i++] = cp[n + f];
405 gdk_draw_rgb_image(da->window,
409 GDK_RGB_DITHER_NORMAL,
419 color_sample_draw_samples (GtkColorSelection *colorsel)
421 color_sample_draw_sample (colorsel, 0);
422 color_sample_draw_sample (colorsel, 1);
426 color_old_sample_expose(GtkWidget* da, GdkEventExpose* event, GtkColorSelection *colorsel)
428 color_sample_draw_sample (colorsel, 0);
433 color_cur_sample_expose(GtkWidget* da, GdkEventExpose* event, GtkColorSelection *colorsel)
435 color_sample_draw_sample (colorsel, 1);
439 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
441 static const GtkTargetEntry targets[] = {
442 { "application/x-color", 0 }
444 ColorSelectionPrivate *priv;
445 priv = colorsel->private_data;
447 gtk_drag_source_set (sample,
448 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
450 GDK_ACTION_COPY | GDK_ACTION_MOVE);
452 gtk_signal_connect (GTK_OBJECT (sample),
454 GTK_SIGNAL_FUNC (color_sample_drag_begin),
456 if (sample == priv->cur_sample)
459 gtk_drag_dest_set (sample,
460 GTK_DEST_DEFAULT_HIGHLIGHT |
461 GTK_DEST_DEFAULT_MOTION |
462 GTK_DEST_DEFAULT_DROP,
466 gtk_signal_connect (GTK_OBJECT (sample),
468 GTK_SIGNAL_FUNC (color_sample_drag_end),
472 gtk_signal_connect (GTK_OBJECT (sample),
474 GTK_SIGNAL_FUNC (color_sample_drag_handle),
476 gtk_signal_connect (GTK_OBJECT (sample),
477 "drag_data_received",
478 GTK_SIGNAL_FUNC (color_sample_drop_handle),
485 color_sample_new (GtkColorSelection *colorsel)
487 ColorSelectionPrivate *priv;
489 priv = colorsel->private_data;
491 priv->sample_area = gtk_hbox_new (FALSE, 0);
492 priv->old_sample = gtk_drawing_area_new ();
493 priv->cur_sample = gtk_drawing_area_new ();
495 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
497 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
500 gtk_signal_connect(GTK_OBJECT (priv->old_sample), "expose_event",
501 GTK_SIGNAL_FUNC (color_old_sample_expose),
503 gtk_signal_connect(GTK_OBJECT (priv->cur_sample), "expose_event",
504 GTK_SIGNAL_FUNC (color_cur_sample_expose),
507 color_sample_setup_dnd (colorsel, priv->old_sample);
508 color_sample_setup_dnd (colorsel, priv->cur_sample);
510 gtk_widget_show_all (priv->sample_area);
516 * The palette area code
519 #define CUSTOM_PALETTE_ENTRY_WIDTH 16
520 #define CUSTOM_PALETTE_ENTRY_HEIGHT 16
523 palette_get_color (GtkWidget *drawing_area, gdouble *color)
527 g_return_if_fail (color != NULL);
529 color_val = gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
530 if (color_val == NULL)
532 /* Default to white for no good reason */
540 color[0] = color_val[0];
541 color[1] = color_val[1];
542 color[2] = color_val[2];
546 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
548 palette_paint (GtkWidget *drawing_area,
552 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
553 ColorSelectionPrivate *priv = colorsel->private_data;
555 if (drawing_area->window == NULL)
558 gdk_window_clear_area (drawing_area->window,
564 if (priv->last_palette == drawing_area)
569 palette_get_color (drawing_area, color);
571 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
572 gc = drawing_area->style->black_gc;
574 gc = drawing_area->style->white_gc;
576 gdk_draw_rectangle (drawing_area->window,
578 drawing_area->allocation.width - 1,
579 drawing_area->allocation.height - 1);
584 palette_expose (GtkWidget *drawing_area,
585 GdkEventExpose *event,
588 if (drawing_area->window == NULL)
591 palette_paint (drawing_area, &(event->area), data);
595 palette_press (GtkWidget *drawing_area,
596 GdkEventButton *event,
599 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
600 ColorSelectionPrivate *priv = colorsel->private_data;
602 if (priv->last_palette != NULL)
603 gtk_widget_queue_clear (priv->last_palette);
605 priv->last_palette = drawing_area;
607 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0)
610 palette_get_color (drawing_area, color);
611 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
614 gtk_widget_queue_clear (priv->last_palette);
618 palette_draw (GtkWidget *drawing_area,
622 palette_paint (drawing_area, area, data);
626 palette_unset_color (GtkWidget *drawing_area)
628 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
631 gtk_widget_reset_rc_styles (drawing_area);
632 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0));
636 palette_drag_begin (GtkWidget *widget,
637 GdkDragContext *context,
640 GtkColorSelection *colorsel = data;
641 ColorSelectionPrivate *priv;
646 priv = colorsel->private_data;
647 window = gtk_window_new (GTK_WINDOW_POPUP);
648 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
649 gtk_widget_set_usize (window, 48, 32);
650 gtk_widget_realize (window);
651 gtk_object_set_data_full (GTK_OBJECT (widget),
652 "gtk-color-selection-drag-window",
654 (GtkDestroyNotify) gtk_widget_destroy);
656 palette_get_color (widget, colors);
657 bg.red = 0xffff * colors[0];
658 bg.green = 0xffff * colors[1];
659 bg.blue = 0xffff * colors[2];
661 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
662 gdk_window_set_background (window->window, &bg);
664 gtk_drag_set_icon_widget (context, window, -2, -2);
668 palette_drag_handle (GtkWidget *widget,
669 GdkDragContext *context,
670 GtkSelectionData *selection_data,
678 palette_get_color (widget, colsrc);
680 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
681 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
682 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
685 gtk_selection_data_set (selection_data,
686 gdk_atom_intern ("application/x-color", FALSE),
687 16, (guchar *)vals, 8);
691 palette_set_color (GtkWidget *drawing_area,
692 GtkColorSelection *colorsel,
695 GtkRcStyle *rc_style;
696 gdouble *new_color = g_new (double, 4);
699 rc_style = gtk_rc_style_new ();
700 rc_style->bg[GTK_STATE_NORMAL].red = color[0]*65535;
701 rc_style->bg[GTK_STATE_NORMAL].green = color[1]*65535;
702 rc_style->bg[GTK_STATE_NORMAL].blue = color[2]*65535;
703 rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
704 gtk_rc_style_ref (rc_style);
705 gtk_widget_modify_style (drawing_area, rc_style);
707 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
709 static const GtkTargetEntry targets[] = {
710 { "application/x-color", 0 }
712 gtk_drag_source_set (drawing_area,
713 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
715 GDK_ACTION_COPY | GDK_ACTION_MOVE);
717 gtk_signal_connect (GTK_OBJECT (drawing_area),
719 GTK_SIGNAL_FUNC (palette_drag_begin),
721 gtk_signal_connect (GTK_OBJECT (drawing_area),
723 GTK_SIGNAL_FUNC (palette_drag_handle),
726 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
730 old_color = (gdouble *) gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
736 new_color[0] = color[0];
737 new_color[1] = color[1];
738 new_color[2] = color[2];
741 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_val", new_color);
745 palette_drag_end (GtkWidget *widget,
746 GdkDragContext *context,
749 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
753 palette_drop_handle (GtkWidget *widget,
754 GdkDragContext *context,
757 GtkSelectionData *selection_data,
765 if (selection_data->length < 0)
768 if ((selection_data->format != 16) ||
769 (selection_data->length != 8))
771 g_warning ("Received invalid color data\n");
775 vals = (guint16 *)selection_data->data;
777 color[0] = (gdouble)vals[0] / 0xffff;
778 color[1] = (gdouble)vals[1] / 0xffff;
779 color[2] = (gdouble)vals[2] / 0xffff;
780 color[3] = (gdouble)vals[3] / 0xffff;
781 palette_set_color (widget, GTK_COLOR_SELECTION (data), color);
782 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
786 palette_activate (GtkWidget *widget,
790 GtkColorSelection *colorsel = data;
791 ColorSelectionPrivate *priv;
793 if ((event->keyval == ' ') || (event->keyval == GDK_Return))
795 priv = colorsel->private_data;
796 palette_set_color (widget, GTK_COLOR_SELECTION (data), priv->color);
803 palette_new (GtkColorSelection *colorsel)
807 static const GtkTargetEntry targets[] = {
808 { "application/x-color", 0 }
811 retval = gtk_drawing_area_new ();
812 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
813 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK);
815 gtk_signal_connect (GTK_OBJECT (retval), "draw", palette_draw, colorsel);
816 gtk_signal_connect (GTK_OBJECT (retval), "expose_event", palette_expose, colorsel);
817 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event", palette_press, colorsel);
819 gtk_drag_dest_set (retval,
820 GTK_DEST_DEFAULT_HIGHLIGHT |
821 GTK_DEST_DEFAULT_MOTION |
822 GTK_DEST_DEFAULT_DROP,
826 gtk_signal_connect (GTK_OBJECT (retval), "drag_end", palette_drag_end, NULL);
827 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received", palette_drop_handle, colorsel);
828 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event", GTK_SIGNAL_FUNC (palette_activate), colorsel);
836 * The actual GtkColorSelection widget
841 initialize_cursor (void)
846 gdk_bitmap_create_from_data (NULL,
848 DROPPER_WIDTH, DROPPER_HEIGHT);
850 gdk_bitmap_create_from_data (NULL,
852 DROPPER_WIDTH, DROPPER_HEIGHT);
854 gdk_color_white (gdk_colormap_get_system (), &bg);
855 gdk_color_black (gdk_colormap_get_system (), &fg);
857 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
859 gdk_pixmap_unref (pixmap);
860 gdk_pixmap_unref (mask);
865 grab_color_at_mouse (GtkWidget *button,
873 GtkColorSelection *colorsel = data;
874 ColorSelectionPrivate *priv;
875 GdkColormap *colormap = gdk_colormap_get_system ();
876 #if defined (GDK_WINDOWING_X11)
880 priv = colorsel->private_data;
882 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
883 pixel = gdk_image_get_pixel (image, 0, 0);
884 visual = gdk_colormap_get_visual (colormap);
886 switch (visual->type) {
887 case GDK_VISUAL_DIRECT_COLOR:
888 case GDK_VISUAL_TRUE_COLOR:
889 priv->color[COLORSEL_RED] = (double)((pixel & visual->red_mask)>>visual->red_shift)/((1<<visual->red_prec) - 1);
890 priv->color[COLORSEL_GREEN] = (double)((pixel & visual->green_mask)>>visual->green_shift)/((1<<visual->green_prec) - 1);
891 priv->color[COLORSEL_BLUE] = (double)((pixel & visual->blue_mask)>>visual->blue_shift)/((1<<visual->blue_prec) - 1);
893 case GDK_VISUAL_STATIC_GRAY:
894 case GDK_VISUAL_GRAYSCALE:
895 priv->color[COLORSEL_RED] = (double)pixel/((1<<visual->depth) - 1);
896 priv->color[COLORSEL_GREEN] = (double)pixel/((1<<visual->depth) - 1);
897 priv->color[COLORSEL_BLUE] = (double)pixel/((1<<visual->depth) - 1);
899 #if defined (GDK_WINDOWING_X11)
900 case GDK_VISUAL_STATIC_COLOR:
901 xcolor.pixel = pixel;
902 XQueryColor (GDK_DISPLAY (), GDK_COLORMAP_XCOLORMAP (colormap), &xcolor);
903 priv->color[COLORSEL_RED] = xcolor.red/65535.0;
904 priv->color[COLORSEL_GREEN] = xcolor.green/65535.0;
905 priv->color[COLORSEL_BLUE] = xcolor.blue/65535.0;
908 case GDK_VISUAL_PSEUDO_COLOR:
909 priv->color[COLORSEL_RED] = colormap->colors[pixel].red/(double)0xffffff;
910 priv->color[COLORSEL_GREEN] = colormap->colors[pixel].green/(double)0xffffff;
911 priv->color[COLORSEL_BLUE] = colormap->colors[pixel].blue/(double)0xffffff;
914 g_assert_not_reached ();
918 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
919 priv->color[COLORSEL_GREEN],
920 priv->color[COLORSEL_BLUE],
921 &priv->color[COLORSEL_HUE],
922 &priv->color[COLORSEL_SATURATION],
923 &priv->color[COLORSEL_VALUE]);
924 update_color (colorsel);
928 mouse_motion (GtkWidget *button,
929 GdkEventMotion *event,
932 grab_color_at_mouse (button, event->x_root, event->y_root, data);
936 mouse_release (GtkWidget *button,
937 GdkEventButton *event,
940 GtkColorSelection *colorsel = data;
941 ColorSelectionPrivate *priv;
942 priv = colorsel->private_data;
944 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_motion, data);
945 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_release, data);
947 grab_color_at_mouse (button, event->x_root, event->y_root, data);
948 gdk_pointer_ungrab (0);
951 /* Helper Functions */
953 mouse_press (GtkWidget *button,
954 GdkEventButton *event,
957 GtkColorSelection *colorsel = data;
958 ColorSelectionPrivate *priv;
959 priv = colorsel->private_data;
961 gtk_signal_connect (GTK_OBJECT (button), "motion_notify_event", mouse_motion, data);
962 gtk_signal_connect (GTK_OBJECT (button), "button_release_event", mouse_release, data);
963 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_press, data);
966 /* when the button is clicked */
968 get_screen_color (GtkWidget *button)
970 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
971 ColorSelectionPrivate *priv = colorsel->private_data;
973 if (picker_cursor == NULL)
975 initialize_cursor ();
978 /* Why do we do this? Because the "clicked" signal will be emitted after the "button_released"
979 signal. We don't want to do this stuff again, though, or else it will get trapped here. So,
980 priv->moving_dropper is initialized to FALSE at the initialization of the colorselector,
981 it is initialized to true when we start waiting for the user to click the the dropper on a
982 color, and whenver it is true when this function starts to execute, we set it to false. */
983 if (priv->moving_dropper == FALSE)
985 priv->moving_dropper = TRUE;
986 gtk_signal_connect (GTK_OBJECT (button), "button_press_event", mouse_press, colorsel);
988 gdk_pointer_grab (button->window,
990 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
997 priv->moving_dropper = FALSE;
1002 hex_changed (GtkWidget *hex_entry,
1005 GtkColorSelection *colorsel;
1006 ColorSelectionPrivate *priv;
1010 colorsel = GTK_COLOR_SELECTION (data);
1011 priv = colorsel->private_data;
1016 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1017 if (gdk_color_parse (text, &color))
1019 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1020 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1021 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1022 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1023 priv->color[COLORSEL_GREEN],
1024 priv->color[COLORSEL_BLUE],
1025 &priv->color[COLORSEL_HUE],
1026 &priv->color[COLORSEL_SATURATION],
1027 &priv->color[COLORSEL_VALUE]);
1028 update_color (colorsel);
1034 hsv_changed (GtkWidget *hsv,
1037 GtkColorSelection *colorsel;
1038 ColorSelectionPrivate *priv;
1040 colorsel = GTK_COLOR_SELECTION (data);
1041 priv = colorsel->private_data;
1046 gtk_hsv_get_color (GTK_HSV (hsv),
1047 &priv->color[COLORSEL_HUE],
1048 &priv->color[COLORSEL_SATURATION],
1049 &priv->color[COLORSEL_VALUE]);
1050 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1051 priv->color[COLORSEL_SATURATION],
1052 priv->color[COLORSEL_VALUE],
1053 &priv->color[COLORSEL_RED],
1054 &priv->color[COLORSEL_GREEN],
1055 &priv->color[COLORSEL_BLUE]);
1056 update_color (colorsel);
1060 adjustment_changed (GtkAdjustment *adjustment,
1063 GtkColorSelection *colorsel;
1064 ColorSelectionPrivate *priv;
1066 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1067 priv = colorsel->private_data;
1072 switch (GPOINTER_TO_INT (data))
1074 case COLORSEL_SATURATION:
1075 case COLORSEL_VALUE:
1076 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1077 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1078 priv->color[COLORSEL_SATURATION],
1079 priv->color[COLORSEL_VALUE],
1080 &priv->color[COLORSEL_RED],
1081 &priv->color[COLORSEL_GREEN],
1082 &priv->color[COLORSEL_BLUE]);
1085 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1086 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1087 priv->color[COLORSEL_SATURATION],
1088 priv->color[COLORSEL_VALUE],
1089 &priv->color[COLORSEL_RED],
1090 &priv->color[COLORSEL_GREEN],
1091 &priv->color[COLORSEL_BLUE]);
1094 case COLORSEL_GREEN:
1096 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1098 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1099 priv->color[COLORSEL_GREEN],
1100 priv->color[COLORSEL_BLUE],
1101 &priv->color[COLORSEL_HUE],
1102 &priv->color[COLORSEL_SATURATION],
1103 &priv->color[COLORSEL_VALUE]);
1106 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1109 update_color (colorsel);
1113 opacity_entry_changed (GtkWidget *opacity_entry,
1116 GtkColorSelection *colorsel;
1117 ColorSelectionPrivate *priv;
1121 colorsel = GTK_COLOR_SELECTION (data);
1122 priv = colorsel->private_data;
1127 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1128 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1129 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1131 update_color (colorsel);
1137 widget_focus_in (GtkWidget *drawing_area,
1138 GdkEventFocus *event,
1141 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1142 ColorSelectionPrivate *priv = colorsel->private_data;
1144 /* This signal is connected to by all of the widgets except the "Set Color" button
1145 * This will let you add a color to the currently selected palette
1148 priv->last_palette = NULL;
1153 make_label_spinbutton (GtkColorSelection *colorsel,
1154 GtkWidget **spinbutton,
1162 GtkAdjustment *adjust;
1164 if (channel_type == COLORSEL_HUE)
1166 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1170 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1172 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1173 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1174 gtk_signal_connect (GTK_OBJECT (*spinbutton), "focus_in_event", widget_focus_in, colorsel);
1175 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed", adjustment_changed, GINT_TO_POINTER (channel_type));
1176 label = gtk_label_new (text);
1177 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1178 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1179 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1184 make_palette_frame (GtkColorSelection *colorsel,
1190 ColorSelectionPrivate *priv;
1192 priv = colorsel->private_data;
1193 frame = gtk_frame_new (NULL);
1194 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1195 priv->custom_palette[i][j] = palette_new (colorsel);
1196 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1197 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1198 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1201 /* Set the palette entry [x][y] to be the currently selected one. */
1203 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1205 ColorSelectionPrivate *priv = colorsel->private_data;
1207 if (priv->last_palette != NULL)
1208 gtk_widget_queue_clear (priv->last_palette);
1210 priv->last_palette = priv->custom_palette[x][y];
1212 gtk_widget_queue_clear (priv->last_palette);
1216 update_color (GtkColorSelection *colorsel)
1218 ColorSelectionPrivate *priv = colorsel->private_data;
1220 gchar opacity_text[32];
1223 priv->changing = TRUE;
1224 color_sample_draw_samples (colorsel);
1226 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1227 priv->color[COLORSEL_HUE],
1228 priv->color[COLORSEL_SATURATION],
1229 priv->color[COLORSEL_VALUE]);
1230 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1231 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1232 priv->color[COLORSEL_HUE] * 360);
1233 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1234 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1235 priv->color[COLORSEL_SATURATION] * 255);
1236 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1237 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1238 priv->color[COLORSEL_VALUE] * 255);
1239 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1240 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1241 priv->color[COLORSEL_RED] * 255);
1242 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1243 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1244 priv->color[COLORSEL_GREEN] * 255);
1245 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1246 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1247 priv->color[COLORSEL_BLUE] * 255);
1248 gtk_adjustment_set_value (gtk_range_get_adjustment
1249 (GTK_RANGE (priv->opacity_slider)),
1250 priv->color[COLORSEL_OPACITY] * 255);
1252 g_snprintf (opacity_text, 32, "%.0f", priv->color[COLORSEL_OPACITY] * 255);
1253 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1255 g_snprintf (entryval, 11, "#%2X%2X%2X",
1256 (guint) (255 * priv->color[COLORSEL_RED]),
1257 (guint) (255 * priv->color[COLORSEL_GREEN]),
1258 (guint) (255 * priv->color[COLORSEL_BLUE]));
1260 for (ptr = entryval; *ptr; ptr++)
1263 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1264 priv->changing = FALSE;
1268 add_button_pressed (GtkWidget *button,
1269 GtkColorSelection *colorsel)
1271 ColorSelectionPrivate *priv;
1274 priv = colorsel->private_data;
1276 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1278 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1280 /* Either last_palette is set and we're on it, or it's an empty palette */
1281 if ((priv->last_palette && priv->last_palette == priv->custom_palette[i][j]) ||
1282 ((priv->last_palette == NULL) &&
1283 (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[i][j]),
1284 "color_set")) == 0)))
1286 palette_set_color (priv->custom_palette[i][j], colorsel, priv->color);
1288 /* forward the selection */
1289 if ((i == GTK_CUSTOM_PALETTE_WIDTH - 1) && (j == GTK_CUSTOM_PALETTE_HEIGHT - 1))
1290 set_selected_palette (colorsel, 0, 0);
1291 else if (i == GTK_CUSTOM_PALETTE_WIDTH - 1)
1292 set_selected_palette (colorsel, 0, j + 1);
1294 set_selected_palette (colorsel, i + 1, j);
1301 /* the palette is totally full. Add to the first one totally arbitrarily */
1302 palette_set_color (priv->custom_palette[0][0], colorsel, priv->color);
1304 /* forward the selection */
1305 set_selected_palette (colorsel, 1, 0);
1309 gtk_color_selection_get_type (void)
1311 static GtkType color_selection_type = 0;
1313 if (!color_selection_type)
1315 static const GtkTypeInfo color_selection_info =
1317 "GtkColorSelection",
1318 sizeof (GtkColorSelection),
1319 sizeof (GtkColorSelectionClass),
1320 (GtkClassInitFunc) gtk_color_selection_class_init,
1321 (GtkObjectInitFunc) gtk_color_selection_init,
1322 /* reserved_1 */ NULL,
1323 /* reserved_2 */ NULL,
1324 (GtkClassInitFunc) NULL,
1327 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1330 return color_selection_type;
1334 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1336 GtkObjectClass *object_class;
1338 object_class = (GtkObjectClass*) klass;
1340 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1342 color_selection_signals[COLOR_CHANGED] =
1343 gtk_signal_new ("color_changed",
1345 GTK_CLASS_TYPE (object_class),
1346 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1347 gtk_marshal_NONE__NONE,
1351 gtk_object_class_add_signals (object_class, color_selection_signals, LAST_SIGNAL);
1353 object_class->destroy = gtk_color_selection_destroy;
1356 /* widget functions */
1358 gtk_color_selection_init (GtkColorSelection *colorsel)
1360 GtkWidget *top_hbox;
1361 GtkWidget *top_right_vbox;
1362 GtkWidget *table, *label, *hbox, *frame, *vbox;
1363 GtkAdjustment *adjust;
1364 GdkPixmap *dropper_pixmap;
1365 GtkWidget *dropper_image;
1367 GdkBitmap *mask = NULL;
1369 ColorSelectionPrivate *priv;
1371 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1372 priv->changing = FALSE;
1373 priv->default_set = FALSE;
1374 priv->last_palette = NULL;
1375 priv->moving_dropper = FALSE;
1377 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1378 top_hbox = gtk_hbox_new (FALSE, 8);
1379 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1381 vbox = gtk_vbox_new (FALSE, 4);
1382 priv->triangle_colorsel = gtk_hsv_new ();
1383 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed", hsv_changed, colorsel);
1384 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1385 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1386 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1388 hbox = gtk_hbox_new (FALSE, 4);
1389 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1391 frame = gtk_frame_new (NULL);
1392 gtk_widget_set_usize (frame, -1, 30);
1393 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1394 color_sample_new (colorsel);
1395 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1396 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1398 button = gtk_button_new ();
1399 gtk_signal_connect (GTK_OBJECT (button), "focus_in_event", widget_focus_in, colorsel);
1400 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1401 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1402 gtk_signal_connect (GTK_OBJECT (button), "clicked", get_screen_color, NULL);
1403 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1404 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1405 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1406 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1408 top_right_vbox = gtk_vbox_new (FALSE, 4);
1409 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1410 table = gtk_table_new (8, 6, FALSE);
1411 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1412 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1413 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1415 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("Hue:"), table, 0, 0, COLORSEL_HUE);
1416 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("Saturation:"), table, 0, 1, COLORSEL_SATURATION);
1417 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("Value:"), table, 0, 2, COLORSEL_VALUE);
1418 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("Red:"), table, 6, 0, COLORSEL_RED);
1419 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("Green:"), table, 6, 1, COLORSEL_GREEN);
1420 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("Blue:"), table, 6, 2, COLORSEL_BLUE);
1421 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1423 priv->opacity_label = gtk_label_new (_("Opacity:"));
1424 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1425 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1426 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1427 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1428 priv->opacity_slider = gtk_hscale_new (adjust);
1429 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1430 gtk_signal_connect (GTK_OBJECT(adjust), "value_changed", adjustment_changed, GINT_TO_POINTER (COLORSEL_OPACITY));
1431 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1432 priv->opacity_entry = gtk_entry_new ();
1433 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1434 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "focus_in_event", widget_focus_in, colorsel);
1435 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate", opacity_entry_changed, colorsel);
1436 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1438 label = gtk_label_new (_("Hex Value:"));
1439 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1440 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1441 priv->hex_entry = gtk_entry_new ();
1442 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate", hex_changed, colorsel);
1443 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1444 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1445 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1447 /* Set up the palette */
1448 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1449 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1450 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1451 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1453 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1455 make_palette_frame (colorsel, table, i, j);
1458 set_selected_palette (colorsel, 0, 0);
1459 priv->palette_frame = gtk_frame_new (_("Custom Palette"));
1460 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1461 vbox = gtk_vbox_new (FALSE, 4);
1462 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1463 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1464 button = gtk_button_new_with_label (_("Set Color"));
1465 gtk_signal_connect (GTK_OBJECT (button), "clicked", add_button_pressed, colorsel);
1466 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1467 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1469 gtk_widget_show_all (top_hbox);
1471 if (priv->use_opacity == FALSE)
1473 gtk_widget_hide (priv->opacity_label);
1474 gtk_widget_hide (priv->opacity_slider);
1475 gtk_widget_hide (priv->opacity_entry);
1478 if (priv->use_palette == FALSE)
1480 gtk_widget_hide (priv->palette_frame);
1485 gtk_color_selection_destroy (GtkObject *object)
1487 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1489 if (cselection->private_data)
1491 g_free (cselection->private_data);
1492 cselection->private_data = NULL;
1495 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1501 * gtk_color_selection_new:
1504 * Creates a new GtkColorSelection.
1506 * Return value: The new GtkColorSelection.
1509 gtk_color_selection_new (void)
1511 GtkColorSelection *colorsel;
1512 ColorSelectionPrivate *priv;
1519 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
1520 priv = colorsel->private_data;
1521 gtk_color_selection_set_color (colorsel, color);
1522 gtk_color_selection_set_use_opacity (colorsel, FALSE);
1524 /* We want to make sure that default_set is FALSE */
1525 /* This way the user can still set it */
1526 priv->default_set = FALSE;
1528 return GTK_WIDGET (colorsel);
1533 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
1534 GtkUpdateType policy)
1536 g_return_if_fail (colorsel != NULL);
1537 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1539 g_warning (G_STRLOC ": This function is deprecated.");
1543 * gtk_color_selection_get_use_opacity:
1544 * @colorsel: A GtkColorSelection.
1546 * Determines whether the colorsel can use opacity.
1548 * Return value: TRUE if the @colorsel uses opacity. FALSE if it does't.
1551 gtk_color_selection_get_use_opacity (GtkColorSelection *colorsel)
1553 ColorSelectionPrivate *priv;
1555 g_return_val_if_fail (colorsel != NULL, FALSE);
1556 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1558 priv = colorsel->private_data;
1560 return priv->use_opacity;
1564 * gtk_color_selection_set_use_opacity:
1565 * @colorsel: A GtkColorSelection.
1566 * @use_opacity: TRUE if @colorsel can set the opacity, FALSE otherwise.
1568 * Sets the @colorsel to use or not use opacity.
1572 gtk_color_selection_set_use_opacity (GtkColorSelection *colorsel,
1573 gboolean use_opacity)
1575 ColorSelectionPrivate *priv;
1577 g_return_if_fail (colorsel != NULL);
1578 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1580 priv = colorsel->private_data;
1581 use_opacity = use_opacity != FALSE;
1583 if (priv->use_opacity != use_opacity)
1585 priv->use_opacity = use_opacity;
1588 gtk_widget_show (priv->opacity_slider);
1589 gtk_widget_show (priv->opacity_label);
1590 gtk_widget_show (priv->opacity_entry);
1594 gtk_widget_hide (priv->opacity_slider);
1595 gtk_widget_hide (priv->opacity_label);
1596 gtk_widget_hide (priv->opacity_entry);
1598 color_sample_draw_samples (colorsel);
1603 * gtk_color_selection_get_use_palette:
1604 * @colorsel: A GtkColorSelection.
1606 * Determines whether the palette is used.
1608 * Return value: TRUE if the palette is used. FALSE if it isn't.
1611 gtk_color_selection_get_use_palette (GtkColorSelection *colorsel)
1613 ColorSelectionPrivate *priv;
1615 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1617 priv = colorsel->private_data;
1619 return priv->use_palette;
1623 * gtk_color_selection_set_use_palette:
1624 * @colorsel: A GtkColorSelection.
1625 * @use_palette: TRUE if palette is to be visible, FALSE otherwise.
1627 * Shows and hides the palette based upon the value of @use_palette.
1631 gtk_color_selection_set_use_palette (GtkColorSelection *colorsel,
1632 gboolean use_palette)
1634 ColorSelectionPrivate *priv;
1635 g_return_if_fail (colorsel != NULL);
1636 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1638 priv = colorsel->private_data;
1639 use_palette = use_palette != FALSE;
1641 if (priv->use_palette != use_palette)
1643 priv->use_palette = use_palette;
1645 gtk_widget_show (priv->palette_frame);
1647 gtk_widget_hide (priv->palette_frame);
1652 * gtk_color_selection_set_color:
1653 * @colorsel: A GtkColorSelection.
1654 * @color: A color to set the current color with.
1656 * Sets the current color to be @color. The first time this is called, it will
1657 * also set the original color to be @color too.
1661 gtk_color_selection_set_color (GtkColorSelection *colorsel,
1664 ColorSelectionPrivate *priv;
1667 g_return_if_fail (colorsel != NULL);
1668 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1670 priv = colorsel->private_data;
1671 priv->changing = TRUE;
1672 priv->color[COLORSEL_RED] = color[0];
1673 priv->color[COLORSEL_GREEN] = color[1];
1674 priv->color[COLORSEL_BLUE] = color[2];
1675 priv->color[COLORSEL_OPACITY] = color[3];
1676 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1677 priv->color[COLORSEL_GREEN],
1678 priv->color[COLORSEL_BLUE],
1679 &priv->color[COLORSEL_HUE],
1680 &priv->color[COLORSEL_SATURATION],
1681 &priv->color[COLORSEL_VALUE]);
1682 if (priv->default_set == FALSE)
1684 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
1685 priv->old_color[i] = priv->color[i];
1687 update_color (colorsel);
1688 priv->default_set = TRUE;
1692 * gtk_color_selection_get_color:
1693 * @colorsel: A GtkColorSelection.
1694 * @color: A color to fill in with the current color.
1696 * Sets @color to be the current color in the GtkColorSelection widget.
1700 gtk_color_selection_get_color (GtkColorSelection *colorsel,
1703 ColorSelectionPrivate *priv;
1705 g_return_if_fail (colorsel != NULL);
1706 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1708 priv = colorsel->private_data;
1709 color[0] = priv->color[COLORSEL_RED];
1710 color[1] = priv->color[COLORSEL_GREEN];
1711 color[2] = priv->color[COLORSEL_BLUE];
1712 color[3] = priv->use_opacity ? priv->color[COLORSEL_OPACITY] : 1.0;
1716 * gtk_color_selection_get_old_color:
1717 * @colorsel: A GtkColorSelection.
1718 * @color: A color to set the original color with.
1720 * Sets the 'original' color to be @color. This function should be called with
1721 * some hesitations, as it might seem confusing to have that color change.
1722 * Calling gtk_color_selection_set_color will also set this color the first
1723 * time it is called.
1727 gtk_color_selection_set_old_color (GtkColorSelection *colorsel,
1730 ColorSelectionPrivate *priv;
1732 g_return_if_fail (colorsel != NULL);
1733 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1735 priv = colorsel->private_data;
1736 priv->changing = TRUE;
1737 priv->old_color[COLORSEL_RED] = color[0];
1738 priv->old_color[COLORSEL_GREEN] = color[1];
1739 priv->old_color[COLORSEL_BLUE] = color[2];
1740 priv->old_color[COLORSEL_OPACITY] = color[3];
1741 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
1742 priv->old_color[COLORSEL_GREEN],
1743 priv->old_color[COLORSEL_BLUE],
1744 &priv->old_color[COLORSEL_HUE],
1745 &priv->old_color[COLORSEL_SATURATION],
1746 &priv->old_color[COLORSEL_VALUE]);
1747 color_sample_draw_samples (colorsel);
1748 priv->default_set = TRUE;
1752 * gtk_color_selection_get_old_color:
1753 * @colorsel: A GtkColorSelection.
1754 * @color: A color to fill in with the original color value.
1756 * Fills @color in with the original color value.
1760 gtk_color_selection_get_old_color (GtkColorSelection *colorsel,
1763 ColorSelectionPrivate *priv;
1765 g_return_if_fail (colorsel != NULL);
1766 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1768 priv = colorsel->private_data;
1769 color[0] = priv->old_color[COLORSEL_RED];
1770 color[1] = priv->old_color[COLORSEL_GREEN];
1771 color[2] = priv->old_color[COLORSEL_BLUE];
1772 color[3] = priv->use_opacity ? priv->old_color[COLORSEL_OPACITY] : 1.0;
1776 * gtk_color_selection_set_palette_color:
1777 * @colorsel: A GtkColorSelection.
1778 * @x: The x coordinate of the palette.
1779 * @y: The y coordinate of the palette.
1780 * @color: A color to set the palette with.
1782 * Set the palette located at (@x, @y) to have @color set as its color.
1786 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
1791 ColorSelectionPrivate *priv;
1793 g_return_if_fail (colorsel != NULL);
1794 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1795 g_return_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT);
1797 priv = colorsel->private_data;
1798 palette_set_color (priv->custom_palette[x][y], colorsel, color);
1802 * gtk_color_selection_get_palette_color:
1803 * @colorsel: A GtkColorSelection.
1804 * @x: The x coordinate of the palette.
1805 * @y: The y coordinate of the palette.
1806 * @color: A color to fill in with the color value.
1808 * Set @color to have the color found in the palette located at (@x, @y). If
1809 * the palette is unset, it will leave the color unset.
1811 * Return value: TRUE if the palette located at (@x, @y) has a color set. FALSE
1815 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
1820 ColorSelectionPrivate *priv;
1822 g_return_val_if_fail (colorsel != NULL, FALSE);
1823 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1824 g_return_val_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
1826 priv = colorsel->private_data;
1828 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
1831 palette_get_color (priv->custom_palette[x][y], color);
1836 * gtk_color_selection_unset_palette_color:
1837 * @colorsel: A GtkColorSelection.
1838 * @x: The x coordinate of the palette.
1839 * @y: The y coordinate of the palette.
1841 * Change the palette located at (@x, @y) to have no color set.
1845 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
1849 ColorSelectionPrivate *priv;
1851 g_return_if_fail (colorsel != NULL);
1852 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1853 g_return_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT);
1855 priv = colorsel->private_data;
1856 palette_unset_color (priv->custom_palette[x][y]);
1860 * gtk_color_selection_is_adjusting:
1861 * @colorsel: A GtkColorSelection.
1863 * Gets the current state of the @colorsel.
1865 * Return value: TRUE if the user is currently dragging a color around, and FALSE
1866 * if the selection has stopped.
1869 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
1871 ColorSelectionPrivate *priv;
1873 g_return_val_if_fail (colorsel != NULL, FALSE);
1874 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1876 priv = colorsel->private_data;
1878 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));