1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include "gtkcolorsel.h"
32 #include "gtkwindow.h"
36 #include "gtkselection.h"
39 * If you change the way the color values are stored,
40 * please make sure to update the drag & drop support so it sends
41 * across all the color info (currently RGBA). - Elliot
45 #define M_PI 3.14159265358979323846
48 #define DEGTORAD(a) (2.0*M_PI*a/360.0)
51 #define TIMER_DELAY 300
53 #define CIRCLE_RADIUS 65
55 #define WHEEL_WIDTH 2*CIRCLE_RADIUS+2
56 #define WHEEL_HEIGHT 2*CIRCLE_RADIUS+2
58 #define VALUE_WIDTH 32
59 #define VALUE_HEIGHT WHEEL_HEIGHT
61 #define SAMPLE_WIDTH WHEEL_WIDTH+VALUE_WIDTH+5
62 #define SAMPLE_HEIGHT 28
64 static void gtk_color_selection_class_init (GtkColorSelectionClass *klass);
65 static void gtk_color_selection_init (GtkColorSelection *colorsel);
66 static void gtk_color_selection_dialog_class_init(GtkColorSelectionDialogClass *klass);
67 static void gtk_color_selection_dialog_init(GtkColorSelectionDialog *colorseldiag);
79 OPACITY_INPUTS = 1 << 2
104 gfloat lower, upper, step_inc, page_inc;
105 GtkSignalFunc updater;
109 #define HSV_TO_RGB() gtk_color_selection_hsv_to_rgb( \
110 colorsel->values[HUE], \
111 colorsel->values[SATURATION], \
112 colorsel->values[VALUE], \
113 &colorsel->values[RED], \
114 &colorsel->values[GREEN], \
115 &colorsel->values[BLUE])
117 #define RGB_TO_HSV() gtk_color_selection_rgb_to_hsv( \
118 colorsel->values[RED], \
119 colorsel->values[GREEN], \
120 colorsel->values[BLUE], \
121 &colorsel->values[HUE], \
122 &colorsel->values[SATURATION], \
123 &colorsel->values[VALUE])
126 static void gtk_color_selection_hsv_updater (GtkWidget *widget,
128 static void gtk_color_selection_rgb_updater (GtkWidget *widget,
130 static void gtk_color_selection_opacity_updater (GtkWidget *widget,
132 static void gtk_color_selection_realize (GtkWidget *widget);
133 static void gtk_color_selection_unrealize (GtkWidget *widget);
134 static void gtk_color_selection_finalize (GtkObject *object);
135 static void gtk_color_selection_color_changed (GtkColorSelection *colorsel);
136 static void gtk_color_selection_update_input (GtkWidget *scale,
139 static void gtk_color_selection_update_inputs (GtkColorSelection *colorsel,
142 static void gtk_color_selection_update_value (GtkColorSelection *colorsel,
144 static void gtk_color_selection_update_wheel (GtkColorSelection *colorsel,
147 static void gtk_color_selection_value_resize (GtkWidget *widget,
149 static gint gtk_color_selection_value_events (GtkWidget *area,
151 static gint gtk_color_selection_value_timeout (GtkColorSelection *colorsel);
152 static void gtk_color_selection_wheel_resize (GtkWidget *widget,
154 static gint gtk_color_selection_wheel_events (GtkWidget *area,
156 static gint gtk_color_selection_wheel_timeout (GtkColorSelection *colorsel);
157 static void gtk_color_selection_sample_resize (GtkWidget *widget,
159 static void gtk_color_selection_drag_begin (GtkWidget *widget,
160 GdkDragContext *context,
162 static void gtk_color_selection_drag_end (GtkWidget *widget,
163 GdkDragContext *context,
165 static void gtk_color_selection_drop_handle (GtkWidget *widget,
166 GdkDragContext *context,
169 GtkSelectionData *selection_data,
173 static void gtk_color_selection_drag_handle (GtkWidget *widget,
174 GdkDragContext *context,
175 GtkSelectionData *selection_data,
179 static void gtk_color_selection_draw_wheel_marker (GtkColorSelection *colorsel);
180 static void gtk_color_selection_draw_wheel_frame (GtkColorSelection *colorsel);
181 static void gtk_color_selection_draw_value_marker (GtkColorSelection *colorsel);
182 static void gtk_color_selection_draw_value_bar (GtkColorSelection *colorsel,
184 static void gtk_color_selection_draw_wheel (GtkColorSelection *colorsel,
186 static void gtk_color_selection_draw_sample (GtkColorSelection *colorsel,
189 static gint gtk_color_selection_eval_wheel (gint x, gint y,
190 gdouble cx, gdouble cy,
191 gdouble *h, gdouble *s);
193 static void gtk_color_selection_hsv_to_rgb (gdouble h, gdouble s, gdouble v,
194 gdouble *r, gdouble *g, gdouble *b);
195 static void gtk_color_selection_rgb_to_hsv (gdouble r, gdouble g, gdouble b,
196 gdouble *h, gdouble *s, gdouble *v);
199 static GtkVBoxClass *color_selection_parent_class = NULL;
200 static GtkWindowClass *color_selection_dialog_parent_class = NULL;
203 static guint color_selection_signals[LAST_SIGNAL] = {0};
205 static const gchar *value_index_key = "gtk-value-index";
208 #define SF GtkSignalFunc
211 static const scale_val_type scale_vals[NUM_CHANNELS] =
213 {N_("Hue:"), 0.0, 360.0, 1.00, 10.00, (SF) gtk_color_selection_hsv_updater},
214 {N_("Saturation:"), 0.0, 1.0, 0.01, 0.01, (SF) gtk_color_selection_hsv_updater},
215 {N_("Value:"), 0.0, 1.0, 0.01, 0.01, (SF) gtk_color_selection_hsv_updater},
216 {N_("Red:"), 0.0, 1.0, 0.01, 0.01, (SF) gtk_color_selection_rgb_updater},
217 {N_("Green:"), 0.0, 1.0, 0.01, 0.01, (SF) gtk_color_selection_rgb_updater},
218 {N_("Blue:"), 0.0, 1.0, 0.01, 0.01, (SF) gtk_color_selection_rgb_updater},
219 {N_("Opacity:"), 0.0, 1.0, 0.01, 0.01, (SF) gtk_color_selection_opacity_updater}
223 gtk_color_selection_get_type (void)
225 static GtkType color_selection_type = 0;
227 if (!color_selection_type)
229 static const GtkTypeInfo colorsel_info =
232 sizeof (GtkColorSelection),
233 sizeof (GtkColorSelectionClass),
234 (GtkClassInitFunc) gtk_color_selection_class_init,
235 (GtkObjectInitFunc) gtk_color_selection_init,
236 /* reserved_1 */ NULL,
237 /* reserved_2 */ NULL,
238 (GtkClassInitFunc) NULL,
241 color_selection_type = gtk_type_unique (gtk_vbox_get_type (), &colorsel_info);
244 return color_selection_type;
248 gtk_color_selection_class_init (GtkColorSelectionClass *klass)
250 GtkObjectClass *object_class;
251 GtkWidgetClass *widget_class;
252 GtkContainerClass *container_class;
254 object_class = (GtkObjectClass*) klass;
255 widget_class = (GtkWidgetClass*) klass;
256 container_class = (GtkContainerClass*) klass;
258 color_selection_parent_class = gtk_type_class (gtk_vbox_get_type ());
260 color_selection_signals[COLOR_CHANGED] =
261 gtk_signal_new ("color_changed",
264 GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
265 gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);
267 gtk_object_class_add_signals (object_class, color_selection_signals, LAST_SIGNAL);
269 object_class->finalize = gtk_color_selection_finalize;
271 widget_class->realize = gtk_color_selection_realize;
272 widget_class->unrealize = gtk_color_selection_unrealize;
276 gtk_color_selection_init (GtkColorSelection *colorsel)
278 GtkWidget *frame, *hbox, *vbox, *hbox2, *label, *table;
283 for (n = RED; n <= OPACITY; n++)
284 colorsel->values[n] = 1.0;
288 for (n = HUE; n <= OPACITY; n++)
289 colorsel->old_values[n] = colorsel->values[n];
291 colorsel->wheel_gc = NULL;
292 colorsel->value_gc = NULL;
293 colorsel->sample_gc = NULL;
294 colorsel->wheel_buf = NULL;
295 colorsel->value_buf = NULL;
296 colorsel->sample_buf = NULL;
298 colorsel->use_opacity = FALSE;
299 colorsel->timer_active = FALSE;
300 colorsel->policy = GTK_UPDATE_CONTINUOUS;
302 hbox = gtk_hbox_new (FALSE, 5);
303 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
304 gtk_container_add (GTK_CONTAINER (colorsel), hbox);
306 vbox = gtk_vbox_new (FALSE, 5);
307 gtk_container_add (GTK_CONTAINER (hbox), vbox);
308 gtk_widget_show (vbox);
310 hbox2 = gtk_hbox_new (FALSE, 5);
311 gtk_container_add (GTK_CONTAINER (vbox), hbox2);
312 gtk_widget_show (hbox2);
314 colorsel->wheel_area = gtk_preview_new (GTK_PREVIEW_COLOR);
315 old_mask = gtk_widget_get_events(colorsel->wheel_area);
316 gtk_widget_set_events (colorsel->wheel_area,
318 GDK_BUTTON_PRESS_MASK |
319 GDK_BUTTON_RELEASE_MASK |
320 GDK_BUTTON_MOTION_MASK |
321 GDK_POINTER_MOTION_HINT_MASK);
322 gtk_preview_size (GTK_PREVIEW (colorsel->wheel_area), WHEEL_WIDTH, WHEEL_HEIGHT);
323 gtk_preview_set_expand (GTK_PREVIEW (colorsel->wheel_area), TRUE);
324 gtk_container_add (GTK_CONTAINER (hbox2), colorsel->wheel_area);
325 gtk_widget_show (colorsel->wheel_area);
327 old_mask = gtk_widget_get_events (colorsel->wheel_area);
329 gtk_signal_connect (GTK_OBJECT (colorsel->wheel_area), "event",
330 (SF) gtk_color_selection_wheel_events, (gpointer) colorsel->wheel_area);
331 gtk_signal_connect_after (GTK_OBJECT (colorsel->wheel_area), "expose_event",
332 (SF) gtk_color_selection_wheel_events, (gpointer) colorsel->wheel_area);
333 gtk_signal_connect_after (GTK_OBJECT (colorsel->wheel_area), "size_allocate",
334 (SF) gtk_color_selection_wheel_resize, (gpointer) colorsel->wheel_area);
335 gtk_object_set_data (GTK_OBJECT (colorsel->wheel_area), "_GtkColorSelection", (gpointer) colorsel);
337 frame = gtk_frame_new (NULL);
338 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
339 gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
340 gtk_box_pack_start (GTK_BOX (hbox2), frame, FALSE, TRUE, 0);
341 gtk_widget_show (frame);
343 colorsel->value_area = gtk_preview_new (GTK_PREVIEW_COLOR);
344 gtk_preview_size (GTK_PREVIEW (colorsel->value_area), VALUE_WIDTH, VALUE_HEIGHT);
345 gtk_preview_set_expand (GTK_PREVIEW (colorsel->value_area), TRUE);
346 gtk_container_add (GTK_CONTAINER (frame), colorsel->value_area);
347 gtk_widget_show (colorsel->value_area);
349 old_mask = gtk_widget_get_events (colorsel->value_area);
350 gtk_widget_set_events (colorsel->value_area,
352 GDK_BUTTON_PRESS_MASK |
353 GDK_BUTTON_RELEASE_MASK |
354 GDK_BUTTON_MOTION_MASK |
355 GDK_POINTER_MOTION_HINT_MASK);
357 gtk_signal_connect_after (GTK_OBJECT (colorsel->value_area), "expose_event",
358 (SF) gtk_color_selection_value_events, (gpointer) colorsel->value_area);
359 gtk_signal_connect_after (GTK_OBJECT (colorsel->value_area), "size_allocate",
360 (SF) gtk_color_selection_value_resize, (gpointer) colorsel->value_area);
361 gtk_signal_connect (GTK_OBJECT (colorsel->value_area), "event",
362 (SF) gtk_color_selection_value_events, (gpointer) colorsel->value_area);
363 gtk_object_set_data (GTK_OBJECT (colorsel->value_area), "_GtkColorSelection", (gpointer) colorsel);
365 /* New/old color samples */
366 /* ===================== */
368 frame = gtk_frame_new (NULL);
369 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
370 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
371 gtk_widget_show (frame);
373 /* colorsel->sample_area_eb = gtk_button_new ();
374 gtk_container_add (GTK_CONTAINER (frame), colorsel->sample_area_eb);
375 gtk_widget_show (colorsel->sample_area_eb); */
377 colorsel->sample_area = gtk_preview_new (GTK_PREVIEW_COLOR);
378 gtk_preview_size (GTK_PREVIEW (colorsel->sample_area), SAMPLE_WIDTH, SAMPLE_HEIGHT);
379 gtk_preview_set_expand (GTK_PREVIEW (colorsel->sample_area), TRUE);
380 gtk_container_add (GTK_CONTAINER (frame),
381 colorsel->sample_area);
382 gtk_widget_set_events(colorsel->sample_area,
383 gtk_widget_get_events(colorsel->sample_area)
384 | GDK_BUTTON_MOTION_MASK
385 | GDK_BUTTON_PRESS_MASK
386 | GDK_BUTTON_RELEASE_MASK
387 | GDK_ENTER_NOTIFY_MASK
388 | GDK_LEAVE_NOTIFY_MASK);
389 gtk_widget_show (colorsel->sample_area);
391 gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
393 GTK_SIGNAL_FUNC (gtk_color_selection_sample_resize),
394 colorsel->sample_area);
395 gtk_object_set_data (GTK_OBJECT (colorsel->sample_area), "_GtkColorSelection", (gpointer) colorsel);
397 table = gtk_table_new (NUM_CHANNELS, 3, FALSE);
398 gtk_table_set_col_spacings (GTK_TABLE (table), 3);
399 gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, TRUE, 0);
401 for (n = HUE; n <= OPACITY; n++)
403 label = gtk_label_new (_(scale_vals[n].label));
404 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
405 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, n, n + 1);
407 adj = gtk_adjustment_new (colorsel->values[n], scale_vals[n].lower,
408 scale_vals[n].upper, scale_vals[n].step_inc,
409 scale_vals[n].page_inc, 0.0);
410 colorsel->scales[n] = gtk_hscale_new (GTK_ADJUSTMENT (adj));
411 gtk_widget_set_usize (colorsel->scales[n], 128, 0);
412 gtk_scale_set_value_pos (GTK_SCALE (colorsel->scales[n]), GTK_POS_TOP);
414 gtk_range_set_update_policy (GTK_RANGE (colorsel->scales[n]), colorsel->policy);
415 gtk_scale_set_draw_value (GTK_SCALE (colorsel->scales[n]), FALSE);
416 gtk_scale_set_digits (GTK_SCALE (colorsel->scales[n]), 2);
417 gtk_table_attach_defaults (GTK_TABLE (table), colorsel->scales[n], 1, 2, n, n + 1);
419 colorsel->entries[n] = gtk_entry_new ();
420 gtk_widget_set_usize (colorsel->entries[n], 40, 0);
421 sprintf (txt, "%.2f", colorsel->values[n]);
422 gtk_entry_set_text (GTK_ENTRY (colorsel->entries[n]), txt);
423 gtk_table_attach_defaults (GTK_TABLE (table), colorsel->entries[n], 2, 3, n, n + 1);
427 gtk_widget_show (label);
428 gtk_widget_show (colorsel->scales[n]);
429 gtk_widget_show (colorsel->entries[n]);
432 gtk_signal_connect_object (GTK_OBJECT (adj), "value_changed",
433 scale_vals[n].updater, (gpointer) colorsel->scales[n]);
434 gtk_object_set_data (GTK_OBJECT (colorsel->scales[n]), "_GtkColorSelection", (gpointer) colorsel);
435 gtk_object_set_data (GTK_OBJECT (colorsel->scales[n]), value_index_key, GINT_TO_POINTER (n));
436 gtk_signal_connect_object (GTK_OBJECT (colorsel->entries[n]), "changed",
437 scale_vals[n].updater, (gpointer) colorsel->entries[n]);
438 gtk_object_set_data (GTK_OBJECT (colorsel->entries[n]), "_GtkColorSelection", (gpointer) colorsel);
439 gtk_object_set_data (GTK_OBJECT (colorsel->entries[n]), value_index_key, GINT_TO_POINTER (n));
442 colorsel->opacity_label = label;
444 gtk_widget_show (table);
445 gtk_widget_show (hbox);
449 gtk_color_selection_new (void)
451 GtkColorSelection *colorsel;
453 colorsel = gtk_type_new (gtk_color_selection_get_type ());
455 return GTK_WIDGET (colorsel);
459 gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
460 GtkUpdateType policy)
464 g_return_if_fail (colorsel != NULL);
466 if (policy != colorsel->policy)
468 colorsel->policy = policy;
470 for (n = 0; n < NUM_CHANNELS; n++)
471 gtk_range_set_update_policy (GTK_RANGE (colorsel->scales[n]), policy);
477 gtk_color_selection_set_color (GtkColorSelection *colorsel,
482 g_return_if_fail (colorsel != NULL);
483 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
485 if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (colorsel)))
486 gtk_color_selection_draw_wheel_marker (colorsel);
488 for (n = RED; n <= BLUE; n++)
490 colorsel->old_values[n] = colorsel->values[n];
491 colorsel->values[n] = color[i++];
494 if (colorsel->use_opacity)
496 colorsel->old_values[OPACITY] = colorsel->values[OPACITY];
497 colorsel->values[OPACITY] = color[i];
502 gtk_color_selection_update_inputs (colorsel, RGB_INPUTS | HSV_INPUTS | OPACITY_INPUTS, BOTH);
504 if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (colorsel)))
506 gtk_color_selection_draw_value_bar (colorsel, FALSE);
507 gtk_color_selection_draw_sample (colorsel, FALSE);
508 gtk_color_selection_draw_wheel_marker (colorsel);
513 gtk_color_selection_get_color (GtkColorSelection *colorsel,
518 g_return_if_fail (colorsel != NULL);
519 g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
521 for (n = RED; n <= BLUE; n++)
522 color[i++] = colorsel->values[n];
523 if (colorsel->use_opacity)
524 color[i] = colorsel->values[OPACITY];
528 gtk_color_selection_realize (GtkWidget *widget)
530 GtkColorSelection *colorsel;
532 static const GtkTargetEntry targets[] = {
533 { "application/x-color", 0 }
536 g_return_if_fail (widget != NULL);
537 g_return_if_fail (GTK_IS_COLOR_SELECTION (widget));
539 colorsel = GTK_COLOR_SELECTION (widget);
541 if (GTK_WIDGET_CLASS (color_selection_parent_class)->realize)
542 (*GTK_WIDGET_CLASS (color_selection_parent_class)->realize) (widget);
544 gtk_drag_dest_set (colorsel->sample_area,
545 GTK_DEST_DEFAULT_HIGHLIGHT |
546 GTK_DEST_DEFAULT_MOTION |
547 GTK_DEST_DEFAULT_DROP,
551 gtk_drag_source_set (colorsel->sample_area,
552 GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
554 GDK_ACTION_COPY | GDK_ACTION_MOVE);
556 gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
558 GTK_SIGNAL_FUNC (gtk_color_selection_drag_begin),
560 gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
562 GTK_SIGNAL_FUNC (gtk_color_selection_drag_end),
564 gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
566 GTK_SIGNAL_FUNC (gtk_color_selection_drag_handle),
568 gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
569 "drag_data_received",
570 GTK_SIGNAL_FUNC (gtk_color_selection_drop_handle),
575 gtk_color_selection_unrealize (GtkWidget *widget)
577 GtkColorSelection *colorsel;
579 g_return_if_fail (widget != NULL);
580 g_return_if_fail (GTK_IS_COLOR_SELECTION (widget));
582 colorsel = GTK_COLOR_SELECTION (widget);
584 if (colorsel->value_gc != NULL)
586 gdk_gc_unref (colorsel->value_gc);
587 colorsel->value_gc = NULL;
589 if (colorsel->wheel_gc != NULL)
591 gdk_gc_unref (colorsel->wheel_gc);
592 colorsel->wheel_gc = NULL;
594 if (colorsel->sample_gc != NULL)
596 gdk_gc_unref (colorsel->sample_gc);
597 colorsel->sample_gc = NULL;
600 (* GTK_WIDGET_CLASS (color_selection_parent_class)->unrealize) (widget);
604 gtk_color_selection_finalize (GtkObject *object)
606 GtkColorSelection *colorsel;
608 g_return_if_fail (object != NULL);
609 g_return_if_fail (GTK_IS_COLOR_SELECTION (object));
611 colorsel = GTK_COLOR_SELECTION (object);
613 if (colorsel->wheel_buf != NULL)
614 g_free (colorsel->wheel_buf);
615 if (colorsel->value_buf != NULL)
616 g_free (colorsel->value_buf);
617 if (colorsel->sample_buf != NULL)
618 g_free (colorsel->sample_buf);
620 (*GTK_OBJECT_CLASS (color_selection_parent_class)->finalize) (object);
624 gtk_color_selection_color_changed (GtkColorSelection *colorsel)
626 gtk_signal_emit (GTK_OBJECT (colorsel), color_selection_signals[COLOR_CHANGED]);
630 gtk_color_selection_update_input (GtkWidget *scale,
639 adj = gtk_range_get_adjustment (GTK_RANGE (scale));
640 adj->value = (gfloat) value;
641 gtk_signal_handler_block_by_data (GTK_OBJECT (adj), (gpointer) scale);
642 gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
643 gtk_range_slider_update (GTK_RANGE (scale));
644 gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), (gpointer) scale);
649 gtk_signal_handler_block_by_data (GTK_OBJECT (entry), (gpointer) entry);
650 sprintf (txt, "%.2f", value);
651 gtk_entry_set_text (GTK_ENTRY (entry), txt);
652 gtk_signal_handler_unblock_by_data (GTK_OBJECT (entry), (gpointer) entry);
657 gtk_color_selection_update_inputs (GtkColorSelection *colorsel,
666 if ((inputs & RGB_INPUTS) != 0)
667 for (n = RED; n <= BLUE; n++)
668 gtk_color_selection_update_input (colorsel->scales[n], NULL,
669 colorsel->values[n]);
670 if ((inputs & HSV_INPUTS) != 0)
671 for (n = HUE; n <= VALUE; n++)
672 gtk_color_selection_update_input (colorsel->scales[n], NULL,
673 colorsel->values[n]);
674 if ((inputs & OPACITY_INPUTS) != 0)
675 gtk_color_selection_update_input(colorsel->scales[OPACITY], NULL,
676 colorsel->values[OPACITY]);
679 if ((inputs & RGB_INPUTS) != 0)
680 for (n = RED; n <= BLUE; n++)
681 gtk_color_selection_update_input (NULL, colorsel->entries[n], colorsel->values[n]);
682 if ((inputs & HSV_INPUTS) != 0)
683 for (n = HUE; n <= VALUE; n++)
684 gtk_color_selection_update_input (NULL, colorsel->entries[n], colorsel->values[n]);
685 if ((inputs & OPACITY_INPUTS) != 0)
686 gtk_color_selection_update_input(NULL, colorsel->entries[OPACITY], colorsel->values[OPACITY]);
689 if ((inputs & RGB_INPUTS) != 0)
690 for (n = RED; n <= BLUE; n++)
691 gtk_color_selection_update_input (colorsel->scales[n], colorsel->entries[n],
692 colorsel->values[n]);
693 if ((inputs & HSV_INPUTS) != 0)
694 for (n = HUE; n <= VALUE; n++)
695 gtk_color_selection_update_input (colorsel->scales[n], colorsel->entries[n],
696 colorsel->values[n]);
697 if ((inputs & OPACITY_INPUTS) != 0)
698 gtk_color_selection_update_input(colorsel->scales[OPACITY], colorsel->entries[OPACITY],
699 colorsel->values[OPACITY]);
705 gtk_color_selection_hsv_updater (GtkWidget *widget,
708 GtkColorSelection *colorsel;
711 gint i, which = SCALE;
713 if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (widget)))
715 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
716 i = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), value_index_key));
718 if (GTK_IS_SCALE (widget))
720 adj = gtk_range_get_adjustment (GTK_RANGE (GTK_SCALE (widget)));
721 newvalue = (gdouble) adj->value;
725 newvalue = (gdouble) atof (gtk_entry_get_text (GTK_ENTRY (widget)));
729 gtk_color_selection_draw_value_marker (colorsel);
730 colorsel->values[i] = newvalue;
734 gtk_color_selection_draw_value_marker (colorsel);
738 gtk_color_selection_draw_wheel_marker (colorsel);
739 colorsel->values[i] = newvalue;
743 gtk_color_selection_draw_wheel_marker (colorsel);
744 gtk_color_selection_draw_value_bar (colorsel, FALSE);
747 gtk_color_selection_draw_sample (colorsel, FALSE);
748 gtk_color_selection_color_changed (colorsel);
749 gtk_color_selection_update_inputs (colorsel, HSV_INPUTS, which);
750 gtk_color_selection_update_inputs (colorsel, RGB_INPUTS, BOTH);
755 gtk_color_selection_rgb_updater (GtkWidget *widget,
758 GtkColorSelection *colorsel;
761 gint i, which = SCALE;
763 if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (widget)))
765 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
766 i = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), value_index_key));
768 if (GTK_IS_SCALE (widget))
770 adj = gtk_range_get_adjustment (GTK_RANGE (GTK_SCALE (widget)));
771 newvalue = (gdouble) adj->value;
775 newvalue = (gdouble) atof (gtk_entry_get_text (GTK_ENTRY (widget)));
777 gtk_color_selection_draw_wheel_marker (colorsel);
779 colorsel->values[i] = newvalue;
782 gtk_color_selection_draw_wheel_marker (colorsel);
783 gtk_color_selection_draw_value_bar (colorsel, FALSE);
784 gtk_color_selection_draw_sample (colorsel, FALSE);
785 gtk_color_selection_color_changed (colorsel);
786 gtk_color_selection_update_inputs (colorsel, RGB_INPUTS, which);
787 gtk_color_selection_update_inputs (colorsel, HSV_INPUTS, BOTH);
792 gtk_color_selection_opacity_updater (GtkWidget *widget,
795 GtkColorSelection *colorsel;
798 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
800 if (GTK_IS_SCALE (widget))
802 adj = gtk_range_get_adjustment (GTK_RANGE (widget));
803 colorsel->values[OPACITY] = (gdouble) adj->value;
804 gtk_color_selection_update_input (NULL, colorsel->entries[OPACITY], colorsel->values[OPACITY]);
808 colorsel->values[OPACITY] = (gdouble) atof (gtk_entry_get_text (GTK_ENTRY (widget)));
809 gtk_color_selection_update_input (colorsel->scales[OPACITY], NULL, colorsel->values[OPACITY]);
812 gtk_color_selection_draw_sample (colorsel, FALSE);
813 gtk_color_selection_color_changed (colorsel);
817 gtk_color_selection_set_opacity (GtkColorSelection *colorsel,
820 g_return_if_fail (colorsel != NULL);
822 colorsel->use_opacity = use_opacity;
824 if (!use_opacity && GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
826 gtk_widget_hide (colorsel->opacity_label);
827 gtk_widget_hide (colorsel->scales[OPACITY]);
828 gtk_widget_hide (colorsel->entries[OPACITY]);
830 else if (use_opacity && !GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
832 gtk_widget_show (colorsel->opacity_label);
833 gtk_widget_show (colorsel->scales[OPACITY]);
834 gtk_widget_show (colorsel->entries[OPACITY]);
837 if (GTK_WIDGET_DRAWABLE (colorsel->sample_area))
838 gtk_color_selection_draw_sample (colorsel, FALSE);
842 gtk_color_selection_value_resize (GtkWidget *widget,
845 GtkColorSelection *colorsel;
847 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
848 gtk_color_selection_draw_value_bar (colorsel, TRUE);
852 gtk_color_selection_wheel_resize (GtkWidget *widget,
855 GtkColorSelection *colorsel;
857 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
858 gtk_color_selection_draw_wheel (colorsel, TRUE);
862 gtk_color_selection_sample_resize (GtkWidget *widget,
865 GtkColorSelection *colorsel;
867 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
868 gtk_color_selection_draw_sample (colorsel, TRUE);
872 gtk_color_selection_drag_begin (GtkWidget *widget,
873 GdkDragContext *context,
876 GtkColorSelection *colorsel = data;
881 window = gtk_window_new (GTK_WINDOW_POPUP);
882 gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
883 gtk_widget_set_usize (window, 48, 32);
884 gtk_widget_realize (window);
885 gtk_object_set_data_full (GTK_OBJECT (widget),
886 "gtk-color-selection-drag-window",
888 (GtkDestroyNotify) gtk_widget_destroy);
890 gtk_color_selection_get_color (colorsel, colors);
891 bg.red = 0xffff * colors[0];
892 bg.green = 0xffff * colors[1];
893 bg.blue = 0xffff * colors[2];
895 gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
896 gdk_window_set_background (window->window, &bg);
898 gtk_drag_set_icon_widget (context, window, -2, -2);
902 gtk_color_selection_drag_end (GtkWidget *widget,
903 GdkDragContext *context,
906 gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL);
910 gtk_color_selection_drop_handle (GtkWidget *widget,
911 GdkDragContext *context,
914 GtkSelectionData *selection_data,
919 GtkColorSelection *colorsel = data;
923 /* This is currently a guint16 array of the format:
930 if (selection_data->length < 0)
933 if ((selection_data->format != 16) ||
934 (selection_data->length != 8))
936 g_warning ("Received invalid color data\n");
940 vals = (guint16 *)selection_data->data;
942 colors[0] = (gdouble)vals[0] / 0xffff;
943 colors[1] = (gdouble)vals[1] / 0xffff;
944 colors[2] = (gdouble)vals[2] / 0xffff;
945 colors[3] = (gdouble)vals[3] / 0xffff;
947 gtk_color_selection_set_color(colorsel, colors);
951 gtk_color_selection_drag_handle (GtkWidget *widget,
952 GdkDragContext *context,
953 GtkSelectionData *selection_data,
958 GtkColorSelection *colorsel = data;
962 gtk_color_selection_get_color(colorsel, colors);
964 vals[0] = colors[0] * 0xffff;
965 vals[1] = colors[1] * 0xffff;
966 vals[2] = colors[2] * 0xffff;
967 vals[3] = colorsel->use_opacity ? colors[3] * 0xffff : 0xffff;
969 gtk_selection_data_set (selection_data,
970 gdk_atom_intern ("application/x-color", FALSE),
971 16, (guchar *)vals, 8);
975 gtk_color_selection_draw_wheel_marker (GtkColorSelection *colorsel)
979 gdk_gc_set_function (colorsel->wheel_gc, GDK_INVERT);
981 xpos = (gint) ((-(gdouble) (colorsel->wheel_area->allocation.width) / 2.0) *
982 colorsel->values[SATURATION] * cos (DEGTORAD ((colorsel->values[HUE] - 90)))) +
983 (colorsel->wheel_area->allocation.width >> 1) - 4;
984 ypos = (gint) (((gdouble) (colorsel->wheel_area->allocation.height) / 2.0) *
985 colorsel->values[SATURATION] * sin (DEGTORAD ((colorsel->values[HUE] - 90)))) +
986 (colorsel->wheel_area->allocation.height >> 1) - 4;
988 gdk_draw_arc (colorsel->wheel_area->window, colorsel->wheel_gc, FALSE, xpos, ypos, 8, 8, 0, 360 * 64);
992 gtk_color_selection_draw_value_marker (GtkColorSelection *colorsel)
996 gdk_gc_set_function (colorsel->value_gc, GDK_INVERT);
998 y = (gint) ((gdouble) (colorsel->value_area->allocation.height) * (1.0 - colorsel->values[VALUE]));
999 gdk_draw_line (colorsel->value_area->window, colorsel->value_gc,
1000 0, y, colorsel->value_area->allocation.width, y);
1004 gtk_color_selection_update_value (GtkColorSelection *colorsel,
1007 gtk_color_selection_draw_value_marker (colorsel);
1011 else if (y > colorsel->value_area->allocation.height - 1)
1012 y = colorsel->value_area->allocation.height - 1;
1014 colorsel->values[VALUE] = 1.0 - (gdouble) y / (gdouble) (colorsel->value_area->allocation.height);
1018 gtk_color_selection_draw_value_marker (colorsel);
1019 gtk_color_selection_draw_sample (colorsel, FALSE);
1020 gtk_color_selection_update_input (colorsel->scales[VALUE], colorsel->entries[VALUE],
1021 colorsel->values[VALUE]);
1022 gtk_color_selection_update_inputs (colorsel, RGB_INPUTS, BOTH);
1026 gtk_color_selection_update_wheel (GtkColorSelection *colorsel,
1033 gtk_color_selection_draw_wheel_marker (colorsel);
1035 wid = (gdouble) (colorsel->wheel_area->allocation.width) / 2.0;
1036 heig = (gdouble) (colorsel->wheel_area->allocation.height) / 2.0;
1038 res = gtk_color_selection_eval_wheel (x, y, wid, heig, &colorsel->values[HUE],
1039 &colorsel->values[SATURATION]);
1043 gtk_color_selection_draw_wheel_marker (colorsel);
1044 gtk_color_selection_draw_value_bar (colorsel, FALSE);
1045 gtk_color_selection_draw_sample (colorsel, FALSE);
1046 gtk_color_selection_update_inputs (colorsel, RGB_INPUTS | HSV_INPUTS, BOTH);
1050 gtk_color_selection_value_timeout (GtkColorSelection *colorsel)
1054 GDK_THREADS_ENTER ();
1056 gdk_window_get_pointer (colorsel->value_area->window, &x, &y, NULL);
1057 gtk_color_selection_update_value (colorsel, y);
1058 gtk_color_selection_color_changed (colorsel);
1060 GDK_THREADS_LEAVE ();
1066 gtk_color_selection_value_events (GtkWidget *area,
1069 GtkColorSelection *colorsel;
1072 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (area), "_GtkColorSelection");
1074 if (colorsel->value_gc == NULL)
1075 colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
1077 switch (event->type)
1080 gtk_color_selection_draw_value_bar (colorsel, FALSE);
1081 gtk_color_selection_draw_value_marker (colorsel);
1084 gtk_color_selection_draw_value_marker (colorsel);
1086 case GDK_BUTTON_PRESS:
1087 gtk_grab_add (area);
1088 gtk_color_selection_update_value (colorsel, event->button.y);
1089 gtk_color_selection_color_changed (colorsel);
1091 case GDK_BUTTON_RELEASE:
1092 gtk_grab_remove (area);
1093 if (colorsel->timer_active)
1094 gtk_timeout_remove (colorsel->timer_tag);
1095 colorsel->timer_active = FALSE;
1097 y = event->button.y;
1098 if (event->button.window != area->window)
1099 gdk_window_get_pointer (area->window, NULL, &y, NULL);
1101 gtk_color_selection_update_value (colorsel, y);
1102 gtk_color_selection_color_changed (colorsel);
1104 case GDK_MOTION_NOTIFY:
1105 /* Even though we select BUTTON_MOTION_MASK, we seem to need
1106 * to occasionally get events without buttons pressed.
1108 if (!(event->motion.state &
1109 (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
1112 y = event->motion.y;
1114 if (event->motion.is_hint || (event->motion.window != area->window))
1115 gdk_window_get_pointer (area->window, NULL, &y, NULL);
1117 switch (colorsel->policy)
1119 case GTK_UPDATE_CONTINUOUS:
1120 gtk_color_selection_update_value (colorsel, y);
1121 gtk_color_selection_color_changed (colorsel);
1123 case GTK_UPDATE_DELAYED:
1124 if (colorsel->timer_active)
1125 gtk_timeout_remove (colorsel->timer_tag);
1127 colorsel->timer_tag = gtk_timeout_add (TIMER_DELAY,
1128 (GtkFunction) gtk_color_selection_value_timeout,
1129 (gpointer) colorsel);
1130 colorsel->timer_active = TRUE;
1144 gtk_color_selection_wheel_timeout (GtkColorSelection *colorsel)
1148 gdk_window_get_pointer (colorsel->wheel_area->window, &x, &y, NULL);
1149 gtk_color_selection_update_wheel (colorsel, x, y);
1150 gtk_color_selection_color_changed (colorsel);
1156 gtk_color_selection_wheel_events (GtkWidget *area,
1159 GtkColorSelection *colorsel;
1162 colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (area), "_GtkColorSelection");
1164 if (colorsel->wheel_gc == NULL)
1165 colorsel->wheel_gc = gdk_gc_new (colorsel->wheel_area->window);
1166 if (colorsel->sample_gc == NULL)
1167 colorsel->sample_gc = gdk_gc_new (colorsel->sample_area->window);
1168 if (colorsel->value_gc == NULL)
1169 colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
1171 switch (event->type)
1174 gtk_color_selection_draw_wheel (colorsel, TRUE);
1175 gtk_color_selection_draw_wheel_marker (colorsel);
1176 gtk_color_selection_draw_sample (colorsel, TRUE);
1179 gtk_color_selection_draw_wheel_marker (colorsel);
1180 gtk_color_selection_draw_wheel_frame (colorsel);
1182 case GDK_BUTTON_PRESS:
1183 gtk_grab_add (area);
1184 gtk_color_selection_update_wheel (colorsel, event->button.x, event->button.y);
1185 gtk_color_selection_color_changed (colorsel);
1187 case GDK_BUTTON_RELEASE:
1188 gtk_grab_remove (area);
1189 if (colorsel->timer_active)
1190 gtk_timeout_remove (colorsel->timer_tag);
1191 colorsel->timer_active = FALSE;
1193 x = event->button.x;
1194 y = event->button.y;
1196 if (event->button.window != area->window)
1197 gdk_window_get_pointer (area->window, &x, &y, NULL);
1199 gtk_color_selection_update_wheel (colorsel, x, y);
1200 gtk_color_selection_color_changed (colorsel);
1202 case GDK_MOTION_NOTIFY:
1203 /* Even though we select BUTTON_MOTION_MASK, we seem to need
1204 * to occasionally get events without buttons pressed.
1206 if (!(event->motion.state &
1207 (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
1210 x = event->motion.x;
1211 y = event->motion.y;
1213 if (event->motion.is_hint || (event->motion.window != area->window))
1214 gdk_window_get_pointer (area->window, &x, &y, NULL);
1216 switch (colorsel->policy)
1218 case GTK_UPDATE_CONTINUOUS:
1219 gtk_color_selection_update_wheel (colorsel, x, y);
1220 gtk_color_selection_color_changed (colorsel);
1222 case GTK_UPDATE_DELAYED:
1223 if (colorsel->timer_active)
1224 gtk_timeout_remove (colorsel->timer_tag);
1225 colorsel->timer_tag = gtk_timeout_add (TIMER_DELAY,
1226 (GtkFunction) gtk_color_selection_wheel_timeout,
1227 (gpointer) colorsel);
1228 colorsel->timer_active = TRUE;
1242 gtk_color_selection_draw_value_bar (GtkColorSelection *colorsel,
1245 gint x, y, wid, heig, n;
1248 wid = colorsel->value_area->allocation.width;
1249 heig = colorsel->value_area->allocation.height;
1251 if (resize || !colorsel->value_buf)
1253 g_free (colorsel->value_buf);
1254 colorsel->value_buf = g_new0 (guchar, 3 * wid);
1258 sv = 1.0 / (gdouble) (heig - 1);
1260 for (y = 0; y < heig; y++)
1266 gtk_color_selection_hsv_to_rgb (colorsel->values[HUE],
1267 colorsel->values[SATURATION],
1269 &c[0], &c[1], &c[2]);
1271 for (n = 0; n < 3; n++)
1272 rc[n] = (guchar) (255.0 * c[n]);
1274 for (x = 0; x < wid; x++)
1276 for (n = 0; n < 3; n++)
1277 colorsel->value_buf[i++] = rc[n];
1280 gtk_preview_draw_row (GTK_PREVIEW (colorsel->value_area), colorsel->value_buf, 0, y, wid);
1284 gtk_widget_queue_draw (colorsel->value_area);
1288 gtk_color_selection_draw_wheel_frame (GtkColorSelection *colorsel)
1293 style = gtk_widget_get_style (colorsel->wheel_area);
1295 w = colorsel->wheel_area->allocation.width;
1296 h = colorsel->wheel_area->allocation.height;
1298 gdk_draw_arc (colorsel->wheel_area->window, style->black_gc,
1299 FALSE, 1, 1, w - 1, h - 1, 30 * 64, 180 * 64);
1300 gdk_draw_arc (colorsel->wheel_area->window, style->mid_gc[GTK_STATE_NORMAL],
1301 FALSE, 0, 0, w, h, 30 * 64, 180 * 64);
1303 gdk_draw_arc (colorsel->wheel_area->window, style->bg_gc[GTK_STATE_NORMAL],
1304 FALSE, 1, 1, w - 1, h - 1, 210 * 64, 180 * 64);
1305 gdk_draw_arc (colorsel->wheel_area->window, style->light_gc[GTK_STATE_NORMAL],
1306 FALSE, 0, 0, w, h, 210 * 64, 180 * 64);
1310 gtk_color_selection_draw_wheel (GtkColorSelection *colorsel,
1313 gint x, y, i, wid, heig, n;
1314 gdouble cx, cy, h, s, c[3];
1316 GtkStyle *style = gtk_widget_get_style (colorsel->wheel_area);
1318 wid = colorsel->wheel_area->allocation.width;
1319 heig = colorsel->wheel_area->allocation.height;
1323 if (colorsel->wheel_buf != NULL)
1324 g_free (colorsel->wheel_buf);
1326 colorsel->wheel_buf = g_new(guchar, 3 * wid);
1329 cx = (gdouble) (wid) / 2.0;
1330 cy = (gdouble) (heig) / 2.0;
1332 bg[0] = style->bg[GTK_STATE_NORMAL].red >> 8;
1333 bg[1] = style->bg[GTK_STATE_NORMAL].green >> 8;
1334 bg[2] = style->bg[GTK_STATE_NORMAL].blue >> 8;
1336 for (y = 0; y < heig; y++)
1339 for (x = 0; x < wid; x++)
1341 if (gtk_color_selection_eval_wheel (x, y, cx, cy, &h, &s))
1343 for (n = 0; n < 3; n++)
1344 colorsel->wheel_buf[i++] = bg[n];
1348 gtk_color_selection_hsv_to_rgb (h, s, 1.0, &c[0], &c[1], &c[2]);
1349 for (n = 0; n < 3; n++)
1350 colorsel->wheel_buf[i++] = (guchar) (255.0 * c[n]);
1354 gtk_preview_draw_row (GTK_PREVIEW (colorsel->wheel_area), colorsel->wheel_buf, 0, y, wid);
1357 if (colorsel->wheel_area->window)
1359 GdkPixmap *pm = NULL;
1364 pm = gdk_pixmap_new (colorsel->wheel_area->window, wid, heig, 1);
1365 pmgc = gdk_gc_new (pm);
1368 gdk_gc_set_foreground(pmgc, &col);
1369 gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, wid, heig);
1372 gdk_gc_set_foreground(pmgc, &col);
1373 gdk_draw_arc (pm, pmgc, TRUE, 0, 0, wid, heig, 0, 360*64);
1375 w = colorsel->wheel_area->allocation.width;
1376 h = colorsel->wheel_area->allocation.height;
1378 gdk_draw_arc (pm, pmgc,
1379 FALSE, 1, 1, w - 1, h - 1, 30 * 64, 180 * 64);
1380 gdk_draw_arc (pm, pmgc,
1381 FALSE, 0, 0, w, h, 30 * 64, 180 * 64);
1382 gdk_draw_arc (pm, pmgc,
1383 FALSE, 1, 1, w - 1, h - 1, 210 * 64, 180 * 64);
1384 gdk_draw_arc (pm, pmgc,
1385 FALSE, 0, 0, w, h, 210 * 64, 180 * 64);
1386 gdk_window_shape_combine_mask (colorsel->wheel_area->window, pm, 0, 0);
1387 gdk_pixmap_unref (pm);
1388 gdk_gc_destroy (pmgc);
1393 gtk_color_selection_draw_sample (GtkColorSelection *colorsel,
1396 gint x, y, i, wid, heig, f, half, n;
1397 guchar c[3 * 2], cc[3 * 4], *cp = c;
1400 wid = colorsel->sample_area->allocation.width;
1401 heig = colorsel->sample_area->allocation.height;
1406 if (colorsel->sample_buf != NULL)
1407 g_free (colorsel->sample_buf);
1409 colorsel->sample_buf = g_new(guchar, 3 * wid);
1413 for (n = 0; n < 3; n++)
1415 c[n] = (guchar) (255.0 * colorsel->old_values[i]);
1416 c[n + 3] = (guchar) (255.0 * colorsel->values[i++]);
1419 if (colorsel->use_opacity)
1421 o = colorsel->values[OPACITY];
1422 oldo = colorsel->old_values[OPACITY];
1424 for (n = 0; n < 3; n++)
1426 cc[n] = (guchar) ((1.0 - oldo) * 192 + (oldo * (gdouble) c[n]));
1427 cc[n + 3] = (guchar) ((1.0 - oldo) * 128 + (oldo * (gdouble) c[n]));
1428 cc[n + 6] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n + 3]));
1429 cc[n + 9] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n + 3]));
1434 for (y = 0; y < heig; y++)
1437 for (x = 0; x < wid; x++)
1439 if (colorsel->use_opacity)
1441 f = 3 * (((x % 32) < 16) ^ ((y % 32) < 16));
1442 f += (x > half) * 6;
1447 for (n = 0; n < 3; n++)
1448 colorsel->sample_buf[i++] = cp[n + f];
1451 gtk_preview_draw_row (GTK_PREVIEW (colorsel->sample_area), colorsel->sample_buf, 0, y, wid);
1454 gtk_widget_queue_draw (colorsel->sample_area);
1458 gtk_color_selection_eval_wheel (gint x, gint y,
1459 gdouble cx, gdouble cy,
1460 gdouble *h, gdouble *s)
1464 rx = ((gdouble) x - cx);
1465 ry = ((gdouble) y - cy);
1470 r = sqrt (SQR (rx) + SQR (ry));
1473 *h = atan2 (rx / r, ry / r);
1478 *h = 360.0 * (*h) / (2.0 * M_PI) + 180;
1491 gtk_color_selection_hsv_to_rgb (gdouble h, gdouble s, gdouble v,
1492 gdouble *r, gdouble *g, gdouble *b)
1514 q = v * (1.0 - (s * f));
1515 t = v * (1.0 - (s * (1.0 - f)));
1554 gtk_color_selection_rgb_to_hsv (gdouble r, gdouble g, gdouble b,
1555 gdouble *h, gdouble *s, gdouble *v)
1557 double max, min, delta;
1574 *s = (max - min) / max;
1585 *h = (g - b) / delta;
1587 *h = 2.0 + (b - r) / delta;
1589 *h = 4.0 + (r - g) / delta;
1598 /***************************/
1599 /* GtkColorSelectionDialog */
1600 /***************************/
1603 gtk_color_selection_dialog_get_type (void)
1605 static guint color_selection_dialog_type = 0;
1607 if (!color_selection_dialog_type)
1609 GtkTypeInfo colorsel_diag_info =
1611 "GtkColorSelectionDialog",
1612 sizeof (GtkColorSelectionDialog),
1613 sizeof (GtkColorSelectionDialogClass),
1614 (GtkClassInitFunc) gtk_color_selection_dialog_class_init,
1615 (GtkObjectInitFunc) gtk_color_selection_dialog_init,
1616 /* reserved_1 */ NULL,
1617 /* reserved_2 */ NULL,
1618 (GtkClassInitFunc) NULL,
1621 color_selection_dialog_type = gtk_type_unique (gtk_window_get_type (), &colorsel_diag_info);
1624 return color_selection_dialog_type;
1628 gtk_color_selection_dialog_class_init (GtkColorSelectionDialogClass *klass)
1630 GtkObjectClass *object_class;
1632 object_class = (GtkObjectClass*) klass;
1634 color_selection_dialog_parent_class = gtk_type_class (gtk_window_get_type ());
1638 gtk_color_selection_dialog_init (GtkColorSelectionDialog *colorseldiag)
1640 GtkWidget *action_area, *frame;
1642 gtk_widget_set_visual (GTK_WIDGET (colorseldiag), gdk_rgb_get_visual ());
1643 gtk_widget_set_colormap (GTK_WIDGET (colorseldiag), gdk_rgb_get_cmap ());
1645 gtk_widget_push_visual (gdk_rgb_get_visual ());
1646 gtk_widget_push_colormap (gdk_rgb_get_cmap ());
1648 colorseldiag->main_vbox = gtk_vbox_new (FALSE, 10);
1649 gtk_container_set_border_width (GTK_CONTAINER (colorseldiag), 10);
1650 gtk_container_add (GTK_CONTAINER (colorseldiag), colorseldiag->main_vbox);
1651 gtk_widget_show (colorseldiag->main_vbox);
1653 frame = gtk_frame_new (NULL);
1654 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
1655 gtk_container_add (GTK_CONTAINER (colorseldiag->main_vbox), frame);
1656 gtk_widget_show (frame);
1658 colorseldiag->colorsel = gtk_color_selection_new ();
1659 gtk_container_add (GTK_CONTAINER (frame), colorseldiag->colorsel);
1660 gtk_widget_show (colorseldiag->colorsel);
1662 action_area = gtk_hbutton_box_new ();
1663 gtk_button_box_set_layout(GTK_BUTTON_BOX(action_area), GTK_BUTTONBOX_END);
1664 gtk_button_box_set_spacing(GTK_BUTTON_BOX(action_area), 5);
1665 gtk_box_pack_end (GTK_BOX (colorseldiag->main_vbox), action_area, FALSE, FALSE, 0);
1666 gtk_widget_show (action_area);
1668 colorseldiag->ok_button = gtk_button_new_with_label (_("OK"));
1669 GTK_WIDGET_SET_FLAGS (colorseldiag->ok_button, GTK_CAN_DEFAULT);
1670 gtk_box_pack_start (GTK_BOX (action_area), colorseldiag->ok_button, TRUE, TRUE, 0);
1671 gtk_widget_grab_default (colorseldiag->ok_button);
1672 gtk_widget_show (colorseldiag->ok_button);
1674 colorseldiag->cancel_button = gtk_button_new_with_label (_("Cancel"));
1675 GTK_WIDGET_SET_FLAGS (colorseldiag->cancel_button, GTK_CAN_DEFAULT);
1676 gtk_box_pack_start (GTK_BOX (action_area), colorseldiag->cancel_button, TRUE, TRUE, 0);
1677 gtk_widget_show (colorseldiag->cancel_button);
1679 colorseldiag->help_button = gtk_button_new_with_label (_("Help"));
1680 GTK_WIDGET_SET_FLAGS (colorseldiag->help_button, GTK_CAN_DEFAULT);
1681 gtk_box_pack_start (GTK_BOX (action_area), colorseldiag->help_button, TRUE, TRUE, 0);
1682 gtk_widget_show (colorseldiag->help_button);
1684 gtk_widget_pop_colormap ();
1685 gtk_widget_pop_visual ();
1689 gtk_color_selection_dialog_new (const gchar *title)
1691 GtkColorSelectionDialog *colorseldiag;
1693 colorseldiag = gtk_type_new (gtk_color_selection_dialog_get_type ());
1694 gtk_window_set_title (GTK_WINDOW (colorseldiag), title);
1696 return GTK_WIDGET (colorseldiag);