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 Lesser 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser 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-2000. 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)
32 #elif defined (GDK_WINDOWING_WIN32)
33 #include "win32/gdkwin32.h"
36 #include "gdk/gdkkeysyms.h"
37 #include "gtkcolorsel.h"
39 #include "gtkwindow.h"
40 #include "gtkselection.h"
42 #include "gtkdrawingarea.h"
43 #include "gtksignal.h"
50 #include "gtkpixmap.h"
51 #include "gtkspinbutton.h"
53 #include "gtkhscale.h"
55 #include "gtkbutton.h"
56 #include "gtkhseparator.h"
77 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
79 struct _ColorSelectionPrivate
81 guint use_opacity : 1;
82 guint use_palette : 1;
84 guint default_set : 1;
86 /* The color dropper */
87 guint moving_dropper : 1;
89 gdouble color[COLORSEL_NUM_CHANNELS];
90 gdouble old_color[COLORSEL_NUM_CHANNELS];
92 GtkWidget *triangle_colorsel;
93 GtkWidget *hue_spinbutton;
94 GtkWidget *sat_spinbutton;
95 GtkWidget *val_spinbutton;
96 GtkWidget *red_spinbutton;
97 GtkWidget *green_spinbutton;
98 GtkWidget *blue_spinbutton;
99 GtkWidget *opacity_slider;
100 GtkWidget *opacity_label;
101 GtkWidget *opacity_entry;
102 GtkWidget *palette_frame;
103 GtkWidget *hex_entry;
105 /* The Palette code */
106 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
107 GtkWidget *last_palette;
109 /* The color_sample stuff */
110 GtkWidget *sample_area;
111 GtkWidget *old_sample;
112 GtkWidget *cur_sample;
117 static void gtk_color_selection_init (GtkColorSelection *colorsel);
118 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
119 static void gtk_color_selection_destroy (GtkObject *object);
120 static void update_color (GtkColorSelection *colorsel);
122 static gpointer parent_class = NULL;
123 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
126 /* The cursor for the dropper */
127 #define DROPPER_WIDTH 17
128 #define DROPPER_HEIGHT 17
129 #define DROPPER_X_HOT 2
130 #define DROPPER_Y_HOT 16
133 static char dropper_bits[] = {
134 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
135 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
136 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
137 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
140 static char dropper_mask[] = {
141 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
142 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
143 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
144 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
147 static GdkCursor *picker_cursor = NULL;
151 static char *picker[] = {
152 /* columns rows colors chars-per-pixel */
163 "#########################",
164 "#########################",
165 "#########################",
166 "#########################",
167 "#########################",
168 "################# #####",
169 "################ ####",
170 "################ +###",
171 "############# +###",
172 "############## ++###",
173 "#############+@ +++####",
174 "############+@@@ +######",
175 "###########+@@@ + +######",
176 "##########+@@@ ++#+######",
177 "#########+@@@ ++#########",
178 "########+@@@ ++##########",
179 "#######+@@@ ++###########",
180 "######+@@@ ++############",
181 "######+@@ ++#############",
182 "#####+@ ++##############",
183 "###### +++###############",
184 "#########################",
185 "#########################",
186 "#########################",
187 "#########################"
196 #define SAMPLE_WIDTH 64
197 #define SAMPLE_HEIGHT 28
199 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
200 static void color_sample_draw_samples (GtkColorSelection *colorsel);
203 color_sample_drag_begin (GtkWidget *widget,
204 GdkDragContext *context,
207 GtkColorSelection *colorsel = data;
208 ColorSelectionPrivate *priv;
215 priv = colorsel->private_data;
216 window = gtk_window_new (GTK_WINDOW_POPUP);
217 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
218 gtk_widget_set_usize (window, 48, 32);
219 gtk_widget_realize (window);
220 gtk_object_set_data_full (GTK_OBJECT (widget),
221 "gtk-color-selection-drag-window",
223 (GtkDestroyNotify) gtk_widget_destroy);
225 if (widget == priv->old_sample)
226 colsrc = priv->old_color;
228 colsrc = priv->color;
230 for (i=0, n = COLORSEL_RED; n <= COLORSEL_BLUE; n++)
232 colors[i++] = colsrc[n];
235 if (priv->use_opacity)
237 colors[i] = colsrc[COLORSEL_OPACITY];
240 bg.red = 0xffff * colors[0];
241 bg.green = 0xffff * colors[1];
242 bg.blue = 0xffff * colors[2];
244 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
245 gdk_window_set_background (window->window, &bg);
247 gtk_drag_set_icon_widget (context, window, -2, -2);
251 color_sample_drag_end (GtkWidget *widget,
252 GdkDragContext *context,
255 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
259 color_sample_drop_handle (GtkWidget *widget,
260 GdkDragContext *context,
263 GtkSelectionData *selection_data,
268 GtkColorSelection *colorsel = data;
269 ColorSelectionPrivate *priv;
272 priv = colorsel->private_data;
274 /* This is currently a guint16 array of the format:
281 if (selection_data->length < 0)
284 if ((selection_data->format != 16) ||
285 (selection_data->length != 8))
287 g_warning ("Received invalid color data\n");
291 vals = (guint16 *)selection_data->data;
293 if (widget == priv->cur_sample)
295 color[0] = (gdouble)vals[0] / 0xffff;
296 color[1] = (gdouble)vals[1] / 0xffff;
297 color[2] = (gdouble)vals[2] / 0xffff;
298 color[3] = (gdouble)vals[3] / 0xffff;
300 gtk_color_selection_set_color (colorsel, color);
305 color_sample_drag_handle (GtkWidget *widget,
306 GdkDragContext *context,
307 GtkSelectionData *selection_data,
312 GtkColorSelection *colorsel = data;
313 ColorSelectionPrivate *priv;
317 priv = colorsel->private_data;
319 if (widget == priv->old_sample)
320 colsrc = priv->old_color;
322 colsrc = priv->color;
324 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
325 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
326 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
327 vals[3] = priv->use_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
329 gtk_selection_data_set (selection_data,
330 gdk_atom_intern ("application/x-color", FALSE),
331 16, (guchar *)vals, 8);
334 /* which = 0 means draw old sample, which = 1 means draw new */
336 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
339 gint x, y, i, wid, heig, f, n, goff;
340 guchar c[3 * 2], cc[3 * 4], *cp = c;
343 ColorSelectionPrivate *priv;
345 g_return_if_fail (colorsel != NULL);
346 priv = colorsel->private_data;
348 g_return_if_fail (priv->sample_area != NULL);
349 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
354 da = priv->old_sample;
355 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
356 c[n] = (guchar) (255.0 * priv->old_color[i]);
361 da = priv->cur_sample;
362 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
363 c[n] = (guchar) (255.0 * priv->color[i]);
364 goff = priv->old_sample->allocation.width % 32;
367 wid = da->allocation.width;
368 heig = da->allocation.height;
370 buf = g_new(guchar, 3 * wid * heig);
374 for (n = 0; n < 3; n++)
376 c[n] = (guchar) (255.0 * priv->old_color[i]);
377 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
381 if (priv->use_opacity)
383 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
385 for (n = 0; n < 3; n++)
387 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
388 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
394 for (y = 0; y < heig; y++)
396 for (x = 0; x < wid; x++)
398 if (priv->use_opacity)
399 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
403 for (n = 0; n < 3; n++)
404 buf[i++] = cp[n + f];
408 gdk_draw_rgb_image(da->window,
412 GDK_RGB_DITHER_NORMAL,
422 color_sample_draw_samples (GtkColorSelection *colorsel)
424 color_sample_draw_sample (colorsel, 0);
425 color_sample_draw_sample (colorsel, 1);
429 color_old_sample_expose(GtkWidget* da, GdkEventExpose* event, GtkColorSelection *colorsel)
431 color_sample_draw_sample (colorsel, 0);
436 color_cur_sample_expose(GtkWidget* da, GdkEventExpose* event, GtkColorSelection *colorsel)
438 color_sample_draw_sample (colorsel, 1);
442 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
444 static const GtkTargetEntry targets[] = {
445 { "application/x-color", 0 }
447 ColorSelectionPrivate *priv;
448 priv = colorsel->private_data;
450 gtk_drag_source_set (sample,
451 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
453 GDK_ACTION_COPY | GDK_ACTION_MOVE);
455 gtk_signal_connect (GTK_OBJECT (sample),
457 GTK_SIGNAL_FUNC (color_sample_drag_begin),
459 if (sample == priv->cur_sample)
462 gtk_drag_dest_set (sample,
463 GTK_DEST_DEFAULT_HIGHLIGHT |
464 GTK_DEST_DEFAULT_MOTION |
465 GTK_DEST_DEFAULT_DROP,
469 gtk_signal_connect (GTK_OBJECT (sample),
471 GTK_SIGNAL_FUNC (color_sample_drag_end),
475 gtk_signal_connect (GTK_OBJECT (sample),
477 GTK_SIGNAL_FUNC (color_sample_drag_handle),
479 gtk_signal_connect (GTK_OBJECT (sample),
480 "drag_data_received",
481 GTK_SIGNAL_FUNC (color_sample_drop_handle),
488 color_sample_new (GtkColorSelection *colorsel)
490 ColorSelectionPrivate *priv;
492 priv = colorsel->private_data;
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,
503 gtk_signal_connect(GTK_OBJECT (priv->old_sample), "expose_event",
504 GTK_SIGNAL_FUNC (color_old_sample_expose),
506 gtk_signal_connect(GTK_OBJECT (priv->cur_sample), "expose_event",
507 GTK_SIGNAL_FUNC (color_cur_sample_expose),
510 color_sample_setup_dnd (colorsel, priv->old_sample);
511 color_sample_setup_dnd (colorsel, priv->cur_sample);
513 gtk_widget_show_all (priv->sample_area);
519 * The palette area code
522 #define CUSTOM_PALETTE_ENTRY_WIDTH 16
523 #define CUSTOM_PALETTE_ENTRY_HEIGHT 16
526 palette_get_color (GtkWidget *drawing_area, gdouble *color)
530 g_return_if_fail (color != NULL);
532 color_val = gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
533 if (color_val == NULL)
535 /* Default to white for no good reason */
543 color[0] = color_val[0];
544 color[1] = color_val[1];
545 color[2] = color_val[2];
549 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
551 palette_paint (GtkWidget *drawing_area,
555 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
556 ColorSelectionPrivate *priv = colorsel->private_data;
558 if (drawing_area->window == NULL)
561 gdk_window_clear_area (drawing_area->window,
567 if (priv->last_palette == drawing_area)
572 palette_get_color (drawing_area, color);
574 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
575 gc = drawing_area->style->black_gc;
577 gc = drawing_area->style->white_gc;
579 gdk_draw_rectangle (drawing_area->window,
581 drawing_area->allocation.width - 1,
582 drawing_area->allocation.height - 1);
587 palette_expose (GtkWidget *drawing_area,
588 GdkEventExpose *event,
591 if (drawing_area->window == NULL)
594 palette_paint (drawing_area, &(event->area), data);
598 palette_press (GtkWidget *drawing_area,
599 GdkEventButton *event,
602 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
603 ColorSelectionPrivate *priv = colorsel->private_data;
605 if (priv->last_palette != NULL)
606 gtk_widget_queue_clear (priv->last_palette);
608 priv->last_palette = drawing_area;
610 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0)
613 palette_get_color (drawing_area, color);
614 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
617 gtk_widget_queue_clear (priv->last_palette);
621 palette_draw (GtkWidget *drawing_area,
625 palette_paint (drawing_area, area, data);
629 palette_unset_color (GtkWidget *drawing_area)
631 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
634 gtk_widget_reset_rc_styles (drawing_area);
635 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0));
639 palette_drag_begin (GtkWidget *widget,
640 GdkDragContext *context,
643 GtkColorSelection *colorsel = data;
644 ColorSelectionPrivate *priv;
649 priv = colorsel->private_data;
650 window = gtk_window_new (GTK_WINDOW_POPUP);
651 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
652 gtk_widget_set_usize (window, 48, 32);
653 gtk_widget_realize (window);
654 gtk_object_set_data_full (GTK_OBJECT (widget),
655 "gtk-color-selection-drag-window",
657 (GtkDestroyNotify) gtk_widget_destroy);
659 palette_get_color (widget, colors);
660 bg.red = 0xffff * colors[0];
661 bg.green = 0xffff * colors[1];
662 bg.blue = 0xffff * colors[2];
664 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
665 gdk_window_set_background (window->window, &bg);
667 gtk_drag_set_icon_widget (context, window, -2, -2);
671 palette_drag_handle (GtkWidget *widget,
672 GdkDragContext *context,
673 GtkSelectionData *selection_data,
681 palette_get_color (widget, colsrc);
683 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
684 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
685 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
688 gtk_selection_data_set (selection_data,
689 gdk_atom_intern ("application/x-color", FALSE),
690 16, (guchar *)vals, 8);
694 palette_set_color (GtkWidget *drawing_area,
695 GtkColorSelection *colorsel,
698 GtkRcStyle *rc_style;
699 gdouble *new_color = g_new (double, 4);
702 rc_style = gtk_rc_style_new ();
703 rc_style->bg[GTK_STATE_NORMAL].red = color[0]*65535;
704 rc_style->bg[GTK_STATE_NORMAL].green = color[1]*65535;
705 rc_style->bg[GTK_STATE_NORMAL].blue = color[2]*65535;
706 rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
707 gtk_rc_style_ref (rc_style);
708 gtk_widget_modify_style (drawing_area, rc_style);
710 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
712 static const GtkTargetEntry targets[] = {
713 { "application/x-color", 0 }
715 gtk_drag_source_set (drawing_area,
716 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
718 GDK_ACTION_COPY | GDK_ACTION_MOVE);
720 gtk_signal_connect (GTK_OBJECT (drawing_area),
722 GTK_SIGNAL_FUNC (palette_drag_begin),
724 gtk_signal_connect (GTK_OBJECT (drawing_area),
726 GTK_SIGNAL_FUNC (palette_drag_handle),
729 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
733 old_color = (gdouble *) gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
739 new_color[0] = color[0];
740 new_color[1] = color[1];
741 new_color[2] = color[2];
744 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_val", new_color);
748 palette_drag_end (GtkWidget *widget,
749 GdkDragContext *context,
752 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
756 palette_drop_handle (GtkWidget *widget,
757 GdkDragContext *context,
760 GtkSelectionData *selection_data,
768 if (selection_data->length < 0)
771 if ((selection_data->format != 16) ||
772 (selection_data->length != 8))
774 g_warning ("Received invalid color data\n");
778 vals = (guint16 *)selection_data->data;
780 color[0] = (gdouble)vals[0] / 0xffff;
781 color[1] = (gdouble)vals[1] / 0xffff;
782 color[2] = (gdouble)vals[2] / 0xffff;
783 color[3] = (gdouble)vals[3] / 0xffff;
784 palette_set_color (widget, GTK_COLOR_SELECTION (data), color);
785 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
789 palette_activate (GtkWidget *widget,
793 GtkColorSelection *colorsel = data;
794 ColorSelectionPrivate *priv;
796 if ((event->keyval == ' ') || (event->keyval == GDK_Return))
798 priv = colorsel->private_data;
799 palette_set_color (widget, GTK_COLOR_SELECTION (data), priv->color);
806 palette_new (GtkColorSelection *colorsel)
810 static const GtkTargetEntry targets[] = {
811 { "application/x-color", 0 }
814 retval = gtk_drawing_area_new ();
815 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
816 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK);
818 gtk_signal_connect (GTK_OBJECT (retval), "draw", palette_draw, colorsel);
819 gtk_signal_connect (GTK_OBJECT (retval), "expose_event", palette_expose, colorsel);
820 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event", palette_press, colorsel);
822 gtk_drag_dest_set (retval,
823 GTK_DEST_DEFAULT_HIGHLIGHT |
824 GTK_DEST_DEFAULT_MOTION |
825 GTK_DEST_DEFAULT_DROP,
829 gtk_signal_connect (GTK_OBJECT (retval), "drag_end", palette_drag_end, NULL);
830 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received", palette_drop_handle, colorsel);
831 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event", GTK_SIGNAL_FUNC (palette_activate), colorsel);
839 * The actual GtkColorSelection widget
844 initialize_cursor (void)
849 gdk_bitmap_create_from_data (NULL,
851 DROPPER_WIDTH, DROPPER_HEIGHT);
853 gdk_bitmap_create_from_data (NULL,
855 DROPPER_WIDTH, DROPPER_HEIGHT);
857 gdk_color_white (gdk_colormap_get_system (), &bg);
858 gdk_color_black (gdk_colormap_get_system (), &fg);
860 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
862 gdk_pixmap_unref (pixmap);
863 gdk_pixmap_unref (mask);
868 grab_color_at_mouse (GtkWidget *button,
876 GtkColorSelection *colorsel = data;
877 ColorSelectionPrivate *priv;
878 GdkColormap *colormap = gdk_colormap_get_system ();
879 #if defined (GDK_WINDOWING_X11)
883 priv = colorsel->private_data;
885 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
886 pixel = gdk_image_get_pixel (image, 0, 0);
887 visual = gdk_colormap_get_visual (colormap);
889 switch (visual->type) {
890 case GDK_VISUAL_DIRECT_COLOR:
891 case GDK_VISUAL_TRUE_COLOR:
892 priv->color[COLORSEL_RED] = (double)((pixel & visual->red_mask)>>visual->red_shift)/((1<<visual->red_prec) - 1);
893 priv->color[COLORSEL_GREEN] = (double)((pixel & visual->green_mask)>>visual->green_shift)/((1<<visual->green_prec) - 1);
894 priv->color[COLORSEL_BLUE] = (double)((pixel & visual->blue_mask)>>visual->blue_shift)/((1<<visual->blue_prec) - 1);
896 case GDK_VISUAL_STATIC_GRAY:
897 case GDK_VISUAL_GRAYSCALE:
898 priv->color[COLORSEL_RED] = (double)pixel/((1<<visual->depth) - 1);
899 priv->color[COLORSEL_GREEN] = (double)pixel/((1<<visual->depth) - 1);
900 priv->color[COLORSEL_BLUE] = (double)pixel/((1<<visual->depth) - 1);
902 #if defined (GDK_WINDOWING_X11)
903 case GDK_VISUAL_STATIC_COLOR:
904 xcolor.pixel = pixel;
905 XQueryColor (GDK_DISPLAY (), GDK_COLORMAP_XCOLORMAP (colormap), &xcolor);
906 priv->color[COLORSEL_RED] = xcolor.red/65535.0;
907 priv->color[COLORSEL_GREEN] = xcolor.green/65535.0;
908 priv->color[COLORSEL_BLUE] = xcolor.blue/65535.0;
911 case GDK_VISUAL_PSEUDO_COLOR:
912 priv->color[COLORSEL_RED] = colormap->colors[pixel].red/(double)0xffffff;
913 priv->color[COLORSEL_GREEN] = colormap->colors[pixel].green/(double)0xffffff;
914 priv->color[COLORSEL_BLUE] = colormap->colors[pixel].blue/(double)0xffffff;
917 g_assert_not_reached ();
921 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
922 priv->color[COLORSEL_GREEN],
923 priv->color[COLORSEL_BLUE],
924 &priv->color[COLORSEL_HUE],
925 &priv->color[COLORSEL_SATURATION],
926 &priv->color[COLORSEL_VALUE]);
927 update_color (colorsel);
931 mouse_motion (GtkWidget *button,
932 GdkEventMotion *event,
935 grab_color_at_mouse (button, event->x_root, event->y_root, data);
939 mouse_release (GtkWidget *button,
940 GdkEventButton *event,
943 GtkColorSelection *colorsel = data;
944 ColorSelectionPrivate *priv;
945 priv = colorsel->private_data;
947 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_motion, data);
948 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_release, data);
950 grab_color_at_mouse (button, event->x_root, event->y_root, data);
951 gdk_pointer_ungrab (0);
954 /* Helper Functions */
956 mouse_press (GtkWidget *button,
957 GdkEventButton *event,
960 GtkColorSelection *colorsel = data;
961 ColorSelectionPrivate *priv;
962 priv = colorsel->private_data;
964 gtk_signal_connect (GTK_OBJECT (button), "motion_notify_event", mouse_motion, data);
965 gtk_signal_connect (GTK_OBJECT (button), "button_release_event", mouse_release, data);
966 gtk_signal_disconnect_by_func (GTK_OBJECT (button), mouse_press, data);
969 /* when the button is clicked */
971 get_screen_color (GtkWidget *button)
973 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
974 ColorSelectionPrivate *priv = colorsel->private_data;
976 if (picker_cursor == NULL)
978 initialize_cursor ();
981 /* Why do we do this? Because the "clicked" signal will be emitted after the "button_released"
982 signal. We don't want to do this stuff again, though, or else it will get trapped here. So,
983 priv->moving_dropper is initialized to FALSE at the initialization of the colorselector,
984 it is initialized to true when we start waiting for the user to click the the dropper on a
985 color, and whenver it is true when this function starts to execute, we set it to false. */
986 if (priv->moving_dropper == FALSE)
988 priv->moving_dropper = TRUE;
989 gtk_signal_connect (GTK_OBJECT (button), "button_press_event", mouse_press, colorsel);
991 gdk_pointer_grab (button->window,
993 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1000 priv->moving_dropper = FALSE;
1005 hex_changed (GtkWidget *hex_entry,
1008 GtkColorSelection *colorsel;
1009 ColorSelectionPrivate *priv;
1013 colorsel = GTK_COLOR_SELECTION (data);
1014 priv = colorsel->private_data;
1019 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1020 if (gdk_color_parse (text, &color))
1022 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1023 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1024 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1025 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1026 priv->color[COLORSEL_GREEN],
1027 priv->color[COLORSEL_BLUE],
1028 &priv->color[COLORSEL_HUE],
1029 &priv->color[COLORSEL_SATURATION],
1030 &priv->color[COLORSEL_VALUE]);
1031 update_color (colorsel);
1037 hsv_changed (GtkWidget *hsv,
1040 GtkColorSelection *colorsel;
1041 ColorSelectionPrivate *priv;
1043 colorsel = GTK_COLOR_SELECTION (data);
1044 priv = colorsel->private_data;
1049 gtk_hsv_get_color (GTK_HSV (hsv),
1050 &priv->color[COLORSEL_HUE],
1051 &priv->color[COLORSEL_SATURATION],
1052 &priv->color[COLORSEL_VALUE]);
1053 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1054 priv->color[COLORSEL_SATURATION],
1055 priv->color[COLORSEL_VALUE],
1056 &priv->color[COLORSEL_RED],
1057 &priv->color[COLORSEL_GREEN],
1058 &priv->color[COLORSEL_BLUE]);
1059 update_color (colorsel);
1063 adjustment_changed (GtkAdjustment *adjustment,
1066 GtkColorSelection *colorsel;
1067 ColorSelectionPrivate *priv;
1069 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1070 priv = colorsel->private_data;
1075 switch (GPOINTER_TO_INT (data))
1077 case COLORSEL_SATURATION:
1078 case COLORSEL_VALUE:
1079 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1080 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1081 priv->color[COLORSEL_SATURATION],
1082 priv->color[COLORSEL_VALUE],
1083 &priv->color[COLORSEL_RED],
1084 &priv->color[COLORSEL_GREEN],
1085 &priv->color[COLORSEL_BLUE]);
1088 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1089 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1090 priv->color[COLORSEL_SATURATION],
1091 priv->color[COLORSEL_VALUE],
1092 &priv->color[COLORSEL_RED],
1093 &priv->color[COLORSEL_GREEN],
1094 &priv->color[COLORSEL_BLUE]);
1097 case COLORSEL_GREEN:
1099 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1101 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1102 priv->color[COLORSEL_GREEN],
1103 priv->color[COLORSEL_BLUE],
1104 &priv->color[COLORSEL_HUE],
1105 &priv->color[COLORSEL_SATURATION],
1106 &priv->color[COLORSEL_VALUE]);
1109 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1112 update_color (colorsel);
1116 opacity_entry_changed (GtkWidget *opacity_entry,
1119 GtkColorSelection *colorsel;
1120 ColorSelectionPrivate *priv;
1124 colorsel = GTK_COLOR_SELECTION (data);
1125 priv = colorsel->private_data;
1130 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1131 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1132 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1134 update_color (colorsel);
1140 widget_focus_in (GtkWidget *drawing_area,
1141 GdkEventFocus *event,
1144 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1145 ColorSelectionPrivate *priv = colorsel->private_data;
1147 /* This signal is connected to by all of the widgets except the "Set Color" button
1148 * This will let you add a color to the currently selected palette
1151 priv->last_palette = NULL;
1156 make_label_spinbutton (GtkColorSelection *colorsel,
1157 GtkWidget **spinbutton,
1165 GtkAdjustment *adjust;
1167 if (channel_type == COLORSEL_HUE)
1169 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1173 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1175 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1176 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1177 gtk_signal_connect (GTK_OBJECT (*spinbutton), "focus_in_event", widget_focus_in, colorsel);
1178 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed", adjustment_changed, GINT_TO_POINTER (channel_type));
1179 label = gtk_label_new (text);
1180 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1181 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1182 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1187 make_palette_frame (GtkColorSelection *colorsel,
1193 ColorSelectionPrivate *priv;
1195 priv = colorsel->private_data;
1196 frame = gtk_frame_new (NULL);
1197 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1198 priv->custom_palette[i][j] = palette_new (colorsel);
1199 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1200 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1201 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1204 /* Set the palette entry [x][y] to be the currently selected one. */
1206 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1208 ColorSelectionPrivate *priv = colorsel->private_data;
1210 if (priv->last_palette != NULL)
1211 gtk_widget_queue_clear (priv->last_palette);
1213 priv->last_palette = priv->custom_palette[x][y];
1215 gtk_widget_queue_clear (priv->last_palette);
1219 update_color (GtkColorSelection *colorsel)
1221 ColorSelectionPrivate *priv = colorsel->private_data;
1223 gchar opacity_text[32];
1226 priv->changing = TRUE;
1227 color_sample_draw_samples (colorsel);
1229 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1230 priv->color[COLORSEL_HUE],
1231 priv->color[COLORSEL_SATURATION],
1232 priv->color[COLORSEL_VALUE]);
1233 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1234 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1235 priv->color[COLORSEL_HUE] * 360);
1236 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1237 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1238 priv->color[COLORSEL_SATURATION] * 255);
1239 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1240 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1241 priv->color[COLORSEL_VALUE] * 255);
1242 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1243 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1244 priv->color[COLORSEL_RED] * 255);
1245 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1246 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1247 priv->color[COLORSEL_GREEN] * 255);
1248 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1249 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1250 priv->color[COLORSEL_BLUE] * 255);
1251 gtk_adjustment_set_value (gtk_range_get_adjustment
1252 (GTK_RANGE (priv->opacity_slider)),
1253 priv->color[COLORSEL_OPACITY] * 255);
1255 g_snprintf (opacity_text, 32, "%.0f", priv->color[COLORSEL_OPACITY] * 255);
1256 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1258 g_snprintf (entryval, 11, "#%2X%2X%2X",
1259 (guint) (255 * priv->color[COLORSEL_RED]),
1260 (guint) (255 * priv->color[COLORSEL_GREEN]),
1261 (guint) (255 * priv->color[COLORSEL_BLUE]));
1263 for (ptr = entryval; *ptr; ptr++)
1266 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1267 priv->changing = FALSE;
1271 add_button_pressed (GtkWidget *button,
1272 GtkColorSelection *colorsel)
1274 ColorSelectionPrivate *priv;
1277 priv = colorsel->private_data;
1279 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1281 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1283 /* Either last_palette is set and we're on it, or it's an empty palette */
1284 if ((priv->last_palette && priv->last_palette == priv->custom_palette[i][j]) ||
1285 ((priv->last_palette == NULL) &&
1286 (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[i][j]),
1287 "color_set")) == 0)))
1289 palette_set_color (priv->custom_palette[i][j], colorsel, priv->color);
1291 /* forward the selection */
1292 if ((i == GTK_CUSTOM_PALETTE_WIDTH - 1) && (j == GTK_CUSTOM_PALETTE_HEIGHT - 1))
1293 set_selected_palette (colorsel, 0, 0);
1294 else if (i == GTK_CUSTOM_PALETTE_WIDTH - 1)
1295 set_selected_palette (colorsel, 0, j + 1);
1297 set_selected_palette (colorsel, i + 1, j);
1304 /* the palette is totally full. Add to the first one totally arbitrarily */
1305 palette_set_color (priv->custom_palette[0][0], colorsel, priv->color);
1307 /* forward the selection */
1308 set_selected_palette (colorsel, 1, 0);
1312 gtk_color_selection_get_type (void)
1314 static GtkType color_selection_type = 0;
1316 if (!color_selection_type)
1318 static const GtkTypeInfo color_selection_info =
1320 "GtkColorSelection",
1321 sizeof (GtkColorSelection),
1322 sizeof (GtkColorSelectionClass),
1323 (GtkClassInitFunc) gtk_color_selection_class_init,
1324 (GtkObjectInitFunc) gtk_color_selection_init,
1325 /* reserved_1 */ NULL,
1326 /* reserved_2 */ NULL,
1327 (GtkClassInitFunc) NULL,
1330 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1333 return color_selection_type;
1337 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1339 GtkObjectClass *object_class;
1341 object_class = (GtkObjectClass*) klass;
1343 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1345 color_selection_signals[COLOR_CHANGED] =
1346 gtk_signal_new ("color_changed",
1348 GTK_CLASS_TYPE (object_class),
1349 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1350 gtk_marshal_NONE__NONE,
1354 gtk_object_class_add_signals (object_class, color_selection_signals, LAST_SIGNAL);
1356 object_class->destroy = gtk_color_selection_destroy;
1359 /* widget functions */
1361 gtk_color_selection_init (GtkColorSelection *colorsel)
1363 GtkWidget *top_hbox;
1364 GtkWidget *top_right_vbox;
1365 GtkWidget *table, *label, *hbox, *frame, *vbox;
1366 GtkAdjustment *adjust;
1367 GdkPixmap *dropper_pixmap;
1368 GtkWidget *dropper_image;
1370 GdkBitmap *mask = NULL;
1372 ColorSelectionPrivate *priv;
1374 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1375 priv->changing = FALSE;
1376 priv->default_set = FALSE;
1377 priv->last_palette = NULL;
1378 priv->moving_dropper = FALSE;
1380 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1381 top_hbox = gtk_hbox_new (FALSE, 8);
1382 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1384 vbox = gtk_vbox_new (FALSE, 4);
1385 priv->triangle_colorsel = gtk_hsv_new ();
1386 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed", hsv_changed, colorsel);
1387 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1388 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1389 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1391 hbox = gtk_hbox_new (FALSE, 4);
1392 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1394 frame = gtk_frame_new (NULL);
1395 gtk_widget_set_usize (frame, -1, 30);
1396 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1397 color_sample_new (colorsel);
1398 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1399 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1401 button = gtk_button_new ();
1402 gtk_signal_connect (GTK_OBJECT (button), "focus_in_event", widget_focus_in, colorsel);
1403 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1404 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1405 gtk_signal_connect (GTK_OBJECT (button), "clicked", get_screen_color, NULL);
1406 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1407 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1408 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1409 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1411 top_right_vbox = gtk_vbox_new (FALSE, 4);
1412 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1413 table = gtk_table_new (8, 6, FALSE);
1414 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1415 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1416 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1418 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("Hue:"), table, 0, 0, COLORSEL_HUE);
1419 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("Saturation:"), table, 0, 1, COLORSEL_SATURATION);
1420 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("Value:"), table, 0, 2, COLORSEL_VALUE);
1421 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("Red:"), table, 6, 0, COLORSEL_RED);
1422 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("Green:"), table, 6, 1, COLORSEL_GREEN);
1423 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("Blue:"), table, 6, 2, COLORSEL_BLUE);
1424 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1426 priv->opacity_label = gtk_label_new (_("Opacity:"));
1427 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1428 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1429 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1430 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1431 priv->opacity_slider = gtk_hscale_new (adjust);
1432 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1433 gtk_signal_connect (GTK_OBJECT(adjust), "value_changed", adjustment_changed, GINT_TO_POINTER (COLORSEL_OPACITY));
1434 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1435 priv->opacity_entry = gtk_entry_new ();
1436 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1437 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "focus_in_event", widget_focus_in, colorsel);
1438 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate", opacity_entry_changed, colorsel);
1439 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1441 label = gtk_label_new (_("Hex Value:"));
1442 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1443 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1444 priv->hex_entry = gtk_entry_new ();
1445 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate", hex_changed, colorsel);
1446 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1447 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1448 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1450 /* Set up the palette */
1451 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1452 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1453 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1454 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1456 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1458 make_palette_frame (colorsel, table, i, j);
1461 set_selected_palette (colorsel, 0, 0);
1462 priv->palette_frame = gtk_frame_new (_("Custom Palette"));
1463 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1464 vbox = gtk_vbox_new (FALSE, 4);
1465 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1466 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1467 button = gtk_button_new_with_label (_("Set Color"));
1468 gtk_signal_connect (GTK_OBJECT (button), "clicked", add_button_pressed, colorsel);
1469 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1470 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1472 gtk_widget_show_all (top_hbox);
1474 if (priv->use_opacity == FALSE)
1476 gtk_widget_hide (priv->opacity_label);
1477 gtk_widget_hide (priv->opacity_slider);
1478 gtk_widget_hide (priv->opacity_entry);
1481 if (priv->use_palette == FALSE)
1483 gtk_widget_hide (priv->palette_frame);
1488 gtk_color_selection_destroy (GtkObject *object)
1490 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1492 if (cselection->private_data)
1494 g_free (cselection->private_data);
1495 cselection->private_data = NULL;
1498 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1504 * gtk_color_selection_new:
1507 * Creates a new GtkColorSelection.
1509 * Return value: The new GtkColorSelection.
1512 gtk_color_selection_new (void)
1514 GtkColorSelection *colorsel;
1515 ColorSelectionPrivate *priv;
1522 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
1523 priv = colorsel->private_data;
1524 gtk_color_selection_set_color (colorsel, color);
1525 gtk_color_selection_set_use_opacity (colorsel, FALSE);
1527 /* We want to make sure that default_set is FALSE */
1528 /* This way the user can still set it */
1529 priv->default_set = FALSE;
1531 return GTK_WIDGET (colorsel);
1536 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
1537 GtkUpdateType policy)
1539 g_return_if_fail (colorsel != NULL);
1540 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1542 g_warning (G_STRLOC ": This function is deprecated.");
1546 * gtk_color_selection_get_use_opacity:
1547 * @colorsel: A GtkColorSelection.
1549 * Determines whether the colorsel can use opacity.
1551 * Return value: TRUE if the @colorsel uses opacity. FALSE if it does't.
1554 gtk_color_selection_get_use_opacity (GtkColorSelection *colorsel)
1556 ColorSelectionPrivate *priv;
1558 g_return_val_if_fail (colorsel != NULL, FALSE);
1559 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1561 priv = colorsel->private_data;
1563 return priv->use_opacity;
1567 * gtk_color_selection_set_use_opacity:
1568 * @colorsel: A GtkColorSelection.
1569 * @use_opacity: TRUE if @colorsel can set the opacity, FALSE otherwise.
1571 * Sets the @colorsel to use or not use opacity.
1575 gtk_color_selection_set_use_opacity (GtkColorSelection *colorsel,
1576 gboolean use_opacity)
1578 ColorSelectionPrivate *priv;
1580 g_return_if_fail (colorsel != NULL);
1581 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1583 priv = colorsel->private_data;
1584 use_opacity = use_opacity != FALSE;
1586 if (priv->use_opacity != use_opacity)
1588 priv->use_opacity = use_opacity;
1591 gtk_widget_show (priv->opacity_slider);
1592 gtk_widget_show (priv->opacity_label);
1593 gtk_widget_show (priv->opacity_entry);
1597 gtk_widget_hide (priv->opacity_slider);
1598 gtk_widget_hide (priv->opacity_label);
1599 gtk_widget_hide (priv->opacity_entry);
1601 color_sample_draw_samples (colorsel);
1606 * gtk_color_selection_get_use_palette:
1607 * @colorsel: A GtkColorSelection.
1609 * Determines whether the palette is used.
1611 * Return value: TRUE if the palette is used. FALSE if it isn't.
1614 gtk_color_selection_get_use_palette (GtkColorSelection *colorsel)
1616 ColorSelectionPrivate *priv;
1618 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1620 priv = colorsel->private_data;
1622 return priv->use_palette;
1626 * gtk_color_selection_set_use_palette:
1627 * @colorsel: A GtkColorSelection.
1628 * @use_palette: TRUE if palette is to be visible, FALSE otherwise.
1630 * Shows and hides the palette based upon the value of @use_palette.
1634 gtk_color_selection_set_use_palette (GtkColorSelection *colorsel,
1635 gboolean use_palette)
1637 ColorSelectionPrivate *priv;
1638 g_return_if_fail (colorsel != NULL);
1639 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1641 priv = colorsel->private_data;
1642 use_palette = use_palette != FALSE;
1644 if (priv->use_palette != use_palette)
1646 priv->use_palette = use_palette;
1648 gtk_widget_show (priv->palette_frame);
1650 gtk_widget_hide (priv->palette_frame);
1655 * gtk_color_selection_set_color:
1656 * @colorsel: A GtkColorSelection.
1657 * @color: A color to set the current color with.
1659 * Sets the current color to be @color. The first time this is called, it will
1660 * also set the original color to be @color too.
1664 gtk_color_selection_set_color (GtkColorSelection *colorsel,
1667 ColorSelectionPrivate *priv;
1670 g_return_if_fail (colorsel != NULL);
1671 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1673 priv = colorsel->private_data;
1674 priv->changing = TRUE;
1675 priv->color[COLORSEL_RED] = color[0];
1676 priv->color[COLORSEL_GREEN] = color[1];
1677 priv->color[COLORSEL_BLUE] = color[2];
1678 priv->color[COLORSEL_OPACITY] = color[3];
1679 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1680 priv->color[COLORSEL_GREEN],
1681 priv->color[COLORSEL_BLUE],
1682 &priv->color[COLORSEL_HUE],
1683 &priv->color[COLORSEL_SATURATION],
1684 &priv->color[COLORSEL_VALUE]);
1685 if (priv->default_set == FALSE)
1687 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
1688 priv->old_color[i] = priv->color[i];
1690 update_color (colorsel);
1691 priv->default_set = TRUE;
1695 * gtk_color_selection_get_color:
1696 * @colorsel: A GtkColorSelection.
1697 * @color: A color to fill in with the current color.
1699 * Sets @color to be the current color in the GtkColorSelection widget.
1703 gtk_color_selection_get_color (GtkColorSelection *colorsel,
1706 ColorSelectionPrivate *priv;
1708 g_return_if_fail (colorsel != NULL);
1709 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1711 priv = colorsel->private_data;
1712 color[0] = priv->color[COLORSEL_RED];
1713 color[1] = priv->color[COLORSEL_GREEN];
1714 color[2] = priv->color[COLORSEL_BLUE];
1715 color[3] = priv->use_opacity ? priv->color[COLORSEL_OPACITY] : 1.0;
1719 * gtk_color_selection_get_old_color:
1720 * @colorsel: A GtkColorSelection.
1721 * @color: A color to set the original color with.
1723 * Sets the 'original' color to be @color. This function should be called with
1724 * some hesitations, as it might seem confusing to have that color change.
1725 * Calling gtk_color_selection_set_color will also set this color the first
1726 * time it is called.
1730 gtk_color_selection_set_old_color (GtkColorSelection *colorsel,
1733 ColorSelectionPrivate *priv;
1735 g_return_if_fail (colorsel != NULL);
1736 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1738 priv = colorsel->private_data;
1739 priv->changing = TRUE;
1740 priv->old_color[COLORSEL_RED] = color[0];
1741 priv->old_color[COLORSEL_GREEN] = color[1];
1742 priv->old_color[COLORSEL_BLUE] = color[2];
1743 priv->old_color[COLORSEL_OPACITY] = color[3];
1744 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
1745 priv->old_color[COLORSEL_GREEN],
1746 priv->old_color[COLORSEL_BLUE],
1747 &priv->old_color[COLORSEL_HUE],
1748 &priv->old_color[COLORSEL_SATURATION],
1749 &priv->old_color[COLORSEL_VALUE]);
1750 color_sample_draw_samples (colorsel);
1751 priv->default_set = TRUE;
1755 * gtk_color_selection_get_old_color:
1756 * @colorsel: A GtkColorSelection.
1757 * @color: A color to fill in with the original color value.
1759 * Fills @color in with the original color value.
1763 gtk_color_selection_get_old_color (GtkColorSelection *colorsel,
1766 ColorSelectionPrivate *priv;
1768 g_return_if_fail (colorsel != NULL);
1769 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1771 priv = colorsel->private_data;
1772 color[0] = priv->old_color[COLORSEL_RED];
1773 color[1] = priv->old_color[COLORSEL_GREEN];
1774 color[2] = priv->old_color[COLORSEL_BLUE];
1775 color[3] = priv->use_opacity ? priv->old_color[COLORSEL_OPACITY] : 1.0;
1779 * gtk_color_selection_set_palette_color:
1780 * @colorsel: A GtkColorSelection.
1781 * @x: The x coordinate of the palette.
1782 * @y: The y coordinate of the palette.
1783 * @color: A color to set the palette with.
1785 * Set the palette located at (@x, @y) to have @color set as its color.
1789 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
1794 ColorSelectionPrivate *priv;
1796 g_return_if_fail (colorsel != NULL);
1797 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1798 g_return_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT);
1800 priv = colorsel->private_data;
1801 palette_set_color (priv->custom_palette[x][y], colorsel, color);
1805 * gtk_color_selection_get_palette_color:
1806 * @colorsel: A GtkColorSelection.
1807 * @x: The x coordinate of the palette.
1808 * @y: The y coordinate of the palette.
1809 * @color: A color to fill in with the color value.
1811 * Set @color to have the color found in the palette located at (@x, @y). If
1812 * the palette is unset, it will leave the color unset.
1814 * Return value: TRUE if the palette located at (@x, @y) has a color set. FALSE
1818 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
1823 ColorSelectionPrivate *priv;
1825 g_return_val_if_fail (colorsel != NULL, FALSE);
1826 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1827 g_return_val_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
1829 priv = colorsel->private_data;
1831 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
1834 palette_get_color (priv->custom_palette[x][y], color);
1839 * gtk_color_selection_unset_palette_color:
1840 * @colorsel: A GtkColorSelection.
1841 * @x: The x coordinate of the palette.
1842 * @y: The y coordinate of the palette.
1844 * Change the palette located at (@x, @y) to have no color set.
1848 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
1852 ColorSelectionPrivate *priv;
1854 g_return_if_fail (colorsel != NULL);
1855 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1856 g_return_if_fail (x >= 0 && y >= 0 && x < GTK_CUSTOM_PALETTE_WIDTH && y < GTK_CUSTOM_PALETTE_HEIGHT);
1858 priv = colorsel->private_data;
1859 palette_unset_color (priv->custom_palette[x][y]);
1863 * gtk_color_selection_is_adjusting:
1864 * @colorsel: A GtkColorSelection.
1866 * Gets the current state of the @colorsel.
1868 * Return value: TRUE if the user is currently dragging a color around, and FALSE
1869 * if the selection has stopped.
1872 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
1874 ColorSelectionPrivate *priv;
1876 g_return_val_if_fail (colorsel != NULL, FALSE);
1877 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1879 priv = colorsel->private_data;
1881 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));