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-2001. 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
73 /* Conversion between 0->1 double and and guint16. See
74 * scale_round() below for more general conversions
76 #define SCALE(i) (i / 65535.)
77 #define UNSCALE(d) ((guint16)(d * 65535 + 0.5))
88 PROP_HAS_OPACITY_CONTROL,
101 COLORSEL_NUM_CHANNELS
104 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
106 struct _ColorSelectionPrivate
108 guint has_opacity : 1;
109 guint has_palette : 1;
111 guint default_set : 1;
112 guint default_alpha_set : 1;
114 gdouble color[COLORSEL_NUM_CHANNELS];
115 gdouble old_color[COLORSEL_NUM_CHANNELS];
117 GtkWidget *triangle_colorsel;
118 GtkWidget *hue_spinbutton;
119 GtkWidget *sat_spinbutton;
120 GtkWidget *val_spinbutton;
121 GtkWidget *red_spinbutton;
122 GtkWidget *green_spinbutton;
123 GtkWidget *blue_spinbutton;
124 GtkWidget *opacity_slider;
125 GtkWidget *opacity_label;
126 GtkWidget *opacity_entry;
127 GtkWidget *palette_frame;
128 GtkWidget *hex_entry;
130 /* The Palette code */
131 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
133 /* The color_sample stuff */
134 GtkWidget *sample_area;
135 GtkWidget *old_sample;
136 GtkWidget *cur_sample;
140 GtkTooltips *tooltips;
142 /* Window for grabbing on */
143 GtkWidget *dropper_grab_widget;
145 /* Connection to settings */
146 guint settings_connection;
150 static void gtk_color_selection_init (GtkColorSelection *colorsel);
151 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
152 static void gtk_color_selection_destroy (GtkObject *object);
153 static void gtk_color_selection_finalize (GObject *object);
154 static void update_color (GtkColorSelection *colorsel);
155 static void gtk_color_selection_set_property (GObject *object,
159 static void gtk_color_selection_get_property (GObject *object,
164 static gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel);
165 static gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
168 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
171 static void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
174 static gpointer parent_class = NULL;
175 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
177 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";
179 static GtkColorSelectionChangePaletteFunc change_palette_hook = NULL;
181 static GdkColor current_colors[GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT];
183 /* The cursor for the dropper */
184 #define DROPPER_WIDTH 17
185 #define DROPPER_HEIGHT 17
186 #define DROPPER_X_HOT 2
187 #define DROPPER_Y_HOT 16
190 static char dropper_bits[] = {
191 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
192 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
193 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
194 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
197 static char dropper_mask[] = {
198 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
199 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
200 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
201 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
204 static GdkCursor *picker_cursor = NULL;
208 static char *picker[] = {
209 /* columns rows colors chars-per-pixel */
220 "#########################",
221 "#########################",
222 "#########################",
223 "#########################",
224 "#########################",
225 "################# #####",
226 "################ ####",
227 "################ +###",
228 "############# +###",
229 "############## ++###",
230 "#############+@ +++####",
231 "############+@@@ +######",
232 "###########+@@@ + +######",
233 "##########+@@@ ++#+######",
234 "#########+@@@ ++#########",
235 "########+@@@ ++##########",
236 "#######+@@@ ++###########",
237 "######+@@@ ++############",
238 "######+@@ ++#############",
239 "#####+@ ++##############",
240 "###### +++###############",
241 "#########################",
242 "#########################",
243 "#########################",
244 "#########################"
253 #define SAMPLE_WIDTH 64
254 #define SAMPLE_HEIGHT 28
256 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
257 static void color_sample_draw_samples (GtkColorSelection *colorsel);
260 color_sample_drag_begin (GtkWidget *widget,
261 GdkDragContext *context,
264 GtkColorSelection *colorsel = data;
265 ColorSelectionPrivate *priv;
272 priv = colorsel->private_data;
273 window = gtk_window_new (GTK_WINDOW_POPUP);
274 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
275 gtk_widget_set_usize (window, 48, 32);
276 gtk_widget_realize (window);
277 gtk_object_set_data_full (GTK_OBJECT (widget),
278 "gtk-color-selection-drag-window",
280 (GtkDestroyNotify) gtk_widget_destroy);
282 if (widget == priv->old_sample)
283 colsrc = priv->old_color;
285 colsrc = priv->color;
287 for (i=0, n = COLORSEL_RED; n <= COLORSEL_BLUE; n++)
289 colors[i++] = colsrc[n];
292 if (priv->has_opacity)
294 colors[i] = colsrc[COLORSEL_OPACITY];
297 bg.red = 0xffff * colors[0];
298 bg.green = 0xffff * colors[1];
299 bg.blue = 0xffff * colors[2];
301 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
302 gdk_window_set_background (window->window, &bg);
304 gtk_drag_set_icon_widget (context, window, -2, -2);
308 color_sample_drag_end (GtkWidget *widget,
309 GdkDragContext *context,
312 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
316 color_sample_drop_handle (GtkWidget *widget,
317 GdkDragContext *context,
320 GtkSelectionData *selection_data,
325 GtkColorSelection *colorsel = data;
326 ColorSelectionPrivate *priv;
329 priv = colorsel->private_data;
331 /* This is currently a guint16 array of the format:
338 if (selection_data->length < 0)
341 if ((selection_data->format != 16) ||
342 (selection_data->length != 8))
344 g_warning ("Received invalid color data\n");
348 vals = (guint16 *)selection_data->data;
350 if (widget == priv->cur_sample)
352 color[0] = (gdouble)vals[0] / 0xffff;
353 color[1] = (gdouble)vals[1] / 0xffff;
354 color[2] = (gdouble)vals[2] / 0xffff;
355 color[3] = (gdouble)vals[3] / 0xffff;
357 gtk_color_selection_set_color (colorsel, color);
362 color_sample_drag_handle (GtkWidget *widget,
363 GdkDragContext *context,
364 GtkSelectionData *selection_data,
369 GtkColorSelection *colorsel = data;
370 ColorSelectionPrivate *priv;
374 priv = colorsel->private_data;
376 if (widget == priv->old_sample)
377 colsrc = priv->old_color;
379 colsrc = priv->color;
381 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
382 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
383 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
384 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
386 gtk_selection_data_set (selection_data,
387 gdk_atom_intern ("application/x-color", FALSE),
388 16, (guchar *)vals, 8);
391 /* which = 0 means draw old sample, which = 1 means draw new */
393 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
396 gint x, y, i, wid, heig, f, n, goff;
397 guchar c[3 * 2], cc[3 * 4], *cp = c;
400 ColorSelectionPrivate *priv;
402 g_return_if_fail (colorsel != NULL);
403 priv = colorsel->private_data;
405 g_return_if_fail (priv->sample_area != NULL);
406 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
411 da = priv->old_sample;
412 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
413 c[n] = (guchar) (UNSCALE (priv->old_color[i]) >> 8);
418 da = priv->cur_sample;
419 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
420 c[n] = (guchar) (UNSCALE (priv->color[i]) >> 8);
421 goff = priv->old_sample->allocation.width % 32;
424 wid = da->allocation.width;
425 heig = da->allocation.height;
427 buf = g_new (guchar, 3 * wid * heig);
431 for (n = 0; n < 3; n++)
433 c[n] = (guchar) (255.0 * priv->old_color[i]);
434 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
438 if (priv->has_opacity)
440 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
442 for (n = 0; n < 3; n++)
444 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
445 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
451 for (y = 0; y < heig; y++)
453 for (x = 0; x < wid; x++)
455 if (priv->has_opacity)
456 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
460 for (n = 0; n < 3; n++)
461 buf[i++] = cp[n + f];
465 gdk_draw_rgb_image (da->window,
469 GDK_RGB_DITHER_NORMAL,
479 color_sample_draw_samples (GtkColorSelection *colorsel)
481 color_sample_draw_sample (colorsel, 0);
482 color_sample_draw_sample (colorsel, 1);
486 color_old_sample_expose (GtkWidget *da,
487 GdkEventExpose *event,
488 GtkColorSelection *colorsel)
490 color_sample_draw_sample (colorsel, 0);
495 color_cur_sample_expose (GtkWidget *da,
496 GdkEventExpose *event,
497 GtkColorSelection *colorsel)
499 color_sample_draw_sample (colorsel, 1);
503 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
505 static const GtkTargetEntry targets[] = {
506 { "application/x-color", 0 }
508 ColorSelectionPrivate *priv;
509 priv = colorsel->private_data;
511 gtk_drag_source_set (sample,
512 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
514 GDK_ACTION_COPY | GDK_ACTION_MOVE);
516 gtk_signal_connect (GTK_OBJECT (sample),
518 GTK_SIGNAL_FUNC (color_sample_drag_begin),
520 if (sample == priv->cur_sample)
523 gtk_drag_dest_set (sample,
524 GTK_DEST_DEFAULT_HIGHLIGHT |
525 GTK_DEST_DEFAULT_MOTION |
526 GTK_DEST_DEFAULT_DROP,
530 gtk_signal_connect (GTK_OBJECT (sample),
532 GTK_SIGNAL_FUNC (color_sample_drag_end),
536 gtk_signal_connect (GTK_OBJECT (sample),
538 GTK_SIGNAL_FUNC (color_sample_drag_handle),
540 gtk_signal_connect (GTK_OBJECT (sample),
541 "drag_data_received",
542 GTK_SIGNAL_FUNC (color_sample_drop_handle),
549 color_sample_new (GtkColorSelection *colorsel)
551 ColorSelectionPrivate *priv;
553 priv = colorsel->private_data;
555 priv->sample_area = gtk_hbox_new (FALSE, 0);
556 priv->old_sample = gtk_drawing_area_new ();
557 priv->cur_sample = gtk_drawing_area_new ();
559 /* We need enter/leave to do tooltips */
560 gtk_widget_add_events (priv->old_sample,
561 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
562 gtk_widget_add_events (priv->cur_sample,
563 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
565 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
567 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
570 gtk_signal_connect (GTK_OBJECT (priv->old_sample), "expose_event",
571 GTK_SIGNAL_FUNC (color_old_sample_expose),
573 gtk_signal_connect (GTK_OBJECT (priv->cur_sample), "expose_event",
574 GTK_SIGNAL_FUNC (color_cur_sample_expose),
577 color_sample_setup_dnd (colorsel, priv->old_sample);
578 color_sample_setup_dnd (colorsel, priv->cur_sample);
580 gtk_tooltips_set_tip (priv->tooltips,
582 _("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);
585 gtk_tooltips_set_tip (priv->tooltips,
587 _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL);
589 gtk_widget_show_all (priv->sample_area);
595 * The palette area code
598 #define CUSTOM_PALETTE_ENTRY_WIDTH 20
599 #define CUSTOM_PALETTE_ENTRY_HEIGHT 20
602 palette_get_color (GtkWidget *drawing_area, gdouble *color)
606 g_return_if_fail (color != NULL);
608 color_val = gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
609 if (color_val == NULL)
611 /* Default to white for no good reason */
619 color[0] = color_val[0];
620 color[1] = color_val[1];
621 color[2] = color_val[2];
625 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
627 palette_paint (GtkWidget *drawing_area,
631 if (drawing_area->window == NULL)
634 gdk_window_clear_area (drawing_area->window,
640 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
645 palette_get_color (drawing_area, color);
647 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
648 gc = drawing_area->style->black_gc;
650 gc = drawing_area->style->white_gc;
652 gdk_draw_rectangle (drawing_area->window,
654 drawing_area->allocation.width - 1,
655 drawing_area->allocation.height - 1);
661 palette_drag_begin (GtkWidget *widget,
662 GdkDragContext *context,
665 GtkColorSelection *colorsel = data;
666 ColorSelectionPrivate *priv;
671 priv = colorsel->private_data;
672 window = gtk_window_new (GTK_WINDOW_POPUP);
673 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
674 gtk_widget_set_usize (window, 48, 32);
675 gtk_widget_realize (window);
676 gtk_object_set_data_full (GTK_OBJECT (widget),
677 "gtk-color-selection-drag-window",
679 (GtkDestroyNotify) gtk_widget_destroy);
681 palette_get_color (widget, colors);
682 bg.red = 0xffff * colors[0];
683 bg.green = 0xffff * colors[1];
684 bg.blue = 0xffff * colors[2];
686 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
687 gdk_window_set_background (window->window, &bg);
689 gtk_drag_set_icon_widget (context, window, -2, -2);
693 palette_drag_handle (GtkWidget *widget,
694 GdkDragContext *context,
695 GtkSelectionData *selection_data,
703 palette_get_color (widget, colsrc);
705 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
706 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
707 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
710 gtk_selection_data_set (selection_data,
711 gdk_atom_intern ("application/x-color", FALSE),
712 16, (guchar *)vals, 8);
716 palette_drag_end (GtkWidget *widget,
717 GdkDragContext *context,
720 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
723 /* Changes the model color */
725 palette_change_color (GtkWidget *drawing_area,
726 GtkColorSelection *colorsel,
730 ColorSelectionPrivate *priv;
733 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
734 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
736 priv = colorsel->private_data;
738 gdk_color.red = UNSCALE (color[0]);
739 gdk_color.green = UNSCALE (color[1]);
740 gdk_color.blue = UNSCALE (color[2]);
743 while (x < GTK_CUSTOM_PALETTE_WIDTH)
746 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
748 if (priv->custom_palette[x][y] == drawing_area)
759 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
761 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
763 if (change_palette_hook)
764 (* change_palette_hook) (current_colors, GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
767 /* Changes the view color */
769 palette_set_color (GtkWidget *drawing_area,
770 GtkColorSelection *colorsel,
773 gdouble *new_color = g_new (double, 4);
777 gdk_color.red = UNSCALE (color[0]);
778 gdk_color.green = UNSCALE (color[1]);
779 gdk_color.blue = UNSCALE (color[2]);
781 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
783 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
785 static const GtkTargetEntry targets[] = {
786 { "application/x-color", 0 }
788 gtk_drag_source_set (drawing_area,
789 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
791 GDK_ACTION_COPY | GDK_ACTION_MOVE);
793 gtk_signal_connect (GTK_OBJECT (drawing_area),
795 GTK_SIGNAL_FUNC (palette_drag_begin),
797 gtk_signal_connect (GTK_OBJECT (drawing_area),
799 GTK_SIGNAL_FUNC (palette_drag_handle),
802 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
806 old_color = (gdouble *) gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
812 new_color[0] = color[0];
813 new_color[1] = color[1];
814 new_color[2] = color[2];
817 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_val", new_color);
821 palette_expose (GtkWidget *drawing_area,
822 GdkEventExpose *event,
825 if (drawing_area->window == NULL)
828 palette_paint (drawing_area, &(event->area), data);
832 popup_position_func (GtkMenu *menu,
842 widget = GTK_WIDGET (user_data);
844 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
846 gdk_window_get_origin (widget->window, &root_x, &root_y);
848 gtk_widget_size_request (GTK_WIDGET (menu), &req);
850 /* Put corner of menu centered on color cell */
851 *x = root_x + widget->allocation.width / 2;
852 *y = root_y + widget->allocation.height / 2;
855 *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
856 *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
860 save_color_selected (GtkWidget *menuitem,
863 GtkColorSelection *colorsel;
864 GtkWidget *drawing_area;
865 ColorSelectionPrivate *priv;
867 drawing_area = GTK_WIDGET (data);
869 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
872 priv = colorsel->private_data;
874 palette_change_color (drawing_area, colorsel, priv->color);
878 do_popup (GtkColorSelection *colorsel,
879 GtkWidget *drawing_area,
885 g_object_set_data (G_OBJECT (drawing_area),
889 menu = gtk_menu_new ();
891 mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
893 gtk_signal_connect (GTK_OBJECT (mi), "activate",
894 GTK_SIGNAL_FUNC (save_color_selected),
897 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
899 gtk_widget_show_all (mi);
901 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
902 popup_position_func, drawing_area,
908 palette_press (GtkWidget *drawing_area,
909 GdkEventButton *event,
912 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
914 gtk_widget_grab_focus (drawing_area);
916 if (event->button == 1 &&
917 event->type == GDK_BUTTON_PRESS)
919 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0)
922 palette_get_color (drawing_area, color);
923 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
927 if (event->button == 3 &&
928 event->type == GDK_BUTTON_PRESS)
930 do_popup (colorsel, drawing_area, event->time);
937 palette_unset_color (GtkWidget *drawing_area)
939 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
942 gtk_widget_reset_rc_styles (drawing_area);
943 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0));
947 palette_drop_handle (GtkWidget *widget,
948 GdkDragContext *context,
951 GtkSelectionData *selection_data,
959 if (selection_data->length < 0)
962 if ((selection_data->format != 16) ||
963 (selection_data->length != 8))
965 g_warning ("Received invalid color data\n");
969 vals = (guint16 *)selection_data->data;
971 color[0] = (gdouble)vals[0] / 0xffff;
972 color[1] = (gdouble)vals[1] / 0xffff;
973 color[2] = (gdouble)vals[2] / 0xffff;
974 color[3] = (gdouble)vals[3] / 0xffff;
975 palette_change_color (widget, GTK_COLOR_SELECTION (data), color);
976 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
980 palette_activate (GtkWidget *widget,
984 /* should have a drawing area subclass with an activate signal */
985 if ((event->keyval == GDK_space) ||
986 (event->keyval == GDK_Return) ||
987 (event->keyval == GDK_KP_Enter) ||
988 (event->keyval == GDK_KP_Space))
990 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "color_set")) != 0)
993 palette_get_color (widget, color);
994 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
1003 palette_popup (GtkWidget *widget,
1006 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1008 do_popup (colorsel, widget, GDK_CURRENT_TIME);
1013 palette_new (GtkColorSelection *colorsel)
1016 ColorSelectionPrivate *priv;
1018 static const GtkTargetEntry targets[] = {
1019 { "application/x-color", 0 }
1022 priv = colorsel->private_data;
1024 retval = gtk_drawing_area_new ();
1026 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1028 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
1029 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1030 | GDK_BUTTON_RELEASE_MASK
1032 | GDK_ENTER_NOTIFY_MASK
1033 | GDK_LEAVE_NOTIFY_MASK);
1036 gtk_signal_connect (GTK_OBJECT (retval), "expose_event",
1037 GTK_SIGNAL_FUNC (palette_expose), colorsel);
1038 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event",
1039 GTK_SIGNAL_FUNC (palette_press), colorsel);
1040 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event",
1041 GTK_SIGNAL_FUNC (palette_activate), colorsel);
1042 gtk_signal_connect (GTK_OBJECT (retval), "popup_menu",
1043 GTK_SIGNAL_FUNC (palette_popup), colorsel);
1045 gtk_drag_dest_set (retval,
1046 GTK_DEST_DEFAULT_HIGHLIGHT |
1047 GTK_DEST_DEFAULT_MOTION |
1048 GTK_DEST_DEFAULT_DROP,
1052 gtk_signal_connect (GTK_OBJECT (retval), "drag_end",
1053 GTK_SIGNAL_FUNC (palette_drag_end), NULL);
1054 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received",
1055 GTK_SIGNAL_FUNC (palette_drop_handle), colorsel);
1057 gtk_tooltips_set_tip (priv->tooltips,
1059 _("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.\""),
1067 * The actual GtkColorSelection widget
1072 initialize_cursor (void)
1077 gdk_bitmap_create_from_data (NULL,
1079 DROPPER_WIDTH, DROPPER_HEIGHT);
1081 gdk_bitmap_create_from_data (NULL,
1083 DROPPER_WIDTH, DROPPER_HEIGHT);
1085 gdk_color_white (gdk_colormap_get_system (), &bg);
1086 gdk_color_black (gdk_colormap_get_system (), &fg);
1088 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
1090 gdk_pixmap_unref (pixmap);
1091 gdk_pixmap_unref (mask);
1096 grab_color_at_mouse (GtkWidget *invisible,
1103 GtkColorSelection *colorsel = data;
1104 ColorSelectionPrivate *priv;
1105 GdkColormap *colormap = gdk_colormap_get_system ();
1108 priv = colorsel->private_data;
1110 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
1111 pixel = gdk_image_get_pixel (image, 0, 0);
1112 gdk_image_unref (image);
1114 gdk_colormap_query_color (colormap, pixel, &color);
1116 priv->color[COLORSEL_RED] = SCALE (color.red);
1117 priv->color[COLORSEL_GREEN] = SCALE (color.green);
1118 priv->color[COLORSEL_BLUE] = SCALE (color.blue);
1120 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1121 priv->color[COLORSEL_GREEN],
1122 priv->color[COLORSEL_BLUE],
1123 &priv->color[COLORSEL_HUE],
1124 &priv->color[COLORSEL_SATURATION],
1125 &priv->color[COLORSEL_VALUE]);
1127 update_color (colorsel);
1131 shutdown_eyedropper (GtkWidget *widget)
1133 GtkColorSelection *colorsel;
1134 ColorSelectionPrivate *priv;
1136 colorsel = GTK_COLOR_SELECTION (widget);
1137 priv = colorsel->private_data;
1139 gdk_keyboard_ungrab (gtk_get_current_event_time ());
1140 gdk_pointer_ungrab (gtk_get_current_event_time ());
1141 gtk_grab_remove (priv->dropper_grab_widget);
1145 mouse_motion (GtkWidget *invisible,
1146 GdkEventMotion *event,
1149 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1153 mouse_release (GtkWidget *invisible,
1154 GdkEventButton *event,
1157 GtkColorSelection *colorsel = data;
1158 ColorSelectionPrivate *priv;
1159 priv = colorsel->private_data;
1161 if (event->button != 1)
1164 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1166 shutdown_eyedropper (GTK_WIDGET (data));
1168 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1169 GTK_SIGNAL_FUNC (mouse_motion), data);
1170 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1171 GTK_SIGNAL_FUNC (mouse_release), data);
1176 /* Helper Functions */
1178 static gboolean mouse_press (GtkWidget *invisible,
1179 GdkEventButton *event,
1183 key_press (GtkWidget *invisible,
1187 if (event->keyval == GDK_Escape)
1189 shutdown_eyedropper (data);
1191 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1192 GTK_SIGNAL_FUNC (mouse_press),
1194 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1195 GTK_SIGNAL_FUNC (key_press),
1205 mouse_press (GtkWidget *invisible,
1206 GdkEventButton *event,
1209 GtkColorSelection *colorsel = data;
1210 ColorSelectionPrivate *priv;
1211 priv = colorsel->private_data;
1213 if (event->type == GDK_BUTTON_PRESS &&
1216 gtk_signal_connect (GTK_OBJECT (invisible), "motion_notify_event",
1217 GTK_SIGNAL_FUNC (mouse_motion),
1219 gtk_signal_connect (GTK_OBJECT (invisible), "button_release_event",
1220 GTK_SIGNAL_FUNC (mouse_release),
1222 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1223 GTK_SIGNAL_FUNC (mouse_press),
1225 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1226 GTK_SIGNAL_FUNC (key_press),
1234 /* when the button is clicked */
1236 get_screen_color (GtkWidget *button)
1238 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
1239 ColorSelectionPrivate *priv = colorsel->private_data;
1241 if (picker_cursor == NULL)
1243 initialize_cursor ();
1246 if (priv->dropper_grab_widget == NULL)
1248 priv->dropper_grab_widget = gtk_invisible_new ();
1250 gtk_widget_add_events (priv->dropper_grab_widget,
1251 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1253 gtk_widget_show (priv->dropper_grab_widget);
1256 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1258 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1260 g_warning ("Failed to grab keyboard to do eyedropper");
1264 if (gdk_pointer_grab (priv->dropper_grab_widget->window,
1266 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1269 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1271 gdk_keyboard_ungrab (GDK_CURRENT_TIME);
1272 g_warning ("Failed to grab pointer to do eyedropper");
1276 gtk_grab_add (priv->dropper_grab_widget);
1278 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "button_press_event",
1279 GTK_SIGNAL_FUNC (mouse_press), colorsel);
1280 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "key_press_event",
1281 GTK_SIGNAL_FUNC (key_press), colorsel);
1285 hex_changed (GtkWidget *hex_entry,
1288 GtkColorSelection *colorsel;
1289 ColorSelectionPrivate *priv;
1293 colorsel = GTK_COLOR_SELECTION (data);
1294 priv = colorsel->private_data;
1299 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1300 if (gdk_color_parse (text, &color))
1302 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1303 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1304 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1305 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1306 priv->color[COLORSEL_GREEN],
1307 priv->color[COLORSEL_BLUE],
1308 &priv->color[COLORSEL_HUE],
1309 &priv->color[COLORSEL_SATURATION],
1310 &priv->color[COLORSEL_VALUE]);
1311 update_color (colorsel);
1317 hsv_changed (GtkWidget *hsv,
1320 GtkColorSelection *colorsel;
1321 ColorSelectionPrivate *priv;
1323 colorsel = GTK_COLOR_SELECTION (data);
1324 priv = colorsel->private_data;
1329 gtk_hsv_get_color (GTK_HSV (hsv),
1330 &priv->color[COLORSEL_HUE],
1331 &priv->color[COLORSEL_SATURATION],
1332 &priv->color[COLORSEL_VALUE]);
1333 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1334 priv->color[COLORSEL_SATURATION],
1335 priv->color[COLORSEL_VALUE],
1336 &priv->color[COLORSEL_RED],
1337 &priv->color[COLORSEL_GREEN],
1338 &priv->color[COLORSEL_BLUE]);
1339 update_color (colorsel);
1343 adjustment_changed (GtkAdjustment *adjustment,
1346 GtkColorSelection *colorsel;
1347 ColorSelectionPrivate *priv;
1349 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1350 priv = colorsel->private_data;
1355 switch (GPOINTER_TO_INT (data))
1357 case COLORSEL_SATURATION:
1358 case COLORSEL_VALUE:
1359 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1360 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1361 priv->color[COLORSEL_SATURATION],
1362 priv->color[COLORSEL_VALUE],
1363 &priv->color[COLORSEL_RED],
1364 &priv->color[COLORSEL_GREEN],
1365 &priv->color[COLORSEL_BLUE]);
1368 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1369 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1370 priv->color[COLORSEL_SATURATION],
1371 priv->color[COLORSEL_VALUE],
1372 &priv->color[COLORSEL_RED],
1373 &priv->color[COLORSEL_GREEN],
1374 &priv->color[COLORSEL_BLUE]);
1377 case COLORSEL_GREEN:
1379 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1381 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1382 priv->color[COLORSEL_GREEN],
1383 priv->color[COLORSEL_BLUE],
1384 &priv->color[COLORSEL_HUE],
1385 &priv->color[COLORSEL_SATURATION],
1386 &priv->color[COLORSEL_VALUE]);
1389 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1392 update_color (colorsel);
1396 opacity_entry_changed (GtkWidget *opacity_entry,
1399 GtkColorSelection *colorsel;
1400 ColorSelectionPrivate *priv;
1404 colorsel = GTK_COLOR_SELECTION (data);
1405 priv = colorsel->private_data;
1410 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1411 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1412 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1414 update_color (colorsel);
1420 make_label_spinbutton (GtkColorSelection *colorsel,
1421 GtkWidget **spinbutton,
1427 const gchar *tooltip)
1430 GtkAdjustment *adjust;
1431 ColorSelectionPrivate *priv = colorsel->private_data;
1433 if (channel_type == COLORSEL_HUE)
1435 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1439 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1441 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1442 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1444 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1446 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1447 GTK_SIGNAL_FUNC (adjustment_changed),
1448 GINT_TO_POINTER (channel_type));
1449 label = gtk_label_new_with_mnemonic (text);
1450 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1452 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1453 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1454 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1459 make_palette_frame (GtkColorSelection *colorsel,
1465 ColorSelectionPrivate *priv;
1467 priv = colorsel->private_data;
1468 frame = gtk_frame_new (NULL);
1469 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1470 priv->custom_palette[i][j] = palette_new (colorsel);
1471 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1472 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1473 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1476 /* Set the palette entry [x][y] to be the currently selected one. */
1478 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1480 ColorSelectionPrivate *priv = colorsel->private_data;
1482 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1486 scale_round (double val, double factor)
1488 val = floor (val * factor + 0.5);
1490 val = MIN (val, factor);
1495 update_color (GtkColorSelection *colorsel)
1497 ColorSelectionPrivate *priv = colorsel->private_data;
1499 gchar opacity_text[32];
1502 priv->changing = TRUE;
1503 color_sample_draw_samples (colorsel);
1505 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1506 priv->color[COLORSEL_HUE],
1507 priv->color[COLORSEL_SATURATION],
1508 priv->color[COLORSEL_VALUE]);
1509 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1510 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1511 scale_round (priv->color[COLORSEL_HUE], 360));
1512 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1513 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1514 scale_round (priv->color[COLORSEL_SATURATION], 255));
1515 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1516 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1517 scale_round (priv->color[COLORSEL_VALUE], 255));
1518 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1519 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1520 scale_round (priv->color[COLORSEL_RED], 255));
1521 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1522 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1523 scale_round (priv->color[COLORSEL_GREEN], 255));
1524 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1525 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1526 scale_round (priv->color[COLORSEL_BLUE], 255));
1527 gtk_adjustment_set_value (gtk_range_get_adjustment
1528 (GTK_RANGE (priv->opacity_slider)),
1529 scale_round (priv->color[COLORSEL_OPACITY], 255));
1531 g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
1532 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1534 g_snprintf (entryval, 11, "#%2X%2X%2X",
1535 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1536 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1537 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1539 for (ptr = entryval; *ptr; ptr++)
1542 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1543 priv->changing = FALSE;
1545 g_object_freeze_notify (G_OBJECT (colorsel));
1546 g_object_notify (G_OBJECT (colorsel), "current_color");
1547 g_object_notify (G_OBJECT (colorsel), "current_alpha");
1548 g_object_thaw_notify (G_OBJECT (colorsel));
1553 fill_palette_from_string (const gchar *str)
1555 GdkColor *colors = NULL;
1561 if (!gtk_color_selection_palette_from_string (str, &colors, &n_colors))
1564 if (n_colors > (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
1565 n_colors = GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
1567 memcpy (current_colors, colors, sizeof (GdkColor) * n_colors);
1573 palette_change_notify_class (GObject *object,
1578 g_object_get (object, pspec->name, &str, NULL);
1580 fill_palette_from_string (str);
1586 update_palette (GtkColorSelection *colorsel)
1590 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1592 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1596 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1598 gtk_color_selection_set_palette_color (colorsel,
1600 ¤t_colors[index]);
1606 palette_change_notify_instance (GObject *object,
1610 update_palette (GTK_COLOR_SELECTION (data));
1614 default_change_palette_func (const GdkColor *colors,
1619 str = gtk_color_selection_palette_to_string (colors, n_colors);
1621 gtk_settings_set_string_property (gtk_settings_get_default (),
1622 "gtk-color-palette",
1624 "gtk_color_selection_palette_to_string");
1630 gtk_color_selection_get_type (void)
1632 static GtkType color_selection_type = 0;
1634 if (!color_selection_type)
1636 static const GtkTypeInfo color_selection_info =
1638 "GtkColorSelection",
1639 sizeof (GtkColorSelection),
1640 sizeof (GtkColorSelectionClass),
1641 (GtkClassInitFunc) gtk_color_selection_class_init,
1642 (GtkObjectInitFunc) gtk_color_selection_init,
1643 /* reserved_1 */ NULL,
1644 /* reserved_2 */ NULL,
1645 (GtkClassInitFunc) NULL,
1648 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1651 return color_selection_type;
1655 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1657 GtkObjectClass *object_class;
1658 GObjectClass *gobject_class;
1661 object_class = GTK_OBJECT_CLASS (klass);
1662 gobject_class = G_OBJECT_CLASS (klass);
1664 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1666 object_class->destroy = gtk_color_selection_destroy;
1667 gobject_class->finalize = gtk_color_selection_finalize;
1669 gobject_class->set_property = gtk_color_selection_set_property;
1670 gobject_class->get_property = gtk_color_selection_get_property;
1672 g_object_class_install_property (gobject_class,
1673 PROP_HAS_OPACITY_CONTROL,
1674 g_param_spec_boolean ("has_opacity_control",
1675 _("Has Opacity Control"),
1676 _("Whether the color selector should allow setting opacity"),
1678 G_PARAM_READABLE | G_PARAM_WRITABLE));
1679 g_object_class_install_property (gobject_class,
1681 g_param_spec_boolean ("has_palette",
1683 _("Whether a palette should be used"),
1685 G_PARAM_READABLE | G_PARAM_WRITABLE));
1686 g_object_class_install_property (gobject_class,
1688 g_param_spec_boxed ("current_color",
1690 _("The current color"),
1692 G_PARAM_READABLE | G_PARAM_WRITABLE));
1693 g_object_class_install_property (gobject_class,
1695 g_param_spec_uint ("current_alpha",
1697 _("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1699 G_PARAM_READABLE | G_PARAM_WRITABLE));
1701 color_selection_signals[COLOR_CHANGED] =
1702 gtk_signal_new ("color_changed",
1704 GTK_CLASS_TYPE (object_class),
1705 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1706 gtk_marshal_VOID__VOID,
1709 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1710 _("Custom palette"),
1711 _("Palette to use in the color selector"),
1713 G_PARAM_READWRITE));
1715 g_object_get (G_OBJECT (gtk_settings_get_default ()),
1716 "gtk-color-palette",
1720 fill_palette_from_string (palette);
1723 change_palette_hook = default_change_palette_func;
1725 g_signal_connect_data (G_OBJECT (gtk_settings_get_default ()),
1726 "notify::gtk-color-palette",
1727 G_CALLBACK (palette_change_notify_class),
1731 /* widget functions */
1734 gtk_color_selection_init (GtkColorSelection *colorsel)
1736 GtkWidget *top_hbox;
1737 GtkWidget *top_right_vbox;
1738 GtkWidget *table, *label, *hbox, *frame, *vbox;
1739 GtkAdjustment *adjust;
1740 GdkPixmap *dropper_pixmap;
1741 GtkWidget *dropper_image;
1743 GdkBitmap *mask = NULL;
1745 ColorSelectionPrivate *priv;
1747 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1748 priv->changing = FALSE;
1749 priv->default_set = FALSE;
1750 priv->default_alpha_set = FALSE;
1752 priv->tooltips = gtk_tooltips_new ();
1754 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1755 top_hbox = gtk_hbox_new (FALSE, 8);
1756 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1758 vbox = gtk_vbox_new (FALSE, 4);
1759 priv->triangle_colorsel = gtk_hsv_new ();
1760 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed",
1761 GTK_SIGNAL_FUNC (hsv_changed), colorsel);
1762 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1763 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1764 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1765 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1766 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1768 hbox = gtk_hbox_new (FALSE, 4);
1769 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1771 frame = gtk_frame_new (NULL);
1772 gtk_widget_set_usize (frame, -1, 30);
1773 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1774 color_sample_new (colorsel);
1775 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1776 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1778 button = gtk_button_new ();
1780 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1781 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1782 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1783 GTK_SIGNAL_FUNC (get_screen_color), NULL);
1784 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1785 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1786 gdk_pixmap_unref (dropper_pixmap);
1788 gdk_pixmap_unref (mask);
1789 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1790 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1792 gtk_tooltips_set_tip (priv->tooltips,
1794 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1796 top_right_vbox = gtk_vbox_new (FALSE, 4);
1797 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1798 table = gtk_table_new (8, 6, FALSE);
1799 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1800 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1801 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1803 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1804 _("Position on the color wheel."));
1805 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1806 _("\"Deepness\" of the color."));
1807 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1808 _("Brightness of the color."));
1809 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1810 _("Amount of red light in the color."));
1811 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1812 _("Amount of green light in the color."));
1813 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1814 _("Amount of blue light in the color."));
1815 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1817 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1818 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1819 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1820 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1821 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1822 priv->opacity_slider = gtk_hscale_new (adjust);
1823 gtk_tooltips_set_tip (priv->tooltips,
1824 priv->opacity_slider,
1825 _("Transparency of the currently-selected color."), NULL);
1826 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1827 priv->opacity_slider);
1828 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1829 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1830 GTK_SIGNAL_FUNC (adjustment_changed),
1831 GINT_TO_POINTER (COLORSEL_OPACITY));
1832 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1833 priv->opacity_entry = gtk_entry_new ();
1834 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1836 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate",
1837 GTK_SIGNAL_FUNC (opacity_entry_changed), colorsel);
1838 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1840 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1841 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1842 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1843 priv->hex_entry = gtk_entry_new ();
1845 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1847 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate",
1848 GTK_SIGNAL_FUNC (hex_changed), colorsel);
1850 gtk_tooltips_set_tip (priv->tooltips,
1852 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1854 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1855 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1856 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1858 /* Set up the palette */
1859 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1860 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1861 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1862 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1864 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1866 make_palette_frame (colorsel, table, i, j);
1869 set_selected_palette (colorsel, 0, 0);
1870 priv->palette_frame = gtk_frame_new (NULL);
1871 label = gtk_label_new_with_mnemonic (_("_Palette"));
1872 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1874 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1875 priv->custom_palette[0][0]);
1877 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1878 vbox = gtk_vbox_new (FALSE, 4);
1879 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1880 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1882 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1884 gtk_widget_show_all (top_hbox);
1886 /* Set default colors */
1888 update_palette (colorsel);
1890 priv->settings_connection =
1891 g_signal_connect_data (G_OBJECT (gtk_settings_get_default ()),
1892 "notify::gtk-color-palette",
1893 G_CALLBACK (palette_change_notify_instance),
1896 /* hide unused stuff */
1898 if (priv->has_opacity == FALSE)
1900 gtk_widget_hide (priv->opacity_label);
1901 gtk_widget_hide (priv->opacity_slider);
1902 gtk_widget_hide (priv->opacity_entry);
1905 if (priv->has_palette == FALSE)
1907 gtk_widget_hide (priv->palette_frame);
1912 gtk_color_selection_destroy (GtkObject *object)
1914 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1915 ColorSelectionPrivate *priv = cselection->private_data;
1917 if (priv->dropper_grab_widget)
1919 gtk_widget_destroy (priv->dropper_grab_widget);
1920 priv->dropper_grab_widget = NULL;
1925 gtk_object_destroy (GTK_OBJECT (priv->tooltips));
1926 priv->tooltips = NULL;
1929 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1933 gtk_color_selection_finalize (GObject *object)
1935 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1937 if (cselection->private_data)
1939 ColorSelectionPrivate *priv;
1941 priv = cselection->private_data;
1943 g_signal_handler_disconnect (gtk_settings_get_default (),
1944 priv->settings_connection);
1946 g_free (cselection->private_data);
1947 cselection->private_data = NULL;
1950 G_OBJECT_CLASS (parent_class)->finalize (object);
1955 * gtk_color_selection_new:
1957 * Creates a new GtkColorSelection.
1959 * Return value: a new #GtkColorSelection
1962 gtk_color_selection_new (void)
1964 GtkColorSelection *colorsel;
1965 ColorSelectionPrivate *priv;
1972 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
1973 priv = colorsel->private_data;
1974 gtk_color_selection_set_color (colorsel, color);
1975 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
1977 /* We want to make sure that default_set is FALSE */
1978 /* This way the user can still set it */
1979 priv->default_set = FALSE;
1980 priv->default_alpha_set = FALSE;
1982 return GTK_WIDGET (colorsel);
1987 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
1988 GtkUpdateType policy)
1990 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
1992 g_warning (G_STRLOC ": This function is deprecated.");
1996 * gtk_color_selection_get_has_opacity_control:
1997 * @colorsel: A GtkColorSelection.
1999 * Determines whether the colorsel has an opacity control.
2001 * Return value: TRUE if the @colorsel has an opacity control. FALSE if it does't.
2004 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2006 ColorSelectionPrivate *priv;
2008 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2010 priv = colorsel->private_data;
2012 return priv->has_opacity;
2016 * gtk_color_selection_set_has_opacity_control:
2017 * @colorsel: A GtkColorSelection.
2018 * @has_opacity: TRUE if @colorsel can set the opacity, FALSE otherwise.
2020 * Sets the @colorsel to use or not use opacity.
2024 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2025 gboolean has_opacity)
2027 ColorSelectionPrivate *priv;
2029 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2031 priv = colorsel->private_data;
2032 has_opacity = has_opacity != FALSE;
2034 if (priv->has_opacity != has_opacity)
2036 priv->has_opacity = has_opacity;
2039 gtk_widget_show (priv->opacity_slider);
2040 gtk_widget_show (priv->opacity_label);
2041 gtk_widget_show (priv->opacity_entry);
2045 gtk_widget_hide (priv->opacity_slider);
2046 gtk_widget_hide (priv->opacity_label);
2047 gtk_widget_hide (priv->opacity_entry);
2049 color_sample_draw_samples (colorsel);
2051 g_object_notify (G_OBJECT (colorsel), "has_opacity_control");
2056 * gtk_color_selection_get_has_palette:
2057 * @colorsel: A GtkColorSelection.
2059 * Determines whether the color selector has a color palette.
2061 * Return value: TRUE if the selector has a palette. FALSE if it hasn't.
2064 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2066 ColorSelectionPrivate *priv;
2068 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2070 priv = colorsel->private_data;
2072 return priv->has_palette;
2076 * gtk_color_selection_set_has_palette:
2077 * @colorsel: A GtkColorSelection.
2078 * @has_palette: TRUE if palette is to be visible, FALSE otherwise.
2080 * Shows and hides the palette based upon the value of @has_palette.
2084 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2085 gboolean has_palette)
2087 ColorSelectionPrivate *priv;
2088 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2090 priv = colorsel->private_data;
2091 has_palette = has_palette != FALSE;
2093 if (priv->has_palette != has_palette)
2095 priv->has_palette = has_palette;
2097 gtk_widget_show (priv->palette_frame);
2099 gtk_widget_hide (priv->palette_frame);
2101 g_object_notify (G_OBJECT (colorsel), "has_palette");
2106 * gtk_color_selection_set_current_color:
2107 * @colorsel: A GtkColorSelection.
2108 * @color: A GdkColor to set the current color with.
2110 * Sets the current color to be @color. The first time this is called, it will
2111 * also set the original color to be @color too.
2115 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2118 ColorSelectionPrivate *priv;
2120 gboolean previous_changed;
2122 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2124 priv = colorsel->private_data;
2125 priv->changing = TRUE;
2126 priv->color[COLORSEL_RED] = SCALE (color->red);
2127 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2128 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2129 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2130 priv->color[COLORSEL_GREEN],
2131 priv->color[COLORSEL_BLUE],
2132 &priv->color[COLORSEL_HUE],
2133 &priv->color[COLORSEL_SATURATION],
2134 &priv->color[COLORSEL_VALUE]);
2135 if (priv->default_set == FALSE)
2137 previous_changed = TRUE;
2138 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2139 priv->old_color[i] = priv->color[i];
2141 update_color (colorsel);
2142 priv->default_set = TRUE;
2146 * gtk_color_selection_set_current_alpha:
2147 * @colorsel: A GtkColorSelection.
2148 * @alpha: an integer between 0 and 65535
2150 * Sets the current opacity to be @alpha. The first time this is called, it will
2151 * also set the original opacity to be @alpha too.
2155 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2158 ColorSelectionPrivate *priv;
2161 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2163 priv = colorsel->private_data;
2164 priv->changing = TRUE;
2165 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2166 if (priv->default_alpha_set == FALSE)
2168 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2169 priv->old_color[i] = priv->color[i];
2171 update_color (colorsel);
2172 priv->default_alpha_set = TRUE;
2176 * gtk_color_selection_set_color:
2177 * @colorsel: A GtkColorSelection.
2178 * @color: A array of doubles that specifies the color to set the current color with.
2180 * Sets the current color to be @color. The first time this is called, it will
2181 * also set the original color to be @color too.
2183 * This function is deprecated, use gtk_color_selection_set_current_color() instead.
2187 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2190 ColorSelectionPrivate *priv;
2193 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2195 priv = colorsel->private_data;
2196 priv->changing = TRUE;
2197 priv->color[COLORSEL_RED] = color[0];
2198 priv->color[COLORSEL_GREEN] = color[1];
2199 priv->color[COLORSEL_BLUE] = color[2];
2200 priv->color[COLORSEL_OPACITY] = color[3];
2201 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2202 priv->color[COLORSEL_GREEN],
2203 priv->color[COLORSEL_BLUE],
2204 &priv->color[COLORSEL_HUE],
2205 &priv->color[COLORSEL_SATURATION],
2206 &priv->color[COLORSEL_VALUE]);
2207 if (priv->default_set == FALSE)
2209 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2210 priv->old_color[i] = priv->color[i];
2212 update_color (colorsel);
2213 priv->default_set = TRUE;
2214 priv->default_alpha_set = TRUE;
2218 * gtk_color_selection_get_current_color:
2219 * @colorsel: A GtkColorSelection.
2220 * @color: A GdkColor to fill in with the current color.
2222 * Sets @color to be the current color in the GtkColorSelection widget.
2224 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2227 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2230 ColorSelectionPrivate *priv;
2232 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2234 priv = colorsel->private_data;
2235 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2236 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2237 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2241 * gtk_color_selection_get_current_alpha:
2242 * @colorsel: A GtkColorSelection.
2244 * Returns the current alpha value
2246 * Return value: an integer between 0 and 65535
2249 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2251 ColorSelectionPrivate *priv;
2253 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2255 priv = colorsel->private_data;
2256 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2260 * gtk_color_selection_get_color:
2261 * @colorsel: A GtkColorSelection.
2262 * @color: A color to fill in with the current color.
2264 * Sets @color to be the current color in the GtkColorSelection widget.
2268 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2271 ColorSelectionPrivate *priv;
2273 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2275 priv = colorsel->private_data;
2276 color[0] = priv->color[COLORSEL_RED];
2277 color[1] = priv->color[COLORSEL_GREEN];
2278 color[2] = priv->color[COLORSEL_BLUE];
2279 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2283 * gtk_color_selection_set_previous_color:
2284 * @colorsel: A GtkColorSelection.
2285 * @color: A color to set the previous color with.
2287 * Sets the 'previous' color to be @color. This function should be called with
2288 * some hesitations, as it might seem confusing to have that color change.
2289 * Calling gtk_color_selection_set_current_color will also set this color the first
2290 * time it is called.
2294 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2297 ColorSelectionPrivate *priv;
2299 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2301 priv = colorsel->private_data;
2302 priv->changing = TRUE;
2303 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2304 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2305 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2306 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2307 priv->old_color[COLORSEL_GREEN],
2308 priv->old_color[COLORSEL_BLUE],
2309 &priv->old_color[COLORSEL_HUE],
2310 &priv->old_color[COLORSEL_SATURATION],
2311 &priv->old_color[COLORSEL_VALUE]);
2312 color_sample_draw_samples (colorsel);
2313 priv->default_set = TRUE;
2317 * gtk_color_selection_set_previous_alpha:
2318 * @colorsel: A GtkColorSelection.
2319 * @alpha: an integer between 0 and 65535
2321 * Sets the 'previous' alpha to be @alpha. This function should be called with
2322 * some hesitations, as it might seem confusing to have that color change.
2326 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2329 ColorSelectionPrivate *priv;
2331 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2333 priv = colorsel->private_data;
2334 priv->changing = TRUE;
2335 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2336 color_sample_draw_samples (colorsel);
2337 priv->default_alpha_set = TRUE;
2342 * gtk_color_selection_get_previous_color:
2343 * @colorsel: A GtkColorSelection.
2344 * @color: A GdkColor to fill in with the original color value.
2346 * Fills @color in with the original color value.
2350 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2353 ColorSelectionPrivate *priv;
2355 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2357 priv = colorsel->private_data;
2358 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2359 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2360 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2364 * gtk_color_selection_get_previous_alpha:
2365 * @colorsel: A GtkColorSelection.
2367 * Returns the previous alpha value
2369 * Return value: an integer between 0 and 65535
2372 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2374 ColorSelectionPrivate *priv;
2376 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2378 priv = colorsel->private_data;
2379 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2383 * gtk_color_selection_set_palette_color:
2384 * @colorsel: A GtkColorSelection.
2385 * @index: The color index of the palette.
2386 * @color: A GdkColor to set the palette with.
2388 * Set the palette located at at @index to have @color set as its color.
2392 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2396 ColorSelectionPrivate *priv;
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 col[0] = SCALE (color->red);
2408 col[1] = SCALE (color->green);
2409 col[2] = SCALE (color->blue);
2411 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2415 * gtk_color_selection_get_palette_color:
2416 * @colorsel: A GtkColorSelection.
2417 * @index: The color index of the palette.
2418 * @color: A color to fill in with the color value.
2420 * Set @color to have the color found in the palette at @index. If
2421 * the palette is unset, it will leave the color unset.
2423 * Return value: TRUE if the palette located at @index has a color set. FALSE
2427 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
2431 ColorSelectionPrivate *priv;
2435 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2436 g_return_val_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
2438 priv = colorsel->private_data;
2440 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2441 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2443 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
2446 palette_get_color (priv->custom_palette[x][y], col);
2448 color->red = UNSCALE (col[0]);
2449 color->green = UNSCALE (col[1]);
2450 color->blue = UNSCALE (col[2]);
2456 * gtk_color_selection_unset_palette_color:
2457 * @colorsel: A GtkColorSelection.
2458 * @index: The color index in the palette.
2460 * Change the palette located @index to have no color set.
2464 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
2467 ColorSelectionPrivate *priv;
2470 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2471 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2473 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2474 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2476 priv = colorsel->private_data;
2477 palette_unset_color (priv->custom_palette[x][y]);
2481 * gtk_color_selection_get_current_alpha:
2482 * @colorsel: A GtkColorSelection.
2484 * Returns the maximum number of palette colors.
2486 * Return value: the maximum number of palette indexes
2489 gtk_color_selection_get_palette_size (GtkColorSelection *colorsel)
2491 return GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
2496 * gtk_color_selection_is_adjusting:
2497 * @colorsel: A GtkColorSelection.
2499 * Gets the current state of the @colorsel.
2501 * Return value: TRUE if the user is currently dragging a color around, and FALSE
2502 * if the selection has stopped.
2505 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2507 ColorSelectionPrivate *priv;
2509 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2511 priv = colorsel->private_data;
2513 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2517 gtk_color_selection_set_property (GObject *object,
2519 const GValue *value,
2522 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2526 case PROP_HAS_OPACITY_CONTROL:
2527 gtk_color_selection_set_has_opacity_control (colorsel,
2528 g_value_get_boolean (value));
2530 case PROP_HAS_PALETTE:
2531 gtk_color_selection_set_has_palette (colorsel,
2532 g_value_get_boolean (value));
2534 case PROP_CURRENT_COLOR:
2535 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2537 case PROP_CURRENT_ALPHA:
2538 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2541 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2548 gtk_color_selection_get_property (GObject *object,
2553 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2558 case PROP_HAS_OPACITY_CONTROL:
2559 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2561 case PROP_HAS_PALETTE:
2562 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2564 case PROP_CURRENT_COLOR:
2565 gtk_color_selection_get_current_color (colorsel, &color);
2566 g_value_set_boxed (value, &color);
2568 case PROP_CURRENT_ALPHA:
2569 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2572 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2579 * gtk_color_selection_palette_from_string:
2580 * @str: a string encoding a color palette
2581 * @colors: return location for allocated array of GdkColor
2582 * @n_colors: return location for length of array
2584 * Parses a color palette string; the string is a colon-separated
2585 * list of color names readable by gdk_color_parse().
2587 * Return value: %TRUE if a palette was successfully parsed
2590 gtk_color_selection_palette_from_string (const gchar *str,
2602 copy = g_strdup (str);
2608 if (*p == ':' || *p == '\0')
2610 gboolean done = TRUE;
2614 goto failed; /* empty entry */
2623 retval = g_renew (GdkColor, retval, count + 1);
2624 if (!gdk_color_parse (start, retval + count))
2665 * gtk_color_selection_palette_to_string:
2666 * @colors: an array of colors
2667 * @n_colors: length of the array
2669 * Encodes a palette as a string, useful for persistent storage.
2671 * Return value: allocated string encoding the palette
2674 gtk_color_selection_palette_to_string (const GdkColor *colors,
2678 gchar **strs = NULL;
2682 return g_strdup ("");
2684 strs = g_new0 (gchar*, n_colors + 1);
2687 while (i < n_colors)
2692 g_strdup_printf ("#%2X%2X%2X",
2693 colors[i].red / 256,
2694 colors[i].green / 256,
2695 colors[i].blue / 256);
2697 for (ptr = strs[i]; *ptr; ptr++)
2704 retval = g_strjoinv (":", strs);
2712 * gtk_color_selection_set_change_palette_hook:
2713 * @func: a function to call when the custom palette needs saving
2715 * Installs a global function to be called whenever the user tries to
2716 * modify the palette in a color selection. This function should save
2717 * the new palette contents, and update the GtkSettings property
2718 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2720 * Return value: the previous change palette hook (that was replaced)
2722 GtkColorSelectionChangePaletteFunc
2723 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2725 GtkColorSelectionChangePaletteFunc old;
2727 old = change_palette_hook;
2729 change_palette_hook = func;