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 gtk_widget_push_visual(gdk_rgb_get_visual());
492 gtk_widget_push_colormap(gdk_rgb_get_cmap());
494 priv->sample_area = gtk_hbox_new (FALSE, 0);
495 priv->old_sample = gtk_drawing_area_new ();
496 priv->cur_sample = gtk_drawing_area_new ();
498 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
500 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
502 gtk_widget_pop_visual();
503 gtk_widget_pop_colormap();
505 gtk_signal_connect(GTK_OBJECT (priv->old_sample), "expose_event",
506 GTK_SIGNAL_FUNC (color_old_sample_expose),
508 gtk_signal_connect(GTK_OBJECT (priv->cur_sample), "expose_event",
509 GTK_SIGNAL_FUNC (color_cur_sample_expose),
512 color_sample_setup_dnd (colorsel, priv->old_sample);
513 color_sample_setup_dnd (colorsel, priv->cur_sample);
515 gtk_widget_show_all (priv->sample_area);
521 * The palette area code
524 #define CUSTOM_PALETTE_ENTRY_WIDTH 16
525 #define CUSTOM_PALETTE_ENTRY_HEIGHT 16
528 palette_get_color (GtkWidget *drawing_area, gdouble *color)
532 g_return_if_fail (color != NULL);
534 color_val = gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
535 if (color_val == NULL)
537 /* Default to white for no good reason */
545 color[0] = color_val[0];
546 color[1] = color_val[1];
547 color[2] = color_val[2];
551 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
553 palette_paint (GtkWidget *drawing_area,
557 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
558 ColorSelectionPrivate *priv = colorsel->private_data;
560 if (drawing_area->window == NULL)
563 gdk_window_clear_area (drawing_area->window,
569 if (priv->last_palette == drawing_area)
574 palette_get_color (drawing_area, color);
576 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
577 gc = drawing_area->style->black_gc;
579 gc = drawing_area->style->white_gc;
581 gdk_draw_rectangle (drawing_area->window,
583 drawing_area->allocation.width - 1,
584 drawing_area->allocation.height - 1);
589 palette_expose (GtkWidget *drawing_area,
590 GdkEventExpose *event,
593 if (drawing_area->window == NULL)
596 palette_paint (drawing_area, &(event->area), data);
600 palette_press (GtkWidget *drawing_area,
601 GdkEventButton *event,
604 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
605 ColorSelectionPrivate *priv = colorsel->private_data;
607 if (priv->last_palette != NULL)
608 gtk_widget_queue_clear (priv->last_palette);
610 priv->last_palette = drawing_area;
612 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0)
615 palette_get_color (drawing_area, color);
616 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
619 gtk_widget_queue_clear (priv->last_palette);
623 palette_draw (GtkWidget *drawing_area,
627 palette_paint (drawing_area, area, data);
631 palette_unset_color (GtkWidget *drawing_area)
633 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
636 gtk_widget_reset_rc_styles (drawing_area);
637 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0));
641 palette_drag_begin (GtkWidget *widget,
642 GdkDragContext *context,
645 GtkColorSelection *colorsel = data;
646 ColorSelectionPrivate *priv;
651 priv = colorsel->private_data;
652 window = gtk_window_new (GTK_WINDOW_POPUP);
653 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
654 gtk_widget_set_usize (window, 48, 32);
655 gtk_widget_realize (window);
656 gtk_object_set_data_full (GTK_OBJECT (widget),
657 "gtk-color-selection-drag-window",
659 (GtkDestroyNotify) gtk_widget_destroy);
661 palette_get_color (widget, colors);
662 bg.red = 0xffff * colors[0];
663 bg.green = 0xffff * colors[1];
664 bg.blue = 0xffff * colors[2];
666 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
667 gdk_window_set_background (window->window, &bg);
669 gtk_drag_set_icon_widget (context, window, -2, -2);
673 palette_drag_handle (GtkWidget *widget,
674 GdkDragContext *context,
675 GtkSelectionData *selection_data,
683 palette_get_color (widget, colsrc);
685 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
686 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
687 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
690 gtk_selection_data_set (selection_data,
691 gdk_atom_intern ("application/x-color", FALSE),
692 16, (guchar *)vals, 8);
696 palette_set_color (GtkWidget *drawing_area,
697 GtkColorSelection *colorsel,
700 GtkRcStyle *rc_style;
701 gdouble *new_color = g_new (double, 4);
704 rc_style = gtk_rc_style_new ();
705 rc_style->bg[GTK_STATE_NORMAL].red = color[0]*65535;
706 rc_style->bg[GTK_STATE_NORMAL].green = color[1]*65535;
707 rc_style->bg[GTK_STATE_NORMAL].blue = color[2]*65535;
708 rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
709 gtk_rc_style_ref (rc_style);
710 gtk_widget_modify_style (drawing_area, rc_style);
712 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
714 static const GtkTargetEntry targets[] = {
715 { "application/x-color", 0 }
717 gtk_drag_source_set (drawing_area,
718 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
720 GDK_ACTION_COPY | GDK_ACTION_MOVE);
722 gtk_signal_connect (GTK_OBJECT (drawing_area),
724 GTK_SIGNAL_FUNC (palette_drag_begin),
726 gtk_signal_connect (GTK_OBJECT (drawing_area),
728 GTK_SIGNAL_FUNC (palette_drag_handle),
731 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
735 old_color = (gdouble *) gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
741 new_color[0] = color[0];
742 new_color[1] = color[1];
743 new_color[2] = color[2];
746 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_val", new_color);
750 palette_drag_end (GtkWidget *widget,
751 GdkDragContext *context,
754 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
758 palette_drop_handle (GtkWidget *widget,
759 GdkDragContext *context,
762 GtkSelectionData *selection_data,
770 if (selection_data->length < 0)
773 if ((selection_data->format != 16) ||
774 (selection_data->length != 8))
776 g_warning ("Received invalid color data\n");
780 vals = (guint16 *)selection_data->data;
782 color[0] = (gdouble)vals[0] / 0xffff;
783 color[1] = (gdouble)vals[1] / 0xffff;
784 color[2] = (gdouble)vals[2] / 0xffff;
785 color[3] = (gdouble)vals[3] / 0xffff;
786 palette_set_color (widget, GTK_COLOR_SELECTION (data), color);
787 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
791 palette_activate (GtkWidget *widget,
795 GtkColorSelection *colorsel = data;
796 ColorSelectionPrivate *priv;
798 if ((event->keyval == ' ') || (event->keyval == GDK_Return))
800 priv = colorsel->private_data;
801 palette_set_color (widget, GTK_COLOR_SELECTION (data), priv->color);
808 palette_new (GtkColorSelection *colorsel)
812 static const GtkTargetEntry targets[] = {
813 { "application/x-color", 0 }
816 retval = gtk_drawing_area_new ();
817 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
818 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK);
820 gtk_signal_connect (GTK_OBJECT (retval), "draw", palette_draw, colorsel);
821 gtk_signal_connect (GTK_OBJECT (retval), "expose_event", palette_expose, colorsel);
822 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event", palette_press, colorsel);
824 gtk_drag_dest_set (retval,
825 GTK_DEST_DEFAULT_HIGHLIGHT |
826 GTK_DEST_DEFAULT_MOTION |
827 GTK_DEST_DEFAULT_DROP,
831 gtk_signal_connect (GTK_OBJECT (retval), "drag_end", palette_drag_end, NULL);
832 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received", palette_drop_handle, colorsel);
833 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event", GTK_SIGNAL_FUNC (palette_activate), colorsel);
841 * The actual GtkColorSelection widget
846 initialize_cursor (void)
851 gdk_bitmap_create_from_data (NULL,
853 DROPPER_WIDTH, DROPPER_HEIGHT);
855 gdk_bitmap_create_from_data (NULL,
857 DROPPER_WIDTH, DROPPER_HEIGHT);
859 gdk_color_white (gdk_colormap_get_system (), &bg);
860 gdk_color_black (gdk_colormap_get_system (), &fg);
862 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
864 gdk_pixmap_unref (pixmap);
865 gdk_pixmap_unref (mask);
870 grab_color_at_mouse (GtkWidget *button,
878 GtkColorSelection *colorsel = data;
879 ColorSelectionPrivate *priv;
880 GdkColormap *colormap = gdk_colormap_get_system ();
881 #if defined (GDK_WINDOWING_X11)
885 priv = colorsel->private_data;
887 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
888 pixel = gdk_image_get_pixel (image, 0, 0);
889 visual = gdk_colormap_get_visual (colormap);
891 switch (visual->type) {
892 case GDK_VISUAL_DIRECT_COLOR:
893 case GDK_VISUAL_TRUE_COLOR:
894 priv->color[COLORSEL_RED] = (double)((pixel & visual->red_mask)>>visual->red_shift)/((1<<visual->red_prec) - 1);
895 priv->color[COLORSEL_GREEN] = (double)((pixel & visual->green_mask)>>visual->green_shift)/((1<<visual->green_prec) - 1);
896 priv->color[COLORSEL_BLUE] = (double)((pixel & visual->blue_mask)>>visual->blue_shift)/((1<<visual->blue_prec) - 1);
898 case GDK_VISUAL_STATIC_GRAY:
899 case GDK_VISUAL_GRAYSCALE:
900 priv->color[COLORSEL_RED] = (double)pixel/((1<<visual->depth) - 1);
901 priv->color[COLORSEL_GREEN] = (double)pixel/((1<<visual->depth) - 1);
902 priv->color[COLORSEL_BLUE] = (double)pixel/((1<<visual->depth) - 1);
904 #if defined (GDK_WINDOWING_X11)
905 case GDK_VISUAL_STATIC_COLOR:
906 xcolor.pixel = pixel;
907 XQueryColor (GDK_DISPLAY (), GDK_COLORMAP_XCOLORMAP (colormap), &xcolor);
908 priv->color[COLORSEL_RED] = xcolor.red/65535.0;
909 priv->color[COLORSEL_GREEN] = xcolor.green/65535.0;
910 priv->color[COLORSEL_BLUE] = xcolor.blue/65535.0;
913 case GDK_VISUAL_PSEUDO_COLOR:
914 priv->color[COLORSEL_RED] = colormap->colors[pixel].red/(double)0xffffff;
915 priv->color[COLORSEL_GREEN] = colormap->colors[pixel].green/(double)0xffffff;
916 priv->color[COLORSEL_BLUE] = colormap->colors[pixel].blue/(double)0xffffff;
919 g_assert_not_reached ();
923 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
924 priv->color[COLORSEL_GREEN],
925 priv->color[COLORSEL_BLUE],
926 &priv->color[COLORSEL_HUE],
927 &priv->color[COLORSEL_SATURATION],
928 &priv->color[COLORSEL_VALUE]);
929 update_color (colorsel);
933 mouse_motion (GtkWidget *button,
934 GdkEventMotion *event,
937 grab_color_at_mouse (button, event->x_root, event->y_root, data);
941 mouse_release (GtkWidget *button,
942 GdkEventButton *event,
945 GtkColorSelection *colorsel = data;
946 ColorSelectionPrivate *priv;
947 priv = colorsel->private_data;
949 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_motion, data);
950 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_release, data);
952 grab_color_at_mouse (button, event->x_root, event->y_root, data);
953 gdk_pointer_ungrab (0);
956 /* Helper Functions */
958 mouse_press (GtkWidget *button,
959 GdkEventButton *event,
962 GtkColorSelection *colorsel = data;
963 ColorSelectionPrivate *priv;
964 priv = colorsel->private_data;
966 gtk_signal_connect (GTK_OBJECT (button), "motion_notify_event", mouse_motion, data);
967 gtk_signal_connect (GTK_OBJECT (button), "button_release_event", mouse_release, data);
968 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_press, data);
971 /* when the button is clicked */
973 get_screen_color (GtkWidget *button)
975 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
976 ColorSelectionPrivate *priv = colorsel->private_data;
978 if (picker_cursor == NULL)
980 initialize_cursor ();
983 /* Why do we do this? Because the "clicked" signal will be emitted after the "button_released"
984 signal. We don't want to do this stuff again, though, or else it will get trapped here. So,
985 priv->moving_dropper is initialized to FALSE at the initialization of the colorselector,
986 it is initialized to true when we start waiting for the user to click the the dropper on a
987 color, and whenver it is true when this function starts to execute, we set it to false. */
988 if (priv->moving_dropper == FALSE)
990 priv->moving_dropper = TRUE;
991 gtk_signal_connect (GTK_OBJECT (button), "button_press_event", mouse_press, colorsel);
993 gdk_pointer_grab (button->window,
995 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1002 priv->moving_dropper = FALSE;
1007 hex_changed (GtkWidget *hex_entry,
1010 GtkColorSelection *colorsel;
1011 ColorSelectionPrivate *priv;
1015 colorsel = GTK_COLOR_SELECTION (data);
1016 priv = colorsel->private_data;
1021 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1022 if (gdk_color_parse (text, &color))
1024 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1025 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1026 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1027 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1028 priv->color[COLORSEL_GREEN],
1029 priv->color[COLORSEL_BLUE],
1030 &priv->color[COLORSEL_HUE],
1031 &priv->color[COLORSEL_SATURATION],
1032 &priv->color[COLORSEL_VALUE]);
1033 update_color (colorsel);
1039 hsv_changed (GtkWidget *hsv,
1042 GtkColorSelection *colorsel;
1043 ColorSelectionPrivate *priv;
1045 colorsel = GTK_COLOR_SELECTION (data);
1046 priv = colorsel->private_data;
1051 gtk_hsv_get_color (GTK_HSV (hsv),
1052 &priv->color[COLORSEL_HUE],
1053 &priv->color[COLORSEL_SATURATION],
1054 &priv->color[COLORSEL_VALUE]);
1055 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1056 priv->color[COLORSEL_SATURATION],
1057 priv->color[COLORSEL_VALUE],
1058 &priv->color[COLORSEL_RED],
1059 &priv->color[COLORSEL_GREEN],
1060 &priv->color[COLORSEL_BLUE]);
1061 update_color (colorsel);
1065 adjustment_changed (GtkAdjustment *adjustment,
1068 GtkColorSelection *colorsel;
1069 ColorSelectionPrivate *priv;
1071 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1072 priv = colorsel->private_data;
1077 switch (GPOINTER_TO_INT (data))
1079 case COLORSEL_SATURATION:
1080 case COLORSEL_VALUE:
1081 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1082 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1083 priv->color[COLORSEL_SATURATION],
1084 priv->color[COLORSEL_VALUE],
1085 &priv->color[COLORSEL_RED],
1086 &priv->color[COLORSEL_GREEN],
1087 &priv->color[COLORSEL_BLUE]);
1090 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1091 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1092 priv->color[COLORSEL_SATURATION],
1093 priv->color[COLORSEL_VALUE],
1094 &priv->color[COLORSEL_RED],
1095 &priv->color[COLORSEL_GREEN],
1096 &priv->color[COLORSEL_BLUE]);
1099 case COLORSEL_GREEN:
1101 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1103 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1104 priv->color[COLORSEL_GREEN],
1105 priv->color[COLORSEL_BLUE],
1106 &priv->color[COLORSEL_HUE],
1107 &priv->color[COLORSEL_SATURATION],
1108 &priv->color[COLORSEL_VALUE]);
1111 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1114 update_color (colorsel);
1118 opacity_entry_changed (GtkWidget *opacity_entry,
1121 GtkColorSelection *colorsel;
1122 ColorSelectionPrivate *priv;
1126 colorsel = GTK_COLOR_SELECTION (data);
1127 priv = colorsel->private_data;
1132 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1133 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1134 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1136 update_color (colorsel);
1142 widget_focus_in (GtkWidget *drawing_area,
1143 GdkEventFocus *event,
1146 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1147 ColorSelectionPrivate *priv = colorsel->private_data;
1149 /* This signal is connected to by all of the widgets except the "Set Color" button
1150 * This will let you add a color to the currently selected palette
1153 priv->last_palette = NULL;
1158 make_label_spinbutton (GtkColorSelection *colorsel,
1159 GtkWidget **spinbutton,
1167 GtkAdjustment *adjust;
1169 if (channel_type == COLORSEL_HUE)
1171 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1175 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1177 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1178 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1179 gtk_signal_connect (GTK_OBJECT (*spinbutton), "focus_in_event", widget_focus_in, colorsel);
1180 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed", adjustment_changed, GINT_TO_POINTER (channel_type));
1181 label = gtk_label_new (text);
1182 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1183 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1184 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1189 make_palette_frame (GtkColorSelection *colorsel,
1195 ColorSelectionPrivate *priv;
1197 priv = colorsel->private_data;
1198 frame = gtk_frame_new (NULL);
1199 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1200 priv->custom_palette[i][j] = palette_new (colorsel);
1201 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1202 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1203 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1206 /* Set the palette entry [x][y] to be the currently selected one. */
1208 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1210 ColorSelectionPrivate *priv = colorsel->private_data;
1212 if (priv->last_palette != NULL)
1213 gtk_widget_queue_clear (priv->last_palette);
1215 priv->last_palette = priv->custom_palette[x][y];
1217 gtk_widget_queue_clear (priv->last_palette);
1221 update_color (GtkColorSelection *colorsel)
1223 ColorSelectionPrivate *priv = colorsel->private_data;
1225 gchar opacity_text[32];
1228 priv->changing = TRUE;
1229 color_sample_draw_samples (colorsel);
1231 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1232 priv->color[COLORSEL_HUE],
1233 priv->color[COLORSEL_SATURATION],
1234 priv->color[COLORSEL_VALUE]);
1235 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1236 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1237 priv->color[COLORSEL_HUE] * 360);
1238 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1239 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1240 priv->color[COLORSEL_SATURATION] * 255);
1241 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1242 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1243 priv->color[COLORSEL_VALUE] * 255);
1244 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1245 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1246 priv->color[COLORSEL_RED] * 255);
1247 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1248 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1249 priv->color[COLORSEL_GREEN] * 255);
1250 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1251 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1252 priv->color[COLORSEL_BLUE] * 255);
1253 gtk_adjustment_set_value (gtk_range_get_adjustment
1254 (GTK_RANGE (priv->opacity_slider)),
1255 priv->color[COLORSEL_OPACITY] * 255);
1257 g_snprintf (opacity_text, 32, "%.0f", priv->color[COLORSEL_OPACITY] * 255);
1258 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1260 g_snprintf (entryval, 11, "#%2X%2X%2X",
1261 (guint) (255 * priv->color[COLORSEL_RED]),
1262 (guint) (255 * priv->color[COLORSEL_GREEN]),
1263 (guint) (255 * priv->color[COLORSEL_BLUE]));
1265 for (ptr = entryval; *ptr; ptr++)
1268 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1269 priv->changing = FALSE;
1273 add_button_pressed (GtkWidget *button,
1274 GtkColorSelection *colorsel)
1276 ColorSelectionPrivate *priv;
1279 priv = colorsel->private_data;
1281 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1283 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1285 /* Either last_palette is set and we're on it, or it's an empty palette */
1286 if ((priv->last_palette && priv->last_palette == priv->custom_palette[i][j]) ||
1287 ((priv->last_palette == NULL) &&
1288 (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[i][j]),
1289 "color_set")) == 0)))
1291 palette_set_color (priv->custom_palette[i][j], colorsel, priv->color);
1293 /* forward the selection */
1294 if ((i == GTK_CUSTOM_PALETTE_WIDTH - 1) && (j == GTK_CUSTOM_PALETTE_HEIGHT - 1))
1295 set_selected_palette (colorsel, 0, 0);
1296 else if (i == GTK_CUSTOM_PALETTE_WIDTH - 1)
1297 set_selected_palette (colorsel, 0, j + 1);
1299 set_selected_palette (colorsel, i + 1, j);
1306 /* the palette is totally full. Add to the first one totally arbitrarily */
1307 palette_set_color (priv->custom_palette[0][0], colorsel, priv->color);
1309 /* forward the selection */
1310 set_selected_palette (colorsel, 1, 0);
1314 gtk_color_selection_get_type (void)
1316 static GtkType color_selection_type = 0;
1318 if (!color_selection_type)
1320 static const GtkTypeInfo color_selection_info =
1322 "GtkColorSelection",
1323 sizeof (GtkColorSelection),
1324 sizeof (GtkColorSelectionClass),
1325 (GtkClassInitFunc) gtk_color_selection_class_init,
1326 (GtkObjectInitFunc) gtk_color_selection_init,
1327 /* reserved_1 */ NULL,
1328 /* reserved_2 */ NULL,
1329 (GtkClassInitFunc) NULL,
1332 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1335 return color_selection_type;
1339 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1341 GtkObjectClass *object_class;
1343 object_class = (GtkObjectClass*) klass;
1345 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1347 color_selection_signals[COLOR_CHANGED] =
1348 gtk_signal_new ("color_changed",
1350 GTK_CLASS_TYPE (object_class),
1351 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1352 gtk_marshal_NONE__NONE,
1356 gtk_object_class_add_signals (object_class, color_selection_signals, LAST_SIGNAL);
1358 object_class->destroy = gtk_color_selection_destroy;
1361 /* widget functions */
1363 gtk_color_selection_init (GtkColorSelection *colorsel)
1365 GtkWidget *top_hbox;
1366 GtkWidget *top_right_vbox;
1367 GtkWidget *table, *label, *hbox, *frame, *vbox;
1368 GtkAdjustment *adjust;
1369 GdkPixmap *dropper_pixmap;
1370 GtkWidget *dropper_image;
1372 GdkBitmap *mask = NULL;
1374 ColorSelectionPrivate *priv;
1376 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1377 priv->changing = FALSE;
1378 priv->default_set = FALSE;
1379 priv->last_palette = NULL;
1380 priv->moving_dropper = FALSE;
1382 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1383 top_hbox = gtk_hbox_new (FALSE, 8);
1384 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1386 vbox = gtk_vbox_new (FALSE, 4);
1387 priv->triangle_colorsel = gtk_hsv_new ();
1388 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed", hsv_changed, colorsel);
1389 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1390 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1391 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1393 hbox = gtk_hbox_new (FALSE, 4);
1394 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1396 frame = gtk_frame_new (NULL);
1397 gtk_widget_set_usize (frame, -1, 30);
1398 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1399 color_sample_new (colorsel);
1400 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1401 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1403 button = gtk_button_new ();
1404 gtk_signal_connect (GTK_OBJECT (button), "focus_in_event", widget_focus_in, colorsel);
1405 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1406 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1407 gtk_signal_connect (GTK_OBJECT (button), "clicked", get_screen_color, NULL);
1408 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1409 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1410 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1411 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1413 top_right_vbox = gtk_vbox_new (FALSE, 4);
1414 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1415 table = gtk_table_new (8, 6, FALSE);
1416 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1417 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1418 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1420 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("Hue:"), table, 0, 0, COLORSEL_HUE);
1421 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("Saturation:"), table, 0, 1, COLORSEL_SATURATION);
1422 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("Value:"), table, 0, 2, COLORSEL_VALUE);
1423 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("Red:"), table, 6, 0, COLORSEL_RED);
1424 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("Green:"), table, 6, 1, COLORSEL_GREEN);
1425 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("Blue:"), table, 6, 2, COLORSEL_BLUE);
1426 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1428 priv->opacity_label = gtk_label_new (_("Opacity:"));
1429 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1430 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1431 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1432 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1433 priv->opacity_slider = gtk_hscale_new (adjust);
1434 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1435 gtk_signal_connect (GTK_OBJECT(adjust), "value_changed", adjustment_changed, GINT_TO_POINTER (COLORSEL_OPACITY));
1436 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1437 priv->opacity_entry = gtk_entry_new ();
1438 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1439 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "focus_in_event", widget_focus_in, colorsel);
1440 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate", opacity_entry_changed, colorsel);
1441 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1443 label = gtk_label_new (_("Hex Value:"));
1444 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1445 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1446 priv->hex_entry = gtk_entry_new ();
1447 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate", hex_changed, colorsel);
1448 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1449 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1450 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1452 /* Set up the palette */
1453 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1454 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1455 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1456 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1458 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1460 make_palette_frame (colorsel, table, i, j);
1463 set_selected_palette (colorsel, 0, 0);
1464 priv->palette_frame = gtk_frame_new (_("Custom Palette"));
1465 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1466 vbox = gtk_vbox_new (FALSE, 4);
1467 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1468 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1469 button = gtk_button_new_with_label (_("Set Color"));
1470 gtk_signal_connect (GTK_OBJECT (button), "clicked", add_button_pressed, colorsel);
1471 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1472 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1474 gtk_widget_show_all (top_hbox);
1476 if (priv->use_opacity == FALSE)
1478 gtk_widget_hide (priv->opacity_label);
1479 gtk_widget_hide (priv->opacity_slider);
1480 gtk_widget_hide (priv->opacity_entry);
1483 if (priv->use_palette == FALSE)
1485 gtk_widget_hide (priv->palette_frame);
1490 gtk_color_selection_destroy (GtkObject *object)
1492 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1494 if (cselection->private_data)
1496 g_free (cselection->private_data);
1497 cselection->private_data = NULL;
1500 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1506 * gtk_color_selection_new:
1509 * Creates a new GtkColorSelection.
1511 * Return value: The new GtkColorSelection.
1514 gtk_color_selection_new (void)
1516 GtkColorSelection *colorsel;
1517 ColorSelectionPrivate *priv;
1524 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
1525 priv = colorsel->private_data;
1526 gtk_color_selection_set_color (colorsel, color);
1527 gtk_color_selection_set_use_opacity (colorsel, FALSE);
1529 /* We want to make sure that default_set is FALSE */
1530 /* This way the user can still set it */
1531 priv->default_set = FALSE;
1533 return GTK_WIDGET (colorsel);
1538 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
1539 GtkUpdateType policy)
1541 g_return_if_fail (colorsel != NULL);
1542 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1544 g_warning (G_STRLOC ": This function is deprecated.");
1548 * gtk_color_selection_get_use_opacity:
1549 * @colorsel: A GtkColorSelection.
1551 * Determines whether the colorsel can use opacity.
1553 * Return value: TRUE if the @colorsel uses opacity. FALSE if it does't.
1556 gtk_color_selection_get_use_opacity (GtkColorSelection *colorsel)
1558 ColorSelectionPrivate *priv;
1560 g_return_val_if_fail (colorsel != NULL, FALSE);
1561 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1563 priv = colorsel->private_data;
1565 return priv->use_opacity;
1569 * gtk_color_selection_set_use_opacity:
1570 * @colorsel: A GtkColorSelection.
1571 * @use_opacity: TRUE if @colorsel can set the opacity, FALSE otherwise.
1573 * Sets the @colorsel to use or not use opacity.
1577 gtk_color_selection_set_use_opacity (GtkColorSelection *colorsel,
1578 gboolean use_opacity)
1580 ColorSelectionPrivate *priv;
1582 g_return_if_fail (colorsel != NULL);
1583 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1585 priv = colorsel->private_data;
1586 use_opacity = use_opacity != FALSE;
1588 if (priv->use_opacity != use_opacity)
1590 priv->use_opacity = use_opacity;
1593 gtk_widget_show (priv->opacity_slider);
1594 gtk_widget_show (priv->opacity_label);
1595 gtk_widget_show (priv->opacity_entry);
1599 gtk_widget_hide (priv->opacity_slider);
1600 gtk_widget_hide (priv->opacity_label);
1601 gtk_widget_hide (priv->opacity_entry);
1603 color_sample_draw_samples (colorsel);
1608 * gtk_color_selection_get_use_palette:
1609 * @colorsel: A GtkColorSelection.
1611 * Determines whether the palette is used.
1613 * Return value: TRUE if the palette is used. FALSE if it isn't.
1616 gtk_color_selection_get_use_palette (GtkColorSelection *colorsel)
1618 ColorSelectionPrivate *priv;
1620 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1622 priv = colorsel->private_data;
1624 return priv->use_palette;
1628 * gtk_color_selection_set_use_palette:
1629 * @colorsel: A GtkColorSelection.
1630 * @use_palette: TRUE if palette is to be visible, FALSE otherwise.
1632 * Shows and hides the palette based upon the value of @use_palette.
1636 gtk_color_selection_set_use_palette (GtkColorSelection *colorsel,
1637 gboolean use_palette)
1639 ColorSelectionPrivate *priv;
1640 g_return_if_fail (colorsel != NULL);
1641 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1643 priv = colorsel->private_data;
1644 use_palette = use_palette != FALSE;
1646 if (priv->use_palette != use_palette)
1648 priv->use_palette = use_palette;
1650 gtk_widget_show (priv->palette_frame);
1652 gtk_widget_hide (priv->palette_frame);
1657 * gtk_color_selection_set_color:
1658 * @colorsel: A GtkColorSelection.
1659 * @color: A color to set the current color with.
1661 * Sets the current color to be @color. The first time this is called, it will
1662 * also set the original color to be @color too.
1666 gtk_color_selection_set_color (GtkColorSelection *colorsel,
1669 ColorSelectionPrivate *priv;
1672 g_return_if_fail (colorsel != NULL);
1673 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1675 priv = colorsel->private_data;
1676 priv->changing = TRUE;
1677 priv->color[COLORSEL_RED] = color[0];
1678 priv->color[COLORSEL_GREEN] = color[1];
1679 priv->color[COLORSEL_BLUE] = color[2];
1680 priv->color[COLORSEL_OPACITY] = color[3];
1681 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1682 priv->color[COLORSEL_GREEN],
1683 priv->color[COLORSEL_BLUE],
1684 &priv->color[COLORSEL_HUE],
1685 &priv->color[COLORSEL_SATURATION],
1686 &priv->color[COLORSEL_VALUE]);
1687 if (priv->default_set == FALSE)
1689 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
1690 priv->old_color[i] = priv->color[i];
1692 update_color (colorsel);
1693 priv->default_set = TRUE;
1697 * gtk_color_selection_get_color:
1698 * @colorsel: A GtkColorSelection.
1699 * @color: A color to fill in with the current color.
1701 * Sets @color to be the current color in the GtkColorSelection widget.
1705 gtk_color_selection_get_color (GtkColorSelection *colorsel,
1708 ColorSelectionPrivate *priv;
1710 g_return_if_fail (colorsel != NULL);
1711 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1713 priv = colorsel->private_data;
1714 color[0] = priv->color[COLORSEL_RED];
1715 color[1] = priv->color[COLORSEL_GREEN];
1716 color[2] = priv->color[COLORSEL_BLUE];
1717 color[3] = priv->use_opacity ? priv->color[COLORSEL_OPACITY] : 1.0;
1721 * gtk_color_selection_get_old_color:
1722 * @colorsel: A GtkColorSelection.
1723 * @color: A color to set the original color with.
1725 * Sets the 'original' color to be @color. This function should be called with
1726 * some hesitations, as it might seem confusing to have that color change.
1727 * Calling gtk_color_selection_set_color will also set this color the first
1728 * time it is called.
1732 gtk_color_selection_set_old_color (GtkColorSelection *colorsel,
1735 ColorSelectionPrivate *priv;
1737 g_return_if_fail (colorsel != NULL);
1738 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1740 priv = colorsel->private_data;
1741 priv->changing = TRUE;
1742 priv->old_color[COLORSEL_RED] = color[0];
1743 priv->old_color[COLORSEL_GREEN] = color[1];
1744 priv->old_color[COLORSEL_BLUE] = color[2];
1745 priv->old_color[COLORSEL_OPACITY] = color[3];
1746 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
1747 priv->old_color[COLORSEL_GREEN],
1748 priv->old_color[COLORSEL_BLUE],
1749 &priv->old_color[COLORSEL_HUE],
1750 &priv->old_color[COLORSEL_SATURATION],
1751 &priv->old_color[COLORSEL_VALUE]);
1752 color_sample_draw_samples (colorsel);
1753 priv->default_set = TRUE;
1757 * gtk_color_selection_get_old_color:
1758 * @colorsel: A GtkColorSelection.
1759 * @color: A color to fill in with the original color value.
1761 * Fills @color in with the original color value.
1765 gtk_color_selection_get_old_color (GtkColorSelection *colorsel,
1768 ColorSelectionPrivate *priv;
1770 g_return_if_fail (colorsel != NULL);
1771 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1773 priv = colorsel->private_data;
1774 color[0] = priv->old_color[COLORSEL_RED];
1775 color[1] = priv->old_color[COLORSEL_GREEN];
1776 color[2] = priv->old_color[COLORSEL_BLUE];
1777 color[3] = priv->use_opacity ? priv->old_color[COLORSEL_OPACITY] : 1.0;
1781 * gtk_color_selection_set_palette_color:
1782 * @colorsel: A GtkColorSelection.
1783 * @x: The x coordinate of the palette.
1784 * @y: The y coordinate of the palette.
1785 * @color: A color to set the palette with.
1787 * Set the palette located at (@x, @y) to have @color set as its color.
1791 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
1796 ColorSelectionPrivate *priv;
1798 g_return_if_fail (colorsel != NULL);
1799 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1800 g_return_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT);
1802 priv = colorsel->private_data;
1803 palette_set_color (priv->custom_palette[x][y], colorsel, color);
1807 * gtk_color_selection_get_palette_color:
1808 * @colorsel: A GtkColorSelection.
1809 * @x: The x coordinate of the palette.
1810 * @y: The y coordinate of the palette.
1811 * @color: A color to fill in with the color value.
1813 * Set @color to have the color found in the palette located at (@x, @y). If
1814 * the palette is unset, it will leave the color unset.
1816 * Return value: TRUE if the palette located at (@x, @y) has a color set. FALSE
1820 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
1825 ColorSelectionPrivate *priv;
1827 g_return_val_if_fail (colorsel != NULL, FALSE);
1828 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1829 g_return_val_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
1831 priv = colorsel->private_data;
1833 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
1836 palette_get_color (priv->custom_palette[x][y], color);
1841 * gtk_color_selection_unset_palette_color:
1842 * @colorsel: A GtkColorSelection.
1843 * @x: The x coordinate of the palette.
1844 * @y: The y coordinate of the palette.
1846 * Change the palette located at (@x, @y) to have no color set.
1850 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
1854 ColorSelectionPrivate *priv;
1856 g_return_if_fail (colorsel != NULL);
1857 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1858 g_return_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT);
1860 priv = colorsel->private_data;
1861 palette_unset_color (priv->custom_palette[x][y]);
1865 * gtk_color_selection_is_adjusting:
1866 * @colorsel: A GtkColorSelection.
1868 * Gets the current state of the @colorsel.
1870 * Return value: TRUE if the user is currently dragging a color around, and FALSE
1871 * if the selection has stopped.
1874 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
1876 ColorSelectionPrivate *priv;
1878 g_return_val_if_fail (colorsel != NULL, FALSE);
1879 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1881 priv = colorsel->private_data;
1883 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));