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 #include "gdk/gdkkeysyms.h"
32 #include "gtkcolorsel.h"
34 #include "gtkwindow.h"
35 #include "gtkselection.h"
37 #include "gtkdrawingarea.h"
38 #include "gtksignal.h"
45 #include "gtkmarshalers.h"
46 #include "gtkpixmap.h"
47 #include "gtkspinbutton.h"
49 #include "gtkhscale.h"
51 #include "gtkbutton.h"
52 #include "gtkhseparator.h"
53 #include "gtktooltips.h"
54 #include "gtkinvisible.h"
55 #include "gtkmenuitem.h"
57 #include "gtksettings.h"
62 /* Number of elements in the custom palatte */
63 #define GTK_CUSTOM_PALETTE_WIDTH 10
64 #define GTK_CUSTOM_PALETTE_HEIGHT 2
66 /* Conversion between 0->1 double and and guint16. See
67 * scale_round() below for more general conversions
69 #define SCALE(i) (i / 65535.)
70 #define UNSCALE(d) ((guint16)(d * 65535 + 0.5))
81 PROP_HAS_OPACITY_CONTROL,
97 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
99 struct _ColorSelectionPrivate
101 guint has_opacity : 1;
102 guint has_palette : 1;
104 guint default_set : 1;
105 guint default_alpha_set : 1;
107 gdouble color[COLORSEL_NUM_CHANNELS];
108 gdouble old_color[COLORSEL_NUM_CHANNELS];
110 GtkWidget *triangle_colorsel;
111 GtkWidget *hue_spinbutton;
112 GtkWidget *sat_spinbutton;
113 GtkWidget *val_spinbutton;
114 GtkWidget *red_spinbutton;
115 GtkWidget *green_spinbutton;
116 GtkWidget *blue_spinbutton;
117 GtkWidget *opacity_slider;
118 GtkWidget *opacity_label;
119 GtkWidget *opacity_entry;
120 GtkWidget *palette_frame;
121 GtkWidget *hex_entry;
123 /* The Palette code */
124 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
126 /* The color_sample stuff */
127 GtkWidget *sample_area;
128 GtkWidget *old_sample;
129 GtkWidget *cur_sample;
133 GtkTooltips *tooltips;
135 /* Window for grabbing on */
136 GtkWidget *dropper_grab_widget;
138 /* Connection to settings */
139 guint settings_connection;
143 static void gtk_color_selection_init (GtkColorSelection *colorsel);
144 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
145 static void gtk_color_selection_destroy (GtkObject *object);
146 static void gtk_color_selection_finalize (GObject *object);
147 static void gtk_color_selection_realize (GtkWidget *widget);
148 static void update_color (GtkColorSelection *colorsel);
149 static void gtk_color_selection_set_property (GObject *object,
153 static void gtk_color_selection_get_property (GObject *object,
158 static gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel);
159 static gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
162 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
165 static void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
167 static void default_change_palette_func (const GdkColor *colors,
170 static gpointer parent_class = NULL;
171 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
173 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";
175 static GtkColorSelectionChangePaletteFunc change_palette_hook = default_change_palette_func;
177 static GdkColor current_colors[GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT];
179 /* The cursor for the dropper */
180 #define DROPPER_WIDTH 17
181 #define DROPPER_HEIGHT 17
182 #define DROPPER_X_HOT 2
183 #define DROPPER_Y_HOT 16
186 static char dropper_bits[] = {
187 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
188 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
189 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
190 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
193 static char dropper_mask[] = {
194 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
195 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
196 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
197 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
200 static GdkCursor *picker_cursor = NULL;
204 static char *picker[] = {
205 /* columns rows colors chars-per-pixel */
216 "#########################",
217 "#########################",
218 "#########################",
219 "#########################",
220 "#########################",
221 "################# #####",
222 "################ ####",
223 "################ +###",
224 "############# +###",
225 "############## ++###",
226 "#############+@ +++####",
227 "############+@@@ +######",
228 "###########+@@@ + +######",
229 "##########+@@@ ++#+######",
230 "#########+@@@ ++#########",
231 "########+@@@ ++##########",
232 "#######+@@@ ++###########",
233 "######+@@@ ++############",
234 "######+@@ ++#############",
235 "#####+@ ++##############",
236 "###### +++###############",
237 "#########################",
238 "#########################",
239 "#########################",
240 "#########################"
249 #define SAMPLE_WIDTH 64
250 #define SAMPLE_HEIGHT 28
252 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
253 static void color_sample_draw_samples (GtkColorSelection *colorsel);
256 color_sample_drag_begin (GtkWidget *widget,
257 GdkDragContext *context,
260 GtkColorSelection *colorsel = data;
261 ColorSelectionPrivate *priv;
268 priv = colorsel->private_data;
269 window = gtk_window_new (GTK_WINDOW_POPUP);
270 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
271 gtk_widget_set_usize (window, 48, 32);
272 gtk_widget_realize (window);
273 gtk_object_set_data_full (GTK_OBJECT (widget),
274 "gtk-color-selection-drag-window",
276 (GtkDestroyNotify) gtk_widget_destroy);
278 if (widget == priv->old_sample)
279 colsrc = priv->old_color;
281 colsrc = priv->color;
283 for (i=0, n = COLORSEL_RED; n <= COLORSEL_BLUE; n++)
285 colors[i++] = colsrc[n];
288 if (priv->has_opacity)
290 colors[i] = colsrc[COLORSEL_OPACITY];
293 bg.red = 0xffff * colors[0];
294 bg.green = 0xffff * colors[1];
295 bg.blue = 0xffff * colors[2];
297 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
298 gdk_window_set_background (window->window, &bg);
300 gtk_drag_set_icon_widget (context, window, -2, -2);
304 color_sample_drag_end (GtkWidget *widget,
305 GdkDragContext *context,
308 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
312 color_sample_drop_handle (GtkWidget *widget,
313 GdkDragContext *context,
316 GtkSelectionData *selection_data,
321 GtkColorSelection *colorsel = data;
322 ColorSelectionPrivate *priv;
325 priv = colorsel->private_data;
327 /* This is currently a guint16 array of the format:
334 if (selection_data->length < 0)
337 if ((selection_data->format != 16) ||
338 (selection_data->length != 8))
340 g_warning ("Received invalid color data\n");
344 vals = (guint16 *)selection_data->data;
346 if (widget == priv->cur_sample)
348 color[0] = (gdouble)vals[0] / 0xffff;
349 color[1] = (gdouble)vals[1] / 0xffff;
350 color[2] = (gdouble)vals[2] / 0xffff;
351 color[3] = (gdouble)vals[3] / 0xffff;
353 gtk_color_selection_set_color (colorsel, color);
358 color_sample_drag_handle (GtkWidget *widget,
359 GdkDragContext *context,
360 GtkSelectionData *selection_data,
365 GtkColorSelection *colorsel = data;
366 ColorSelectionPrivate *priv;
370 priv = colorsel->private_data;
372 if (widget == priv->old_sample)
373 colsrc = priv->old_color;
375 colsrc = priv->color;
377 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
378 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
379 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
380 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
382 gtk_selection_data_set (selection_data,
383 gdk_atom_intern ("application/x-color", FALSE),
384 16, (guchar *)vals, 8);
387 /* which = 0 means draw old sample, which = 1 means draw new */
389 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
392 gint x, y, i, wid, heig, f, n, goff;
393 guchar c[3 * 2], cc[3 * 4], *cp = c;
396 ColorSelectionPrivate *priv;
398 g_return_if_fail (colorsel != NULL);
399 priv = colorsel->private_data;
401 g_return_if_fail (priv->sample_area != NULL);
402 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
407 da = priv->old_sample;
408 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
409 c[n] = (guchar) (UNSCALE (priv->old_color[i]) >> 8);
414 da = priv->cur_sample;
415 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
416 c[n] = (guchar) (UNSCALE (priv->color[i]) >> 8);
417 goff = priv->old_sample->allocation.width % 32;
420 wid = da->allocation.width;
421 heig = da->allocation.height;
423 buf = g_new (guchar, 3 * wid * heig);
427 for (n = 0; n < 3; n++)
429 c[n] = (guchar) (255.0 * priv->old_color[i]);
430 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
434 if (priv->has_opacity)
436 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
438 for (n = 0; n < 3; n++)
440 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
441 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
447 for (y = 0; y < heig; y++)
449 for (x = 0; x < wid; x++)
451 if (priv->has_opacity)
452 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
456 for (n = 0; n < 3; n++)
457 buf[i++] = cp[n + f];
461 gdk_draw_rgb_image (da->window,
465 GDK_RGB_DITHER_NORMAL,
475 color_sample_draw_samples (GtkColorSelection *colorsel)
477 color_sample_draw_sample (colorsel, 0);
478 color_sample_draw_sample (colorsel, 1);
482 color_old_sample_expose (GtkWidget *da,
483 GdkEventExpose *event,
484 GtkColorSelection *colorsel)
486 color_sample_draw_sample (colorsel, 0);
492 color_cur_sample_expose (GtkWidget *da,
493 GdkEventExpose *event,
494 GtkColorSelection *colorsel)
496 color_sample_draw_sample (colorsel, 1);
501 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
503 static const GtkTargetEntry targets[] = {
504 { "application/x-color", 0 }
506 ColorSelectionPrivate *priv;
507 priv = colorsel->private_data;
509 gtk_drag_source_set (sample,
510 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
512 GDK_ACTION_COPY | GDK_ACTION_MOVE);
514 gtk_signal_connect (GTK_OBJECT (sample),
516 GTK_SIGNAL_FUNC (color_sample_drag_begin),
518 if (sample == priv->cur_sample)
521 gtk_drag_dest_set (sample,
522 GTK_DEST_DEFAULT_HIGHLIGHT |
523 GTK_DEST_DEFAULT_MOTION |
524 GTK_DEST_DEFAULT_DROP,
528 gtk_signal_connect (GTK_OBJECT (sample),
530 GTK_SIGNAL_FUNC (color_sample_drag_end),
534 gtk_signal_connect (GTK_OBJECT (sample),
536 GTK_SIGNAL_FUNC (color_sample_drag_handle),
538 gtk_signal_connect (GTK_OBJECT (sample),
539 "drag_data_received",
540 GTK_SIGNAL_FUNC (color_sample_drop_handle),
547 color_sample_new (GtkColorSelection *colorsel)
549 ColorSelectionPrivate *priv;
551 priv = colorsel->private_data;
553 priv->sample_area = gtk_hbox_new (FALSE, 0);
554 priv->old_sample = gtk_drawing_area_new ();
555 priv->cur_sample = gtk_drawing_area_new ();
557 /* We need enter/leave to do tooltips */
558 gtk_widget_add_events (priv->old_sample,
559 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
560 gtk_widget_add_events (priv->cur_sample,
561 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
563 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
565 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
568 gtk_signal_connect (GTK_OBJECT (priv->old_sample), "expose_event",
569 GTK_SIGNAL_FUNC (color_old_sample_expose),
571 gtk_signal_connect (GTK_OBJECT (priv->cur_sample), "expose_event",
572 GTK_SIGNAL_FUNC (color_cur_sample_expose),
575 color_sample_setup_dnd (colorsel, priv->old_sample);
576 color_sample_setup_dnd (colorsel, priv->cur_sample);
578 gtk_tooltips_set_tip (priv->tooltips,
580 _("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);
583 gtk_tooltips_set_tip (priv->tooltips,
585 _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL);
587 gtk_widget_show_all (priv->sample_area);
593 * The palette area code
596 #define CUSTOM_PALETTE_ENTRY_WIDTH 20
597 #define CUSTOM_PALETTE_ENTRY_HEIGHT 20
600 palette_get_color (GtkWidget *drawing_area, gdouble *color)
604 g_return_if_fail (color != NULL);
606 color_val = gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
607 if (color_val == NULL)
609 /* Default to white for no good reason */
617 color[0] = color_val[0];
618 color[1] = color_val[1];
619 color[2] = color_val[2];
623 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
625 palette_paint (GtkWidget *drawing_area,
629 if (drawing_area->window == NULL)
632 gdk_window_clear_area (drawing_area->window,
638 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
643 palette_get_color (drawing_area, color);
645 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
646 gc = drawing_area->style->black_gc;
648 gc = drawing_area->style->white_gc;
650 gdk_draw_rectangle (drawing_area->window,
652 drawing_area->allocation.width - 1,
653 drawing_area->allocation.height - 1);
659 palette_drag_begin (GtkWidget *widget,
660 GdkDragContext *context,
663 GtkColorSelection *colorsel = data;
664 ColorSelectionPrivate *priv;
669 priv = colorsel->private_data;
670 window = gtk_window_new (GTK_WINDOW_POPUP);
671 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
672 gtk_widget_set_usize (window, 48, 32);
673 gtk_widget_realize (window);
674 gtk_object_set_data_full (GTK_OBJECT (widget),
675 "gtk-color-selection-drag-window",
677 (GtkDestroyNotify) gtk_widget_destroy);
679 palette_get_color (widget, colors);
680 bg.red = 0xffff * colors[0];
681 bg.green = 0xffff * colors[1];
682 bg.blue = 0xffff * colors[2];
684 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
685 gdk_window_set_background (window->window, &bg);
687 gtk_drag_set_icon_widget (context, window, -2, -2);
691 palette_drag_handle (GtkWidget *widget,
692 GdkDragContext *context,
693 GtkSelectionData *selection_data,
701 palette_get_color (widget, colsrc);
703 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
704 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
705 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
708 gtk_selection_data_set (selection_data,
709 gdk_atom_intern ("application/x-color", FALSE),
710 16, (guchar *)vals, 8);
714 palette_drag_end (GtkWidget *widget,
715 GdkDragContext *context,
718 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
721 /* Changes the model color */
723 palette_change_color (GtkWidget *drawing_area,
724 GtkColorSelection *colorsel,
728 ColorSelectionPrivate *priv;
731 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
732 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
734 priv = colorsel->private_data;
736 gdk_color.red = UNSCALE (color[0]);
737 gdk_color.green = UNSCALE (color[1]);
738 gdk_color.blue = UNSCALE (color[2]);
741 while (x < GTK_CUSTOM_PALETTE_WIDTH)
744 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
746 if (priv->custom_palette[x][y] == drawing_area)
757 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
759 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
761 if (change_palette_hook)
762 (* change_palette_hook) (current_colors, GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
765 /* Changes the view color */
767 palette_set_color (GtkWidget *drawing_area,
768 GtkColorSelection *colorsel,
771 gdouble *new_color = g_new (double, 4);
775 gdk_color.red = UNSCALE (color[0]);
776 gdk_color.green = UNSCALE (color[1]);
777 gdk_color.blue = UNSCALE (color[2]);
779 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
781 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
783 static const GtkTargetEntry targets[] = {
784 { "application/x-color", 0 }
786 gtk_drag_source_set (drawing_area,
787 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
789 GDK_ACTION_COPY | GDK_ACTION_MOVE);
791 gtk_signal_connect (GTK_OBJECT (drawing_area),
793 GTK_SIGNAL_FUNC (palette_drag_begin),
795 gtk_signal_connect (GTK_OBJECT (drawing_area),
797 GTK_SIGNAL_FUNC (palette_drag_handle),
800 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
804 old_color = (gdouble *) gtk_object_get_data (GTK_OBJECT (drawing_area), "color_val");
810 new_color[0] = color[0];
811 new_color[1] = color[1];
812 new_color[2] = color[2];
815 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_val", new_color);
819 palette_expose (GtkWidget *drawing_area,
820 GdkEventExpose *event,
823 if (drawing_area->window == NULL)
826 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;
1659 GtkWidgetClass *widget_class;
1661 object_class = GTK_OBJECT_CLASS (klass);
1662 gobject_class = G_OBJECT_CLASS (klass);
1663 widget_class = GTK_WIDGET_CLASS (klass);
1665 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1667 object_class->destroy = gtk_color_selection_destroy;
1668 gobject_class->finalize = gtk_color_selection_finalize;
1670 gobject_class->set_property = gtk_color_selection_set_property;
1671 gobject_class->get_property = gtk_color_selection_get_property;
1673 widget_class->realize = gtk_color_selection_realize;
1675 g_object_class_install_property (gobject_class,
1676 PROP_HAS_OPACITY_CONTROL,
1677 g_param_spec_boolean ("has_opacity_control",
1678 _("Has Opacity Control"),
1679 _("Whether the color selector should allow setting opacity"),
1681 G_PARAM_READABLE | G_PARAM_WRITABLE));
1682 g_object_class_install_property (gobject_class,
1684 g_param_spec_boolean ("has_palette",
1686 _("Whether a palette should be used"),
1688 G_PARAM_READABLE | G_PARAM_WRITABLE));
1689 g_object_class_install_property (gobject_class,
1691 g_param_spec_boxed ("current_color",
1693 _("The current color"),
1695 G_PARAM_READABLE | G_PARAM_WRITABLE));
1696 g_object_class_install_property (gobject_class,
1698 g_param_spec_uint ("current_alpha",
1700 _("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1702 G_PARAM_READABLE | G_PARAM_WRITABLE));
1704 color_selection_signals[COLOR_CHANGED] =
1705 gtk_signal_new ("color_changed",
1707 GTK_CLASS_TYPE (object_class),
1708 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1709 _gtk_marshal_VOID__VOID,
1712 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1713 _("Custom palette"),
1714 _("Palette to use in the color selector"),
1716 G_PARAM_READWRITE));
1719 /* widget functions */
1722 gtk_color_selection_init (GtkColorSelection *colorsel)
1724 GtkWidget *top_hbox;
1725 GtkWidget *top_right_vbox;
1726 GtkWidget *table, *label, *hbox, *frame, *vbox;
1727 GtkAdjustment *adjust;
1728 GdkPixmap *dropper_pixmap;
1729 GtkWidget *dropper_image;
1731 GdkBitmap *mask = NULL;
1733 ColorSelectionPrivate *priv;
1735 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1736 priv->changing = FALSE;
1737 priv->default_set = FALSE;
1738 priv->default_alpha_set = FALSE;
1740 priv->tooltips = gtk_tooltips_new ();
1742 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1743 top_hbox = gtk_hbox_new (FALSE, 8);
1744 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1746 vbox = gtk_vbox_new (FALSE, 4);
1747 priv->triangle_colorsel = gtk_hsv_new ();
1748 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed",
1749 GTK_SIGNAL_FUNC (hsv_changed), colorsel);
1750 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1751 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1752 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1753 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1754 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1756 hbox = gtk_hbox_new (FALSE, 4);
1757 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1759 frame = gtk_frame_new (NULL);
1760 gtk_widget_set_usize (frame, -1, 30);
1761 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1762 color_sample_new (colorsel);
1763 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1764 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1766 button = gtk_button_new ();
1768 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1769 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1770 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1771 GTK_SIGNAL_FUNC (get_screen_color), NULL);
1772 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1773 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1774 gdk_pixmap_unref (dropper_pixmap);
1776 gdk_pixmap_unref (mask);
1777 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1778 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1780 gtk_tooltips_set_tip (priv->tooltips,
1782 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1784 top_right_vbox = gtk_vbox_new (FALSE, 4);
1785 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1786 table = gtk_table_new (8, 6, FALSE);
1787 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1788 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1789 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1791 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1792 _("Position on the color wheel."));
1793 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1794 _("\"Deepness\" of the color."));
1795 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1796 _("Brightness of the color."));
1797 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1798 _("Amount of red light in the color."));
1799 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1800 _("Amount of green light in the color."));
1801 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1802 _("Amount of blue light in the color."));
1803 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1805 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1806 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1807 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1808 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1809 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1810 priv->opacity_slider = gtk_hscale_new (adjust);
1811 gtk_tooltips_set_tip (priv->tooltips,
1812 priv->opacity_slider,
1813 _("Transparency of the currently-selected color."), NULL);
1814 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1815 priv->opacity_slider);
1816 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1817 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1818 GTK_SIGNAL_FUNC (adjustment_changed),
1819 GINT_TO_POINTER (COLORSEL_OPACITY));
1820 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1821 priv->opacity_entry = gtk_entry_new ();
1822 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1824 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate",
1825 GTK_SIGNAL_FUNC (opacity_entry_changed), colorsel);
1826 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1828 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1829 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1830 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1831 priv->hex_entry = gtk_entry_new ();
1833 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1835 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate",
1836 GTK_SIGNAL_FUNC (hex_changed), colorsel);
1838 gtk_tooltips_set_tip (priv->tooltips,
1840 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1842 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1843 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1844 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1846 /* Set up the palette */
1847 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1848 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1849 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1850 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1852 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1854 make_palette_frame (colorsel, table, i, j);
1857 set_selected_palette (colorsel, 0, 0);
1858 priv->palette_frame = gtk_frame_new (NULL);
1859 label = gtk_label_new_with_mnemonic (_("_Palette"));
1860 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1862 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1863 priv->custom_palette[0][0]);
1865 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1866 vbox = gtk_vbox_new (FALSE, 4);
1867 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1868 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1870 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1872 gtk_widget_show_all (top_hbox);
1874 /* hide unused stuff */
1876 if (priv->has_opacity == FALSE)
1878 gtk_widget_hide (priv->opacity_label);
1879 gtk_widget_hide (priv->opacity_slider);
1880 gtk_widget_hide (priv->opacity_entry);
1883 if (priv->has_palette == FALSE)
1885 gtk_widget_hide (priv->palette_frame);
1890 gtk_color_selection_destroy (GtkObject *object)
1892 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1893 ColorSelectionPrivate *priv = cselection->private_data;
1895 if (priv->dropper_grab_widget)
1897 gtk_widget_destroy (priv->dropper_grab_widget);
1898 priv->dropper_grab_widget = NULL;
1903 gtk_object_destroy (GTK_OBJECT (priv->tooltips));
1904 priv->tooltips = NULL;
1907 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1911 gtk_color_selection_finalize (GObject *object)
1913 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1915 if (cselection->private_data)
1917 ColorSelectionPrivate *priv;
1919 priv = cselection->private_data;
1921 g_signal_handler_disconnect (gtk_settings_get_default (),
1922 priv->settings_connection);
1924 g_free (cselection->private_data);
1925 cselection->private_data = NULL;
1928 G_OBJECT_CLASS (parent_class)->finalize (object);
1932 gtk_color_selection_realize (GtkWidget *widget)
1934 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
1935 ColorSelectionPrivate *priv = colorsel->private_data;
1937 static gboolean initialized = FALSE;
1941 g_object_get (gtk_settings_get_default (),
1942 "gtk-color-palette", &palette,
1945 fill_palette_from_string (palette);
1948 g_signal_connect (gtk_settings_get_default (),
1949 "notify::gtk-color-palette",
1950 G_CALLBACK (palette_change_notify_class),
1956 /* Set default colors */
1958 update_palette (colorsel);
1959 priv->settings_connection =
1960 g_signal_connect (gtk_settings_get_default (),
1961 "notify::gtk-color-palette",
1962 G_CALLBACK (palette_change_notify_instance),
1965 if (GTK_WIDGET_CLASS (parent_class)->realize)
1966 GTK_WIDGET_CLASS (parent_class)->realize (widget);
1970 * gtk_color_selection_new:
1972 * Creates a new GtkColorSelection.
1974 * Return value: a new #GtkColorSelection
1977 gtk_color_selection_new (void)
1979 GtkColorSelection *colorsel;
1980 ColorSelectionPrivate *priv;
1987 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
1988 priv = colorsel->private_data;
1989 gtk_color_selection_set_color (colorsel, color);
1990 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
1992 /* We want to make sure that default_set is FALSE */
1993 /* This way the user can still set it */
1994 priv->default_set = FALSE;
1995 priv->default_alpha_set = FALSE;
1997 return GTK_WIDGET (colorsel);
2002 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
2003 GtkUpdateType policy)
2005 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2007 g_warning (G_STRLOC ": This function is deprecated.");
2011 * gtk_color_selection_get_has_opacity_control:
2012 * @colorsel: a #GtkColorSelection.
2014 * Determines whether the colorsel has an opacity control.
2016 * Return value: %TRUE if the @colorsel has an opacity control. %FALSE if it does't.
2019 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2021 ColorSelectionPrivate *priv;
2023 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2025 priv = colorsel->private_data;
2027 return priv->has_opacity;
2031 * gtk_color_selection_set_has_opacity_control:
2032 * @colorsel: a #GtkColorSelection.
2033 * @has_opacity: %TRUE if @colorsel can set the opacity, %FALSE otherwise.
2035 * Sets the @colorsel to use or not use opacity.
2039 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2040 gboolean has_opacity)
2042 ColorSelectionPrivate *priv;
2044 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2046 priv = colorsel->private_data;
2047 has_opacity = has_opacity != FALSE;
2049 if (priv->has_opacity != has_opacity)
2051 priv->has_opacity = has_opacity;
2054 gtk_widget_show (priv->opacity_slider);
2055 gtk_widget_show (priv->opacity_label);
2056 gtk_widget_show (priv->opacity_entry);
2060 gtk_widget_hide (priv->opacity_slider);
2061 gtk_widget_hide (priv->opacity_label);
2062 gtk_widget_hide (priv->opacity_entry);
2064 color_sample_draw_samples (colorsel);
2066 g_object_notify (G_OBJECT (colorsel), "has_opacity_control");
2071 * gtk_color_selection_get_has_palette:
2072 * @colorsel: a #GtkColorSelection.
2074 * Determines whether the color selector has a color palette.
2076 * Return value: %TRUE if the selector has a palette. %FALSE if it hasn't.
2079 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2081 ColorSelectionPrivate *priv;
2083 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2085 priv = colorsel->private_data;
2087 return priv->has_palette;
2091 * gtk_color_selection_set_has_palette:
2092 * @colorsel: a #GtkColorSelection.
2093 * @has_palette: %TRUE if palette is to be visible, %FALSE otherwise.
2095 * Shows and hides the palette based upon the value of @has_palette.
2099 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2100 gboolean has_palette)
2102 ColorSelectionPrivate *priv;
2103 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2105 priv = colorsel->private_data;
2106 has_palette = has_palette != FALSE;
2108 if (priv->has_palette != has_palette)
2110 priv->has_palette = has_palette;
2112 gtk_widget_show (priv->palette_frame);
2114 gtk_widget_hide (priv->palette_frame);
2116 g_object_notify (G_OBJECT (colorsel), "has_palette");
2121 * gtk_color_selection_set_current_color:
2122 * @colorsel: a #GtkColorSelection.
2123 * @color: A #GdkColor to set the current color with.
2125 * Sets the current color to be @color. The first time this is called, it will
2126 * also set the original color to be @color too.
2129 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2132 ColorSelectionPrivate *priv;
2134 gboolean previous_changed;
2136 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2138 priv = colorsel->private_data;
2139 priv->changing = TRUE;
2140 priv->color[COLORSEL_RED] = SCALE (color->red);
2141 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2142 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2143 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2144 priv->color[COLORSEL_GREEN],
2145 priv->color[COLORSEL_BLUE],
2146 &priv->color[COLORSEL_HUE],
2147 &priv->color[COLORSEL_SATURATION],
2148 &priv->color[COLORSEL_VALUE]);
2149 if (priv->default_set == FALSE)
2151 previous_changed = TRUE;
2152 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2153 priv->old_color[i] = priv->color[i];
2155 update_color (colorsel);
2156 priv->default_set = TRUE;
2160 * gtk_color_selection_set_current_alpha:
2161 * @colorsel: a #GtkColorSelection.
2162 * @alpha: an integer between 0 and 65535.
2164 * Sets the current opacity to be @alpha. The first time this is called, it will
2165 * also set the original opacity to be @alpha too.
2168 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2171 ColorSelectionPrivate *priv;
2174 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2176 priv = colorsel->private_data;
2177 priv->changing = TRUE;
2178 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2179 if (priv->default_alpha_set == FALSE)
2181 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2182 priv->old_color[i] = priv->color[i];
2184 update_color (colorsel);
2185 priv->default_alpha_set = TRUE;
2189 * gtk_color_selection_set_color:
2190 * @colorsel: a #GtkColorSelection.
2191 * @color: an array of 4 doubles specifying the red, green, blue and opacity
2192 * to set the current color to.
2194 * Sets the current color to be @color. The first time this is called, it will
2195 * also set the original color to be @color too.
2197 * This function is deprecated, use gtk_color_selection_set_current_color() instead.
2200 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2203 ColorSelectionPrivate *priv;
2206 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2208 priv = colorsel->private_data;
2209 priv->changing = TRUE;
2210 priv->color[COLORSEL_RED] = color[0];
2211 priv->color[COLORSEL_GREEN] = color[1];
2212 priv->color[COLORSEL_BLUE] = color[2];
2213 priv->color[COLORSEL_OPACITY] = color[3];
2214 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2215 priv->color[COLORSEL_GREEN],
2216 priv->color[COLORSEL_BLUE],
2217 &priv->color[COLORSEL_HUE],
2218 &priv->color[COLORSEL_SATURATION],
2219 &priv->color[COLORSEL_VALUE]);
2220 if (priv->default_set == FALSE)
2222 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2223 priv->old_color[i] = priv->color[i];
2225 update_color (colorsel);
2226 priv->default_set = TRUE;
2227 priv->default_alpha_set = TRUE;
2231 * gtk_color_selection_get_current_color:
2232 * @colorsel: a #GtkColorSelection.
2233 * @color: a #GdkColor to fill in with the current color.
2235 * Sets @color to be the current color in the GtkColorSelection widget.
2238 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2241 ColorSelectionPrivate *priv;
2243 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2245 priv = colorsel->private_data;
2246 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2247 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2248 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2252 * gtk_color_selection_get_current_alpha:
2253 * @colorsel: a #GtkColorSelection.
2255 * Returns the current alpha value.
2257 * Return value: an integer between 0 and 65535.
2260 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2262 ColorSelectionPrivate *priv;
2264 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2266 priv = colorsel->private_data;
2267 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2271 * gtk_color_selection_get_color:
2272 * @colorsel: a #GtkColorSelection.
2273 * @color: an array of 4 #gdouble to fill in with the current color.
2275 * Sets @color to be the current color in the GtkColorSelection widget.
2277 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2280 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2283 ColorSelectionPrivate *priv;
2285 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2287 priv = colorsel->private_data;
2288 color[0] = priv->color[COLORSEL_RED];
2289 color[1] = priv->color[COLORSEL_GREEN];
2290 color[2] = priv->color[COLORSEL_BLUE];
2291 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2295 * gtk_color_selection_set_previous_color:
2296 * @colorsel: a #GtkColorSelection.
2297 * @color: a #GdkColor to set the previous color with.
2299 * Sets the 'previous' color to be @color. This function should be called with
2300 * some hesitations, as it might seem confusing to have that color change.
2301 * Calling gtk_color_selection_set_current_color() will also set this color the first
2302 * time it is called.
2305 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2308 ColorSelectionPrivate *priv;
2310 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2312 priv = colorsel->private_data;
2313 priv->changing = TRUE;
2314 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2315 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2316 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2317 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2318 priv->old_color[COLORSEL_GREEN],
2319 priv->old_color[COLORSEL_BLUE],
2320 &priv->old_color[COLORSEL_HUE],
2321 &priv->old_color[COLORSEL_SATURATION],
2322 &priv->old_color[COLORSEL_VALUE]);
2323 color_sample_draw_samples (colorsel);
2324 priv->default_set = TRUE;
2328 * gtk_color_selection_set_previous_alpha:
2329 * @colorsel: a #GtkColorSelection.
2330 * @alpha: an integer between 0 and 65535.
2332 * Sets the 'previous' alpha to be @alpha. This function should be called with
2333 * some hesitations, as it might seem confusing to have that alpha change.
2336 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2339 ColorSelectionPrivate *priv;
2341 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2343 priv = colorsel->private_data;
2344 priv->changing = TRUE;
2345 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2346 color_sample_draw_samples (colorsel);
2347 priv->default_alpha_set = TRUE;
2352 * gtk_color_selection_get_previous_color:
2353 * @colorsel: a #GtkColorSelection.
2354 * @color: a #GdkColor to fill in with the original color value.
2356 * Fills @color in with the original color value.
2359 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2362 ColorSelectionPrivate *priv;
2364 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2366 priv = colorsel->private_data;
2367 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2368 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2369 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2373 * gtk_color_selection_get_previous_alpha:
2374 * @colorsel: a #GtkColorSelection.
2376 * Returns the previous alpha value.
2378 * Return value: an integer between 0 and 65535.
2381 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2383 ColorSelectionPrivate *priv;
2385 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2387 priv = colorsel->private_data;
2388 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2392 * gtk_color_selection_set_palette_color:
2393 * @colorsel: a #GtkColorSelection.
2394 * @index: the color index of the palette.
2395 * @color: A #GdkColor to set the palette with.
2397 * Sets the palette located at @index to have @color as its color.
2401 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2405 ColorSelectionPrivate *priv;
2409 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2410 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2412 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2413 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2415 priv = colorsel->private_data;
2416 col[0] = SCALE (color->red);
2417 col[1] = SCALE (color->green);
2418 col[2] = SCALE (color->blue);
2420 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2424 * gtk_color_selection_get_palette_color:
2425 * @colorsel: a #GtkColorSelection.
2426 * @index: the color index of the palette.
2427 * @color: a #GdkColor to fill in with the color value.
2429 * Set @color to have the color found in the palette at @index. If
2430 * the palette is unset, it will leave the color unset.
2432 * Return value: %TRUE if the palette located at @index has a color set. %FALSE
2436 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
2440 ColorSelectionPrivate *priv;
2444 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2445 g_return_val_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
2447 priv = colorsel->private_data;
2449 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2450 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2452 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
2455 palette_get_color (priv->custom_palette[x][y], col);
2457 color->red = UNSCALE (col[0]);
2458 color->green = UNSCALE (col[1]);
2459 color->blue = UNSCALE (col[2]);
2465 * gtk_color_selection_unset_palette_color:
2466 * @colorsel: a #GtkColorSelection.
2467 * @index: the color index in the palette.
2469 * Changes the palette located @index to have no color set.
2472 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
2475 ColorSelectionPrivate *priv;
2478 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2479 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2481 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2482 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2484 priv = colorsel->private_data;
2485 palette_unset_color (priv->custom_palette[x][y]);
2489 * gtk_color_selection_get_current_alpha:
2490 * @colorsel: a #GtkColorSelection.
2492 * Returns the maximum number of palette colors.
2494 * Return value: the maximum number of palette indexes.
2497 gtk_color_selection_get_palette_size (GtkColorSelection *colorsel)
2499 return GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
2504 * gtk_color_selection_is_adjusting:
2505 * @colorsel: a #GtkColorSelection.
2507 * Gets the current state of the @colorsel.
2509 * Return value: %TRUE if the user is currently dragging a color around, and %FALSE
2510 * if the selection has stopped.
2513 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2515 ColorSelectionPrivate *priv;
2517 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2519 priv = colorsel->private_data;
2521 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2525 gtk_color_selection_set_property (GObject *object,
2527 const GValue *value,
2530 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2534 case PROP_HAS_OPACITY_CONTROL:
2535 gtk_color_selection_set_has_opacity_control (colorsel,
2536 g_value_get_boolean (value));
2538 case PROP_HAS_PALETTE:
2539 gtk_color_selection_set_has_palette (colorsel,
2540 g_value_get_boolean (value));
2542 case PROP_CURRENT_COLOR:
2543 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2545 case PROP_CURRENT_ALPHA:
2546 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2549 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2556 gtk_color_selection_get_property (GObject *object,
2561 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2566 case PROP_HAS_OPACITY_CONTROL:
2567 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2569 case PROP_HAS_PALETTE:
2570 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2572 case PROP_CURRENT_COLOR:
2573 gtk_color_selection_get_current_color (colorsel, &color);
2574 g_value_set_boxed (value, &color);
2576 case PROP_CURRENT_ALPHA:
2577 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2580 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2587 * gtk_color_selection_palette_from_string:
2588 * @str: a string encoding a color palette.
2589 * @colors: return location for allocated array of #GdkColor.
2590 * @n_colors: return location for length of array.
2592 * Parses a color palette string; the string is a colon-separated
2593 * list of color names readable by gdk_color_parse().
2595 * Return value: %TRUE if a palette was successfully parsed.
2598 gtk_color_selection_palette_from_string (const gchar *str,
2610 copy = g_strdup (str);
2616 if (*p == ':' || *p == '\0')
2618 gboolean done = TRUE;
2622 goto failed; /* empty entry */
2631 retval = g_renew (GdkColor, retval, count + 1);
2632 if (!gdk_color_parse (start, retval + count))
2673 * gtk_color_selection_palette_to_string:
2674 * @colors: an array of colors.
2675 * @n_colors: length of the array.
2677 * Encodes a palette as a string, useful for persistent storage.
2679 * Return value: allocated string encoding the palette.
2682 gtk_color_selection_palette_to_string (const GdkColor *colors,
2686 gchar **strs = NULL;
2690 return g_strdup ("");
2692 strs = g_new0 (gchar*, n_colors + 1);
2695 while (i < n_colors)
2700 g_strdup_printf ("#%2X%2X%2X",
2701 colors[i].red / 256,
2702 colors[i].green / 256,
2703 colors[i].blue / 256);
2705 for (ptr = strs[i]; *ptr; ptr++)
2712 retval = g_strjoinv (":", strs);
2720 * gtk_color_selection_set_change_palette_hook:
2721 * @func: a function to call when the custom palette needs saving.
2723 * Installs a global function to be called whenever the user tries to
2724 * modify the palette in a color selection. This function should save
2725 * the new palette contents, and update the GtkSettings property
2726 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2728 * Return value: the previous change palette hook (that was replaced).
2730 GtkColorSelectionChangePaletteFunc
2731 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2733 GtkColorSelectionChangePaletteFunc old;
2735 old = change_palette_hook;
2737 change_palette_hook = func;