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"
31 #if defined (GDK_WINDOWING_X11)
33 #elif defined (GDK_WINDOWING_WIN32)
34 #include "win32/gdkwin32.h"
35 #elif defined (GDK_WINDOWING_FB)
36 #include "linux-fb/gdkfb.h"
39 #include "gdk/gdkkeysyms.h"
40 #include "gtkcolorsel.h"
42 #include "gtkwindow.h"
43 #include "gtkselection.h"
45 #include "gtkdrawingarea.h"
46 #include "gtksignal.h"
53 #include "gtkpixmap.h"
54 #include "gtkspinbutton.h"
56 #include "gtkhscale.h"
58 #include "gtkbutton.h"
59 #include "gtkhseparator.h"
60 #include "gtktooltips.h"
61 #include "gtkinvisible.h"
62 #include "gtkmenuitem.h"
64 #include "gtksettings.h"
69 /* Number of elements in the custom palatte */
70 #define GTK_CUSTOM_PALETTE_WIDTH 10
71 #define GTK_CUSTOM_PALETTE_HEIGHT 2
89 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
91 struct _ColorSelectionPrivate
93 guint has_opacity : 1;
94 guint has_palette : 1;
96 guint default_set : 1;
97 guint default_alpha_set : 1;
99 gdouble color[COLORSEL_NUM_CHANNELS];
100 gdouble old_color[COLORSEL_NUM_CHANNELS];
102 GtkWidget *triangle_colorsel;
103 GtkWidget *hue_spinbutton;
104 GtkWidget *sat_spinbutton;
105 GtkWidget *val_spinbutton;
106 GtkWidget *red_spinbutton;
107 GtkWidget *green_spinbutton;
108 GtkWidget *blue_spinbutton;
109 GtkWidget *opacity_slider;
110 GtkWidget *opacity_label;
111 GtkWidget *opacity_entry;
112 GtkWidget *palette_frame;
113 GtkWidget *hex_entry;
115 /* The Palette code */
116 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
118 /* The color_sample stuff */
119 GtkWidget *sample_area;
120 GtkWidget *old_sample;
121 GtkWidget *cur_sample;
125 GtkTooltips *tooltips;
127 /* Window for grabbing on */
128 GtkWidget *dropper_grab_widget;
132 static void gtk_color_selection_init (GtkColorSelection *colorsel);
133 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
134 static void gtk_color_selection_destroy (GtkObject *object);
135 static void gtk_color_selection_finalize (GObject *object);
136 static void update_color (GtkColorSelection *colorsel);
138 static gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel);
139 static gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
142 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
145 static void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
148 static gpointer parent_class = NULL;
149 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
151 static gchar* default_colors = "black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90";
153 static GtkColorSelectionChangePaletteFunc change_palette_hook = NULL;
155 static GdkColor current_colors[GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT];
157 /* The cursor for the dropper */
158 #define DROPPER_WIDTH 17
159 #define DROPPER_HEIGHT 17
160 #define DROPPER_X_HOT 2
161 #define DROPPER_Y_HOT 16
164 static char dropper_bits[] = {
165 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
166 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
167 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
168 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
171 static char dropper_mask[] = {
172 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
173 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
174 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
175 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
178 static GdkCursor *picker_cursor = NULL;
182 static char *picker[] = {
183 /* columns rows colors chars-per-pixel */
194 "#########################",
195 "#########################",
196 "#########################",
197 "#########################",
198 "#########################",
199 "################# #####",
200 "################ ####",
201 "################ +###",
202 "############# +###",
203 "############## ++###",
204 "#############+@ +++####",
205 "############+@@@ +######",
206 "###########+@@@ + +######",
207 "##########+@@@ ++#+######",
208 "#########+@@@ ++#########",
209 "########+@@@ ++##########",
210 "#######+@@@ ++###########",
211 "######+@@@ ++############",
212 "######+@@ ++#############",
213 "#####+@ ++##############",
214 "###### +++###############",
215 "#########################",
216 "#########################",
217 "#########################",
218 "#########################"
227 #define SAMPLE_WIDTH 64
228 #define SAMPLE_HEIGHT 28
230 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
231 static void color_sample_draw_samples (GtkColorSelection *colorsel);
234 color_sample_drag_begin (GtkWidget *widget,
235 GdkDragContext *context,
238 GtkColorSelection *colorsel = data;
239 ColorSelectionPrivate *priv;
246 priv = colorsel->private_data;
247 window = gtk_window_new (GTK_WINDOW_POPUP);
248 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
249 gtk_widget_set_usize (window, 48, 32);
250 gtk_widget_realize (window);
251 gtk_object_set_data_full (GTK_OBJECT (widget),
252 "gtk-color-selection-drag-window",
254 (GtkDestroyNotify) gtk_widget_destroy);
256 if (widget == priv->old_sample)
257 colsrc = priv->old_color;
259 colsrc = priv->color;
261 for (i=0, n = COLORSEL_RED; n <= COLORSEL_BLUE; n++)
263 colors[i++] = colsrc[n];
266 if (priv->has_opacity)
268 colors[i] = colsrc[COLORSEL_OPACITY];
271 bg.red = 0xffff * colors[0];
272 bg.green = 0xffff * colors[1];
273 bg.blue = 0xffff * colors[2];
275 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
276 gdk_window_set_background (window->window, &bg);
278 gtk_drag_set_icon_widget (context, window, -2, -2);
282 color_sample_drag_end (GtkWidget *widget,
283 GdkDragContext *context,
286 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
290 color_sample_drop_handle (GtkWidget *widget,
291 GdkDragContext *context,
294 GtkSelectionData *selection_data,
299 GtkColorSelection *colorsel = data;
300 ColorSelectionPrivate *priv;
303 priv = colorsel->private_data;
305 /* This is currently a guint16 array of the format:
312 if (selection_data->length < 0)
315 if ((selection_data->format != 16) ||
316 (selection_data->length != 8))
318 g_warning ("Received invalid color data\n");
322 vals = (guint16 *)selection_data->data;
324 if (widget == priv->cur_sample)
326 color[0] = (gdouble)vals[0] / 0xffff;
327 color[1] = (gdouble)vals[1] / 0xffff;
328 color[2] = (gdouble)vals[2] / 0xffff;
329 color[3] = (gdouble)vals[3] / 0xffff;
331 gtk_color_selection_set_color (colorsel, color);
336 color_sample_drag_handle (GtkWidget *widget,
337 GdkDragContext *context,
338 GtkSelectionData *selection_data,
343 GtkColorSelection *colorsel = data;
344 ColorSelectionPrivate *priv;
348 priv = colorsel->private_data;
350 if (widget == priv->old_sample)
351 colsrc = priv->old_color;
353 colsrc = priv->color;
355 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
356 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
357 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
358 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
360 gtk_selection_data_set (selection_data,
361 gdk_atom_intern ("application/x-color", FALSE),
362 16, (guchar *)vals, 8);
365 /* which = 0 means draw old sample, which = 1 means draw new */
367 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
370 gint x, y, i, wid, heig, f, n, goff;
371 guchar c[3 * 2], cc[3 * 4], *cp = c;
374 ColorSelectionPrivate *priv;
376 g_return_if_fail (colorsel != NULL);
377 priv = colorsel->private_data;
379 g_return_if_fail (priv->sample_area != NULL);
380 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
385 da = priv->old_sample;
386 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
387 c[n] = (guchar) (255.0 * priv->old_color[i]);
392 da = priv->cur_sample;
393 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
394 c[n] = (guchar) (255.0 * priv->color[i]);
395 goff = priv->old_sample->allocation.width % 32;
398 wid = da->allocation.width;
399 heig = da->allocation.height;
401 buf = g_new(guchar, 3 * wid * heig);
405 for (n = 0; n < 3; n++)
407 c[n] = (guchar) (255.0 * priv->old_color[i]);
408 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
412 if (priv->has_opacity)
414 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
416 for (n = 0; n < 3; n++)
418 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
419 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
425 for (y = 0; y < heig; y++)
427 for (x = 0; x < wid; x++)
429 if (priv->has_opacity)
430 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
434 for (n = 0; n < 3; n++)
435 buf[i++] = cp[n + f];
439 gdk_draw_rgb_image(da->window,
443 GDK_RGB_DITHER_NORMAL,
453 color_sample_draw_samples (GtkColorSelection *colorsel)
455 color_sample_draw_sample (colorsel, 0);
456 color_sample_draw_sample (colorsel, 1);
460 color_old_sample_expose(GtkWidget* da, GdkEventExpose* event, GtkColorSelection *colorsel)
462 color_sample_draw_sample (colorsel, 0);
467 color_cur_sample_expose(GtkWidget* da, GdkEventExpose* event, GtkColorSelection *colorsel)
469 color_sample_draw_sample (colorsel, 1);
473 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
475 static const GtkTargetEntry targets[] = {
476 { "application/x-color", 0 }
478 ColorSelectionPrivate *priv;
479 priv = colorsel->private_data;
481 gtk_drag_source_set (sample,
482 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
484 GDK_ACTION_COPY | GDK_ACTION_MOVE);
486 gtk_signal_connect (GTK_OBJECT (sample),
488 GTK_SIGNAL_FUNC (color_sample_drag_begin),
490 if (sample == priv->cur_sample)
493 gtk_drag_dest_set (sample,
494 GTK_DEST_DEFAULT_HIGHLIGHT |
495 GTK_DEST_DEFAULT_MOTION |
496 GTK_DEST_DEFAULT_DROP,
500 gtk_signal_connect (GTK_OBJECT (sample),
502 GTK_SIGNAL_FUNC (color_sample_drag_end),
506 gtk_signal_connect (GTK_OBJECT (sample),
508 GTK_SIGNAL_FUNC (color_sample_drag_handle),
510 gtk_signal_connect (GTK_OBJECT (sample),
511 "drag_data_received",
512 GTK_SIGNAL_FUNC (color_sample_drop_handle),
519 color_sample_new (GtkColorSelection *colorsel)
521 ColorSelectionPrivate *priv;
523 priv = colorsel->private_data;
525 priv->sample_area = gtk_hbox_new (FALSE, 0);
526 priv->old_sample = gtk_drawing_area_new ();
527 priv->cur_sample = gtk_drawing_area_new ();
529 /* We need enter/leave to do tooltips */
530 gtk_widget_add_events (priv->old_sample,
531 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
532 gtk_widget_add_events (priv->cur_sample,
533 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
535 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
537 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
540 gtk_signal_connect(GTK_OBJECT (priv->old_sample), "expose_event",
541 GTK_SIGNAL_FUNC (color_old_sample_expose),
543 gtk_signal_connect(GTK_OBJECT (priv->cur_sample), "expose_event",
544 GTK_SIGNAL_FUNC (color_cur_sample_expose),
547 color_sample_setup_dnd (colorsel, priv->old_sample);
548 color_sample_setup_dnd (colorsel, priv->cur_sample);
550 gtk_tooltips_set_tip (priv->tooltips,
552 _("The previously-selected color, for comparison to the color you're selecting now. You can drag this color to a palette entry, or select this color as current by dragging it to the other color swatch alongside."), NULL);
555 gtk_tooltips_set_tip (priv->tooltips,
557 _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL);
559 gtk_widget_show_all (priv->sample_area);
565 * The palette area code
568 #define CUSTOM_PALETTE_ENTRY_WIDTH 20
569 #define CUSTOM_PALETTE_ENTRY_HEIGHT 20
572 palette_get_color (GtkWidget *drawing_area, gdouble *color)
576 g_return_if_fail (color != NULL);
578 color_val = gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
579 if (color_val == NULL)
581 /* Default to white for no good reason */
589 color[0] = color_val[0];
590 color[1] = color_val[1];
591 color[2] = color_val[2];
595 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
597 palette_paint (GtkWidget *drawing_area,
601 if (drawing_area->window == NULL)
604 gdk_window_clear_area (drawing_area->window,
610 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
615 palette_get_color (drawing_area, color);
617 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
618 gc = drawing_area->style->black_gc;
620 gc = drawing_area->style->white_gc;
622 gdk_draw_rectangle (drawing_area->window,
624 drawing_area->allocation.width - 1,
625 drawing_area->allocation.height - 1);
631 palette_drag_begin (GtkWidget *widget,
632 GdkDragContext *context,
635 GtkColorSelection *colorsel = data;
636 ColorSelectionPrivate *priv;
641 priv = colorsel->private_data;
642 window = gtk_window_new (GTK_WINDOW_POPUP);
643 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
644 gtk_widget_set_usize (window, 48, 32);
645 gtk_widget_realize (window);
646 gtk_object_set_data_full (GTK_OBJECT (widget),
647 "gtk-color-selection-drag-window",
649 (GtkDestroyNotify) gtk_widget_destroy);
651 palette_get_color (widget, colors);
652 bg.red = 0xffff * colors[0];
653 bg.green = 0xffff * colors[1];
654 bg.blue = 0xffff * colors[2];
656 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
657 gdk_window_set_background (window->window, &bg);
659 gtk_drag_set_icon_widget (context, window, -2, -2);
663 palette_drag_handle (GtkWidget *widget,
664 GdkDragContext *context,
665 GtkSelectionData *selection_data,
673 palette_get_color (widget, colsrc);
675 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
676 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
677 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
680 gtk_selection_data_set (selection_data,
681 gdk_atom_intern ("application/x-color", FALSE),
682 16, (guchar *)vals, 8);
686 palette_drag_end (GtkWidget *widget,
687 GdkDragContext *context,
690 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
693 /* Changes the model color */
695 palette_change_color (GtkWidget *drawing_area,
696 GtkColorSelection *colorsel,
700 ColorSelectionPrivate *priv;
703 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
704 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
706 priv = colorsel->private_data;
708 gdk_color.red = color[0]*65535;
709 gdk_color.green = color[1]*65535;
710 gdk_color.blue = color[2]*65535;
713 while (x < GTK_CUSTOM_PALETTE_WIDTH)
716 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
718 if (priv->custom_palette[x][y] == drawing_area)
729 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
731 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
733 if (change_palette_hook)
734 (* change_palette_hook) (current_colors, GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
737 /* Changes the view color */
739 palette_set_color (GtkWidget *drawing_area,
740 GtkColorSelection *colorsel,
743 gdouble *new_color = g_new (double, 4);
747 gdk_color.red = color[0]*65535;
748 gdk_color.green = color[1]*65535;
749 gdk_color.blue = color[2]*65535;
751 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
753 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
755 static const GtkTargetEntry targets[] = {
756 { "application/x-color", 0 }
758 gtk_drag_source_set (drawing_area,
759 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
761 GDK_ACTION_COPY | GDK_ACTION_MOVE);
763 gtk_signal_connect (GTK_OBJECT (drawing_area),
765 GTK_SIGNAL_FUNC (palette_drag_begin),
767 gtk_signal_connect (GTK_OBJECT (drawing_area),
769 GTK_SIGNAL_FUNC (palette_drag_handle),
772 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
776 old_color = (gdouble *) gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
782 new_color[0] = color[0];
783 new_color[1] = color[1];
784 new_color[2] = color[2];
787 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_val", new_color);
791 palette_expose (GtkWidget *drawing_area,
792 GdkEventExpose *event,
795 if (drawing_area->window == NULL)
798 palette_paint (drawing_area, &(event->area), data);
802 popup_position_func (GtkMenu *menu,
812 widget = GTK_WIDGET (user_data);
814 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
816 gdk_window_get_origin (widget->window, &root_x, &root_y);
818 gtk_widget_size_request (GTK_WIDGET (menu), &req);
820 /* Put corner of menu centered on color cell */
821 *x = root_x + widget->allocation.width / 2;
822 *y = root_y + widget->allocation.height / 2;
825 *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
826 *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
830 save_color_selected (GtkWidget *menuitem,
833 GtkColorSelection *colorsel;
834 GtkWidget *drawing_area;
835 ColorSelectionPrivate *priv;
837 drawing_area = GTK_WIDGET (data);
839 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
842 priv = colorsel->private_data;
844 palette_change_color (drawing_area, colorsel, priv->color);
848 do_popup (GtkColorSelection *colorsel,
849 GtkWidget *drawing_area,
856 g_object_set_data (G_OBJECT (drawing_area),
860 menu = gtk_menu_new ();
862 label = gtk_label_new_with_mnemonic (_("_Save color here"));
863 mi = gtk_menu_item_new ();
864 gtk_container_add (GTK_CONTAINER (mi), label);
866 gtk_signal_connect (GTK_OBJECT (mi), "activate",
867 GTK_SIGNAL_FUNC (save_color_selected),
870 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
872 gtk_widget_show_all (mi);
874 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
875 popup_position_func, drawing_area,
881 palette_press (GtkWidget *drawing_area,
882 GdkEventButton *event,
885 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
887 gtk_widget_grab_focus (drawing_area);
889 if (event->button == 1 &&
890 event->type == GDK_BUTTON_PRESS)
892 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0)
895 palette_get_color (drawing_area, color);
896 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
900 if (event->button == 3 &&
901 event->type == GDK_BUTTON_PRESS)
903 do_popup (colorsel, drawing_area, event->time);
910 palette_unset_color (GtkWidget *drawing_area)
912 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
915 gtk_widget_reset_rc_styles (drawing_area);
916 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0));
920 palette_drop_handle (GtkWidget *widget,
921 GdkDragContext *context,
924 GtkSelectionData *selection_data,
932 if (selection_data->length < 0)
935 if ((selection_data->format != 16) ||
936 (selection_data->length != 8))
938 g_warning ("Received invalid color data\n");
942 vals = (guint16 *)selection_data->data;
944 color[0] = (gdouble)vals[0] / 0xffff;
945 color[1] = (gdouble)vals[1] / 0xffff;
946 color[2] = (gdouble)vals[2] / 0xffff;
947 color[3] = (gdouble)vals[3] / 0xffff;
948 palette_change_color (widget, GTK_COLOR_SELECTION (data), color);
949 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
953 palette_activate (GtkWidget *widget,
957 /* should have a drawing area subclass with an activate signal */
958 if ((event->keyval == ' ') || (event->keyval == GDK_Return))
960 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "color_set")) != 0)
963 palette_get_color (widget, color);
964 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
973 palette_popup (GtkWidget *widget,
976 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
978 do_popup (colorsel, widget, GDK_CURRENT_TIME);
983 palette_new (GtkColorSelection *colorsel)
986 ColorSelectionPrivate *priv;
988 static const GtkTargetEntry targets[] = {
989 { "application/x-color", 0 }
992 priv = colorsel->private_data;
994 retval = gtk_drawing_area_new ();
996 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
998 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
999 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1000 | GDK_BUTTON_RELEASE_MASK
1002 | GDK_ENTER_NOTIFY_MASK
1003 | GDK_LEAVE_NOTIFY_MASK);
1006 gtk_signal_connect (GTK_OBJECT (retval), "expose_event",
1007 GTK_SIGNAL_FUNC (palette_expose), colorsel);
1008 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event",
1009 GTK_SIGNAL_FUNC (palette_press), colorsel);
1010 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event",
1011 GTK_SIGNAL_FUNC (palette_activate), colorsel);
1012 gtk_signal_connect (GTK_OBJECT (retval), "popup_menu",
1013 GTK_SIGNAL_FUNC (palette_popup), colorsel);
1015 gtk_drag_dest_set (retval,
1016 GTK_DEST_DEFAULT_HIGHLIGHT |
1017 GTK_DEST_DEFAULT_MOTION |
1018 GTK_DEST_DEFAULT_DROP,
1022 gtk_signal_connect (GTK_OBJECT (retval), "drag_end",
1023 GTK_SIGNAL_FUNC (palette_drag_end), NULL);
1024 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received",
1025 GTK_SIGNAL_FUNC (palette_drop_handle), colorsel);
1027 gtk_tooltips_set_tip (priv->tooltips,
1029 _("Click this palette entry to make it the current color. To change this entry, drag a color swatch here or right-click it and select \"Save color here.\""),
1037 * The actual GtkColorSelection widget
1042 initialize_cursor (void)
1047 gdk_bitmap_create_from_data (NULL,
1049 DROPPER_WIDTH, DROPPER_HEIGHT);
1051 gdk_bitmap_create_from_data (NULL,
1053 DROPPER_WIDTH, DROPPER_HEIGHT);
1055 gdk_color_white (gdk_colormap_get_system (), &bg);
1056 gdk_color_black (gdk_colormap_get_system (), &fg);
1058 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
1060 gdk_pixmap_unref (pixmap);
1061 gdk_pixmap_unref (mask);
1066 grab_color_at_mouse (GtkWidget *invisible,
1073 GtkColorSelection *colorsel = data;
1074 ColorSelectionPrivate *priv;
1075 GdkColormap *colormap = gdk_colormap_get_system ();
1078 priv = colorsel->private_data;
1080 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
1081 pixel = gdk_image_get_pixel (image, 0, 0);
1082 gdk_image_unref (image);
1084 gdk_colormap_query_color (colormap, pixel, &color);
1086 priv->color[COLORSEL_RED] = (double)color.red / 65535.0;
1087 priv->color[COLORSEL_GREEN] = (double)color.green / 65535.0;
1088 priv->color[COLORSEL_BLUE] = (double)color.blue / 65535.0;
1090 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1091 priv->color[COLORSEL_GREEN],
1092 priv->color[COLORSEL_BLUE],
1093 &priv->color[COLORSEL_HUE],
1094 &priv->color[COLORSEL_SATURATION],
1095 &priv->color[COLORSEL_VALUE]);
1097 update_color (colorsel);
1101 shutdown_eyedropper (GtkWidget *widget)
1103 GtkColorSelection *colorsel;
1104 ColorSelectionPrivate *priv;
1106 colorsel = GTK_COLOR_SELECTION (widget);
1107 priv = colorsel->private_data;
1109 gdk_keyboard_ungrab (gtk_get_current_event_time ());
1110 gdk_pointer_ungrab (gtk_get_current_event_time ());
1111 gtk_grab_remove (priv->dropper_grab_widget);
1115 mouse_motion (GtkWidget *invisible,
1116 GdkEventMotion *event,
1119 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1123 mouse_release (GtkWidget *invisible,
1124 GdkEventButton *event,
1127 GtkColorSelection *colorsel = data;
1128 ColorSelectionPrivate *priv;
1129 priv = colorsel->private_data;
1131 if (event->button != 1)
1134 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1136 shutdown_eyedropper (GTK_WIDGET (data));
1138 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1139 GTK_SIGNAL_FUNC (mouse_motion), data);
1140 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1141 GTK_SIGNAL_FUNC (mouse_release), data);
1146 /* Helper Functions */
1148 static gboolean mouse_press (GtkWidget *invisible,
1149 GdkEventButton *event,
1153 key_press (GtkWidget *invisible,
1157 if (event->keyval == GDK_Escape)
1159 shutdown_eyedropper (data);
1161 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1162 GTK_SIGNAL_FUNC (mouse_press),
1164 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1165 GTK_SIGNAL_FUNC (key_press),
1175 mouse_press (GtkWidget *invisible,
1176 GdkEventButton *event,
1179 GtkColorSelection *colorsel = data;
1180 ColorSelectionPrivate *priv;
1181 priv = colorsel->private_data;
1183 if (event->type == GDK_BUTTON_PRESS &&
1186 gtk_signal_connect (GTK_OBJECT (invisible), "motion_notify_event",
1187 GTK_SIGNAL_FUNC (mouse_motion),
1189 gtk_signal_connect (GTK_OBJECT (invisible), "button_release_event",
1190 GTK_SIGNAL_FUNC (mouse_release),
1192 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1193 GTK_SIGNAL_FUNC (mouse_press),
1195 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1196 GTK_SIGNAL_FUNC (key_press),
1204 /* when the button is clicked */
1206 get_screen_color (GtkWidget *button)
1208 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
1209 ColorSelectionPrivate *priv = colorsel->private_data;
1211 if (picker_cursor == NULL)
1213 initialize_cursor ();
1216 if (priv->dropper_grab_widget == NULL)
1218 priv->dropper_grab_widget = gtk_invisible_new ();
1220 gtk_widget_add_events (priv->dropper_grab_widget,
1221 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1223 gtk_widget_show (priv->dropper_grab_widget);
1226 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1228 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1230 g_warning ("Failed to grab keyboard to do eyedropper");
1234 if (gdk_pointer_grab (priv->dropper_grab_widget->window,
1236 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1239 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1241 gdk_keyboard_ungrab (GDK_CURRENT_TIME);
1242 g_warning ("Failed to grab pointer to do eyedropper");
1246 gtk_grab_add (priv->dropper_grab_widget);
1248 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "button_press_event",
1249 GTK_SIGNAL_FUNC (mouse_press), colorsel);
1250 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "key_press_event",
1251 GTK_SIGNAL_FUNC (key_press), colorsel);
1255 hex_changed (GtkWidget *hex_entry,
1258 GtkColorSelection *colorsel;
1259 ColorSelectionPrivate *priv;
1263 colorsel = GTK_COLOR_SELECTION (data);
1264 priv = colorsel->private_data;
1269 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1270 if (gdk_color_parse (text, &color))
1272 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1273 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1274 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1275 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1276 priv->color[COLORSEL_GREEN],
1277 priv->color[COLORSEL_BLUE],
1278 &priv->color[COLORSEL_HUE],
1279 &priv->color[COLORSEL_SATURATION],
1280 &priv->color[COLORSEL_VALUE]);
1281 update_color (colorsel);
1287 hsv_changed (GtkWidget *hsv,
1290 GtkColorSelection *colorsel;
1291 ColorSelectionPrivate *priv;
1293 colorsel = GTK_COLOR_SELECTION (data);
1294 priv = colorsel->private_data;
1299 gtk_hsv_get_color (GTK_HSV (hsv),
1300 &priv->color[COLORSEL_HUE],
1301 &priv->color[COLORSEL_SATURATION],
1302 &priv->color[COLORSEL_VALUE]);
1303 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1304 priv->color[COLORSEL_SATURATION],
1305 priv->color[COLORSEL_VALUE],
1306 &priv->color[COLORSEL_RED],
1307 &priv->color[COLORSEL_GREEN],
1308 &priv->color[COLORSEL_BLUE]);
1309 update_color (colorsel);
1313 adjustment_changed (GtkAdjustment *adjustment,
1316 GtkColorSelection *colorsel;
1317 ColorSelectionPrivate *priv;
1319 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1320 priv = colorsel->private_data;
1325 switch (GPOINTER_TO_INT (data))
1327 case COLORSEL_SATURATION:
1328 case COLORSEL_VALUE:
1329 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1330 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1331 priv->color[COLORSEL_SATURATION],
1332 priv->color[COLORSEL_VALUE],
1333 &priv->color[COLORSEL_RED],
1334 &priv->color[COLORSEL_GREEN],
1335 &priv->color[COLORSEL_BLUE]);
1338 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1339 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1340 priv->color[COLORSEL_SATURATION],
1341 priv->color[COLORSEL_VALUE],
1342 &priv->color[COLORSEL_RED],
1343 &priv->color[COLORSEL_GREEN],
1344 &priv->color[COLORSEL_BLUE]);
1347 case COLORSEL_GREEN:
1349 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1351 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1352 priv->color[COLORSEL_GREEN],
1353 priv->color[COLORSEL_BLUE],
1354 &priv->color[COLORSEL_HUE],
1355 &priv->color[COLORSEL_SATURATION],
1356 &priv->color[COLORSEL_VALUE]);
1359 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1362 update_color (colorsel);
1366 opacity_entry_changed (GtkWidget *opacity_entry,
1369 GtkColorSelection *colorsel;
1370 ColorSelectionPrivate *priv;
1374 colorsel = GTK_COLOR_SELECTION (data);
1375 priv = colorsel->private_data;
1380 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1381 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1382 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1384 update_color (colorsel);
1390 make_label_spinbutton (GtkColorSelection *colorsel,
1391 GtkWidget **spinbutton,
1397 const gchar *tooltip)
1400 GtkAdjustment *adjust;
1401 ColorSelectionPrivate *priv = colorsel->private_data;
1403 if (channel_type == COLORSEL_HUE)
1405 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1409 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1411 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1412 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1414 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1416 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1417 GTK_SIGNAL_FUNC (adjustment_changed),
1418 GINT_TO_POINTER (channel_type));
1419 label = gtk_label_new_with_mnemonic (text);
1420 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1422 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1423 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1424 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1429 make_palette_frame (GtkColorSelection *colorsel,
1435 ColorSelectionPrivate *priv;
1437 priv = colorsel->private_data;
1438 frame = gtk_frame_new (NULL);
1439 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1440 priv->custom_palette[i][j] = palette_new (colorsel);
1441 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1442 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1443 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1446 /* Set the palette entry [x][y] to be the currently selected one. */
1448 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1450 ColorSelectionPrivate *priv = colorsel->private_data;
1452 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1456 scale_round (double val, double factor)
1458 val = floor (val * factor + 0.5);
1460 val = MIN (val, factor);
1465 update_color (GtkColorSelection *colorsel)
1467 ColorSelectionPrivate *priv = colorsel->private_data;
1469 gchar opacity_text[32];
1472 priv->changing = TRUE;
1473 color_sample_draw_samples (colorsel);
1475 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1476 priv->color[COLORSEL_HUE],
1477 priv->color[COLORSEL_SATURATION],
1478 priv->color[COLORSEL_VALUE]);
1479 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1480 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1481 scale_round (priv->color[COLORSEL_HUE], 360));
1482 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1483 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1484 scale_round (priv->color[COLORSEL_SATURATION], 255));
1485 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1486 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1487 scale_round (priv->color[COLORSEL_VALUE], 255));
1488 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1489 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1490 scale_round (priv->color[COLORSEL_RED], 255));
1491 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1492 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1493 scale_round (priv->color[COLORSEL_GREEN], 255));
1494 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1495 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1496 scale_round (priv->color[COLORSEL_BLUE], 255));
1497 gtk_adjustment_set_value (gtk_range_get_adjustment
1498 (GTK_RANGE (priv->opacity_slider)),
1499 scale_round (priv->color[COLORSEL_OPACITY], 255));
1501 g_snprintf (opacity_text, 32, "%.0f", priv->color[COLORSEL_OPACITY] * 255);
1502 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1504 g_snprintf (entryval, 11, "#%2X%2X%2X",
1505 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1506 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1507 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1509 for (ptr = entryval; *ptr; ptr++)
1512 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1513 priv->changing = FALSE;
1518 fill_palette_from_string (const gchar *str)
1520 GdkColor *colors = NULL;
1526 if (!gtk_color_selection_palette_from_string (str, &colors, &n_colors))
1529 if (n_colors > (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
1530 n_colors = GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
1532 memcpy (current_colors, colors, sizeof (GdkColor) * n_colors);
1538 palette_change_notify_class (GObject *object,
1543 g_object_get (object, pspec->name, &str, NULL);
1545 fill_palette_from_string (str);
1551 update_palette (GtkColorSelection *colorsel)
1555 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1557 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1561 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1563 gtk_color_selection_set_palette_color (colorsel,
1565 ¤t_colors[index]);
1571 palette_change_notify_instance (GObject *object,
1575 update_palette (GTK_COLOR_SELECTION (data));
1579 default_change_palette_func (const GdkColor *colors,
1584 str = gtk_color_selection_palette_to_string (colors, n_colors);
1586 gtk_settings_set_string_property (gtk_settings_get_global (),
1587 "gtk-color-palette",
1589 "gtk_color_selection_palette_to_string");
1595 gtk_color_selection_get_type (void)
1597 static GtkType color_selection_type = 0;
1599 if (!color_selection_type)
1601 static const GtkTypeInfo color_selection_info =
1603 "GtkColorSelection",
1604 sizeof (GtkColorSelection),
1605 sizeof (GtkColorSelectionClass),
1606 (GtkClassInitFunc) gtk_color_selection_class_init,
1607 (GtkObjectInitFunc) gtk_color_selection_init,
1608 /* reserved_1 */ NULL,
1609 /* reserved_2 */ NULL,
1610 (GtkClassInitFunc) NULL,
1613 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1616 return color_selection_type;
1620 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1622 GtkObjectClass *object_class;
1623 GObjectClass *gobject_class;
1625 object_class = GTK_OBJECT_CLASS (klass);
1626 gobject_class = G_OBJECT_CLASS (klass);
1628 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1630 object_class->destroy = gtk_color_selection_destroy;
1631 gobject_class->finalize = gtk_color_selection_finalize;
1633 color_selection_signals[COLOR_CHANGED] =
1634 gtk_signal_new ("color_changed",
1636 GTK_CLASS_TYPE (object_class),
1637 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1638 gtk_marshal_VOID__VOID,
1641 gtk_settings_install_property (gtk_settings_get_global (),
1642 g_param_spec_string ("gtk-color-palette",
1643 _("Custom palette"),
1644 _("Palette to use in the color selector"),
1646 G_PARAM_READWRITE));
1648 fill_palette_from_string (default_colors);
1650 change_palette_hook = default_change_palette_func;
1652 g_signal_connect_data (G_OBJECT (gtk_settings_get_global ()),
1653 "notify::gtk-color-palette",
1654 G_CALLBACK (palette_change_notify_class),
1655 NULL, NULL, FALSE, FALSE);
1658 /* widget functions */
1661 gtk_color_selection_init (GtkColorSelection *colorsel)
1663 GtkWidget *top_hbox;
1664 GtkWidget *top_right_vbox;
1665 GtkWidget *table, *label, *hbox, *frame, *vbox;
1666 GtkAdjustment *adjust;
1667 GdkPixmap *dropper_pixmap;
1668 GtkWidget *dropper_image;
1670 GdkBitmap *mask = NULL;
1672 ColorSelectionPrivate *priv;
1674 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1675 priv->changing = FALSE;
1676 priv->default_set = FALSE;
1677 priv->default_alpha_set = FALSE;
1679 priv->tooltips = gtk_tooltips_new ();
1681 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1682 top_hbox = gtk_hbox_new (FALSE, 8);
1683 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1685 vbox = gtk_vbox_new (FALSE, 4);
1686 priv->triangle_colorsel = gtk_hsv_new ();
1687 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed",
1688 GTK_SIGNAL_FUNC (hsv_changed), colorsel);
1689 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1690 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1691 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1692 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1693 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1695 hbox = gtk_hbox_new (FALSE, 4);
1696 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1698 frame = gtk_frame_new (NULL);
1699 gtk_widget_set_usize (frame, -1, 30);
1700 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1701 color_sample_new (colorsel);
1702 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1703 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1705 button = gtk_button_new ();
1707 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1708 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1709 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1710 GTK_SIGNAL_FUNC (get_screen_color), NULL);
1711 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1712 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1713 gdk_pixmap_unref (dropper_pixmap);
1715 gdk_pixmap_unref (mask);
1716 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1717 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1719 gtk_tooltips_set_tip (priv->tooltips,
1721 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1723 top_right_vbox = gtk_vbox_new (FALSE, 4);
1724 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1725 table = gtk_table_new (8, 6, FALSE);
1726 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1727 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1728 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1730 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1731 _("Position on the color wheel."));
1732 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1733 _("\"Deepness\" of the color."));
1734 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1735 _("Brightness of the color."));
1736 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1737 _("Amount of red light in the color."));
1738 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1739 _("Amount of green light in the color."));
1740 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1741 _("Amount of blue light in the color."));
1742 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1744 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1745 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1746 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1747 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1748 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1749 priv->opacity_slider = gtk_hscale_new (adjust);
1750 gtk_tooltips_set_tip (priv->tooltips,
1751 priv->opacity_slider,
1752 _("Transparency of the currently-selected color."), NULL);
1753 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1754 priv->opacity_slider);
1755 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1756 gtk_signal_connect (GTK_OBJECT(adjust), "value_changed",
1757 GTK_SIGNAL_FUNC (adjustment_changed),
1758 GINT_TO_POINTER (COLORSEL_OPACITY));
1759 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1760 priv->opacity_entry = gtk_entry_new ();
1761 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1763 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate",
1764 GTK_SIGNAL_FUNC (opacity_entry_changed), colorsel);
1765 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1767 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1768 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1769 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1770 priv->hex_entry = gtk_entry_new ();
1772 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1774 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate",
1775 GTK_SIGNAL_FUNC (hex_changed), colorsel);
1777 gtk_tooltips_set_tip (priv->tooltips,
1779 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1781 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1782 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1783 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1785 /* Set up the palette */
1786 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1787 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1788 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1789 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1791 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1793 make_palette_frame (colorsel, table, i, j);
1796 set_selected_palette (colorsel, 0, 0);
1797 priv->palette_frame = gtk_frame_new (NULL);
1798 label = gtk_label_new_with_mnemonic (_("_Palette"));
1799 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1801 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1802 priv->custom_palette[0][0]);
1804 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1805 vbox = gtk_vbox_new (FALSE, 4);
1806 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1807 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1809 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1811 gtk_widget_show_all (top_hbox);
1813 /* Set default colors */
1815 update_palette (colorsel);
1817 g_signal_connect_data (G_OBJECT (gtk_settings_get_global ()),
1818 "notify::gtk-color-palette",
1819 G_CALLBACK (palette_change_notify_instance),
1820 colorsel, NULL, FALSE, FALSE);
1822 /* hide unused stuff */
1824 if (priv->has_opacity == FALSE)
1826 gtk_widget_hide (priv->opacity_label);
1827 gtk_widget_hide (priv->opacity_slider);
1828 gtk_widget_hide (priv->opacity_entry);
1831 if (priv->has_palette == FALSE)
1833 gtk_widget_hide (priv->palette_frame);
1838 gtk_color_selection_destroy (GtkObject *object)
1840 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1841 ColorSelectionPrivate *priv = cselection->private_data;
1843 if (priv->dropper_grab_widget)
1845 gtk_widget_destroy (priv->dropper_grab_widget);
1846 priv->dropper_grab_widget = NULL;
1851 gtk_object_destroy (priv->tooltips);
1852 priv->tooltips = NULL;
1855 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1859 gtk_color_selection_finalize (GObject *object)
1861 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1863 if (cselection->private_data)
1865 g_free (cselection->private_data);
1866 cselection->private_data = NULL;
1869 G_OBJECT_CLASS (parent_class)->finalize (object);
1874 * gtk_color_selection_new:
1876 * Creates a new GtkColorSelection.
1878 * Return value: The new GtkColorSelection.
1881 gtk_color_selection_new (void)
1883 GtkColorSelection *colorsel;
1884 ColorSelectionPrivate *priv;
1891 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
1892 priv = colorsel->private_data;
1893 gtk_color_selection_set_color (colorsel, color);
1894 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
1896 /* We want to make sure that default_set is FALSE */
1897 /* This way the user can still set it */
1898 priv->default_set = FALSE;
1899 priv->default_alpha_set = FALSE;
1901 return GTK_WIDGET (colorsel);
1906 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
1907 GtkUpdateType policy)
1909 g_return_if_fail (colorsel != NULL);
1910 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1912 g_warning (G_STRLOC ": This function is deprecated.");
1916 * gtk_color_selection_get_has_opacity_control:
1917 * @colorsel: A GtkColorSelection.
1919 * Determines whether the colorsel has an opacity control.
1921 * Return value: TRUE if the @colorsel has an opacity control. FALSE if it does't.
1924 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
1926 ColorSelectionPrivate *priv;
1928 g_return_val_if_fail (colorsel != NULL, FALSE);
1929 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1931 priv = colorsel->private_data;
1933 return priv->has_opacity;
1937 * gtk_color_selection_set_has_opacity_control:
1938 * @colorsel: A GtkColorSelection.
1939 * @has_opacity: TRUE if @colorsel can set the opacity, FALSE otherwise.
1941 * Sets the @colorsel to use or not use opacity.
1945 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
1946 gboolean has_opacity)
1948 ColorSelectionPrivate *priv;
1950 g_return_if_fail (colorsel != NULL);
1951 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1953 priv = colorsel->private_data;
1954 has_opacity = has_opacity != FALSE;
1956 if (priv->has_opacity != has_opacity)
1958 priv->has_opacity = has_opacity;
1961 gtk_widget_show (priv->opacity_slider);
1962 gtk_widget_show (priv->opacity_label);
1963 gtk_widget_show (priv->opacity_entry);
1967 gtk_widget_hide (priv->opacity_slider);
1968 gtk_widget_hide (priv->opacity_label);
1969 gtk_widget_hide (priv->opacity_entry);
1971 color_sample_draw_samples (colorsel);
1976 * gtk_color_selection_get_has_palette:
1977 * @colorsel: A GtkColorSelection.
1979 * Determines whether the color selector has a color palette.
1981 * Return value: TRUE if the selector has a palette. FALSE if it hasn't.
1984 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
1986 ColorSelectionPrivate *priv;
1988 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1990 priv = colorsel->private_data;
1992 return priv->has_palette;
1996 * gtk_color_selection_set_has_palette:
1997 * @colorsel: A GtkColorSelection.
1998 * @has_palette: TRUE if palette is to be visible, FALSE otherwise.
2000 * Shows and hides the palette based upon the value of @has_palette.
2004 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2005 gboolean has_palette)
2007 ColorSelectionPrivate *priv;
2008 g_return_if_fail (colorsel != NULL);
2009 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2011 priv = colorsel->private_data;
2012 has_palette = has_palette != FALSE;
2014 if (priv->has_palette != has_palette)
2016 priv->has_palette = has_palette;
2018 gtk_widget_show (priv->palette_frame);
2020 gtk_widget_hide (priv->palette_frame);
2025 * gtk_color_selection_set_current_color:
2026 * @colorsel: A GtkColorSelection.
2027 * @color: A GdkColor to set the current color with.
2029 * Sets the current color to be @color. The first time this is called, it will
2030 * also set the original color to be @color too.
2034 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2037 ColorSelectionPrivate *priv;
2040 g_return_if_fail (colorsel != NULL);
2041 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2043 priv = colorsel->private_data;
2044 priv->changing = TRUE;
2045 priv->color[COLORSEL_RED] = color->red / 65535.0;
2046 priv->color[COLORSEL_GREEN] = color->green / 65535.0;
2047 priv->color[COLORSEL_BLUE] = color->blue / 65535.0;
2048 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2049 priv->color[COLORSEL_GREEN],
2050 priv->color[COLORSEL_BLUE],
2051 &priv->color[COLORSEL_HUE],
2052 &priv->color[COLORSEL_SATURATION],
2053 &priv->color[COLORSEL_VALUE]);
2054 if (priv->default_set == FALSE)
2056 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2057 priv->old_color[i] = priv->color[i];
2059 update_color (colorsel);
2060 priv->default_set = TRUE;
2064 * gtk_color_selection_set_current_alpha:
2065 * @colorsel: A GtkColorSelection.
2066 * @alpha: an integer between 0 and 65535
2068 * Sets the current opacity to be @alpha. The first time this is called, it will
2069 * also set the original opacity to be @alpha too.
2073 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2076 ColorSelectionPrivate *priv;
2079 g_return_if_fail (colorsel != NULL);
2080 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2082 priv = colorsel->private_data;
2083 priv->changing = TRUE;
2084 priv->color[COLORSEL_OPACITY] = alpha / 65535.0;
2085 if (priv->default_alpha_set == FALSE)
2087 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2088 priv->old_color[i] = priv->color[i];
2090 update_color (colorsel);
2091 priv->default_alpha_set = TRUE;
2095 * gtk_color_selection_set_color:
2096 * @colorsel: A GtkColorSelection.
2097 * @color: A array of doubles that specifies the color to set the current color with.
2099 * Sets the current color to be @color. The first time this is called, it will
2100 * also set the original color to be @color too.
2102 * This function is deprecated, use gtk_color_selection_set_current_color() instead.
2106 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2109 ColorSelectionPrivate *priv;
2112 g_return_if_fail (colorsel != NULL);
2113 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2115 priv = colorsel->private_data;
2116 priv->changing = TRUE;
2117 priv->color[COLORSEL_RED] = color[0];
2118 priv->color[COLORSEL_GREEN] = color[1];
2119 priv->color[COLORSEL_BLUE] = color[2];
2120 priv->color[COLORSEL_OPACITY] = color[3];
2121 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2122 priv->color[COLORSEL_GREEN],
2123 priv->color[COLORSEL_BLUE],
2124 &priv->color[COLORSEL_HUE],
2125 &priv->color[COLORSEL_SATURATION],
2126 &priv->color[COLORSEL_VALUE]);
2127 if (priv->default_set == FALSE)
2129 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2130 priv->old_color[i] = priv->color[i];
2132 update_color (colorsel);
2133 priv->default_set = TRUE;
2134 priv->default_alpha_set = TRUE;
2138 * gtk_color_selection_get_current_color:
2139 * @colorsel: A GtkColorSelection.
2140 * @color: A GdkColor to fill in with the current color.
2142 * Sets @color to be the current color in the GtkColorSelection widget.
2144 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2147 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2150 ColorSelectionPrivate *priv;
2152 g_return_if_fail (colorsel != NULL);
2153 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2155 priv = colorsel->private_data;
2156 color->red = priv->color[COLORSEL_RED] * 65535;
2157 color->green = priv->color[COLORSEL_GREEN] * 65535;
2158 color->blue = priv->color[COLORSEL_BLUE] * 65535;
2162 * gtk_color_selection_get_current_alpha:
2163 * @colorsel: A GtkColorSelection.
2165 * Returns the current alpha value
2167 * Return value: an integer between 0 and 65535
2170 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2172 ColorSelectionPrivate *priv;
2174 g_return_val_if_fail (colorsel != NULL, 0);
2175 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2177 priv = colorsel->private_data;
2178 return priv->has_opacity ? priv->color[COLORSEL_OPACITY] * 65535 : 1.0;
2182 * gtk_color_selection_get_color:
2183 * @colorsel: A GtkColorSelection.
2184 * @color: A color to fill in with the current color.
2186 * Sets @color to be the current color in the GtkColorSelection widget.
2190 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2193 ColorSelectionPrivate *priv;
2195 g_return_if_fail (colorsel != NULL);
2196 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2198 priv = colorsel->private_data;
2199 color[0] = priv->color[COLORSEL_RED];
2200 color[1] = priv->color[COLORSEL_GREEN];
2201 color[2] = priv->color[COLORSEL_BLUE];
2202 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 1.0;
2206 * gtk_color_selection_set_previous_color:
2207 * @colorsel: A GtkColorSelection.
2208 * @color: A color to set the previous color with.
2210 * Sets the 'previous' color to be @color. This function should be called with
2211 * some hesitations, as it might seem confusing to have that color change.
2212 * Calling gtk_color_selection_set_current_color will also set this color the first
2213 * time it is called.
2217 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2220 ColorSelectionPrivate *priv;
2222 g_return_if_fail (colorsel != NULL);
2223 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2225 priv = colorsel->private_data;
2226 priv->changing = TRUE;
2227 priv->old_color[COLORSEL_RED] = color->red / 65535.0;
2228 priv->old_color[COLORSEL_GREEN] = color->green / 65535.0;
2229 priv->old_color[COLORSEL_BLUE] = color->blue / 65535.0;
2230 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2231 priv->old_color[COLORSEL_GREEN],
2232 priv->old_color[COLORSEL_BLUE],
2233 &priv->old_color[COLORSEL_HUE],
2234 &priv->old_color[COLORSEL_SATURATION],
2235 &priv->old_color[COLORSEL_VALUE]);
2236 color_sample_draw_samples (colorsel);
2237 priv->default_set = TRUE;
2241 * gtk_color_selection_set_previous_alpha:
2242 * @colorsel: A GtkColorSelection.
2243 * @alpha: an integer between 0 and 65535
2245 * Sets the 'previous' alpha to be @alpha. This function should be called with
2246 * some hesitations, as it might seem confusing to have that color change.
2250 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2253 ColorSelectionPrivate *priv;
2255 g_return_if_fail (colorsel != NULL);
2256 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2258 priv = colorsel->private_data;
2259 priv->changing = TRUE;
2260 priv->old_color[COLORSEL_OPACITY] = alpha / 65535.0;
2261 color_sample_draw_samples (colorsel);
2262 priv->default_alpha_set = TRUE;
2267 * gtk_color_selection_get_previous_color:
2268 * @colorsel: A GtkColorSelection.
2269 * @color: A GdkColor to fill in with the original color value.
2271 * Fills @color in with the original color value.
2275 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2278 ColorSelectionPrivate *priv;
2280 g_return_if_fail (colorsel != NULL);
2281 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2283 priv = colorsel->private_data;
2284 color->red = priv->old_color[COLORSEL_RED] * 65535;
2285 color->green = priv->old_color[COLORSEL_GREEN] * 65535;
2286 color->blue = priv->old_color[COLORSEL_BLUE] * 65535;
2290 * gtk_color_selection_get_previous_alpha:
2291 * @colorsel: A GtkColorSelection.
2293 * Returns the previous alpha value
2295 * Return value: an integer between 0 and 65535
2298 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2300 ColorSelectionPrivate *priv;
2302 g_return_val_if_fail (colorsel != NULL, 0);
2303 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2305 priv = colorsel->private_data;
2306 return priv->has_opacity ? priv->old_color[COLORSEL_OPACITY] * 65535 : 1.0;
2310 * gtk_color_selection_set_palette_color:
2311 * @colorsel: A GtkColorSelection.
2312 * @index: The color index of the palette.
2313 * @color: A GdkColor to set the palette with.
2315 * Set the palette located at at @index to have @color set as its color.
2319 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2323 ColorSelectionPrivate *priv;
2327 g_return_if_fail (colorsel != NULL);
2328 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2329 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2331 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2332 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2334 priv = colorsel->private_data;
2335 col[0] = color->red / 65535.0;
2336 col[1] = color->green / 65535.0;
2337 col[2] = color->blue / 65535.0;
2339 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2343 * gtk_color_selection_get_palette_color:
2344 * @colorsel: A GtkColorSelection.
2345 * @index: The color index of the palette.
2346 * @color: A color to fill in with the color value.
2348 * Set @color to have the color found in the palette at @index. If
2349 * the palette is unset, it will leave the color unset.
2351 * Return value: TRUE if the palette located at @index has a color set. FALSE
2355 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
2359 ColorSelectionPrivate *priv;
2363 g_return_val_if_fail (colorsel != NULL, FALSE);
2364 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2365 g_return_val_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
2367 priv = colorsel->private_data;
2369 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2370 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2372 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
2375 palette_get_color (priv->custom_palette[x][y], col);
2377 color->red = col[0] * 65535;
2378 color->green = col[1] * 65535;
2379 color->blue = col[2] * 65535;
2385 * gtk_color_selection_unset_palette_color:
2386 * @colorsel: A GtkColorSelection.
2387 * @index: The color index in the palette.
2389 * Change the palette located @index to have no color set.
2393 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
2396 ColorSelectionPrivate *priv;
2399 g_return_if_fail (colorsel != NULL);
2400 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2401 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2403 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2404 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2406 priv = colorsel->private_data;
2407 palette_unset_color (priv->custom_palette[x][y]);
2411 * gtk_color_selection_get_current_alpha:
2412 * @colorsel: A GtkColorSelection.
2414 * Returns the maximum number of palette colors.
2416 * Return value: the maximum number of palette indexes
2419 gtk_color_selection_get_palette_size (GtkColorSelection *colorsel)
2421 return GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
2426 * gtk_color_selection_is_adjusting:
2427 * @colorsel: A GtkColorSelection.
2429 * Gets the current state of the @colorsel.
2431 * Return value: TRUE if the user is currently dragging a color around, and FALSE
2432 * if the selection has stopped.
2435 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2437 ColorSelectionPrivate *priv;
2439 g_return_val_if_fail (colorsel != NULL, FALSE);
2440 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2442 priv = colorsel->private_data;
2444 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2449 * gtk_color_selection_palette_from_string:
2450 * @str: a string encoding a color palette
2451 * @colors: return location for allocated array of GdkColor
2452 * @n_colors: return location for length of array
2454 * Parses a color palette string; the string is a colon-separated
2455 * list of color names readable by gdk_color_parse().
2457 * Return value: %TRUE if a palette was successfully parsed
2460 gtk_color_selection_palette_from_string (const gchar *str,
2472 copy = g_strdup (str);
2478 if (*p == ':' || *p == '\0')
2480 gboolean done = TRUE;
2484 goto failed; /* empty entry */
2493 retval = g_renew (GdkColor, retval, count + 1);
2494 if (!gdk_color_parse (start, retval + count))
2535 * gtk_color_selection_palette_to_string:
2536 * @colors: an array of colors
2537 * @n_colors: length of the array
2539 * Encodes a palette as a string, useful for persistent storage.
2541 * Return value: allocated string encoding the palette
2544 gtk_color_selection_palette_to_string (const GdkColor *colors,
2548 gchar **strs = NULL;
2552 return g_strdup ("");
2554 strs = g_new0 (gchar*, n_colors + 1);
2557 while (i < n_colors)
2562 g_strdup_printf ("#%2X%2X%2X",
2563 colors[i].red / 256,
2564 colors[i].green / 256,
2565 colors[i].blue / 256);
2567 for (ptr = strs[i]; *ptr; ptr++)
2574 retval = g_strjoinv (":", strs);
2582 * gtk_color_selection_set_change_palette_hook:
2583 * @func: a function to call when the custom palette needs saving
2585 * Installs a global function to be called whenever the user tries to
2586 * modify the palette in a color selection. This function should save
2587 * the new palette contents, and update the GtkSettings property
2588 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2590 * Return value: the previous change palette hook (that was replaced)
2592 GtkColorSelectionChangePaletteFunc
2593 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2595 GtkColorSelectionChangePaletteFunc old;
2597 old = change_palette_hook;
2599 change_palette_hook = func;