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/.
29 #include "gdkconfig.h"
33 #include "gdk/gdkkeysyms.h"
34 #include "gtkcolorsel.h"
36 #include "gtkwindow.h"
37 #include "gtkselection.h"
39 #include "gtkdrawingarea.h"
46 #include "gtkmarshalers.h"
48 #include "gtkspinbutton.h"
50 #include "gtkhscale.h"
52 #include "gtkbutton.h"
53 #include "gtkhseparator.h"
54 #include "gtktooltips.h"
55 #include "gtkinvisible.h"
56 #include "gtkmenuitem.h"
58 #include "gtksettings.h"
62 #include "gtkaccessible.h"
66 /* Number of elements in the custom palatte */
67 #define GTK_CUSTOM_PALETTE_WIDTH 10
68 #define GTK_CUSTOM_PALETTE_HEIGHT 2
70 /* Conversion between 0->1 double and and guint16. See
71 * scale_round() below for more general conversions
73 #define SCALE(i) (i / 65535.)
74 #define UNSCALE(d) ((guint16)(d * 65535 + 0.5))
85 PROP_HAS_OPACITY_CONTROL,
101 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
103 struct _ColorSelectionPrivate
105 guint has_opacity : 1;
106 guint has_palette : 1;
108 guint default_set : 1;
109 guint default_alpha_set : 1;
111 gdouble color[COLORSEL_NUM_CHANNELS];
112 gdouble old_color[COLORSEL_NUM_CHANNELS];
114 GtkWidget *triangle_colorsel;
115 GtkWidget *hue_spinbutton;
116 GtkWidget *sat_spinbutton;
117 GtkWidget *val_spinbutton;
118 GtkWidget *red_spinbutton;
119 GtkWidget *green_spinbutton;
120 GtkWidget *blue_spinbutton;
121 GtkWidget *opacity_slider;
122 GtkWidget *opacity_label;
123 GtkWidget *opacity_entry;
124 GtkWidget *palette_frame;
125 GtkWidget *hex_entry;
127 /* The Palette code */
128 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
130 /* The color_sample stuff */
131 GtkWidget *sample_area;
132 GtkWidget *old_sample;
133 GtkWidget *cur_sample;
137 GtkTooltips *tooltips;
139 /* Window for grabbing on */
140 GtkWidget *dropper_grab_widget;
142 /* Connection to settings */
143 gulong settings_connection;
147 static void gtk_color_selection_init (GtkColorSelection *colorsel);
148 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
149 static void gtk_color_selection_destroy (GtkObject *object);
150 static void gtk_color_selection_finalize (GObject *object);
151 static void update_color (GtkColorSelection *colorsel);
152 static void gtk_color_selection_set_property (GObject *object,
156 static void gtk_color_selection_get_property (GObject *object,
161 static void gtk_color_selection_realize (GtkWidget *widget);
162 static void gtk_color_selection_unrealize (GtkWidget *widget);
163 static void gtk_color_selection_show_all (GtkWidget *widget);
165 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
168 static GdkGC *get_focus_gc (GtkWidget *drawing_area,
170 static void default_noscreen_change_palette_func (const GdkColor *colors,
172 static void default_change_palette_func (GdkScreen *screen,
173 const GdkColor *colors,
175 static void make_control_relations (AtkObject *atk_obj,
177 static void make_all_relations (AtkObject *atk_obj,
178 ColorSelectionPrivate *priv);
180 static gpointer parent_class = NULL;
181 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
183 static const 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";
185 static GtkColorSelectionChangePaletteFunc noscreen_change_palette_hook = default_noscreen_change_palette_func;
186 static GtkColorSelectionChangePaletteWithScreenFunc change_palette_hook = default_change_palette_func;
188 /* The cursor for the dropper */
189 #define DROPPER_WIDTH 17
190 #define DROPPER_HEIGHT 17
191 #define DROPPER_X_HOT 2
192 #define DROPPER_Y_HOT 16
195 static const guchar dropper_bits[] = {
196 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
197 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
198 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
199 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
202 static const guchar dropper_mask[] = {
203 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
204 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
205 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
206 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
215 #define SAMPLE_WIDTH 64
216 #define SAMPLE_HEIGHT 28
218 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
219 static void color_sample_draw_samples (GtkColorSelection *colorsel);
222 set_color_internal (GtkColorSelection *colorsel,
225 ColorSelectionPrivate *priv;
228 priv = colorsel->private_data;
229 priv->changing = TRUE;
230 priv->color[COLORSEL_RED] = color[0];
231 priv->color[COLORSEL_GREEN] = color[1];
232 priv->color[COLORSEL_BLUE] = color[2];
233 priv->color[COLORSEL_OPACITY] = color[3];
234 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
235 priv->color[COLORSEL_GREEN],
236 priv->color[COLORSEL_BLUE],
237 &priv->color[COLORSEL_HUE],
238 &priv->color[COLORSEL_SATURATION],
239 &priv->color[COLORSEL_VALUE]);
240 if (priv->default_set == FALSE)
242 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
243 priv->old_color[i] = priv->color[i];
245 priv->default_set = TRUE;
246 priv->default_alpha_set = TRUE;
247 update_color (colorsel);
251 set_color_icon (GdkDragContext *context,
257 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
260 pixel = (((UNSCALE (colors[COLORSEL_RED]) & 0xff00) << 16) |
261 ((UNSCALE (colors[COLORSEL_GREEN]) & 0xff00) << 8) |
262 ((UNSCALE (colors[COLORSEL_BLUE]) & 0xff00)));
264 gdk_pixbuf_fill (pixbuf, pixel);
266 gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
267 g_object_unref (pixbuf);
271 color_sample_drag_begin (GtkWidget *widget,
272 GdkDragContext *context,
275 GtkColorSelection *colorsel = data;
276 ColorSelectionPrivate *priv;
279 priv = colorsel->private_data;
281 if (widget == priv->old_sample)
282 colsrc = priv->old_color;
284 colsrc = priv->color;
286 set_color_icon (context, colsrc);
290 color_sample_drag_end (GtkWidget *widget,
291 GdkDragContext *context,
294 g_object_set_data (G_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
298 color_sample_drop_handle (GtkWidget *widget,
299 GdkDragContext *context,
302 GtkSelectionData *selection_data,
307 GtkColorSelection *colorsel = data;
308 ColorSelectionPrivate *priv;
311 priv = colorsel->private_data;
313 /* This is currently a guint16 array of the format:
320 if (selection_data->length < 0)
323 /* We accept drops with the wrong format, since the KDE color
324 * chooser incorrectly drops application/x-color with format 8.
326 if (selection_data->length != 8)
328 g_warning ("Received invalid color data\n");
332 vals = (guint16 *)selection_data->data;
334 if (widget == priv->cur_sample)
336 color[0] = (gdouble)vals[0] / 0xffff;
337 color[1] = (gdouble)vals[1] / 0xffff;
338 color[2] = (gdouble)vals[2] / 0xffff;
339 color[3] = (gdouble)vals[3] / 0xffff;
341 set_color_internal (colorsel, color);
346 color_sample_drag_handle (GtkWidget *widget,
347 GdkDragContext *context,
348 GtkSelectionData *selection_data,
353 GtkColorSelection *colorsel = data;
354 ColorSelectionPrivate *priv;
358 priv = colorsel->private_data;
360 if (widget == priv->old_sample)
361 colsrc = priv->old_color;
363 colsrc = priv->color;
365 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
366 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
367 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
368 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
370 gtk_selection_data_set (selection_data,
371 gdk_atom_intern ("application/x-color", FALSE),
372 16, (guchar *)vals, 8);
375 /* which = 0 means draw old sample, which = 1 means draw new */
377 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
380 gint x, y, i, wid, heig, f, n, goff;
381 guchar c[3 * 2], cc[3 * 4], *cp = c;
384 ColorSelectionPrivate *priv;
386 g_return_if_fail (colorsel != NULL);
387 priv = colorsel->private_data;
389 g_return_if_fail (priv->sample_area != NULL);
390 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
395 da = priv->old_sample;
396 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
397 c[n] = (guchar) (UNSCALE (priv->old_color[i]) >> 8);
402 da = priv->cur_sample;
403 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
404 c[n] = (guchar) (UNSCALE (priv->color[i]) >> 8);
405 goff = priv->old_sample->allocation.width % 32;
408 wid = da->allocation.width;
409 heig = da->allocation.height;
411 buf = g_new (guchar, 3 * wid * heig);
415 for (n = 0; n < 3; n++)
417 c[n] = (guchar) (255.0 * priv->old_color[i]);
418 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
422 if (priv->has_opacity)
424 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
426 for (n = 0; n < 3; n++)
428 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
429 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
435 for (y = 0; y < heig; y++)
437 for (x = 0; x < wid; x++)
439 if (priv->has_opacity)
440 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
444 for (n = 0; n < 3; n++)
445 buf[i++] = cp[n + f];
449 gdk_draw_rgb_image (da->window,
453 GDK_RGB_DITHER_NORMAL,
463 color_sample_draw_samples (GtkColorSelection *colorsel)
465 color_sample_draw_sample (colorsel, 0);
466 color_sample_draw_sample (colorsel, 1);
470 color_old_sample_expose (GtkWidget *da,
471 GdkEventExpose *event,
472 GtkColorSelection *colorsel)
474 color_sample_draw_sample (colorsel, 0);
480 color_cur_sample_expose (GtkWidget *da,
481 GdkEventExpose *event,
482 GtkColorSelection *colorsel)
484 color_sample_draw_sample (colorsel, 1);
489 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
491 static const GtkTargetEntry targets[] = {
492 { "application/x-color", 0 }
494 ColorSelectionPrivate *priv;
495 priv = colorsel->private_data;
497 gtk_drag_source_set (sample,
498 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
500 GDK_ACTION_COPY | GDK_ACTION_MOVE);
502 g_signal_connect (sample,
504 G_CALLBACK (color_sample_drag_begin),
506 if (sample == priv->cur_sample)
509 gtk_drag_dest_set (sample,
510 GTK_DEST_DEFAULT_HIGHLIGHT |
511 GTK_DEST_DEFAULT_MOTION |
512 GTK_DEST_DEFAULT_DROP,
516 g_signal_connect (sample,
518 G_CALLBACK (color_sample_drag_end),
522 g_signal_connect (sample,
524 G_CALLBACK (color_sample_drag_handle),
526 g_signal_connect (sample,
527 "drag_data_received",
528 G_CALLBACK (color_sample_drop_handle),
535 color_sample_new (GtkColorSelection *colorsel)
537 ColorSelectionPrivate *priv;
539 priv = colorsel->private_data;
541 priv->sample_area = gtk_hbox_new (FALSE, 0);
542 priv->old_sample = gtk_drawing_area_new ();
543 priv->cur_sample = gtk_drawing_area_new ();
545 /* We need enter/leave to do tooltips */
546 gtk_widget_add_events (priv->old_sample,
547 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
548 gtk_widget_add_events (priv->cur_sample,
549 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
551 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
553 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
556 g_signal_connect (priv->old_sample, "expose_event",
557 G_CALLBACK (color_old_sample_expose),
559 g_signal_connect (priv->cur_sample, "expose_event",
560 G_CALLBACK (color_cur_sample_expose),
563 color_sample_setup_dnd (colorsel, priv->old_sample);
564 color_sample_setup_dnd (colorsel, priv->cur_sample);
566 gtk_tooltips_set_tip (priv->tooltips,
568 _("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);
571 gtk_tooltips_set_tip (priv->tooltips,
573 _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL);
575 gtk_widget_show_all (priv->sample_area);
581 * The palette area code
584 #define CUSTOM_PALETTE_ENTRY_WIDTH 20
585 #define CUSTOM_PALETTE_ENTRY_HEIGHT 20
588 palette_get_color (GtkWidget *drawing_area, gdouble *color)
592 g_return_if_fail (color != NULL);
594 color_val = g_object_get_data (G_OBJECT (drawing_area), "color_val");
595 if (color_val == NULL)
597 /* Default to white for no good reason */
605 color[0] = color_val[0];
606 color[1] = color_val[1];
607 color[2] = color_val[2];
611 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
613 palette_paint (GtkWidget *drawing_area,
617 if (drawing_area->window == NULL)
620 gdk_draw_rectangle (drawing_area->window,
621 drawing_area->style->bg_gc[GTK_STATE_NORMAL],
623 area->x, area->y, area->width, area->height);
625 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
628 GdkGC *gc = get_focus_gc (drawing_area, &focus_width);
629 gdk_draw_rectangle (drawing_area->window,
630 gc, FALSE, focus_width / 2, focus_width / 2,
631 drawing_area->allocation.width - focus_width,
632 drawing_area->allocation.height - focus_width);
638 get_focus_gc (GtkWidget *drawing_area,
641 GdkGC *gc = gdk_gc_new (drawing_area->window);
645 gtk_widget_style_get (drawing_area,
646 "focus-line-width", focus_width,
647 "focus-line-pattern", (gchar *)&dash_list,
650 palette_get_color (drawing_area, color);
652 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
653 gdk_gc_copy (gc, drawing_area->style->black_gc);
655 gdk_gc_copy (gc, drawing_area->style->white_gc);
657 gdk_gc_set_line_attributes (gc, *focus_width,
658 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
659 GDK_CAP_BUTT, GDK_JOIN_MITER);
662 gdk_gc_set_dashes (gc, 0, dash_list, strlen ((char *)dash_list));
670 palette_drag_begin (GtkWidget *widget,
671 GdkDragContext *context,
676 palette_get_color (widget, colors);
677 set_color_icon (context, colors);
681 palette_drag_handle (GtkWidget *widget,
682 GdkDragContext *context,
683 GtkSelectionData *selection_data,
691 palette_get_color (widget, colsrc);
693 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
694 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
695 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
698 gtk_selection_data_set (selection_data,
699 gdk_atom_intern ("application/x-color", FALSE),
700 16, (guchar *)vals, 8);
704 palette_drag_end (GtkWidget *widget,
705 GdkDragContext *context,
708 g_object_set_data (G_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
712 get_current_colors (GtkColorSelection *colorsel)
714 GtkSettings *settings;
715 GdkColor *colors = NULL;
719 settings = gtk_widget_get_settings (GTK_WIDGET (colorsel));
720 g_object_get (settings,
721 "gtk-color-palette", &palette,
724 if (!gtk_color_selection_palette_from_string (palette, &colors, &n_colors))
726 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
730 /* If there are less colors provided than the number of slots in the
731 * color selection, we fill in the rest from the defaults.
733 if (n_colors < (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
735 GdkColor *tmp_colors = colors;
736 gint tmp_n_colors = n_colors;
738 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
739 memcpy (colors, tmp_colors, sizeof (GdkColor) * tmp_n_colors);
745 g_assert (n_colors >= GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
751 /* Changes the model color */
753 palette_change_color (GtkWidget *drawing_area,
754 GtkColorSelection *colorsel,
758 ColorSelectionPrivate *priv;
760 GdkColor *current_colors;
763 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
764 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
766 priv = colorsel->private_data;
768 gdk_color.red = UNSCALE (color[0]);
769 gdk_color.green = UNSCALE (color[1]);
770 gdk_color.blue = UNSCALE (color[2]);
773 y = 0; /* Quiet GCC */
774 while (x < GTK_CUSTOM_PALETTE_WIDTH)
777 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
779 if (priv->custom_palette[x][y] == drawing_area)
790 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
792 current_colors = get_current_colors (colorsel);
793 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
795 screen = gtk_widget_get_screen (GTK_WIDGET (colorsel));
796 if (change_palette_hook != default_change_palette_func)
797 (* change_palette_hook) (screen, current_colors,
798 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
799 else if (noscreen_change_palette_hook != default_noscreen_change_palette_func)
801 if (screen != gdk_screen_get_default ())
802 g_warning ("gtk_color_selection_set_change_palette_hook used by widget is not on the default screen.");
803 (* noscreen_change_palette_hook) (current_colors,
804 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
807 (* change_palette_hook) (screen, current_colors,
808 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
810 g_free (current_colors);
813 /* Changes the view color */
815 palette_set_color (GtkWidget *drawing_area,
816 GtkColorSelection *colorsel,
819 gdouble *new_color = g_new (double, 4);
822 gdk_color.red = UNSCALE (color[0]);
823 gdk_color.green = UNSCALE (color[1]);
824 gdk_color.blue = UNSCALE (color[2]);
826 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
828 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) == 0)
830 static const GtkTargetEntry targets[] = {
831 { "application/x-color", 0 }
833 gtk_drag_source_set (drawing_area,
834 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
836 GDK_ACTION_COPY | GDK_ACTION_MOVE);
838 g_signal_connect (drawing_area,
840 G_CALLBACK (palette_drag_begin),
842 g_signal_connect (drawing_area,
844 G_CALLBACK (palette_drag_handle),
847 g_object_set_data (G_OBJECT (drawing_area), "color_set",
848 GINT_TO_POINTER (1));
851 new_color[0] = color[0];
852 new_color[1] = color[1];
853 new_color[2] = color[2];
856 g_object_set_data_full (G_OBJECT (drawing_area), "color_val", new_color, (GDestroyNotify)g_free);
860 palette_expose (GtkWidget *drawing_area,
861 GdkEventExpose *event,
864 if (drawing_area->window == NULL)
867 palette_paint (drawing_area, &(event->area), data);
873 popup_position_func (GtkMenu *menu,
884 widget = GTK_WIDGET (user_data);
886 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
888 gdk_window_get_origin (widget->window, &root_x, &root_y);
890 gtk_widget_size_request (GTK_WIDGET (menu), &req);
892 /* Put corner of menu centered on color cell */
893 *x = root_x + widget->allocation.width / 2;
894 *y = root_y + widget->allocation.height / 2;
897 screen = gtk_widget_get_screen (widget);
898 *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
899 *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
903 save_color_selected (GtkWidget *menuitem,
906 GtkColorSelection *colorsel;
907 GtkWidget *drawing_area;
908 ColorSelectionPrivate *priv;
910 drawing_area = GTK_WIDGET (data);
912 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
915 priv = colorsel->private_data;
917 palette_change_color (drawing_area, colorsel, priv->color);
921 do_popup (GtkColorSelection *colorsel,
922 GtkWidget *drawing_area,
928 g_object_set_data (G_OBJECT (drawing_area),
932 menu = gtk_menu_new ();
934 mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
936 g_signal_connect (mi, "activate",
937 G_CALLBACK (save_color_selected),
940 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
942 gtk_widget_show_all (mi);
944 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
945 popup_position_func, drawing_area,
951 palette_enter (GtkWidget *drawing_area,
952 GdkEventCrossing *event,
955 g_object_set_data (G_OBJECT (drawing_area),
956 "gtk-colorsel-have-pointer",
957 GUINT_TO_POINTER (TRUE));
963 palette_leave (GtkWidget *drawing_area,
964 GdkEventCrossing *event,
967 g_object_set_data (G_OBJECT (drawing_area),
968 "gtk-colorsel-have-pointer",
975 palette_press (GtkWidget *drawing_area,
976 GdkEventButton *event,
979 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
981 gtk_widget_grab_focus (drawing_area);
983 if (event->button == 3 &&
984 event->type == GDK_BUTTON_PRESS)
986 do_popup (colorsel, drawing_area, event->time);
994 palette_release (GtkWidget *drawing_area,
995 GdkEventButton *event,
998 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1000 gtk_widget_grab_focus (drawing_area);
1002 if (event->button == 1 &&
1003 g_object_get_data (G_OBJECT (drawing_area),
1004 "gtk-colorsel-have-pointer") != NULL)
1006 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) != 0)
1009 palette_get_color (drawing_area, color);
1010 set_color_internal (colorsel, color);
1018 palette_drop_handle (GtkWidget *widget,
1019 GdkDragContext *context,
1022 GtkSelectionData *selection_data,
1027 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1031 if (selection_data->length < 0)
1034 /* We accept drops with the wrong format, since the KDE color
1035 * chooser incorrectly drops application/x-color with format 8.
1037 if (selection_data->length != 8)
1039 g_warning ("Received invalid color data\n");
1043 vals = (guint16 *)selection_data->data;
1045 color[0] = (gdouble)vals[0] / 0xffff;
1046 color[1] = (gdouble)vals[1] / 0xffff;
1047 color[2] = (gdouble)vals[2] / 0xffff;
1048 color[3] = (gdouble)vals[3] / 0xffff;
1049 palette_change_color (widget, colorsel, color);
1050 set_color_internal (colorsel, color);
1054 palette_activate (GtkWidget *widget,
1058 /* should have a drawing area subclass with an activate signal */
1059 if ((event->keyval == GDK_space) ||
1060 (event->keyval == GDK_Return) ||
1061 (event->keyval == GDK_KP_Enter) ||
1062 (event->keyval == GDK_KP_Space))
1064 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "color_set")) != 0)
1067 palette_get_color (widget, color);
1068 set_color_internal (GTK_COLOR_SELECTION (data), color);
1077 palette_popup (GtkWidget *widget,
1080 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1082 do_popup (colorsel, widget, GDK_CURRENT_TIME);
1088 palette_new (GtkColorSelection *colorsel)
1091 ColorSelectionPrivate *priv;
1093 static const GtkTargetEntry targets[] = {
1094 { "application/x-color", 0 }
1097 priv = colorsel->private_data;
1099 retval = gtk_drawing_area_new ();
1101 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1103 g_object_set_data (G_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
1104 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1105 | GDK_BUTTON_RELEASE_MASK
1107 | GDK_ENTER_NOTIFY_MASK
1108 | GDK_LEAVE_NOTIFY_MASK);
1110 g_signal_connect (retval, "expose_event",
1111 G_CALLBACK (palette_expose), colorsel);
1112 g_signal_connect (retval, "button_press_event",
1113 G_CALLBACK (palette_press), colorsel);
1114 g_signal_connect (retval, "button_release_event",
1115 G_CALLBACK (palette_release), colorsel);
1116 g_signal_connect (retval, "enter_notify_event",
1117 G_CALLBACK (palette_enter), colorsel);
1118 g_signal_connect (retval, "leave_notify_event",
1119 G_CALLBACK (palette_leave), colorsel);
1120 g_signal_connect (retval, "key_press_event",
1121 G_CALLBACK (palette_activate), colorsel);
1122 g_signal_connect (retval, "popup_menu",
1123 G_CALLBACK (palette_popup), colorsel);
1125 gtk_drag_dest_set (retval,
1126 GTK_DEST_DEFAULT_HIGHLIGHT |
1127 GTK_DEST_DEFAULT_MOTION |
1128 GTK_DEST_DEFAULT_DROP,
1132 g_signal_connect (retval, "drag_end",
1133 G_CALLBACK (palette_drag_end), NULL);
1134 g_signal_connect (retval, "drag_data_received",
1135 G_CALLBACK (palette_drop_handle), colorsel);
1137 gtk_tooltips_set_tip (priv->tooltips,
1139 _("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.\""),
1147 * The actual GtkColorSelection widget
1152 make_picker_cursor (GdkScreen *screen)
1155 GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
1156 GdkColor fg = { 0, 0x0000, 0x0000, 0x0000 };
1157 GdkWindow *window = gdk_screen_get_root_window (screen);
1160 gdk_bitmap_create_from_data (window, (gchar *) dropper_bits,
1161 DROPPER_WIDTH, DROPPER_HEIGHT);
1164 gdk_bitmap_create_from_data (window, (gchar *) dropper_mask,
1165 DROPPER_WIDTH, DROPPER_HEIGHT);
1167 cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg,
1168 DROPPER_X_HOT, DROPPER_Y_HOT);
1170 g_object_unref (pixmap);
1171 g_object_unref (mask);
1177 grab_color_at_mouse (GdkScreen *screen,
1184 GtkColorSelection *colorsel = data;
1185 ColorSelectionPrivate *priv;
1187 GdkColormap *colormap = gdk_screen_get_system_colormap (screen);
1188 GdkWindow *root_window = gdk_screen_get_root_window (screen);
1190 priv = colorsel->private_data;
1192 image = gdk_drawable_get_image (root_window, x_root, y_root, 1, 1);
1193 pixel = gdk_image_get_pixel (image, 0, 0);
1194 g_object_unref (image);
1196 gdk_colormap_query_color (colormap, pixel, &color);
1198 priv->color[COLORSEL_RED] = SCALE (color.red);
1199 priv->color[COLORSEL_GREEN] = SCALE (color.green);
1200 priv->color[COLORSEL_BLUE] = SCALE (color.blue);
1202 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1203 priv->color[COLORSEL_GREEN],
1204 priv->color[COLORSEL_BLUE],
1205 &priv->color[COLORSEL_HUE],
1206 &priv->color[COLORSEL_SATURATION],
1207 &priv->color[COLORSEL_VALUE]);
1209 update_color (colorsel);
1213 shutdown_eyedropper (GtkWidget *widget)
1215 GtkColorSelection *colorsel;
1216 ColorSelectionPrivate *priv;
1217 GdkDisplay *display = gtk_widget_get_display (widget);
1218 guint32 time = gtk_get_current_event_time ();
1220 colorsel = GTK_COLOR_SELECTION (widget);
1221 priv = colorsel->private_data;
1223 gdk_display_keyboard_ungrab (display, time);
1224 gdk_display_pointer_ungrab (display, time);
1225 gtk_grab_remove (priv->dropper_grab_widget);
1229 mouse_motion (GtkWidget *invisible,
1230 GdkEventMotion *event,
1233 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1234 event->x_root, event->y_root, data);
1238 mouse_release (GtkWidget *invisible,
1239 GdkEventButton *event,
1242 GtkColorSelection *colorsel = data;
1243 ColorSelectionPrivate *priv;
1244 priv = colorsel->private_data;
1246 if (event->button != 1)
1249 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1250 event->x_root, event->y_root, data);
1252 shutdown_eyedropper (GTK_WIDGET (data));
1254 g_signal_handlers_disconnect_by_func (invisible,
1257 g_signal_handlers_disconnect_by_func (invisible,
1264 /* Helper Functions */
1266 static gboolean mouse_press (GtkWidget *invisible,
1267 GdkEventButton *event,
1273 key_press (GtkWidget *invisible,
1277 GdkDisplay *display = gtk_widget_get_display (invisible);
1278 GdkScreen *screen = gdk_event_get_screen ((GdkEvent *)event);
1279 guint state = event->state & gtk_accelerator_get_default_mod_mask ();
1283 gdk_display_get_pointer (display, NULL, &x, &y, NULL);
1288 switch (event->keyval)
1294 grab_color_at_mouse (screen, x, y, data);
1298 shutdown_eyedropper (data);
1300 g_signal_handlers_disconnect_by_func (invisible,
1303 g_signal_handlers_disconnect_by_func (invisible,
1309 #if defined GDK_WINDOWING_X11 || defined GDK_WINDOWING_WIN32
1312 dy = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
1317 dy = state == GDK_MOD1_MASK ? BIG_STEP : 1;
1322 dx = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
1327 dx = state == GDK_MOD1_MASK ? BIG_STEP : 1;
1335 gdk_display_warp_pointer (display, screen, x + dx, y + dy);
1342 mouse_press (GtkWidget *invisible,
1343 GdkEventButton *event,
1346 GtkColorSelection *colorsel = data;
1347 ColorSelectionPrivate *priv;
1348 priv = colorsel->private_data;
1350 if (event->type == GDK_BUTTON_PRESS &&
1353 g_signal_connect (invisible, "motion_notify_event",
1354 G_CALLBACK (mouse_motion),
1356 g_signal_connect (invisible, "button_release_event",
1357 G_CALLBACK (mouse_release),
1359 g_signal_handlers_disconnect_by_func (invisible,
1362 g_signal_handlers_disconnect_by_func (invisible,
1371 /* when the button is clicked */
1373 get_screen_color (GtkWidget *button)
1375 GtkColorSelection *colorsel = g_object_get_data (G_OBJECT (button), "COLORSEL");
1376 ColorSelectionPrivate *priv = colorsel->private_data;
1377 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (button));
1378 GdkCursor *picker_cursor;
1379 GdkGrabStatus grab_status;
1381 if (priv->dropper_grab_widget == NULL)
1383 priv->dropper_grab_widget = gtk_invisible_new_for_screen (screen);
1385 gtk_widget_add_events (priv->dropper_grab_widget,
1386 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1388 gtk_widget_show (priv->dropper_grab_widget);
1391 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1393 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1396 picker_cursor = make_picker_cursor (screen);
1397 grab_status = gdk_pointer_grab (priv->dropper_grab_widget->window,
1399 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1402 gtk_get_current_event_time ());
1403 gdk_cursor_unref (picker_cursor);
1405 if (grab_status != GDK_GRAB_SUCCESS)
1407 gdk_display_keyboard_ungrab (gtk_widget_get_display (button), GDK_CURRENT_TIME);
1411 gtk_grab_add (priv->dropper_grab_widget);
1413 g_signal_connect (priv->dropper_grab_widget, "button_press_event",
1414 G_CALLBACK (mouse_press), colorsel);
1415 g_signal_connect (priv->dropper_grab_widget, "key_press_event",
1416 G_CALLBACK (key_press), colorsel);
1420 hex_changed (GtkWidget *hex_entry,
1423 GtkColorSelection *colorsel;
1424 ColorSelectionPrivate *priv;
1428 colorsel = GTK_COLOR_SELECTION (data);
1429 priv = colorsel->private_data;
1434 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1435 if (gdk_color_parse (text, &color))
1437 priv->color[COLORSEL_RED] = CLAMP (color.red/65535.0, 0.0, 1.0);
1438 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65535.0, 0.0, 1.0);
1439 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65535.0, 0.0, 1.0);
1440 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1441 priv->color[COLORSEL_GREEN],
1442 priv->color[COLORSEL_BLUE],
1443 &priv->color[COLORSEL_HUE],
1444 &priv->color[COLORSEL_SATURATION],
1445 &priv->color[COLORSEL_VALUE]);
1446 update_color (colorsel);
1452 hex_focus_out (GtkWidget *hex_entry,
1453 GdkEventFocus *event,
1456 hex_changed (hex_entry, data);
1462 hsv_changed (GtkWidget *hsv,
1465 GtkColorSelection *colorsel;
1466 ColorSelectionPrivate *priv;
1468 colorsel = GTK_COLOR_SELECTION (data);
1469 priv = colorsel->private_data;
1474 gtk_hsv_get_color (GTK_HSV (hsv),
1475 &priv->color[COLORSEL_HUE],
1476 &priv->color[COLORSEL_SATURATION],
1477 &priv->color[COLORSEL_VALUE]);
1478 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1479 priv->color[COLORSEL_SATURATION],
1480 priv->color[COLORSEL_VALUE],
1481 &priv->color[COLORSEL_RED],
1482 &priv->color[COLORSEL_GREEN],
1483 &priv->color[COLORSEL_BLUE]);
1484 update_color (colorsel);
1488 adjustment_changed (GtkAdjustment *adjustment,
1491 GtkColorSelection *colorsel;
1492 ColorSelectionPrivate *priv;
1494 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (adjustment), "COLORSEL"));
1495 priv = colorsel->private_data;
1500 switch (GPOINTER_TO_INT (data))
1502 case COLORSEL_SATURATION:
1503 case COLORSEL_VALUE:
1504 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 100;
1505 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1506 priv->color[COLORSEL_SATURATION],
1507 priv->color[COLORSEL_VALUE],
1508 &priv->color[COLORSEL_RED],
1509 &priv->color[COLORSEL_GREEN],
1510 &priv->color[COLORSEL_BLUE]);
1513 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1514 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1515 priv->color[COLORSEL_SATURATION],
1516 priv->color[COLORSEL_VALUE],
1517 &priv->color[COLORSEL_RED],
1518 &priv->color[COLORSEL_GREEN],
1519 &priv->color[COLORSEL_BLUE]);
1522 case COLORSEL_GREEN:
1524 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1526 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1527 priv->color[COLORSEL_GREEN],
1528 priv->color[COLORSEL_BLUE],
1529 &priv->color[COLORSEL_HUE],
1530 &priv->color[COLORSEL_SATURATION],
1531 &priv->color[COLORSEL_VALUE]);
1534 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1537 update_color (colorsel);
1541 opacity_entry_changed (GtkWidget *opacity_entry,
1544 GtkColorSelection *colorsel;
1545 ColorSelectionPrivate *priv;
1549 colorsel = GTK_COLOR_SELECTION (data);
1550 priv = colorsel->private_data;
1555 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1556 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1557 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1559 update_color (colorsel);
1565 make_label_spinbutton (GtkColorSelection *colorsel,
1566 GtkWidget **spinbutton,
1572 const gchar *tooltip)
1575 GtkAdjustment *adjust;
1576 ColorSelectionPrivate *priv = colorsel->private_data;
1578 if (channel_type == COLORSEL_HUE)
1580 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1582 else if (channel_type == COLORSEL_SATURATION ||
1583 channel_type == COLORSEL_VALUE)
1585 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 1.0, 1.0));
1589 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1591 g_object_set_data (G_OBJECT (adjust), "COLORSEL", colorsel);
1592 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1594 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1596 g_signal_connect (adjust, "value_changed",
1597 G_CALLBACK (adjustment_changed),
1598 GINT_TO_POINTER (channel_type));
1599 label = gtk_label_new_with_mnemonic (text);
1600 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1602 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1603 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1604 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1608 make_palette_frame (GtkColorSelection *colorsel,
1614 ColorSelectionPrivate *priv;
1616 priv = colorsel->private_data;
1617 frame = gtk_frame_new (NULL);
1618 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1619 priv->custom_palette[i][j] = palette_new (colorsel);
1620 gtk_widget_set_size_request (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1621 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1622 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1625 /* Set the palette entry [x][y] to be the currently selected one. */
1627 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1629 ColorSelectionPrivate *priv = colorsel->private_data;
1631 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1635 scale_round (double val, double factor)
1637 val = floor (val * factor + 0.5);
1639 val = MIN (val, factor);
1644 update_color (GtkColorSelection *colorsel)
1646 ColorSelectionPrivate *priv = colorsel->private_data;
1648 gchar opacity_text[32];
1651 priv->changing = TRUE;
1652 color_sample_draw_samples (colorsel);
1654 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1655 priv->color[COLORSEL_HUE],
1656 priv->color[COLORSEL_SATURATION],
1657 priv->color[COLORSEL_VALUE]);
1658 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1659 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1660 scale_round (priv->color[COLORSEL_HUE], 360));
1661 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1662 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1663 scale_round (priv->color[COLORSEL_SATURATION], 100));
1664 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1665 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1666 scale_round (priv->color[COLORSEL_VALUE], 100));
1667 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1668 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1669 scale_round (priv->color[COLORSEL_RED], 255));
1670 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1671 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1672 scale_round (priv->color[COLORSEL_GREEN], 255));
1673 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1674 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1675 scale_round (priv->color[COLORSEL_BLUE], 255));
1676 gtk_adjustment_set_value (gtk_range_get_adjustment
1677 (GTK_RANGE (priv->opacity_slider)),
1678 scale_round (priv->color[COLORSEL_OPACITY], 255));
1680 g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
1681 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1683 g_snprintf (entryval, 11, "#%2X%2X%2X",
1684 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1685 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1686 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1688 for (ptr = entryval; *ptr; ptr++)
1691 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1692 priv->changing = FALSE;
1694 g_object_ref (colorsel);
1696 g_signal_emit (colorsel, color_selection_signals[COLOR_CHANGED], 0);
1698 g_object_freeze_notify (G_OBJECT (colorsel));
1699 g_object_notify (G_OBJECT (colorsel), "current_color");
1700 g_object_notify (G_OBJECT (colorsel), "current_alpha");
1701 g_object_thaw_notify (G_OBJECT (colorsel));
1703 g_object_unref (colorsel);
1707 update_palette (GtkColorSelection *colorsel)
1709 GdkColor *current_colors;
1712 current_colors = get_current_colors (colorsel);
1714 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1716 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1720 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1722 gtk_color_selection_set_palette_color (colorsel,
1724 ¤t_colors[index]);
1728 g_free (current_colors);
1732 palette_change_notify_instance (GObject *object,
1736 update_palette (GTK_COLOR_SELECTION (data));
1740 default_noscreen_change_palette_func (const GdkColor *colors,
1743 default_change_palette_func (gdk_screen_get_default (), colors, n_colors);
1747 default_change_palette_func (GdkScreen *screen,
1748 const GdkColor *colors,
1753 str = gtk_color_selection_palette_to_string (colors, n_colors);
1755 gtk_settings_set_string_property (gtk_settings_get_for_screen (screen),
1756 "gtk-color-palette",
1758 "gtk_color_selection_palette_to_string");
1764 gtk_color_selection_get_type (void)
1766 static GType color_selection_type = 0;
1768 if (!color_selection_type)
1770 static const GTypeInfo color_selection_info =
1772 sizeof (GtkColorSelectionClass),
1773 NULL, /* base_init */
1774 NULL, /* base_finalize */
1775 (GClassInitFunc) gtk_color_selection_class_init,
1776 NULL, /* class_finalize */
1777 NULL, /* class_data */
1778 sizeof (GtkColorSelection),
1779 0, /* n_preallocs */
1780 (GInstanceInitFunc) gtk_color_selection_init,
1783 color_selection_type =
1784 g_type_register_static (GTK_TYPE_VBOX, "GtkColorSelection",
1785 &color_selection_info, 0);
1788 return color_selection_type;
1792 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1794 GObjectClass *gobject_class;
1795 GtkObjectClass *object_class;
1796 GtkWidgetClass *widget_class;
1798 gobject_class = G_OBJECT_CLASS (klass);
1799 object_class = GTK_OBJECT_CLASS (klass);
1800 widget_class = GTK_WIDGET_CLASS (klass);
1802 parent_class = g_type_class_peek_parent (klass);
1804 object_class->destroy = gtk_color_selection_destroy;
1805 gobject_class->finalize = gtk_color_selection_finalize;
1807 gobject_class->set_property = gtk_color_selection_set_property;
1808 gobject_class->get_property = gtk_color_selection_get_property;
1810 widget_class->realize = gtk_color_selection_realize;
1811 widget_class->unrealize = gtk_color_selection_unrealize;
1812 widget_class->show_all = gtk_color_selection_show_all;
1814 g_object_class_install_property (gobject_class,
1815 PROP_HAS_OPACITY_CONTROL,
1816 g_param_spec_boolean ("has-opacity-control",
1817 P_("Has Opacity Control"),
1818 P_("Whether the color selector should allow setting opacity"),
1820 G_PARAM_READABLE | G_PARAM_WRITABLE));
1821 g_object_class_install_property (gobject_class,
1823 g_param_spec_boolean ("has-palette",
1825 P_("Whether a palette should be used"),
1827 G_PARAM_READABLE | G_PARAM_WRITABLE));
1828 g_object_class_install_property (gobject_class,
1830 g_param_spec_boxed ("current-color",
1831 P_("Current Color"),
1832 P_("The current color"),
1834 G_PARAM_READABLE | G_PARAM_WRITABLE));
1835 g_object_class_install_property (gobject_class,
1837 g_param_spec_uint ("current-alpha",
1838 P_("Current Alpha"),
1839 P_("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1841 G_PARAM_READABLE | G_PARAM_WRITABLE));
1843 color_selection_signals[COLOR_CHANGED] =
1844 g_signal_new ("color_changed",
1845 G_OBJECT_CLASS_TYPE (object_class),
1847 G_STRUCT_OFFSET (GtkColorSelectionClass, color_changed),
1849 _gtk_marshal_VOID__VOID,
1852 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1853 P_("Custom palette"),
1854 P_("Palette to use in the color selector"),
1856 G_PARAM_READWRITE));
1859 /* widget functions */
1862 gtk_color_selection_init (GtkColorSelection *colorsel)
1864 GtkWidget *top_hbox;
1865 GtkWidget *top_right_vbox;
1866 GtkWidget *table, *label, *hbox, *frame, *vbox, *button;
1867 GtkAdjustment *adjust;
1868 GtkWidget *picker_image;
1870 ColorSelectionPrivate *priv;
1873 gtk_widget_push_composite_child ();
1875 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1876 priv->changing = FALSE;
1877 priv->default_set = FALSE;
1878 priv->default_alpha_set = FALSE;
1880 priv->tooltips = gtk_tooltips_new ();
1881 g_object_ref (priv->tooltips);
1882 gtk_object_sink (GTK_OBJECT (priv->tooltips));
1884 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1885 top_hbox = gtk_hbox_new (FALSE, 8);
1886 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1888 vbox = gtk_vbox_new (FALSE, 4);
1889 priv->triangle_colorsel = gtk_hsv_new ();
1890 g_signal_connect (priv->triangle_colorsel, "changed",
1891 G_CALLBACK (hsv_changed), colorsel);
1892 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1893 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1894 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1895 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1896 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1898 hbox = gtk_hbox_new (FALSE, 4);
1899 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1901 frame = gtk_frame_new (NULL);
1902 gtk_widget_set_size_request (frame, -1, 30);
1903 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1904 color_sample_new (colorsel);
1905 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1906 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1908 button = gtk_button_new ();
1910 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1911 g_object_set_data (G_OBJECT (button), "COLORSEL", colorsel);
1912 g_signal_connect (button, "clicked",
1913 G_CALLBACK (get_screen_color), NULL);
1914 picker_image = gtk_image_new_from_stock (GTK_STOCK_COLOR_PICKER, GTK_ICON_SIZE_BUTTON);
1915 gtk_container_add (GTK_CONTAINER (button), picker_image);
1916 gtk_widget_show (GTK_WIDGET (picker_image));
1917 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1919 gtk_tooltips_set_tip (priv->tooltips,
1921 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1923 top_right_vbox = gtk_vbox_new (FALSE, 4);
1924 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1925 table = gtk_table_new (8, 6, FALSE);
1926 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1927 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1928 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1930 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1931 _("Position on the color wheel."));
1932 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (priv->hue_spinbutton), TRUE);
1933 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1934 _("\"Deepness\" of the color."));
1935 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1936 _("Brightness of the color."));
1937 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1938 _("Amount of red light in the color."));
1939 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1940 _("Amount of green light in the color."));
1941 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1942 _("Amount of blue light in the color."));
1943 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1945 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1946 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1947 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1948 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1949 g_object_set_data (G_OBJECT (adjust), "COLORSEL", colorsel);
1950 priv->opacity_slider = gtk_hscale_new (adjust);
1951 gtk_tooltips_set_tip (priv->tooltips,
1952 priv->opacity_slider,
1953 _("Transparency of the color."), NULL);
1954 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1955 priv->opacity_slider);
1956 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1957 g_signal_connect (adjust, "value_changed",
1958 G_CALLBACK (adjustment_changed),
1959 GINT_TO_POINTER (COLORSEL_OPACITY));
1960 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1961 priv->opacity_entry = gtk_entry_new ();
1962 gtk_tooltips_set_tip (priv->tooltips,
1963 priv->opacity_entry,
1964 _("Transparency of the color."), NULL);
1965 gtk_widget_set_size_request (priv->opacity_entry, 40, -1);
1967 g_signal_connect (priv->opacity_entry, "activate",
1968 G_CALLBACK (opacity_entry_changed), colorsel);
1969 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1971 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1972 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1973 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1974 priv->hex_entry = gtk_entry_new ();
1976 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1978 g_signal_connect (priv->hex_entry, "activate",
1979 G_CALLBACK (hex_changed), colorsel);
1981 g_signal_connect (priv->hex_entry, "focus_out_event",
1982 G_CALLBACK (hex_focus_out), colorsel);
1984 gtk_tooltips_set_tip (priv->tooltips,
1986 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1988 gtk_entry_set_width_chars (GTK_ENTRY (priv->hex_entry), 7);
1989 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1990 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1992 /* Set up the palette */
1993 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1994 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1995 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1996 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1998 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
2000 make_palette_frame (colorsel, table, i, j);
2003 set_selected_palette (colorsel, 0, 0);
2004 priv->palette_frame = gtk_frame_new (NULL);
2005 label = gtk_label_new_with_mnemonic (_("_Palette"));
2006 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
2008 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
2009 priv->custom_palette[0][0]);
2011 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
2012 vbox = gtk_vbox_new (FALSE, 4);
2013 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
2014 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
2016 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
2018 gtk_widget_show_all (top_hbox);
2020 /* hide unused stuff */
2022 if (priv->has_opacity == FALSE)
2024 gtk_widget_hide (priv->opacity_label);
2025 gtk_widget_hide (priv->opacity_slider);
2026 gtk_widget_hide (priv->opacity_entry);
2029 if (priv->has_palette == FALSE)
2031 gtk_widget_hide (priv->palette_frame);
2034 atk_obj = gtk_widget_get_accessible (priv->triangle_colorsel);
2035 if (GTK_IS_ACCESSIBLE (atk_obj))
2037 atk_object_set_name (atk_obj, _("Color Wheel"));
2038 atk_object_set_role (gtk_widget_get_accessible (GTK_WIDGET (colorsel)), ATK_ROLE_COLOR_CHOOSER);
2039 make_all_relations (atk_obj, priv);
2042 gtk_widget_pop_composite_child ();
2046 gtk_color_selection_destroy (GtkObject *object)
2048 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
2049 ColorSelectionPrivate *priv = cselection->private_data;
2051 if (priv->dropper_grab_widget)
2053 gtk_widget_destroy (priv->dropper_grab_widget);
2054 priv->dropper_grab_widget = NULL;
2059 g_object_unref (priv->tooltips);
2060 priv->tooltips = NULL;
2063 GTK_OBJECT_CLASS (parent_class)->destroy (object);
2067 gtk_color_selection_finalize (GObject *object)
2069 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
2071 if (cselection->private_data)
2073 g_free (cselection->private_data);
2074 cselection->private_data = NULL;
2077 G_OBJECT_CLASS (parent_class)->finalize (object);
2081 gtk_color_selection_realize (GtkWidget *widget)
2083 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
2084 ColorSelectionPrivate *priv = colorsel->private_data;
2085 GtkSettings *settings = gtk_widget_get_settings (widget);
2087 priv->settings_connection = g_signal_connect (settings,
2088 "notify::gtk-color-palette",
2089 G_CALLBACK (palette_change_notify_instance),
2091 update_palette (colorsel);
2093 GTK_WIDGET_CLASS (parent_class)->realize (widget);
2097 gtk_color_selection_unrealize (GtkWidget *widget)
2099 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
2100 ColorSelectionPrivate *priv = colorsel->private_data;
2101 GtkSettings *settings = gtk_widget_get_settings (widget);
2103 g_signal_handler_disconnect (settings, priv->settings_connection);
2105 GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
2108 /* We override show-all since we have internal widgets that
2109 * shouldn't be shown when you call show_all(), like the
2110 * palette and opacity sliders.
2113 gtk_color_selection_show_all (GtkWidget *widget)
2115 gtk_widget_show (widget);
2119 * gtk_color_selection_new:
2121 * Creates a new GtkColorSelection.
2123 * Return value: a new #GtkColorSelection
2126 gtk_color_selection_new (void)
2128 GtkColorSelection *colorsel;
2129 ColorSelectionPrivate *priv;
2136 colorsel = g_object_new (GTK_TYPE_COLOR_SELECTION, NULL);
2137 priv = colorsel->private_data;
2138 set_color_internal (colorsel, color);
2139 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
2141 /* We want to make sure that default_set is FALSE */
2142 /* This way the user can still set it */
2143 priv->default_set = FALSE;
2144 priv->default_alpha_set = FALSE;
2146 return GTK_WIDGET (colorsel);
2151 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
2152 GtkUpdateType policy)
2154 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2158 * gtk_color_selection_get_has_opacity_control:
2159 * @colorsel: a #GtkColorSelection.
2161 * Determines whether the colorsel has an opacity control.
2163 * Return value: %TRUE if the @colorsel has an opacity control. %FALSE if it does't.
2166 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2168 ColorSelectionPrivate *priv;
2170 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2172 priv = colorsel->private_data;
2174 return priv->has_opacity;
2178 * gtk_color_selection_set_has_opacity_control:
2179 * @colorsel: a #GtkColorSelection.
2180 * @has_opacity: %TRUE if @colorsel can set the opacity, %FALSE otherwise.
2182 * Sets the @colorsel to use or not use opacity.
2186 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2187 gboolean has_opacity)
2189 ColorSelectionPrivate *priv;
2191 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2193 priv = colorsel->private_data;
2194 has_opacity = has_opacity != FALSE;
2196 if (priv->has_opacity != has_opacity)
2198 priv->has_opacity = has_opacity;
2201 gtk_widget_show (priv->opacity_slider);
2202 gtk_widget_show (priv->opacity_label);
2203 gtk_widget_show (priv->opacity_entry);
2207 gtk_widget_hide (priv->opacity_slider);
2208 gtk_widget_hide (priv->opacity_label);
2209 gtk_widget_hide (priv->opacity_entry);
2211 color_sample_draw_samples (colorsel);
2213 g_object_notify (G_OBJECT (colorsel), "has_opacity_control");
2218 * gtk_color_selection_get_has_palette:
2219 * @colorsel: a #GtkColorSelection.
2221 * Determines whether the color selector has a color palette.
2223 * Return value: %TRUE if the selector has a palette. %FALSE if it hasn't.
2226 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2228 ColorSelectionPrivate *priv;
2230 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2232 priv = colorsel->private_data;
2234 return priv->has_palette;
2238 * gtk_color_selection_set_has_palette:
2239 * @colorsel: a #GtkColorSelection.
2240 * @has_palette: %TRUE if palette is to be visible, %FALSE otherwise.
2242 * Shows and hides the palette based upon the value of @has_palette.
2246 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2247 gboolean has_palette)
2249 ColorSelectionPrivate *priv;
2250 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2252 priv = colorsel->private_data;
2253 has_palette = has_palette != FALSE;
2255 if (priv->has_palette != has_palette)
2257 priv->has_palette = has_palette;
2259 gtk_widget_show (priv->palette_frame);
2261 gtk_widget_hide (priv->palette_frame);
2263 g_object_notify (G_OBJECT (colorsel), "has_palette");
2268 * gtk_color_selection_set_current_color:
2269 * @colorsel: a #GtkColorSelection.
2270 * @color: A #GdkColor to set the current color with.
2272 * Sets the current color to be @color. The first time this is called, it will
2273 * also set the original color to be @color too.
2276 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2277 const GdkColor *color)
2279 ColorSelectionPrivate *priv;
2281 gboolean previous_changed;
2283 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2284 g_return_if_fail (color != NULL);
2286 priv = colorsel->private_data;
2287 priv->changing = TRUE;
2288 priv->color[COLORSEL_RED] = SCALE (color->red);
2289 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2290 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2291 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2292 priv->color[COLORSEL_GREEN],
2293 priv->color[COLORSEL_BLUE],
2294 &priv->color[COLORSEL_HUE],
2295 &priv->color[COLORSEL_SATURATION],
2296 &priv->color[COLORSEL_VALUE]);
2297 if (priv->default_set == FALSE)
2299 previous_changed = TRUE;
2300 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2301 priv->old_color[i] = priv->color[i];
2303 priv->default_set = TRUE;
2304 update_color (colorsel);
2308 * gtk_color_selection_set_current_alpha:
2309 * @colorsel: a #GtkColorSelection.
2310 * @alpha: an integer between 0 and 65535.
2312 * Sets the current opacity to be @alpha. The first time this is called, it will
2313 * also set the original opacity to be @alpha too.
2316 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2319 ColorSelectionPrivate *priv;
2322 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2324 priv = colorsel->private_data;
2325 priv->changing = TRUE;
2326 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2327 if (priv->default_alpha_set == FALSE)
2329 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2330 priv->old_color[i] = priv->color[i];
2332 priv->default_alpha_set = TRUE;
2333 update_color (colorsel);
2337 * gtk_color_selection_set_color:
2338 * @colorsel: a #GtkColorSelection.
2339 * @color: an array of 4 doubles specifying the red, green, blue and opacity
2340 * to set the current color to.
2342 * Sets the current color to be @color. The first time this is called, it will
2343 * also set the original color to be @color too.
2345 * Deprecated: Use gtk_color_selection_set_current_color() instead.
2348 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2351 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2353 set_color_internal (colorsel, color);
2357 * gtk_color_selection_get_current_color:
2358 * @colorsel: a #GtkColorSelection.
2359 * @color: a #GdkColor to fill in with the current color.
2361 * Sets @color to be the current color in the GtkColorSelection widget.
2364 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2367 ColorSelectionPrivate *priv;
2369 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2370 g_return_if_fail (color != NULL);
2372 priv = colorsel->private_data;
2373 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2374 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2375 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2379 * gtk_color_selection_get_current_alpha:
2380 * @colorsel: a #GtkColorSelection.
2382 * Returns the current alpha value.
2384 * Return value: an integer between 0 and 65535.
2387 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2389 ColorSelectionPrivate *priv;
2391 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2393 priv = colorsel->private_data;
2394 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2398 * gtk_color_selection_get_color:
2399 * @colorsel: a #GtkColorSelection.
2400 * @color: an array of 4 #gdouble to fill in with the current color.
2402 * Sets @color to be the current color in the GtkColorSelection widget.
2404 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2407 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2410 ColorSelectionPrivate *priv;
2412 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2414 priv = colorsel->private_data;
2415 color[0] = priv->color[COLORSEL_RED];
2416 color[1] = priv->color[COLORSEL_GREEN];
2417 color[2] = priv->color[COLORSEL_BLUE];
2418 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2422 * gtk_color_selection_set_previous_color:
2423 * @colorsel: a #GtkColorSelection.
2424 * @color: a #GdkColor to set the previous color with.
2426 * Sets the 'previous' color to be @color. This function should be called with
2427 * some hesitations, as it might seem confusing to have that color change.
2428 * Calling gtk_color_selection_set_current_color() will also set this color the first
2429 * time it is called.
2432 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2433 const GdkColor *color)
2435 ColorSelectionPrivate *priv;
2437 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2438 g_return_if_fail (color != NULL);
2440 priv = colorsel->private_data;
2441 priv->changing = TRUE;
2442 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2443 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2444 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2445 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2446 priv->old_color[COLORSEL_GREEN],
2447 priv->old_color[COLORSEL_BLUE],
2448 &priv->old_color[COLORSEL_HUE],
2449 &priv->old_color[COLORSEL_SATURATION],
2450 &priv->old_color[COLORSEL_VALUE]);
2451 color_sample_draw_samples (colorsel);
2452 priv->default_set = TRUE;
2453 priv->changing = FALSE;
2457 * gtk_color_selection_set_previous_alpha:
2458 * @colorsel: a #GtkColorSelection.
2459 * @alpha: an integer between 0 and 65535.
2461 * Sets the 'previous' alpha to be @alpha. This function should be called with
2462 * some hesitations, as it might seem confusing to have that alpha change.
2465 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2468 ColorSelectionPrivate *priv;
2470 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2472 priv = colorsel->private_data;
2473 priv->changing = TRUE;
2474 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2475 color_sample_draw_samples (colorsel);
2476 priv->default_alpha_set = TRUE;
2477 priv->changing = FALSE;
2482 * gtk_color_selection_get_previous_color:
2483 * @colorsel: a #GtkColorSelection.
2484 * @color: a #GdkColor to fill in with the original color value.
2486 * Fills @color in with the original color value.
2489 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2492 ColorSelectionPrivate *priv;
2494 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2495 g_return_if_fail (color != NULL);
2497 priv = colorsel->private_data;
2498 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2499 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2500 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2504 * gtk_color_selection_get_previous_alpha:
2505 * @colorsel: a #GtkColorSelection.
2507 * Returns the previous alpha value.
2509 * Return value: an integer between 0 and 65535.
2512 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2514 ColorSelectionPrivate *priv;
2516 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2518 priv = colorsel->private_data;
2519 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2523 * gtk_color_selection_set_palette_color:
2524 * @colorsel: a #GtkColorSelection.
2525 * @index: the color index of the palette.
2526 * @color: A #GdkColor to set the palette with.
2528 * Sets the palette located at @index to have @color as its color.
2532 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2536 ColorSelectionPrivate *priv;
2540 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2541 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2543 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2544 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2546 priv = colorsel->private_data;
2547 col[0] = SCALE (color->red);
2548 col[1] = SCALE (color->green);
2549 col[2] = SCALE (color->blue);
2551 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2555 * gtk_color_selection_is_adjusting:
2556 * @colorsel: a #GtkColorSelection.
2558 * Gets the current state of the @colorsel.
2560 * Return value: %TRUE if the user is currently dragging a color around, and %FALSE
2561 * if the selection has stopped.
2564 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2566 ColorSelectionPrivate *priv;
2568 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2570 priv = colorsel->private_data;
2572 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2576 gtk_color_selection_set_property (GObject *object,
2578 const GValue *value,
2581 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2585 case PROP_HAS_OPACITY_CONTROL:
2586 gtk_color_selection_set_has_opacity_control (colorsel,
2587 g_value_get_boolean (value));
2589 case PROP_HAS_PALETTE:
2590 gtk_color_selection_set_has_palette (colorsel,
2591 g_value_get_boolean (value));
2593 case PROP_CURRENT_COLOR:
2594 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2596 case PROP_CURRENT_ALPHA:
2597 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2600 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2607 gtk_color_selection_get_property (GObject *object,
2612 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2617 case PROP_HAS_OPACITY_CONTROL:
2618 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2620 case PROP_HAS_PALETTE:
2621 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2623 case PROP_CURRENT_COLOR:
2624 gtk_color_selection_get_current_color (colorsel, &color);
2625 g_value_set_boxed (value, &color);
2627 case PROP_CURRENT_ALPHA:
2628 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2631 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2638 * gtk_color_selection_palette_from_string:
2639 * @str: a string encoding a color palette.
2640 * @colors: return location for allocated array of #GdkColor.
2641 * @n_colors: return location for length of array.
2643 * Parses a color palette string; the string is a colon-separated
2644 * list of color names readable by gdk_color_parse().
2646 * Return value: %TRUE if a palette was successfully parsed.
2649 gtk_color_selection_palette_from_string (const gchar *str,
2661 copy = g_strdup (str);
2667 if (*p == ':' || *p == '\0')
2669 gboolean done = TRUE;
2673 goto failed; /* empty entry */
2682 retval = g_renew (GdkColor, retval, count + 1);
2683 if (!gdk_color_parse (start, retval + count))
2724 * gtk_color_selection_palette_to_string:
2725 * @colors: an array of colors.
2726 * @n_colors: length of the array.
2728 * Encodes a palette as a string, useful for persistent storage.
2730 * Return value: allocated string encoding the palette.
2733 gtk_color_selection_palette_to_string (const GdkColor *colors,
2737 gchar **strs = NULL;
2741 return g_strdup ("");
2743 strs = g_new0 (gchar*, n_colors + 1);
2746 while (i < n_colors)
2751 g_strdup_printf ("#%2X%2X%2X",
2752 colors[i].red / 256,
2753 colors[i].green / 256,
2754 colors[i].blue / 256);
2756 for (ptr = strs[i]; *ptr; ptr++)
2763 retval = g_strjoinv (":", strs);
2771 * gtk_color_selection_set_change_palette_hook:
2772 * @func: a function to call when the custom palette needs saving.
2774 * Installs a global function to be called whenever the user tries to
2775 * modify the palette in a color selection. This function should save
2776 * the new palette contents, and update the GtkSettings property
2777 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2779 * Return value: the previous change palette hook (that was replaced).
2781 * Deprecated: This function is deprecated in favor of
2782 * gtk_color_selection_set_change_palette_with_screen_hook(), and does
2783 * not work in multihead environments.
2786 GtkColorSelectionChangePaletteFunc
2787 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2789 GtkColorSelectionChangePaletteFunc old;
2791 old = noscreen_change_palette_hook;
2793 noscreen_change_palette_hook = func;
2799 * gtk_color_selection_set_change_palette_with_screen_hook:
2800 * @func: a function to call when the custom palette needs saving.
2802 * Installs a global function to be called whenever the user tries to
2803 * modify the palette in a color selection. This function should save
2804 * the new palette contents, and update the GtkSettings property
2805 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2807 * Return value: the previous change palette hook (that was replaced).
2811 GtkColorSelectionChangePaletteWithScreenFunc
2812 gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func)
2814 GtkColorSelectionChangePaletteWithScreenFunc old;
2816 old = change_palette_hook;
2818 change_palette_hook = func;
2824 make_control_relations (AtkObject *atk_obj,
2829 obj = gtk_widget_get_accessible (widget);
2830 atk_object_add_relationship (atk_obj, ATK_RELATION_CONTROLLED_BY, obj);
2831 atk_object_add_relationship (obj, ATK_RELATION_CONTROLLER_FOR, atk_obj);
2835 make_all_relations (AtkObject *atk_obj,
2836 ColorSelectionPrivate *priv)
2838 make_control_relations (atk_obj, priv->hue_spinbutton);
2839 make_control_relations (atk_obj, priv->sat_spinbutton);
2840 make_control_relations (atk_obj, priv->val_spinbutton);
2841 make_control_relations (atk_obj, priv->red_spinbutton);
2842 make_control_relations (atk_obj, priv->green_spinbutton);
2843 make_control_relations (atk_obj, priv->blue_spinbutton);