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"
60 #include "gtkaccessible.h"
61 #include "gtkprivate.h"
67 /* Number of elements in the custom palatte */
68 #define GTK_CUSTOM_PALETTE_WIDTH 10
69 #define GTK_CUSTOM_PALETTE_HEIGHT 2
71 /* Conversion between 0->1 double and and guint16. See
72 * scale_round() below for more general conversions
74 #define SCALE(i) (i / 65535.)
75 #define UNSCALE(d) ((guint16)(d * 65535 + 0.5))
86 PROP_HAS_OPACITY_CONTROL,
102 typedef struct _ColorSelectionPrivate ColorSelectionPrivate;
104 struct _ColorSelectionPrivate
106 guint has_opacity : 1;
107 guint has_palette : 1;
109 guint default_set : 1;
110 guint default_alpha_set : 1;
113 gdouble color[COLORSEL_NUM_CHANNELS];
114 gdouble old_color[COLORSEL_NUM_CHANNELS];
116 GtkWidget *triangle_colorsel;
117 GtkWidget *hue_spinbutton;
118 GtkWidget *sat_spinbutton;
119 GtkWidget *val_spinbutton;
120 GtkWidget *red_spinbutton;
121 GtkWidget *green_spinbutton;
122 GtkWidget *blue_spinbutton;
123 GtkWidget *opacity_slider;
124 GtkWidget *opacity_label;
125 GtkWidget *opacity_entry;
126 GtkWidget *palette_frame;
127 GtkWidget *hex_entry;
129 /* The Palette code */
130 GtkWidget *custom_palette [GTK_CUSTOM_PALETTE_WIDTH][GTK_CUSTOM_PALETTE_HEIGHT];
132 /* The color_sample stuff */
133 GtkWidget *sample_area;
134 GtkWidget *old_sample;
135 GtkWidget *cur_sample;
139 GtkTooltips *tooltips;
141 /* Window for grabbing on */
142 GtkWidget *dropper_grab_widget;
145 /* Connection to settings */
146 gulong settings_connection;
150 static void gtk_color_selection_destroy (GtkObject *object);
151 static void gtk_color_selection_finalize (GObject *object);
152 static void update_color (GtkColorSelection *colorsel);
153 static void gtk_color_selection_set_property (GObject *object,
157 static void gtk_color_selection_get_property (GObject *object,
162 static void gtk_color_selection_realize (GtkWidget *widget);
163 static void gtk_color_selection_unrealize (GtkWidget *widget);
164 static void gtk_color_selection_show_all (GtkWidget *widget);
165 static gboolean gtk_color_selection_grab_broken (GtkWidget *widget,
166 GdkEventGrabBroken *event);
168 static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
171 static void set_focus_line_attributes (GtkWidget *drawing_area,
174 static void default_noscreen_change_palette_func (const GdkColor *colors,
176 static void default_change_palette_func (GdkScreen *screen,
177 const GdkColor *colors,
179 static void make_control_relations (AtkObject *atk_obj,
181 static void make_all_relations (AtkObject *atk_obj,
182 ColorSelectionPrivate *priv);
184 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
186 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";
188 static GtkColorSelectionChangePaletteFunc noscreen_change_palette_hook = default_noscreen_change_palette_func;
189 static GtkColorSelectionChangePaletteWithScreenFunc change_palette_hook = default_change_palette_func;
191 /* The cursor for the dropper */
192 #define DROPPER_WIDTH 17
193 #define DROPPER_HEIGHT 17
194 #define DROPPER_X_HOT 2
195 #define DROPPER_Y_HOT 16
198 static const guchar dropper_bits[] = {
199 0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
200 0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
201 0x7f, 0xd4, 0x01, 0x3f, 0xee, 0x01, 0x1f, 0xff, 0x01, 0x8f, 0xff, 0x01,
202 0xc7, 0xff, 0x01, 0xe3, 0xff, 0x01, 0xf3, 0xff, 0x01, 0xfd, 0xff, 0x01,
205 static const guchar dropper_mask[] = {
206 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xff, 0x01,
207 0x80, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x80, 0x3f, 0x00,
208 0xc0, 0x3f, 0x00, 0xe0, 0x13, 0x00, 0xf0, 0x01, 0x00, 0xf8, 0x00, 0x00,
209 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
218 #define SAMPLE_WIDTH 64
219 #define SAMPLE_HEIGHT 28
221 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
222 static void color_sample_update_samples (GtkColorSelection *colorsel);
225 set_color_internal (GtkColorSelection *colorsel,
228 ColorSelectionPrivate *priv;
231 priv = colorsel->private_data;
232 priv->changing = TRUE;
233 priv->color[COLORSEL_RED] = color[0];
234 priv->color[COLORSEL_GREEN] = color[1];
235 priv->color[COLORSEL_BLUE] = color[2];
236 priv->color[COLORSEL_OPACITY] = color[3];
237 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
238 priv->color[COLORSEL_GREEN],
239 priv->color[COLORSEL_BLUE],
240 &priv->color[COLORSEL_HUE],
241 &priv->color[COLORSEL_SATURATION],
242 &priv->color[COLORSEL_VALUE]);
243 if (priv->default_set == FALSE)
245 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
246 priv->old_color[i] = priv->color[i];
248 priv->default_set = TRUE;
249 priv->default_alpha_set = TRUE;
250 update_color (colorsel);
254 set_color_icon (GdkDragContext *context,
260 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
263 pixel = (((UNSCALE (colors[COLORSEL_RED]) & 0xff00) << 16) |
264 ((UNSCALE (colors[COLORSEL_GREEN]) & 0xff00) << 8) |
265 ((UNSCALE (colors[COLORSEL_BLUE]) & 0xff00)));
267 gdk_pixbuf_fill (pixbuf, pixel);
269 gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
270 g_object_unref (pixbuf);
274 color_sample_drag_begin (GtkWidget *widget,
275 GdkDragContext *context,
278 GtkColorSelection *colorsel = data;
279 ColorSelectionPrivate *priv;
282 priv = colorsel->private_data;
284 if (widget == priv->old_sample)
285 colsrc = priv->old_color;
287 colsrc = priv->color;
289 set_color_icon (context, colsrc);
293 color_sample_drag_end (GtkWidget *widget,
294 GdkDragContext *context,
297 g_object_set_data (G_OBJECT (widget), I_("gtk-color-selection-drag-window"), NULL);
301 color_sample_drop_handle (GtkWidget *widget,
302 GdkDragContext *context,
305 GtkSelectionData *selection_data,
310 GtkColorSelection *colorsel = data;
311 ColorSelectionPrivate *priv;
314 priv = colorsel->private_data;
316 /* This is currently a guint16 array of the format:
323 if (selection_data->length < 0)
326 /* We accept drops with the wrong format, since the KDE color
327 * chooser incorrectly drops application/x-color with format 8.
329 if (selection_data->length != 8)
331 g_warning ("Received invalid color data\n");
335 vals = (guint16 *)selection_data->data;
337 if (widget == priv->cur_sample)
339 color[0] = (gdouble)vals[0] / 0xffff;
340 color[1] = (gdouble)vals[1] / 0xffff;
341 color[2] = (gdouble)vals[2] / 0xffff;
342 color[3] = (gdouble)vals[3] / 0xffff;
344 set_color_internal (colorsel, color);
349 color_sample_drag_handle (GtkWidget *widget,
350 GdkDragContext *context,
351 GtkSelectionData *selection_data,
356 GtkColorSelection *colorsel = data;
357 ColorSelectionPrivate *priv;
361 priv = colorsel->private_data;
363 if (widget == priv->old_sample)
364 colsrc = priv->old_color;
366 colsrc = priv->color;
368 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
369 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
370 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
371 vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
373 gtk_selection_data_set (selection_data,
374 gdk_atom_intern_static_string ("application/x-color"),
375 16, (guchar *)vals, 8);
378 /* which = 0 means draw old sample, which = 1 means draw new */
380 color_sample_draw_sample (GtkColorSelection *colorsel, int which)
383 gint x, y, wid, heig, goff;
384 ColorSelectionPrivate *priv;
387 g_return_if_fail (colorsel != NULL);
388 priv = colorsel->private_data;
390 g_return_if_fail (priv->sample_area != NULL);
391 if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
396 da = priv->old_sample;
401 da = priv->cur_sample;
402 goff = priv->old_sample->allocation.width % 32;
405 cr = gdk_cairo_create (da->window);
407 wid = da->allocation.width;
408 heig = da->allocation.height;
410 /* Below needs tweaking for non-power-of-two */
411 #define CHECK_SIZE 16
413 if (priv->has_opacity)
415 /* Draw checks in background */
417 cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
418 cairo_rectangle (cr, 0, 0, wid, heig);
421 cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
422 for (x = goff & -CHECK_SIZE; x < goff + wid; x += CHECK_SIZE)
423 for (y = 0; y < heig; y += CHECK_SIZE)
424 if ((x / CHECK_SIZE + y / CHECK_SIZE) % 2 == 0)
425 cairo_rectangle (cr, x - goff, y, CHECK_SIZE, CHECK_SIZE);
431 cairo_set_source_rgba (cr,
432 priv->old_color[COLORSEL_RED],
433 priv->old_color[COLORSEL_GREEN],
434 priv->old_color[COLORSEL_BLUE],
436 priv->old_color[COLORSEL_OPACITY] : 1.0);
440 cairo_set_source_rgba (cr,
441 priv->color[COLORSEL_RED],
442 priv->color[COLORSEL_GREEN],
443 priv->color[COLORSEL_BLUE],
445 priv->color[COLORSEL_OPACITY] : 1.0);
448 cairo_rectangle (cr, 0, 0, wid, heig);
456 color_sample_update_samples (GtkColorSelection *colorsel)
458 ColorSelectionPrivate *priv = colorsel->private_data;
459 gtk_widget_queue_draw (priv->old_sample);
460 gtk_widget_queue_draw (priv->cur_sample);
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,
614 if (drawing_area->window == NULL)
617 cr = gdk_cairo_create (drawing_area->window);
619 gdk_cairo_set_source_color (cr, &drawing_area->style->bg[GTK_STATE_NORMAL]);
620 gdk_cairo_rectangle (cr, area);
623 if (GTK_WIDGET_HAS_FOCUS (drawing_area))
625 set_focus_line_attributes (drawing_area, cr, &focus_width);
628 focus_width / 2., focus_width / 2.,
629 drawing_area->allocation.width - focus_width,
630 drawing_area->allocation.height - focus_width);
638 set_focus_line_attributes (GtkWidget *drawing_area,
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 cairo_set_source_rgb (cr, 0., 0., 0.);
655 cairo_set_source_rgb (cr, 1., 1., 1.);
657 cairo_set_line_width (cr, *focus_width);
661 gint n_dashes = strlen (dash_list);
662 gdouble *dashes = g_new (gdouble, n_dashes);
663 gdouble total_length = 0;
667 for (i = 0; i < n_dashes; i++)
669 dashes[i] = dash_list[i];
670 total_length += dash_list[i];
673 /* The dash offset here aligns the pattern to integer pixels
674 * by starting the dash at the right side of the left border
675 * Negative dash offsets in cairo don't work
676 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
678 dash_offset = - *focus_width / 2.;
679 while (dash_offset < 0)
680 dash_offset += total_length;
682 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
690 palette_drag_begin (GtkWidget *widget,
691 GdkDragContext *context,
696 palette_get_color (widget, colors);
697 set_color_icon (context, colors);
701 palette_drag_handle (GtkWidget *widget,
702 GdkDragContext *context,
703 GtkSelectionData *selection_data,
711 palette_get_color (widget, colsrc);
713 vals[0] = colsrc[COLORSEL_RED] * 0xffff;
714 vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
715 vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
718 gtk_selection_data_set (selection_data,
719 gdk_atom_intern_static_string ("application/x-color"),
720 16, (guchar *)vals, 8);
724 palette_drag_end (GtkWidget *widget,
725 GdkDragContext *context,
728 g_object_set_data (G_OBJECT (widget), I_("gtk-color-selection-drag-window"), NULL);
732 get_current_colors (GtkColorSelection *colorsel)
734 GtkSettings *settings;
735 GdkColor *colors = NULL;
739 settings = gtk_widget_get_settings (GTK_WIDGET (colorsel));
740 g_object_get (settings,
741 "gtk-color-palette", &palette,
744 if (!gtk_color_selection_palette_from_string (palette, &colors, &n_colors))
746 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
750 /* If there are less colors provided than the number of slots in the
751 * color selection, we fill in the rest from the defaults.
753 if (n_colors < (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
755 GdkColor *tmp_colors = colors;
756 gint tmp_n_colors = n_colors;
758 gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
759 memcpy (colors, tmp_colors, sizeof (GdkColor) * tmp_n_colors);
765 g_assert (n_colors >= GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
771 /* Changes the model color */
773 palette_change_color (GtkWidget *drawing_area,
774 GtkColorSelection *colorsel,
778 ColorSelectionPrivate *priv;
780 GdkColor *current_colors;
783 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
784 g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
786 priv = colorsel->private_data;
788 gdk_color.red = UNSCALE (color[0]);
789 gdk_color.green = UNSCALE (color[1]);
790 gdk_color.blue = UNSCALE (color[2]);
793 y = 0; /* Quiet GCC */
794 while (x < GTK_CUSTOM_PALETTE_WIDTH)
797 while (y < GTK_CUSTOM_PALETTE_HEIGHT)
799 if (priv->custom_palette[x][y] == drawing_area)
810 g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
812 current_colors = get_current_colors (colorsel);
813 current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
815 screen = gtk_widget_get_screen (GTK_WIDGET (colorsel));
816 if (change_palette_hook != default_change_palette_func)
817 (* change_palette_hook) (screen, current_colors,
818 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
819 else if (noscreen_change_palette_hook != default_noscreen_change_palette_func)
821 if (screen != gdk_screen_get_default ())
822 g_warning ("gtk_color_selection_set_change_palette_hook used by widget is not on the default screen.");
823 (* noscreen_change_palette_hook) (current_colors,
824 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
827 (* change_palette_hook) (screen, current_colors,
828 GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
830 g_free (current_colors);
833 /* Changes the view color */
835 palette_set_color (GtkWidget *drawing_area,
836 GtkColorSelection *colorsel,
839 gdouble *new_color = g_new (double, 4);
842 gdk_color.red = UNSCALE (color[0]);
843 gdk_color.green = UNSCALE (color[1]);
844 gdk_color.blue = UNSCALE (color[2]);
846 gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
848 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) == 0)
850 static const GtkTargetEntry targets[] = {
851 { "application/x-color", 0 }
853 gtk_drag_source_set (drawing_area,
854 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
856 GDK_ACTION_COPY | GDK_ACTION_MOVE);
858 g_signal_connect (drawing_area,
860 G_CALLBACK (palette_drag_begin),
862 g_signal_connect (drawing_area,
864 G_CALLBACK (palette_drag_handle),
867 g_object_set_data (G_OBJECT (drawing_area), I_("color_set"),
868 GINT_TO_POINTER (1));
871 new_color[0] = color[0];
872 new_color[1] = color[1];
873 new_color[2] = color[2];
876 g_object_set_data_full (G_OBJECT (drawing_area), I_("color_val"), new_color, (GDestroyNotify)g_free);
880 palette_expose (GtkWidget *drawing_area,
881 GdkEventExpose *event,
884 if (drawing_area->window == NULL)
887 palette_paint (drawing_area, &(event->area), data);
893 popup_position_func (GtkMenu *menu,
904 widget = GTK_WIDGET (user_data);
906 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
908 gdk_window_get_origin (widget->window, &root_x, &root_y);
910 gtk_widget_size_request (GTK_WIDGET (menu), &req);
912 /* Put corner of menu centered on color cell */
913 *x = root_x + widget->allocation.width / 2;
914 *y = root_y + widget->allocation.height / 2;
917 screen = gtk_widget_get_screen (widget);
918 *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
919 *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
923 save_color_selected (GtkWidget *menuitem,
926 GtkColorSelection *colorsel;
927 GtkWidget *drawing_area;
928 ColorSelectionPrivate *priv;
930 drawing_area = GTK_WIDGET (data);
932 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
935 priv = colorsel->private_data;
937 palette_change_color (drawing_area, colorsel, priv->color);
941 do_popup (GtkColorSelection *colorsel,
942 GtkWidget *drawing_area,
948 g_object_set_data (G_OBJECT (drawing_area),
952 menu = gtk_menu_new ();
954 mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
956 g_signal_connect (mi, "activate",
957 G_CALLBACK (save_color_selected),
960 gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
962 gtk_widget_show_all (mi);
964 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
965 popup_position_func, drawing_area,
971 palette_enter (GtkWidget *drawing_area,
972 GdkEventCrossing *event,
975 g_object_set_data (G_OBJECT (drawing_area),
976 I_("gtk-colorsel-have-pointer"),
977 GUINT_TO_POINTER (TRUE));
983 palette_leave (GtkWidget *drawing_area,
984 GdkEventCrossing *event,
987 g_object_set_data (G_OBJECT (drawing_area),
988 I_("gtk-colorsel-have-pointer"),
995 palette_press (GtkWidget *drawing_area,
996 GdkEventButton *event,
999 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1001 gtk_widget_grab_focus (drawing_area);
1003 if (event->button == 3 &&
1004 event->type == GDK_BUTTON_PRESS)
1006 do_popup (colorsel, drawing_area, event->time);
1014 palette_release (GtkWidget *drawing_area,
1015 GdkEventButton *event,
1018 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1020 gtk_widget_grab_focus (drawing_area);
1022 if (event->button == 1 &&
1023 g_object_get_data (G_OBJECT (drawing_area),
1024 "gtk-colorsel-have-pointer") != NULL)
1026 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) != 0)
1029 palette_get_color (drawing_area, color);
1030 set_color_internal (colorsel, color);
1038 palette_drop_handle (GtkWidget *widget,
1039 GdkDragContext *context,
1042 GtkSelectionData *selection_data,
1047 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1051 if (selection_data->length < 0)
1054 /* We accept drops with the wrong format, since the KDE color
1055 * chooser incorrectly drops application/x-color with format 8.
1057 if (selection_data->length != 8)
1059 g_warning ("Received invalid color data\n");
1063 vals = (guint16 *)selection_data->data;
1065 color[0] = (gdouble)vals[0] / 0xffff;
1066 color[1] = (gdouble)vals[1] / 0xffff;
1067 color[2] = (gdouble)vals[2] / 0xffff;
1068 color[3] = (gdouble)vals[3] / 0xffff;
1069 palette_change_color (widget, colorsel, color);
1070 set_color_internal (colorsel, color);
1074 palette_activate (GtkWidget *widget,
1078 /* should have a drawing area subclass with an activate signal */
1079 if ((event->keyval == GDK_space) ||
1080 (event->keyval == GDK_Return) ||
1081 (event->keyval == GDK_KP_Enter) ||
1082 (event->keyval == GDK_KP_Space))
1084 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "color_set")) != 0)
1087 palette_get_color (widget, color);
1088 set_color_internal (GTK_COLOR_SELECTION (data), color);
1097 palette_popup (GtkWidget *widget,
1100 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
1102 do_popup (colorsel, widget, GDK_CURRENT_TIME);
1108 palette_new (GtkColorSelection *colorsel)
1111 ColorSelectionPrivate *priv;
1113 static const GtkTargetEntry targets[] = {
1114 { "application/x-color", 0 }
1117 priv = colorsel->private_data;
1119 retval = gtk_drawing_area_new ();
1121 GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
1123 g_object_set_data (G_OBJECT (retval), I_("color_set"), GINT_TO_POINTER (0));
1124 gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
1125 | GDK_BUTTON_RELEASE_MASK
1127 | GDK_ENTER_NOTIFY_MASK
1128 | GDK_LEAVE_NOTIFY_MASK);
1130 g_signal_connect (retval, "expose_event",
1131 G_CALLBACK (palette_expose), colorsel);
1132 g_signal_connect (retval, "button_press_event",
1133 G_CALLBACK (palette_press), colorsel);
1134 g_signal_connect (retval, "button_release_event",
1135 G_CALLBACK (palette_release), colorsel);
1136 g_signal_connect (retval, "enter_notify_event",
1137 G_CALLBACK (palette_enter), colorsel);
1138 g_signal_connect (retval, "leave_notify_event",
1139 G_CALLBACK (palette_leave), colorsel);
1140 g_signal_connect (retval, "key_press_event",
1141 G_CALLBACK (palette_activate), colorsel);
1142 g_signal_connect (retval, "popup_menu",
1143 G_CALLBACK (palette_popup), colorsel);
1145 gtk_drag_dest_set (retval,
1146 GTK_DEST_DEFAULT_HIGHLIGHT |
1147 GTK_DEST_DEFAULT_MOTION |
1148 GTK_DEST_DEFAULT_DROP,
1152 g_signal_connect (retval, "drag_end",
1153 G_CALLBACK (palette_drag_end), NULL);
1154 g_signal_connect (retval, "drag_data_received",
1155 G_CALLBACK (palette_drop_handle), colorsel);
1157 gtk_tooltips_set_tip (priv->tooltips,
1159 _("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.\""),
1167 * The actual GtkColorSelection widget
1172 make_picker_cursor (GdkScreen *screen)
1176 cursor = gdk_cursor_new_from_name (gdk_screen_get_display (screen),
1181 GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
1182 GdkColor fg = { 0, 0x0000, 0x0000, 0x0000 };
1184 GdkPixmap *pixmap, *mask;
1186 window = gdk_screen_get_root_window (screen);
1189 gdk_bitmap_create_from_data (window, (gchar *) dropper_bits,
1190 DROPPER_WIDTH, DROPPER_HEIGHT);
1193 gdk_bitmap_create_from_data (window, (gchar *) dropper_mask,
1194 DROPPER_WIDTH, DROPPER_HEIGHT);
1196 cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg,
1197 DROPPER_X_HOT, DROPPER_Y_HOT);
1199 g_object_unref (pixmap);
1200 g_object_unref (mask);
1207 grab_color_at_mouse (GdkScreen *screen,
1214 GtkColorSelection *colorsel = data;
1215 ColorSelectionPrivate *priv;
1217 GdkColormap *colormap = gdk_screen_get_system_colormap (screen);
1218 GdkWindow *root_window = gdk_screen_get_root_window (screen);
1220 priv = colorsel->private_data;
1222 image = gdk_drawable_get_image (root_window, x_root, y_root, 1, 1);
1226 GdkDisplay *display = gdk_screen_get_display (screen);
1227 GdkWindow *window = gdk_display_get_window_at_pointer (display, &x, &y);
1230 image = gdk_drawable_get_image (window, x, y, 1, 1);
1234 pixel = gdk_image_get_pixel (image, 0, 0);
1235 g_object_unref (image);
1237 gdk_colormap_query_color (colormap, pixel, &color);
1239 priv->color[COLORSEL_RED] = SCALE (color.red);
1240 priv->color[COLORSEL_GREEN] = SCALE (color.green);
1241 priv->color[COLORSEL_BLUE] = SCALE (color.blue);
1243 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1244 priv->color[COLORSEL_GREEN],
1245 priv->color[COLORSEL_BLUE],
1246 &priv->color[COLORSEL_HUE],
1247 &priv->color[COLORSEL_SATURATION],
1248 &priv->color[COLORSEL_VALUE]);
1250 update_color (colorsel);
1254 shutdown_eyedropper (GtkWidget *widget)
1256 GtkColorSelection *colorsel;
1257 ColorSelectionPrivate *priv;
1258 GdkDisplay *display = gtk_widget_get_display (widget);
1260 colorsel = GTK_COLOR_SELECTION (widget);
1261 priv = colorsel->private_data;
1265 gdk_display_keyboard_ungrab (display, priv->grab_time);
1266 gdk_display_pointer_ungrab (display, priv->grab_time);
1267 gtk_grab_remove (priv->dropper_grab_widget);
1269 priv->has_grab = FALSE;
1274 gtk_color_selection_grab_broken (GtkWidget *widget,
1275 GdkEventGrabBroken *event)
1277 shutdown_eyedropper (widget);
1283 mouse_motion (GtkWidget *invisible,
1284 GdkEventMotion *event,
1287 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1288 event->x_root, event->y_root, data);
1292 mouse_release (GtkWidget *invisible,
1293 GdkEventButton *event,
1296 /* GtkColorSelection *colorsel = data; */
1298 if (event->button != 1)
1301 grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
1302 event->x_root, event->y_root, data);
1304 shutdown_eyedropper (GTK_WIDGET (data));
1306 g_signal_handlers_disconnect_by_func (invisible,
1309 g_signal_handlers_disconnect_by_func (invisible,
1316 /* Helper Functions */
1318 static gboolean mouse_press (GtkWidget *invisible,
1319 GdkEventButton *event,
1325 key_press (GtkWidget *invisible,
1329 GdkDisplay *display = gtk_widget_get_display (invisible);
1330 GdkScreen *screen = gdk_event_get_screen ((GdkEvent *)event);
1331 guint state = event->state & gtk_accelerator_get_default_mod_mask ();
1335 gdk_display_get_pointer (display, NULL, &x, &y, NULL);
1340 switch (event->keyval)
1346 grab_color_at_mouse (screen, x, y, data);
1350 shutdown_eyedropper (data);
1352 g_signal_handlers_disconnect_by_func (invisible,
1355 g_signal_handlers_disconnect_by_func (invisible,
1361 #if defined GDK_WINDOWING_X11 || defined GDK_WINDOWING_WIN32
1364 dy = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
1369 dy = state == GDK_MOD1_MASK ? BIG_STEP : 1;
1374 dx = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
1379 dx = state == GDK_MOD1_MASK ? BIG_STEP : 1;
1387 gdk_display_warp_pointer (display, screen, x + dx, y + dy);
1394 mouse_press (GtkWidget *invisible,
1395 GdkEventButton *event,
1398 /* GtkColorSelection *colorsel = data; */
1400 if (event->type == GDK_BUTTON_PRESS &&
1403 g_signal_connect (invisible, "motion_notify_event",
1404 G_CALLBACK (mouse_motion),
1406 g_signal_connect (invisible, "button_release_event",
1407 G_CALLBACK (mouse_release),
1409 g_signal_handlers_disconnect_by_func (invisible,
1412 g_signal_handlers_disconnect_by_func (invisible,
1421 /* when the button is clicked */
1423 get_screen_color (GtkWidget *button)
1425 GtkColorSelection *colorsel = g_object_get_data (G_OBJECT (button), "COLORSEL");
1426 ColorSelectionPrivate *priv = colorsel->private_data;
1427 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (button));
1428 GdkCursor *picker_cursor;
1429 GdkGrabStatus grab_status;
1430 GtkWidget *grab_widget, *toplevel;
1432 guint32 time = gtk_get_current_event_time ();
1434 if (priv->dropper_grab_widget == NULL)
1436 grab_widget = gtk_window_new (GTK_WINDOW_POPUP);
1437 gtk_window_set_screen (GTK_WINDOW (grab_widget), screen);
1438 gtk_window_resize (GTK_WINDOW (grab_widget), 1, 1);
1439 gtk_window_move (GTK_WINDOW (grab_widget), -100, -100);
1440 gtk_widget_show (grab_widget);
1442 gtk_widget_add_events (grab_widget,
1443 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
1445 toplevel = gtk_widget_get_toplevel (colorsel);
1447 if (GTK_IS_WINDOW (toplevel))
1449 if (GTK_WINDOW (toplevel)->group)
1450 gtk_window_group_add_window (GTK_WINDOW (toplevel)->group,
1451 GTK_WINDOW (grab_widget));
1454 priv->dropper_grab_widget = grab_widget;
1457 if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
1458 FALSE, time) != GDK_GRAB_SUCCESS)
1461 picker_cursor = make_picker_cursor (screen);
1462 grab_status = gdk_pointer_grab (priv->dropper_grab_widget->window,
1464 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
1468 gdk_cursor_unref (picker_cursor);
1470 if (grab_status != GDK_GRAB_SUCCESS)
1472 gdk_display_keyboard_ungrab (gtk_widget_get_display (button), time);
1476 gtk_grab_add (priv->dropper_grab_widget);
1477 priv->grab_time = time;
1478 priv->has_grab = TRUE;
1480 g_signal_connect (priv->dropper_grab_widget, "button_press_event",
1481 G_CALLBACK (mouse_press), colorsel);
1482 g_signal_connect (priv->dropper_grab_widget, "key_press_event",
1483 G_CALLBACK (key_press), colorsel);
1487 hex_changed (GtkWidget *hex_entry,
1490 GtkColorSelection *colorsel;
1491 ColorSelectionPrivate *priv;
1495 colorsel = GTK_COLOR_SELECTION (data);
1496 priv = colorsel->private_data;
1501 text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
1502 if (gdk_color_parse (text, &color))
1504 priv->color[COLORSEL_RED] = CLAMP (color.red/65535.0, 0.0, 1.0);
1505 priv->color[COLORSEL_GREEN] = CLAMP (color.green/65535.0, 0.0, 1.0);
1506 priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65535.0, 0.0, 1.0);
1507 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1508 priv->color[COLORSEL_GREEN],
1509 priv->color[COLORSEL_BLUE],
1510 &priv->color[COLORSEL_HUE],
1511 &priv->color[COLORSEL_SATURATION],
1512 &priv->color[COLORSEL_VALUE]);
1513 update_color (colorsel);
1519 hex_focus_out (GtkWidget *hex_entry,
1520 GdkEventFocus *event,
1523 hex_changed (hex_entry, data);
1529 hsv_changed (GtkWidget *hsv,
1532 GtkColorSelection *colorsel;
1533 ColorSelectionPrivate *priv;
1535 colorsel = GTK_COLOR_SELECTION (data);
1536 priv = colorsel->private_data;
1541 gtk_hsv_get_color (GTK_HSV (hsv),
1542 &priv->color[COLORSEL_HUE],
1543 &priv->color[COLORSEL_SATURATION],
1544 &priv->color[COLORSEL_VALUE]);
1545 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1546 priv->color[COLORSEL_SATURATION],
1547 priv->color[COLORSEL_VALUE],
1548 &priv->color[COLORSEL_RED],
1549 &priv->color[COLORSEL_GREEN],
1550 &priv->color[COLORSEL_BLUE]);
1551 update_color (colorsel);
1555 adjustment_changed (GtkAdjustment *adjustment,
1558 GtkColorSelection *colorsel;
1559 ColorSelectionPrivate *priv;
1561 colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (adjustment), "COLORSEL"));
1562 priv = colorsel->private_data;
1567 switch (GPOINTER_TO_INT (data))
1569 case COLORSEL_SATURATION:
1570 case COLORSEL_VALUE:
1571 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 100;
1572 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1573 priv->color[COLORSEL_SATURATION],
1574 priv->color[COLORSEL_VALUE],
1575 &priv->color[COLORSEL_RED],
1576 &priv->color[COLORSEL_GREEN],
1577 &priv->color[COLORSEL_BLUE]);
1580 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
1581 gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
1582 priv->color[COLORSEL_SATURATION],
1583 priv->color[COLORSEL_VALUE],
1584 &priv->color[COLORSEL_RED],
1585 &priv->color[COLORSEL_GREEN],
1586 &priv->color[COLORSEL_BLUE]);
1589 case COLORSEL_GREEN:
1591 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1593 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
1594 priv->color[COLORSEL_GREEN],
1595 priv->color[COLORSEL_BLUE],
1596 &priv->color[COLORSEL_HUE],
1597 &priv->color[COLORSEL_SATURATION],
1598 &priv->color[COLORSEL_VALUE]);
1601 priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
1604 update_color (colorsel);
1608 opacity_entry_changed (GtkWidget *opacity_entry,
1611 GtkColorSelection *colorsel;
1612 ColorSelectionPrivate *priv;
1616 colorsel = GTK_COLOR_SELECTION (data);
1617 priv = colorsel->private_data;
1622 text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
1623 adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
1624 gtk_adjustment_set_value (adj, g_strtod (text, NULL));
1626 update_color (colorsel);
1632 make_label_spinbutton (GtkColorSelection *colorsel,
1633 GtkWidget **spinbutton,
1639 const gchar *tooltip)
1642 GtkAdjustment *adjust;
1643 ColorSelectionPrivate *priv = colorsel->private_data;
1645 if (channel_type == COLORSEL_HUE)
1647 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
1649 else if (channel_type == COLORSEL_SATURATION ||
1650 channel_type == COLORSEL_VALUE)
1652 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 1.0, 1.0));
1656 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
1658 g_object_set_data (G_OBJECT (adjust), I_("COLORSEL"), colorsel);
1659 *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
1661 gtk_tooltips_set_tip (priv->tooltips, *spinbutton, tooltip, NULL);
1663 g_signal_connect (adjust, "value_changed",
1664 G_CALLBACK (adjustment_changed),
1665 GINT_TO_POINTER (channel_type));
1666 label = gtk_label_new_with_mnemonic (text);
1667 gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
1669 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1670 gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
1671 gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
1675 make_palette_frame (GtkColorSelection *colorsel,
1681 ColorSelectionPrivate *priv;
1683 priv = colorsel->private_data;
1684 frame = gtk_frame_new (NULL);
1685 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1686 priv->custom_palette[i][j] = palette_new (colorsel);
1687 gtk_widget_set_size_request (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
1688 gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
1689 gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
1692 /* Set the palette entry [x][y] to be the currently selected one. */
1694 set_selected_palette (GtkColorSelection *colorsel, int x, int y)
1696 ColorSelectionPrivate *priv = colorsel->private_data;
1698 gtk_widget_grab_focus (priv->custom_palette[x][y]);
1702 scale_round (double val, double factor)
1704 val = floor (val * factor + 0.5);
1706 val = MIN (val, factor);
1711 update_color (GtkColorSelection *colorsel)
1713 ColorSelectionPrivate *priv = colorsel->private_data;
1715 gchar opacity_text[32];
1718 priv->changing = TRUE;
1719 color_sample_update_samples (colorsel);
1721 gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
1722 priv->color[COLORSEL_HUE],
1723 priv->color[COLORSEL_SATURATION],
1724 priv->color[COLORSEL_VALUE]);
1725 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1726 (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
1727 scale_round (priv->color[COLORSEL_HUE], 360));
1728 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1729 (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
1730 scale_round (priv->color[COLORSEL_SATURATION], 100));
1731 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1732 (GTK_SPIN_BUTTON (priv->val_spinbutton)),
1733 scale_round (priv->color[COLORSEL_VALUE], 100));
1734 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1735 (GTK_SPIN_BUTTON (priv->red_spinbutton)),
1736 scale_round (priv->color[COLORSEL_RED], 255));
1737 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1738 (GTK_SPIN_BUTTON (priv->green_spinbutton)),
1739 scale_round (priv->color[COLORSEL_GREEN], 255));
1740 gtk_adjustment_set_value (gtk_spin_button_get_adjustment
1741 (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
1742 scale_round (priv->color[COLORSEL_BLUE], 255));
1743 gtk_adjustment_set_value (gtk_range_get_adjustment
1744 (GTK_RANGE (priv->opacity_slider)),
1745 scale_round (priv->color[COLORSEL_OPACITY], 255));
1747 g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
1748 gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
1750 g_snprintf (entryval, 11, "#%2X%2X%2X",
1751 (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
1752 (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
1753 (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
1755 for (ptr = entryval; *ptr; ptr++)
1758 gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
1759 priv->changing = FALSE;
1761 g_object_ref (colorsel);
1763 g_signal_emit (colorsel, color_selection_signals[COLOR_CHANGED], 0);
1765 g_object_freeze_notify (G_OBJECT (colorsel));
1766 g_object_notify (G_OBJECT (colorsel), "current-color");
1767 g_object_notify (G_OBJECT (colorsel), "current-alpha");
1768 g_object_thaw_notify (G_OBJECT (colorsel));
1770 g_object_unref (colorsel);
1774 update_palette (GtkColorSelection *colorsel)
1776 GdkColor *current_colors;
1779 current_colors = get_current_colors (colorsel);
1781 for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
1783 for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
1787 index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
1789 gtk_color_selection_set_palette_color (colorsel,
1791 ¤t_colors[index]);
1795 g_free (current_colors);
1799 palette_change_notify_instance (GObject *object,
1803 update_palette (GTK_COLOR_SELECTION (data));
1807 default_noscreen_change_palette_func (const GdkColor *colors,
1810 default_change_palette_func (gdk_screen_get_default (), colors, n_colors);
1814 default_change_palette_func (GdkScreen *screen,
1815 const GdkColor *colors,
1820 str = gtk_color_selection_palette_to_string (colors, n_colors);
1822 gtk_settings_set_string_property (gtk_settings_get_for_screen (screen),
1823 "gtk-color-palette",
1825 "gtk_color_selection_palette_to_string");
1830 G_DEFINE_TYPE (GtkColorSelection, gtk_color_selection, GTK_TYPE_VBOX)
1833 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
1835 GObjectClass *gobject_class;
1836 GtkObjectClass *object_class;
1837 GtkWidgetClass *widget_class;
1839 gobject_class = G_OBJECT_CLASS (klass);
1840 object_class = GTK_OBJECT_CLASS (klass);
1841 widget_class = GTK_WIDGET_CLASS (klass);
1843 object_class->destroy = gtk_color_selection_destroy;
1844 gobject_class->finalize = gtk_color_selection_finalize;
1846 gobject_class->set_property = gtk_color_selection_set_property;
1847 gobject_class->get_property = gtk_color_selection_get_property;
1849 widget_class->realize = gtk_color_selection_realize;
1850 widget_class->unrealize = gtk_color_selection_unrealize;
1851 widget_class->show_all = gtk_color_selection_show_all;
1852 widget_class->grab_broken_event = gtk_color_selection_grab_broken;
1854 g_object_class_install_property (gobject_class,
1855 PROP_HAS_OPACITY_CONTROL,
1856 g_param_spec_boolean ("has-opacity-control",
1857 P_("Has Opacity Control"),
1858 P_("Whether the color selector should allow setting opacity"),
1860 GTK_PARAM_READWRITE));
1861 g_object_class_install_property (gobject_class,
1863 g_param_spec_boolean ("has-palette",
1865 P_("Whether a palette should be used"),
1867 GTK_PARAM_READWRITE));
1868 g_object_class_install_property (gobject_class,
1870 g_param_spec_boxed ("current-color",
1871 P_("Current Color"),
1872 P_("The current color"),
1874 GTK_PARAM_READWRITE));
1875 g_object_class_install_property (gobject_class,
1877 g_param_spec_uint ("current-alpha",
1878 P_("Current Alpha"),
1879 P_("The current opacity value (0 fully transparent, 65535 fully opaque)"),
1881 GTK_PARAM_READWRITE));
1883 color_selection_signals[COLOR_CHANGED] =
1884 g_signal_new (I_("color_changed"),
1885 G_OBJECT_CLASS_TYPE (object_class),
1887 G_STRUCT_OFFSET (GtkColorSelectionClass, color_changed),
1889 _gtk_marshal_VOID__VOID,
1892 gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
1893 P_("Custom palette"),
1894 P_("Palette to use in the color selector"),
1896 GTK_PARAM_READWRITE));
1898 g_type_class_add_private (gobject_class, sizeof (ColorSelectionPrivate));
1901 /* widget functions */
1904 gtk_color_selection_init (GtkColorSelection *colorsel)
1906 GtkWidget *top_hbox;
1907 GtkWidget *top_right_vbox;
1908 GtkWidget *table, *label, *hbox, *frame, *vbox, *button;
1909 GtkAdjustment *adjust;
1910 GtkWidget *picker_image;
1912 ColorSelectionPrivate *priv;
1914 GList *focus_chain = NULL;
1916 gtk_widget_push_composite_child ();
1918 priv = colorsel->private_data = G_TYPE_INSTANCE_GET_PRIVATE (colorsel, GTK_TYPE_COLOR_SELECTION, ColorSelectionPrivate);
1919 priv->changing = FALSE;
1920 priv->default_set = FALSE;
1921 priv->default_alpha_set = FALSE;
1923 priv->tooltips = gtk_tooltips_new ();
1924 g_object_ref_sink (priv->tooltips);
1926 top_hbox = gtk_hbox_new (FALSE, 12);
1927 gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
1929 vbox = gtk_vbox_new (FALSE, 6);
1930 priv->triangle_colorsel = gtk_hsv_new ();
1931 g_signal_connect (priv->triangle_colorsel, "changed",
1932 G_CALLBACK (hsv_changed), colorsel);
1933 gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
1934 gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
1935 gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
1936 gtk_tooltips_set_tip (priv->tooltips, priv->triangle_colorsel,
1937 _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."), NULL);
1939 hbox = gtk_hbox_new (FALSE, 6);
1940 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1942 frame = gtk_frame_new (NULL);
1943 gtk_widget_set_size_request (frame, -1, 30);
1944 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1945 color_sample_new (colorsel);
1946 gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
1947 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1949 button = gtk_button_new ();
1951 gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1952 g_object_set_data (G_OBJECT (button), I_("COLORSEL"), colorsel);
1953 g_signal_connect (button, "clicked",
1954 G_CALLBACK (get_screen_color), NULL);
1955 picker_image = gtk_image_new_from_stock (GTK_STOCK_COLOR_PICKER, GTK_ICON_SIZE_BUTTON);
1956 gtk_container_add (GTK_CONTAINER (button), picker_image);
1957 gtk_widget_show (GTK_WIDGET (picker_image));
1958 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1960 gtk_tooltips_set_tip (priv->tooltips,
1962 _("Click the eyedropper, then click a color anywhere on your screen to select that color."), NULL);
1964 top_right_vbox = gtk_vbox_new (FALSE, 6);
1965 gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
1966 table = gtk_table_new (8, 6, FALSE);
1967 gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
1968 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1969 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
1971 make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
1972 _("Position on the color wheel."));
1973 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (priv->hue_spinbutton), TRUE);
1974 make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
1975 _("\"Deepness\" of the color."));
1976 make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
1977 _("Brightness of the color."));
1978 make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
1979 _("Amount of red light in the color."));
1980 make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
1981 _("Amount of green light in the color."));
1982 make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
1983 _("Amount of blue light in the color."));
1984 gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
1986 priv->opacity_label = gtk_label_new_with_mnemonic (_("Op_acity:"));
1987 gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 0.0, 0.5);
1988 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
1989 adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
1990 g_object_set_data (G_OBJECT (adjust), I_("COLORSEL"), colorsel);
1991 priv->opacity_slider = gtk_hscale_new (adjust);
1992 gtk_tooltips_set_tip (priv->tooltips,
1993 priv->opacity_slider,
1994 _("Transparency of the color."), NULL);
1995 gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
1996 priv->opacity_slider);
1997 gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
1998 g_signal_connect (adjust, "value_changed",
1999 G_CALLBACK (adjustment_changed),
2000 GINT_TO_POINTER (COLORSEL_OPACITY));
2001 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
2002 priv->opacity_entry = gtk_entry_new ();
2003 gtk_tooltips_set_tip (priv->tooltips,
2004 priv->opacity_entry,
2005 _("Transparency of the color."), NULL);
2006 gtk_widget_set_size_request (priv->opacity_entry, 40, -1);
2008 g_signal_connect (priv->opacity_entry, "activate",
2009 G_CALLBACK (opacity_entry_changed), colorsel);
2010 gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
2012 label = gtk_label_new_with_mnemonic (_("Color _name:"));
2013 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
2014 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2015 priv->hex_entry = gtk_entry_new ();
2017 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
2019 g_signal_connect (priv->hex_entry, "activate",
2020 G_CALLBACK (hex_changed), colorsel);
2022 g_signal_connect (priv->hex_entry, "focus_out_event",
2023 G_CALLBACK (hex_focus_out), colorsel);
2025 gtk_tooltips_set_tip (priv->tooltips,
2027 _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."), NULL);
2029 gtk_entry_set_width_chars (GTK_ENTRY (priv->hex_entry), 7);
2030 gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
2032 focus_chain = g_list_append (focus_chain, priv->hue_spinbutton);
2033 focus_chain = g_list_append (focus_chain, priv->sat_spinbutton);
2034 focus_chain = g_list_append (focus_chain, priv->val_spinbutton);
2035 focus_chain = g_list_append (focus_chain, priv->red_spinbutton);
2036 focus_chain = g_list_append (focus_chain, priv->green_spinbutton);
2037 focus_chain = g_list_append (focus_chain, priv->blue_spinbutton);
2038 focus_chain = g_list_append (focus_chain, priv->opacity_slider);
2039 focus_chain = g_list_append (focus_chain, priv->opacity_entry);
2040 focus_chain = g_list_append (focus_chain, priv->hex_entry);
2041 gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
2042 g_list_free (focus_chain);
2044 /* Set up the palette */
2045 table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
2046 gtk_table_set_row_spacings (GTK_TABLE (table), 1);
2047 gtk_table_set_col_spacings (GTK_TABLE (table), 1);
2048 for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
2050 for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
2052 make_palette_frame (colorsel, table, i, j);
2055 set_selected_palette (colorsel, 0, 0);
2056 priv->palette_frame = gtk_vbox_new (FALSE, 6);
2057 label = gtk_label_new_with_mnemonic (_("_Palette:"));
2058 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2059 gtk_box_pack_start (GTK_BOX (priv->palette_frame), label, FALSE, FALSE, 0);
2061 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
2062 priv->custom_palette[0][0]);
2064 gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
2065 gtk_box_pack_start (GTK_BOX (priv->palette_frame), table, FALSE, FALSE, 0);
2067 gtk_widget_show_all (top_hbox);
2069 /* hide unused stuff */
2071 if (priv->has_opacity == FALSE)
2073 gtk_widget_hide (priv->opacity_label);
2074 gtk_widget_hide (priv->opacity_slider);
2075 gtk_widget_hide (priv->opacity_entry);
2078 if (priv->has_palette == FALSE)
2080 gtk_widget_hide (priv->palette_frame);
2083 atk_obj = gtk_widget_get_accessible (priv->triangle_colorsel);
2084 if (GTK_IS_ACCESSIBLE (atk_obj))
2086 atk_object_set_name (atk_obj, _("Color Wheel"));
2087 atk_object_set_role (gtk_widget_get_accessible (GTK_WIDGET (colorsel)), ATK_ROLE_COLOR_CHOOSER);
2088 make_all_relations (atk_obj, priv);
2091 gtk_widget_pop_composite_child ();
2095 gtk_color_selection_destroy (GtkObject *object)
2097 GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
2098 ColorSelectionPrivate *priv = cselection->private_data;
2100 if (priv->dropper_grab_widget)
2102 gtk_widget_destroy (priv->dropper_grab_widget);
2103 priv->dropper_grab_widget = NULL;
2108 g_object_unref (priv->tooltips);
2109 priv->tooltips = NULL;
2112 GTK_OBJECT_CLASS (gtk_color_selection_parent_class)->destroy (object);
2116 gtk_color_selection_finalize (GObject *object)
2118 G_OBJECT_CLASS (gtk_color_selection_parent_class)->finalize (object);
2122 gtk_color_selection_realize (GtkWidget *widget)
2124 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
2125 ColorSelectionPrivate *priv = colorsel->private_data;
2126 GtkSettings *settings = gtk_widget_get_settings (widget);
2128 priv->settings_connection = g_signal_connect (settings,
2129 "notify::gtk-color-palette",
2130 G_CALLBACK (palette_change_notify_instance),
2132 update_palette (colorsel);
2134 GTK_WIDGET_CLASS (gtk_color_selection_parent_class)->realize (widget);
2138 gtk_color_selection_unrealize (GtkWidget *widget)
2140 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
2141 ColorSelectionPrivate *priv = colorsel->private_data;
2142 GtkSettings *settings = gtk_widget_get_settings (widget);
2144 g_signal_handler_disconnect (settings, priv->settings_connection);
2146 GTK_WIDGET_CLASS (gtk_color_selection_parent_class)->unrealize (widget);
2149 /* We override show-all since we have internal widgets that
2150 * shouldn't be shown when you call show_all(), like the
2151 * palette and opacity sliders.
2154 gtk_color_selection_show_all (GtkWidget *widget)
2156 gtk_widget_show (widget);
2160 * gtk_color_selection_new:
2162 * Creates a new GtkColorSelection.
2164 * Return value: a new #GtkColorSelection
2167 gtk_color_selection_new (void)
2169 GtkColorSelection *colorsel;
2170 ColorSelectionPrivate *priv;
2177 colorsel = g_object_new (GTK_TYPE_COLOR_SELECTION, NULL);
2178 priv = colorsel->private_data;
2179 set_color_internal (colorsel, color);
2180 gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
2182 /* We want to make sure that default_set is FALSE */
2183 /* This way the user can still set it */
2184 priv->default_set = FALSE;
2185 priv->default_alpha_set = FALSE;
2187 return GTK_WIDGET (colorsel);
2192 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
2193 GtkUpdateType policy)
2195 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2199 * gtk_color_selection_get_has_opacity_control:
2200 * @colorsel: a #GtkColorSelection.
2202 * Determines whether the colorsel has an opacity control.
2204 * Return value: %TRUE if the @colorsel has an opacity control. %FALSE if it does't.
2207 gtk_color_selection_get_has_opacity_control (GtkColorSelection *colorsel)
2209 ColorSelectionPrivate *priv;
2211 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2213 priv = colorsel->private_data;
2215 return priv->has_opacity;
2219 * gtk_color_selection_set_has_opacity_control:
2220 * @colorsel: a #GtkColorSelection.
2221 * @has_opacity: %TRUE if @colorsel can set the opacity, %FALSE otherwise.
2223 * Sets the @colorsel to use or not use opacity.
2227 gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel,
2228 gboolean has_opacity)
2230 ColorSelectionPrivate *priv;
2232 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2234 priv = colorsel->private_data;
2235 has_opacity = has_opacity != FALSE;
2237 if (priv->has_opacity != has_opacity)
2239 priv->has_opacity = has_opacity;
2242 gtk_widget_show (priv->opacity_slider);
2243 gtk_widget_show (priv->opacity_label);
2244 gtk_widget_show (priv->opacity_entry);
2248 gtk_widget_hide (priv->opacity_slider);
2249 gtk_widget_hide (priv->opacity_label);
2250 gtk_widget_hide (priv->opacity_entry);
2252 color_sample_update_samples (colorsel);
2254 g_object_notify (G_OBJECT (colorsel), "has-opacity-control");
2259 * gtk_color_selection_get_has_palette:
2260 * @colorsel: a #GtkColorSelection.
2262 * Determines whether the color selector has a color palette.
2264 * Return value: %TRUE if the selector has a palette. %FALSE if it hasn't.
2267 gtk_color_selection_get_has_palette (GtkColorSelection *colorsel)
2269 ColorSelectionPrivate *priv;
2271 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2273 priv = colorsel->private_data;
2275 return priv->has_palette;
2279 * gtk_color_selection_set_has_palette:
2280 * @colorsel: a #GtkColorSelection.
2281 * @has_palette: %TRUE if palette is to be visible, %FALSE otherwise.
2283 * Shows and hides the palette based upon the value of @has_palette.
2287 gtk_color_selection_set_has_palette (GtkColorSelection *colorsel,
2288 gboolean has_palette)
2290 ColorSelectionPrivate *priv;
2291 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2293 priv = colorsel->private_data;
2294 has_palette = has_palette != FALSE;
2296 if (priv->has_palette != has_palette)
2298 priv->has_palette = has_palette;
2300 gtk_widget_show (priv->palette_frame);
2302 gtk_widget_hide (priv->palette_frame);
2304 g_object_notify (G_OBJECT (colorsel), "has-palette");
2309 * gtk_color_selection_set_current_color:
2310 * @colorsel: a #GtkColorSelection.
2311 * @color: A #GdkColor to set the current color with.
2313 * Sets the current color to be @color. The first time this is called, it will
2314 * also set the original color to be @color too.
2317 gtk_color_selection_set_current_color (GtkColorSelection *colorsel,
2318 const GdkColor *color)
2320 ColorSelectionPrivate *priv;
2323 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2324 g_return_if_fail (color != NULL);
2326 priv = colorsel->private_data;
2327 priv->changing = TRUE;
2328 priv->color[COLORSEL_RED] = SCALE (color->red);
2329 priv->color[COLORSEL_GREEN] = SCALE (color->green);
2330 priv->color[COLORSEL_BLUE] = SCALE (color->blue);
2331 gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
2332 priv->color[COLORSEL_GREEN],
2333 priv->color[COLORSEL_BLUE],
2334 &priv->color[COLORSEL_HUE],
2335 &priv->color[COLORSEL_SATURATION],
2336 &priv->color[COLORSEL_VALUE]);
2337 if (priv->default_set == FALSE)
2339 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2340 priv->old_color[i] = priv->color[i];
2342 priv->default_set = TRUE;
2343 update_color (colorsel);
2347 * gtk_color_selection_set_current_alpha:
2348 * @colorsel: a #GtkColorSelection.
2349 * @alpha: an integer between 0 and 65535.
2351 * Sets the current opacity to be @alpha. The first time this is called, it will
2352 * also set the original opacity to be @alpha too.
2355 gtk_color_selection_set_current_alpha (GtkColorSelection *colorsel,
2358 ColorSelectionPrivate *priv;
2361 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2363 priv = colorsel->private_data;
2364 priv->changing = TRUE;
2365 priv->color[COLORSEL_OPACITY] = SCALE (alpha);
2366 if (priv->default_alpha_set == FALSE)
2368 for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
2369 priv->old_color[i] = priv->color[i];
2371 priv->default_alpha_set = TRUE;
2372 update_color (colorsel);
2376 * gtk_color_selection_set_color:
2377 * @colorsel: a #GtkColorSelection.
2378 * @color: an array of 4 doubles specifying the red, green, blue and opacity
2379 * to set the current color to.
2381 * Sets the current color to be @color. The first time this is called, it will
2382 * also set the original color to be @color too.
2384 * Deprecated: Use gtk_color_selection_set_current_color() instead.
2387 gtk_color_selection_set_color (GtkColorSelection *colorsel,
2390 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2392 set_color_internal (colorsel, color);
2396 * gtk_color_selection_get_current_color:
2397 * @colorsel: a #GtkColorSelection.
2398 * @color: a #GdkColor to fill in with the current color.
2400 * Sets @color to be the current color in the GtkColorSelection widget.
2403 gtk_color_selection_get_current_color (GtkColorSelection *colorsel,
2406 ColorSelectionPrivate *priv;
2408 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2409 g_return_if_fail (color != NULL);
2411 priv = colorsel->private_data;
2412 color->red = UNSCALE (priv->color[COLORSEL_RED]);
2413 color->green = UNSCALE (priv->color[COLORSEL_GREEN]);
2414 color->blue = UNSCALE (priv->color[COLORSEL_BLUE]);
2418 * gtk_color_selection_get_current_alpha:
2419 * @colorsel: a #GtkColorSelection.
2421 * Returns the current alpha value.
2423 * Return value: an integer between 0 and 65535.
2426 gtk_color_selection_get_current_alpha (GtkColorSelection *colorsel)
2428 ColorSelectionPrivate *priv;
2430 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2432 priv = colorsel->private_data;
2433 return priv->has_opacity ? UNSCALE (priv->color[COLORSEL_OPACITY]) : 65535;
2437 * gtk_color_selection_get_color:
2438 * @colorsel: a #GtkColorSelection.
2439 * @color: an array of 4 #gdouble to fill in with the current color.
2441 * Sets @color to be the current color in the GtkColorSelection widget.
2443 * This function is deprecated, use gtk_color_selection_get_current_color() instead.
2446 gtk_color_selection_get_color (GtkColorSelection *colorsel,
2449 ColorSelectionPrivate *priv;
2451 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2453 priv = colorsel->private_data;
2454 color[0] = priv->color[COLORSEL_RED];
2455 color[1] = priv->color[COLORSEL_GREEN];
2456 color[2] = priv->color[COLORSEL_BLUE];
2457 color[3] = priv->has_opacity ? priv->color[COLORSEL_OPACITY] : 65535;
2461 * gtk_color_selection_set_previous_color:
2462 * @colorsel: a #GtkColorSelection.
2463 * @color: a #GdkColor to set the previous color with.
2465 * Sets the 'previous' color to be @color. This function should be called with
2466 * some hesitations, as it might seem confusing to have that color change.
2467 * Calling gtk_color_selection_set_current_color() will also set this color the first
2468 * time it is called.
2471 gtk_color_selection_set_previous_color (GtkColorSelection *colorsel,
2472 const GdkColor *color)
2474 ColorSelectionPrivate *priv;
2476 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2477 g_return_if_fail (color != NULL);
2479 priv = colorsel->private_data;
2480 priv->changing = TRUE;
2481 priv->old_color[COLORSEL_RED] = SCALE (color->red);
2482 priv->old_color[COLORSEL_GREEN] = SCALE (color->green);
2483 priv->old_color[COLORSEL_BLUE] = SCALE (color->blue);
2484 gtk_rgb_to_hsv (priv->old_color[COLORSEL_RED],
2485 priv->old_color[COLORSEL_GREEN],
2486 priv->old_color[COLORSEL_BLUE],
2487 &priv->old_color[COLORSEL_HUE],
2488 &priv->old_color[COLORSEL_SATURATION],
2489 &priv->old_color[COLORSEL_VALUE]);
2490 color_sample_update_samples (colorsel);
2491 priv->default_set = TRUE;
2492 priv->changing = FALSE;
2496 * gtk_color_selection_set_previous_alpha:
2497 * @colorsel: a #GtkColorSelection.
2498 * @alpha: an integer between 0 and 65535.
2500 * Sets the 'previous' alpha to be @alpha. This function should be called with
2501 * some hesitations, as it might seem confusing to have that alpha change.
2504 gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel,
2507 ColorSelectionPrivate *priv;
2509 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2511 priv = colorsel->private_data;
2512 priv->changing = TRUE;
2513 priv->old_color[COLORSEL_OPACITY] = SCALE (alpha);
2514 color_sample_update_samples (colorsel);
2515 priv->default_alpha_set = TRUE;
2516 priv->changing = FALSE;
2521 * gtk_color_selection_get_previous_color:
2522 * @colorsel: a #GtkColorSelection.
2523 * @color: a #GdkColor to fill in with the original color value.
2525 * Fills @color in with the original color value.
2528 gtk_color_selection_get_previous_color (GtkColorSelection *colorsel,
2531 ColorSelectionPrivate *priv;
2533 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2534 g_return_if_fail (color != NULL);
2536 priv = colorsel->private_data;
2537 color->red = UNSCALE (priv->old_color[COLORSEL_RED]);
2538 color->green = UNSCALE (priv->old_color[COLORSEL_GREEN]);
2539 color->blue = UNSCALE (priv->old_color[COLORSEL_BLUE]);
2543 * gtk_color_selection_get_previous_alpha:
2544 * @colorsel: a #GtkColorSelection.
2546 * Returns the previous alpha value.
2548 * Return value: an integer between 0 and 65535.
2551 gtk_color_selection_get_previous_alpha (GtkColorSelection *colorsel)
2553 ColorSelectionPrivate *priv;
2555 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), 0);
2557 priv = colorsel->private_data;
2558 return priv->has_opacity ? UNSCALE (priv->old_color[COLORSEL_OPACITY]) : 65535;
2562 * gtk_color_selection_set_palette_color:
2563 * @colorsel: a #GtkColorSelection.
2564 * @index: the color index of the palette.
2565 * @color: A #GdkColor to set the palette with.
2567 * Sets the palette located at @index to have @color as its color.
2571 gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
2575 ColorSelectionPrivate *priv;
2579 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
2580 g_return_if_fail (index >= 0 && index < GTK_CUSTOM_PALETTE_WIDTH*GTK_CUSTOM_PALETTE_HEIGHT);
2582 x = index % GTK_CUSTOM_PALETTE_WIDTH;
2583 y = index / GTK_CUSTOM_PALETTE_WIDTH;
2585 priv = colorsel->private_data;
2586 col[0] = SCALE (color->red);
2587 col[1] = SCALE (color->green);
2588 col[2] = SCALE (color->blue);
2590 palette_set_color (priv->custom_palette[x][y], colorsel, col);
2594 * gtk_color_selection_is_adjusting:
2595 * @colorsel: a #GtkColorSelection.
2597 * Gets the current state of the @colorsel.
2599 * Return value: %TRUE if the user is currently dragging a color around, and %FALSE
2600 * if the selection has stopped.
2603 gtk_color_selection_is_adjusting (GtkColorSelection *colorsel)
2605 ColorSelectionPrivate *priv;
2607 g_return_val_if_fail (GTK_IS_COLOR_SELECTION (colorsel), FALSE);
2609 priv = colorsel->private_data;
2611 return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
2615 gtk_color_selection_set_property (GObject *object,
2617 const GValue *value,
2620 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2624 case PROP_HAS_OPACITY_CONTROL:
2625 gtk_color_selection_set_has_opacity_control (colorsel,
2626 g_value_get_boolean (value));
2628 case PROP_HAS_PALETTE:
2629 gtk_color_selection_set_has_palette (colorsel,
2630 g_value_get_boolean (value));
2632 case PROP_CURRENT_COLOR:
2633 gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
2635 case PROP_CURRENT_ALPHA:
2636 gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
2639 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2646 gtk_color_selection_get_property (GObject *object,
2651 GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
2656 case PROP_HAS_OPACITY_CONTROL:
2657 g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
2659 case PROP_HAS_PALETTE:
2660 g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
2662 case PROP_CURRENT_COLOR:
2663 gtk_color_selection_get_current_color (colorsel, &color);
2664 g_value_set_boxed (value, &color);
2666 case PROP_CURRENT_ALPHA:
2667 g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
2670 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2677 * gtk_color_selection_palette_from_string:
2678 * @str: a string encoding a color palette.
2679 * @colors: return location for allocated array of #GdkColor.
2680 * @n_colors: return location for length of array.
2682 * Parses a color palette string; the string is a colon-separated
2683 * list of color names readable by gdk_color_parse().
2685 * Return value: %TRUE if a palette was successfully parsed.
2688 gtk_color_selection_palette_from_string (const gchar *str,
2700 copy = g_strdup (str);
2706 if (*p == ':' || *p == '\0')
2708 gboolean done = TRUE;
2712 goto failed; /* empty entry */
2721 retval = g_renew (GdkColor, retval, count + 1);
2722 if (!gdk_color_parse (start, retval + count))
2763 * gtk_color_selection_palette_to_string:
2764 * @colors: an array of colors.
2765 * @n_colors: length of the array.
2767 * Encodes a palette as a string, useful for persistent storage.
2769 * Return value: allocated string encoding the palette.
2772 gtk_color_selection_palette_to_string (const GdkColor *colors,
2776 gchar **strs = NULL;
2780 return g_strdup ("");
2782 strs = g_new0 (gchar*, n_colors + 1);
2785 while (i < n_colors)
2790 g_strdup_printf ("#%2X%2X%2X",
2791 colors[i].red / 256,
2792 colors[i].green / 256,
2793 colors[i].blue / 256);
2795 for (ptr = strs[i]; *ptr; ptr++)
2802 retval = g_strjoinv (":", strs);
2810 * gtk_color_selection_set_change_palette_hook:
2811 * @func: a function to call when the custom palette needs saving.
2813 * Installs a global function to be called whenever the user tries to
2814 * modify the palette in a color selection. This function should save
2815 * the new palette contents, and update the GtkSettings property
2816 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2818 * Return value: the previous change palette hook (that was replaced).
2820 * Deprecated: This function is deprecated in favor of
2821 * gtk_color_selection_set_change_palette_with_screen_hook(), and does
2822 * not work in multihead environments.
2825 GtkColorSelectionChangePaletteFunc
2826 gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func)
2828 GtkColorSelectionChangePaletteFunc old;
2830 old = noscreen_change_palette_hook;
2832 noscreen_change_palette_hook = func;
2838 * gtk_color_selection_set_change_palette_with_screen_hook:
2839 * @func: a function to call when the custom palette needs saving.
2841 * Installs a global function to be called whenever the user tries to
2842 * modify the palette in a color selection. This function should save
2843 * the new palette contents, and update the GtkSettings property
2844 * "gtk-color-palette" so all GtkColorSelection widgets will be modified.
2846 * Return value: the previous change palette hook (that was replaced).
2850 GtkColorSelectionChangePaletteWithScreenFunc
2851 gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func)
2853 GtkColorSelectionChangePaletteWithScreenFunc old;
2855 old = change_palette_hook;
2857 change_palette_hook = func;
2863 make_control_relations (AtkObject *atk_obj,
2868 obj = gtk_widget_get_accessible (widget);
2869 atk_object_add_relationship (atk_obj, ATK_RELATION_CONTROLLED_BY, obj);
2870 atk_object_add_relationship (obj, ATK_RELATION_CONTROLLER_FOR, atk_obj);
2874 make_all_relations (AtkObject *atk_obj,
2875 ColorSelectionPrivate *priv)
2877 make_control_relations (atk_obj, priv->hue_spinbutton);
2878 make_control_relations (atk_obj, priv->sat_spinbutton);
2879 make_control_relations (atk_obj, priv->val_spinbutton);
2880 make_control_relations (atk_obj, priv->red_spinbutton);
2881 make_control_relations (atk_obj, priv->green_spinbutton);
2882 make_control_relations (atk_obj, priv->blue_spinbutton);
2885 #define __GTK_COLOR_SELECTION_C__
2886 #include "gtkaliasdef.c"