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);
1032 palette_new (GtkColorSelection *colorsel)
1035 ColorSelectionPrivate *priv;
1037 static const GtkTargetEntry targets[] = {
1038 { "application/x-color", 0 }
1041 priv = colorsel->private_data;
1043 retval = gtk_drawing_area_new ();
1045 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1047 gtk_object_set_data (GTK_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
1048 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1049 | GDK_BUTTON_RELEASE_MASK
1051 | GDK_ENTER_NOTIFY_MASK
1052 | GDK_LEAVE_NOTIFY_MASK);
1055 gtk_signal_connect (GTK_OBJECT (retval), "expose_event",
1056 GTK_SIGNAL_FUNC (palette_expose), colorsel);
1057 gtk_signal_connect (GTK_OBJECT (retval), "button_press_event",
1058 GTK_SIGNAL_FUNC (palette_press), colorsel);
1059 gtk_signal_connect (GTK_OBJECT (retval), "key_press_event",
1060 GTK_SIGNAL_FUNC (palette_activate), colorsel);
1061 gtk_signal_connect (GTK_OBJECT (retval), "popup_menu",
1062 GTK_SIGNAL_FUNC (palette_popup), colorsel);
1064 gtk_drag_dest_set (retval,
1065 GTK_DEST_DEFAULT_HIGHLIGHT |
1066 GTK_DEST_DEFAULT_MOTION |
1067 GTK_DEST_DEFAULT_DROP,
1071 gtk_signal_connect (GTK_OBJECT (retval), "drag_end",
1072 GTK_SIGNAL_FUNC (palette_drag_end), NULL);
1073 gtk_signal_connect (GTK_OBJECT (retval), "drag_data_received",
1074 GTK_SIGNAL_FUNC (palette_drop_handle), colorsel);
1076 gtk_tooltips_set_tip (priv->tooltips,
1078 _("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.\""),
1086 * The actual GtkColorSelection widget
1091 initialize_cursor (void)
1096 gdk_bitmap_create_from_data (NULL,
1098 DROPPER_WIDTH, DROPPER_HEIGHT);
1100 gdk_bitmap_create_from_data (NULL,
1102 DROPPER_WIDTH, DROPPER_HEIGHT);
1104 gdk_color_white (gdk_colormap_get_system (), &bg);
1105 gdk_color_black (gdk_colormap_get_system (), &fg);
1107 picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT);
1109 gdk_pixmap_unref (pixmap);
1110 gdk_pixmap_unref (mask);
1115 grab_color_at_mouse (GtkWidget *invisible,
1122 GtkColorSelection *colorsel = data;
1123 ColorSelectionPrivate *priv;
1124 GdkColormap *colormap = gdk_colormap_get_system ();
1127 priv = colorsel->private_data;
1129 image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1);
1130 pixel = gdk_image_get_pixel (image, 0, 0);
1131 gdk_image_unref (image);
1133 gdk_colormap_query_color (colormap, pixel, &color);
1135 priv->color[COLORSEL_RED] = SCALE (color.red);
1136 priv->color[COLORSEL_GREEN] = SCALE (color.green);
1137 priv->color[COLORSEL_BLUE] = SCALE (color.blue);
1139 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1140 priv->color[COLORSEL_GREEN],
1141 priv->color[COLORSEL_BLUE],
1142 &priv->color[COLORSEL_HUE],
1143 &priv->color[COLORSEL_SATURATION],
1144 &priv->color[COLORSEL_VALUE]);
1146 update_color (colorsel);
1150 shutdown_eyedropper (GtkWidget *widget)
1152 GtkColorSelection *colorsel;
1153 ColorSelectionPrivate *priv;
1155 colorsel = GTK_COLOR_SELECTION (widget);
1156 priv = colorsel->private_data;
1158 gdk_keyboard_ungrab (gtk_get_current_event_time ());
1159 gdk_pointer_ungrab (gtk_get_current_event_time ());
1160 gtk_grab_remove (priv->dropper_grab_widget);
1164 mouse_motion (GtkWidget *invisible,
1165 GdkEventMotion *event,
1168 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1172 mouse_release (GtkWidget *invisible,
1173 GdkEventButton *event,
1176 GtkColorSelection *colorsel = data;
1177 ColorSelectionPrivate *priv;
1178 priv = colorsel->private_data;
1180 if (event->button != 1)
1183 grab_color_at_mouse (invisible, event->x_root, event->y_root, data);
1185 shutdown_eyedropper (GTK_WIDGET (data));
1187 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1188 GTK_SIGNAL_FUNC (mouse_motion), data);
1189 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1190 GTK_SIGNAL_FUNC (mouse_release), data);
1195 /* Helper Functions */
1197 static gboolean mouse_press (GtkWidget *invisible,
1198 GdkEventButton *event,
1202 key_press (GtkWidget *invisible,
1206 if (event->keyval == GDK_Escape)
1208 shutdown_eyedropper (data);
1210 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1211 GTK_SIGNAL_FUNC (mouse_press),
1213 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1214 GTK_SIGNAL_FUNC (key_press),
1224 mouse_press (GtkWidget *invisible,
1225 GdkEventButton *event,
1228 GtkColorSelection *colorsel = data;
1229 ColorSelectionPrivate *priv;
1230 priv = colorsel->private_data;
1232 if (event->type == GDK_BUTTON_PRESS &&
1235 gtk_signal_connect (GTK_OBJECT (invisible), "motion_notify_event",
1236 GTK_SIGNAL_FUNC (mouse_motion),
1238 gtk_signal_connect (GTK_OBJECT (invisible), "button_release_event",
1239 GTK_SIGNAL_FUNC (mouse_release),
1241 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1242 GTK_SIGNAL_FUNC (mouse_press),
1244 gtk_signal_disconnect_by_func (GTK_OBJECT (invisible),
1245 GTK_SIGNAL_FUNC (key_press),
1253 /* when the button is clicked */
1255 get_screen_color (GtkWidget *button)
1257 GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL");
1258 ColorSelectionPrivate *priv = colorsel->private_data;
1260 if (picker_cursor == NULL)
1262 initialize_cursor ();
1265 if (priv->dropper_grab_widget == NULL)
1267 priv->dropper_grab_widget = gtk_invisible_new ();
1269 gtk_widget_add_events (priv->dropper_grab_widget,
1270 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1272 gtk_widget_show (priv->dropper_grab_widget);
1275 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1277 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1279 g_warning ("Failed to grab keyboard to do eyedropper");
1283 if (gdk_pointer_grab (priv->dropper_grab_widget->window,
1285 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1288 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1290 gdk_keyboard_ungrab (GDK_CURRENT_TIME);
1291 g_warning ("Failed to grab pointer to do eyedropper");
1295 gtk_grab_add (priv->dropper_grab_widget);
1297 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "button_press_event",
1298 GTK_SIGNAL_FUNC (mouse_press), colorsel);
1299 gtk_signal_connect (GTK_OBJECT (priv->dropper_grab_widget), "key_press_event",
1300 GTK_SIGNAL_FUNC (key_press), colorsel);
1304 hex_changed (GtkWidget *hex_entry,
1307 GtkColorSelection *colorsel;
1308 ColorSelectionPrivate *priv;
1312 colorsel = GTK_COLOR_SELECTION (data);
1313 priv = colorsel->private_data;
1318 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1319 if (gdk_color_parse (text, &color))
1321 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1322 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1323 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1324 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1325 priv->color[COLORSEL_GREEN],
1326 priv->color[COLORSEL_BLUE],
1327 &priv->color[COLORSEL_HUE],
1328 &priv->color[COLORSEL_SATURATION],
1329 &priv->color[COLORSEL_VALUE]);
1330 update_color (colorsel);
1336 hsv_changed (GtkWidget *hsv,
1339 GtkColorSelection *colorsel;
1340 ColorSelectionPrivate *priv;
1342 colorsel = GTK_COLOR_SELECTION (data);
1343 priv = colorsel->private_data;
1348 gtk_hsv_get_color (GTK_HSV (hsv),
1349 &priv->color[COLORSEL_HUE],
1350 &priv->color[COLORSEL_SATURATION],
1351 &priv->color[COLORSEL_VALUE]);
1352 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1353 priv->color[COLORSEL_SATURATION],
1354 priv->color[COLORSEL_VALUE],
1355 &priv->color[COLORSEL_RED],
1356 &priv->color[COLORSEL_GREEN],
1357 &priv->color[COLORSEL_BLUE]);
1358 update_color (colorsel);
1362 adjustment_changed (GtkAdjustment *adjustment,
1365 GtkColorSelection *colorsel;
1366 ColorSelectionPrivate *priv;
1368 colorsel = GTK_COLOR_SELECTION (gtk_object_get_data (GTK_OBJECT (adjustment), "COLORSEL"));
1369 priv = colorsel->private_data;
1374 switch (GPOINTER_TO_INT (data))
1376 case COLORSEL_SATURATION:
1377 case COLORSEL_VALUE:
1378 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1379 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1380 priv->color[COLORSEL_SATURATION],
1381 priv->color[COLORSEL_VALUE],
1382 &priv->color[COLORSEL_RED],
1383 &priv->color[COLORSEL_GREEN],
1384 &priv->color[COLORSEL_BLUE]);
1387 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1388 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1389 priv->color[COLORSEL_SATURATION],
1390 priv->color[COLORSEL_VALUE],
1391 &priv->color[COLORSEL_RED],
1392 &priv->color[COLORSEL_GREEN],
1393 &priv->color[COLORSEL_BLUE]);
1396 case COLORSEL_GREEN:
1398 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1400 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1401 priv->color[COLORSEL_GREEN],
1402 priv->color[COLORSEL_BLUE],
1403 &priv->color[COLORSEL_HUE],
1404 &priv->color[COLORSEL_SATURATION],
1405 &priv->color[COLORSEL_VALUE]);
1408 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1411 update_color (colorsel);
1415 opacity_entry_changed (GtkWidget *opacity_entry,
1418 GtkColorSelection *colorsel;
1419 ColorSelectionPrivate *priv;
1423 colorsel = GTK_COLOR_SELECTION (data);
1424 priv = colorsel->private_data;
1429 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1430 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1431 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1433 update_color (colorsel);
1439 make_label_spinbutton (GtkColorSelection *colorsel,
1440 GtkWidget **spinbutton,
1446 const gchar *tooltip)
1449 GtkAdjustment *adjust;
1450 ColorSelectionPrivate *priv = colorsel->private_data;
1452 if (channel_type == COLORSEL_HUE)
1454 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1458 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1460 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1461 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1463 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1465 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1466 GTK_SIGNAL_FUNC (adjustment_changed),
1467 GINT_TO_POINTER (channel_type));
1468 label = gtk_label_new_with_mnemonic (text);
1469 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1471 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1472 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1473 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1478 make_palette_frame (GtkColorSelection *colorsel,
1484 ColorSelectionPrivate *priv;
1486 priv = colorsel->private_data;
1487 frame = gtk_frame_new (NULL);
1488 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1489 priv->custom_palette[i][j] = palette_new (colorsel);
1490 gtk_widget_set_usize (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1491 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1492 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1495 /* Set the palette entry [x][y] to be the currently selected one. */
1497 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1499 ColorSelectionPrivate *priv = colorsel->private_data;
1501 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1505 scale_round (double val, double factor)
1507 val = floor (val * factor + 0.5);
1509 val = MIN (val, factor);
1514 update_color (GtkColorSelection *colorsel)
1516 ColorSelectionPrivate *priv = colorsel->private_data;
1518 gchar opacity_text[32];
1521 priv->changing = TRUE;
1522 color_sample_draw_samples (colorsel);
1524 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1525 priv->color[COLORSEL_HUE],
1526 priv->color[COLORSEL_SATURATION],
1527 priv->color[COLORSEL_VALUE]);
1528 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1529 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1530 scale_round (priv->color[COLORSEL_HUE], 360));
1531 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1532 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1533 scale_round (priv->color[COLORSEL_SATURATION], 255));
1534 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1535 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1536 scale_round (priv->color[COLORSEL_VALUE], 255));
1537 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1538 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1539 scale_round (priv->color[COLORSEL_RED], 255));
1540 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1541 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1542 scale_round (priv->color[COLORSEL_GREEN], 255));
1543 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1544 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1545 scale_round (priv->color[COLORSEL_BLUE], 255));
1546 gtk_adjustment_set_value (gtk_range_get_adjustment
1547 (GTK_RANGE (priv->opacity_slider)),
1548 scale_round (priv->color[COLORSEL_OPACITY], 255));
1550 g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
1551 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1553 g_snprintf (entryval, 11, "#%2X%2X%2X",
1554 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1555 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1556 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1558 for (ptr = entryval; *ptr; ptr++)
1561 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1562 priv->changing = FALSE;
1564 g_object_freeze_notify (G_OBJECT (colorsel));
1565 g_object_notify (G_OBJECT (colorsel), "current_color");
1566 g_object_notify (G_OBJECT (colorsel), "current_alpha");
1567 g_object_thaw_notify (G_OBJECT (colorsel));
1572 fill_palette_from_string (const gchar *str)
1574 GdkColor *colors = NULL;
1580 if (!gtk_color_selection_palette_from_string (str, &colors, &n_colors))
1583 if (n_colors > (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
1584 n_colors = GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
1586 memcpy (current_colors, colors, sizeof (GdkColor) * n_colors);
1592 palette_change_notify_class (GObject *object,
1597 g_object_get (object, pspec->name, &str, NULL);
1599 fill_palette_from_string (str);
1605 update_palette (GtkColorSelection *colorsel)
1609 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1611 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1615 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1617 gtk_color_selection_set_palette_color (colorsel,
1619 ¤t_colors[index]);
1625 palette_change_notify_instance (GObject *object,
1629 update_palette (GTK_COLOR_SELECTION (data));
1633 default_change_palette_func (const GdkColor *colors,
1638 str = gtk_color_selection_palette_to_string (colors, n_colors);
1640 gtk_settings_set_string_property (gtk_settings_get_default (),
1641 "gtk-color-palette",
1643 "gtk_color_selection_palette_to_string");
1649 gtk_color_selection_get_type (void)
1651 static GtkType color_selection_type = 0;
1653 if (!color_selection_type)
1655 static const GtkTypeInfo color_selection_info =
1657 "GtkColorSelection",
1658 sizeof (GtkColorSelection),
1659 sizeof (GtkColorSelectionClass),
1660 (GtkClassInitFunc) gtk_color_selection_class_init,
1661 (GtkObjectInitFunc) gtk_color_selection_init,
1662 /* reserved_1 */ NULL,
1663 /* reserved_2 */ NULL,
1664 (GtkClassInitFunc) NULL,
1667 color_selection_type = gtk_type_unique (GTK_TYPE_VBOX, &color_selection_info);
1670 return color_selection_type;
1674 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1676 GtkObjectClass *object_class;
1677 GObjectClass *gobject_class;
1678 GtkWidgetClass *widget_class;
1680 object_class = GTK_OBJECT_CLASS (klass);
1681 gobject_class = G_OBJECT_CLASS (klass);
1682 widget_class = GTK_WIDGET_CLASS (klass);
1684 parent_class = gtk_type_class (GTK_TYPE_VBOX);
1686 object_class->destroy = gtk_color_selection_destroy;
1687 gobject_class->finalize = gtk_color_selection_finalize;
1689 gobject_class->set_property = gtk_color_selection_set_property;
1690 gobject_class->get_property = gtk_color_selection_get_property;
1692 widget_class->realize = gtk_color_selection_realize;
1694 g_object_class_install_property (gobject_class,
1695 PROP_HAS_OPACITY_CONTROL,
1696 g_param_spec_boolean ("has_opacity_control",
1697 _("Has Opacity Control"),
1698 _("Whether the color selector should allow setting opacity"),
1700 G_PARAM_READABLE | G_PARAM_WRITABLE));
1701 g_object_class_install_property (gobject_class,
1703 g_param_spec_boolean ("has_palette",
1705 _("Whether a palette should be used"),
1707 G_PARAM_READABLE | G_PARAM_WRITABLE));
1708 g_object_class_install_property (gobject_class,
1710 g_param_spec_boxed ("current_color",
1712 _("The current color"),
1714 G_PARAM_READABLE | G_PARAM_WRITABLE));
1715 g_object_class_install_property (gobject_class,
1717 g_param_spec_uint ("current_alpha",
1719 _("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1721 G_PARAM_READABLE | G_PARAM_WRITABLE));
1723 color_selection_signals[COLOR_CHANGED] =
1724 gtk_signal_new ("color_changed",
1726 GTK_CLASS_TYPE (object_class),
1727 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
1728 _gtk_marshal_VOID__VOID,
1731 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1732 _("Custom palette"),
1733 _("Palette to use in the color selector"),
1735 G_PARAM_READWRITE));
1738 /* widget functions */
1741 gtk_color_selection_init (GtkColorSelection *colorsel)
1743 GtkWidget *top_hbox;
1744 GtkWidget *top_right_vbox;
1745 GtkWidget *table, *label, *hbox, *frame, *vbox;
1746 GtkAdjustment *adjust;
1747 GdkPixmap *dropper_pixmap;
1748 GtkWidget *dropper_image;
1750 GdkBitmap *mask = NULL;
1752 ColorSelectionPrivate *priv;
1754 gtk_widget_push_composite_child ();
1756 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1757 priv->changing = FALSE;
1758 priv->default_set = FALSE;
1759 priv->default_alpha_set = FALSE;
1761 priv->tooltips = gtk_tooltips_new ();
1762 g_object_ref (priv->tooltips);
1763 gtk_object_sink (GTK_OBJECT (priv->tooltips));
1765 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1766 top_hbox = gtk_hbox_new (FALSE, 8);
1767 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1769 vbox = gtk_vbox_new (FALSE, 4);
1770 priv->triangle_colorsel = gtk_hsv_new ();
1771 gtk_signal_connect (GTK_OBJECT (priv->triangle_colorsel), "changed",
1772 GTK_SIGNAL_FUNC (hsv_changed), colorsel);
1773 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1774 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1775 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1776 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1777 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1779 hbox = gtk_hbox_new (FALSE, 4);
1780 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1782 frame = gtk_frame_new (NULL);
1783 gtk_widget_set_usize (frame, -1, 30);
1784 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1785 color_sample_new (colorsel);
1786 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1787 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1789 button = gtk_button_new ();
1791 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1792 gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel);
1793 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1794 GTK_SIGNAL_FUNC (get_screen_color), NULL);
1795 dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker);
1796 dropper_image = gtk_pixmap_new (dropper_pixmap, mask);
1797 gdk_pixmap_unref (dropper_pixmap);
1799 gdk_pixmap_unref (mask);
1800 gtk_container_add (GTK_CONTAINER (button), dropper_image);
1801 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1803 gtk_tooltips_set_tip (priv->tooltips,
1805 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1807 top_right_vbox = gtk_vbox_new (FALSE, 4);
1808 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1809 table = gtk_table_new (8, 6, FALSE);
1810 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1811 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1812 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1814 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1815 _("Position on the color wheel."));
1816 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1817 _("\"Deepness\" of the color."));
1818 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1819 _("Brightness of the color."));
1820 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1821 _("Amount of red light in the color."));
1822 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1823 _("Amount of green light in the color."));
1824 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1825 _("Amount of blue light in the color."));
1826 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1828 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1829 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1830 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1831 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1832 gtk_object_set_data (GTK_OBJECT (adjust), "COLORSEL", colorsel);
1833 priv->opacity_slider = gtk_hscale_new (adjust);
1834 gtk_tooltips_set_tip (priv->tooltips,
1835 priv->opacity_slider,
1836 _("Transparency of the currently-selected color."), NULL);
1837 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1838 priv->opacity_slider);
1839 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1840 gtk_signal_connect (GTK_OBJECT (adjust), "value_changed",
1841 GTK_SIGNAL_FUNC (adjustment_changed),
1842 GINT_TO_POINTER (COLORSEL_OPACITY));
1843 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1844 priv->opacity_entry = gtk_entry_new ();
1845 gtk_widget_set_usize (priv->opacity_entry, 40, 0);
1847 gtk_signal_connect (GTK_OBJECT (priv->opacity_entry), "activate",
1848 GTK_SIGNAL_FUNC (opacity_entry_changed), colorsel);
1849 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1851 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1852 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1853 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1854 priv->hex_entry = gtk_entry_new ();
1856 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1858 gtk_signal_connect (GTK_OBJECT (priv->hex_entry), "activate",
1859 GTK_SIGNAL_FUNC (hex_changed), colorsel);
1861 gtk_tooltips_set_tip (priv->tooltips,
1863 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1865 gtk_widget_set_usize (priv->hex_entry, 75, -1);
1866 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1867 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1869 /* Set up the palette */
1870 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1871 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1872 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1873 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1875 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1877 make_palette_frame (colorsel, table, i, j);
1880 set_selected_palette (colorsel, 0, 0);
1881 priv->palette_frame = gtk_frame_new (NULL);
1882 label = gtk_label_new_with_mnemonic (_("_Palette"));
1883 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1885 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1886 priv->custom_palette[0][0]);
1888 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1889 vbox = gtk_vbox_new (FALSE, 4);
1890 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1891 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1893 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1895 gtk_widget_show_all (top_hbox);
1897 /* hide unused stuff */
1899 if (priv->has_opacity == FALSE)
1901 gtk_widget_hide (priv->opacity_label);
1902 gtk_widget_hide (priv->opacity_slider);
1903 gtk_widget_hide (priv->opacity_entry);
1906 if (priv->has_palette == FALSE)
1908 gtk_widget_hide (priv->palette_frame);
1911 gtk_widget_pop_composite_child ();
1915 gtk_color_selection_destroy (GtkObject *object)
1917 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1918 ColorSelectionPrivate *priv = cselection->private_data;
1920 if (priv->dropper_grab_widget)
1922 gtk_widget_destroy (priv->dropper_grab_widget);
1923 priv->dropper_grab_widget = NULL;
1928 g_object_unref (priv->tooltips);
1929 priv->tooltips = NULL;
1932 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1936 gtk_color_selection_finalize (GObject *object)
1938 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1940 if (cselection->private_data)
1942 ColorSelectionPrivate *priv;
1944 priv = cselection->private_data;
1946 g_signal_handler_disconnect (gtk_settings_get_default (),
1947 priv->settings_connection);
1949 g_free (cselection->private_data);
1950 cselection->private_data = NULL;
1953 G_OBJECT_CLASS (parent_class)->finalize (object);
1957 gtk_color_selection_realize (GtkWidget *widget)
1959 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
1960 ColorSelectionPrivate *priv = colorsel->private_data;
1962 static gboolean initialized = FALSE;
1966 g_object_get (gtk_settings_get_default (),
1967 "gtk-color-palette", &palette,
1970 fill_palette_from_string (palette);
1973 g_signal_connect (gtk_settings_get_default (),
1974 "notify::gtk-color-palette",
1975 G_CALLBACK (palette_change_notify_class),
1981 /* Set default colors */
1983 update_palette (colorsel);
1984 priv->settings_connection =
1985 g_signal_connect (gtk_settings_get_default (),
1986 "notify::gtk-color-palette",
1987 G_CALLBACK (palette_change_notify_instance),
1990 if (GTK_WIDGET_CLASS (parent_class)->realize)
1991 GTK_WIDGET_CLASS (parent_class)->realize (widget);
1995 * gtk_color_selection_new:
1997 * Creates a new GtkColorSelection.
1999 * Return value: a new #GtkColorSelection
2002 gtk_color_selection_new (void)
2004 GtkColorSelection *colorsel;
2005 ColorSelectionPrivate *priv;
2012 colorsel = gtk_type_new (GTK_TYPE_COLOR_SELECTION);
2013 priv = colorsel->private_data;
2014 gtk_color_selection_set_color (colorsel, color);
2015 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
2017 /* We want to make sure that default_set is FALSE */
2018 /* This way the user can still set it */
2019 priv->default_set = FALSE;
2020 priv->default_alpha_set = FALSE;
2022 return GTK_WIDGET (colorsel);
2027 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
2028 GtkUpdateType policy)
2030 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2034 * gtk_color_selection_get_has_opacity_control:
2035 * @colorsel: a #GtkColorSelection.
2037 * Determines whether the colorsel has an opacity control.
2039 * Return value: %TRUE if the @colorsel has an opacity control. %FALSE if it does't.
2042 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2044 ColorSelectionPrivate *priv;
2046 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2048 priv = colorsel->private_data;
2050 return priv->has_opacity;
2054 * gtk_color_selection_set_has_opacity_control:
2055 * @colorsel: a #GtkColorSelection.
2056 * @has_opacity: %TRUE if @colorsel can set the opacity, %FALSE otherwise.
2058 * Sets the @colorsel to use or not use opacity.
2062 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2063 gboolean has_opacity)
2065 ColorSelectionPrivate *priv;
2067 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2069 priv = colorsel->private_data;
2070 has_opacity = has_opacity != FALSE;
2072 if (priv->has_opacity != has_opacity)
2074 priv->has_opacity = has_opacity;
2077 gtk_widget_show (priv->opacity_slider);
2078 gtk_widget_show (priv->opacity_label);
2079 gtk_widget_show (priv->opacity_entry);
2083 gtk_widget_hide (priv->opacity_slider);
2084 gtk_widget_hide (priv->opacity_label);
2085 gtk_widget_hide (priv->opacity_entry);
2087 color_sample_draw_samples (colorsel);
2089 g_object_notify (G_OBJECT (colorsel), "has_opacity_control");
2094 * gtk_color_selection_get_has_palette:
2095 * @colorsel: a #GtkColorSelection.
2097 * Determines whether the color selector has a color palette.
2099 * Return value: %TRUE if the selector has a palette. %FALSE if it hasn't.
2102 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2104 ColorSelectionPrivate *priv;
2106 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2108 priv = colorsel->private_data;
2110 return priv->has_palette;
2114 * gtk_color_selection_set_has_palette:
2115 * @colorsel: a #GtkColorSelection.
2116 * @has_palette: %TRUE if palette is to be visible, %FALSE otherwise.
2118 * Shows and hides the palette based upon the value of @has_palette.
2122 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2123 gboolean has_palette)
2125 ColorSelectionPrivate *priv;
2126 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2128 priv = colorsel->private_data;
2129 has_palette = has_palette != FALSE;
2131 if (priv->has_palette != has_palette)
2133 priv->has_palette = has_palette;
2135 gtk_widget_show (priv->palette_frame);
2137 gtk_widget_hide (priv->palette_frame);
2139 g_object_notify (G_OBJECT (colorsel), "has_palette");
2144 * gtk_color_selection_set_current_color:
2145 * @colorsel: a #GtkColorSelection.
2146 * @color: A #GdkColor to set the current color with.
2148 * Sets the current color to be @color. The first time this is called, it will
2149 * also set the original color to be @color too.
2152 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2155 ColorSelectionPrivate *priv;
2157 gboolean previous_changed;
2159 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2161 priv = colorsel->private_data;
2162 priv->changing = TRUE;
2163 priv->color[COLORSEL_RED] = SCALE (color->red);
2164 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2165 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2166 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2167 priv->color[COLORSEL_GREEN],
2168 priv->color[COLORSEL_BLUE],
2169 &priv->color[COLORSEL_HUE],
2170 &priv->color[COLORSEL_SATURATION],
2171 &priv->color[COLORSEL_VALUE]);
2172 if (priv->default_set == FALSE)
2174 previous_changed = TRUE;
2175 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2176 priv->old_color[i] = priv->color[i];
2178 update_color (colorsel);
2179 priv->default_set = TRUE;
2183 * gtk_color_selection_set_current_alpha:
2184 * @colorsel: a #GtkColorSelection.
2185 * @alpha: an integer between 0 and 65535.
2187 * Sets the current opacity to be @alpha. The first time this is called, it will
2188 * also set the original opacity to be @alpha too.
2191 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2194 ColorSelectionPrivate *priv;
2197 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2199 priv = colorsel->private_data;
2200 priv->changing = TRUE;
2201 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2202 if (priv->default_alpha_set == FALSE)
2204 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2205 priv->old_color[i] = priv->color[i];
2207 update_color (colorsel);
2208 priv->default_alpha_set = TRUE;
2212 * gtk_color_selection_set_color:
2213 * @colorsel: a #GtkColorSelection.
2214 * @color: an array of 4 doubles specifying the red, green, blue and opacity
2215 * to set the current color to.
2217 * Sets the current color to be @color. The first time this is called, it will
2218 * also set the original color to be @color too.
2220 * This function is deprecated, use gtk_color_selection_set_current_color() instead.
2223 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2226 ColorSelectionPrivate *priv;
2229 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2231 priv = colorsel->private_data;
2232 priv->changing = TRUE;
2233 priv->color[COLORSEL_RED] = color[0];
2234 priv->color[COLORSEL_GREEN] = color[1];
2235 priv->color[COLORSEL_BLUE] = color[2];
2236 priv->color[COLORSEL_OPACITY] = color[3];
2237 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2238 priv->color[COLORSEL_GREEN],
2239 priv->color[COLORSEL_BLUE],
2240 &priv->color[COLORSEL_HUE],
2241 &priv->color[COLORSEL_SATURATION],
2242 &priv->color[COLORSEL_VALUE]);
2243 if (priv->default_set == FALSE)
2245 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2246 priv->old_color[i] = priv->color[i];
2248 update_color (colorsel);
2249 priv->default_set = TRUE;
2250 priv->default_alpha_set = TRUE;
2254 * gtk_color_selection_get_current_color:
2255 * @colorsel: a #GtkColorSelection.
2256 * @color: a #GdkColor to fill in with the current color.
2258 * Sets @color to be the current color in the GtkColorSelection widget.
2261 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2264 ColorSelectionPrivate *priv;
2266 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2268 priv = colorsel->private_data;
2269 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2270 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2271 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2275 * gtk_color_selection_get_current_alpha:
2276 * @colorsel: a #GtkColorSelection.
2278 * Returns the current alpha value.
2280 * Return value: an integer between 0 and 65535.
2283 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2285 ColorSelectionPrivate *priv;
2287 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2289 priv = colorsel->private_data;
2290 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2294 * gtk_color_selection_get_color:
2295 * @colorsel: a #GtkColorSelection.
2296 * @color: an array of 4 #gdouble to fill in with the current color.
2298 * Sets @color to be the current color in the GtkColorSelection widget.
2300 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2303 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2306 ColorSelectionPrivate *priv;
2308 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2310 priv = colorsel->private_data;
2311 color[0] = priv->color[COLORSEL_RED];
2312 color[1] = priv->color[COLORSEL_GREEN];
2313 color[2] = priv->color[COLORSEL_BLUE];
2314 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2318 * gtk_color_selection_set_previous_color:
2319 * @colorsel: a #GtkColorSelection.
2320 * @color: a #GdkColor to set the previous color with.
2322 * Sets the 'previous' color to be @color. This function should be called with
2323 * some hesitations, as it might seem confusing to have that color change.
2324 * Calling gtk_color_selection_set_current_color() will also set this color the first
2325 * time it is called.
2328 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2331 ColorSelectionPrivate *priv;
2333 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2335 priv = colorsel->private_data;
2336 priv->changing = TRUE;
2337 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2338 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2339 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2340 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2341 priv->old_color[COLORSEL_GREEN],
2342 priv->old_color[COLORSEL_BLUE],
2343 &priv->old_color[COLORSEL_HUE],
2344 &priv->old_color[COLORSEL_SATURATION],
2345 &priv->old_color[COLORSEL_VALUE]);
2346 color_sample_draw_samples (colorsel);
2347 priv->default_set = TRUE;
2351 * gtk_color_selection_set_previous_alpha:
2352 * @colorsel: a #GtkColorSelection.
2353 * @alpha: an integer between 0 and 65535.
2355 * Sets the 'previous' alpha to be @alpha. This function should be called with
2356 * some hesitations, as it might seem confusing to have that alpha change.
2359 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2362 ColorSelectionPrivate *priv;
2364 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2366 priv = colorsel->private_data;
2367 priv->changing = TRUE;
2368 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2369 color_sample_draw_samples (colorsel);
2370 priv->default_alpha_set = TRUE;
2375 * gtk_color_selection_get_previous_color:
2376 * @colorsel: a #GtkColorSelection.
2377 * @color: a #GdkColor to fill in with the original color value.
2379 * Fills @color in with the original color value.
2382 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2385 ColorSelectionPrivate *priv;
2387 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2389 priv = colorsel->private_data;
2390 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2391 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2392 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2396 * gtk_color_selection_get_previous_alpha:
2397 * @colorsel: a #GtkColorSelection.
2399 * Returns the previous alpha value.
2401 * Return value: an integer between 0 and 65535.
2404 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2406 ColorSelectionPrivate *priv;
2408 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2410 priv = colorsel->private_data;
2411 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2415 * gtk_color_selection_set_palette_color:
2416 * @colorsel: a #GtkColorSelection.
2417 * @index: the color index of the palette.
2418 * @color: A #GdkColor to set the palette with.
2420 * Sets the palette located at @index to have @color as its color.
2424 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2428 ColorSelectionPrivate *priv;
2432 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2433 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2435 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2436 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2438 priv = colorsel->private_data;
2439 col[0] = SCALE (color->red);
2440 col[1] = SCALE (color->green);
2441 col[2] = SCALE (color->blue);
2443 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2447 * gtk_color_selection_get_palette_color:
2448 * @colorsel: a #GtkColorSelection.
2449 * @index: the color index of the palette.
2450 * @color: a #GdkColor to fill in with the color value.
2452 * Set @color to have the color found in the palette at @index. If
2453 * the palette is unset, it will leave the color unset.
2455 * Return value: %TRUE if the palette located at @index has a color set. %FALSE
2459 gtk_color_selection_get_palette_color (GtkColorSelection *colorsel,
2463 ColorSelectionPrivate *priv;
2467 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2468 g_return_val_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT, FALSE);
2470 priv = colorsel->private_data;
2472 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2473 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2475 if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (priv->custom_palette[x][y]), "color_set")) == 0)
2478 palette_get_color (priv->custom_palette[x][y], col);
2480 color->red = UNSCALE (col[0]);
2481 color->green = UNSCALE (col[1]);
2482 color->blue = UNSCALE (col[2]);
2488 * gtk_color_selection_unset_palette_color:
2489 * @colorsel: a #GtkColorSelection.
2490 * @index: the color index in the palette.
2492 * Changes the palette located @index to have no color set.
2495 gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
2498 ColorSelectionPrivate *priv;
2501 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2502 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2504 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2505 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2507 priv = colorsel->private_data;
2508 palette_unset_color (priv->custom_palette[x][y]);
2512 * gtk_color_selection_get_current_alpha:
2513 * @colorsel: a #GtkColorSelection.
2515 * Returns the maximum number of palette colors.
2517 * Return value: the maximum number of palette indexes.
2520 gtk_color_selection_get_palette_size (GtkColorSelection *colorsel)
2522 return GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT;
2527 * gtk_color_selection_is_adjusting:
2528 * @colorsel: a #GtkColorSelection.
2530 * Gets the current state of the @colorsel.
2532 * Return value: %TRUE if the user is currently dragging a color around, and %FALSE
2533 * if the selection has stopped.
2536 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2538 ColorSelectionPrivate *priv;
2540 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2542 priv = colorsel->private_data;
2544 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2548 gtk_color_selection_set_property (GObject *object,
2550 const GValue *value,
2553 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2557 case PROP_HAS_OPACITY_CONTROL:
2558 gtk_color_selection_set_has_opacity_control (colorsel,
2559 g_value_get_boolean (value));
2561 case PROP_HAS_PALETTE:
2562 gtk_color_selection_set_has_palette (colorsel,
2563 g_value_get_boolean (value));
2565 case PROP_CURRENT_COLOR:
2566 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2568 case PROP_CURRENT_ALPHA:
2569 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2572 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2579 gtk_color_selection_get_property (GObject *object,
2584 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2589 case PROP_HAS_OPACITY_CONTROL:
2590 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2592 case PROP_HAS_PALETTE:
2593 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2595 case PROP_CURRENT_COLOR:
2596 gtk_color_selection_get_current_color (colorsel, &color);
2597 g_value_set_boxed (value, &color);
2599 case PROP_CURRENT_ALPHA:
2600 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2603 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2610 * gtk_color_selection_palette_from_string:
2611 * @str: a string encoding a color palette.
2612 * @colors: return location for allocated array of #GdkColor.
2613 * @n_colors: return location for length of array.
2615 * Parses a color palette string; the string is a colon-separated
2616 * list of color names readable by gdk_color_parse().
2618 * Return value: %TRUE if a palette was successfully parsed.
2621 gtk_color_selection_palette_from_string (const gchar *str,
2633 copy = g_strdup (str);
2639 if (*p == ':' || *p == '\0')
2641 gboolean done = TRUE;
2645 goto failed; /* empty entry */
2654 retval = g_renew (GdkColor, retval, count + 1);
2655 if (!gdk_color_parse (start, retval + count))
2696 * gtk_color_selection_palette_to_string:
2697 * @colors: an array of colors.
2698 * @n_colors: length of the array.
2700 * Encodes a palette as a string, useful for persistent storage.
2702 * Return value: allocated string encoding the palette.
2705 gtk_color_selection_palette_to_string (const GdkColor *colors,
2709 gchar **strs = NULL;
2713 return g_strdup ("");
2715 strs = g_new0 (gchar*, n_colors + 1);
2718 while (i < n_colors)
2723 g_strdup_printf ("#%2X%2X%2X",
2724 colors[i].red / 256,
2725 colors[i].green / 256,
2726 colors[i].blue / 256);
2728 for (ptr = strs[i]; *ptr; ptr++)
2735 retval = g_strjoinv (":", strs);
2743 * gtk_color_selection_set_change_palette_hook:
2744 * @func: a function to call when the custom palette needs saving.
2746 * Installs a global function to be called whenever the user tries to
2747 * modify the palette in a color selection. This function should save
2748 * the new palette contents, and update the GtkSettings property
2749 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2751 * Return value: the previous change palette hook (that was replaced).
2753 GtkColorSelectionChangePaletteFunc
2754 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2756 GtkColorSelectionChangePaletteFunc old;
2758 old = change_palette_hook;
2760 change_palette_hook = func;