Fl_Panzoomer: Always draw box.
[ntk.git] / src / Fl_Color_Chooser.cxx
blobd5bd6e6a19daa38e605972a51365f8d745272f2a
1 //
2 // "$Id: Fl_Color_Chooser.cxx 7981 2010-12-08 23:53:04Z greg.ercolano $"
3 //
4 // Color chooser for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 // USA.
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
28 #include <FL/Fl.H>
29 #include <FL/Fl_Color_Chooser.H>
30 #include <FL/fl_draw.H>
31 #include <FL/math.h>
32 #include <stdio.h>
34 // Besides being a useful object on it's own, the Fl_Color_Chooser was
35 // an attempt to make a complex composite object that could be easily
36 // imbedded into a user interface. If you wish to make complex objects
37 // of your own, be sure to read this code.
39 // The function fl_color_chooser() creates a window containing a color
40 // chooser and a few buttons and current-color indicators. It is an
41 // easier interface for simple programs that just need a color.
43 // The "hue box" can be a circle or rectilinear.
44 // You get a circle by defining this:
45 #define CIRCLE 1
46 // And the "hue box" can auto-update when the value changes
47 // you get this by defining this:
48 #define UPDATE_HUE_BOX 1
50 /**
51 This \e static method converts HSV colors to RGB colorspace.
52 \param[in] H, S, V color components
53 \param[out] R, G, B color components
55 void Fl_Color_Chooser::hsv2rgb(
56 double H, double S, double V, double& R, double& G, double& B) {
57 if (S < 5.0e-6) {
58 R = G = B = V;
59 } else {
60 int i = (int)H;
61 double f = H - (float)i;
62 double p1 = V*(1.0-S);
63 double p2 = V*(1.0-S*f);
64 double p3 = V*(1.0-S*(1.0-f));
65 switch (i) {
66 case 0: R = V; G = p3; B = p1; break;
67 case 1: R = p2; G = V; B = p1; break;
68 case 2: R = p1; G = V; B = p3; break;
69 case 3: R = p1; G = p2; B = V; break;
70 case 4: R = p3; G = p1; B = V; break;
71 case 5: R = V; G = p1; B = p2; break;
76 /**
77 This \e static method converts RGB colors to HSV colorspace.
78 \param[in] R, G, B color components
79 \param[out] H, S, V color components
81 void Fl_Color_Chooser::rgb2hsv(
82 double R, double G, double B, double& H, double& S, double& V) {
83 double maxv = R > G ? R : G; if (B > maxv) maxv = B;
84 V = maxv;
85 if (maxv>0) {
86 double minv = R < G ? R : G; if (B < minv) minv = B;
87 S = 1.0 - double(minv)/maxv;
88 if (maxv > minv) {
89 if (maxv == R) {H = (G-B)/double(maxv-minv); if (H<0) H += 6.0;}
90 else if (maxv == G) H = 2.0+(B-R)/double(maxv-minv);
91 else H = 4.0+(R-G)/double(maxv-minv);
96 /** Fl_Color_Chooser modes */
97 enum {
98 M_RGB, /**< mode() of Fl_Color_Chooser showing RGB values */
99 M_BYTE, /**< mode() of Fl_Color_Chooser showing byte values */
100 M_HEX, /**< mode() of Fl_Color_Chooser showing hex values */
101 M_HSV /**< mode() of Fl_Color_Chooser showing HSV values */
103 static Fl_Menu_Item mode_menu[] = {
104 {"rgb"},
105 {"byte"},
106 {"hex"},
107 {"hsv"},
111 #ifndef FL_DOXYGEN
112 int Flcc_Value_Input::format(char* buf) {
113 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
114 if (c->mode() == M_HEX) return sprintf(buf,"0x%02X", int(value()));
115 else return Fl_Valuator::format(buf);
117 #endif // !FL_DOXYGEN
119 void Fl_Color_Chooser::set_valuators() {
120 switch (mode()) {
121 case M_RGB:
122 rvalue.range(0,1); rvalue.step(1,1000); rvalue.value(r_);
123 gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_);
124 bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_);
125 break;
126 case M_BYTE: /* FALLTHROUGH */
127 case M_HEX:
128 rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5));
129 gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5));
130 bvalue.range(0,255); bvalue.step(1); bvalue.value(int(255*b_+.5));
131 break;
132 case M_HSV:
133 rvalue.range(0,6); rvalue.step(1,1000); rvalue.value(hue_);
134 gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(saturation_);
135 bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(value_);
136 break;
141 Sets the current rgb color values.
142 Does not do the callback. Does not clamp (but out of range values will
143 produce psychedelic effects in the hue selector).
144 \param[in] R, G, B color components.
145 \return 1 if a new rgb value was set, 0 if the rgb value was the previous one.
147 int Fl_Color_Chooser::rgb(double R, double G, double B) {
148 if (R == r_ && G == g_ && B == b_) return 0;
149 r_ = R; g_ = G; b_ = B;
150 double ph = hue_;
151 double ps = saturation_;
152 double pv = value_;
153 rgb2hsv(R,G,B,hue_,saturation_,value_);
154 set_valuators();
155 set_changed();
156 if (value_ != pv) {
157 #ifdef UPDATE_HUE_BOX
158 huebox.damage(FL_DAMAGE_SCROLL);
159 #endif
160 valuebox.damage(FL_DAMAGE_EXPOSE);}
161 if (hue_ != ph || saturation_ != ps) {
162 huebox.damage(FL_DAMAGE_EXPOSE);
163 valuebox.damage(FL_DAMAGE_SCROLL);
165 return 1;
169 Set the hsv values.
170 The passed values are clamped (or for hue, modulus 6 is used) to get
171 legal values. Does not do the callback.
172 \param[in] H, S, V color components.
173 \return 1 if a new hsv value was set, 0 if the hsv value was the previous one.
175 int Fl_Color_Chooser::hsv(double H, double S, double V) {
176 H = fmod(H,6.0); if (H < 0.0) H += 6.0;
177 if (S < 0.0) S = 0.0; else if (S > 1.0) S = 1.0;
178 if (V < 0.0) V = 0.0; else if (V > 1.0) V = 1.0;
179 if (H == hue_ && S == saturation_ && V == value_) return 0;
180 double ph = hue_;
181 double ps = saturation_;
182 double pv = value_;
183 hue_ = H; saturation_ = S; value_ = V;
184 if (value_ != pv) {
185 #ifdef UPDATE_HUE_BOX
186 huebox.damage(FL_DAMAGE_SCROLL);
187 #endif
188 valuebox.damage(FL_DAMAGE_EXPOSE);}
189 if (hue_ != ph || saturation_ != ps) {
190 huebox.damage(FL_DAMAGE_EXPOSE);
191 valuebox.damage(FL_DAMAGE_SCROLL);
193 hsv2rgb(H,S,V,r_,g_,b_);
194 set_valuators();
195 set_changed();
196 return 1;
199 ////////////////////////////////////////////////////////////////
201 static void tohs(double x, double y, double& h, double& s) {
202 #ifdef CIRCLE
203 x = 2*x-1;
204 y = 1-2*y;
205 s = sqrt(x*x+y*y); if (s > 1.0) s = 1.0;
206 h = (3.0/M_PI)*atan2(y,x);
207 if (h<0) h += 6.0;
208 #else
209 h = fmod(6.0*x,6.0); if (h < 0.0) h += 6.0;
210 s = 1.0-y; if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0;
211 #endif
214 #ifndef FL_DOXYGEN
215 int Flcc_HueBox::handle(int e) {
216 static double ih, is;
217 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
218 switch (e) {
219 case FL_PUSH:
220 if (Fl::visible_focus()) {
221 Fl::focus(this);
222 redraw();
224 ih = c->hue();
225 is = c->saturation();
226 case FL_DRAG: {
227 double Xf, Yf, H, S;
228 Xf = (Fl::event_x()-x()-Fl::box_dx(box()))/double(w()-Fl::box_dw(box()));
229 Yf = (Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
230 tohs(Xf, Yf, H, S);
231 if (fabs(H-ih) < 3*6.0/w()) H = ih;
232 if (fabs(S-is) < 3*1.0/h()) S = is;
233 if (Fl::event_state(FL_CTRL)) H = ih;
234 if (c->hsv(H, S, c->value())) c->do_callback();
235 } return 1;
236 case FL_FOCUS : /* FALLTHROUGH */
237 case FL_UNFOCUS :
238 if (Fl::visible_focus()) {
239 redraw();
240 return 1;
242 else return 1;
243 case FL_KEYBOARD :
244 return handle_key(Fl::event_key());
245 default:
246 return 0;
249 #endif // !FL_DOXYGEN
251 static void generate_image(void* vv, int X, int Y, int W, uchar* buf) {
252 Flcc_HueBox* v = (Flcc_HueBox*)vv;
253 int iw = v->w()-Fl::box_dw(v->box());
254 double Yf = double(Y)/(v->h()-Fl::box_dh(v->box()));
255 #ifdef UPDATE_HUE_BOX
256 const double V = ((Fl_Color_Chooser*)(v->parent()))->value();
257 #else
258 const double V = 1.0;
259 #endif
260 for (int x = X; x < X+W; x++) {
261 double Xf = double(x)/iw;
262 double H,S; tohs(Xf,Yf,H,S);
263 double r,g,b;
264 Fl_Color_Chooser::hsv2rgb(H,S,V,r,g,b);
265 *buf++ = uchar(255*r+.5);
266 *buf++ = uchar(255*g+.5);
267 *buf++ = uchar(255*b+.5);
271 #ifndef FL_DOXYGEN
272 int Flcc_HueBox::handle_key(int key) {
273 int w1 = w()-Fl::box_dw(box())-6;
274 int h1 = h()-Fl::box_dh(box())-6;
275 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
277 #ifdef CIRCLE
278 int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * w1);
279 int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * h1);
280 #else
281 int X = int(c->hue()/6.0*w1);
282 int Y = int((1-c->saturation())*h1);
283 #endif
285 switch (key) {
286 case FL_Up :
287 Y -= 3;
288 break;
289 case FL_Down :
290 Y += 3;
291 break;
292 case FL_Left :
293 X -= 3;
294 break;
295 case FL_Right :
296 X += 3;
297 break;
298 default :
299 return 0;
302 double Xf, Yf, H, S;
303 Xf = (double)X/(double)w1;
304 Yf = (double)Y/(double)h1;
305 tohs(Xf, Yf, H, S);
306 if (c->hsv(H, S, c->value())) c->do_callback();
308 return 1;
310 #endif // !FL_DOXYGEN
312 #ifndef FL_DOXYGEN
313 void Flcc_HueBox::draw() {
314 if (damage()&FL_DAMAGE_ALL) draw_box();
315 int x1 = x()+Fl::box_dx(box());
316 int yy1 = y()+Fl::box_dy(box());
317 int w1 = w()-Fl::box_dw(box());
318 int h1 = h()-Fl::box_dh(box());
319 if (damage() == FL_DAMAGE_EXPOSE) fl_push_clip(x1+px,yy1+py,6,6);
320 fl_draw_image(generate_image, this, x1, yy1, w1, h1);
321 if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip();
322 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
323 #ifdef CIRCLE
324 int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * (w1-6));
325 int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * (h1-6));
326 #else
327 int X = int(c->hue()/6.0*(w1-6));
328 int Y = int((1-c->saturation())*(h1-6));
329 #endif
330 if (X < 0) X = 0; else if (X > w1-6) X = w1-6;
331 if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
332 // fl_color(c->value()>.75 ? FL_BLACK : FL_WHITE);
333 draw_box(FL_UP_BOX,x1+X,yy1+Y,6,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY);
334 px = X; py = Y;
336 #endif // !FL_DOXYGEN
338 ////////////////////////////////////////////////////////////////
340 #ifndef FL_DOXYGEN
341 int Flcc_ValueBox::handle(int e) {
342 static double iv;
343 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
344 switch (e) {
345 case FL_PUSH:
346 if (Fl::visible_focus()) {
347 Fl::focus(this);
348 redraw();
350 iv = c->value();
351 case FL_DRAG: {
352 double Yf;
353 Yf = 1-(Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
354 if (fabs(Yf-iv)<(3*1.0/h())) Yf = iv;
355 if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback();
356 } return 1;
357 case FL_FOCUS : /* FALLTHROUGH */
358 case FL_UNFOCUS :
359 if (Fl::visible_focus()) {
360 redraw();
361 return 1;
363 else return 1;
364 case FL_KEYBOARD :
365 return handle_key(Fl::event_key());
366 default:
367 return 0;
370 #endif // !FL_DOXYGEN
372 static double tr, tg, tb;
373 static void generate_vimage(void* vv, int X, int Y, int W, uchar* buf) {
374 Flcc_ValueBox* v = (Flcc_ValueBox*)vv;
375 double Yf = 255*(1.0-double(Y)/(v->h()-Fl::box_dh(v->box())));
376 uchar r = uchar(tr*Yf+.5);
377 uchar g = uchar(tg*Yf+.5);
378 uchar b = uchar(tb*Yf+.5);
379 for (int x = X; x < X+W; x++) {
380 *buf++ = r; *buf++ = g; *buf++ = b;
384 #ifndef FL_DOXYGEN
385 void Flcc_ValueBox::draw() {
386 if (damage()&FL_DAMAGE_ALL) draw_box();
387 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
388 c->hsv2rgb(c->hue(),c->saturation(),1.0,tr,tg,tb);
389 int x1 = x()+Fl::box_dx(box());
390 int yy1 = y()+Fl::box_dy(box());
391 int w1 = w()-Fl::box_dw(box());
392 int h1 = h()-Fl::box_dh(box());
393 if (damage() == FL_DAMAGE_EXPOSE) fl_push_clip(x1,yy1+py,w1,6);
394 fl_draw_image(generate_vimage, this, x1, yy1, w1, h1);
395 if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip();
396 int Y = int((1-c->value()) * (h1-6));
397 if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
398 draw_box(FL_UP_BOX,x1,yy1+Y,w1,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY);
399 py = Y;
401 #endif // !FL_DOXYGEN
403 #ifndef FL_DOXYGEN
404 int Flcc_ValueBox::handle_key(int key) {
405 int h1 = h()-Fl::box_dh(box())-6;
406 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
408 int Y = int((1-c->value()) * h1);
409 if (Y < 0) Y = 0; else if (Y > h1) Y = h1;
411 switch (key) {
412 case FL_Up :
413 Y -= 3;
414 break;
415 case FL_Down :
416 Y += 3;
417 break;
418 default :
419 return 0;
422 double Yf;
423 Yf = 1-((double)Y/(double)h1);
424 if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback();
426 return 1;
428 #endif // !FL_DOXYGEN
430 ////////////////////////////////////////////////////////////////
432 void Fl_Color_Chooser::rgb_cb(Fl_Widget* o, void*) {
433 Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
434 double R = c->rvalue.value();
435 double G = c->gvalue.value();
436 double B = c->bvalue.value();
437 if (c->mode() == M_HSV) {
438 if (c->hsv(R,G,B)) c->do_callback();
439 return;
441 if (c->mode() != M_RGB) {
442 R = R/255;
443 G = G/255;
444 B = B/255;
446 if (c->rgb(R,G,B)) c->do_callback();
449 void Fl_Color_Chooser::mode_cb(Fl_Widget* o, void*) {
450 Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
451 // force them to redraw even if value is the same:
452 c->rvalue.value(-1);
453 c->gvalue.value(-1);
454 c->bvalue.value(-1);
455 c->set_valuators();
458 void Fl_Color_Chooser::mode(int newMode)
460 choice.value(newMode);
461 choice.do_callback();
465 ////////////////////////////////////////////////////////////////
468 Creates a new Fl_Color_Chooser widget using the given position, size, and
469 label string.
470 The recommended dimensions are 200x95. The color is initialized to black.
471 \param[in] X, Y, W, H position and size of the widget
472 \param[in] L widget label, default is no label
474 Fl_Color_Chooser::Fl_Color_Chooser(int X, int Y, int W, int H, const char* L)
475 : Fl_Group(0,0,195,115,L),
476 huebox(0,0,115,115),
477 valuebox(115,0,20,115),
478 choice(140,0,55,25),
479 rvalue(140,30,55,25),
480 gvalue(140,60,55,25),
481 bvalue(140,90,55,25),
482 resize_box(0,0,115,115)
484 end();
485 resizable(resize_box);
486 resize(X,Y,W,H);
487 r_ = g_ = b_ = 0;
488 hue_ = 0.0;
489 saturation_ = 0.0;
490 value_ = 0.0;
491 huebox.box(FL_DOWN_FRAME);
492 valuebox.box(FL_DOWN_FRAME);
493 choice.menu(mode_menu);
494 set_valuators();
495 rvalue.callback(rgb_cb);
496 gvalue.callback(rgb_cb);
497 bvalue.callback(rgb_cb);
498 choice.callback(mode_cb);
499 choice.box(FL_THIN_UP_BOX);
500 choice.textfont(FL_HELVETICA_BOLD_ITALIC);
503 ////////////////////////////////////////////////////////////////
504 // fl_color_chooser():
506 #include <FL/Fl_Window.H>
507 #include <FL/Fl_Box.H>
508 #include <FL/Fl_Return_Button.H>
510 class ColorChip : public Fl_Widget {
511 void draw();
512 public:
513 uchar r,g,b;
514 ColorChip(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
515 box(FL_ENGRAVED_FRAME);}
518 void ColorChip::draw() {
519 if (damage()&FL_DAMAGE_ALL) draw_box();
520 fl_rectf(x()+Fl::box_dx(box()),
521 y()+Fl::box_dy(box()),
522 w()-Fl::box_dw(box()),
523 h()-Fl::box_dh(box()),r,g,b);
526 static void chooser_cb(Fl_Widget* o, void* vv) {
527 Fl_Color_Chooser* c = (Fl_Color_Chooser*)o;
528 ColorChip* v = (ColorChip*)vv;
529 v->r = uchar(255*c->r()+.5);
530 v->g = uchar(255*c->g()+.5);
531 v->b = uchar(255*c->b()+.5);
532 v->damage(FL_DAMAGE_EXPOSE);
535 extern const char* fl_ok;
536 extern const char* fl_cancel;
538 // fl_color_chooser's callback for ok_button (below)
539 // [in] o is a pointer to okay_button (below)
540 // [in] p is a pointer to an int to receive the return value (1)
541 // closes the fl_color_chooser window
542 static void cc_ok_cb (Fl_Widget *o, void *p) {
543 *((int *)p) = 1; // set return value
544 o->window()->hide();
547 // fl_color_chooser's callback for cancel_button and window close
548 // [in] o is a pointer to cancel_button (below) _or_ the dialog window
549 // [in] p is a pointer to an int to receive the return value (0)
550 // closes the fl_color_chooser window
551 static void cc_cancel_cb (Fl_Widget *o, void *p) {
552 *((int *)p) = 0; // set return value
553 if (o->window()) // cancel button
554 o->window()->hide();
555 else // window close
556 o->hide();
559 /** \addtogroup group_comdlg
560 @{ */
562 \brief Pops up a window to let the user pick an arbitrary RGB color.
563 \note \#include <FL/Fl_Color_Chooser.H>
564 \image html fl_color_chooser.jpg
565 \image latex fl_color_chooser.jpg "fl_color_chooser" width=8cm
566 \param[in] name Title label for the window
567 \param[in,out] r, g, b Color components in the range 0.0 to 1.0.
568 \param[in] cmode Optional mode for color chooser. See mode(int). Default -1 if none (rgb mode).
569 \retval 1 if user confirms the selection
570 \retval 0 if user cancels the dialog
571 \relates Fl_Color_Chooser
573 int fl_color_chooser(const char* name, double& r, double& g, double& b, int cmode) {
574 int ret = 0;
575 Fl_Window window(215,200,name);
576 window.callback(cc_cancel_cb,&ret);
577 Fl_Color_Chooser chooser(10, 10, 195, 115);
578 ColorChip ok_color(10, 130, 95, 25);
579 Fl_Return_Button ok_button(10, 165, 95, 25, fl_ok);
580 ok_button.callback(cc_ok_cb,&ret);
581 ColorChip cancel_color(110, 130, 95, 25);
582 cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r;
583 ok_color.g = cancel_color.g = uchar(255*g+.5);
584 ok_color.b = cancel_color.b = uchar(255*b+.5);
585 Fl_Button cancel_button(110, 165, 95, 25, fl_cancel);
586 cancel_button.callback(cc_cancel_cb,&ret);
587 window.resizable(chooser);
588 chooser.rgb(r,g,b);
589 chooser.callback(chooser_cb, &ok_color);
590 if (cmode!=-1) chooser.mode(cmode);
591 window.end();
592 window.set_modal();
593 window.hotspot(window);
594 window.show();
595 while (window.shown()) Fl::wait();
596 if (ret) { // ok_button or Enter
597 r = chooser.r();
598 g = chooser.g();
599 b = chooser.b();
601 return ret;
605 \brief Pops up a window to let the user pick an arbitrary RGB color.
606 \note \#include <FL/Fl_Color_Chooser.H>
607 \image html fl_color_chooser.jpg
608 \image latex fl_color_chooser.jpg "fl_color_chooser" width=8cm
609 \param[in] name Title label for the window
610 \param[in,out] r, g, b Color components in the range 0 to 255.
611 \param[in] cmode Optional mode for color chooser. See mode(int). Default -1 if none (rgb mode).
612 \retval 1 if user confirms the selection
613 \retval 0 if user cancels the dialog
614 \relates Fl_Color_Chooser
616 int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b, int cmode) {
617 double dr = r/255.0;
618 double dg = g/255.0;
619 double db = b/255.0;
620 if (fl_color_chooser(name,dr,dg,db,cmode)) {
621 r = uchar(255*dr+.5);
622 g = uchar(255*dg+.5);
623 b = uchar(255*db+.5);
624 return 1;
626 return 0;
629 /** @} */
631 // End of "$Id: Fl_Color_Chooser.cxx 7981 2010-12-08 23:53:04Z greg.ercolano $".