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;
130 /* Connection to settings */
131 guint settings_connection;
135 static void gtk_color_selection_init (GtkColorSelection *colorsel);
136 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
137 static void gtk_color_selection_destroy (GtkObject *object);
138 static void gtk_color_selection_finalize (GObject *object);
139 static void update_color (GtkColorSelection *colorsel);
141 static gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel);
142 static gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
145 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
148 static void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
151 static gpointer parent_class = NULL;
152 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
154 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";
156 static GtkColorSelectionChangePaletteFunc change_palette_hook = NULL;
158 static GdkColor current_colors[GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT];
160 /* The cursor for the dropper */
161 #define DROPPER_WIDTH 17
162 #define DROPPER_HEIGHT 17
163 #define DROPPER_X_HOT 2
164 #define DROPPER_Y_HOT 16
167 static char dropper_bits[] = {
168 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
169 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
170 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
171 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
174 static char dropper_mask[] = {
175 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
176 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
177 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
178 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
181 static GdkCursor *picker_cursor = NULL;
185 static char *picker[] = {
186 /* columns rows colors chars-per-pixel */
197 "#########################",
198 "#########################",
199 "#########################",
200 "#########################",
201 "#########################",
202 "################# #####",
203 "################ ####",
204 "################ +###",
205 "############# +###",
206 "############## ++###",
207 "#############+@ +++####",
208 "############+@@@ +######",
209 "###########+@@@ + +######",
210 "##########+@@@ ++#+######",
211 "#########+@@@ ++#########",
212 "########+@@@ ++##########",
213 "#######+@@@ ++###########",
214 "######+@@@ ++############",
215 "######+@@ ++#############",
216 "#####+@ ++##############",
217 "###### +++###############",
218 "#########################",
219 "#########################",
220 "#########################",
221 "#########################"
230 #define SAMPLE_WIDTH 64
231 #define SAMPLE_HEIGHT 28
233 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
234 static void color_sample_draw_samples (GtkColorSelection *colorsel);
237 color_sample_drag_begin (GtkWidget *widget,
238 GdkDragContext *context,
241 GtkColorSelection *colorsel = data;
242 ColorSelectionPrivate *priv;
249 priv = colorsel->private_data;
250 window = gtk_window_new (GTK_WINDOW_POPUP);
251 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
252 gtk_widget_set_usize (window, 48, 32);
253 gtk_widget_realize (window);
254 gtk_object_set_data_full (GTK_OBJECT (widget),
255 "gtk-color-selection-drag-window",
257 (GtkDestroyNotify) gtk_widget_destroy);
259 if (widget == priv->old_sample)
260 colsrc = priv->old_color;
262 colsrc = priv->color;
264 for (i=0, n = COLORSEL_RED; n <= COLORSEL_BLUE; n++)
266 colors[i++] = colsrc[n];
269 if (priv->has_opacity)
271 colors[i] = colsrc[COLORSEL_OPACITY];
274 bg.red = 0xffff * colors[0];
275 bg.green = 0xffff * colors[1];
276 bg.blue = 0xffff * colors[2];
278 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
279 gdk_window_set_background (window->window, &bg);
281 gtk_drag_set_icon_widget (context, window, -2, -2);
285 color_sample_drag_end (GtkWidget *widget,
286 GdkDragContext *context,
289 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
293 color_sample_drop_handle (GtkWidget *widget,
294 GdkDragContext *context,
297 GtkSelectionData *selection_data,
302 GtkColorSelection *colorsel = data;
303 ColorSelectionPrivate *priv;
306 priv = colorsel->private_data;
308 /* This is currently a guint16 array of the format:
315 if (selection_data->length < 0)
318 if ((selection_data->format != 16) ||
319 (selection_data->length != 8))
321 g_warning ("Received invalid color data\n");
325 vals = (guint16 *)selection_data->data;
327 if (widget == priv->cur_sample)
329 color[0] = (gdouble)vals[0] / 0xffff;
330 color[1] = (gdouble)vals[1] / 0xffff;
331 color[2] = (gdouble)vals[2] / 0xffff;
332 color[3] = (gdouble)vals[3] / 0xffff;
334 gtk_color_selection_set_color (colorsel, color);
339 color_sample_drag_handle (GtkWidget *widget,
340 GdkDragContext *context,
341 GtkSelectionData *selection_data,
346 GtkColorSelection *colorsel = data;
347 ColorSelectionPrivate *priv;
351 priv = colorsel->private_data;
353 if (widget == priv->old_sample)
354 colsrc = priv->old_color;
356 colsrc = priv->color;
358 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
359 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
360 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
361 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
363 gtk_selection_data_set (selection_data,
364 gdk_atom_intern ("application/x-color", FALSE),
365 16, (guchar *)vals, 8);
368 /* which = 0 means draw old sample, which = 1 means draw new */
370 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
373 gint x, y, i, wid, heig, f, n, goff;
374 guchar c[3 * 2], cc[3 * 4], *cp = c;
377 ColorSelectionPrivate *priv;
379 g_return_if_fail (colorsel != NULL);
380 priv = colorsel->private_data;
382 g_return_if_fail (priv->sample_area != NULL);
383 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
388 da = priv->old_sample;
389 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
390 c[n] = (guchar) (255.0 * priv->old_color[i]);
395 da = priv->cur_sample;
396 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
397 c[n] = (guchar) (255.0 * priv->color[i]);
398 goff = priv->old_sample->allocation.width % 32;
401 wid = da->allocation.width;
402 heig = da->allocation.height;
404 buf = g_new (guchar, 3 * wid * heig);
408 for (n = 0; n < 3; n++)
410 c[n] = (guchar) (255.0 * priv->old_color[i]);
411 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
415 if (priv->has_opacity)
417 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
419 for (n = 0; n < 3; n++)
421 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
422 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
428 for (y = 0; y < heig; y++)
430 for (x = 0; x < wid; x++)
432 if (priv->has_opacity)
433 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
437 for (n = 0; n < 3; n++)
438 buf[i++] = cp[n + f];
442 gdk_draw_rgb_image (da->window,
446 GDK_RGB_DITHER_NORMAL,
456 color_sample_draw_samples (GtkColorSelection *colorsel)
458 color_sample_draw_sample (colorsel, 0);
459 color_sample_draw_sample (colorsel, 1);
463 color_old_sample_expose (GtkWidget *da,
464 GdkEventExpose *event,
465 GtkColorSelection *colorsel)
467 color_sample_draw_sample (colorsel, 0);
472 color_cur_sample_expose (GtkWidget *da,
473 GdkEventExpose *event,
474 GtkColorSelection *colorsel)
476 color_sample_draw_sample (colorsel, 1);
480 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
482 static const GtkTargetEntry targets[] = {
483 { "application/x-color", 0 }
485 ColorSelectionPrivate *priv;
486 priv = colorsel->private_data;
488 gtk_drag_source_set (sample,
489 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
491 GDK_ACTION_COPY | GDK_ACTION_MOVE);
493 gtk_signal_connect (GTK_OBJECT (sample),
495 GTK_SIGNAL_FUNC (color_sample_drag_begin),
497 if (sample == priv->cur_sample)
500 gtk_drag_dest_set (sample,
501 GTK_DEST_DEFAULT_HIGHLIGHT |
502 GTK_DEST_DEFAULT_MOTION |
503 GTK_DEST_DEFAULT_DROP,
507 gtk_signal_connect (GTK_OBJECT (sample),
509 GTK_SIGNAL_FUNC (color_sample_drag_end),
513 gtk_signal_connect (GTK_OBJECT (sample),
515 GTK_SIGNAL_FUNC (color_sample_drag_handle),
517 gtk_signal_connect (GTK_OBJECT (sample),
518 "drag_data_received",
519 GTK_SIGNAL_FUNC (color_sample_drop_handle),
526 color_sample_new (GtkColorSelection *colorsel)
528 ColorSelectionPrivate *priv;
530 priv = colorsel->private_data;
532 priv->sample_area = gtk_hbox_new (FALSE, 0);
533 priv->old_sample = gtk_drawing_area_new ();
534 priv->cur_sample = gtk_drawing_area_new ();
536 /* We need enter/leave to do tooltips */
537 gtk_widget_add_events (priv->old_sample,
538 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
539 gtk_widget_add_events (priv->cur_sample,
540 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
542 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
544 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
547 gtk_signal_connect(GTK_OBJECT (priv->old_sample), "expose_event",
548 GTK_SIGNAL_FUNC (color_old_sample_expose),
550 gtk_signal_connect(GTK_OBJECT (priv->cur_sample), "expose_event",
551 GTK_SIGNAL_FUNC (color_cur_sample_expose),
554 color_sample_setup_dnd (colorsel, priv->old_sample);
555 color_sample_setup_dnd (colorsel, priv->cur_sample);
557 gtk_tooltips_set_tip (priv->tooltips,
559 _("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);
562 gtk_tooltips_set_tip (priv->tooltips,
564 _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL);
566 gtk_widget_show_all (priv->sample_area);
572 * The palette area code
575 #define CUSTOM_PALETTE_ENTRY_WIDTH 20
576 #define CUSTOM_PALETTE_ENTRY_HEIGHT 20
579 palette_get_color (GtkWidget *drawing_area, gdouble *color)
583 g_return_if_fail (color != NULL);
585 color_val = gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
586 if (color_val == NULL)
588 /* Default to white for no good reason */
596 color[0] = color_val[0];
597 color[1] = color_val[1];
598 color[2] = color_val[2];
602 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
604 palette_paint (GtkWidget *drawing_area,
608 if (drawing_area->window == NULL)
611 gdk_window_clear_area (drawing_area->window,
617 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
622 palette_get_color (drawing_area, color);
624 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
625 gc = drawing_area->style->black_gc;
627 gc = drawing_area->style->white_gc;
629 gdk_draw_rectangle (drawing_area->window,
631 drawing_area->allocation.width - 1,
632 drawing_area->allocation.height - 1);
638 palette_drag_begin (GtkWidget *widget,
639 GdkDragContext *context,
642 GtkColorSelection *colorsel = data;
643 ColorSelectionPrivate *priv;
648 priv = colorsel->private_data;
649 window = gtk_window_new (GTK_WINDOW_POPUP);
650 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
651 gtk_widget_set_usize (window, 48, 32);
652 gtk_widget_realize (window);
653 gtk_object_set_data_full (GTK_OBJECT (widget),
654 "gtk-color-selection-drag-window",
656 (GtkDestroyNotify) gtk_widget_destroy);
658 palette_get_color (widget, colors);
659 bg.red = 0xffff * colors[0];
660 bg.green = 0xffff * colors[1];
661 bg.blue = 0xffff * colors[2];
663 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
664 gdk_window_set_background (window->window, &bg);
666 gtk_drag_set_icon_widget (context, window, -2, -2);
670 palette_drag_handle (GtkWidget *widget,
671 GdkDragContext *context,
672 GtkSelectionData *selection_data,
680 palette_get_color (widget, colsrc);
682 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
683 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
684 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
687 gtk_selection_data_set (selection_data,
688 gdk_atom_intern ("application/x-color", FALSE),
689 16, (guchar *)vals, 8);
693 palette_drag_end (GtkWidget *widget,
694 GdkDragContext *context,
697 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
700 /* Changes the model color */
702 palette_change_color (GtkWidget *drawing_area,
703 GtkColorSelection *colorsel,
707 ColorSelectionPrivate *priv;
710 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
711 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
713 priv = colorsel->private_data;
715 gdk_color.red = color[0]*65535;
716 gdk_color.green = color[1]*65535;
717 gdk_color.blue = color[2]*65535;
720 while (x < GTK_CUSTOM_PALETTE_WIDTH)
723 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
725 if (priv->custom_palette[x][y] == drawing_area)
736 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
738 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
740 if (change_palette_hook)
741 (* change_palette_hook) (current_colors, GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
744 /* Changes the view color */
746 palette_set_color (GtkWidget *drawing_area,
747 GtkColorSelection *colorsel,
750 gdouble *new_color = g_new (double, 4);
754 gdk_color.red = color[0]*65535;
755 gdk_color.green = color[1]*65535;
756 gdk_color.blue = color[2]*65535;
758 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
760 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
762 static const GtkTargetEntry targets[] = {
763 { "application/x-color", 0 }
765 gtk_drag_source_set (drawing_area,
766 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
768 GDK_ACTION_COPY | GDK_ACTION_MOVE);
770 gtk_signal_connect (GTK_OBJECT (drawing_area),
772 GTK_SIGNAL_FUNC (palette_drag_begin),
774 gtk_signal_connect (GTK_OBJECT (drawing_area),
776 GTK_SIGNAL_FUNC (palette_drag_handle),
779 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
783 old_color = (gdouble *) gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
789 new_color[0] = color[0];
790 new_color[1] = color[1];
791 new_color[2] = color[2];
794 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_val", new_color);
798 palette_expose (GtkWidget *drawing_area,
799 GdkEventExpose *event,
802 if (drawing_area->window == NULL)
805 palette_paint (drawing_area, &(event->area), data);
809 popup_position_func (GtkMenu *menu,
819 widget = GTK_WIDGET (user_data);
821 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
823 gdk_window_get_origin (widget->window, &root_x, &root_y);
825 gtk_widget_size_request (GTK_WIDGET (menu), &req);
827 /* Put corner of menu centered on color cell */
828 *x = root_x + widget->allocation.width / 2;
829 *y = root_y + widget->allocation.height / 2;
832 *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
833 *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
837 save_color_selected (GtkWidget *menuitem,
840 GtkColorSelection *colorsel;
841 GtkWidget *drawing_area;
842 ColorSelectionPrivate *priv;
844 drawing_area = GTK_WIDGET (data);
846 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
849 priv = colorsel->private_data;
851 palette_change_color (drawing_area, colorsel, priv->color);
855 do_popup (GtkColorSelection *colorsel,
856 GtkWidget *drawing_area,
862 g_object_set_data (G_OBJECT (drawing_area),
866 menu = gtk_menu_new ();
868 mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
870 gtk_signal_connect (GTK_OBJECT (mi), "activate",
871 GTK_SIGNAL_FUNC (save_color_selected),
874 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
876 gtk_widget_show_all (mi);
878 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
879 popup_position_func, drawing_area,
885 palette_press (GtkWidget *drawing_area,
886 GdkEventButton *event,
889 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
891 gtk_widget_grab_focus (drawing_area);
893 if (event->button == 1 &&
894 event->type == GDK_BUTTON_PRESS)
896 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0)
899 palette_get_color (drawing_area, color);
900 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
904 if (event->button == 3 &&
905 event->type == GDK_BUTTON_PRESS)
907 do_popup (colorsel, drawing_area, event->time);
914 palette_unset_color (GtkWidget *drawing_area)
916 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
919 gtk_widget_reset_rc_styles (drawing_area);
920 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0));
924 palette_drop_handle (GtkWidget *widget,
925 GdkDragContext *context,
928 GtkSelectionData *selection_data,
936 if (selection_data->length < 0)
939 if ((selection_data->format != 16) ||
940 (selection_data->length != 8))
942 g_warning ("Received invalid color data\n");
946 vals = (guint16 *)selection_data->data;
948 color[0] = (gdouble)vals[0] / 0xffff;
949 color[1] = (gdouble)vals[1] / 0xffff;
950 color[2] = (gdouble)vals[2] / 0xffff;
951 color[3] = (gdouble)vals[3] / 0xffff;
952 palette_change_color (widget, GTK_COLOR_SELECTION (data), color);
953 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
957 palette_activate (GtkWidget *widget,
961 /* should have a drawing area subclass with an activate signal */
962 if ((event->keyval == GDK_space) ||
963 (event->keyval == GDK_Return) ||
964 (event->keyval == GDK_KP_Enter) ||
965 (event->keyval == GDK_KP_Space))
967 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "color_set")) != 0)
970 palette_get_color (widget, color);
971 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
980 palette_popup (GtkWidget *widget,
983 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
985 do_popup (colorsel, widget, GDK_CURRENT_TIME);
990 palette_new (GtkColorSelection *colorsel)
993 ColorSelectionPrivate *priv;
995 static const GtkTargetEntry targets[] = {
996 { "application/x-color", 0 }
999 priv = colorsel->private_data;
1001 retval = gtk_drawing_area_new ();
1003 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1005 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
1006 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1007 | GDK_BUTTON_RELEASE_MASK
1009 | GDK_ENTER_NOTIFY_MASK
1010 | GDK_LEAVE_NOTIFY_MASK);
1013 gtk_signal_connect (GTK_OBJECT (retval), "expose_event",
1014 GTK_SIGNAL_FUNC (palette_expose), colorsel);
1015 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event",
1016 GTK_SIGNAL_FUNC (palette_press), colorsel);
1017 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event",
1018 GTK_SIGNAL_FUNC (palette_activate), colorsel);
1019 gtk_signal_connect (GTK_OBJECT (retval), "popup_menu",
1020 GTK_SIGNAL_FUNC (palette_popup), colorsel);
1022 gtk_drag_dest_set (retval,
1023 GTK_DEST_DEFAULT_HIGHLIGHT |
1024 GTK_DEST_DEFAULT_MOTION |
1025 GTK_DEST_DEFAULT_DROP,
1029 gtk_signal_connect (GTK_OBJECT (retval), "drag_end",
1030 GTK_SIGNAL_FUNC (palette_drag_end), NULL);
1031 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received",
1032 GTK_SIGNAL_FUNC (palette_drop_handle), colorsel);
1034 gtk_tooltips_set_tip (priv->tooltips,
1036 _("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.\""),
1044 * The actual GtkColorSelection widget
1049 initialize_cursor (void)
1054 gdk_bitmap_create_from_data (NULL,
1056 DROPPER_WIDTH, DROPPER_HEIGHT);
1058 gdk_bitmap_create_from_data (NULL,
1060 DROPPER_WIDTH, DROPPER_HEIGHT);
1062 gdk_color_white (gdk_colormap_get_system (), &bg);
1063 gdk_color_black (gdk_colormap_get_system (), &fg);
1065 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
1067 gdk_pixmap_unref (pixmap);
1068 gdk_pixmap_unref (mask);
1073 grab_color_at_mouse (GtkWidget *invisible,
1080 GtkColorSelection *colorsel = data;
1081 ColorSelectionPrivate *priv;
1082 GdkColormap *colormap = gdk_colormap_get_system ();
1085 priv = colorsel->private_data;
1087 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
1088 pixel = gdk_image_get_pixel (image, 0, 0);
1089 gdk_image_unref (image);
1091 gdk_colormap_query_color (colormap, pixel, &color);
1093 priv->color[COLORSEL_RED] = (double)color.red / 65535.0;
1094 priv->color[COLORSEL_GREEN] = (double)color.green / 65535.0;
1095 priv->color[COLORSEL_BLUE] = (double)color.blue / 65535.0;
1097 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1098 priv->color[COLORSEL_GREEN],
1099 priv->color[COLORSEL_BLUE],
1100 &priv->color[COLORSEL_HUE],
1101 &priv->color[COLORSEL_SATURATION],
1102 &priv->color[COLORSEL_VALUE]);
1104 update_color (colorsel);
1108 shutdown_eyedropper (GtkWidget *widget)
1110 GtkColorSelection *colorsel;
1111 ColorSelectionPrivate *priv;
1113 colorsel = GTK_COLOR_SELECTION (widget);
1114 priv = colorsel->private_data;
1116 gdk_keyboard_ungrab (gtk_get_current_event_time ());
1117 gdk_pointer_ungrab (gtk_get_current_event_time ());
1118 gtk_grab_remove (priv->dropper_grab_widget);
1122 mouse_motion (GtkWidget *invisible,
1123 GdkEventMotion *event,
1126 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1130 mouse_release (GtkWidget *invisible,
1131 GdkEventButton *event,
1134 GtkColorSelection *colorsel = data;
1135 ColorSelectionPrivate *priv;
1136 priv = colorsel->private_data;
1138 if (event->button != 1)
1141 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1143 shutdown_eyedropper (GTK_WIDGET (data));
1145 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1146 GTK_SIGNAL_FUNC (mouse_motion), data);
1147 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1148 GTK_SIGNAL_FUNC (mouse_release), data);
1153 /* Helper Functions */
1155 static gboolean mouse_press (GtkWidget *invisible,
1156 GdkEventButton *event,
1160 key_press (GtkWidget *invisible,
1164 if (event->keyval == GDK_Escape)
1166 shutdown_eyedropper (data);
1168 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1169 GTK_SIGNAL_FUNC (mouse_press),
1171 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1172 GTK_SIGNAL_FUNC (key_press),
1182 mouse_press (GtkWidget *invisible,
1183 GdkEventButton *event,
1186 GtkColorSelection *colorsel = data;
1187 ColorSelectionPrivate *priv;
1188 priv = colorsel->private_data;
1190 if (event->type == GDK_BUTTON_PRESS &&
1193 gtk_signal_connect (GTK_OBJECT (invisible), "motion_notify_event",
1194 GTK_SIGNAL_FUNC (mouse_motion),
1196 gtk_signal_connect (GTK_OBJECT (invisible), "button_release_event",
1197 GTK_SIGNAL_FUNC (mouse_release),
1199 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1200 GTK_SIGNAL_FUNC (mouse_press),
1202 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1203 GTK_SIGNAL_FUNC (key_press),
1211 /* when the button is clicked */
1213 get_screen_color (GtkWidget *button)
1215 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
1216 ColorSelectionPrivate *priv = colorsel->private_data;
1218 if (picker_cursor == NULL)
1220 initialize_cursor ();
1223 if (priv->dropper_grab_widget == NULL)
1225 priv->dropper_grab_widget = gtk_invisible_new ();
1227 gtk_widget_add_events (priv->dropper_grab_widget,
1228 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1230 gtk_widget_show (priv->dropper_grab_widget);
1233 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1235 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1237 g_warning ("Failed to grab keyboard to do eyedropper");
1241 if (gdk_pointer_grab (priv->dropper_grab_widget->window,
1243 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1246 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1248 gdk_keyboard_ungrab (GDK_CURRENT_TIME);
1249 g_warning ("Failed to grab pointer to do eyedropper");
1253 gtk_grab_add (priv->dropper_grab_widget);
1255 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "button_press_event",
1256 GTK_SIGNAL_FUNC (mouse_press), colorsel);
1257 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "key_press_event",
1258 GTK_SIGNAL_FUNC (key_press), colorsel);
1262 hex_changed (GtkWidget *hex_entry,
1265 GtkColorSelection *colorsel;
1266 ColorSelectionPrivate *priv;
1270 colorsel = GTK_COLOR_SELECTION (data);
1271 priv = colorsel->private_data;
1276 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1277 if (gdk_color_parse (text, &color))
1279 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1280 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1281 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1282 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1283 priv->color[COLORSEL_GREEN],
1284 priv->color[COLORSEL_BLUE],
1285 &priv->color[COLORSEL_HUE],
1286 &priv->color[COLORSEL_SATURATION],
1287 &priv->color[COLORSEL_VALUE]);
1288 update_color (colorsel);
1294 hsv_changed (GtkWidget *hsv,
1297 GtkColorSelection *colorsel;
1298 ColorSelectionPrivate *priv;
1300 colorsel = GTK_COLOR_SELECTION (data);
1301 priv = colorsel->private_data;
1306 gtk_hsv_get_color (GTK_HSV (hsv),
1307 &priv->color[COLORSEL_HUE],
1308 &priv->color[COLORSEL_SATURATION],
1309 &priv->color[COLORSEL_VALUE]);
1310 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1311 priv->color[COLORSEL_SATURATION],
1312 priv->color[COLORSEL_VALUE],
1313 &priv->color[COLORSEL_RED],
1314 &priv->color[COLORSEL_GREEN],
1315 &priv->color[COLORSEL_BLUE]);
1316 update_color (colorsel);
1320 adjustment_changed (GtkAdjustment *adjustment,
1323 GtkColorSelection *colorsel;
1324 ColorSelectionPrivate *priv;
1326 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1327 priv = colorsel->private_data;
1332 switch (GPOINTER_TO_INT (data))
1334 case COLORSEL_SATURATION:
1335 case COLORSEL_VALUE:
1336 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1337 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1338 priv->color[COLORSEL_SATURATION],
1339 priv->color[COLORSEL_VALUE],
1340 &priv->color[COLORSEL_RED],
1341 &priv->color[COLORSEL_GREEN],
1342 &priv->color[COLORSEL_BLUE]);
1345 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1346 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1347 priv->color[COLORSEL_SATURATION],
1348 priv->color[COLORSEL_VALUE],
1349 &priv->color[COLORSEL_RED],
1350 &priv->color[COLORSEL_GREEN],
1351 &priv->color[COLORSEL_BLUE]);
1354 case COLORSEL_GREEN:
1356 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1358 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1359 priv->color[COLORSEL_GREEN],
1360 priv->color[COLORSEL_BLUE],
1361 &priv->color[COLORSEL_HUE],
1362 &priv->color[COLORSEL_SATURATION],
1363 &priv->color[COLORSEL_VALUE]);
1366 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1369 update_color (colorsel);
1373 opacity_entry_changed (GtkWidget *opacity_entry,
1376 GtkColorSelection *colorsel;
1377 ColorSelectionPrivate *priv;
1381 colorsel = GTK_COLOR_SELECTION (data);
1382 priv = colorsel->private_data;
1387 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1388 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1389 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1391 update_color (colorsel);
1397 make_label_spinbutton (GtkColorSelection *colorsel,
1398 GtkWidget **spinbutton,
1404 const gchar *tooltip)
1407 GtkAdjustment *adjust;
1408 ColorSelectionPrivate *priv = colorsel->private_data;
1410 if (channel_type == COLORSEL_HUE)
1412 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1416 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1418 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1419 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1421 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1423 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1424 GTK_SIGNAL_FUNC (adjustment_changed),
1425 GINT_TO_POINTER (channel_type));
1426 label = gtk_label_new_with_mnemonic (text);
1427 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1429 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1430 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1431 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1436 make_palette_frame (GtkColorSelection *colorsel,
1442 ColorSelectionPrivate *priv;
1444 priv = colorsel->private_data;
1445 frame = gtk_frame_new (NULL);
1446 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1447 priv->custom_palette[i][j] = palette_new (colorsel);
1448 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1449 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1450 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1453 /* Set the palette entry [x][y] to be the currently selected one. */
1455 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1457 ColorSelectionPrivate *priv = colorsel->private_data;
1459 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1463 scale_round (double val, double factor)
1465 val = floor (val * factor + 0.5);
1467 val = MIN (val, factor);
1472 update_color (GtkColorSelection *colorsel)
1474 ColorSelectionPrivate *priv = colorsel->private_data;
1476 gchar opacity_text[32];
1479 priv->changing = TRUE;
1480 color_sample_draw_samples (colorsel);
1482 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1483 priv->color[COLORSEL_HUE],
1484 priv->color[COLORSEL_SATURATION],
1485 priv->color[COLORSEL_VALUE]);
1486 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1487 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1488 scale_round (priv->color[COLORSEL_HUE], 360));
1489 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1490 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1491 scale_round (priv->color[COLORSEL_SATURATION], 255));
1492 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1493 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1494 scale_round (priv->color[COLORSEL_VALUE], 255));
1495 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1496 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1497 scale_round (priv->color[COLORSEL_RED], 255));
1498 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1499 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1500 scale_round (priv->color[COLORSEL_GREEN], 255));
1501 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1502 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1503 scale_round (priv->color[COLORSEL_BLUE], 255));
1504 gtk_adjustment_set_value (gtk_range_get_adjustment
1505 (GTK_RANGE (priv->opacity_slider)),
1506 scale_round (priv->color[COLORSEL_OPACITY], 255));
1508 g_snprintf (opacity_text, 32, "%.0f", priv->color[COLORSEL_OPACITY] * 255);
1509 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1511 g_snprintf (entryval, 11, "#%2X%2X%2X",
1512 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1513 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1514 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1516 for (ptr = entryval; *ptr; ptr++)
1519 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1520 priv->changing = FALSE;
1525 fill_palette_from_string (const gchar *str)
1527 GdkColor *colors = NULL;
1533 if (!gtk_color_selection_palette_from_string (str, &colors, &n_colors))
1536 if (n_colors > (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
1537 n_colors = GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
1539 memcpy (current_colors, colors, sizeof (GdkColor) * n_colors);
1545 palette_change_notify_class (GObject *object,
1550 g_object_get (object, pspec->name, &str, NULL);
1552 fill_palette_from_string (str);
1558 update_palette (GtkColorSelection *colorsel)
1562 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1564 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1568 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1570 gtk_color_selection_set_palette_color (colorsel,
1572 ¤t_colors[index]);
1578 palette_change_notify_instance (GObject *object,
1582 update_palette (GTK_COLOR_SELECTION (data));
1586 default_change_palette_func (const GdkColor *colors,
1591 str = gtk_color_selection_palette_to_string (colors, n_colors);
1593 gtk_settings_set_string_property (gtk_settings_get_default (),
1594 "gtk-color-palette",
1596 "gtk_color_selection_palette_to_string");
1602 gtk_color_selection_get_type (void)
1604 static GtkType color_selection_type = 0;
1606 if (!color_selection_type)
1608 static const GtkTypeInfo color_selection_info =
1610 "GtkColorSelection",
1611 sizeof (GtkColorSelection),
1612 sizeof (GtkColorSelectionClass),
1613 (GtkClassInitFunc) gtk_color_selection_class_init,
1614 (GtkObjectInitFunc) gtk_color_selection_init,
1615 /* reserved_1 */ NULL,
1616 /* reserved_2 */ NULL,
1617 (GtkClassInitFunc) NULL,
1620 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1623 return color_selection_type;
1627 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1629 GtkObjectClass *object_class;
1630 GObjectClass *gobject_class;
1633 object_class = GTK_OBJECT_CLASS (klass);
1634 gobject_class = G_OBJECT_CLASS (klass);
1636 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1638 object_class->destroy = gtk_color_selection_destroy;
1639 gobject_class->finalize = gtk_color_selection_finalize;
1641 color_selection_signals[COLOR_CHANGED] =
1642 gtk_signal_new ("color_changed",
1644 GTK_CLASS_TYPE (object_class),
1645 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1646 gtk_marshal_VOID__VOID,
1649 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1650 _("Custom palette"),
1651 _("Palette to use in the color selector"),
1653 G_PARAM_READWRITE));
1655 g_object_get (G_OBJECT (gtk_settings_get_default ()),
1656 "gtk-color-palette",
1660 fill_palette_from_string (palette);
1663 change_palette_hook = default_change_palette_func;
1665 g_signal_connect_data (G_OBJECT (gtk_settings_get_default ()),
1666 "notify::gtk-color-palette",
1667 G_CALLBACK (palette_change_notify_class),
1671 /* widget functions */
1674 gtk_color_selection_init (GtkColorSelection *colorsel)
1676 GtkWidget *top_hbox;
1677 GtkWidget *top_right_vbox;
1678 GtkWidget *table, *label, *hbox, *frame, *vbox;
1679 GtkAdjustment *adjust;
1680 GdkPixmap *dropper_pixmap;
1681 GtkWidget *dropper_image;
1683 GdkBitmap *mask = NULL;
1685 ColorSelectionPrivate *priv;
1687 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1688 priv->changing = FALSE;
1689 priv->default_set = FALSE;
1690 priv->default_alpha_set = FALSE;
1692 priv->tooltips = gtk_tooltips_new ();
1694 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1695 top_hbox = gtk_hbox_new (FALSE, 8);
1696 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1698 vbox = gtk_vbox_new (FALSE, 4);
1699 priv->triangle_colorsel = gtk_hsv_new ();
1700 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed",
1701 GTK_SIGNAL_FUNC (hsv_changed), colorsel);
1702 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1703 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1704 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1705 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1706 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1708 hbox = gtk_hbox_new (FALSE, 4);
1709 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1711 frame = gtk_frame_new (NULL);
1712 gtk_widget_set_usize (frame, -1, 30);
1713 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1714 color_sample_new (colorsel);
1715 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1716 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1718 button = gtk_button_new ();
1720 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1721 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1722 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1723 GTK_SIGNAL_FUNC (get_screen_color), NULL);
1724 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1725 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1726 gdk_pixmap_unref (dropper_pixmap);
1728 gdk_pixmap_unref (mask);
1729 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1730 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1732 gtk_tooltips_set_tip (priv->tooltips,
1734 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1736 top_right_vbox = gtk_vbox_new (FALSE, 4);
1737 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1738 table = gtk_table_new (8, 6, FALSE);
1739 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1740 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1741 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1743 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1744 _("Position on the color wheel."));
1745 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1746 _("\"Deepness\" of the color."));
1747 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1748 _("Brightness of the color."));
1749 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1750 _("Amount of red light in the color."));
1751 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1752 _("Amount of green light in the color."));
1753 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1754 _("Amount of blue light in the color."));
1755 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1757 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1758 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1759 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1760 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1761 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1762 priv->opacity_slider = gtk_hscale_new (adjust);
1763 gtk_tooltips_set_tip (priv->tooltips,
1764 priv->opacity_slider,
1765 _("Transparency of the currently-selected color."), NULL);
1766 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1767 priv->opacity_slider);
1768 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1769 gtk_signal_connect (GTK_OBJECT(adjust), "value_changed",
1770 GTK_SIGNAL_FUNC (adjustment_changed),
1771 GINT_TO_POINTER (COLORSEL_OPACITY));
1772 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1773 priv->opacity_entry = gtk_entry_new ();
1774 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1776 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate",
1777 GTK_SIGNAL_FUNC (opacity_entry_changed), colorsel);
1778 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1780 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1781 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1782 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1783 priv->hex_entry = gtk_entry_new ();
1785 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1787 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate",
1788 GTK_SIGNAL_FUNC (hex_changed), colorsel);
1790 gtk_tooltips_set_tip (priv->tooltips,
1792 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1794 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1795 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1796 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1798 /* Set up the palette */
1799 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1800 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1801 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1802 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1804 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1806 make_palette_frame (colorsel, table, i, j);
1809 set_selected_palette (colorsel, 0, 0);
1810 priv->palette_frame = gtk_frame_new (NULL);
1811 label = gtk_label_new_with_mnemonic (_("_Palette"));
1812 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1814 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1815 priv->custom_palette[0][0]);
1817 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1818 vbox = gtk_vbox_new (FALSE, 4);
1819 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1820 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1822 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1824 gtk_widget_show_all (top_hbox);
1826 /* Set default colors */
1828 update_palette (colorsel);
1830 priv->settings_connection =
1831 g_signal_connect_data (G_OBJECT (gtk_settings_get_default ()),
1832 "notify::gtk-color-palette",
1833 G_CALLBACK (palette_change_notify_instance),
1836 /* hide unused stuff */
1838 if (priv->has_opacity == FALSE)
1840 gtk_widget_hide (priv->opacity_label);
1841 gtk_widget_hide (priv->opacity_slider);
1842 gtk_widget_hide (priv->opacity_entry);
1845 if (priv->has_palette == FALSE)
1847 gtk_widget_hide (priv->palette_frame);
1852 gtk_color_selection_destroy (GtkObject *object)
1854 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1855 ColorSelectionPrivate *priv = cselection->private_data;
1857 if (priv->dropper_grab_widget)
1859 gtk_widget_destroy (priv->dropper_grab_widget);
1860 priv->dropper_grab_widget = NULL;
1865 gtk_object_destroy (GTK_OBJECT (priv->tooltips));
1866 priv->tooltips = NULL;
1869 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1873 gtk_color_selection_finalize (GObject *object)
1875 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1877 if (cselection->private_data)
1879 ColorSelectionPrivate *priv;
1881 priv = cselection->private_data;
1883 g_signal_handler_disconnect (gtk_settings_get_default (),
1884 priv->settings_connection);
1886 g_free (cselection->private_data);
1887 cselection->private_data = NULL;
1890 G_OBJECT_CLASS (parent_class)->finalize (object);
1895 * gtk_color_selection_new:
1897 * Creates a new GtkColorSelection.
1899 * Return value: a new #GtkColorSelection
1902 gtk_color_selection_new (void)
1904 GtkColorSelection *colorsel;
1905 ColorSelectionPrivate *priv;
1912 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
1913 priv = colorsel->private_data;
1914 gtk_color_selection_set_color (colorsel, color);
1915 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
1917 /* We want to make sure that default_set is FALSE */
1918 /* This way the user can still set it */
1919 priv->default_set = FALSE;
1920 priv->default_alpha_set = FALSE;
1922 return GTK_WIDGET (colorsel);
1927 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
1928 GtkUpdateType policy)
1930 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1932 g_warning (G_STRLOC ": This function is deprecated.");
1936 * gtk_color_selection_get_has_opacity_control:
1937 * @colorsel: A GtkColorSelection.
1939 * Determines whether the colorsel has an opacity control.
1941 * Return value: TRUE if the @colorsel has an opacity control. FALSE if it does't.
1944 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
1946 ColorSelectionPrivate *priv;
1948 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
1950 priv = colorsel->private_data;
1952 return priv->has_opacity;
1956 * gtk_color_selection_set_has_opacity_control:
1957 * @colorsel: A GtkColorSelection.
1958 * @has_opacity: TRUE if @colorsel can set the opacity, FALSE otherwise.
1960 * Sets the @colorsel to use or not use opacity.
1964 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
1965 gboolean has_opacity)
1967 ColorSelectionPrivate *priv;
1969 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1971 priv = colorsel->private_data;
1972 has_opacity = has_opacity != FALSE;
1974 if (priv->has_opacity != has_opacity)
1976 priv->has_opacity = has_opacity;
1979 gtk_widget_show (priv->opacity_slider);
1980 gtk_widget_show (priv->opacity_label);
1981 gtk_widget_show (priv->opacity_entry);
1985 gtk_widget_hide (priv->opacity_slider);
1986 gtk_widget_hide (priv->opacity_label);
1987 gtk_widget_hide (priv->opacity_entry);
1989 color_sample_draw_samples (colorsel);
1994 * gtk_color_selection_get_has_palette:
1995 * @colorsel: A GtkColorSelection.
1997 * Determines whether the color selector has a color palette.
1999 * Return value: TRUE if the selector has a palette. FALSE if it hasn't.
2002 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2004 ColorSelectionPrivate *priv;
2006 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2008 priv = colorsel->private_data;
2010 return priv->has_palette;
2014 * gtk_color_selection_set_has_palette:
2015 * @colorsel: A GtkColorSelection.
2016 * @has_palette: TRUE if palette is to be visible, FALSE otherwise.
2018 * Shows and hides the palette based upon the value of @has_palette.
2022 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2023 gboolean has_palette)
2025 ColorSelectionPrivate *priv;
2026 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2028 priv = colorsel->private_data;
2029 has_palette = has_palette != FALSE;
2031 if (priv->has_palette != has_palette)
2033 priv->has_palette = has_palette;
2035 gtk_widget_show (priv->palette_frame);
2037 gtk_widget_hide (priv->palette_frame);
2042 * gtk_color_selection_set_current_color:
2043 * @colorsel: A GtkColorSelection.
2044 * @color: A GdkColor to set the current color with.
2046 * Sets the current color to be @color. The first time this is called, it will
2047 * also set the original color to be @color too.
2051 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2054 ColorSelectionPrivate *priv;
2057 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2059 priv = colorsel->private_data;
2060 priv->changing = TRUE;
2061 priv->color[COLORSEL_RED] = color->red / 65535.0;
2062 priv->color[COLORSEL_GREEN] = color->green / 65535.0;
2063 priv->color[COLORSEL_BLUE] = color->blue / 65535.0;
2064 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2065 priv->color[COLORSEL_GREEN],
2066 priv->color[COLORSEL_BLUE],
2067 &priv->color[COLORSEL_HUE],
2068 &priv->color[COLORSEL_SATURATION],
2069 &priv->color[COLORSEL_VALUE]);
2070 if (priv->default_set == FALSE)
2072 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2073 priv->old_color[i] = priv->color[i];
2075 update_color (colorsel);
2076 priv->default_set = TRUE;
2080 * gtk_color_selection_set_current_alpha:
2081 * @colorsel: A GtkColorSelection.
2082 * @alpha: an integer between 0 and 65535
2084 * Sets the current opacity to be @alpha. The first time this is called, it will
2085 * also set the original opacity to be @alpha too.
2089 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2092 ColorSelectionPrivate *priv;
2095 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2097 priv = colorsel->private_data;
2098 priv->changing = TRUE;
2099 priv->color[COLORSEL_OPACITY] = alpha / 65535.0;
2100 if (priv->default_alpha_set == FALSE)
2102 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2103 priv->old_color[i] = priv->color[i];
2105 update_color (colorsel);
2106 priv->default_alpha_set = TRUE;
2110 * gtk_color_selection_set_color:
2111 * @colorsel: A GtkColorSelection.
2112 * @color: A array of doubles that specifies the color to set the current color with.
2114 * Sets the current color to be @color. The first time this is called, it will
2115 * also set the original color to be @color too.
2117 * This function is deprecated, use gtk_color_selection_set_current_color() instead.
2121 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2124 ColorSelectionPrivate *priv;
2127 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2129 priv = colorsel->private_data;
2130 priv->changing = TRUE;
2131 priv->color[COLORSEL_RED] = color[0];
2132 priv->color[COLORSEL_GREEN] = color[1];
2133 priv->color[COLORSEL_BLUE] = color[2];
2134 priv->color[COLORSEL_OPACITY] = color[3];
2135 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2136 priv->color[COLORSEL_GREEN],
2137 priv->color[COLORSEL_BLUE],
2138 &priv->color[COLORSEL_HUE],
2139 &priv->color[COLORSEL_SATURATION],
2140 &priv->color[COLORSEL_VALUE]);
2141 if (priv->default_set == FALSE)
2143 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2144 priv->old_color[i] = priv->color[i];
2146 update_color (colorsel);
2147 priv->default_set = TRUE;
2148 priv->default_alpha_set = TRUE;
2152 * gtk_color_selection_get_current_color:
2153 * @colorsel: A GtkColorSelection.
2154 * @color: A GdkColor to fill in with the current color.
2156 * Sets @color to be the current color in the GtkColorSelection widget.
2158 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2161 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2164 ColorSelectionPrivate *priv;
2166 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2168 priv = colorsel->private_data;
2169 color->red = priv->color[COLORSEL_RED] * 65535;
2170 color->green = priv->color[COLORSEL_GREEN] * 65535;
2171 color->blue = priv->color[COLORSEL_BLUE] * 65535;
2175 * gtk_color_selection_get_current_alpha:
2176 * @colorsel: A GtkColorSelection.
2178 * Returns the current alpha value
2180 * Return value: an integer between 0 and 65535
2183 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2185 ColorSelectionPrivate *priv;
2187 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2189 priv = colorsel->private_data;
2190 return priv->has_opacity ? priv->color[COLORSEL_OPACITY] * 65535 : 1.0;
2194 * gtk_color_selection_get_color:
2195 * @colorsel: A GtkColorSelection.
2196 * @color: A color to fill in with the current color.
2198 * Sets @color to be the current color in the GtkColorSelection widget.
2202 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2205 ColorSelectionPrivate *priv;
2207 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2209 priv = colorsel->private_data;
2210 color[0] = priv->color[COLORSEL_RED];
2211 color[1] = priv->color[COLORSEL_GREEN];
2212 color[2] = priv->color[COLORSEL_BLUE];
2213 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 1.0;
2217 * gtk_color_selection_set_previous_color:
2218 * @colorsel: A GtkColorSelection.
2219 * @color: A color to set the previous color with.
2221 * Sets the 'previous' color to be @color. This function should be called with
2222 * some hesitations, as it might seem confusing to have that color change.
2223 * Calling gtk_color_selection_set_current_color will also set this color the first
2224 * time it is called.
2228 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2231 ColorSelectionPrivate *priv;
2233 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2235 priv = colorsel->private_data;
2236 priv->changing = TRUE;
2237 priv->old_color[COLORSEL_RED] = color->red / 65535.0;
2238 priv->old_color[COLORSEL_GREEN] = color->green / 65535.0;
2239 priv->old_color[COLORSEL_BLUE] = color->blue / 65535.0;
2240 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2241 priv->old_color[COLORSEL_GREEN],
2242 priv->old_color[COLORSEL_BLUE],
2243 &priv->old_color[COLORSEL_HUE],
2244 &priv->old_color[COLORSEL_SATURATION],
2245 &priv->old_color[COLORSEL_VALUE]);
2246 color_sample_draw_samples (colorsel);
2247 priv->default_set = TRUE;
2251 * gtk_color_selection_set_previous_alpha:
2252 * @colorsel: A GtkColorSelection.
2253 * @alpha: an integer between 0 and 65535
2255 * Sets the 'previous' alpha to be @alpha. This function should be called with
2256 * some hesitations, as it might seem confusing to have that color change.
2260 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2263 ColorSelectionPrivate *priv;
2265 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2267 priv = colorsel->private_data;
2268 priv->changing = TRUE;
2269 priv->old_color[COLORSEL_OPACITY] = alpha / 65535.0;
2270 color_sample_draw_samples (colorsel);
2271 priv->default_alpha_set = TRUE;
2276 * gtk_color_selection_get_previous_color:
2277 * @colorsel: A GtkColorSelection.
2278 * @color: A GdkColor to fill in with the original color value.
2280 * Fills @color in with the original color value.
2284 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2287 ColorSelectionPrivate *priv;
2289 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2291 priv = colorsel->private_data;
2292 color->red = priv->old_color[COLORSEL_RED] * 65535;
2293 color->green = priv->old_color[COLORSEL_GREEN] * 65535;
2294 color->blue = priv->old_color[COLORSEL_BLUE] * 65535;
2298 * gtk_color_selection_get_previous_alpha:
2299 * @colorsel: A GtkColorSelection.
2301 * Returns the previous alpha value
2303 * Return value: an integer between 0 and 65535
2306 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2308 ColorSelectionPrivate *priv;
2310 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2312 priv = colorsel->private_data;
2313 return priv->has_opacity ? priv->old_color[COLORSEL_OPACITY] * 65535 : 1.0;
2317 * gtk_color_selection_set_palette_color:
2318 * @colorsel: A GtkColorSelection.
2319 * @index: The color index of the palette.
2320 * @color: A GdkColor to set the palette with.
2322 * Set the palette located at at @index to have @color set as its color.
2326 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2330 ColorSelectionPrivate *priv;
2334 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2335 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2337 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2338 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2340 priv = colorsel->private_data;
2341 col[0] = color->red / 65535.0;
2342 col[1] = color->green / 65535.0;
2343 col[2] = color->blue / 65535.0;
2345 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2349 * gtk_color_selection_get_palette_color:
2350 * @colorsel: A GtkColorSelection.
2351 * @index: The color index of the palette.
2352 * @color: A color to fill in with the color value.
2354 * Set @color to have the color found in the palette at @index. If
2355 * the palette is unset, it will leave the color unset.
2357 * Return value: TRUE if the palette located at @index has a color set. FALSE
2361 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
2365 ColorSelectionPrivate *priv;
2369 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2370 g_return_val_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
2372 priv = colorsel->private_data;
2374 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2375 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2377 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
2380 palette_get_color (priv->custom_palette[x][y], col);
2382 color->red = col[0] * 65535;
2383 color->green = col[1] * 65535;
2384 color->blue = col[2] * 65535;
2390 * gtk_color_selection_unset_palette_color:
2391 * @colorsel: A GtkColorSelection.
2392 * @index: The color index in the palette.
2394 * Change the palette located @index to have no color set.
2398 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
2401 ColorSelectionPrivate *priv;
2404 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2405 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2407 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2408 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2410 priv = colorsel->private_data;
2411 palette_unset_color (priv->custom_palette[x][y]);
2415 * gtk_color_selection_get_current_alpha:
2416 * @colorsel: A GtkColorSelection.
2418 * Returns the maximum number of palette colors.
2420 * Return value: the maximum number of palette indexes
2423 gtk_color_selection_get_palette_size (GtkColorSelection *colorsel)
2425 return GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
2430 * gtk_color_selection_is_adjusting:
2431 * @colorsel: A GtkColorSelection.
2433 * Gets the current state of the @colorsel.
2435 * Return value: TRUE if the user is currently dragging a color around, and FALSE
2436 * if the selection has stopped.
2439 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2441 ColorSelectionPrivate *priv;
2443 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2445 priv = colorsel->private_data;
2447 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2452 * gtk_color_selection_palette_from_string:
2453 * @str: a string encoding a color palette
2454 * @colors: return location for allocated array of GdkColor
2455 * @n_colors: return location for length of array
2457 * Parses a color palette string; the string is a colon-separated
2458 * list of color names readable by gdk_color_parse().
2460 * Return value: %TRUE if a palette was successfully parsed
2463 gtk_color_selection_palette_from_string (const gchar *str,
2475 copy = g_strdup (str);
2481 if (*p == ':' || *p == '\0')
2483 gboolean done = TRUE;
2487 goto failed; /* empty entry */
2496 retval = g_renew (GdkColor, retval, count + 1);
2497 if (!gdk_color_parse (start, retval + count))
2538 * gtk_color_selection_palette_to_string:
2539 * @colors: an array of colors
2540 * @n_colors: length of the array
2542 * Encodes a palette as a string, useful for persistent storage.
2544 * Return value: allocated string encoding the palette
2547 gtk_color_selection_palette_to_string (const GdkColor *colors,
2551 gchar **strs = NULL;
2555 return g_strdup ("");
2557 strs = g_new0 (gchar*, n_colors + 1);
2560 while (i < n_colors)
2565 g_strdup_printf ("#%2X%2X%2X",
2566 colors[i].red / 256,
2567 colors[i].green / 256,
2568 colors[i].blue / 256);
2570 for (ptr = strs[i]; *ptr; ptr++)
2577 retval = g_strjoinv (":", strs);
2585 * gtk_color_selection_set_change_palette_hook:
2586 * @func: a function to call when the custom palette needs saving
2588 * Installs a global function to be called whenever the user tries to
2589 * modify the palette in a color selection. This function should save
2590 * the new palette contents, and update the GtkSettings property
2591 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2593 * Return value: the previous change palette hook (that was replaced)
2595 GtkColorSelectionChangePaletteFunc
2596 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2598 GtkColorSelectionChangePaletteFunc old;
2600 old = change_palette_hook;
2602 change_palette_hook = func;