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"
32 #include "gdk/gdkkeysyms.h"
33 #include "gtkcolorsel.h"
35 #include "gtkwindow.h"
36 #include "gtkselection.h"
38 #include "gtkdrawingarea.h"
45 #include "gtkmarshalers.h"
47 #include "gtkspinbutton.h"
49 #include "gtkhscale.h"
51 #include "gtkbutton.h"
52 #include "gtkhseparator.h"
53 #include "gtktooltips.h"
54 #include "gtkinvisible.h"
55 #include "gtkmenuitem.h"
57 #include "gtksettings.h"
64 /* Number of elements in the custom palatte */
65 #define GTK_CUSTOM_PALETTE_WIDTH 10
66 #define GTK_CUSTOM_PALETTE_HEIGHT 2
68 /* Conversion between 0->1 double and and guint16. See
69 * scale_round() below for more general conversions
71 #define SCALE(i) (i / 65535.)
72 #define UNSCALE(d) ((guint16)(d * 65535 + 0.5))
83 PROP_HAS_OPACITY_CONTROL,
99 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
101 struct _ColorSelectionPrivate
103 guint has_opacity : 1;
104 guint has_palette : 1;
106 guint default_set : 1;
107 guint default_alpha_set : 1;
109 gdouble color[COLORSEL_NUM_CHANNELS];
110 gdouble old_color[COLORSEL_NUM_CHANNELS];
112 GtkWidget *triangle_colorsel;
113 GtkWidget *hue_spinbutton;
114 GtkWidget *sat_spinbutton;
115 GtkWidget *val_spinbutton;
116 GtkWidget *red_spinbutton;
117 GtkWidget *green_spinbutton;
118 GtkWidget *blue_spinbutton;
119 GtkWidget *opacity_slider;
120 GtkWidget *opacity_label;
121 GtkWidget *opacity_entry;
122 GtkWidget *palette_frame;
123 GtkWidget *hex_entry;
125 /* The Palette code */
126 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
128 /* The color_sample stuff */
129 GtkWidget *sample_area;
130 GtkWidget *old_sample;
131 GtkWidget *cur_sample;
135 GtkTooltips *tooltips;
137 /* Window for grabbing on */
138 GtkWidget *dropper_grab_widget;
140 /* Connection to settings */
141 gulong settings_connection;
145 static void gtk_color_selection_init (GtkColorSelection *colorsel);
146 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
147 static void gtk_color_selection_destroy (GtkObject *object);
148 static void gtk_color_selection_finalize (GObject *object);
149 static void update_color (GtkColorSelection *colorsel);
150 static void gtk_color_selection_set_property (GObject *object,
154 static void gtk_color_selection_get_property (GObject *object,
159 static void gtk_color_selection_realize (GtkWidget *widget);
160 static void gtk_color_selection_unrealize (GtkWidget *widget);
161 static void gtk_color_selection_show_all (GtkWidget *widget);
163 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
166 static GdkGC *get_focus_gc (GtkWidget *drawing_area,
168 static void default_noscreen_change_palette_func (const GdkColor *colors,
170 static void default_change_palette_func (GdkScreen *screen,
171 const GdkColor *colors,
174 static gpointer parent_class = NULL;
175 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
177 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";
179 static GtkColorSelectionChangePaletteFunc noscreen_change_palette_hook = default_noscreen_change_palette_func;
180 static GtkColorSelectionChangePaletteWithScreenFunc change_palette_hook = default_change_palette_func;
182 /* The cursor for the dropper */
183 #define DROPPER_WIDTH 17
184 #define DROPPER_HEIGHT 17
185 #define DROPPER_X_HOT 2
186 #define DROPPER_Y_HOT 16
189 static const guchar dropper_bits[] = {
190 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
191 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
192 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
193 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
196 static const guchar dropper_mask[] = {
197 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
198 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
199 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
200 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
209 #define SAMPLE_WIDTH 64
210 #define SAMPLE_HEIGHT 28
212 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
213 static void color_sample_draw_samples (GtkColorSelection *colorsel);
216 set_color_internal (GtkColorSelection *colorsel,
219 ColorSelectionPrivate *priv;
222 priv = colorsel->private_data;
223 priv->changing = TRUE;
224 priv->color[COLORSEL_RED] = color[0];
225 priv->color[COLORSEL_GREEN] = color[1];
226 priv->color[COLORSEL_BLUE] = color[2];
227 priv->color[COLORSEL_OPACITY] = color[3];
228 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
229 priv->color[COLORSEL_GREEN],
230 priv->color[COLORSEL_BLUE],
231 &priv->color[COLORSEL_HUE],
232 &priv->color[COLORSEL_SATURATION],
233 &priv->color[COLORSEL_VALUE]);
234 if (priv->default_set == FALSE)
236 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
237 priv->old_color[i] = priv->color[i];
239 priv->default_set = TRUE;
240 priv->default_alpha_set = TRUE;
241 update_color (colorsel);
245 set_color_icon (GdkDragContext *context,
251 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
254 pixel = (((UNSCALE (colors[COLORSEL_RED]) & 0xff00) << 16) |
255 ((UNSCALE (colors[COLORSEL_GREEN]) & 0xff00) << 8) |
256 ((UNSCALE (colors[COLORSEL_BLUE]) & 0xff00)));
258 gdk_pixbuf_fill (pixbuf, pixel);
260 gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
261 g_object_unref (pixbuf);
265 color_sample_drag_begin (GtkWidget *widget,
266 GdkDragContext *context,
269 GtkColorSelection *colorsel = data;
270 ColorSelectionPrivate *priv;
273 priv = colorsel->private_data;
275 if (widget == priv->old_sample)
276 colsrc = priv->old_color;
278 colsrc = priv->color;
280 set_color_icon (context, colsrc);
284 color_sample_drag_end (GtkWidget *widget,
285 GdkDragContext *context,
288 g_object_set_data (G_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
292 color_sample_drop_handle (GtkWidget *widget,
293 GdkDragContext *context,
296 GtkSelectionData *selection_data,
301 GtkColorSelection *colorsel = data;
302 ColorSelectionPrivate *priv;
305 priv = colorsel->private_data;
307 /* This is currently a guint16 array of the format:
314 if (selection_data->length < 0)
317 /* We accept drops with the wrong format, since the KDE color
318 * chooser incorrectly drops application/x-color with format 8.
320 if (selection_data->length != 8)
322 g_warning ("Received invalid color data\n");
326 vals = (guint16 *)selection_data->data;
328 if (widget == priv->cur_sample)
330 color[0] = (gdouble)vals[0] / 0xffff;
331 color[1] = (gdouble)vals[1] / 0xffff;
332 color[2] = (gdouble)vals[2] / 0xffff;
333 color[3] = (gdouble)vals[3] / 0xffff;
335 set_color_internal (colorsel, color);
340 color_sample_drag_handle (GtkWidget *widget,
341 GdkDragContext *context,
342 GtkSelectionData *selection_data,
347 GtkColorSelection *colorsel = data;
348 ColorSelectionPrivate *priv;
352 priv = colorsel->private_data;
354 if (widget == priv->old_sample)
355 colsrc = priv->old_color;
357 colsrc = priv->color;
359 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
360 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
361 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
362 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
364 gtk_selection_data_set (selection_data,
365 gdk_atom_intern ("application/x-color", FALSE),
366 16, (guchar *)vals, 8);
369 /* which = 0 means draw old sample, which = 1 means draw new */
371 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
374 gint x, y, i, wid, heig, f, n, goff;
375 guchar c[3 * 2], cc[3 * 4], *cp = c;
378 ColorSelectionPrivate *priv;
380 g_return_if_fail (colorsel != NULL);
381 priv = colorsel->private_data;
383 g_return_if_fail (priv->sample_area != NULL);
384 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
389 da = priv->old_sample;
390 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
391 c[n] = (guchar) (UNSCALE (priv->old_color[i]) >> 8);
396 da = priv->cur_sample;
397 for (n = 0, i = COLORSEL_RED; n < 3; n++, i++)
398 c[n] = (guchar) (UNSCALE (priv->color[i]) >> 8);
399 goff = priv->old_sample->allocation.width % 32;
402 wid = da->allocation.width;
403 heig = da->allocation.height;
405 buf = g_new (guchar, 3 * wid * heig);
409 for (n = 0; n < 3; n++)
411 c[n] = (guchar) (255.0 * priv->old_color[i]);
412 c[n + 3] = (guchar) (255.0 * priv->color[i++]);
416 if (priv->has_opacity)
418 o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY];
420 for (n = 0; n < 3; n++)
422 cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n]));
423 cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n]));
429 for (y = 0; y < heig; y++)
431 for (x = 0; x < wid; x++)
433 if (priv->has_opacity)
434 f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16));
438 for (n = 0; n < 3; n++)
439 buf[i++] = cp[n + f];
443 gdk_draw_rgb_image (da->window,
447 GDK_RGB_DITHER_NORMAL,
457 color_sample_draw_samples (GtkColorSelection *colorsel)
459 color_sample_draw_sample (colorsel, 0);
460 color_sample_draw_sample (colorsel, 1);
464 color_old_sample_expose (GtkWidget *da,
465 GdkEventExpose *event,
466 GtkColorSelection *colorsel)
468 color_sample_draw_sample (colorsel, 0);
474 color_cur_sample_expose (GtkWidget *da,
475 GdkEventExpose *event,
476 GtkColorSelection *colorsel)
478 color_sample_draw_sample (colorsel, 1);
483 color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
485 static const GtkTargetEntry targets[] = {
486 { "application/x-color", 0 }
488 ColorSelectionPrivate *priv;
489 priv = colorsel->private_data;
491 gtk_drag_source_set (sample,
492 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
494 GDK_ACTION_COPY | GDK_ACTION_MOVE);
496 g_signal_connect (sample,
498 G_CALLBACK (color_sample_drag_begin),
500 if (sample == priv->cur_sample)
503 gtk_drag_dest_set (sample,
504 GTK_DEST_DEFAULT_HIGHLIGHT |
505 GTK_DEST_DEFAULT_MOTION |
506 GTK_DEST_DEFAULT_DROP,
510 g_signal_connect (sample,
512 G_CALLBACK (color_sample_drag_end),
516 g_signal_connect (sample,
518 G_CALLBACK (color_sample_drag_handle),
520 g_signal_connect (sample,
521 "drag_data_received",
522 G_CALLBACK (color_sample_drop_handle),
529 color_sample_new (GtkColorSelection *colorsel)
531 ColorSelectionPrivate *priv;
533 priv = colorsel->private_data;
535 priv->sample_area = gtk_hbox_new (FALSE, 0);
536 priv->old_sample = gtk_drawing_area_new ();
537 priv->cur_sample = gtk_drawing_area_new ();
539 /* We need enter/leave to do tooltips */
540 gtk_widget_add_events (priv->old_sample,
541 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
542 gtk_widget_add_events (priv->cur_sample,
543 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
545 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
547 gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
550 g_signal_connect (priv->old_sample, "expose_event",
551 G_CALLBACK (color_old_sample_expose),
553 g_signal_connect (priv->cur_sample, "expose_event",
554 G_CALLBACK (color_cur_sample_expose),
557 color_sample_setup_dnd (colorsel, priv->old_sample);
558 color_sample_setup_dnd (colorsel, priv->cur_sample);
560 gtk_tooltips_set_tip (priv->tooltips,
562 _("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);
565 gtk_tooltips_set_tip (priv->tooltips,
567 _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."), NULL);
569 gtk_widget_show_all (priv->sample_area);
575 * The palette area code
578 #define CUSTOM_PALETTE_ENTRY_WIDTH 20
579 #define CUSTOM_PALETTE_ENTRY_HEIGHT 20
582 palette_get_color (GtkWidget *drawing_area, gdouble *color)
586 g_return_if_fail (color != NULL);
588 color_val = g_object_get_data (G_OBJECT (drawing_area), "color_val");
589 if (color_val == NULL)
591 /* Default to white for no good reason */
599 color[0] = color_val[0];
600 color[1] = color_val[1];
601 color[2] = color_val[2];
605 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
607 palette_paint (GtkWidget *drawing_area,
611 if (drawing_area->window == NULL)
614 gdk_draw_rectangle (drawing_area->window,
615 drawing_area->style->bg_gc[GTK_STATE_NORMAL],
617 area->x, area->y, area->width, area->height);
619 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
622 GdkGC *gc = get_focus_gc (drawing_area, &focus_width);
623 gdk_draw_rectangle (drawing_area->window,
624 gc, FALSE, focus_width / 2, focus_width / 2,
625 drawing_area->allocation.width - focus_width,
626 drawing_area->allocation.height - focus_width);
632 get_focus_gc (GtkWidget *drawing_area,
635 GdkGC *gc = gdk_gc_new (drawing_area->window);
639 gtk_widget_style_get (drawing_area,
640 "focus-line-width", focus_width,
641 "focus-line-pattern", (gchar *)&dash_list,
644 palette_get_color (drawing_area, color);
646 if (INTENSITY (color[0], color[1], color[2]) > 0.5)
647 gdk_gc_copy (gc, drawing_area->style->black_gc);
649 gdk_gc_copy (gc, drawing_area->style->white_gc);
651 gdk_gc_set_line_attributes (gc, *focus_width,
652 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
653 GDK_CAP_BUTT, GDK_JOIN_MITER);
656 gdk_gc_set_dashes (gc, 0, dash_list, strlen ((char *)dash_list));
664 palette_drag_begin (GtkWidget *widget,
665 GdkDragContext *context,
670 palette_get_color (widget, colors);
671 set_color_icon (context, colors);
675 palette_drag_handle (GtkWidget *widget,
676 GdkDragContext *context,
677 GtkSelectionData *selection_data,
685 palette_get_color (widget, colsrc);
687 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
688 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
689 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
692 gtk_selection_data_set (selection_data,
693 gdk_atom_intern ("application/x-color", FALSE),
694 16, (guchar *)vals, 8);
698 palette_drag_end (GtkWidget *widget,
699 GdkDragContext *context,
702 g_object_set_data (G_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
706 get_current_colors (GtkColorSelection *colorsel)
708 GtkSettings *settings;
709 GdkColor *colors = NULL;
713 settings = gtk_widget_get_settings (GTK_WIDGET (colorsel));
714 g_object_get (settings,
715 "gtk-color-palette", &palette,
718 if (!gtk_color_selection_palette_from_string (palette, &colors, &n_colors))
720 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
724 /* If there are less colors provided than the number of slots in the
725 * color selection, we fill in the rest from the defaults.
727 if (n_colors < (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
729 GdkColor *tmp_colors = colors;
730 gint tmp_n_colors = n_colors;
732 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
733 memcpy (colors, tmp_colors, sizeof (GdkColor) * tmp_n_colors);
739 g_assert (n_colors >= GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
745 /* Changes the model color */
747 palette_change_color (GtkWidget *drawing_area,
748 GtkColorSelection *colorsel,
752 ColorSelectionPrivate *priv;
754 GdkColor *current_colors;
757 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
758 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
760 priv = colorsel->private_data;
762 gdk_color.red = UNSCALE (color[0]);
763 gdk_color.green = UNSCALE (color[1]);
764 gdk_color.blue = UNSCALE (color[2]);
767 y = 0; /* Quiet GCC */
768 while (x < GTK_CUSTOM_PALETTE_WIDTH)
771 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
773 if (priv->custom_palette[x][y] == drawing_area)
784 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
786 current_colors = get_current_colors (colorsel);
787 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
789 screen = gtk_widget_get_screen (GTK_WIDGET (colorsel));
790 if (change_palette_hook != default_change_palette_func)
791 (* change_palette_hook) (screen, current_colors,
792 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
793 else if (noscreen_change_palette_hook != default_noscreen_change_palette_func)
795 if (screen != gdk_screen_get_default ())
796 g_warning ("gtk_color_selection_set_change_palette_hook used by widget is not on the default screen.");
797 (* noscreen_change_palette_hook) (current_colors,
798 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
801 (* change_palette_hook) (screen, current_colors,
802 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
804 g_free (current_colors);
807 /* Changes the view color */
809 palette_set_color (GtkWidget *drawing_area,
810 GtkColorSelection *colorsel,
813 gdouble *new_color = g_new (double, 4);
816 gdk_color.red = UNSCALE (color[0]);
817 gdk_color.green = UNSCALE (color[1]);
818 gdk_color.blue = UNSCALE (color[2]);
820 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
822 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) == 0)
824 static const GtkTargetEntry targets[] = {
825 { "application/x-color", 0 }
827 gtk_drag_source_set (drawing_area,
828 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
830 GDK_ACTION_COPY | GDK_ACTION_MOVE);
832 g_signal_connect (drawing_area,
834 G_CALLBACK (palette_drag_begin),
836 g_signal_connect (drawing_area,
838 G_CALLBACK (palette_drag_handle),
841 g_object_set_data (G_OBJECT (drawing_area), "color_set",
842 GINT_TO_POINTER (1));
845 new_color[0] = color[0];
846 new_color[1] = color[1];
847 new_color[2] = color[2];
850 g_object_set_data_full (G_OBJECT (drawing_area), "color_val", new_color, (GDestroyNotify)g_free);
854 palette_expose (GtkWidget *drawing_area,
855 GdkEventExpose *event,
858 if (drawing_area->window == NULL)
861 palette_paint (drawing_area, &(event->area), data);
867 popup_position_func (GtkMenu *menu,
878 widget = GTK_WIDGET (user_data);
880 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
882 gdk_window_get_origin (widget->window, &root_x, &root_y);
884 gtk_widget_size_request (GTK_WIDGET (menu), &req);
886 /* Put corner of menu centered on color cell */
887 *x = root_x + widget->allocation.width / 2;
888 *y = root_y + widget->allocation.height / 2;
891 screen = gtk_widget_get_screen (widget);
892 *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
893 *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
897 save_color_selected (GtkWidget *menuitem,
900 GtkColorSelection *colorsel;
901 GtkWidget *drawing_area;
902 ColorSelectionPrivate *priv;
904 drawing_area = GTK_WIDGET (data);
906 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
909 priv = colorsel->private_data;
911 palette_change_color (drawing_area, colorsel, priv->color);
915 do_popup (GtkColorSelection *colorsel,
916 GtkWidget *drawing_area,
922 g_object_set_data (G_OBJECT (drawing_area),
926 menu = gtk_menu_new ();
928 mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
930 g_signal_connect (mi, "activate",
931 G_CALLBACK (save_color_selected),
934 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
936 gtk_widget_show_all (mi);
938 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
939 popup_position_func, drawing_area,
945 palette_enter (GtkWidget *drawing_area,
946 GdkEventCrossing *event,
949 g_object_set_data (G_OBJECT (drawing_area),
950 "gtk-colorsel-have-pointer",
951 GUINT_TO_POINTER (TRUE));
957 palette_leave (GtkWidget *drawing_area,
958 GdkEventCrossing *event,
961 g_object_set_data (G_OBJECT (drawing_area),
962 "gtk-colorsel-have-pointer",
969 palette_press (GtkWidget *drawing_area,
970 GdkEventButton *event,
973 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
975 gtk_widget_grab_focus (drawing_area);
977 if (event->button == 3 &&
978 event->type == GDK_BUTTON_PRESS)
980 do_popup (colorsel, drawing_area, event->time);
988 palette_release (GtkWidget *drawing_area,
989 GdkEventButton *event,
992 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
994 gtk_widget_grab_focus (drawing_area);
996 if (event->button == 1 &&
997 g_object_get_data (G_OBJECT (drawing_area),
998 "gtk-colorsel-have-pointer") != NULL)
1000 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) != 0)
1003 palette_get_color (drawing_area, color);
1004 set_color_internal (colorsel, color);
1012 palette_drop_handle (GtkWidget *widget,
1013 GdkDragContext *context,
1016 GtkSelectionData *selection_data,
1021 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1025 if (selection_data->length < 0)
1028 /* We accept drops with the wrong format, since the KDE color
1029 * chooser incorrectly drops application/x-color with format 8.
1031 if (selection_data->length != 8)
1033 g_warning ("Received invalid color data\n");
1037 vals = (guint16 *)selection_data->data;
1039 color[0] = (gdouble)vals[0] / 0xffff;
1040 color[1] = (gdouble)vals[1] / 0xffff;
1041 color[2] = (gdouble)vals[2] / 0xffff;
1042 color[3] = (gdouble)vals[3] / 0xffff;
1043 palette_change_color (widget, colorsel, color);
1044 set_color_internal (colorsel, color);
1048 palette_activate (GtkWidget *widget,
1052 /* should have a drawing area subclass with an activate signal */
1053 if ((event->keyval == GDK_space) ||
1054 (event->keyval == GDK_Return) ||
1055 (event->keyval == GDK_KP_Enter) ||
1056 (event->keyval == GDK_KP_Space))
1058 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "color_set")) != 0)
1061 palette_get_color (widget, color);
1062 set_color_internal (GTK_COLOR_SELECTION (data), color);
1071 palette_popup (GtkWidget *widget,
1074 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1076 do_popup (colorsel, widget, GDK_CURRENT_TIME);
1082 palette_new (GtkColorSelection *colorsel)
1085 ColorSelectionPrivate *priv;
1087 static const GtkTargetEntry targets[] = {
1088 { "application/x-color", 0 }
1091 priv = colorsel->private_data;
1093 retval = gtk_drawing_area_new ();
1095 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1097 g_object_set_data (G_OBJECT (retval), "color_set", GINT_TO_POINTER (0));
1098 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1099 | GDK_BUTTON_RELEASE_MASK
1101 | GDK_ENTER_NOTIFY_MASK
1102 | GDK_LEAVE_NOTIFY_MASK);
1104 g_signal_connect (retval, "expose_event",
1105 G_CALLBACK (palette_expose), colorsel);
1106 g_signal_connect (retval, "button_press_event",
1107 G_CALLBACK (palette_press), colorsel);
1108 g_signal_connect (retval, "button_release_event",
1109 G_CALLBACK (palette_release), colorsel);
1110 g_signal_connect (retval, "enter_notify_event",
1111 G_CALLBACK (palette_enter), colorsel);
1112 g_signal_connect (retval, "leave_notify_event",
1113 G_CALLBACK (palette_leave), colorsel);
1114 g_signal_connect (retval, "key_press_event",
1115 G_CALLBACK (palette_activate), colorsel);
1116 g_signal_connect (retval, "popup_menu",
1117 G_CALLBACK (palette_popup), colorsel);
1119 gtk_drag_dest_set (retval,
1120 GTK_DEST_DEFAULT_HIGHLIGHT |
1121 GTK_DEST_DEFAULT_MOTION |
1122 GTK_DEST_DEFAULT_DROP,
1126 g_signal_connect (retval, "drag_end",
1127 G_CALLBACK (palette_drag_end), NULL);
1128 g_signal_connect (retval, "drag_data_received",
1129 G_CALLBACK (palette_drop_handle), colorsel);
1131 gtk_tooltips_set_tip (priv->tooltips,
1133 _("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.\""),
1141 * The actual GtkColorSelection widget
1146 make_picker_cursor (GdkScreen *screen)
1149 GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
1150 GdkColor fg = { 0, 0x0000, 0x0000, 0x0000 };
1151 GdkWindow *window = gdk_screen_get_root_window (screen);
1154 gdk_bitmap_create_from_data (window, (gchar *) dropper_bits,
1155 DROPPER_WIDTH, DROPPER_HEIGHT);
1158 gdk_bitmap_create_from_data (window, (gchar *) dropper_mask,
1159 DROPPER_WIDTH, DROPPER_HEIGHT);
1161 cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg,
1162 DROPPER_X_HOT, DROPPER_Y_HOT);
1164 g_object_unref (pixmap);
1165 g_object_unref (mask);
1171 grab_color_at_mouse (GdkScreen *screen,
1178 GtkColorSelection *colorsel = data;
1179 ColorSelectionPrivate *priv;
1181 GdkColormap *colormap = gdk_screen_get_system_colormap (screen);
1182 GdkWindow *root_window = gdk_screen_get_root_window (screen);
1184 priv = colorsel->private_data;
1186 image = gdk_drawable_get_image (root_window, x_root, y_root, 1, 1);
1187 pixel = gdk_image_get_pixel (image, 0, 0);
1188 g_object_unref (image);
1190 gdk_colormap_query_color (colormap, pixel, &color);
1192 priv->color[COLORSEL_RED] = SCALE (color.red);
1193 priv->color[COLORSEL_GREEN] = SCALE (color.green);
1194 priv->color[COLORSEL_BLUE] = SCALE (color.blue);
1196 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1197 priv->color[COLORSEL_GREEN],
1198 priv->color[COLORSEL_BLUE],
1199 &priv->color[COLORSEL_HUE],
1200 &priv->color[COLORSEL_SATURATION],
1201 &priv->color[COLORSEL_VALUE]);
1203 update_color (colorsel);
1207 shutdown_eyedropper (GtkWidget *widget)
1209 GtkColorSelection *colorsel;
1210 ColorSelectionPrivate *priv;
1211 GdkDisplay *display = gtk_widget_get_display (widget);
1212 guint32 time = gtk_get_current_event_time ();
1214 colorsel = GTK_COLOR_SELECTION (widget);
1215 priv = colorsel->private_data;
1217 gdk_display_keyboard_ungrab (display, time);
1218 gdk_display_pointer_ungrab (display, time);
1219 gtk_grab_remove (priv->dropper_grab_widget);
1223 mouse_motion (GtkWidget *invisible,
1224 GdkEventMotion *event,
1227 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1228 event->x_root, event->y_root, data);
1232 mouse_release (GtkWidget *invisible,
1233 GdkEventButton *event,
1236 GtkColorSelection *colorsel = data;
1237 ColorSelectionPrivate *priv;
1238 priv = colorsel->private_data;
1240 if (event->button != 1)
1243 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1244 event->x_root, event->y_root, data);
1246 shutdown_eyedropper (GTK_WIDGET (data));
1248 g_signal_handlers_disconnect_by_func (invisible,
1251 g_signal_handlers_disconnect_by_func (invisible,
1258 /* Helper Functions */
1260 static gboolean mouse_press (GtkWidget *invisible,
1261 GdkEventButton *event,
1265 key_press (GtkWidget *invisible,
1269 if (event->keyval == GDK_Escape)
1271 shutdown_eyedropper (data);
1273 g_signal_handlers_disconnect_by_func (invisible,
1276 g_signal_handlers_disconnect_by_func (invisible,
1287 mouse_press (GtkWidget *invisible,
1288 GdkEventButton *event,
1291 GtkColorSelection *colorsel = data;
1292 ColorSelectionPrivate *priv;
1293 priv = colorsel->private_data;
1295 if (event->type == GDK_BUTTON_PRESS &&
1298 g_signal_connect (invisible, "motion_notify_event",
1299 G_CALLBACK (mouse_motion),
1301 g_signal_connect (invisible, "button_release_event",
1302 G_CALLBACK (mouse_release),
1304 g_signal_handlers_disconnect_by_func (invisible,
1307 g_signal_handlers_disconnect_by_func (invisible,
1316 /* when the button is clicked */
1318 get_screen_color (GtkWidget *button)
1320 GtkColorSelection *colorsel = g_object_get_data (G_OBJECT (button), "COLORSEL");
1321 ColorSelectionPrivate *priv = colorsel->private_data;
1322 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (button));
1323 GdkCursor *picker_cursor;
1324 GdkGrabStatus grab_status;
1326 if (priv->dropper_grab_widget == NULL)
1328 priv->dropper_grab_widget = gtk_invisible_new_for_screen (screen);
1330 gtk_widget_add_events (priv->dropper_grab_widget,
1331 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1333 gtk_widget_show (priv->dropper_grab_widget);
1336 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1338 gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
1341 picker_cursor = make_picker_cursor (screen);
1342 grab_status = gdk_pointer_grab (priv->dropper_grab_widget->window,
1344 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1347 gtk_get_current_event_time ());
1348 gdk_cursor_unref (picker_cursor);
1350 if (grab_status != GDK_GRAB_SUCCESS)
1352 gdk_display_keyboard_ungrab (gtk_widget_get_display (button), GDK_CURRENT_TIME);
1356 gtk_grab_add (priv->dropper_grab_widget);
1358 g_signal_connect (priv->dropper_grab_widget, "button_press_event",
1359 G_CALLBACK (mouse_press), colorsel);
1360 g_signal_connect (priv->dropper_grab_widget, "key_press_event",
1361 G_CALLBACK (key_press), colorsel);
1365 hex_changed (GtkWidget *hex_entry,
1368 GtkColorSelection *colorsel;
1369 ColorSelectionPrivate *priv;
1373 colorsel = GTK_COLOR_SELECTION (data);
1374 priv = colorsel->private_data;
1379 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1380 if (gdk_color_parse (text, &color))
1382 priv->color[COLORSEL_RED] = CLAMP (color.red/65535.0, 0.0, 1.0);
1383 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65535.0, 0.0, 1.0);
1384 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65535.0, 0.0, 1.0);
1385 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1386 priv->color[COLORSEL_GREEN],
1387 priv->color[COLORSEL_BLUE],
1388 &priv->color[COLORSEL_HUE],
1389 &priv->color[COLORSEL_SATURATION],
1390 &priv->color[COLORSEL_VALUE]);
1391 update_color (colorsel);
1397 hex_focus_out (GtkWidget *hex_entry,
1398 GdkEventFocus *event,
1401 hex_changed (hex_entry, data);
1407 hsv_changed (GtkWidget *hsv,
1410 GtkColorSelection *colorsel;
1411 ColorSelectionPrivate *priv;
1413 colorsel = GTK_COLOR_SELECTION (data);
1414 priv = colorsel->private_data;
1419 gtk_hsv_get_color (GTK_HSV (hsv),
1420 &priv->color[COLORSEL_HUE],
1421 &priv->color[COLORSEL_SATURATION],
1422 &priv->color[COLORSEL_VALUE]);
1423 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1424 priv->color[COLORSEL_SATURATION],
1425 priv->color[COLORSEL_VALUE],
1426 &priv->color[COLORSEL_RED],
1427 &priv->color[COLORSEL_GREEN],
1428 &priv->color[COLORSEL_BLUE]);
1429 update_color (colorsel);
1433 adjustment_changed (GtkAdjustment *adjustment,
1436 GtkColorSelection *colorsel;
1437 ColorSelectionPrivate *priv;
1439 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (adjustment), "COLORSEL"));
1440 priv = colorsel->private_data;
1445 switch (GPOINTER_TO_INT (data))
1447 case COLORSEL_SATURATION:
1448 case COLORSEL_VALUE:
1449 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 100;
1450 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1451 priv->color[COLORSEL_SATURATION],
1452 priv->color[COLORSEL_VALUE],
1453 &priv->color[COLORSEL_RED],
1454 &priv->color[COLORSEL_GREEN],
1455 &priv->color[COLORSEL_BLUE]);
1458 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1459 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1460 priv->color[COLORSEL_SATURATION],
1461 priv->color[COLORSEL_VALUE],
1462 &priv->color[COLORSEL_RED],
1463 &priv->color[COLORSEL_GREEN],
1464 &priv->color[COLORSEL_BLUE]);
1467 case COLORSEL_GREEN:
1469 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1471 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1472 priv->color[COLORSEL_GREEN],
1473 priv->color[COLORSEL_BLUE],
1474 &priv->color[COLORSEL_HUE],
1475 &priv->color[COLORSEL_SATURATION],
1476 &priv->color[COLORSEL_VALUE]);
1479 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1482 update_color (colorsel);
1486 opacity_entry_changed (GtkWidget *opacity_entry,
1489 GtkColorSelection *colorsel;
1490 ColorSelectionPrivate *priv;
1494 colorsel = GTK_COLOR_SELECTION (data);
1495 priv = colorsel->private_data;
1500 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1501 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1502 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1504 update_color (colorsel);
1510 make_label_spinbutton (GtkColorSelection *colorsel,
1511 GtkWidget **spinbutton,
1517 const gchar *tooltip)
1520 GtkAdjustment *adjust;
1521 ColorSelectionPrivate *priv = colorsel->private_data;
1523 if (channel_type == COLORSEL_HUE)
1525 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1527 else if (channel_type == COLORSEL_SATURATION ||
1528 channel_type == COLORSEL_VALUE)
1530 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 1.0, 1.0));
1534 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1536 g_object_set_data (G_OBJECT (adjust), "COLORSEL", colorsel);
1537 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1539 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1541 g_signal_connect (adjust, "value_changed",
1542 G_CALLBACK (adjustment_changed),
1543 GINT_TO_POINTER (channel_type));
1544 label = gtk_label_new_with_mnemonic (text);
1545 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1547 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1548 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1549 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1553 make_palette_frame (GtkColorSelection *colorsel,
1559 ColorSelectionPrivate *priv;
1561 priv = colorsel->private_data;
1562 frame = gtk_frame_new (NULL);
1563 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1564 priv->custom_palette[i][j] = palette_new (colorsel);
1565 gtk_widget_set_size_request (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1566 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1567 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1570 /* Set the palette entry [x][y] to be the currently selected one. */
1572 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1574 ColorSelectionPrivate *priv = colorsel->private_data;
1576 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1580 scale_round (double val, double factor)
1582 val = floor (val * factor + 0.5);
1584 val = MIN (val, factor);
1589 update_color (GtkColorSelection *colorsel)
1591 ColorSelectionPrivate *priv = colorsel->private_data;
1593 gchar opacity_text[32];
1596 priv->changing = TRUE;
1597 color_sample_draw_samples (colorsel);
1599 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1600 priv->color[COLORSEL_HUE],
1601 priv->color[COLORSEL_SATURATION],
1602 priv->color[COLORSEL_VALUE]);
1603 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1604 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1605 scale_round (priv->color[COLORSEL_HUE], 360));
1606 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1607 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1608 scale_round (priv->color[COLORSEL_SATURATION], 100));
1609 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1610 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1611 scale_round (priv->color[COLORSEL_VALUE], 100));
1612 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1613 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1614 scale_round (priv->color[COLORSEL_RED], 255));
1615 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1616 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1617 scale_round (priv->color[COLORSEL_GREEN], 255));
1618 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1619 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1620 scale_round (priv->color[COLORSEL_BLUE], 255));
1621 gtk_adjustment_set_value (gtk_range_get_adjustment
1622 (GTK_RANGE (priv->opacity_slider)),
1623 scale_round (priv->color[COLORSEL_OPACITY], 255));
1625 g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
1626 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1628 g_snprintf (entryval, 11, "#%2X%2X%2X",
1629 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1630 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1631 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1633 for (ptr = entryval; *ptr; ptr++)
1636 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1637 priv->changing = FALSE;
1639 g_object_ref (colorsel);
1641 g_signal_emit (colorsel, color_selection_signals[COLOR_CHANGED], 0);
1643 g_object_freeze_notify (G_OBJECT (colorsel));
1644 g_object_notify (G_OBJECT (colorsel), "current_color");
1645 g_object_notify (G_OBJECT (colorsel), "current_alpha");
1646 g_object_thaw_notify (G_OBJECT (colorsel));
1648 g_object_unref (colorsel);
1652 update_palette (GtkColorSelection *colorsel)
1654 GdkColor *current_colors;
1657 current_colors = get_current_colors (colorsel);
1659 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1661 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1665 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1667 gtk_color_selection_set_palette_color (colorsel,
1669 ¤t_colors[index]);
1673 g_free (current_colors);
1677 palette_change_notify_instance (GObject *object,
1681 update_palette (GTK_COLOR_SELECTION (data));
1685 default_noscreen_change_palette_func (const GdkColor *colors,
1688 default_change_palette_func (gdk_screen_get_default (), colors, n_colors);
1692 default_change_palette_func (GdkScreen *screen,
1693 const GdkColor *colors,
1698 str = gtk_color_selection_palette_to_string (colors, n_colors);
1700 gtk_settings_set_string_property (gtk_settings_get_for_screen (screen),
1701 "gtk-color-palette",
1703 "gtk_color_selection_palette_to_string");
1709 gtk_color_selection_get_type (void)
1711 static GType color_selection_type = 0;
1713 if (!color_selection_type)
1715 static const GTypeInfo color_selection_info =
1717 sizeof (GtkColorSelectionClass),
1718 NULL, /* base_init */
1719 NULL, /* base_finalize */
1720 (GClassInitFunc) gtk_color_selection_class_init,
1721 NULL, /* class_finalize */
1722 NULL, /* class_data */
1723 sizeof (GtkColorSelection),
1724 0, /* n_preallocs */
1725 (GInstanceInitFunc) gtk_color_selection_init,
1728 color_selection_type =
1729 g_type_register_static (GTK_TYPE_VBOX, "GtkColorSelection",
1730 &color_selection_info, 0);
1733 return color_selection_type;
1737 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1739 GObjectClass *gobject_class;
1740 GtkObjectClass *object_class;
1741 GtkWidgetClass *widget_class;
1743 gobject_class = G_OBJECT_CLASS (klass);
1744 object_class = GTK_OBJECT_CLASS (klass);
1745 widget_class = GTK_WIDGET_CLASS (klass);
1747 parent_class = g_type_class_peek_parent (klass);
1749 object_class->destroy = gtk_color_selection_destroy;
1750 gobject_class->finalize = gtk_color_selection_finalize;
1752 gobject_class->set_property = gtk_color_selection_set_property;
1753 gobject_class->get_property = gtk_color_selection_get_property;
1755 widget_class->realize = gtk_color_selection_realize;
1756 widget_class->unrealize = gtk_color_selection_unrealize;
1757 widget_class->show_all = gtk_color_selection_show_all;
1759 g_object_class_install_property (gobject_class,
1760 PROP_HAS_OPACITY_CONTROL,
1761 g_param_spec_boolean ("has_opacity_control",
1762 P_("Has Opacity Control"),
1763 P_("Whether the color selector should allow setting opacity"),
1765 G_PARAM_READABLE | G_PARAM_WRITABLE));
1766 g_object_class_install_property (gobject_class,
1768 g_param_spec_boolean ("has_palette",
1770 P_("Whether a palette should be used"),
1772 G_PARAM_READABLE | G_PARAM_WRITABLE));
1773 g_object_class_install_property (gobject_class,
1775 g_param_spec_boxed ("current_color",
1776 P_("Current Color"),
1777 P_("The current color"),
1779 G_PARAM_READABLE | G_PARAM_WRITABLE));
1780 g_object_class_install_property (gobject_class,
1782 g_param_spec_uint ("current_alpha",
1783 P_("Current Alpha"),
1784 P_("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1786 G_PARAM_READABLE | G_PARAM_WRITABLE));
1788 color_selection_signals[COLOR_CHANGED] =
1789 g_signal_new ("color_changed",
1790 G_OBJECT_CLASS_TYPE (object_class),
1792 G_STRUCT_OFFSET (GtkColorSelectionClass, color_changed),
1794 _gtk_marshal_VOID__VOID,
1797 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1798 P_("Custom palette"),
1799 P_("Palette to use in the color selector"),
1801 G_PARAM_READWRITE));
1804 /* widget functions */
1807 gtk_color_selection_init (GtkColorSelection *colorsel)
1809 GtkWidget *top_hbox;
1810 GtkWidget *top_right_vbox;
1811 GtkWidget *table, *label, *hbox, *frame, *vbox, *button;
1812 GtkAdjustment *adjust;
1813 GtkWidget *picker_image;
1815 ColorSelectionPrivate *priv;
1817 gtk_widget_push_composite_child ();
1819 priv = colorsel->private_data = g_new0 (ColorSelectionPrivate, 1);
1820 priv->changing = FALSE;
1821 priv->default_set = FALSE;
1822 priv->default_alpha_set = FALSE;
1824 priv->tooltips = gtk_tooltips_new ();
1825 g_object_ref (priv->tooltips);
1826 gtk_object_sink (GTK_OBJECT (priv->tooltips));
1828 gtk_box_set_spacing (GTK_BOX (colorsel), 4);
1829 top_hbox = gtk_hbox_new (FALSE, 8);
1830 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1832 vbox = gtk_vbox_new (FALSE, 4);
1833 priv->triangle_colorsel = gtk_hsv_new ();
1834 g_signal_connect (priv->triangle_colorsel, "changed",
1835 G_CALLBACK (hsv_changed), colorsel);
1836 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1837 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1838 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1839 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1840 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1842 hbox = gtk_hbox_new (FALSE, 4);
1843 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1845 frame = gtk_frame_new (NULL);
1846 gtk_widget_set_size_request (frame, -1, 30);
1847 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1848 color_sample_new (colorsel);
1849 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1850 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1852 button = gtk_button_new ();
1854 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1855 g_object_set_data (G_OBJECT (button), "COLORSEL", colorsel);
1856 g_signal_connect (button, "clicked",
1857 G_CALLBACK (get_screen_color), NULL);
1858 picker_image = gtk_image_new_from_stock (GTK_STOCK_COLOR_PICKER, GTK_ICON_SIZE_BUTTON);
1859 gtk_container_add (GTK_CONTAINER (button), picker_image);
1860 gtk_widget_show (GTK_WIDGET (picker_image));
1861 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1863 gtk_tooltips_set_tip (priv->tooltips,
1865 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1867 top_right_vbox = gtk_vbox_new (FALSE, 4);
1868 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1869 table = gtk_table_new (8, 6, FALSE);
1870 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1871 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1872 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1874 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1875 _("Position on the color wheel."));
1876 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (priv->hue_spinbutton), TRUE);
1877 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1878 _("\"Deepness\" of the color."));
1879 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1880 _("Brightness of the color."));
1881 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1882 _("Amount of red light in the color."));
1883 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1884 _("Amount of green light in the color."));
1885 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1886 _("Amount of blue light in the color."));
1887 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1889 priv->opacity_label = gtk_label_new_with_mnemonic (_("_Opacity:"));
1890 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 1.0, 0.5);
1891 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1892 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1893 g_object_set_data (G_OBJECT (adjust), "COLORSEL", colorsel);
1894 priv->opacity_slider = gtk_hscale_new (adjust);
1895 gtk_tooltips_set_tip (priv->tooltips,
1896 priv->opacity_slider,
1897 _("Transparency of the color."), NULL);
1898 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1899 priv->opacity_slider);
1900 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1901 g_signal_connect (adjust, "value_changed",
1902 G_CALLBACK (adjustment_changed),
1903 GINT_TO_POINTER (COLORSEL_OPACITY));
1904 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
1905 priv->opacity_entry = gtk_entry_new ();
1906 gtk_tooltips_set_tip (priv->tooltips,
1907 priv->opacity_entry,
1908 _("Transparency of the color."), NULL);
1909 gtk_widget_set_size_request (priv->opacity_entry, 40, -1);
1911 g_signal_connect (priv->opacity_entry, "activate",
1912 G_CALLBACK (opacity_entry_changed), colorsel);
1913 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
1915 label = gtk_label_new_with_mnemonic (_("Color _Name:"));
1916 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
1917 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
1918 priv->hex_entry = gtk_entry_new ();
1920 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
1922 g_signal_connect (priv->hex_entry, "activate",
1923 G_CALLBACK (hex_changed), colorsel);
1925 g_signal_connect (priv->hex_entry, "focus_out_event",
1926 G_CALLBACK (hex_focus_out), colorsel);
1928 gtk_tooltips_set_tip (priv->tooltips,
1930 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
1932 gtk_entry_set_width_chars (GTK_ENTRY (priv->hex_entry), 7);
1933 gtk_table_set_col_spacing (GTK_TABLE (table), 3, 15);
1934 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
1936 /* Set up the palette */
1937 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
1938 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1939 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1940 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
1942 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
1944 make_palette_frame (colorsel, table, i, j);
1947 set_selected_palette (colorsel, 0, 0);
1948 priv->palette_frame = gtk_frame_new (NULL);
1949 label = gtk_label_new_with_mnemonic (_("_Palette"));
1950 gtk_frame_set_label_widget (GTK_FRAME (priv->palette_frame), label);
1952 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
1953 priv->custom_palette[0][0]);
1955 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
1956 vbox = gtk_vbox_new (FALSE, 4);
1957 gtk_container_add (GTK_CONTAINER (priv->palette_frame), vbox);
1958 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1960 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1962 gtk_widget_show_all (top_hbox);
1964 /* hide unused stuff */
1966 if (priv->has_opacity == FALSE)
1968 gtk_widget_hide (priv->opacity_label);
1969 gtk_widget_hide (priv->opacity_slider);
1970 gtk_widget_hide (priv->opacity_entry);
1973 if (priv->has_palette == FALSE)
1975 gtk_widget_hide (priv->palette_frame);
1978 gtk_widget_pop_composite_child ();
1982 gtk_color_selection_destroy (GtkObject *object)
1984 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
1985 ColorSelectionPrivate *priv = cselection->private_data;
1987 if (priv->dropper_grab_widget)
1989 gtk_widget_destroy (priv->dropper_grab_widget);
1990 priv->dropper_grab_widget = NULL;
1995 g_object_unref (priv->tooltips);
1996 priv->tooltips = NULL;
1999 GTK_OBJECT_CLASS (parent_class)->destroy (object);
2003 gtk_color_selection_finalize (GObject *object)
2005 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
2007 if (cselection->private_data)
2009 g_free (cselection->private_data);
2010 cselection->private_data = NULL;
2013 G_OBJECT_CLASS (parent_class)->finalize (object);
2017 gtk_color_selection_realize (GtkWidget *widget)
2019 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
2020 ColorSelectionPrivate *priv = colorsel->private_data;
2021 GtkSettings *settings = gtk_widget_get_settings (widget);
2023 priv->settings_connection = g_signal_connect (settings,
2024 "notify::gtk-color-palette",
2025 G_CALLBACK (palette_change_notify_instance),
2027 update_palette (colorsel);
2029 GTK_WIDGET_CLASS (parent_class)->realize (widget);
2033 gtk_color_selection_unrealize (GtkWidget *widget)
2035 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
2036 ColorSelectionPrivate *priv = colorsel->private_data;
2037 GtkSettings *settings = gtk_widget_get_settings (widget);
2039 g_signal_handler_disconnect (settings, priv->settings_connection);
2041 GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
2044 /* We override show-all since we have internal widgets that
2045 * shouldn't be shown when you call show_all(), like the
2046 * palette and opacity sliders.
2049 gtk_color_selection_show_all (GtkWidget *widget)
2051 gtk_widget_show (widget);
2055 * gtk_color_selection_new:
2057 * Creates a new GtkColorSelection.
2059 * Return value: a new #GtkColorSelection
2062 gtk_color_selection_new (void)
2064 GtkColorSelection *colorsel;
2065 ColorSelectionPrivate *priv;
2072 colorsel = g_object_new (GTK_TYPE_COLOR_SELECTION, NULL);
2073 priv = colorsel->private_data;
2074 set_color_internal (colorsel, color);
2075 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
2077 /* We want to make sure that default_set is FALSE */
2078 /* This way the user can still set it */
2079 priv->default_set = FALSE;
2080 priv->default_alpha_set = FALSE;
2082 return GTK_WIDGET (colorsel);
2087 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
2088 GtkUpdateType policy)
2090 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2094 * gtk_color_selection_get_has_opacity_control:
2095 * @colorsel: a #GtkColorSelection.
2097 * Determines whether the colorsel has an opacity control.
2099 * Return value: %TRUE if the @colorsel has an opacity control. %FALSE if it does't.
2102 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2104 ColorSelectionPrivate *priv;
2106 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2108 priv = colorsel->private_data;
2110 return priv->has_opacity;
2114 * gtk_color_selection_set_has_opacity_control:
2115 * @colorsel: a #GtkColorSelection.
2116 * @has_opacity: %TRUE if @colorsel can set the opacity, %FALSE otherwise.
2118 * Sets the @colorsel to use or not use opacity.
2122 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2123 gboolean has_opacity)
2125 ColorSelectionPrivate *priv;
2127 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2129 priv = colorsel->private_data;
2130 has_opacity = has_opacity != FALSE;
2132 if (priv->has_opacity != has_opacity)
2134 priv->has_opacity = has_opacity;
2137 gtk_widget_show (priv->opacity_slider);
2138 gtk_widget_show (priv->opacity_label);
2139 gtk_widget_show (priv->opacity_entry);
2143 gtk_widget_hide (priv->opacity_slider);
2144 gtk_widget_hide (priv->opacity_label);
2145 gtk_widget_hide (priv->opacity_entry);
2147 color_sample_draw_samples (colorsel);
2149 g_object_notify (G_OBJECT (colorsel), "has_opacity_control");
2154 * gtk_color_selection_get_has_palette:
2155 * @colorsel: a #GtkColorSelection.
2157 * Determines whether the color selector has a color palette.
2159 * Return value: %TRUE if the selector has a palette. %FALSE if it hasn't.
2162 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2164 ColorSelectionPrivate *priv;
2166 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2168 priv = colorsel->private_data;
2170 return priv->has_palette;
2174 * gtk_color_selection_set_has_palette:
2175 * @colorsel: a #GtkColorSelection.
2176 * @has_palette: %TRUE if palette is to be visible, %FALSE otherwise.
2178 * Shows and hides the palette based upon the value of @has_palette.
2182 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2183 gboolean has_palette)
2185 ColorSelectionPrivate *priv;
2186 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2188 priv = colorsel->private_data;
2189 has_palette = has_palette != FALSE;
2191 if (priv->has_palette != has_palette)
2193 priv->has_palette = has_palette;
2195 gtk_widget_show (priv->palette_frame);
2197 gtk_widget_hide (priv->palette_frame);
2199 g_object_notify (G_OBJECT (colorsel), "has_palette");
2204 * gtk_color_selection_set_current_color:
2205 * @colorsel: a #GtkColorSelection.
2206 * @color: A #GdkColor to set the current color with.
2208 * Sets the current color to be @color. The first time this is called, it will
2209 * also set the original color to be @color too.
2212 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2213 const GdkColor *color)
2215 ColorSelectionPrivate *priv;
2217 gboolean previous_changed;
2219 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2220 g_return_if_fail (color != NULL);
2222 priv = colorsel->private_data;
2223 priv->changing = TRUE;
2224 priv->color[COLORSEL_RED] = SCALE (color->red);
2225 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2226 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2227 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2228 priv->color[COLORSEL_GREEN],
2229 priv->color[COLORSEL_BLUE],
2230 &priv->color[COLORSEL_HUE],
2231 &priv->color[COLORSEL_SATURATION],
2232 &priv->color[COLORSEL_VALUE]);
2233 if (priv->default_set == FALSE)
2235 previous_changed = TRUE;
2236 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2237 priv->old_color[i] = priv->color[i];
2239 priv->default_set = TRUE;
2240 update_color (colorsel);
2244 * gtk_color_selection_set_current_alpha:
2245 * @colorsel: a #GtkColorSelection.
2246 * @alpha: an integer between 0 and 65535.
2248 * Sets the current opacity to be @alpha. The first time this is called, it will
2249 * also set the original opacity to be @alpha too.
2252 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2255 ColorSelectionPrivate *priv;
2258 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2260 priv = colorsel->private_data;
2261 priv->changing = TRUE;
2262 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2263 if (priv->default_alpha_set == FALSE)
2265 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2266 priv->old_color[i] = priv->color[i];
2268 priv->default_alpha_set = TRUE;
2269 update_color (colorsel);
2273 * gtk_color_selection_set_color:
2274 * @colorsel: a #GtkColorSelection.
2275 * @color: an array of 4 doubles specifying the red, green, blue and opacity
2276 * to set the current color to.
2278 * Sets the current color to be @color. The first time this is called, it will
2279 * also set the original color to be @color too.
2281 * Deprecated: Use gtk_color_selection_set_current_color() instead.
2284 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2287 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2289 set_color_internal (colorsel, color);
2293 * gtk_color_selection_get_current_color:
2294 * @colorsel: a #GtkColorSelection.
2295 * @color: a #GdkColor to fill in with the current color.
2297 * Sets @color to be the current color in the GtkColorSelection widget.
2300 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2303 ColorSelectionPrivate *priv;
2305 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2306 g_return_if_fail (color != NULL);
2308 priv = colorsel->private_data;
2309 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2310 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2311 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2315 * gtk_color_selection_get_current_alpha:
2316 * @colorsel: a #GtkColorSelection.
2318 * Returns the current alpha value.
2320 * Return value: an integer between 0 and 65535.
2323 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2325 ColorSelectionPrivate *priv;
2327 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2329 priv = colorsel->private_data;
2330 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2334 * gtk_color_selection_get_color:
2335 * @colorsel: a #GtkColorSelection.
2336 * @color: an array of 4 #gdouble to fill in with the current color.
2338 * Sets @color to be the current color in the GtkColorSelection widget.
2340 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2343 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2346 ColorSelectionPrivate *priv;
2348 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2350 priv = colorsel->private_data;
2351 color[0] = priv->color[COLORSEL_RED];
2352 color[1] = priv->color[COLORSEL_GREEN];
2353 color[2] = priv->color[COLORSEL_BLUE];
2354 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2358 * gtk_color_selection_set_previous_color:
2359 * @colorsel: a #GtkColorSelection.
2360 * @color: a #GdkColor to set the previous color with.
2362 * Sets the 'previous' color to be @color. This function should be called with
2363 * some hesitations, as it might seem confusing to have that color change.
2364 * Calling gtk_color_selection_set_current_color() will also set this color the first
2365 * time it is called.
2368 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2369 const GdkColor *color)
2371 ColorSelectionPrivate *priv;
2373 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2374 g_return_if_fail (color != NULL);
2376 priv = colorsel->private_data;
2377 priv->changing = TRUE;
2378 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2379 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2380 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2381 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2382 priv->old_color[COLORSEL_GREEN],
2383 priv->old_color[COLORSEL_BLUE],
2384 &priv->old_color[COLORSEL_HUE],
2385 &priv->old_color[COLORSEL_SATURATION],
2386 &priv->old_color[COLORSEL_VALUE]);
2387 color_sample_draw_samples (colorsel);
2388 priv->default_set = TRUE;
2389 priv->changing = FALSE;
2393 * gtk_color_selection_set_previous_alpha:
2394 * @colorsel: a #GtkColorSelection.
2395 * @alpha: an integer between 0 and 65535.
2397 * Sets the 'previous' alpha to be @alpha. This function should be called with
2398 * some hesitations, as it might seem confusing to have that alpha change.
2401 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2404 ColorSelectionPrivate *priv;
2406 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2408 priv = colorsel->private_data;
2409 priv->changing = TRUE;
2410 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2411 color_sample_draw_samples (colorsel);
2412 priv->default_alpha_set = TRUE;
2413 priv->changing = FALSE;
2418 * gtk_color_selection_get_previous_color:
2419 * @colorsel: a #GtkColorSelection.
2420 * @color: a #GdkColor to fill in with the original color value.
2422 * Fills @color in with the original color value.
2425 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2428 ColorSelectionPrivate *priv;
2430 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2431 g_return_if_fail (color != NULL);
2433 priv = colorsel->private_data;
2434 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2435 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2436 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2440 * gtk_color_selection_get_previous_alpha:
2441 * @colorsel: a #GtkColorSelection.
2443 * Returns the previous alpha value.
2445 * Return value: an integer between 0 and 65535.
2448 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2450 ColorSelectionPrivate *priv;
2452 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2454 priv = colorsel->private_data;
2455 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2459 * gtk_color_selection_set_palette_color:
2460 * @colorsel: a #GtkColorSelection.
2461 * @index: the color index of the palette.
2462 * @color: A #GdkColor to set the palette with.
2464 * Sets the palette located at @index to have @color as its color.
2468 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2472 ColorSelectionPrivate *priv;
2476 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2477 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2479 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2480 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2482 priv = colorsel->private_data;
2483 col[0] = SCALE (color->red);
2484 col[1] = SCALE (color->green);
2485 col[2] = SCALE (color->blue);
2487 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2491 * gtk_color_selection_is_adjusting:
2492 * @colorsel: a #GtkColorSelection.
2494 * Gets the current state of the @colorsel.
2496 * Return value: %TRUE if the user is currently dragging a color around, and %FALSE
2497 * if the selection has stopped.
2500 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2502 ColorSelectionPrivate *priv;
2504 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2506 priv = colorsel->private_data;
2508 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2512 gtk_color_selection_set_property (GObject *object,
2514 const GValue *value,
2517 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2521 case PROP_HAS_OPACITY_CONTROL:
2522 gtk_color_selection_set_has_opacity_control (colorsel,
2523 g_value_get_boolean (value));
2525 case PROP_HAS_PALETTE:
2526 gtk_color_selection_set_has_palette (colorsel,
2527 g_value_get_boolean (value));
2529 case PROP_CURRENT_COLOR:
2530 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2532 case PROP_CURRENT_ALPHA:
2533 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2536 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2543 gtk_color_selection_get_property (GObject *object,
2548 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2553 case PROP_HAS_OPACITY_CONTROL:
2554 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2556 case PROP_HAS_PALETTE:
2557 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2559 case PROP_CURRENT_COLOR:
2560 gtk_color_selection_get_current_color (colorsel, &color);
2561 g_value_set_boxed (value, &color);
2563 case PROP_CURRENT_ALPHA:
2564 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2567 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2574 * gtk_color_selection_palette_from_string:
2575 * @str: a string encoding a color palette.
2576 * @colors: return location for allocated array of #GdkColor.
2577 * @n_colors: return location for length of array.
2579 * Parses a color palette string; the string is a colon-separated
2580 * list of color names readable by gdk_color_parse().
2582 * Return value: %TRUE if a palette was successfully parsed.
2585 gtk_color_selection_palette_from_string (const gchar *str,
2597 copy = g_strdup (str);
2603 if (*p == ':' || *p == '\0')
2605 gboolean done = TRUE;
2609 goto failed; /* empty entry */
2618 retval = g_renew (GdkColor, retval, count + 1);
2619 if (!gdk_color_parse (start, retval + count))
2660 * gtk_color_selection_palette_to_string:
2661 * @colors: an array of colors.
2662 * @n_colors: length of the array.
2664 * Encodes a palette as a string, useful for persistent storage.
2666 * Return value: allocated string encoding the palette.
2669 gtk_color_selection_palette_to_string (const GdkColor *colors,
2673 gchar **strs = NULL;
2677 return g_strdup ("");
2679 strs = g_new0 (gchar*, n_colors + 1);
2682 while (i < n_colors)
2687 g_strdup_printf ("#%2X%2X%2X",
2688 colors[i].red / 256,
2689 colors[i].green / 256,
2690 colors[i].blue / 256);
2692 for (ptr = strs[i]; *ptr; ptr++)
2699 retval = g_strjoinv (":", strs);
2707 * gtk_color_selection_set_change_palette_hook:
2708 * @func: a function to call when the custom palette needs saving.
2710 * Installs a global function to be called whenever the user tries to
2711 * modify the palette in a color selection. This function should save
2712 * the new palette contents, and update the GtkSettings property
2713 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2715 * Return value: the previous change palette hook (that was replaced).
2717 * Deprecated: This function is deprecated in favor of
2718 * gtk_color_selection_set_change_palette_with_screen_hook(), and does
2719 * not work in multihead environments.
2722 GtkColorSelectionChangePaletteFunc
2723 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2725 GtkColorSelectionChangePaletteFunc old;
2727 old = noscreen_change_palette_hook;
2729 noscreen_change_palette_hook = func;
2735 * gtk_color_selection_set_change_palette_with_screen_hook:
2736 * @func: a function to call when the custom palette needs saving.
2738 * Installs a global function to be called whenever the user tries to
2739 * modify the palette in a color selection. This function should save
2740 * the new palette contents, and update the GtkSettings property
2741 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2743 * Return value: the previous change palette hook (that was replaced).
2747 GtkColorSelectionChangePaletteWithScreenFunc
2748 gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func)
2750 GtkColorSelectionChangePaletteWithScreenFunc old;
2752 old = change_palette_hook;
2754 change_palette_hook = func;