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"
44 #include "gtkmarshalers.h"
46 #include "gtkspinbutton.h"
48 #include "gtkhscale.h"
50 #include "gtkbutton.h"
51 #include "gtkhseparator.h"
52 #include "gtktooltips.h"
53 #include "gtkinvisible.h"
54 #include "gtkmenuitem.h"
56 #include "gtksettings.h"
63 /* Number of elements in the custom palatte */
64 #define GTK_CUSTOM_PALETTE_WIDTH 10
65 #define GTK_CUSTOM_PALETTE_HEIGHT 2
67 /* Conversion between 0->1 double and and guint16. See
68 * scale_round() below for more general conversions
70 #define SCALE(i) (i / 65535.)
71 #define UNSCALE(d) ((guint16)(d * 65535 + 0.5))
82 PROP_HAS_OPACITY_CONTROL,
98 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
100 struct _ColorSelectionPrivate
102 guint has_opacity : 1;
103 guint has_palette : 1;
105 guint default_set : 1;
106 guint default_alpha_set : 1;
108 gdouble color[COLORSEL_NUM_CHANNELS];
109 gdouble old_color[COLORSEL_NUM_CHANNELS];
111 GtkWidget *triangle_colorsel;
112 GtkWidget *hue_spinbutton;
113 GtkWidget *sat_spinbutton;
114 GtkWidget *val_spinbutton;
115 GtkWidget *red_spinbutton;
116 GtkWidget *green_spinbutton;
117 GtkWidget *blue_spinbutton;
118 GtkWidget *opacity_slider;
119 GtkWidget *opacity_label;
120 GtkWidget *opacity_entry;
121 GtkWidget *palette_frame;
122 GtkWidget *hex_entry;
124 /* The Palette code */
125 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
127 /* The color_sample stuff */
128 GtkWidget *sample_area;
129 GtkWidget *old_sample;
130 GtkWidget *cur_sample;
134 GtkTooltips *tooltips;
136 /* Window for grabbing on */
137 GtkWidget *dropper_grab_widget;
139 /* Connection to settings */
140 gulong settings_connection;
144 static void gtk_color_selection_init (GtkColorSelection *colorsel);
145 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
146 static void gtk_color_selection_destroy (GtkObject *object);
147 static void gtk_color_selection_finalize (GObject *object);
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 void gtk_color_selection_realize (GtkWidget *widget);
159 static void gtk_color_selection_unrealize (GtkWidget *widget);
160 static void gtk_color_selection_show_all (GtkWidget *widget);
162 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
165 static GdkGC *get_focus_gc (GtkWidget *drawing_area,
167 static void default_noscreen_change_palette_func (const GdkColor *colors,
169 static void default_change_palette_func (GdkScreen *screen,
170 const GdkColor *colors,
173 static gpointer parent_class = NULL;
174 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
176 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";
178 static GtkColorSelectionChangePaletteFunc noscreen_change_palette_hook = default_noscreen_change_palette_func;
179 static GtkColorSelectionChangePaletteWithScreenFunc change_palette_hook = default_change_palette_func;
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 const guchar 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 const guchar 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,
208 #define SAMPLE_WIDTH 64
209 #define SAMPLE_HEIGHT 28
211 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
212 static void color_sample_draw_samples (GtkColorSelection *colorsel);
215 set_color_internal (GtkColorSelection *colorsel,
218 ColorSelectionPrivate *priv;
221 priv = colorsel->private_data;
222 priv->changing = TRUE;
223 priv->color[COLORSEL_RED] = color[0];
224 priv->color[COLORSEL_GREEN] = color[1];
225 priv->color[COLORSEL_BLUE] = color[2];
226 priv->color[COLORSEL_OPACITY] = color[3];
227 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
228 priv->color[COLORSEL_GREEN],
229 priv->color[COLORSEL_BLUE],
230 &priv->color[COLORSEL_HUE],
231 &priv->color[COLORSEL_SATURATION],
232 &priv->color[COLORSEL_VALUE]);
233 if (priv->default_set == FALSE)
235 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
236 priv->old_color[i] = priv->color[i];
238 priv->default_set = TRUE;
239 priv->default_alpha_set = TRUE;
240 update_color (colorsel);
244 set_color_icon (GdkDragContext *context,
250 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
253 pixel = (((UNSCALE (colors[COLORSEL_RED]) & 0xff00) << 16) |
254 ((UNSCALE (colors[COLORSEL_GREEN]) & 0xff00) << 8) |
255 ((UNSCALE (colors[COLORSEL_BLUE]) & 0xff00)));
257 gdk_pixbuf_fill (pixbuf, pixel);
259 gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
260 g_object_unref (pixbuf);
264 color_sample_drag_begin (GtkWidget *widget,
265 GdkDragContext *context,
268 GtkColorSelection *colorsel = data;
269 ColorSelectionPrivate *priv;
272 priv = colorsel->private_data;
274 if (widget == priv->old_sample)
275 colsrc = priv->old_color;
277 colsrc = priv->color;
279 set_color_icon (context, colsrc);
283 color_sample_drag_end (GtkWidget *widget,
284 GdkDragContext *context,
287 g_object_set_data (G_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
291 color_sample_drop_handle (GtkWidget *widget,
292 GdkDragContext *context,
295 GtkSelectionData *selection_data,
300 GtkColorSelection *colorsel = data;
301 ColorSelectionPrivate *priv;
304 priv = colorsel->private_data;
306 /* This is currently a guint16 array of the format:
313 if (selection_data->length < 0)
316 if ((selection_data->format != 16) ||
317 (selection_data->length != 8))
319 g_warning ("Received invalid color data\n");
323 vals = (guint16 *)selection_data->data;
325 if (widget == priv->cur_sample)
327 color[0] = (gdouble)vals[0] / 0xffff;
328 color[1] = (gdouble)vals[1] / 0xffff;
329 color[2] = (gdouble)vals[2] / 0xffff;
330 color[3] = (gdouble)vals[3] / 0xffff;
332 set_color_internal (colorsel, color);
337 color_sample_drag_handle (GtkWidget *widget,
338 GdkDragContext *context,
339 GtkSelectionData *selection_data,
344 GtkColorSelection *colorsel = data;
345 ColorSelectionPrivate *priv;
349 priv = colorsel->private_data;
351 if (widget == priv->old_sample)
352 colsrc = priv->old_color;
354 colsrc = priv->color;
356 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
357 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
358 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
359 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
361 gtk_selection_data_set (selection_data,
362 gdk_atom_intern ("application/x-color", FALSE),
363 16, (guchar *)vals, 8);
366 /* which = 0 means draw old sample, which = 1 means draw new */
368 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
371 gint x, y, i, wid, heig, f, n, goff;
372 guchar c[3 * 2], cc[3 * 4], *cp = c;
375 ColorSelectionPrivate *priv;
377 g_return_if_fail (colorsel != NULL);
378 priv = colorsel->private_data;
380 g_return_if_fail (priv->sample_area != NULL);
381 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
386 da = priv->old_sample;
387 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
388 c[n] = (guchar) (UNSCALE (priv->old_color[i]) >> 8);
393 da = priv->cur_sample;
394 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
395 c[n] = (guchar) (UNSCALE (priv->color[i]) >> 8);
396 goff = priv->old_sample->allocation.width % 32;
399 wid = da->allocation.width;
400 heig = da->allocation.height;
402 buf = g_new (guchar, 3 * wid * heig);
406 for (n = 0; n < 3; n++)
408 c[n] = (guchar) (255.0 * priv->old_color[i]);
409 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
413 if (priv->has_opacity)
415 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
417 for (n = 0; n < 3; n++)
419 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
420 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
426 for (y = 0; y < heig; y++)
428 for (x = 0; x < wid; x++)
430 if (priv->has_opacity)
431 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
435 for (n = 0; n < 3; n++)
436 buf[i++] = cp[n + f];
440 gdk_draw_rgb_image (da->window,
444 GDK_RGB_DITHER_NORMAL,
454 color_sample_draw_samples (GtkColorSelection *colorsel)
456 color_sample_draw_sample (colorsel, 0);
457 color_sample_draw_sample (colorsel, 1);
461 color_old_sample_expose (GtkWidget *da,
462 GdkEventExpose *event,
463 GtkColorSelection *colorsel)
465 color_sample_draw_sample (colorsel, 0);
471 color_cur_sample_expose (GtkWidget *da,
472 GdkEventExpose *event,
473 GtkColorSelection *colorsel)
475 color_sample_draw_sample (colorsel, 1);
480 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
482 static const GtkTargetEntry targets[] = {
483 { "application/x-color", 0 }
485 ColorSelectionPrivate *priv;
486 priv = colorsel->private_data;
488 gtk_drag_source_set (sample,
489 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
491 GDK_ACTION_COPY | GDK_ACTION_MOVE);
493 g_signal_connect (sample,
495 G_CALLBACK (color_sample_drag_begin),
497 if (sample == priv->cur_sample)
500 gtk_drag_dest_set (sample,
501 GTK_DEST_DEFAULT_HIGHLIGHT |
502 GTK_DEST_DEFAULT_MOTION |
503 GTK_DEST_DEFAULT_DROP,
507 g_signal_connect (sample,
509 G_CALLBACK (color_sample_drag_end),
513 g_signal_connect (sample,
515 G_CALLBACK (color_sample_drag_handle),
517 g_signal_connect (sample,
518 "drag_data_received",
519 G_CALLBACK (color_sample_drop_handle),
526 color_sample_new (GtkColorSelection *colorsel)
528 ColorSelectionPrivate *priv;
530 priv = colorsel->private_data;
532 priv->sample_area = gtk_hbox_new (FALSE, 0);
533 priv->old_sample = gtk_drawing_area_new ();
534 priv->cur_sample = gtk_drawing_area_new ();
536 /* We need enter/leave to do tooltips */
537 gtk_widget_add_events (priv->old_sample,
538 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
539 gtk_widget_add_events (priv->cur_sample,
540 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
542 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
544 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
547 g_signal_connect (priv->old_sample, "expose_event",
548 G_CALLBACK (color_old_sample_expose),
550 g_signal_connect (priv->cur_sample, "expose_event",
551 G_CALLBACK (color_cur_sample_expose),
554 color_sample_setup_dnd (colorsel, priv->old_sample);
555 color_sample_setup_dnd (colorsel, priv->cur_sample);
557 gtk_tooltips_set_tip (priv->tooltips,
559 _("The previously-selected color, for comparison to the color you're selecting now. You can drag this color to a palette entry, or select this color as current by dragging it to the other color swatch alongside."), NULL);
562 gtk_tooltips_set_tip (priv->tooltips,
564 _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL);
566 gtk_widget_show_all (priv->sample_area);
572 * The palette area code
575 #define CUSTOM_PALETTE_ENTRY_WIDTH 20
576 #define CUSTOM_PALETTE_ENTRY_HEIGHT 20
579 palette_get_color (GtkWidget *drawing_area, gdouble *color)
583 g_return_if_fail (color != NULL);
585 color_val = g_object_get_data (G_OBJECT (drawing_area), "color_val");
586 if (color_val == NULL)
588 /* Default to white for no good reason */
596 color[0] = color_val[0];
597 color[1] = color_val[1];
598 color[2] = color_val[2];
602 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
604 palette_paint (GtkWidget *drawing_area,
608 if (drawing_area->window == NULL)
611 gdk_window_clear_area (drawing_area->window,
617 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
620 GdkGC *gc = get_focus_gc (drawing_area, &focus_width);
621 gdk_draw_rectangle (drawing_area->window,
622 gc, FALSE, focus_width / 2, focus_width / 2,
623 drawing_area->allocation.width - focus_width,
624 drawing_area->allocation.height - focus_width);
630 get_focus_gc (GtkWidget *drawing_area,
633 GdkGC *gc = gdk_gc_new (drawing_area->window);
637 gtk_widget_style_get (drawing_area,
638 "focus-line-width", focus_width,
639 "focus-line-pattern", (gchar *)&dash_list,
642 palette_get_color (drawing_area, color);
644 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
645 gdk_gc_copy (gc, drawing_area->style->black_gc);
647 gdk_gc_copy (gc, drawing_area->style->white_gc);
649 gdk_gc_set_line_attributes (gc, *focus_width,
650 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
651 GDK_CAP_BUTT, GDK_JOIN_MITER);
654 gdk_gc_set_dashes (gc, 0, dash_list, strlen ((char *)dash_list));
662 palette_drag_begin (GtkWidget *widget,
663 GdkDragContext *context,
668 palette_get_color (widget, colors);
669 set_color_icon (context, colors);
673 palette_drag_handle (GtkWidget *widget,
674 GdkDragContext *context,
675 GtkSelectionData *selection_data,
683 palette_get_color (widget, colsrc);
685 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
686 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
687 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
690 gtk_selection_data_set (selection_data,
691 gdk_atom_intern ("application/x-color", FALSE),
692 16, (guchar *)vals, 8);
696 palette_drag_end (GtkWidget *widget,
697 GdkDragContext *context,
700 g_object_set_data (G_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
704 get_current_colors (GtkColorSelection *colorsel)
706 GtkSettings *settings;
707 GdkColor *colors = NULL;
711 settings = gtk_widget_get_settings (GTK_WIDGET (colorsel));
712 g_object_get (G_OBJECT (settings),
713 "gtk-color-palette", &palette,
716 if (!gtk_color_selection_palette_from_string (palette, &colors, &n_colors))
718 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
722 /* If there are less colors provided than the number of slots in the
723 * color selection, we fill in the rest from the defaults.
725 if (n_colors < (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
727 GdkColor *tmp_colors = colors;
728 gint tmp_n_colors = n_colors;
730 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
731 memcpy (colors, tmp_colors, sizeof (GdkColor) * tmp_n_colors);
737 g_assert (n_colors >= GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
743 /* Changes the model color */
745 palette_change_color (GtkWidget *drawing_area,
746 GtkColorSelection *colorsel,
750 ColorSelectionPrivate *priv;
752 GdkColor *current_colors;
755 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
756 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
758 priv = colorsel->private_data;
760 gdk_color.red = UNSCALE (color[0]);
761 gdk_color.green = UNSCALE (color[1]);
762 gdk_color.blue = UNSCALE (color[2]);
765 y = 0; /* Quiet GCC */
766 while (x < GTK_CUSTOM_PALETTE_WIDTH)
769 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
771 if (priv->custom_palette[x][y] == drawing_area)
782 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
784 current_colors = get_current_colors (colorsel);
785 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
787 screen = gtk_widget_get_screen (GTK_WIDGET (colorsel));
788 if (change_palette_hook != default_change_palette_func)
789 (* change_palette_hook) (screen, current_colors,
790 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
791 else if (noscreen_change_palette_hook != default_noscreen_change_palette_func)
793 if (screen != gdk_screen_get_default ())
794 g_warning ("gtk_color_selection_set_change_palette_hook used by widget is not on the default screen.");
795 (* noscreen_change_palette_hook) (current_colors,
796 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
799 (* change_palette_hook) (screen, current_colors,
800 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
802 g_free (current_colors);
805 /* Changes the view color */
807 palette_set_color (GtkWidget *drawing_area,
808 GtkColorSelection *colorsel,
811 gdouble *new_color = g_new (double, 4);
814 gdk_color.red = UNSCALE (color[0]);
815 gdk_color.green = UNSCALE (color[1]);
816 gdk_color.blue = UNSCALE (color[2]);
818 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
820 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) == 0)
822 static const GtkTargetEntry targets[] = {
823 { "application/x-color", 0 }
825 gtk_drag_source_set (drawing_area,
826 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
828 GDK_ACTION_COPY | GDK_ACTION_MOVE);
830 g_signal_connect (drawing_area,
832 G_CALLBACK (palette_drag_begin),
834 g_signal_connect (drawing_area,
836 G_CALLBACK (palette_drag_handle),
839 g_object_set_data (G_OBJECT (drawing_area), "color_set",
840 GINT_TO_POINTER (1));
843 new_color[0] = color[0];
844 new_color[1] = color[1];
845 new_color[2] = color[2];
848 g_object_set_data_full (G_OBJECT (drawing_area), "color_val", new_color, (GDestroyNotify)g_free);
852 palette_expose (GtkWidget *drawing_area,
853 GdkEventExpose *event,
856 if (drawing_area->window == NULL)
859 palette_paint (drawing_area, &(event->area), data);
865 popup_position_func (GtkMenu *menu,
876 widget = GTK_WIDGET (user_data);
878 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
880 gdk_window_get_origin (widget->window, &root_x, &root_y);
882 gtk_widget_size_request (GTK_WIDGET (menu), &req);
884 /* Put corner of menu centered on color cell */
885 *x = root_x + widget->allocation.width / 2;
886 *y = root_y + widget->allocation.height / 2;
889 screen = gtk_widget_get_screen (widget);
890 *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
891 *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
895 save_color_selected (GtkWidget *menuitem,
898 GtkColorSelection *colorsel;
899 GtkWidget *drawing_area;
900 ColorSelectionPrivate *priv;
902 drawing_area = GTK_WIDGET (data);
904 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
907 priv = colorsel->private_data;
909 palette_change_color (drawing_area, colorsel, priv->color);
913 do_popup (GtkColorSelection *colorsel,
914 GtkWidget *drawing_area,
920 g_object_set_data (G_OBJECT (drawing_area),
924 menu = gtk_menu_new ();
926 mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
928 g_signal_connect (mi, "activate",
929 G_CALLBACK (save_color_selected),
932 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
934 gtk_widget_show_all (mi);
936 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
937 popup_position_func, drawing_area,
943 palette_enter (GtkWidget *drawing_area,
944 GdkEventCrossing *event,
947 g_object_set_data (G_OBJECT (drawing_area),
948 "gtk-colorsel-have-pointer",
949 GUINT_TO_POINTER (TRUE));
955 palette_leave (GtkWidget *drawing_area,
956 GdkEventCrossing *event,
959 g_object_set_data (G_OBJECT (drawing_area),
960 "gtk-colorsel-have-pointer",
967 palette_press (GtkWidget *drawing_area,
968 GdkEventButton *event,
971 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
973 gtk_widget_grab_focus (drawing_area);
975 if (event->button == 3 &&
976 event->type == GDK_BUTTON_PRESS)
978 do_popup (colorsel, drawing_area, event->time);
986 palette_release (GtkWidget *drawing_area,
987 GdkEventButton *event,
990 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
992 gtk_widget_grab_focus (drawing_area);
994 if (event->button == 1 &&
995 g_object_get_data (G_OBJECT (drawing_area),
996 "gtk-colorsel-have-pointer") != NULL)
998 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) != 0)
1001 palette_get_color (drawing_area, color);
1002 set_color_internal (colorsel, color);
1010 palette_drop_handle (GtkWidget *widget,
1011 GdkDragContext *context,
1014 GtkSelectionData *selection_data,
1019 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1023 if (selection_data->length < 0)
1026 if ((selection_data->format != 16) ||
1027 (selection_data->length != 8))
1029 g_warning ("Received invalid color data\n");
1033 vals = (guint16 *)selection_data->data;
1035 color[0] = (gdouble)vals[0] / 0xffff;
1036 color[1] = (gdouble)vals[1] / 0xffff;
1037 color[2] = (gdouble)vals[2] / 0xffff;
1038 color[3] = (gdouble)vals[3] / 0xffff;
1039 palette_change_color (widget, colorsel, color);
1040 set_color_internal (colorsel, color);
1044 palette_activate (GtkWidget *widget,
1048 /* should have a drawing area subclass with an activate signal */
1049 if ((event->keyval == GDK_space) ||
1050 (event->keyval == GDK_Return) ||
1051 (event->keyval == GDK_KP_Enter) ||
1052 (event->keyval == GDK_KP_Space))
1054 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "color_set")) != 0)
1057 palette_get_color (widget, color);
1058 set_color_internal (GTK_COLOR_SELECTION (data), color);
1067 palette_popup (GtkWidget *widget,
1070 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1072 do_popup (colorsel, widget, GDK_CURRENT_TIME);
1078 palette_new (GtkColorSelection *colorsel)
1081 ColorSelectionPrivate *priv;
1083 static const GtkTargetEntry targets[] = {
1084 { "application/x-color", 0 }
1087 priv = colorsel->private_data;
1089 retval = gtk_drawing_area_new ();
1091 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1093 g_object_set_data (G_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
1094 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1095 | GDK_BUTTON_RELEASE_MASK
1097 | GDK_ENTER_NOTIFY_MASK
1098 | GDK_LEAVE_NOTIFY_MASK);
1100 g_signal_connect (retval, "expose_event",
1101 G_CALLBACK (palette_expose), colorsel);
1102 g_signal_connect (retval, "button_press_event",
1103 G_CALLBACK (palette_press), colorsel);
1104 g_signal_connect (retval, "button_release_event",
1105 G_CALLBACK (palette_release), colorsel);
1106 g_signal_connect (retval, "enter_notify_event",
1107 G_CALLBACK (palette_enter), colorsel);
1108 g_signal_connect (retval, "leave_notify_event",
1109 G_CALLBACK (palette_leave), colorsel);
1110 g_signal_connect (retval, "key_press_event",
1111 G_CALLBACK (palette_activate), colorsel);
1112 g_signal_connect (retval, "popup_menu",
1113 G_CALLBACK (palette_popup), colorsel);
1115 gtk_drag_dest_set (retval,
1116 GTK_DEST_DEFAULT_HIGHLIGHT |
1117 GTK_DEST_DEFAULT_MOTION |
1118 GTK_DEST_DEFAULT_DROP,
1122 g_signal_connect (retval, "drag_end",
1123 G_CALLBACK (palette_drag_end), NULL);
1124 g_signal_connect (retval, "drag_data_received",
1125 G_CALLBACK (palette_drop_handle), colorsel);
1127 gtk_tooltips_set_tip (priv->tooltips,
1129 _("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.\""),
1137 * The actual GtkColorSelection widget
1142 make_picker_cursor (GdkScreen *screen)
1145 GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
1146 GdkColor fg = { 0, 0x0000, 0x0000, 0x0000 };
1147 GdkWindow *window = gdk_screen_get_root_window (screen);
1150 gdk_bitmap_create_from_data (window, (gchar *) dropper_bits,
1151 DROPPER_WIDTH, DROPPER_HEIGHT);
1154 gdk_bitmap_create_from_data (window, (gchar *) dropper_mask,
1155 DROPPER_WIDTH, DROPPER_HEIGHT);
1157 cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg,
1158 DROPPER_X_HOT, DROPPER_Y_HOT);
1160 g_object_unref (pixmap);
1161 g_object_unref (mask);
1167 grab_color_at_mouse (GdkScreen *screen,
1174 GtkColorSelection *colorsel = data;
1175 ColorSelectionPrivate *priv;
1177 GdkColormap *colormap = gdk_screen_get_system_colormap (screen);
1178 GdkWindow *root_window = gdk_screen_get_root_window (screen);
1180 priv = colorsel->private_data;
1182 image = gdk_drawable_get_image (root_window, x_root, y_root, 1, 1);
1183 pixel = gdk_image_get_pixel (image, 0, 0);
1184 g_object_unref (image);
1186 gdk_colormap_query_color (colormap, pixel, &color);
1188 priv->color[COLORSEL_RED] = SCALE (color.red);
1189 priv->color[COLORSEL_GREEN] = SCALE (color.green);
1190 priv->color[COLORSEL_BLUE] = SCALE (color.blue);
1192 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1193 priv->color[COLORSEL_GREEN],
1194 priv->color[COLORSEL_BLUE],
1195 &priv->color[COLORSEL_HUE],
1196 &priv->color[COLORSEL_SATURATION],
1197 &priv->color[COLORSEL_VALUE]);
1199 update_color (colorsel);
1203 shutdown_eyedropper (GtkWidget *widget)
1205 GtkColorSelection *colorsel;
1206 ColorSelectionPrivate *priv;
1207 GdkDisplay *display = gtk_widget_get_display (widget);
1208 guint32 time = gtk_get_current_event_time ();
1210 colorsel = GTK_COLOR_SELECTION (widget);
1211 priv = colorsel->private_data;
1213 gdk_display_keyboard_ungrab (display, time);
1214 gdk_display_pointer_ungrab (display, time);
1215 gtk_grab_remove (priv->dropper_grab_widget);
1219 mouse_motion (GtkWidget *invisible,
1220 GdkEventMotion *event,
1223 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1224 event->x_root, event->y_root, data);
1228 mouse_release (GtkWidget *invisible,
1229 GdkEventButton *event,
1232 GtkColorSelection *colorsel = data;
1233 ColorSelectionPrivate *priv;
1234 priv = colorsel->private_data;
1236 if (event->button != 1)
1239 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1240 event->x_root, event->y_root, data);
1242 shutdown_eyedropper (GTK_WIDGET (data));
1244 g_signal_handlers_disconnect_by_func (invisible,
1247 g_signal_handlers_disconnect_by_func (invisible,
1254 /* Helper Functions */
1256 static gboolean mouse_press (GtkWidget *invisible,
1257 GdkEventButton *event,
1261 key_press (GtkWidget *invisible,
1265 if (event->keyval == GDK_Escape)
1267 shutdown_eyedropper (data);
1269 g_signal_handlers_disconnect_by_func (invisible,
1272 g_signal_handlers_disconnect_by_func (invisible,
1283 mouse_press (GtkWidget *invisible,
1284 GdkEventButton *event,
1287 GtkColorSelection *colorsel = data;
1288 ColorSelectionPrivate *priv;
1289 priv = colorsel->private_data;
1291 if (event->type == GDK_BUTTON_PRESS &&
1294 g_signal_connect (invisible, "motion_notify_event",
1295 G_CALLBACK (mouse_motion),
1297 g_signal_connect (invisible, "button_release_event",
1298 G_CALLBACK (mouse_release),
1300 g_signal_handlers_disconnect_by_func (invisible,
1303 g_signal_handlers_disconnect_by_func (invisible,
1312 /* when the button is clicked */
1314 get_screen_color (GtkWidget *button)
1316 GtkColorSelection *colorsel = g_object_get_data (G_OBJECT (button), "COLORSEL");
1317 ColorSelectionPrivate *priv = colorsel->private_data;
1318 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (button));
1319 GdkCursor *picker_cursor;
1320 GdkGrabStatus grab_status;
1322 if (priv->dropper_grab_widget == NULL)
1324 priv->dropper_grab_widget = gtk_invisible_new_for_screen (screen);
1326 gtk_widget_add_events (priv->dropper_grab_widget,
1327 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1329 gtk_widget_show (priv->dropper_grab_widget);
1332 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1334 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1337 picker_cursor = make_picker_cursor (screen);
1338 grab_status = gdk_pointer_grab (priv->dropper_grab_widget->window,
1340 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1343 gtk_get_current_event_time ());
1344 gdk_cursor_unref (picker_cursor);
1346 if (grab_status != GDK_GRAB_SUCCESS)
1348 gdk_display_keyboard_ungrab (gtk_widget_get_display (button), GDK_CURRENT_TIME);
1352 gtk_grab_add (priv->dropper_grab_widget);
1354 g_signal_connect (priv->dropper_grab_widget, "button_press_event",
1355 G_CALLBACK (mouse_press), colorsel);
1356 g_signal_connect (priv->dropper_grab_widget, "key_press_event",
1357 G_CALLBACK (key_press), colorsel);
1361 hex_changed (GtkWidget *hex_entry,
1364 GtkColorSelection *colorsel;
1365 ColorSelectionPrivate *priv;
1369 colorsel = GTK_COLOR_SELECTION (data);
1370 priv = colorsel->private_data;
1375 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1376 if (gdk_color_parse (text, &color))
1378 priv->color[COLORSEL_RED] = CLAMP (color.red/65280.0, 0.0, 1.0);
1379 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65280.0, 0.0, 1.0);
1380 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65280.0, 0.0, 1.0);
1381 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1382 priv->color[COLORSEL_GREEN],
1383 priv->color[COLORSEL_BLUE],
1384 &priv->color[COLORSEL_HUE],
1385 &priv->color[COLORSEL_SATURATION],
1386 &priv->color[COLORSEL_VALUE]);
1387 update_color (colorsel);
1393 hsv_changed (GtkWidget *hsv,
1396 GtkColorSelection *colorsel;
1397 ColorSelectionPrivate *priv;
1399 colorsel = GTK_COLOR_SELECTION (data);
1400 priv = colorsel->private_data;
1405 gtk_hsv_get_color (GTK_HSV (hsv),
1406 &priv->color[COLORSEL_HUE],
1407 &priv->color[COLORSEL_SATURATION],
1408 &priv->color[COLORSEL_VALUE]);
1409 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1410 priv->color[COLORSEL_SATURATION],
1411 priv->color[COLORSEL_VALUE],
1412 &priv->color[COLORSEL_RED],
1413 &priv->color[COLORSEL_GREEN],
1414 &priv->color[COLORSEL_BLUE]);
1415 update_color (colorsel);
1419 adjustment_changed (GtkAdjustment *adjustment,
1422 GtkColorSelection *colorsel;
1423 ColorSelectionPrivate *priv;
1425 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (adjustment), "COLORSEL"));
1426 priv = colorsel->private_data;
1431 switch (GPOINTER_TO_INT (data))
1433 case COLORSEL_SATURATION:
1434 case COLORSEL_VALUE:
1435 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1436 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1437 priv->color[COLORSEL_SATURATION],
1438 priv->color[COLORSEL_VALUE],
1439 &priv->color[COLORSEL_RED],
1440 &priv->color[COLORSEL_GREEN],
1441 &priv->color[COLORSEL_BLUE]);
1444 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1445 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1446 priv->color[COLORSEL_SATURATION],
1447 priv->color[COLORSEL_VALUE],
1448 &priv->color[COLORSEL_RED],
1449 &priv->color[COLORSEL_GREEN],
1450 &priv->color[COLORSEL_BLUE]);
1453 case COLORSEL_GREEN:
1455 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1457 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1458 priv->color[COLORSEL_GREEN],
1459 priv->color[COLORSEL_BLUE],
1460 &priv->color[COLORSEL_HUE],
1461 &priv->color[COLORSEL_SATURATION],
1462 &priv->color[COLORSEL_VALUE]);
1465 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1468 update_color (colorsel);
1472 opacity_entry_changed (GtkWidget *opacity_entry,
1475 GtkColorSelection *colorsel;
1476 ColorSelectionPrivate *priv;
1480 colorsel = GTK_COLOR_SELECTION (data);
1481 priv = colorsel->private_data;
1486 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1487 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1488 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1490 update_color (colorsel);
1496 make_label_spinbutton (GtkColorSelection *colorsel,
1497 GtkWidget **spinbutton,
1503 const gchar *tooltip)
1506 GtkAdjustment *adjust;
1507 ColorSelectionPrivate *priv = colorsel->private_data;
1509 if (channel_type == COLORSEL_HUE)
1511 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1515 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1517 g_object_set_data (G_OBJECT (adjust), "COLORSEL", colorsel);
1518 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1520 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1522 g_signal_connect (adjust, "value_changed",
1523 G_CALLBACK (adjustment_changed),
1524 GINT_TO_POINTER (channel_type));
1525 label = gtk_label_new_with_mnemonic (text);
1526 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1528 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1529 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1530 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1534 make_palette_frame (GtkColorSelection *colorsel,
1540 ColorSelectionPrivate *priv;
1542 priv = colorsel->private_data;
1543 frame = gtk_frame_new (NULL);
1544 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1545 priv->custom_palette[i][j] = palette_new (colorsel);
1546 gtk_widget_set_size_request (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1547 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1548 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1551 /* Set the palette entry [x][y] to be the currently selected one. */
1553 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1555 ColorSelectionPrivate *priv = colorsel->private_data;
1557 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1561 scale_round (double val, double factor)
1563 val = floor (val * factor + 0.5);
1565 val = MIN (val, factor);
1570 update_color (GtkColorSelection *colorsel)
1572 ColorSelectionPrivate *priv = colorsel->private_data;
1574 gchar opacity_text[32];
1577 priv->changing = TRUE;
1578 color_sample_draw_samples (colorsel);
1580 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1581 priv->color[COLORSEL_HUE],
1582 priv->color[COLORSEL_SATURATION],
1583 priv->color[COLORSEL_VALUE]);
1584 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1585 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1586 scale_round (priv->color[COLORSEL_HUE], 360));
1587 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1588 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1589 scale_round (priv->color[COLORSEL_SATURATION], 255));
1590 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1591 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1592 scale_round (priv->color[COLORSEL_VALUE], 255));
1593 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1594 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1595 scale_round (priv->color[COLORSEL_RED], 255));
1596 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1597 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1598 scale_round (priv->color[COLORSEL_GREEN], 255));
1599 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1600 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1601 scale_round (priv->color[COLORSEL_BLUE], 255));
1602 gtk_adjustment_set_value (gtk_range_get_adjustment
1603 (GTK_RANGE (priv->opacity_slider)),
1604 scale_round (priv->color[COLORSEL_OPACITY], 255));
1606 g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
1607 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1609 g_snprintf (entryval, 11, "#%2X%2X%2X",
1610 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1611 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1612 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1614 for (ptr = entryval; *ptr; ptr++)
1617 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1618 priv->changing = FALSE;
1620 g_object_ref (colorsel);
1622 g_signal_emit (colorsel, color_selection_signals[COLOR_CHANGED], 0);
1624 g_object_freeze_notify (G_OBJECT (colorsel));
1625 g_object_notify (G_OBJECT (colorsel), "current_color");
1626 g_object_notify (G_OBJECT (colorsel), "current_alpha");
1627 g_object_thaw_notify (G_OBJECT (colorsel));
1629 g_object_unref (colorsel);
1633 update_palette (GtkColorSelection *colorsel)
1635 GdkColor *current_colors;
1638 current_colors = get_current_colors (colorsel);
1640 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1642 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1646 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1648 gtk_color_selection_set_palette_color (colorsel,
1650 ¤t_colors[index]);
1654 g_free (current_colors);
1658 palette_change_notify_instance (GObject *object,
1662 update_palette (GTK_COLOR_SELECTION (data));
1666 default_noscreen_change_palette_func (const GdkColor *colors,
1669 default_change_palette_func (gdk_screen_get_default (), colors, n_colors);
1673 default_change_palette_func (GdkScreen *screen,
1674 const GdkColor *colors,
1679 str = gtk_color_selection_palette_to_string (colors, n_colors);
1681 gtk_settings_set_string_property (gtk_settings_get_for_screen (screen),
1682 "gtk-color-palette",
1684 "gtk_color_selection_palette_to_string");
1690 gtk_color_selection_get_type (void)
1692 static GType color_selection_type = 0;
1694 if (!color_selection_type)
1696 static const GTypeInfo color_selection_info =
1698 sizeof (GtkColorSelectionClass),
1699 NULL, /* base_init */
1700 NULL, /* base_finalize */
1701 (GClassInitFunc) gtk_color_selection_class_init,
1702 NULL, /* class_finalize */
1703 NULL, /* class_data */
1704 sizeof (GtkColorSelection),
1705 0, /* n_preallocs */
1706 (GInstanceInitFunc) gtk_color_selection_init,
1709 color_selection_type =
1710 g_type_register_static (GTK_TYPE_VBOX, "GtkColorSelection",
1711 &color_selection_info, 0);
1714 return color_selection_type;
1718 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1720 GObjectClass *gobject_class;
1721 GtkObjectClass *object_class;
1722 GtkWidgetClass *widget_class;
1724 gobject_class = G_OBJECT_CLASS (klass);
1725 object_class = GTK_OBJECT_CLASS (klass);
1726 widget_class = GTK_WIDGET_CLASS (klass);
1728 parent_class = g_type_class_peek_parent (klass);
1730 object_class->destroy = gtk_color_selection_destroy;
1731 gobject_class->finalize = gtk_color_selection_finalize;
1733 gobject_class->set_property = gtk_color_selection_set_property;
1734 gobject_class->get_property = gtk_color_selection_get_property;
1736 widget_class->realize = gtk_color_selection_realize;
1737 widget_class->unrealize = gtk_color_selection_unrealize;
1738 widget_class->show_all = gtk_color_selection_show_all;
1740 g_object_class_install_property (gobject_class,
1741 PROP_HAS_OPACITY_CONTROL,
1742 g_param_spec_boolean ("has_opacity_control",
1743 _("Has Opacity Control"),
1744 _("Whether the color selector should allow setting opacity"),
1746 G_PARAM_READABLE | G_PARAM_WRITABLE));
1747 g_object_class_install_property (gobject_class,
1749 g_param_spec_boolean ("has_palette",
1751 _("Whether a palette should be used"),
1753 G_PARAM_READABLE | G_PARAM_WRITABLE));
1754 g_object_class_install_property (gobject_class,
1756 g_param_spec_boxed ("current_color",
1758 _("The current color"),
1760 G_PARAM_READABLE | G_PARAM_WRITABLE));
1761 g_object_class_install_property (gobject_class,
1763 g_param_spec_uint ("current_alpha",
1765 _("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1767 G_PARAM_READABLE | G_PARAM_WRITABLE));
1769 color_selection_signals[COLOR_CHANGED] =
1770 g_signal_new ("color_changed",
1771 G_OBJECT_CLASS_TYPE (object_class),
1773 G_STRUCT_OFFSET (GtkColorSelectionClass, color_changed),
1775 _gtk_marshal_VOID__VOID,
1778 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1779 _("Custom palette"),
1780 _("Palette to use in the color selector"),
1782 G_PARAM_READWRITE));
1785 /* widget functions */
1788 gtk_color_selection_init (GtkColorSelection *colorsel)
1790 GtkWidget *top_hbox;
1791 GtkWidget *top_right_vbox;
1792 GtkWidget *table, *label, *hbox, *frame, *vbox, *button;
1793 GtkAdjustment *adjust;
1794 GtkWidget *picker_image;
1796 ColorSelectionPrivate *priv;
1798 gtk_widget_push_composite_child ();
1800 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1801 priv->changing = FALSE;
1802 priv->default_set = FALSE;
1803 priv->default_alpha_set = FALSE;
1805 priv->tooltips = gtk_tooltips_new ();
1806 g_object_ref (priv->tooltips);
1807 gtk_object_sink (GTK_OBJECT (priv->tooltips));
1809 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1810 top_hbox = gtk_hbox_new (FALSE, 8);
1811 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1813 vbox = gtk_vbox_new (FALSE, 4);
1814 priv->triangle_colorsel = gtk_hsv_new ();
1815 g_signal_connect (priv->triangle_colorsel, "changed",
1816 G_CALLBACK (hsv_changed), colorsel);
1817 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1818 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1819 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1820 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1821 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1823 hbox = gtk_hbox_new (FALSE, 4);
1824 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1826 frame = gtk_frame_new (NULL);
1827 gtk_widget_set_size_request (frame, -1, 30);
1828 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1829 color_sample_new (colorsel);
1830 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1831 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1833 button = gtk_button_new ();
1835 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1836 g_object_set_data (G_OBJECT (button), "COLORSEL", colorsel);
1837 g_signal_connect (button, "clicked",
1838 G_CALLBACK (get_screen_color), NULL);
1839 picker_image = gtk_image_new_from_stock (GTK_STOCK_COLOR_PICKER, GTK_ICON_SIZE_BUTTON);
1840 gtk_container_add (GTK_CONTAINER (button), picker_image);
1841 gtk_widget_show (GTK_WIDGET (picker_image));
1842 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1844 gtk_tooltips_set_tip (priv->tooltips,
1846 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1848 top_right_vbox = gtk_vbox_new (FALSE, 4);
1849 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1850 table = gtk_table_new (8, 6, FALSE);
1851 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1852 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1853 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1855 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1856 _("Position on the color wheel."));
1857 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1858 _("\"Deepness\" of the color."));
1859 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1860 _("Brightness of the color."));
1861 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1862 _("Amount of red light in the color."));
1863 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1864 _("Amount of green light in the color."));
1865 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1866 _("Amount of blue light in the color."));
1867 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1869 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1870 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1871 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1872 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1873 g_object_set_data (G_OBJECT (adjust), "COLORSEL", colorsel);
1874 priv->opacity_slider = gtk_hscale_new (adjust);
1875 gtk_tooltips_set_tip (priv->tooltips,
1876 priv->opacity_slider,
1877 _("Transparency of the currently-selected color."), NULL);
1878 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1879 priv->opacity_slider);
1880 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1881 g_signal_connect (adjust, "value_changed",
1882 G_CALLBACK (adjustment_changed),
1883 GINT_TO_POINTER (COLORSEL_OPACITY));
1884 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1885 priv->opacity_entry = gtk_entry_new ();
1886 gtk_widget_set_size_request (priv->opacity_entry, 40, -1);
1888 g_signal_connect (priv->opacity_entry, "activate",
1889 G_CALLBACK (opacity_entry_changed), colorsel);
1890 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1892 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1893 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1894 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1895 priv->hex_entry = gtk_entry_new ();
1897 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1899 g_signal_connect (priv->hex_entry, "activate",
1900 G_CALLBACK (hex_changed), colorsel);
1902 gtk_tooltips_set_tip (priv->tooltips,
1904 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1906 gtk_widget_set_size_request (priv->hex_entry, 75, -1);
1907 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1908 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1910 /* Set up the palette */
1911 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1912 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1913 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1914 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1916 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1918 make_palette_frame (colorsel, table, i, j);
1921 set_selected_palette (colorsel, 0, 0);
1922 priv->palette_frame = gtk_frame_new (NULL);
1923 label = gtk_label_new_with_mnemonic (_("_Palette"));
1924 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1926 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1927 priv->custom_palette[0][0]);
1929 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1930 vbox = gtk_vbox_new (FALSE, 4);
1931 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1932 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1934 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1936 gtk_widget_show_all (top_hbox);
1938 /* hide unused stuff */
1940 if (priv->has_opacity == FALSE)
1942 gtk_widget_hide (priv->opacity_label);
1943 gtk_widget_hide (priv->opacity_slider);
1944 gtk_widget_hide (priv->opacity_entry);
1947 if (priv->has_palette == FALSE)
1949 gtk_widget_hide (priv->palette_frame);
1952 gtk_widget_pop_composite_child ();
1956 gtk_color_selection_destroy (GtkObject *object)
1958 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1959 ColorSelectionPrivate *priv = cselection->private_data;
1961 if (priv->dropper_grab_widget)
1963 gtk_widget_destroy (priv->dropper_grab_widget);
1964 priv->dropper_grab_widget = NULL;
1969 g_object_unref (priv->tooltips);
1970 priv->tooltips = NULL;
1973 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1977 gtk_color_selection_finalize (GObject *object)
1979 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1981 if (cselection->private_data)
1983 g_free (cselection->private_data);
1984 cselection->private_data = NULL;
1987 G_OBJECT_CLASS (parent_class)->finalize (object);
1991 gtk_color_selection_realize (GtkWidget *widget)
1993 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
1994 ColorSelectionPrivate *priv = colorsel->private_data;
1995 GtkSettings *settings = gtk_widget_get_settings (widget);
1997 priv->settings_connection = g_signal_connect (settings,
1998 "notify::gtk-color-palette",
1999 G_CALLBACK (palette_change_notify_instance),
2001 update_palette (colorsel);
2003 GTK_WIDGET_CLASS (parent_class)->realize (widget);
2007 gtk_color_selection_unrealize (GtkWidget *widget)
2009 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
2010 ColorSelectionPrivate *priv = colorsel->private_data;
2011 GtkSettings *settings = gtk_widget_get_settings (widget);
2013 g_signal_handler_disconnect (settings, priv->settings_connection);
2015 GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
2018 /* We override show-all since we have internal widgets that
2019 * shouldn't be shown when you call show_all(), like the
2020 * palette and opacity sliders.
2023 gtk_color_selection_show_all (GtkWidget *widget)
2025 gtk_widget_show (widget);
2029 * gtk_color_selection_new:
2031 * Creates a new GtkColorSelection.
2033 * Return value: a new #GtkColorSelection
2036 gtk_color_selection_new (void)
2038 GtkColorSelection *colorsel;
2039 ColorSelectionPrivate *priv;
2046 colorsel = g_object_new (GTK_TYPE_COLOR_SELECTION, NULL);
2047 priv = colorsel->private_data;
2048 set_color_internal (colorsel, color);
2049 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
2051 /* We want to make sure that default_set is FALSE */
2052 /* This way the user can still set it */
2053 priv->default_set = FALSE;
2054 priv->default_alpha_set = FALSE;
2056 return GTK_WIDGET (colorsel);
2061 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
2062 GtkUpdateType policy)
2064 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2068 * gtk_color_selection_get_has_opacity_control:
2069 * @colorsel: a #GtkColorSelection.
2071 * Determines whether the colorsel has an opacity control.
2073 * Return value: %TRUE if the @colorsel has an opacity control. %FALSE if it does't.
2076 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2078 ColorSelectionPrivate *priv;
2080 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2082 priv = colorsel->private_data;
2084 return priv->has_opacity;
2088 * gtk_color_selection_set_has_opacity_control:
2089 * @colorsel: a #GtkColorSelection.
2090 * @has_opacity: %TRUE if @colorsel can set the opacity, %FALSE otherwise.
2092 * Sets the @colorsel to use or not use opacity.
2096 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2097 gboolean has_opacity)
2099 ColorSelectionPrivate *priv;
2101 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2103 priv = colorsel->private_data;
2104 has_opacity = has_opacity != FALSE;
2106 if (priv->has_opacity != has_opacity)
2108 priv->has_opacity = has_opacity;
2111 gtk_widget_show (priv->opacity_slider);
2112 gtk_widget_show (priv->opacity_label);
2113 gtk_widget_show (priv->opacity_entry);
2117 gtk_widget_hide (priv->opacity_slider);
2118 gtk_widget_hide (priv->opacity_label);
2119 gtk_widget_hide (priv->opacity_entry);
2121 color_sample_draw_samples (colorsel);
2123 g_object_notify (G_OBJECT (colorsel), "has_opacity_control");
2128 * gtk_color_selection_get_has_palette:
2129 * @colorsel: a #GtkColorSelection.
2131 * Determines whether the color selector has a color palette.
2133 * Return value: %TRUE if the selector has a palette. %FALSE if it hasn't.
2136 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2138 ColorSelectionPrivate *priv;
2140 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2142 priv = colorsel->private_data;
2144 return priv->has_palette;
2148 * gtk_color_selection_set_has_palette:
2149 * @colorsel: a #GtkColorSelection.
2150 * @has_palette: %TRUE if palette is to be visible, %FALSE otherwise.
2152 * Shows and hides the palette based upon the value of @has_palette.
2156 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2157 gboolean has_palette)
2159 ColorSelectionPrivate *priv;
2160 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2162 priv = colorsel->private_data;
2163 has_palette = has_palette != FALSE;
2165 if (priv->has_palette != has_palette)
2167 priv->has_palette = has_palette;
2169 gtk_widget_show (priv->palette_frame);
2171 gtk_widget_hide (priv->palette_frame);
2173 g_object_notify (G_OBJECT (colorsel), "has_palette");
2178 * gtk_color_selection_set_current_color:
2179 * @colorsel: a #GtkColorSelection.
2180 * @color: A #GdkColor to set the current color with.
2182 * Sets the current color to be @color. The first time this is called, it will
2183 * also set the original color to be @color too.
2186 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2189 ColorSelectionPrivate *priv;
2191 gboolean previous_changed;
2193 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2195 priv = colorsel->private_data;
2196 priv->changing = TRUE;
2197 priv->color[COLORSEL_RED] = SCALE (color->red);
2198 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2199 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2200 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2201 priv->color[COLORSEL_GREEN],
2202 priv->color[COLORSEL_BLUE],
2203 &priv->color[COLORSEL_HUE],
2204 &priv->color[COLORSEL_SATURATION],
2205 &priv->color[COLORSEL_VALUE]);
2206 if (priv->default_set == FALSE)
2208 previous_changed = TRUE;
2209 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2210 priv->old_color[i] = priv->color[i];
2212 priv->default_set = TRUE;
2213 update_color (colorsel);
2217 * gtk_color_selection_set_current_alpha:
2218 * @colorsel: a #GtkColorSelection.
2219 * @alpha: an integer between 0 and 65535.
2221 * Sets the current opacity to be @alpha. The first time this is called, it will
2222 * also set the original opacity to be @alpha too.
2225 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2228 ColorSelectionPrivate *priv;
2231 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2233 priv = colorsel->private_data;
2234 priv->changing = TRUE;
2235 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2236 if (priv->default_alpha_set == FALSE)
2238 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2239 priv->old_color[i] = priv->color[i];
2241 priv->default_alpha_set = TRUE;
2242 update_color (colorsel);
2246 * gtk_color_selection_set_color:
2247 * @colorsel: a #GtkColorSelection.
2248 * @color: an array of 4 doubles specifying the red, green, blue and opacity
2249 * to set the current color to.
2251 * Sets the current color to be @color. The first time this is called, it will
2252 * also set the original color to be @color too.
2254 * This function is deprecated, use gtk_color_selection_set_current_color() instead.
2257 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2260 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2262 set_color_internal (colorsel, color);
2266 * gtk_color_selection_get_current_color:
2267 * @colorsel: a #GtkColorSelection.
2268 * @color: a #GdkColor to fill in with the current color.
2270 * Sets @color to be the current color in the GtkColorSelection widget.
2273 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2276 ColorSelectionPrivate *priv;
2278 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2280 priv = colorsel->private_data;
2281 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2282 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2283 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2287 * gtk_color_selection_get_current_alpha:
2288 * @colorsel: a #GtkColorSelection.
2290 * Returns the current alpha value.
2292 * Return value: an integer between 0 and 65535.
2295 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2297 ColorSelectionPrivate *priv;
2299 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2301 priv = colorsel->private_data;
2302 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2306 * gtk_color_selection_get_color:
2307 * @colorsel: a #GtkColorSelection.
2308 * @color: an array of 4 #gdouble to fill in with the current color.
2310 * Sets @color to be the current color in the GtkColorSelection widget.
2312 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2315 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2318 ColorSelectionPrivate *priv;
2320 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2322 priv = colorsel->private_data;
2323 color[0] = priv->color[COLORSEL_RED];
2324 color[1] = priv->color[COLORSEL_GREEN];
2325 color[2] = priv->color[COLORSEL_BLUE];
2326 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2330 * gtk_color_selection_set_previous_color:
2331 * @colorsel: a #GtkColorSelection.
2332 * @color: a #GdkColor to set the previous color with.
2334 * Sets the 'previous' color to be @color. This function should be called with
2335 * some hesitations, as it might seem confusing to have that color change.
2336 * Calling gtk_color_selection_set_current_color() will also set this color the first
2337 * time it is called.
2340 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2343 ColorSelectionPrivate *priv;
2345 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2347 priv = colorsel->private_data;
2348 priv->changing = TRUE;
2349 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2350 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2351 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2352 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2353 priv->old_color[COLORSEL_GREEN],
2354 priv->old_color[COLORSEL_BLUE],
2355 &priv->old_color[COLORSEL_HUE],
2356 &priv->old_color[COLORSEL_SATURATION],
2357 &priv->old_color[COLORSEL_VALUE]);
2358 color_sample_draw_samples (colorsel);
2359 priv->default_set = TRUE;
2360 priv->changing = FALSE;
2364 * gtk_color_selection_set_previous_alpha:
2365 * @colorsel: a #GtkColorSelection.
2366 * @alpha: an integer between 0 and 65535.
2368 * Sets the 'previous' alpha to be @alpha. This function should be called with
2369 * some hesitations, as it might seem confusing to have that alpha change.
2372 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2375 ColorSelectionPrivate *priv;
2377 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2379 priv = colorsel->private_data;
2380 priv->changing = TRUE;
2381 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2382 color_sample_draw_samples (colorsel);
2383 priv->default_alpha_set = TRUE;
2384 priv->changing = FALSE;
2389 * gtk_color_selection_get_previous_color:
2390 * @colorsel: a #GtkColorSelection.
2391 * @color: a #GdkColor to fill in with the original color value.
2393 * Fills @color in with the original color value.
2396 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2399 ColorSelectionPrivate *priv;
2401 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2403 priv = colorsel->private_data;
2404 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2405 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2406 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2410 * gtk_color_selection_get_previous_alpha:
2411 * @colorsel: a #GtkColorSelection.
2413 * Returns the previous alpha value.
2415 * Return value: an integer between 0 and 65535.
2418 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2420 ColorSelectionPrivate *priv;
2422 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2424 priv = colorsel->private_data;
2425 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2429 * gtk_color_selection_set_palette_color:
2430 * @colorsel: a #GtkColorSelection.
2431 * @index: the color index of the palette.
2432 * @color: A #GdkColor to set the palette with.
2434 * Sets the palette located at @index to have @color as its color.
2438 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2442 ColorSelectionPrivate *priv;
2446 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2447 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2449 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2450 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2452 priv = colorsel->private_data;
2453 col[0] = SCALE (color->red);
2454 col[1] = SCALE (color->green);
2455 col[2] = SCALE (color->blue);
2457 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2461 * gtk_color_selection_is_adjusting:
2462 * @colorsel: a #GtkColorSelection.
2464 * Gets the current state of the @colorsel.
2466 * Return value: %TRUE if the user is currently dragging a color around, and %FALSE
2467 * if the selection has stopped.
2470 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2472 ColorSelectionPrivate *priv;
2474 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2476 priv = colorsel->private_data;
2478 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2482 gtk_color_selection_set_property (GObject *object,
2484 const GValue *value,
2487 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2491 case PROP_HAS_OPACITY_CONTROL:
2492 gtk_color_selection_set_has_opacity_control (colorsel,
2493 g_value_get_boolean (value));
2495 case PROP_HAS_PALETTE:
2496 gtk_color_selection_set_has_palette (colorsel,
2497 g_value_get_boolean (value));
2499 case PROP_CURRENT_COLOR:
2500 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2502 case PROP_CURRENT_ALPHA:
2503 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2506 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2513 gtk_color_selection_get_property (GObject *object,
2518 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2523 case PROP_HAS_OPACITY_CONTROL:
2524 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2526 case PROP_HAS_PALETTE:
2527 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2529 case PROP_CURRENT_COLOR:
2530 gtk_color_selection_get_current_color (colorsel, &color);
2531 g_value_set_boxed (value, &color);
2533 case PROP_CURRENT_ALPHA:
2534 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2537 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2544 * gtk_color_selection_palette_from_string:
2545 * @str: a string encoding a color palette.
2546 * @colors: return location for allocated array of #GdkColor.
2547 * @n_colors: return location for length of array.
2549 * Parses a color palette string; the string is a colon-separated
2550 * list of color names readable by gdk_color_parse().
2552 * Return value: %TRUE if a palette was successfully parsed.
2555 gtk_color_selection_palette_from_string (const gchar *str,
2567 copy = g_strdup (str);
2573 if (*p == ':' || *p == '\0')
2575 gboolean done = TRUE;
2579 goto failed; /* empty entry */
2588 retval = g_renew (GdkColor, retval, count + 1);
2589 if (!gdk_color_parse (start, retval + count))
2630 * gtk_color_selection_palette_to_string:
2631 * @colors: an array of colors.
2632 * @n_colors: length of the array.
2634 * Encodes a palette as a string, useful for persistent storage.
2636 * Return value: allocated string encoding the palette.
2639 gtk_color_selection_palette_to_string (const GdkColor *colors,
2643 gchar **strs = NULL;
2647 return g_strdup ("");
2649 strs = g_new0 (gchar*, n_colors + 1);
2652 while (i < n_colors)
2657 g_strdup_printf ("#%2X%2X%2X",
2658 colors[i].red / 256,
2659 colors[i].green / 256,
2660 colors[i].blue / 256);
2662 for (ptr = strs[i]; *ptr; ptr++)
2669 retval = g_strjoinv (":", strs);
2677 * gtk_color_selection_set_change_palette_hook:
2678 * @func: a function to call when the custom palette needs saving.
2680 * Installs a global function to be called whenever the user tries to
2681 * modify the palette in a color selection. This function should save
2682 * the new palette contents, and update the GtkSettings property
2683 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2685 * This function is deprecated in favor of
2686 * gtk_color_selection_set_change_palette_with_screen_hook(), and does
2687 * not work in multihead environments.
2689 * Return value: the previous change palette hook (that was replaced).
2691 GtkColorSelectionChangePaletteFunc
2692 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2694 GtkColorSelectionChangePaletteFunc old;
2696 old = noscreen_change_palette_hook;
2698 noscreen_change_palette_hook = func;
2704 * gtk_color_selection_set_change_palette_with_screen_hook:
2705 * @func: a function to call when the custom palette needs saving.
2707 * Installs a global function to be called whenever the user tries to
2708 * modify the palette in a color selection. This function should save
2709 * the new palette contents, and update the GtkSettings property
2710 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2712 * Return value: the previous change palette hook (that was replaced).
2716 GtkColorSelectionChangePaletteWithScreenFunc
2717 gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func)
2719 GtkColorSelectionChangePaletteWithScreenFunc old;
2721 old = change_palette_hook;
2723 change_palette_hook = func;