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)  

fl_plastic.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: fl_plastic.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // "Plastic" drawing routines for the Fast Light Tool Kit (FLTK).
00005 //
00006 // These box types provide a cross between Aqua and KDE buttons; kindof
00007 // like translucent plastic buttons...
00008 //
00009 // Copyright 2001-2010 by Michael Sweet.
00010 //
00011 // This library is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU Library General Public
00013 // License as published by the Free Software Foundation; either
00014 // version 2 of the License, or (at your option) any later version.
00015 //
00016 // This library is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Library General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Library General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA.
00025 //
00026 // Please report all bugs and problems on the following page:
00027 //
00028 //     http://www.fltk.org/str.php
00029 //
00030 
00031 // Box drawing code for an obscure box type.
00032 // These box types are in separate files so they are not linked
00033 // in if not used.
00034 
00035 #include <FL/Fl.H>
00036 #include <FL/fl_draw.H>
00037 #include "flstring.h"
00038 
00039 //
00040 // Uncomment the following line to restore the old plastic box type
00041 // appearance.
00042 //
00043 
00044 //#define USE_OLD_PLASTIC_BOX
00045 #define USE_OLD_PLASTIC_COLOR
00046 
00047 extern uchar *fl_gray_ramp();
00048 
00049 inline Fl_Color shade_color(uchar gc, Fl_Color bc) {
00050 #ifdef USE_OLD_PLASTIC_COLOR
00051   return fl_color_average((Fl_Color)gc, bc, 0.75f);
00052 #else
00053   unsigned      grgb = Fl::get_color((Fl_Color)gc),
00054                 brgb = Fl::get_color(bc);
00055   int           red, green, blue, gray;
00056 
00057 
00058   gray  = ((grgb >> 24) & 255);
00059   red   = gray * ((brgb >> 24) & 255) / 255 + gray * gray / 510;
00060   gray  = ((grgb >> 16) & 255);
00061   green = gray * ((brgb >> 16) & 255) / 255 + gray * gray / 510;
00062   gray  = ((grgb >> 8) & 255);
00063   blue  = gray * ((brgb >> 8) & 255) / 255 + gray * gray / 510;
00064 
00065   if (red > 255)
00066     red = 255;
00067 
00068   if (green > 255)
00069     green = 255;
00070 
00071   if (blue > 255)
00072     blue = 255;
00073 
00074   if (Fl::draw_box_active())
00075     return fl_rgb_color(red, green, blue);
00076   else
00077     return fl_color_average(FL_GRAY, fl_rgb_color(red, green, blue), 0.75f);
00078 #endif // USE_OLD_PLASTIC_COLOR
00079 }
00080 
00081 
00082 static void frame_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
00083   uchar *g = fl_gray_ramp();
00084   int b = strlen(c) / 4 + 1;
00085 
00086   for (x += b, y += b, w -= 2 * b, h -= 2 * b; b > 1; b --)
00087   {
00088     // Draw lines around the perimeter of the button, 4 colors per
00089     // circuit.
00090     fl_color(shade_color(g[(int)*c++], bc));
00091     fl_line(x, y + h + b, x + w - 1, y + h + b, x + w + b - 1, y + h);
00092     fl_color(shade_color(g[(int)*c++], bc));
00093     fl_line(x + w + b - 1, y + h, x + w + b - 1, y, x + w - 1, y - b);
00094     fl_color(shade_color(g[(int)*c++], bc));
00095     fl_line(x + w - 1, y - b, x, y - b, x - b, y);
00096     fl_color(shade_color(g[(int)*c++], bc));
00097     fl_line(x - b, y, x - b, y + h, x, y + h + b);
00098   }
00099 }
00100 
00101 
00102 static void frame_round(int x, int y, int w, int h, const char *c, Fl_Color bc) {
00103   uchar *g = fl_gray_ramp();
00104   int b = strlen(c) / 4 + 1;
00105 
00106   if (w==h) {
00107     for (; b > 1; b --, x ++, y ++, w -= 2, h -= 2)
00108     {
00109       fl_color(shade_color(g[(int)*c++], bc));
00110       fl_arc(x, y, w, h, 45.0, 135.0);
00111       fl_color(shade_color(g[(int)*c++], bc));
00112       fl_arc(x, y, w, h, 315.0, 405.0);
00113       fl_color(shade_color(g[(int)*c++], bc));
00114       fl_arc(x, y, w, h, 225.0, 315.0);
00115       fl_color(shade_color(g[(int)*c++], bc));
00116       fl_arc(x, y, w, h, 135.0, 225.0);
00117     }
00118   } else if (w>h) {
00119     int d = h/2;
00120     for (; b > 1; d--, b --, x ++, y ++, w -= 2, h -= 2)
00121     {
00122       fl_color(shade_color(g[(int)*c++], bc));
00123       fl_arc(x, y, h, h, 90.0, 135.0);
00124       fl_xyline(x+d, y, x+w-d);
00125       fl_arc(x+w-h, y, h, h, 45.0, 90.0);
00126       fl_color(shade_color(g[(int)*c++], bc));
00127       fl_arc(x+w-h, y, h, h, 315.0, 405.0);
00128       fl_color(shade_color(g[(int)*c++], bc));
00129       fl_arc(x+w-h, y, h, h, 270.0, 315.0);
00130       fl_xyline(x+d, y+h-1, x+w-d);
00131       fl_arc(x, y, h, h, 225.0, 270.0);
00132       fl_color(shade_color(g[(int)*c++], bc));
00133       fl_arc(x, y, h, h, 135.0, 225.0);
00134     }
00135   } else if (w<h) {
00136     int d = w/2;
00137     for (; b > 1; d--, b --, x ++, y ++, w -= 2, h -= 2)
00138     {
00139       fl_color(shade_color(g[(int)*c++], bc));
00140       fl_arc(x, y, w, w, 45.0, 135.0);
00141       fl_color(shade_color(g[(int)*c++], bc));
00142       fl_arc(x, y, w, w, 0.0, 45.0);
00143       fl_yxline(x+w-1, y+d, y+h-d);
00144       fl_arc(x, y+h-w, w, w, 315.0, 360.0);
00145       fl_color(shade_color(g[(int)*c++], bc));
00146       fl_arc(x, y+h-w, w, w, 225.0, 315.0);
00147       fl_color(shade_color(g[(int)*c++], bc));
00148       fl_arc(x, y+h-w, w, w, 180.0, 225.0);
00149       fl_yxline(x, y+d, y+h-d);
00150       fl_arc(x, y, w, w, 135.0, 180.0);
00151     }
00152   }
00153 }
00154 
00155 
00156 static void shade_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
00157   uchar         *g = fl_gray_ramp();
00158   int           i, j;
00159   int           clen = strlen(c) - 1;
00160   int           chalf = clen / 2;
00161   int           cstep = 1;
00162 
00163   if (h < (w * 2)) {
00164     // Horizontal shading...
00165     if (clen >= h) cstep = 2;
00166 
00167     for (i = 0, j = 0; j < chalf; i ++, j += cstep) {
00168       // Draw the top line and points...
00169       fl_color(shade_color(g[(int)c[i]], bc));
00170       fl_xyline(x + 1, y + i, x + w - 2);
00171 
00172       fl_color(shade_color(g[c[i] - 2], bc));
00173       fl_point(x, y + i + 1);
00174       fl_point(x + w - 1, y + i + 1);
00175 
00176       // Draw the bottom line and points...
00177       fl_color(shade_color(g[(int)c[clen - i]], bc));
00178       fl_xyline(x + 1, y + h - i, x + w - 2);
00179 
00180       fl_color(shade_color(g[c[clen - i] - 2], bc));
00181       fl_point(x, y + h - i);
00182       fl_point(x + w - 1, y + h - i);
00183     }
00184 
00185     // Draw the interior and sides...
00186     i = chalf / cstep;
00187 
00188     fl_color(shade_color(g[(int)c[chalf]], bc));
00189     fl_rectf(x + 1, y + i, w - 2, h - 2 * i + 1);
00190 
00191     fl_color(shade_color(g[c[chalf] - 2], bc));
00192     fl_yxline(x, y + i, y + h - i);
00193     fl_yxline(x + w - 1, y + i, y + h - i);
00194   } else {
00195     // Vertical shading...
00196     if (clen >= w) cstep = 2;
00197 
00198     for (i = 0, j = 0; j < chalf; i ++, j += cstep) {
00199       // Draw the left line and points...
00200       fl_color(shade_color(g[(int)c[i]], bc));
00201       fl_yxline(x + i, y + 1, y + h - 1);
00202 
00203       fl_color(shade_color(g[c[i] - 2], bc));
00204       fl_point(x + i + 1, y);
00205       fl_point(x + i + 1, y + h);
00206 
00207       // Draw the right line and points...
00208       fl_color(shade_color(g[(int)c[clen - i]], bc));
00209       fl_yxline(x + w - 1 - i, y + 1, y + h - 1);
00210 
00211       fl_color(shade_color(g[c[clen - i] - 2], bc));
00212       fl_point(x + w - 2 - i, y);
00213       fl_point(x + w - 2 - i, y + h);
00214     }
00215 
00216     // Draw the interior, top, and bottom...
00217     i = chalf / cstep;
00218 
00219     fl_color(shade_color(g[(int)c[chalf]], bc));
00220     fl_rectf(x + i, y + 1, w - 2 * i, h - 1);
00221 
00222     fl_color(shade_color(g[c[chalf] - 2], bc));
00223     fl_xyline(x + i, y, x + w - i);
00224     fl_xyline(x + i, y + h, x + w - i);
00225   }
00226 }
00227 
00228 static void shade_round(int x, int y, int w, int h, const char *c, Fl_Color bc) {
00229   uchar         *g = fl_gray_ramp();
00230   int           i;
00231   int           clen = strlen(c) - 1;
00232   int           chalf = clen / 2;
00233 
00234   if (w>h) {
00235     int d = h/2;
00236     const int na = 8;
00237     for (i=0; i<chalf; i++, d--, x++, y++, w-=2, h-=2)
00238     {
00239       fl_color(shade_color(g[(int)c[i]], bc));
00240       fl_pie(x, y, h, h, 90.0, 135.0+i*na);
00241       fl_xyline(x+d, y, x+w-d);
00242       fl_pie(x+w-h, y, h, h, 45.0+i*na, 90.0);
00243       fl_color(shade_color(g[(int)c[i] - 2], bc));
00244       fl_pie(x+w-h, y, h, h, 315.0+i*na, 405.0+i*na);
00245       fl_color(shade_color(g[(int)c[clen - i]], bc));
00246       fl_pie(x+w-h, y, h, h, 270.0, 315.0+i*na);
00247       fl_xyline(x+d, y+h-1, x+w-d);
00248       fl_pie(x, y, h, h, 225.0+i*na, 270.0);
00249       fl_color(shade_color(g[c[(int)clen - i] - 2], bc));
00250       fl_pie(x, y, h, h, 135.0+i*na, 225.0+i*na);
00251     }
00252     fl_color(shade_color(g[(int)c[chalf]], bc));
00253     fl_rectf(x+d, y, w-h+1, h+1);
00254     fl_pie(x, y, h, h, 90.0, 270.0);
00255     fl_pie(x+w-h, y, h, h, 270.0, 90.0);
00256   } else {
00257     int d = w/2;
00258     const int na = 8;
00259     for (i=0; i<chalf; i++, d--, x++, y++, w-=2, h-=2)
00260     {
00261       fl_color(shade_color(g[(int)c[i]], bc));
00262       fl_pie(x, y, w, w, 45.0+i*na, 135.0+i*na);
00263       fl_color(shade_color(g[c[i] - 2], bc));
00264       fl_pie(x, y, w, w, 0.0, 45.0+i*na);
00265       fl_yxline(x+w-1, y+d, y+h-d);
00266       fl_pie(x, y+h-w, w, w, 315.0+i*na, 360.0);
00267       fl_color(shade_color(g[(int)c[clen - i]], bc));
00268       fl_pie(x, y+h-w, w, w, 225.0+i*na, 315.0+i*na);
00269       fl_color(shade_color(g[c[clen - i] - 2], bc));
00270       fl_pie(x, y+h-w, w, w, 180.0, 225.0+i*na);
00271       fl_yxline(x, y+d, y+h-d);
00272       fl_pie(x, y, w, w, 135.0+i*na, 180.0);
00273     }
00274     fl_color(shade_color(g[(int)c[chalf]], bc));
00275     fl_rectf(x, y+d, w+1, h-w+1);
00276     fl_pie(x, y, w, w, 0.0, 180.0);
00277     fl_pie(x, y+h-w, w, w, 180.0, 360.0);
00278   }
00279 }
00280 
00281 
00282 static void up_frame(int x, int y, int w, int h, Fl_Color c) {
00283   frame_rect(x, y, w, h - 1, "KLDIIJLM", c);
00284 }
00285 
00286 
00287 static void narrow_thin_box(int x, int y, int w, int h, Fl_Color c) {
00288   if (h<=0 || w<=0) return;
00289   uchar *g = fl_gray_ramp();
00290   fl_color(shade_color(g['R'], c));
00291   fl_rectf(x+1, y+1, w-2, h-2);
00292   fl_color(shade_color(g['I'], c));
00293   if (w > 1) {
00294     fl_xyline(x+1, y, x+w-2);
00295     fl_xyline(x+1, y+h-1, x+w-2);
00296   }
00297   if (h > 1) {
00298     fl_yxline(x, y+1, y+h-2);
00299     fl_yxline(x+w-1, y+1, y+h-2);
00300   }
00301 }
00302 
00303 
00304 static void thin_up_box(int x, int y, int w, int h, Fl_Color c) {
00305 #ifdef USE_OLD_PLASTIC_BOX
00306   shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c);
00307   up_frame(x, y, w, h, c);
00308 #else
00309   if (w > 4 && h > 4) {
00310     shade_rect(x + 1, y + 1, w - 2, h - 3, "RQOQSUWQ", c);
00311     frame_rect(x, y, w, h - 1, "IJLM", c);
00312   } else {
00313     narrow_thin_box(x, y, w, h, c);
00314   }
00315 #endif // USE_OLD_PLASTIC_BOX
00316 }
00317 
00318 
00319 static void up_box(int x, int y, int w, int h, Fl_Color c) {
00320 #ifdef USE_OLD_PLASTIC_BOX
00321   shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c);
00322   up_frame(x, y, w, h, c);
00323 #else
00324   if (w > 8 && h > 8) {
00325     shade_rect(x + 1, y + 1, w - 2, h - 3, "RVQNOPQRSTUVWVQ", c);
00326     frame_rect(x, y, w, h - 1, "IJLM", c);
00327   } else {
00328     thin_up_box(x, y, w, h, c);
00329   }
00330 #endif // USE_OLD_PLASTIC_BOX
00331 }
00332 
00333 
00334 static void up_round(int x, int y, int w, int h, Fl_Color c) {
00335   shade_round(x, y, w, h, "RVQNOPQRSTUVWVQ", c);
00336   frame_round(x, y, w, h, "IJLM", c);
00337 }
00338 
00339 
00340 static void down_frame(int x, int y, int w, int h, Fl_Color c) {
00341   frame_rect(x, y, w, h - 1, "LLLLTTRR", c);
00342 }
00343 
00344 
00345 static void down_box(int x, int y, int w, int h, Fl_Color c) {
00346   if (w > 6 && h > 6) {
00347     shade_rect(x + 2, y + 2, w - 4, h - 5, "STUVWWWVT", c);
00348     down_frame(x, y, w, h, c);
00349   }
00350   else {
00351     narrow_thin_box(x, y, w, h, c);
00352   }
00353 }
00354 
00355 
00356 static void down_round(int x, int y, int w, int h, Fl_Color c) {
00357   shade_round(x, y, w, h, "STUVWWWVT", c);
00358   frame_round(x, y, w, h, "IJLM", c);
00359 }
00360 
00361 
00362 extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
00363 
00364 
00365 Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX() {
00366   fl_internal_boxtype(_FL_PLASTIC_UP_BOX, up_box);
00367   fl_internal_boxtype(_FL_PLASTIC_DOWN_BOX, down_box);
00368   fl_internal_boxtype(_FL_PLASTIC_UP_FRAME, up_frame);
00369   fl_internal_boxtype(_FL_PLASTIC_DOWN_FRAME, down_frame);
00370   fl_internal_boxtype(_FL_PLASTIC_THIN_UP_BOX, thin_up_box);
00371   fl_internal_boxtype(_FL_PLASTIC_THIN_DOWN_BOX, down_box);
00372   fl_internal_boxtype(_FL_PLASTIC_ROUND_UP_BOX, up_round);
00373   fl_internal_boxtype(_FL_PLASTIC_ROUND_DOWN_BOX, down_round);
00374 
00375   return _FL_PLASTIC_UP_BOX;
00376 }
00377 
00378 
00379 //
00380 // End of "$Id: fl_plastic.cxx 7903 2010-11-28 21:06:39Z matt $".
00381 //