|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: Fl_Color_Chooser.cxx 7981 2010-12-08 23:53:04Z greg.ercolano $" 00003 // 00004 // Color chooser for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 #include <FL/Fl.H> 00029 #include <FL/Fl_Color_Chooser.H> 00030 #include <FL/fl_draw.H> 00031 #include <FL/math.h> 00032 #include <stdio.h> 00033 00034 // Besides being a useful object on it's own, the Fl_Color_Chooser was 00035 // an attempt to make a complex composite object that could be easily 00036 // imbedded into a user interface. If you wish to make complex objects 00037 // of your own, be sure to read this code. 00038 00039 // The function fl_color_chooser() creates a window containing a color 00040 // chooser and a few buttons and current-color indicators. It is an 00041 // easier interface for simple programs that just need a color. 00042 00043 // The "hue box" can be a circle or rectilinear. 00044 // You get a circle by defining this: 00045 #define CIRCLE 1 00046 // And the "hue box" can auto-update when the value changes 00047 // you get this by defining this: 00048 #define UPDATE_HUE_BOX 1 00049 00055 void Fl_Color_Chooser::hsv2rgb( 00056 double H, double S, double V, double& R, double& G, double& B) { 00057 if (S < 5.0e-6) { 00058 R = G = B = V; 00059 } else { 00060 int i = (int)H; 00061 double f = H - (float)i; 00062 double p1 = V*(1.0-S); 00063 double p2 = V*(1.0-S*f); 00064 double p3 = V*(1.0-S*(1.0-f)); 00065 switch (i) { 00066 case 0: R = V; G = p3; B = p1; break; 00067 case 1: R = p2; G = V; B = p1; break; 00068 case 2: R = p1; G = V; B = p3; break; 00069 case 3: R = p1; G = p2; B = V; break; 00070 case 4: R = p3; G = p1; B = V; break; 00071 case 5: R = V; G = p1; B = p2; break; 00072 } 00073 } 00074 } 00075 00081 void Fl_Color_Chooser::rgb2hsv( 00082 double R, double G, double B, double& H, double& S, double& V) { 00083 double maxv = R > G ? R : G; if (B > maxv) maxv = B; 00084 V = maxv; 00085 if (maxv>0) { 00086 double minv = R < G ? R : G; if (B < minv) minv = B; 00087 S = 1.0 - double(minv)/maxv; 00088 if (maxv > minv) { 00089 if (maxv == R) {H = (G-B)/double(maxv-minv); if (H<0) H += 6.0;} 00090 else if (maxv == G) H = 2.0+(B-R)/double(maxv-minv); 00091 else H = 4.0+(R-G)/double(maxv-minv); 00092 } 00093 } 00094 } 00095 00097 enum { 00098 M_RGB, 00099 M_BYTE, 00100 M_HEX, 00101 M_HSV 00102 }; 00103 static Fl_Menu_Item mode_menu[] = { 00104 {"rgb"}, 00105 {"byte"}, 00106 {"hex"}, 00107 {"hsv"}, 00108 {0} 00109 }; 00110 00111 #ifndef FL_DOXYGEN 00112 int Flcc_Value_Input::format(char* buf) { 00113 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); 00114 if (c->mode() == M_HEX) return sprintf(buf,"0x%02X", int(value())); 00115 else return Fl_Valuator::format(buf); 00116 } 00117 #endif // !FL_DOXYGEN 00118 00119 void Fl_Color_Chooser::set_valuators() { 00120 switch (mode()) { 00121 case M_RGB: 00122 rvalue.range(0,1); rvalue.step(1,1000); rvalue.value(r_); 00123 gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_); 00124 bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_); 00125 break; 00126 case M_BYTE: /* FALLTHROUGH */ 00127 case M_HEX: 00128 rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5)); 00129 gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5)); 00130 bvalue.range(0,255); bvalue.step(1); bvalue.value(int(255*b_+.5)); 00131 break; 00132 case M_HSV: 00133 rvalue.range(0,6); rvalue.step(1,1000); rvalue.value(hue_); 00134 gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(saturation_); 00135 bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(value_); 00136 break; 00137 } 00138 } 00139 00147 int Fl_Color_Chooser::rgb(double R, double G, double B) { 00148 if (R == r_ && G == g_ && B == b_) return 0; 00149 r_ = R; g_ = G; b_ = B; 00150 double ph = hue_; 00151 double ps = saturation_; 00152 double pv = value_; 00153 rgb2hsv(R,G,B,hue_,saturation_,value_); 00154 set_valuators(); 00155 set_changed(); 00156 if (value_ != pv) { 00157 #ifdef UPDATE_HUE_BOX 00158 huebox.damage(FL_DAMAGE_SCROLL); 00159 #endif 00160 valuebox.damage(FL_DAMAGE_EXPOSE);} 00161 if (hue_ != ph || saturation_ != ps) { 00162 huebox.damage(FL_DAMAGE_EXPOSE); 00163 valuebox.damage(FL_DAMAGE_SCROLL); 00164 } 00165 return 1; 00166 } 00167 00175 int Fl_Color_Chooser::hsv(double H, double S, double V) { 00176 H = fmod(H,6.0); if (H < 0.0) H += 6.0; 00177 if (S < 0.0) S = 0.0; else if (S > 1.0) S = 1.0; 00178 if (V < 0.0) V = 0.0; else if (V > 1.0) V = 1.0; 00179 if (H == hue_ && S == saturation_ && V == value_) return 0; 00180 double ph = hue_; 00181 double ps = saturation_; 00182 double pv = value_; 00183 hue_ = H; saturation_ = S; value_ = V; 00184 if (value_ != pv) { 00185 #ifdef UPDATE_HUE_BOX 00186 huebox.damage(FL_DAMAGE_SCROLL); 00187 #endif 00188 valuebox.damage(FL_DAMAGE_EXPOSE);} 00189 if (hue_ != ph || saturation_ != ps) { 00190 huebox.damage(FL_DAMAGE_EXPOSE); 00191 valuebox.damage(FL_DAMAGE_SCROLL); 00192 } 00193 hsv2rgb(H,S,V,r_,g_,b_); 00194 set_valuators(); 00195 set_changed(); 00196 return 1; 00197 } 00198 00200 00201 static void tohs(double x, double y, double& h, double& s) { 00202 #ifdef CIRCLE 00203 x = 2*x-1; 00204 y = 1-2*y; 00205 s = sqrt(x*x+y*y); if (s > 1.0) s = 1.0; 00206 h = (3.0/M_PI)*atan2(y,x); 00207 if (h<0) h += 6.0; 00208 #else 00209 h = fmod(6.0*x,6.0); if (h < 0.0) h += 6.0; 00210 s = 1.0-y; if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0; 00211 #endif 00212 } 00213 00214 #ifndef FL_DOXYGEN 00215 int Flcc_HueBox::handle(int e) { 00216 static double ih, is; 00217 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); 00218 switch (e) { 00219 case FL_PUSH: 00220 if (Fl::visible_focus()) { 00221 Fl::focus(this); 00222 redraw(); 00223 } 00224 ih = c->hue(); 00225 is = c->saturation(); 00226 case FL_DRAG: { 00227 double Xf, Yf, H, S; 00228 Xf = (Fl::event_x()-x()-Fl::box_dx(box()))/double(w()-Fl::box_dw(box())); 00229 Yf = (Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box())); 00230 tohs(Xf, Yf, H, S); 00231 if (fabs(H-ih) < 3*6.0/w()) H = ih; 00232 if (fabs(S-is) < 3*1.0/h()) S = is; 00233 if (Fl::event_state(FL_CTRL)) H = ih; 00234 if (c->hsv(H, S, c->value())) c->do_callback(); 00235 } return 1; 00236 case FL_FOCUS : /* FALLTHROUGH */ 00237 case FL_UNFOCUS : 00238 if (Fl::visible_focus()) { 00239 redraw(); 00240 return 1; 00241 } 00242 else return 1; 00243 case FL_KEYBOARD : 00244 return handle_key(Fl::event_key()); 00245 default: 00246 return 0; 00247 } 00248 } 00249 #endif // !FL_DOXYGEN 00250 00251 static void generate_image(void* vv, int X, int Y, int W, uchar* buf) { 00252 Flcc_HueBox* v = (Flcc_HueBox*)vv; 00253 int iw = v->w()-Fl::box_dw(v->box()); 00254 double Yf = double(Y)/(v->h()-Fl::box_dh(v->box())); 00255 #ifdef UPDATE_HUE_BOX 00256 const double V = ((Fl_Color_Chooser*)(v->parent()))->value(); 00257 #else 00258 const double V = 1.0; 00259 #endif 00260 for (int x = X; x < X+W; x++) { 00261 double Xf = double(x)/iw; 00262 double H,S; tohs(Xf,Yf,H,S); 00263 double r,g,b; 00264 Fl_Color_Chooser::hsv2rgb(H,S,V,r,g,b); 00265 *buf++ = uchar(255*r+.5); 00266 *buf++ = uchar(255*g+.5); 00267 *buf++ = uchar(255*b+.5); 00268 } 00269 } 00270 00271 #ifndef FL_DOXYGEN 00272 int Flcc_HueBox::handle_key(int key) { 00273 int w1 = w()-Fl::box_dw(box())-6; 00274 int h1 = h()-Fl::box_dh(box())-6; 00275 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); 00276 00277 #ifdef CIRCLE 00278 int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * w1); 00279 int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * h1); 00280 #else 00281 int X = int(c->hue()/6.0*w1); 00282 int Y = int((1-c->saturation())*h1); 00283 #endif 00284 00285 switch (key) { 00286 case FL_Up : 00287 Y -= 3; 00288 break; 00289 case FL_Down : 00290 Y += 3; 00291 break; 00292 case FL_Left : 00293 X -= 3; 00294 break; 00295 case FL_Right : 00296 X += 3; 00297 break; 00298 default : 00299 return 0; 00300 } 00301 00302 double Xf, Yf, H, S; 00303 Xf = (double)X/(double)w1; 00304 Yf = (double)Y/(double)h1; 00305 tohs(Xf, Yf, H, S); 00306 if (c->hsv(H, S, c->value())) c->do_callback(); 00307 00308 return 1; 00309 } 00310 #endif // !FL_DOXYGEN 00311 00312 #ifndef FL_DOXYGEN 00313 void Flcc_HueBox::draw() { 00314 if (damage()&FL_DAMAGE_ALL) draw_box(); 00315 int x1 = x()+Fl::box_dx(box()); 00316 int yy1 = y()+Fl::box_dy(box()); 00317 int w1 = w()-Fl::box_dw(box()); 00318 int h1 = h()-Fl::box_dh(box()); 00319 if (damage() == FL_DAMAGE_EXPOSE) fl_push_clip(x1+px,yy1+py,6,6); 00320 fl_draw_image(generate_image, this, x1, yy1, w1, h1); 00321 if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip(); 00322 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); 00323 #ifdef CIRCLE 00324 int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * (w1-6)); 00325 int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * (h1-6)); 00326 #else 00327 int X = int(c->hue()/6.0*(w1-6)); 00328 int Y = int((1-c->saturation())*(h1-6)); 00329 #endif 00330 if (X < 0) X = 0; else if (X > w1-6) X = w1-6; 00331 if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6; 00332 // fl_color(c->value()>.75 ? FL_BLACK : FL_WHITE); 00333 draw_box(FL_UP_BOX,x1+X,yy1+Y,6,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY); 00334 px = X; py = Y; 00335 } 00336 #endif // !FL_DOXYGEN 00337 00339 00340 #ifndef FL_DOXYGEN 00341 int Flcc_ValueBox::handle(int e) { 00342 static double iv; 00343 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); 00344 switch (e) { 00345 case FL_PUSH: 00346 if (Fl::visible_focus()) { 00347 Fl::focus(this); 00348 redraw(); 00349 } 00350 iv = c->value(); 00351 case FL_DRAG: { 00352 double Yf; 00353 Yf = 1-(Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box())); 00354 if (fabs(Yf-iv)<(3*1.0/h())) Yf = iv; 00355 if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback(); 00356 } return 1; 00357 case FL_FOCUS : /* FALLTHROUGH */ 00358 case FL_UNFOCUS : 00359 if (Fl::visible_focus()) { 00360 redraw(); 00361 return 1; 00362 } 00363 else return 1; 00364 case FL_KEYBOARD : 00365 return handle_key(Fl::event_key()); 00366 default: 00367 return 0; 00368 } 00369 } 00370 #endif // !FL_DOXYGEN 00371 00372 static double tr, tg, tb; 00373 static void generate_vimage(void* vv, int X, int Y, int W, uchar* buf) { 00374 Flcc_ValueBox* v = (Flcc_ValueBox*)vv; 00375 double Yf = 255*(1.0-double(Y)/(v->h()-Fl::box_dh(v->box()))); 00376 uchar r = uchar(tr*Yf+.5); 00377 uchar g = uchar(tg*Yf+.5); 00378 uchar b = uchar(tb*Yf+.5); 00379 for (int x = X; x < X+W; x++) { 00380 *buf++ = r; *buf++ = g; *buf++ = b; 00381 } 00382 } 00383 00384 #ifndef FL_DOXYGEN 00385 void Flcc_ValueBox::draw() { 00386 if (damage()&FL_DAMAGE_ALL) draw_box(); 00387 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); 00388 c->hsv2rgb(c->hue(),c->saturation(),1.0,tr,tg,tb); 00389 int x1 = x()+Fl::box_dx(box()); 00390 int yy1 = y()+Fl::box_dy(box()); 00391 int w1 = w()-Fl::box_dw(box()); 00392 int h1 = h()-Fl::box_dh(box()); 00393 if (damage() == FL_DAMAGE_EXPOSE) fl_push_clip(x1,yy1+py,w1,6); 00394 fl_draw_image(generate_vimage, this, x1, yy1, w1, h1); 00395 if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip(); 00396 int Y = int((1-c->value()) * (h1-6)); 00397 if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6; 00398 draw_box(FL_UP_BOX,x1,yy1+Y,w1,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY); 00399 py = Y; 00400 } 00401 #endif // !FL_DOXYGEN 00402 00403 #ifndef FL_DOXYGEN 00404 int Flcc_ValueBox::handle_key(int key) { 00405 int h1 = h()-Fl::box_dh(box())-6; 00406 Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); 00407 00408 int Y = int((1-c->value()) * h1); 00409 if (Y < 0) Y = 0; else if (Y > h1) Y = h1; 00410 00411 switch (key) { 00412 case FL_Up : 00413 Y -= 3; 00414 break; 00415 case FL_Down : 00416 Y += 3; 00417 break; 00418 default : 00419 return 0; 00420 } 00421 00422 double Yf; 00423 Yf = 1-((double)Y/(double)h1); 00424 if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback(); 00425 00426 return 1; 00427 } 00428 #endif // !FL_DOXYGEN 00429 00431 00432 void Fl_Color_Chooser::rgb_cb(Fl_Widget* o, void*) { 00433 Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent()); 00434 double R = c->rvalue.value(); 00435 double G = c->gvalue.value(); 00436 double B = c->bvalue.value(); 00437 if (c->mode() == M_HSV) { 00438 if (c->hsv(R,G,B)) c->do_callback(); 00439 return; 00440 } 00441 if (c->mode() != M_RGB) { 00442 R = R/255; 00443 G = G/255; 00444 B = B/255; 00445 } 00446 if (c->rgb(R,G,B)) c->do_callback(); 00447 } 00448 00449 void Fl_Color_Chooser::mode_cb(Fl_Widget* o, void*) { 00450 Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent()); 00451 // force them to redraw even if value is the same: 00452 c->rvalue.value(-1); 00453 c->gvalue.value(-1); 00454 c->bvalue.value(-1); 00455 c->set_valuators(); 00456 } 00457 00458 void Fl_Color_Chooser::mode(int newMode) 00459 { 00460 choice.value(newMode); 00461 choice.do_callback(); 00462 } 00463 00464 00466 00474 Fl_Color_Chooser::Fl_Color_Chooser(int X, int Y, int W, int H, const char* L) 00475 : Fl_Group(0,0,195,115,L), 00476 huebox(0,0,115,115), 00477 valuebox(115,0,20,115), 00478 choice(140,0,55,25), 00479 rvalue(140,30,55,25), 00480 gvalue(140,60,55,25), 00481 bvalue(140,90,55,25), 00482 resize_box(0,0,115,115) 00483 { 00484 end(); 00485 resizable(resize_box); 00486 resize(X,Y,W,H); 00487 r_ = g_ = b_ = 0; 00488 hue_ = 0.0; 00489 saturation_ = 0.0; 00490 value_ = 0.0; 00491 huebox.box(FL_DOWN_FRAME); 00492 valuebox.box(FL_DOWN_FRAME); 00493 choice.menu(mode_menu); 00494 set_valuators(); 00495 rvalue.callback(rgb_cb); 00496 gvalue.callback(rgb_cb); 00497 bvalue.callback(rgb_cb); 00498 choice.callback(mode_cb); 00499 choice.box(FL_THIN_UP_BOX); 00500 choice.textfont(FL_HELVETICA_BOLD_ITALIC); 00501 } 00502 00504 // fl_color_chooser(): 00505 00506 #include <FL/Fl_Window.H> 00507 #include <FL/Fl_Box.H> 00508 #include <FL/Fl_Return_Button.H> 00509 00510 class ColorChip : public Fl_Widget { 00511 void draw(); 00512 public: 00513 uchar r,g,b; 00514 ColorChip(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) { 00515 box(FL_ENGRAVED_FRAME);} 00516 }; 00517 00518 void ColorChip::draw() { 00519 if (damage()&FL_DAMAGE_ALL) draw_box(); 00520 fl_rectf(x()+Fl::box_dx(box()), 00521 y()+Fl::box_dy(box()), 00522 w()-Fl::box_dw(box()), 00523 h()-Fl::box_dh(box()),r,g,b); 00524 } 00525 00526 static void chooser_cb(Fl_Widget* o, void* vv) { 00527 Fl_Color_Chooser* c = (Fl_Color_Chooser*)o; 00528 ColorChip* v = (ColorChip*)vv; 00529 v->r = uchar(255*c->r()+.5); 00530 v->g = uchar(255*c->g()+.5); 00531 v->b = uchar(255*c->b()+.5); 00532 v->damage(FL_DAMAGE_EXPOSE); 00533 } 00534 00535 extern const char* fl_ok; 00536 extern const char* fl_cancel; 00537 00538 // fl_color_chooser's callback for ok_button (below) 00539 // [in] o is a pointer to okay_button (below) 00540 // [in] p is a pointer to an int to receive the return value (1) 00541 // closes the fl_color_chooser window 00542 static void cc_ok_cb (Fl_Widget *o, void *p) { 00543 *((int *)p) = 1; // set return value 00544 o->window()->hide(); 00545 } 00546 00547 // fl_color_chooser's callback for cancel_button and window close 00548 // [in] o is a pointer to cancel_button (below) _or_ the dialog window 00549 // [in] p is a pointer to an int to receive the return value (0) 00550 // closes the fl_color_chooser window 00551 static void cc_cancel_cb (Fl_Widget *o, void *p) { 00552 *((int *)p) = 0; // set return value 00553 if (o->window()) // cancel button 00554 o->window()->hide(); 00555 else // window close 00556 o->hide(); 00557 } 00558 00573 int fl_color_chooser(const char* name, double& r, double& g, double& b, int cmode) { 00574 int ret = 0; 00575 Fl_Window window(215,200,name); 00576 window.callback(cc_cancel_cb,&ret); 00577 Fl_Color_Chooser chooser(10, 10, 195, 115); 00578 ColorChip ok_color(10, 130, 95, 25); 00579 Fl_Return_Button ok_button(10, 165, 95, 25, fl_ok); 00580 ok_button.callback(cc_ok_cb,&ret); 00581 ColorChip cancel_color(110, 130, 95, 25); 00582 cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r; 00583 ok_color.g = cancel_color.g = uchar(255*g+.5); 00584 ok_color.b = cancel_color.b = uchar(255*b+.5); 00585 Fl_Button cancel_button(110, 165, 95, 25, fl_cancel); 00586 cancel_button.callback(cc_cancel_cb,&ret); 00587 window.resizable(chooser); 00588 chooser.rgb(r,g,b); 00589 chooser.callback(chooser_cb, &ok_color); 00590 if (cmode!=-1) chooser.mode(cmode); 00591 window.end(); 00592 window.set_modal(); 00593 window.hotspot(window); 00594 window.show(); 00595 while (window.shown()) Fl::wait(); 00596 if (ret) { // ok_button or Enter 00597 r = chooser.r(); 00598 g = chooser.g(); 00599 b = chooser.b(); 00600 } 00601 return ret; 00602 } 00603 00616 int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b, int cmode) { 00617 double dr = r/255.0; 00618 double dg = g/255.0; 00619 double db = b/255.0; 00620 if (fl_color_chooser(name,dr,dg,db,cmode)) { 00621 r = uchar(255*dr+.5); 00622 g = uchar(255*dg+.5); 00623 b = uchar(255*db+.5); 00624 return 1; 00625 } 00626 return 0; 00627 } 00628 00630 // 00631 // End of "$Id: Fl_Color_Chooser.cxx 7981 2010-12-08 23:53:04Z greg.ercolano $". 00632 //