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 GdkGC *get_focus_gc (GtkWidget *drawing_area,
169 static void default_change_palette_func (const GdkColor *colors,
172 static gpointer parent_class = NULL;
173 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
175 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";
177 static GtkColorSelectionChangePaletteFunc change_palette_hook = default_change_palette_func;
179 static GdkColor current_colors[GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT];
181 /* The cursor for the dropper */
182 #define DROPPER_WIDTH 17
183 #define DROPPER_HEIGHT 17
184 #define DROPPER_X_HOT 2
185 #define DROPPER_Y_HOT 16
188 static char dropper_bits[] = {
189 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
190 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
191 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
192 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
195 static char dropper_mask[] = {
196 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
197 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
198 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
199 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
202 static GdkCursor *picker_cursor = NULL;
206 static char *picker[] = {
207 /* columns rows colors chars-per-pixel */
218 "#########################",
219 "#########################",
220 "#########################",
221 "#########################",
222 "#########################",
223 "################# #####",
224 "################ ####",
225 "################ +###",
226 "############# +###",
227 "############## ++###",
228 "#############+@ +++####",
229 "############+@@@ +######",
230 "###########+@@@ + +######",
231 "##########+@@@ ++#+######",
232 "#########+@@@ ++#########",
233 "########+@@@ ++##########",
234 "#######+@@@ ++###########",
235 "######+@@@ ++############",
236 "######+@@ ++#############",
237 "#####+@ ++##############",
238 "###### +++###############",
239 "#########################",
240 "#########################",
241 "#########################",
242 "#########################"
251 #define SAMPLE_WIDTH 64
252 #define SAMPLE_HEIGHT 28
254 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
255 static void color_sample_draw_samples (GtkColorSelection *colorsel);
258 color_sample_drag_begin (GtkWidget *widget,
259 GdkDragContext *context,
262 GtkColorSelection *colorsel = data;
263 ColorSelectionPrivate *priv;
270 priv = colorsel->private_data;
271 window = gtk_window_new (GTK_WINDOW_POPUP);
272 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
273 gtk_widget_set_usize (window, 48, 32);
274 gtk_widget_realize (window);
275 gtk_object_set_data_full (GTK_OBJECT (widget),
276 "gtk-color-selection-drag-window",
278 (GtkDestroyNotify) gtk_widget_destroy);
280 if (widget == priv->old_sample)
281 colsrc = priv->old_color;
283 colsrc = priv->color;
285 for (i=0, n = COLORSEL_RED; n <= COLORSEL_BLUE; n++)
287 colors[i++] = colsrc[n];
290 if (priv->has_opacity)
292 colors[i] = colsrc[COLORSEL_OPACITY];
295 bg.red = 0xffff * colors[0];
296 bg.green = 0xffff * colors[1];
297 bg.blue = 0xffff * colors[2];
299 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
300 gdk_window_set_background (window->window, &bg);
302 gtk_drag_set_icon_widget (context, window, -2, -2);
306 color_sample_drag_end (GtkWidget *widget,
307 GdkDragContext *context,
310 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
314 color_sample_drop_handle (GtkWidget *widget,
315 GdkDragContext *context,
318 GtkSelectionData *selection_data,
323 GtkColorSelection *colorsel = data;
324 ColorSelectionPrivate *priv;
327 priv = colorsel->private_data;
329 /* This is currently a guint16 array of the format:
336 if (selection_data->length < 0)
339 if ((selection_data->format != 16) ||
340 (selection_data->length != 8))
342 g_warning ("Received invalid color data\n");
346 vals = (guint16 *)selection_data->data;
348 if (widget == priv->cur_sample)
350 color[0] = (gdouble)vals[0] / 0xffff;
351 color[1] = (gdouble)vals[1] / 0xffff;
352 color[2] = (gdouble)vals[2] / 0xffff;
353 color[3] = (gdouble)vals[3] / 0xffff;
355 gtk_color_selection_set_color (colorsel, color);
360 color_sample_drag_handle (GtkWidget *widget,
361 GdkDragContext *context,
362 GtkSelectionData *selection_data,
367 GtkColorSelection *colorsel = data;
368 ColorSelectionPrivate *priv;
372 priv = colorsel->private_data;
374 if (widget == priv->old_sample)
375 colsrc = priv->old_color;
377 colsrc = priv->color;
379 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
380 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
381 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
382 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
384 gtk_selection_data_set (selection_data,
385 gdk_atom_intern ("application/x-color", FALSE),
386 16, (guchar *)vals, 8);
389 /* which = 0 means draw old sample, which = 1 means draw new */
391 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
394 gint x, y, i, wid, heig, f, n, goff;
395 guchar c[3 * 2], cc[3 * 4], *cp = c;
398 ColorSelectionPrivate *priv;
400 g_return_if_fail (colorsel != NULL);
401 priv = colorsel->private_data;
403 g_return_if_fail (priv->sample_area != NULL);
404 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
409 da = priv->old_sample;
410 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
411 c[n] = (guchar) (UNSCALE (priv->old_color[i]) >> 8);
416 da = priv->cur_sample;
417 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
418 c[n] = (guchar) (UNSCALE (priv->color[i]) >> 8);
419 goff = priv->old_sample->allocation.width % 32;
422 wid = da->allocation.width;
423 heig = da->allocation.height;
425 buf = g_new (guchar, 3 * wid * heig);
429 for (n = 0; n < 3; n++)
431 c[n] = (guchar) (255.0 * priv->old_color[i]);
432 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
436 if (priv->has_opacity)
438 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
440 for (n = 0; n < 3; n++)
442 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
443 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
449 for (y = 0; y < heig; y++)
451 for (x = 0; x < wid; x++)
453 if (priv->has_opacity)
454 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
458 for (n = 0; n < 3; n++)
459 buf[i++] = cp[n + f];
463 gdk_draw_rgb_image (da->window,
467 GDK_RGB_DITHER_NORMAL,
477 color_sample_draw_samples (GtkColorSelection *colorsel)
479 color_sample_draw_sample (colorsel, 0);
480 color_sample_draw_sample (colorsel, 1);
484 color_old_sample_expose (GtkWidget *da,
485 GdkEventExpose *event,
486 GtkColorSelection *colorsel)
488 color_sample_draw_sample (colorsel, 0);
494 color_cur_sample_expose (GtkWidget *da,
495 GdkEventExpose *event,
496 GtkColorSelection *colorsel)
498 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))
643 GdkGC *gc = get_focus_gc (drawing_area, &focus_width);
644 gdk_draw_rectangle (drawing_area->window,
645 gc, FALSE, focus_width / 2, focus_width / 2,
646 drawing_area->allocation.width - focus_width,
647 drawing_area->allocation.height - focus_width);
653 get_focus_gc (GtkWidget *drawing_area,
656 GdkGC *gc = gdk_gc_new (drawing_area->window);
660 gtk_widget_style_get (drawing_area,
661 "focus-line-width", focus_width,
662 "focus-line-pattern", (gchar *)&dash_list,
665 palette_get_color (drawing_area, color);
667 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
668 gdk_gc_copy (gc, drawing_area->style->black_gc);
670 gdk_gc_copy (gc, drawing_area->style->white_gc);
672 gdk_gc_set_line_attributes (gc, *focus_width,
673 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
674 GDK_CAP_BUTT, GDK_JOIN_MITER);
677 gdk_gc_set_dashes (gc, 0, dash_list, strlen (dash_list));
685 palette_drag_begin (GtkWidget *widget,
686 GdkDragContext *context,
689 GtkColorSelection *colorsel = data;
690 ColorSelectionPrivate *priv;
695 priv = colorsel->private_data;
696 window = gtk_window_new (GTK_WINDOW_POPUP);
697 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
698 gtk_widget_set_usize (window, 48, 32);
699 gtk_widget_realize (window);
700 gtk_object_set_data_full (GTK_OBJECT (widget),
701 "gtk-color-selection-drag-window",
703 (GtkDestroyNotify) gtk_widget_destroy);
705 palette_get_color (widget, colors);
706 bg.red = 0xffff * colors[0];
707 bg.green = 0xffff * colors[1];
708 bg.blue = 0xffff * colors[2];
710 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
711 gdk_window_set_background (window->window, &bg);
713 gtk_drag_set_icon_widget (context, window, -2, -2);
717 palette_drag_handle (GtkWidget *widget,
718 GdkDragContext *context,
719 GtkSelectionData *selection_data,
727 palette_get_color (widget, colsrc);
729 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
730 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
731 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
734 gtk_selection_data_set (selection_data,
735 gdk_atom_intern ("application/x-color", FALSE),
736 16, (guchar *)vals, 8);
740 palette_drag_end (GtkWidget *widget,
741 GdkDragContext *context,
744 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
747 /* Changes the model color */
749 palette_change_color (GtkWidget *drawing_area,
750 GtkColorSelection *colorsel,
754 ColorSelectionPrivate *priv;
757 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
758 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
760 priv = colorsel->private_data;
762 gdk_color.red = UNSCALE (color[0]);
763 gdk_color.green = UNSCALE (color[1]);
764 gdk_color.blue = UNSCALE (color[2]);
767 while (x < GTK_CUSTOM_PALETTE_WIDTH)
770 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
772 if (priv->custom_palette[x][y] == drawing_area)
783 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
785 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
787 if (change_palette_hook)
788 (* change_palette_hook) (current_colors, GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
791 /* Changes the view color */
793 palette_set_color (GtkWidget *drawing_area,
794 GtkColorSelection *colorsel,
797 gdouble *new_color = g_new (double, 4);
800 gdk_color.red = UNSCALE (color[0]);
801 gdk_color.green = UNSCALE (color[1]);
802 gdk_color.blue = UNSCALE (color[2]);
804 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
806 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
808 static const GtkTargetEntry targets[] = {
809 { "application/x-color", 0 }
811 gtk_drag_source_set (drawing_area,
812 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
814 GDK_ACTION_COPY | GDK_ACTION_MOVE);
816 gtk_signal_connect (GTK_OBJECT (drawing_area),
818 GTK_SIGNAL_FUNC (palette_drag_begin),
820 gtk_signal_connect (GTK_OBJECT (drawing_area),
822 GTK_SIGNAL_FUNC (palette_drag_handle),
825 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (1));
828 new_color[0] = color[0];
829 new_color[1] = color[1];
830 new_color[2] = color[2];
833 g_object_set_data_full (G_OBJECT (drawing_area), "color_val", new_color, (GDestroyNotify)g_free);
837 palette_expose (GtkWidget *drawing_area,
838 GdkEventExpose *event,
841 if (drawing_area->window == NULL)
844 palette_paint (drawing_area, &(event->area), data);
850 popup_position_func (GtkMenu *menu,
860 widget = GTK_WIDGET (user_data);
862 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
864 gdk_window_get_origin (widget->window, &root_x, &root_y);
866 gtk_widget_size_request (GTK_WIDGET (menu), &req);
868 /* Put corner of menu centered on color cell */
869 *x = root_x + widget->allocation.width / 2;
870 *y = root_y + widget->allocation.height / 2;
873 *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
874 *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
878 save_color_selected (GtkWidget *menuitem,
881 GtkColorSelection *colorsel;
882 GtkWidget *drawing_area;
883 ColorSelectionPrivate *priv;
885 drawing_area = GTK_WIDGET (data);
887 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
890 priv = colorsel->private_data;
892 palette_change_color (drawing_area, colorsel, priv->color);
896 do_popup (GtkColorSelection *colorsel,
897 GtkWidget *drawing_area,
903 g_object_set_data (G_OBJECT (drawing_area),
907 menu = gtk_menu_new ();
909 mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
911 gtk_signal_connect (GTK_OBJECT (mi), "activate",
912 GTK_SIGNAL_FUNC (save_color_selected),
915 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
917 gtk_widget_show_all (mi);
919 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
920 popup_position_func, drawing_area,
926 palette_press (GtkWidget *drawing_area,
927 GdkEventButton *event,
930 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
932 gtk_widget_grab_focus (drawing_area);
934 if (event->button == 1 &&
935 event->type == GDK_BUTTON_PRESS)
937 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) != 0)
940 palette_get_color (drawing_area, color);
941 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
945 if (event->button == 3 &&
946 event->type == GDK_BUTTON_PRESS)
948 do_popup (colorsel, drawing_area, event->time);
955 palette_unset_color (GtkWidget *drawing_area)
957 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (drawing_area), "color_set")) == 0)
960 gtk_widget_reset_rc_styles (drawing_area);
961 gtk_object_set_data (GTK_OBJECT (drawing_area), "color_set", GINT_TO_POINTER (0));
965 palette_drop_handle (GtkWidget *widget,
966 GdkDragContext *context,
969 GtkSelectionData *selection_data,
977 if (selection_data->length < 0)
980 if ((selection_data->format != 16) ||
981 (selection_data->length != 8))
983 g_warning ("Received invalid color data\n");
987 vals = (guint16 *)selection_data->data;
989 color[0] = (gdouble)vals[0] / 0xffff;
990 color[1] = (gdouble)vals[1] / 0xffff;
991 color[2] = (gdouble)vals[2] / 0xffff;
992 color[3] = (gdouble)vals[3] / 0xffff;
993 palette_change_color (widget, GTK_COLOR_SELECTION (data), color);
994 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
998 palette_activate (GtkWidget *widget,
1002 /* should have a drawing area subclass with an activate signal */
1003 if ((event->keyval == GDK_space) ||
1004 (event->keyval == GDK_Return) ||
1005 (event->keyval == GDK_KP_Enter) ||
1006 (event->keyval == GDK_KP_Space))
1008 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "color_set")) != 0)
1011 palette_get_color (widget, color);
1012 gtk_color_selection_set_color (GTK_COLOR_SELECTION (data), color);
1021 palette_popup (GtkWidget *widget,
1024 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1026 do_popup (colorsel, widget, GDK_CURRENT_TIME);
1031 palette_new (GtkColorSelection *colorsel)
1034 ColorSelectionPrivate *priv;
1036 static const GtkTargetEntry targets[] = {
1037 { "application/x-color", 0 }
1040 priv = colorsel->private_data;
1042 retval = gtk_drawing_area_new ();
1044 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1046 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
1047 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1048 | GDK_BUTTON_RELEASE_MASK
1050 | GDK_ENTER_NOTIFY_MASK
1051 | GDK_LEAVE_NOTIFY_MASK);
1054 gtk_signal_connect (GTK_OBJECT (retval), "expose_event",
1055 GTK_SIGNAL_FUNC (palette_expose), colorsel);
1056 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event",
1057 GTK_SIGNAL_FUNC (palette_press), colorsel);
1058 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event",
1059 GTK_SIGNAL_FUNC (palette_activate), colorsel);
1060 gtk_signal_connect (GTK_OBJECT (retval), "popup_menu",
1061 GTK_SIGNAL_FUNC (palette_popup), colorsel);
1063 gtk_drag_dest_set (retval,
1064 GTK_DEST_DEFAULT_HIGHLIGHT |
1065 GTK_DEST_DEFAULT_MOTION |
1066 GTK_DEST_DEFAULT_DROP,
1070 gtk_signal_connect (GTK_OBJECT (retval), "drag_end",
1071 GTK_SIGNAL_FUNC (palette_drag_end), NULL);
1072 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received",
1073 GTK_SIGNAL_FUNC (palette_drop_handle), colorsel);
1075 gtk_tooltips_set_tip (priv->tooltips,
1077 _("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.\""),
1085 * The actual GtkColorSelection widget
1090 initialize_cursor (void)
1095 gdk_bitmap_create_from_data (NULL,
1097 DROPPER_WIDTH, DROPPER_HEIGHT);
1099 gdk_bitmap_create_from_data (NULL,
1101 DROPPER_WIDTH, DROPPER_HEIGHT);
1103 gdk_color_white (gdk_colormap_get_system (), &bg);
1104 gdk_color_black (gdk_colormap_get_system (), &fg);
1106 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
1108 gdk_pixmap_unref (pixmap);
1109 gdk_pixmap_unref (mask);
1114 grab_color_at_mouse (GtkWidget *invisible,
1121 GtkColorSelection *colorsel = data;
1122 ColorSelectionPrivate *priv;
1123 GdkColormap *colormap = gdk_colormap_get_system ();
1126 priv = colorsel->private_data;
1128 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
1129 pixel = gdk_image_get_pixel (image, 0, 0);
1130 gdk_image_unref (image);
1132 gdk_colormap_query_color (colormap, pixel, &color);
1134 priv->color[COLORSEL_RED] = SCALE (color.red);
1135 priv->color[COLORSEL_GREEN] = SCALE (color.green);
1136 priv->color[COLORSEL_BLUE] = SCALE (color.blue);
1138 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1139 priv->color[COLORSEL_GREEN],
1140 priv->color[COLORSEL_BLUE],
1141 &priv->color[COLORSEL_HUE],
1142 &priv->color[COLORSEL_SATURATION],
1143 &priv->color[COLORSEL_VALUE]);
1145 update_color (colorsel);
1149 shutdown_eyedropper (GtkWidget *widget)
1151 GtkColorSelection *colorsel;
1152 ColorSelectionPrivate *priv;
1154 colorsel = GTK_COLOR_SELECTION (widget);
1155 priv = colorsel->private_data;
1157 gdk_keyboard_ungrab (gtk_get_current_event_time ());
1158 gdk_pointer_ungrab (gtk_get_current_event_time ());
1159 gtk_grab_remove (priv->dropper_grab_widget);
1163 mouse_motion (GtkWidget *invisible,
1164 GdkEventMotion *event,
1167 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1171 mouse_release (GtkWidget *invisible,
1172 GdkEventButton *event,
1175 GtkColorSelection *colorsel = data;
1176 ColorSelectionPrivate *priv;
1177 priv = colorsel->private_data;
1179 if (event->button != 1)
1182 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1184 shutdown_eyedropper (GTK_WIDGET (data));
1186 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1187 GTK_SIGNAL_FUNC (mouse_motion), data);
1188 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1189 GTK_SIGNAL_FUNC (mouse_release), data);
1194 /* Helper Functions */
1196 static gboolean mouse_press (GtkWidget *invisible,
1197 GdkEventButton *event,
1201 key_press (GtkWidget *invisible,
1205 if (event->keyval == GDK_Escape)
1207 shutdown_eyedropper (data);
1209 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1210 GTK_SIGNAL_FUNC (mouse_press),
1212 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1213 GTK_SIGNAL_FUNC (key_press),
1223 mouse_press (GtkWidget *invisible,
1224 GdkEventButton *event,
1227 GtkColorSelection *colorsel = data;
1228 ColorSelectionPrivate *priv;
1229 priv = colorsel->private_data;
1231 if (event->type == GDK_BUTTON_PRESS &&
1234 gtk_signal_connect (GTK_OBJECT (invisible), "motion_notify_event",
1235 GTK_SIGNAL_FUNC (mouse_motion),
1237 gtk_signal_connect (GTK_OBJECT (invisible), "button_release_event",
1238 GTK_SIGNAL_FUNC (mouse_release),
1240 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1241 GTK_SIGNAL_FUNC (mouse_press),
1243 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1244 GTK_SIGNAL_FUNC (key_press),
1252 /* when the button is clicked */
1254 get_screen_color (GtkWidget *button)
1256 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
1257 ColorSelectionPrivate *priv = colorsel->private_data;
1259 if (picker_cursor == NULL)
1261 initialize_cursor ();
1264 if (priv->dropper_grab_widget == NULL)
1266 priv->dropper_grab_widget = gtk_invisible_new ();
1268 gtk_widget_add_events (priv->dropper_grab_widget,
1269 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1271 gtk_widget_show (priv->dropper_grab_widget);
1274 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1276 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1278 g_warning ("Failed to grab keyboard to do eyedropper");
1282 if (gdk_pointer_grab (priv->dropper_grab_widget->window,
1284 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1287 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1289 gdk_keyboard_ungrab (GDK_CURRENT_TIME);
1290 g_warning ("Failed to grab pointer to do eyedropper");
1294 gtk_grab_add (priv->dropper_grab_widget);
1296 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "button_press_event",
1297 GTK_SIGNAL_FUNC (mouse_press), colorsel);
1298 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "key_press_event",
1299 GTK_SIGNAL_FUNC (key_press), colorsel);
1303 hex_changed (GtkWidget *hex_entry,
1306 GtkColorSelection *colorsel;
1307 ColorSelectionPrivate *priv;
1311 colorsel = GTK_COLOR_SELECTION (data);
1312 priv = colorsel->private_data;
1317 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1318 if (gdk_color_parse (text, &color))
1320 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1321 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1322 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1323 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1324 priv->color[COLORSEL_GREEN],
1325 priv->color[COLORSEL_BLUE],
1326 &priv->color[COLORSEL_HUE],
1327 &priv->color[COLORSEL_SATURATION],
1328 &priv->color[COLORSEL_VALUE]);
1329 update_color (colorsel);
1335 hsv_changed (GtkWidget *hsv,
1338 GtkColorSelection *colorsel;
1339 ColorSelectionPrivate *priv;
1341 colorsel = GTK_COLOR_SELECTION (data);
1342 priv = colorsel->private_data;
1347 gtk_hsv_get_color (GTK_HSV (hsv),
1348 &priv->color[COLORSEL_HUE],
1349 &priv->color[COLORSEL_SATURATION],
1350 &priv->color[COLORSEL_VALUE]);
1351 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1352 priv->color[COLORSEL_SATURATION],
1353 priv->color[COLORSEL_VALUE],
1354 &priv->color[COLORSEL_RED],
1355 &priv->color[COLORSEL_GREEN],
1356 &priv->color[COLORSEL_BLUE]);
1357 update_color (colorsel);
1361 adjustment_changed (GtkAdjustment *adjustment,
1364 GtkColorSelection *colorsel;
1365 ColorSelectionPrivate *priv;
1367 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1368 priv = colorsel->private_data;
1373 switch (GPOINTER_TO_INT (data))
1375 case COLORSEL_SATURATION:
1376 case COLORSEL_VALUE:
1377 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1378 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1379 priv->color[COLORSEL_SATURATION],
1380 priv->color[COLORSEL_VALUE],
1381 &priv->color[COLORSEL_RED],
1382 &priv->color[COLORSEL_GREEN],
1383 &priv->color[COLORSEL_BLUE]);
1386 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1387 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1388 priv->color[COLORSEL_SATURATION],
1389 priv->color[COLORSEL_VALUE],
1390 &priv->color[COLORSEL_RED],
1391 &priv->color[COLORSEL_GREEN],
1392 &priv->color[COLORSEL_BLUE]);
1395 case COLORSEL_GREEN:
1397 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1399 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1400 priv->color[COLORSEL_GREEN],
1401 priv->color[COLORSEL_BLUE],
1402 &priv->color[COLORSEL_HUE],
1403 &priv->color[COLORSEL_SATURATION],
1404 &priv->color[COLORSEL_VALUE]);
1407 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1410 update_color (colorsel);
1414 opacity_entry_changed (GtkWidget *opacity_entry,
1417 GtkColorSelection *colorsel;
1418 ColorSelectionPrivate *priv;
1422 colorsel = GTK_COLOR_SELECTION (data);
1423 priv = colorsel->private_data;
1428 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1429 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1430 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1432 update_color (colorsel);
1438 make_label_spinbutton (GtkColorSelection *colorsel,
1439 GtkWidget **spinbutton,
1445 const gchar *tooltip)
1448 GtkAdjustment *adjust;
1449 ColorSelectionPrivate *priv = colorsel->private_data;
1451 if (channel_type == COLORSEL_HUE)
1453 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1457 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1459 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1460 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1462 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1464 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1465 GTK_SIGNAL_FUNC (adjustment_changed),
1466 GINT_TO_POINTER (channel_type));
1467 label = gtk_label_new_with_mnemonic (text);
1468 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1470 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1471 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1472 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1477 make_palette_frame (GtkColorSelection *colorsel,
1483 ColorSelectionPrivate *priv;
1485 priv = colorsel->private_data;
1486 frame = gtk_frame_new (NULL);
1487 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1488 priv->custom_palette[i][j] = palette_new (colorsel);
1489 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1490 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1491 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1494 /* Set the palette entry [x][y] to be the currently selected one. */
1496 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1498 ColorSelectionPrivate *priv = colorsel->private_data;
1500 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1504 scale_round (double val, double factor)
1506 val = floor (val * factor + 0.5);
1508 val = MIN (val, factor);
1513 update_color (GtkColorSelection *colorsel)
1515 ColorSelectionPrivate *priv = colorsel->private_data;
1517 gchar opacity_text[32];
1520 priv->changing = TRUE;
1521 color_sample_draw_samples (colorsel);
1523 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1524 priv->color[COLORSEL_HUE],
1525 priv->color[COLORSEL_SATURATION],
1526 priv->color[COLORSEL_VALUE]);
1527 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1528 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1529 scale_round (priv->color[COLORSEL_HUE], 360));
1530 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1531 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1532 scale_round (priv->color[COLORSEL_SATURATION], 255));
1533 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1534 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1535 scale_round (priv->color[COLORSEL_VALUE], 255));
1536 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1537 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1538 scale_round (priv->color[COLORSEL_RED], 255));
1539 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1540 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1541 scale_round (priv->color[COLORSEL_GREEN], 255));
1542 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1543 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1544 scale_round (priv->color[COLORSEL_BLUE], 255));
1545 gtk_adjustment_set_value (gtk_range_get_adjustment
1546 (GTK_RANGE (priv->opacity_slider)),
1547 scale_round (priv->color[COLORSEL_OPACITY], 255));
1549 g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
1550 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1552 g_snprintf (entryval, 11, "#%2X%2X%2X",
1553 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1554 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1555 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1557 for (ptr = entryval; *ptr; ptr++)
1560 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1561 priv->changing = FALSE;
1563 g_object_freeze_notify (G_OBJECT (colorsel));
1564 g_object_notify (G_OBJECT (colorsel), "current_color");
1565 g_object_notify (G_OBJECT (colorsel), "current_alpha");
1566 g_object_thaw_notify (G_OBJECT (colorsel));
1571 fill_palette_from_string (const gchar *str)
1573 GdkColor *colors = NULL;
1579 if (!gtk_color_selection_palette_from_string (str, &colors, &n_colors))
1582 if (n_colors > (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
1583 n_colors = GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
1585 memcpy (current_colors, colors, sizeof (GdkColor) * n_colors);
1591 palette_change_notify_class (GObject *object,
1596 g_object_get (object, pspec->name, &str, NULL);
1598 fill_palette_from_string (str);
1604 update_palette (GtkColorSelection *colorsel)
1608 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1610 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1614 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1616 gtk_color_selection_set_palette_color (colorsel,
1618 ¤t_colors[index]);
1624 palette_change_notify_instance (GObject *object,
1628 update_palette (GTK_COLOR_SELECTION (data));
1632 default_change_palette_func (const GdkColor *colors,
1637 str = gtk_color_selection_palette_to_string (colors, n_colors);
1639 gtk_settings_set_string_property (gtk_settings_get_default (),
1640 "gtk-color-palette",
1642 "gtk_color_selection_palette_to_string");
1648 gtk_color_selection_get_type (void)
1650 static GtkType color_selection_type = 0;
1652 if (!color_selection_type)
1654 static const GtkTypeInfo color_selection_info =
1656 "GtkColorSelection",
1657 sizeof (GtkColorSelection),
1658 sizeof (GtkColorSelectionClass),
1659 (GtkClassInitFunc) gtk_color_selection_class_init,
1660 (GtkObjectInitFunc) gtk_color_selection_init,
1661 /* reserved_1 */ NULL,
1662 /* reserved_2 */ NULL,
1663 (GtkClassInitFunc) NULL,
1666 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1669 return color_selection_type;
1673 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1675 GtkObjectClass *object_class;
1676 GObjectClass *gobject_class;
1677 GtkWidgetClass *widget_class;
1679 object_class = GTK_OBJECT_CLASS (klass);
1680 gobject_class = G_OBJECT_CLASS (klass);
1681 widget_class = GTK_WIDGET_CLASS (klass);
1683 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1685 object_class->destroy = gtk_color_selection_destroy;
1686 gobject_class->finalize = gtk_color_selection_finalize;
1688 gobject_class->set_property = gtk_color_selection_set_property;
1689 gobject_class->get_property = gtk_color_selection_get_property;
1691 widget_class->realize = gtk_color_selection_realize;
1693 g_object_class_install_property (gobject_class,
1694 PROP_HAS_OPACITY_CONTROL,
1695 g_param_spec_boolean ("has_opacity_control",
1696 _("Has Opacity Control"),
1697 _("Whether the color selector should allow setting opacity"),
1699 G_PARAM_READABLE | G_PARAM_WRITABLE));
1700 g_object_class_install_property (gobject_class,
1702 g_param_spec_boolean ("has_palette",
1704 _("Whether a palette should be used"),
1706 G_PARAM_READABLE | G_PARAM_WRITABLE));
1707 g_object_class_install_property (gobject_class,
1709 g_param_spec_boxed ("current_color",
1711 _("The current color"),
1713 G_PARAM_READABLE | G_PARAM_WRITABLE));
1714 g_object_class_install_property (gobject_class,
1716 g_param_spec_uint ("current_alpha",
1718 _("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1720 G_PARAM_READABLE | G_PARAM_WRITABLE));
1722 color_selection_signals[COLOR_CHANGED] =
1723 gtk_signal_new ("color_changed",
1725 GTK_CLASS_TYPE (object_class),
1726 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1727 _gtk_marshal_VOID__VOID,
1730 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1731 _("Custom palette"),
1732 _("Palette to use in the color selector"),
1734 G_PARAM_READWRITE));
1737 /* widget functions */
1740 gtk_color_selection_init (GtkColorSelection *colorsel)
1742 GtkWidget *top_hbox;
1743 GtkWidget *top_right_vbox;
1744 GtkWidget *table, *label, *hbox, *frame, *vbox;
1745 GtkAdjustment *adjust;
1746 GdkPixmap *dropper_pixmap;
1747 GtkWidget *dropper_image;
1749 GdkBitmap *mask = NULL;
1751 ColorSelectionPrivate *priv;
1753 gtk_widget_push_composite_child ();
1755 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1756 priv->changing = FALSE;
1757 priv->default_set = FALSE;
1758 priv->default_alpha_set = FALSE;
1760 priv->tooltips = gtk_tooltips_new ();
1761 g_object_ref (priv->tooltips);
1762 gtk_object_sink (GTK_OBJECT (priv->tooltips));
1764 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1765 top_hbox = gtk_hbox_new (FALSE, 8);
1766 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1768 vbox = gtk_vbox_new (FALSE, 4);
1769 priv->triangle_colorsel = gtk_hsv_new ();
1770 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed",
1771 GTK_SIGNAL_FUNC (hsv_changed), colorsel);
1772 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1773 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1774 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1775 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1776 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1778 hbox = gtk_hbox_new (FALSE, 4);
1779 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1781 frame = gtk_frame_new (NULL);
1782 gtk_widget_set_usize (frame, -1, 30);
1783 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1784 color_sample_new (colorsel);
1785 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1786 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1788 button = gtk_button_new ();
1790 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1791 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1792 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1793 GTK_SIGNAL_FUNC (get_screen_color), NULL);
1794 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1795 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1796 gdk_pixmap_unref (dropper_pixmap);
1798 gdk_pixmap_unref (mask);
1799 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1800 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1802 gtk_tooltips_set_tip (priv->tooltips,
1804 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1806 top_right_vbox = gtk_vbox_new (FALSE, 4);
1807 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1808 table = gtk_table_new (8, 6, FALSE);
1809 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1810 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1811 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1813 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1814 _("Position on the color wheel."));
1815 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1816 _("\"Deepness\" of the color."));
1817 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1818 _("Brightness of the color."));
1819 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1820 _("Amount of red light in the color."));
1821 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1822 _("Amount of green light in the color."));
1823 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1824 _("Amount of blue light in the color."));
1825 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1827 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1828 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1829 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1830 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1831 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1832 priv->opacity_slider = gtk_hscale_new (adjust);
1833 gtk_tooltips_set_tip (priv->tooltips,
1834 priv->opacity_slider,
1835 _("Transparency of the currently-selected color."), NULL);
1836 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1837 priv->opacity_slider);
1838 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1839 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1840 GTK_SIGNAL_FUNC (adjustment_changed),
1841 GINT_TO_POINTER (COLORSEL_OPACITY));
1842 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1843 priv->opacity_entry = gtk_entry_new ();
1844 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1846 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate",
1847 GTK_SIGNAL_FUNC (opacity_entry_changed), colorsel);
1848 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1850 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1851 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1852 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1853 priv->hex_entry = gtk_entry_new ();
1855 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1857 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate",
1858 GTK_SIGNAL_FUNC (hex_changed), colorsel);
1860 gtk_tooltips_set_tip (priv->tooltips,
1862 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1864 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1865 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1866 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1868 /* Set up the palette */
1869 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1870 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1871 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1872 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1874 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1876 make_palette_frame (colorsel, table, i, j);
1879 set_selected_palette (colorsel, 0, 0);
1880 priv->palette_frame = gtk_frame_new (NULL);
1881 label = gtk_label_new_with_mnemonic (_("_Palette"));
1882 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1884 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1885 priv->custom_palette[0][0]);
1887 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1888 vbox = gtk_vbox_new (FALSE, 4);
1889 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1890 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1892 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1894 gtk_widget_show_all (top_hbox);
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);
1910 gtk_widget_pop_composite_child ();
1914 gtk_color_selection_destroy (GtkObject *object)
1916 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1917 ColorSelectionPrivate *priv = cselection->private_data;
1919 if (priv->dropper_grab_widget)
1921 gtk_widget_destroy (priv->dropper_grab_widget);
1922 priv->dropper_grab_widget = NULL;
1927 g_object_unref (priv->tooltips);
1928 priv->tooltips = NULL;
1931 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1935 gtk_color_selection_finalize (GObject *object)
1937 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1939 if (cselection->private_data)
1941 ColorSelectionPrivate *priv;
1943 priv = cselection->private_data;
1945 g_signal_handler_disconnect (gtk_settings_get_default (),
1946 priv->settings_connection);
1948 g_free (cselection->private_data);
1949 cselection->private_data = NULL;
1952 G_OBJECT_CLASS (parent_class)->finalize (object);
1956 gtk_color_selection_realize (GtkWidget *widget)
1958 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
1959 ColorSelectionPrivate *priv = colorsel->private_data;
1961 static gboolean initialized = FALSE;
1965 g_object_get (gtk_settings_get_default (),
1966 "gtk-color-palette", &palette,
1969 fill_palette_from_string (palette);
1972 g_signal_connect (gtk_settings_get_default (),
1973 "notify::gtk-color-palette",
1974 G_CALLBACK (palette_change_notify_class),
1980 /* Set default colors */
1982 update_palette (colorsel);
1983 priv->settings_connection =
1984 g_signal_connect (gtk_settings_get_default (),
1985 "notify::gtk-color-palette",
1986 G_CALLBACK (palette_change_notify_instance),
1989 if (GTK_WIDGET_CLASS (parent_class)->realize)
1990 GTK_WIDGET_CLASS (parent_class)->realize (widget);
1994 * gtk_color_selection_new:
1996 * Creates a new GtkColorSelection.
1998 * Return value: a new #GtkColorSelection
2001 gtk_color_selection_new (void)
2003 GtkColorSelection *colorsel;
2004 ColorSelectionPrivate *priv;
2011 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
2012 priv = colorsel->private_data;
2013 gtk_color_selection_set_color (colorsel, color);
2014 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
2016 /* We want to make sure that default_set is FALSE */
2017 /* This way the user can still set it */
2018 priv->default_set = FALSE;
2019 priv->default_alpha_set = FALSE;
2021 return GTK_WIDGET (colorsel);
2026 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
2027 GtkUpdateType policy)
2029 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2033 * gtk_color_selection_get_has_opacity_control:
2034 * @colorsel: a #GtkColorSelection.
2036 * Determines whether the colorsel has an opacity control.
2038 * Return value: %TRUE if the @colorsel has an opacity control. %FALSE if it does't.
2041 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2043 ColorSelectionPrivate *priv;
2045 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2047 priv = colorsel->private_data;
2049 return priv->has_opacity;
2053 * gtk_color_selection_set_has_opacity_control:
2054 * @colorsel: a #GtkColorSelection.
2055 * @has_opacity: %TRUE if @colorsel can set the opacity, %FALSE otherwise.
2057 * Sets the @colorsel to use or not use opacity.
2061 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2062 gboolean has_opacity)
2064 ColorSelectionPrivate *priv;
2066 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2068 priv = colorsel->private_data;
2069 has_opacity = has_opacity != FALSE;
2071 if (priv->has_opacity != has_opacity)
2073 priv->has_opacity = has_opacity;
2076 gtk_widget_show (priv->opacity_slider);
2077 gtk_widget_show (priv->opacity_label);
2078 gtk_widget_show (priv->opacity_entry);
2082 gtk_widget_hide (priv->opacity_slider);
2083 gtk_widget_hide (priv->opacity_label);
2084 gtk_widget_hide (priv->opacity_entry);
2086 color_sample_draw_samples (colorsel);
2088 g_object_notify (G_OBJECT (colorsel), "has_opacity_control");
2093 * gtk_color_selection_get_has_palette:
2094 * @colorsel: a #GtkColorSelection.
2096 * Determines whether the color selector has a color palette.
2098 * Return value: %TRUE if the selector has a palette. %FALSE if it hasn't.
2101 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2103 ColorSelectionPrivate *priv;
2105 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2107 priv = colorsel->private_data;
2109 return priv->has_palette;
2113 * gtk_color_selection_set_has_palette:
2114 * @colorsel: a #GtkColorSelection.
2115 * @has_palette: %TRUE if palette is to be visible, %FALSE otherwise.
2117 * Shows and hides the palette based upon the value of @has_palette.
2121 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2122 gboolean has_palette)
2124 ColorSelectionPrivate *priv;
2125 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2127 priv = colorsel->private_data;
2128 has_palette = has_palette != FALSE;
2130 if (priv->has_palette != has_palette)
2132 priv->has_palette = has_palette;
2134 gtk_widget_show (priv->palette_frame);
2136 gtk_widget_hide (priv->palette_frame);
2138 g_object_notify (G_OBJECT (colorsel), "has_palette");
2143 * gtk_color_selection_set_current_color:
2144 * @colorsel: a #GtkColorSelection.
2145 * @color: A #GdkColor to set the current color with.
2147 * Sets the current color to be @color. The first time this is called, it will
2148 * also set the original color to be @color too.
2151 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2154 ColorSelectionPrivate *priv;
2156 gboolean previous_changed;
2158 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2160 priv = colorsel->private_data;
2161 priv->changing = TRUE;
2162 priv->color[COLORSEL_RED] = SCALE (color->red);
2163 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2164 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2165 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2166 priv->color[COLORSEL_GREEN],
2167 priv->color[COLORSEL_BLUE],
2168 &priv->color[COLORSEL_HUE],
2169 &priv->color[COLORSEL_SATURATION],
2170 &priv->color[COLORSEL_VALUE]);
2171 if (priv->default_set == FALSE)
2173 previous_changed = TRUE;
2174 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2175 priv->old_color[i] = priv->color[i];
2177 update_color (colorsel);
2178 priv->default_set = TRUE;
2182 * gtk_color_selection_set_current_alpha:
2183 * @colorsel: a #GtkColorSelection.
2184 * @alpha: an integer between 0 and 65535.
2186 * Sets the current opacity to be @alpha. The first time this is called, it will
2187 * also set the original opacity to be @alpha too.
2190 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2193 ColorSelectionPrivate *priv;
2196 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2198 priv = colorsel->private_data;
2199 priv->changing = TRUE;
2200 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2201 if (priv->default_alpha_set == FALSE)
2203 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2204 priv->old_color[i] = priv->color[i];
2206 update_color (colorsel);
2207 priv->default_alpha_set = TRUE;
2211 * gtk_color_selection_set_color:
2212 * @colorsel: a #GtkColorSelection.
2213 * @color: an array of 4 doubles specifying the red, green, blue and opacity
2214 * to set the current color to.
2216 * Sets the current color to be @color. The first time this is called, it will
2217 * also set the original color to be @color too.
2219 * This function is deprecated, use gtk_color_selection_set_current_color() instead.
2222 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2225 ColorSelectionPrivate *priv;
2228 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2230 priv = colorsel->private_data;
2231 priv->changing = TRUE;
2232 priv->color[COLORSEL_RED] = color[0];
2233 priv->color[COLORSEL_GREEN] = color[1];
2234 priv->color[COLORSEL_BLUE] = color[2];
2235 priv->color[COLORSEL_OPACITY] = color[3];
2236 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2237 priv->color[COLORSEL_GREEN],
2238 priv->color[COLORSEL_BLUE],
2239 &priv->color[COLORSEL_HUE],
2240 &priv->color[COLORSEL_SATURATION],
2241 &priv->color[COLORSEL_VALUE]);
2242 if (priv->default_set == FALSE)
2244 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2245 priv->old_color[i] = priv->color[i];
2247 update_color (colorsel);
2248 priv->default_set = TRUE;
2249 priv->default_alpha_set = TRUE;
2253 * gtk_color_selection_get_current_color:
2254 * @colorsel: a #GtkColorSelection.
2255 * @color: a #GdkColor to fill in with the current color.
2257 * Sets @color to be the current color in the GtkColorSelection widget.
2260 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2263 ColorSelectionPrivate *priv;
2265 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2267 priv = colorsel->private_data;
2268 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2269 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2270 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2274 * gtk_color_selection_get_current_alpha:
2275 * @colorsel: a #GtkColorSelection.
2277 * Returns the current alpha value.
2279 * Return value: an integer between 0 and 65535.
2282 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2284 ColorSelectionPrivate *priv;
2286 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2288 priv = colorsel->private_data;
2289 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2293 * gtk_color_selection_get_color:
2294 * @colorsel: a #GtkColorSelection.
2295 * @color: an array of 4 #gdouble to fill in with the current color.
2297 * Sets @color to be the current color in the GtkColorSelection widget.
2299 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2302 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2305 ColorSelectionPrivate *priv;
2307 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2309 priv = colorsel->private_data;
2310 color[0] = priv->color[COLORSEL_RED];
2311 color[1] = priv->color[COLORSEL_GREEN];
2312 color[2] = priv->color[COLORSEL_BLUE];
2313 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2317 * gtk_color_selection_set_previous_color:
2318 * @colorsel: a #GtkColorSelection.
2319 * @color: a #GdkColor to set the previous color with.
2321 * Sets the 'previous' color to be @color. This function should be called with
2322 * some hesitations, as it might seem confusing to have that color change.
2323 * Calling gtk_color_selection_set_current_color() will also set this color the first
2324 * time it is called.
2327 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2330 ColorSelectionPrivate *priv;
2332 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2334 priv = colorsel->private_data;
2335 priv->changing = TRUE;
2336 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2337 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2338 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2339 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2340 priv->old_color[COLORSEL_GREEN],
2341 priv->old_color[COLORSEL_BLUE],
2342 &priv->old_color[COLORSEL_HUE],
2343 &priv->old_color[COLORSEL_SATURATION],
2344 &priv->old_color[COLORSEL_VALUE]);
2345 color_sample_draw_samples (colorsel);
2346 priv->default_set = TRUE;
2350 * gtk_color_selection_set_previous_alpha:
2351 * @colorsel: a #GtkColorSelection.
2352 * @alpha: an integer between 0 and 65535.
2354 * Sets the 'previous' alpha to be @alpha. This function should be called with
2355 * some hesitations, as it might seem confusing to have that alpha change.
2358 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2361 ColorSelectionPrivate *priv;
2363 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2365 priv = colorsel->private_data;
2366 priv->changing = TRUE;
2367 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2368 color_sample_draw_samples (colorsel);
2369 priv->default_alpha_set = TRUE;
2374 * gtk_color_selection_get_previous_color:
2375 * @colorsel: a #GtkColorSelection.
2376 * @color: a #GdkColor to fill in with the original color value.
2378 * Fills @color in with the original color value.
2381 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2384 ColorSelectionPrivate *priv;
2386 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2388 priv = colorsel->private_data;
2389 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2390 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2391 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2395 * gtk_color_selection_get_previous_alpha:
2396 * @colorsel: a #GtkColorSelection.
2398 * Returns the previous alpha value.
2400 * Return value: an integer between 0 and 65535.
2403 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2405 ColorSelectionPrivate *priv;
2407 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2409 priv = colorsel->private_data;
2410 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2414 * gtk_color_selection_set_palette_color:
2415 * @colorsel: a #GtkColorSelection.
2416 * @index: the color index of the palette.
2417 * @color: A #GdkColor to set the palette with.
2419 * Sets the palette located at @index to have @color as its color.
2423 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2427 ColorSelectionPrivate *priv;
2431 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2432 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2434 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2435 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2437 priv = colorsel->private_data;
2438 col[0] = SCALE (color->red);
2439 col[1] = SCALE (color->green);
2440 col[2] = SCALE (color->blue);
2442 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2446 * gtk_color_selection_get_palette_color:
2447 * @colorsel: a #GtkColorSelection.
2448 * @index: the color index of the palette.
2449 * @color: a #GdkColor to fill in with the color value.
2451 * Set @color to have the color found in the palette at @index. If
2452 * the palette is unset, it will leave the color unset.
2454 * Return value: %TRUE if the palette located at @index has a color set. %FALSE
2458 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
2462 ColorSelectionPrivate *priv;
2466 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2467 g_return_val_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
2469 priv = colorsel->private_data;
2471 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2472 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2474 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
2477 palette_get_color (priv->custom_palette[x][y], col);
2479 color->red = UNSCALE (col[0]);
2480 color->green = UNSCALE (col[1]);
2481 color->blue = UNSCALE (col[2]);
2487 * gtk_color_selection_unset_palette_color:
2488 * @colorsel: a #GtkColorSelection.
2489 * @index: the color index in the palette.
2491 * Changes the palette located @index to have no color set.
2494 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
2497 ColorSelectionPrivate *priv;
2500 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2501 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2503 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2504 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2506 priv = colorsel->private_data;
2507 palette_unset_color (priv->custom_palette[x][y]);
2511 * gtk_color_selection_get_current_alpha:
2512 * @colorsel: a #GtkColorSelection.
2514 * Returns the maximum number of palette colors.
2516 * Return value: the maximum number of palette indexes.
2519 gtk_color_selection_get_palette_size (GtkColorSelection *colorsel)
2521 return GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
2526 * gtk_color_selection_is_adjusting:
2527 * @colorsel: a #GtkColorSelection.
2529 * Gets the current state of the @colorsel.
2531 * Return value: %TRUE if the user is currently dragging a color around, and %FALSE
2532 * if the selection has stopped.
2535 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2537 ColorSelectionPrivate *priv;
2539 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2541 priv = colorsel->private_data;
2543 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2547 gtk_color_selection_set_property (GObject *object,
2549 const GValue *value,
2552 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2556 case PROP_HAS_OPACITY_CONTROL:
2557 gtk_color_selection_set_has_opacity_control (colorsel,
2558 g_value_get_boolean (value));
2560 case PROP_HAS_PALETTE:
2561 gtk_color_selection_set_has_palette (colorsel,
2562 g_value_get_boolean (value));
2564 case PROP_CURRENT_COLOR:
2565 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2567 case PROP_CURRENT_ALPHA:
2568 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2571 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2578 gtk_color_selection_get_property (GObject *object,
2583 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2588 case PROP_HAS_OPACITY_CONTROL:
2589 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2591 case PROP_HAS_PALETTE:
2592 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2594 case PROP_CURRENT_COLOR:
2595 gtk_color_selection_get_current_color (colorsel, &color);
2596 g_value_set_boxed (value, &color);
2598 case PROP_CURRENT_ALPHA:
2599 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2602 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2609 * gtk_color_selection_palette_from_string:
2610 * @str: a string encoding a color palette.
2611 * @colors: return location for allocated array of #GdkColor.
2612 * @n_colors: return location for length of array.
2614 * Parses a color palette string; the string is a colon-separated
2615 * list of color names readable by gdk_color_parse().
2617 * Return value: %TRUE if a palette was successfully parsed.
2620 gtk_color_selection_palette_from_string (const gchar *str,
2632 copy = g_strdup (str);
2638 if (*p == ':' || *p == '\0')
2640 gboolean done = TRUE;
2644 goto failed; /* empty entry */
2653 retval = g_renew (GdkColor, retval, count + 1);
2654 if (!gdk_color_parse (start, retval + count))
2695 * gtk_color_selection_palette_to_string:
2696 * @colors: an array of colors.
2697 * @n_colors: length of the array.
2699 * Encodes a palette as a string, useful for persistent storage.
2701 * Return value: allocated string encoding the palette.
2704 gtk_color_selection_palette_to_string (const GdkColor *colors,
2708 gchar **strs = NULL;
2712 return g_strdup ("");
2714 strs = g_new0 (gchar*, n_colors + 1);
2717 while (i < n_colors)
2722 g_strdup_printf ("#%2X%2X%2X",
2723 colors[i].red / 256,
2724 colors[i].green / 256,
2725 colors[i].blue / 256);
2727 for (ptr = strs[i]; *ptr; ptr++)
2734 retval = g_strjoinv (":", strs);
2742 * gtk_color_selection_set_change_palette_hook:
2743 * @func: a function to call when the custom palette needs saving.
2745 * Installs a global function to be called whenever the user tries to
2746 * modify the palette in a color selection. This function should save
2747 * the new palette contents, and update the GtkSettings property
2748 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2750 * Return value: the previous change palette hook (that was replaced).
2752 GtkColorSelectionChangePaletteFunc
2753 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2755 GtkColorSelectionChangePaletteFunc old;
2757 old = change_palette_hook;
2759 change_palette_hook = func;