gwenhywfar  4.3.1
theme.cpp
Go to the documentation of this file.
00001 /* These widgets have initially been created by Martin Oberzalek who gave them into
00002  * the public domain via an email to the mailing list foxgui-users on 17th of June, 2010
00003  * ("here the source. Free to use for alll.").
00004  * I (Martin Preuss) adapted them to be usable with FOX 1.6 and also added some widgets of
00005  * my own (for now: ThemeHeaderItem).
00006  */
00007 
00008 #ifdef HAVE_CONFIG_H
00009 # include <config.h>
00010 #endif
00011 
00012 
00013 #include "theme.h"
00014 
00015 #define ICON_SPACING  4
00016 
00017 
00018 // Draw rectangle
00019 static void drawRectangle(FXDC& dc,FXColor lower,FXColor upper,FXint x,FXint y,FXint w,FXint h){
00020   register FXint rr,gg,bb,dr,dg,db,r1,g1,b1,r2,g2,b2,yl,yh,yy,dy,n,t;
00021   const FXint MAXSTEPS=128;
00022 
00023   if(0<w && 0<h){
00024     dc.setStipple(STIPPLE_NONE);
00025     dc.setFillStyle(FILL_SOLID);
00026 
00027     r1=FXREDVAL(lower);   r2=FXREDVAL(upper);   dr=r2-r1;
00028     g1=FXGREENVAL(lower); g2=FXGREENVAL(upper); dg=g2-g1;
00029     b1=FXBLUEVAL(lower);  b2=FXBLUEVAL(upper);  db=b2-b1;
00030 
00031     n=FXABS(dr);
00032     if((t=FXABS(dg))>n) n=t;
00033     if((t=FXABS(db))>n) n=t;
00034     n++;
00035     if(n>h) n=h;
00036     if(n>MAXSTEPS) n=MAXSTEPS;
00037     rr=(r1<<16)+32767;
00038     gg=(g1<<16)+32767;
00039     bb=(b1<<16)+32767;
00040     yy=32767;
00041 
00042     dr=(dr<<16)/n;
00043     dg=(dg<<16)/n;
00044     db=(db<<16)/n;
00045     dy=(h<<16)/n;
00046 
00047     do {
00048       yl=yy>>16;
00049       yy+=dy;
00050       yh=yy>>16;
00051       dc.setForeground(FXRGB(rr>>16,gg>>16,bb>>16));
00052       dc.fillRectangle(x,y+yl,w,yh-yl);
00053       rr+=dr;
00054       gg+=dg;
00055       bb+=db;
00056     } while(yh<h);
00057   }
00058 }
00059 
00060 
00061 
00062 
00063 FXDEFMAP(ThemeButton) ThemeButtonMap[]={
00064         FXMAPFUNC( SEL_PAINT, 0, ThemeButton::onPaint)
00065 };
00066 
00067 FXIMPLEMENT( ThemeButton, FXButton, ThemeButtonMap, ARRAYNUMBER(ThemeButtonMap) );
00068 
00069 
00070 ThemeButton::ThemeButton(FXComposite* p, const FXString& text, FXIcon* ic,
00071                          FXObject* tgt, FXSelector sel, FXuint opts,
00072                          FXint x, FXint y, FXint w, FXint h,
00073                          FXint pl, FXint pr, FXint pt, FXint pb)
00074   : FXButton( p, text, ic, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb )
00075 {}
00076 
00077 // Handle repaint
00078 long ThemeButton::onPaint(FXObject*,FXSelector,void* ptr){
00079   FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy;
00080   FXEvent*ev=(FXEvent*)ptr;
00081   FXDCWindow dc(this,ev);
00082 
00083 
00084   FXColor top         = FXRGB(0xfe,0xfd,0xfd);
00085   FXColor bottom      = FXRGB(0xdd,0xd7,0xce);
00086   FXColor shade       = FXRGB(0xdc,0xd9,0xd4);
00087 
00088 //      FXColor bordercolor = FXRGB(0x78,0x70,0x63);
00089 
00090   FXColor bordercolor = FXRGB(123,158,189);
00091 
00092 /*
00093   FXPoint borderbackground[12]={FXPoint(0,0),FXPoint(0,1),FXPoint(1,0),
00094   FXPoint(width-1,0),FXPoint(width-2,0),FXPoint(width-1,1),
00095   FXPoint(0,height-1),FXPoint(0,height-2),FXPoint(1,height-1),
00096   FXPoint(width-1,height-1),FXPoint(width-1,height-2),FXPoint(width-2,height-1)};
00097 */
00098   FXPoint basebackground[4]={FXPoint(0,0),FXPoint(width-1,0),FXPoint(0,height-1),FXPoint(width-1,height-1)};
00099 
00100   FXPoint bordershade[16]={
00101     FXPoint(0,1),FXPoint(1,0),FXPoint(1,2),FXPoint(2,1),
00102     FXPoint(width-2,0),FXPoint(width-1,1),FXPoint(width-3,1),FXPoint(width-2,2),
00103     FXPoint(0,height-2),FXPoint(1,height-1),FXPoint(1,height-3),FXPoint(2,height-2),
00104     FXPoint(width-1,height-2),FXPoint(width-2,height-1),FXPoint(width-2,height-3),FXPoint(width-3,height-2)
00105   };
00106   FXPoint bordercorners[4]={
00107     FXPoint(1,1),FXPoint(1,height-2),FXPoint(width-2,1),FXPoint(width-2,height-2)
00108   };
00109 
00110 
00111   if (options&BUTTON_TOOLBAR && !underCursor()) {
00112     dc.setForeground(baseColor);
00113     dc.fillRectangle(0,0,width,height);
00114   }
00115   else if (state==STATE_UP && ((options&BUTTON_TOOLBAR)==0 || (options&BUTTON_TOOLBAR && underCursor()))) {
00117     dc.setForeground(baseColor);
00118     dc.drawPoints(basebackground,4);
00120     dc.setForeground(bordercolor);
00121     dc.drawRectangle(2,0,width-5,0);
00122     dc.drawRectangle(2,height-1,width-5,height-1);
00123     dc.drawRectangle(0,2,0,height-5);
00124     dc.drawRectangle(width-1,2,width-1,height-5);
00125     dc.drawPoints(bordercorners,4);
00126     dc.setForeground(shade);
00127     dc.drawPoints(bordershade,16);
00129     drawRectangle(dc,top,bottom,2,1,width-4,height-2);
00130     dc.setForeground(top);
00131     dc.drawRectangle(1,3,0,height-7);
00132     dc.setForeground(bottom);
00133     dc.drawRectangle(width-2,3,0,height-7);
00134   }
00135   else {
00137     dc.setForeground(baseColor);
00138     dc.drawPoints(basebackground,4);
00140     dc.setForeground(bordercolor);
00141     dc.drawRectangle(2,0,width-5,0);
00142     dc.drawRectangle(2,height-1,width-5,height-1);
00143     dc.drawRectangle(0,2,0,height-5);
00144     dc.drawRectangle(width-1,2,width-1,height-5);
00145     dc.drawPoints(bordercorners,4);
00146     dc.setForeground(shade);
00147     dc.drawPoints(bordershade,16);
00148 
00149     dc.setForeground(FXRGB(0xdc,0xd4,0xc9));
00150     dc.fillRectangle(2,1,width-4,height-2);
00151   }
00152 
00153   // Place text & icon
00154   if(!label.empty()){
00155     tw=labelWidth(label);
00156     th=labelHeight(label);
00157   }
00158   if(icon){
00159     iw=icon->getWidth();
00160     ih=icon->getHeight();
00161   }
00162 
00163   just_x(tx,ix,tw,iw);
00164   just_y(ty,iy,th,ih);
00165 
00166   // Shift a bit when pressed
00167   if (state && (options&(FRAME_RAISED|FRAME_SUNKEN))){
00168     ++tx; ++ty; ++ix; ++iy;
00169   }
00170 
00171   // Draw enabled state
00172   if(isEnabled()){
00173     if(icon){
00174       dc.drawIcon(icon,ix,iy);
00175     }
00176     if(!label.empty()){
00177       dc.setFont(font);
00178       dc.setForeground(textColor);
00179       drawLabel(dc,label,hotoff,tx,ty,tw,th);
00180     }
00181     if(hasFocus()){
00182       dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2);
00183     }
00184   }
00185 
00186   // Draw grayed-out state
00187   else {
00188     if (icon) {
00189       dc.drawIconSunken(icon,ix,iy);
00190     }
00191     if(!label.empty()) {
00192       dc.setFont(font);
00193       dc.setForeground(hiliteColor);
00194       drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th);
00195       dc.setForeground(shadowColor);
00196       drawLabel(dc,label,hotoff,tx,ty,tw,th);
00197     }
00198   }
00199   return 1;
00200 }
00201 
00202 
00203 
00204 
00205 FXDEFMAP(ThemeTextField) ThemeTextFieldMap[]={
00206   FXMAPFUNC( SEL_PAINT, 0, ThemeTextField::onPaint)
00207 };
00208 
00209 FXIMPLEMENT( ThemeTextField, FXTextField, ThemeTextFieldMap, ARRAYNUMBER(ThemeTextFieldMap) );
00210 
00211 ThemeTextField::ThemeTextField(FXComposite* p,FXint ncols,FXObject* tgt,FXSelector sel,
00212                                FXuint opts,FXint x,FXint y,FXint w,FXint h,
00213                                FXint pl,FXint pr,FXint pt,FXint pb)
00214   : FXTextField( p, ncols, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb )
00215 {
00216         
00217 }
00218 
00219 static void drawFrame(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h) {
00220   if(0<w && 0<h){
00221     dc.setForeground(FXRGB(123,158,189));
00222     dc.fillRectangle(x,y,w,1);
00223     dc.fillRectangle(x,y,1,h);
00224     // dc.setForeground(hiliteColor);
00225     dc.fillRectangle(x,y+h-1,w,1);
00226     dc.fillRectangle(x+w-1,y,1,h);
00227   }
00228 }
00229 
00230 
00231 
00232 
00233 static void drawSunkenFrame(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h){
00234   if(0<w && 0<h){
00235     dc.setForeground(FXRGB(255,158,100));
00236     dc.fillRectangle(x,y,w,1);
00237     dc.fillRectangle(x,y,1,h);
00238     // dc.setForeground(hiliteColor);
00239     dc.fillRectangle(x,y+h-1,w,1);
00240     dc.fillRectangle(x+w-1,y,1,h);
00241 
00242     if(1<w && 1<h){
00243       dc.fillRectangle(x+1,y+1,w-3,1);
00244       dc.fillRectangle(x+1,y+1,1,h-3);
00245       dc.fillRectangle(x+1,y+h-2,w-2,1);
00246       dc.fillRectangle(x+w-2,y+1,1,h-2);
00247     }
00248   }
00249 }
00250 
00251 
00252 
00253 static void drawHighlightFrame(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h) {
00254   if (0<w && 0<h){
00255     dc.setForeground(FXRGB(123,158,255));
00256     dc.fillRectangle(x,y,w,1);
00257     dc.fillRectangle(x,y,1,h);
00258     // dc.setForeground(hiliteColor);
00259     dc.fillRectangle(x,y+h-1,w,1);
00260     dc.fillRectangle(x+w-1,y,1,h);
00261 
00262     if (1<w && 1<h){
00263       dc.fillRectangle(x+1,y+1,w-3,1);
00264       dc.fillRectangle(x+1,y+1,1,h-3);
00265       dc.fillRectangle(x+1,y+h-2,w-2,1);
00266       dc.fillRectangle(x+w-2,y+1,1,h-2);
00267     }
00268   }
00269 }
00270 
00271 
00272 
00273 long ThemeTextField::onPaint(FXObject*,FXSelector,void* ptr) {
00274   FXEvent *ev=(FXEvent*)ptr;
00275   FXDCWindow dc(this,ev);
00276 
00277   // Set font
00278   dc.setFont(font);
00279 
00280   // Draw frame
00281   ::drawFrame(dc,0,0,width,height);
00282 
00283   // Gray background if disabled
00284   dc.setForeground(isEnabled() ? backColor : baseColor);
00285 
00286   // Draw background
00287   dc.fillRectangle(border,border,width-(border<<1),height-(border<<1));
00288 
00289   // Draw text, clipped against frame interior
00290   dc.setClipRectangle(border,border,width-(border<<1),height-(border<<1));
00291   drawTextRange(dc,0,contents.length());
00292   
00293   // Draw caret
00294   if (flags&FLAG_CARET){
00295     int xx=coord(cursor)-1;
00296     dc.setForeground(cursorColor);
00297     dc.fillRectangle(xx,padtop+border,1,height-padbottom-padtop-(border<<1));
00298     dc.fillRectangle(xx-2,padtop+border,5,1);
00299     dc.fillRectangle(xx-2,height-border-padbottom-1,5,1);
00300   }
00301   return 1;
00302 }
00303 
00304 
00305 
00306 struct ColorTheme {
00307   const FXchar* name;
00308   FXColor base;
00309   FXColor border;
00310   FXColor back;
00311   FXColor fore;
00312   FXColor selback;
00313   FXColor selfore;
00314   FXColor tipback;
00315   FXColor tipfore;
00316   FXColor menuback;
00317   FXColor menufore;
00318   };
00319 
00320 
00321 const ColorTheme ColorThemes[]={
00322         {"Redmond XP",FXRGB(238,238,230),FXRGB(  0,  0,  0),FXRGB(255,255,255),FXRGB(  0,  0,  0),FXRGB( 74,121,205),FXRGB(255,255,255),FXRGB(255,255,225),FXRGB(  0,  0,  0),FXRGB( 74,121,205),FXRGB(255,255,255)}
00323 };
00324 
00325 
00326 
00327 void init_theme(FXApp *app) {
00328   app->setBaseColor( ColorThemes[0].base );
00329   app->setBorderColor( ColorThemes[0].border );
00330   app->setBackColor( ColorThemes[0].back );
00331   app->setForeColor( ColorThemes[0].fore );
00332   app->setSelforeColor( ColorThemes[0].selfore );
00333   app->setSelbackColor( ColorThemes[0].selback );
00334   app->setTipforeColor( ColorThemes[0].tipfore );
00335   app->setTipbackColor( ColorThemes[0].tipback );
00336   app->setSelMenuTextColor( ColorThemes[0].menufore );
00337   app->setSelMenuBackColor( ColorThemes[0].menuback );
00338   // app->setHiliteColor(FXRGB(123,158,189));
00339 }
00340 
00341 
00342 
00343 
00344 FXDEFMAP(ThemeComboBox) ThemeComboBoxMap[]={
00345   FXMAPFUNC( SEL_PAINT, 0, ThemeComboBox::onPaint)
00346 };
00347 
00348 FXIMPLEMENT( ThemeComboBox, FXComboBox, ThemeComboBoxMap, ARRAYNUMBER(ThemeComboBoxMap) );
00349 
00350 ThemeComboBox::ThemeComboBox(FXComposite *p,FXint cols,FXObject* tgt,FXSelector sel,FXuint opts,
00351                              FXint x,FXint y,FXint w,FXint h,
00352                              FXint pl,FXint pr,FXint pt,FXint pb)
00353   : FXComboBox(p,cols, tgt, sel, opts,x,y,w,h, pl,pr,pt,pb)
00354 {
00355   delete button;
00356 
00357   button=new ThemeMenuButton(this,FXString::null, NULL, pane,
00358                              FRAME_RAISED|MENUBUTTON_DOWN|MENUBUTTON_ATTACH_RIGHT,
00359                              0,0,0,0, 0,0,0,0);
00360   button->setXOffset(border);
00361   button->setYOffset(border);
00362 }
00363 
00364 
00365 
00366 long ThemeComboBox::onPaint(FXObject*,FXSelector,void* ptr){
00367   FXEvent *ev=(FXEvent*)ptr;
00368   FXDCWindow dc(this,ev);
00369 
00370   dc.setForeground(backColor);
00371   dc.fillRectangle(ev->rect.x,ev->rect.y,ev->rect.w,ev->rect.h);
00372   drawFrame(dc,0,0,width,height);
00373   return 1;
00374 }
00375 
00376 
00377 
00378 
00379 
00380 FXDEFMAP(ThemeLabel) ThemeLabelMap[]={
00381         FXMAPFUNC( SEL_PAINT, 0, ThemeLabel::onPaint )
00382 };
00383 
00384 FXIMPLEMENT( ThemeLabel, FXLabel, ThemeLabelMap, ARRAYNUMBER( ThemeLabelMap ));
00385 
00386 ThemeLabel::ThemeLabel(FXComposite* p,const FXString& text,FXIcon* ic,FXuint opts,
00387                        FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb)
00388   : FXLabel( p, text, ic, opts, x, y, w, h, pl, pr, pt, pb )
00389 {
00390         
00391 }
00392 
00393 
00394 
00395 // Handle repaint
00396 long ThemeLabel::onPaint(FXObject*,FXSelector,void* ptr) {
00397   FXEvent   *ev=(FXEvent*)ptr;
00398   FXDCWindow dc(this,ev);
00399   FXint      tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy;
00400   dc.setForeground(backColor);
00401   dc.fillRectangle(0,0,width,height);
00402   if (!label.empty()){
00403     tw=labelWidth(label);
00404     th=labelHeight(label);
00405   }
00406   if (icon){
00407     iw=icon->getWidth();
00408     ih=icon->getHeight();
00409   }
00410   just_x(tx,ix,tw,iw);
00411   just_y(ty,iy,th,ih);
00412   if(icon) {
00413     if(isEnabled())
00414       dc.drawIcon(icon,ix,iy);
00415     else
00416       dc.drawIconSunken(icon,ix,iy);
00417   }
00418   if (!label.empty()){
00419     dc.setFont(font);
00420     if(isEnabled()){
00421       dc.setForeground(textColor);
00422       drawLabel(dc,label,hotoff,tx,ty,tw,th);
00423     }
00424     else {
00425       dc.setForeground(hiliteColor);
00426       drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th);
00427       dc.setForeground(shadowColor);
00428       drawLabel(dc,label,hotoff,tx,ty,tw,th);
00429     }
00430   }
00431   if (options & (FRAME_THICK|FRAME_RAISED|FRAME_SUNKEN)) {
00432     if( options & (FRAME_SUNKEN) )
00433       drawSunkenFrame(dc,0,0,width,height);
00434     else if( options & (FRAME_RAISED) )
00435       drawHighlightFrame(dc,0,0,width,height);
00436     else
00437       drawFrame(dc,0,0,width,height);
00438   }
00439 
00440   return 1;
00441 }
00442 
00443 
00444 
00445 
00446 FXDEFMAP(ThemeTabItem) ThemeTabItemMap[]={
00447 //      FXMAPFUNC( SEL_PAINT, 0, ThemeTabItem::onPaint )
00448 };
00449 
00450 FXIMPLEMENT( ThemeTabItem, FXTabItem, ThemeTabItemMap, ARRAYNUMBER( ThemeTabItemMap ));
00451 
00452 ThemeTabItem::ThemeTabItem(FXTabBar* p,const FXString& text,FXIcon* ic,FXuint opts,
00453                            FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb)
00454   : FXTabItem(p,text,ic,opts,x,y,w,h,pl,pr,pt,pb)
00455 {
00456   shadowColor = FXRGB(123,158,189);
00457   borderColor = FXRGB(123,158,189);
00458   hiliteColor = FXRGB(123,158,189);
00459 }
00460 
00461 
00462 
00463 
00464 ThemeVerticalFrame::ThemeVerticalFrame(FXComposite* p,FXuint opts,FXint x,FXint y,FXint w,FXint h,
00465                                        FXint pl,FXint pr,FXint pt,FXint pb,FXint hs,FXint vs)
00466 : FXVerticalFrame( p, opts, x, y, w, h, pl, pr, pt, pb, hs, vs )
00467 {
00468   setHiliteColor( FXRGB(123,158,189) );
00469 }
00470 
00471 
00472 ThemeHorizontalFrame::ThemeHorizontalFrame(FXComposite* p,FXuint opts,FXint x,FXint y,FXint w,FXint h,
00473                                            FXint pl,FXint pr,FXint pt,FXint pb,FXint hs,FXint vs)
00474 : FXHorizontalFrame( p, opts, x, y, w, h, pl, pr, pt, pb, hs, vs )
00475 {
00476   setHiliteColor( FXRGB(123,158,189) );
00477 }
00478 
00479 
00480 
00481 
00482 #define MENUBUTTONARROW_WIDTH  13
00483 #define MENUBUTTONARROW_HEIGHT  5
00484 
00485 FXDEFMAP(ThemeMenuButton) ThemeMenuButtonMap[]={
00486   FXMAPFUNC( SEL_PAINT, 0, ThemeMenuButton::onPaint)
00487 };
00488 
00489 FXIMPLEMENT( ThemeMenuButton, FXMenuButton, ThemeMenuButtonMap, ARRAYNUMBER(ThemeMenuButtonMap) );
00490 
00491 
00492 ThemeMenuButton::ThemeMenuButton(FXComposite* p,const FXString& text,
00493                                  FXIcon* ic,FXPopup* pup,FXuint opts,
00494                                  FXint x,FXint y,FXint w,FXint h,
00495                                  FXint pl,FXint pr,FXint pt,FXint pb )
00496   : FXMenuButton( p, text, ic, pup, opts, x, y, w, h,
00497                  pl, pr, pt, pb)
00498 {
00499 }
00500 
00501 
00502 
00503 // Handle repaint
00504 long ThemeMenuButton::onPaint(FXObject*,FXSelector,void* ptr) {
00505   FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy;
00506   FXEvent *ev=(FXEvent*)ptr;
00507   FXPoint points[6];
00508   FXDCWindow dc(this,ev);
00509   /*
00510   FXColor top         = FXRGB(0xfe,0xfd,0xfd);
00511   FXColor bottom      = FXRGB(0xdd,0xd7,0xce);
00512   FXColor shade       = FXRGB(0xdc,0xd9,0xd4);
00513   */
00514   FXColor top         = FXRGB(0xde,0xe7,0xff);
00515   FXColor bottom      = FXRGB(0xbd,0xcf,0xff);
00516   FXColor shade       = FXRGB(0xbd,0xcb,0xf7);
00517 
00518   FXColor buttoncolor = FXRGB(0x4a,0x61,0x84);
00519 
00520   // FXColor bordercolor = FXRGB(123,158,189);
00521   FXColor bordercolor = shade;
00522 
00523   FXPoint basebackground[4]={
00524     FXPoint(0,0),FXPoint(width-1,0),FXPoint(0,height-1),FXPoint(width-1,height-1)
00525   };
00526   FXPoint bordershade[16]={
00527     FXPoint(0,1),FXPoint(1,0),FXPoint(1,2),FXPoint(2,1),
00528     FXPoint(width-2,0),FXPoint(width-1,1),FXPoint(width-3,1),FXPoint(width-2,2),
00529     FXPoint(0,height-2),FXPoint(1,height-1),FXPoint(1,height-3),FXPoint(2,height-2),
00530     FXPoint(width-1,height-2),FXPoint(width-2,height-1),FXPoint(width-2,height-3),FXPoint(width-3,height-2)
00531   };
00532   FXPoint bordercorners[4]={
00533     FXPoint(1,1),FXPoint(1,height-2),FXPoint(width-2,1),FXPoint(width-2,height-2)
00534   };
00535 
00536 
00537   // Got a border at all?
00538   if (options&(FRAME_RAISED|FRAME_SUNKEN)){
00539 
00540     // Toolbar style
00541     if (options&MENUBUTTON_TOOLBAR){
00542 
00543       // Enabled and cursor inside, and not popped up
00544       if (isEnabled() && underCursor() && !state){
00545         dc.setForeground(backColor);
00546         dc.fillRectangle(border,border,width-border*2,height-border*2);
00547         if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height);
00548         else drawRaisedRectangle(dc,0,0,width,height);
00549       }
00550 
00551       // Enabled and popped up
00552       else if (isEnabled() && state){
00553         dc.setForeground(hiliteColor);
00554         dc.fillRectangle(border,border,width-border*2,height-border*2);
00555         if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height);
00556         else drawSunkenRectangle(dc,0,0,width,height);
00557       }
00558 
00559       // Disabled or unchecked or not under cursor
00560       else {
00561         dc.setForeground(backColor);
00562         dc.fillRectangle(0,0,width,height);
00563       }
00564     }
00565 
00566     // Normal style
00567     else {
00568       // Draw in up state if disabled or up
00569       if (!isEnabled() || !state){
00570         /*
00571          * dc.setForeground(backColor);
00572          dc.fillRectangle(border,border,width-border*2,height-border*2);
00573          if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height);
00574          else drawRaisedRectangle(dc,0,0,width,height);
00575          */
00577         dc.setForeground(baseColor);
00578         dc.drawPoints(basebackground,4);
00580         dc.setForeground(bordercolor);
00581         dc.drawRectangle(2,0,width-5,0);
00582         dc.drawRectangle(2,height-1,width-5,height-1);
00583         dc.drawRectangle(0,2,0,height-5);
00584         dc.drawRectangle(width-1,2,0,height-5);
00585         dc.drawPoints(bordercorners,4);
00586         dc.setForeground(shade);
00587         dc.drawPoints(bordershade,16);
00589         drawRectangle(dc,top,bottom,2,1,width-4,height-2);
00590         dc.setForeground(top);
00591         dc.drawRectangle(1,3,0,height-7);
00592         dc.setForeground(bottom);
00593         dc.drawRectangle(width-2,3,0,height-7);
00594       }
00595 
00596       // Draw sunken if enabled and either checked or pressed
00597       else {
00598         dc.setForeground(baseColor);
00599         dc.drawPoints(basebackground,4);
00601         dc.setForeground(bordercolor);
00602         dc.drawRectangle(2,0,width-5,0);
00603         dc.drawRectangle(2,height-1,width-5,height-1);
00604         dc.drawRectangle(0,2,0,height-5);
00605         dc.drawRectangle(width-1,2,0,height-5);
00606         dc.drawPoints(bordercorners,4);
00607         dc.setForeground(shade);
00608         dc.drawPoints(bordershade,16);
00609 
00610         dc.setForeground(FXRGB(0xdc,0xd4,0xc9));
00611         dc.fillRectangle(2,1,width-4,height-2);
00612       }
00613     }
00614   }
00615 
00616   // No borders
00617   else {
00618     if(isEnabled() && state){
00619       dc.setForeground(hiliteColor);
00620       dc.fillRectangle(0,0,width,height);
00621     }
00622     else{
00623       dc.setForeground(backColor);
00624       dc.fillRectangle(0,0,width,height);
00625     }
00626   }
00627 
00628   // Position text & icon
00629   if (!label.empty()){
00630     tw=labelWidth(label);
00631     th=labelHeight(label);
00632   }
00633 
00634   // Icon?
00635   if (icon){
00636     iw=icon->getWidth();
00637     ih=icon->getHeight();
00638   }
00639 
00640   // Arrows?
00641   else if(!(options&MENUBUTTON_NOARROWS)){
00642     if(options&MENUBUTTON_LEFT){
00643       ih=MENUBUTTONARROW_WIDTH;
00644       iw=MENUBUTTONARROW_HEIGHT;
00645     }
00646     else{
00647       iw=MENUBUTTONARROW_WIDTH;
00648       ih=MENUBUTTONARROW_HEIGHT;
00649     }
00650   }
00651 
00652   // Keep some room for the arrow!
00653   just_x(tx,ix,tw,iw);
00654   just_y(ty,iy,th,ih);
00655 
00656   // Move a bit when pressed
00657   if (state){
00658     ++tx; ++ty; ++ix; ++iy;
00659   }
00660 
00661   // Draw icon
00662   if (icon){
00663     if (isEnabled())
00664       dc.drawIcon(icon,ix,iy);
00665     else
00666       dc.drawIconSunken(icon,ix,iy);
00667   }
00668 
00669   // Draw arrows
00670   else if (!(options&MENUBUTTON_NOARROWS)){
00671 
00672     // Right arrow
00673     if ((options&MENUBUTTON_RIGHT)==MENUBUTTON_RIGHT){
00674       if (isEnabled())
00675         dc.setForeground(buttoncolor);
00676       else
00677         dc.setForeground(shadowColor);
00678       points[0].x=ix;
00679       points[0].y=iy;
00680       points[1].x=ix;
00681       points[1].y=iy+MENUBUTTONARROW_WIDTH-1;
00682       points[2].x=ix+MENUBUTTONARROW_HEIGHT;
00683       points[2].y=(FXshort)(iy+(MENUBUTTONARROW_WIDTH>>1));
00684       dc.fillPolygon(points,3);
00685     }
00686 
00687     // Left arrow
00688     else if (options&MENUBUTTON_LEFT){
00689       if (isEnabled())
00690         dc.setForeground(buttoncolor);
00691       else
00692         dc.setForeground(shadowColor);
00693       points[0].x=ix+MENUBUTTONARROW_HEIGHT;
00694       points[0].y=iy;
00695       points[1].x=ix+MENUBUTTONARROW_HEIGHT;
00696       points[1].y=iy+MENUBUTTONARROW_WIDTH-1;
00697       points[2].x=ix;
00698       points[2].y=(FXshort)(iy+(MENUBUTTONARROW_WIDTH>>1));
00699       dc.fillPolygon(points,3);
00700     }
00701 
00702     // Up arrow
00703     else if (options&MENUBUTTON_UP){
00704       if(isEnabled())
00705         dc.setForeground(buttoncolor);
00706       else
00707         dc.setForeground(shadowColor);
00708       points[0].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1));
00709       points[0].y=iy-1;
00710       points[1].x=ix;
00711       points[1].y=iy+MENUBUTTONARROW_HEIGHT;
00712       points[2].x=ix+MENUBUTTONARROW_WIDTH;
00713       points[2].y=iy+MENUBUTTONARROW_HEIGHT;
00714       dc.fillPolygon(points,3);
00715     }
00716 
00717     // Down arrow
00718     else {
00719       if(isEnabled())
00720         dc.setForeground(buttoncolor);
00721       else
00722         dc.setForeground(shadowColor);
00723       points[0].x=ix+1;
00724       points[0].y=iy;
00725       points[2].x=ix+MENUBUTTONARROW_WIDTH-1;
00726       points[2].y=iy;
00727       points[1].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1));
00728       points[1].y=iy+MENUBUTTONARROW_HEIGHT;
00729       points[3].x=ix+MENUBUTTONARROW_WIDTH-3;
00730       points[3].y=iy;
00731       points[4].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1));
00732       points[4].y=iy+MENUBUTTONARROW_HEIGHT-3;
00733       points[5].x=ix+3;
00734       points[5].y=iy;
00735       dc.fillConcavePolygon(points,6);
00736     }
00737   }
00738 
00739   // Draw text
00740   if (!label.empty()){
00741     dc.setFont(font);
00742     if(isEnabled()){
00743       dc.setForeground(textColor);
00744       drawLabel(dc,label,hotoff,tx,ty,tw,th);
00745     }
00746     else {
00747       dc.setForeground(hiliteColor);
00748       drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th);
00749       dc.setForeground(shadowColor);
00750       drawLabel(dc,label,hotoff,tx,ty,tw,th);
00751     }
00752   }
00753 
00754   // Draw focus
00755   if (hasFocus()){
00756     if (isEnabled()){
00757       dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2);
00758     }
00759   }
00760   return 1;
00761 }
00762 
00763 
00764 
00765 // Get default width
00766 FXint ThemeMenuButton::getDefaultWidth(){
00767   FXint tw=0,iw=0,s=0,w,pw;
00768 
00769   if (!label.empty()){
00770     tw=labelWidth(label); s=4;
00771   }
00772   if (!(options&MENUBUTTON_NOARROWS)){
00773     if (options&MENUBUTTON_LEFT)
00774       iw=MENUBUTTONARROW_HEIGHT;
00775     else
00776       iw=MENUBUTTONARROW_WIDTH;
00777   }
00778   if(icon)
00779     iw=icon->getWidth();
00780   if (!(options&(ICON_AFTER_TEXT|ICON_BEFORE_TEXT)))
00781     w=FXMAX(tw,iw);
00782   else
00783     w=tw+iw+s;
00784   w=padleft+padright+(border<<1)+w;
00785   if (!(options&MENUBUTTON_LEFT) &&
00786       (options&MENUBUTTON_ATTACH_RIGHT) &&
00787       (options&MENUBUTTON_ATTACH_CENTER)) {
00788     if (pane){
00789       pw=pane->getDefaultWidth();
00790       if(pw>w)
00791         w=pw;
00792     }
00793   }
00794   return w;
00795 }
00796 
00797 
00798 
00799 
00800 #if 0
00801 FXDEFMAP(ThemeHeaderItem) ThemeHeaderItemMap[]={
00802   FXMAPFUNC(SEL_PAINT, 0, ThemeHeaderItem::onPaint)
00803 };
00804 
00805 FXIMPLEMENT(ThemeHeaderItem, FXHeaderItem, ThemeHeaderItemMap, ARRAYNUMBER(ThemeHeaderItemMap));
00806 #endif
00807 
00808 
00809 ThemeHeaderItem::ThemeHeaderItem(const FXString& text, FXIcon* ic, FXint s, void* ptr)
00810   :FXHeaderItem(text, ic, s, ptr)
00811 {
00812 }
00813 
00814 
00815 
00816 void ThemeHeaderItem::draw(const FXHeader* header,FXDC& dc,FXint x,FXint y,FXint w,FXint h) {
00817   register FXint tx,ty,tw,th,ix,iy,iw,ih,s,ml,mr,mt,mb,beg,end,t,xx,yy,bb,aa,ax,ay;
00818   register FXFont *font=header->getFont();
00819   FXColor top         = FXRGB(0xfe,0xfd,0xfd);
00820   FXColor bottom      = FXRGB(0xdd,0xd7,0xce);
00821   FXColor shade       = FXRGB(0xdc,0xd9,0xd4);
00822 
00823   // Get border width and padding
00824   bb=header->getBorderWidth();
00825   ml=header->getPadLeft()+bb;
00826   mr=header->getPadRight()+bb;
00827   mt=header->getPadTop()+bb;
00828   mb=header->getPadBottom()+bb;
00829 
00830   dc.setForeground(shade);
00832   drawRectangle(dc,top, bottom, x+2, y+1, w-4, h-2);
00833 
00834   // Shrink by margins
00835   x+=ml; w-=ml+mr;
00836   y+=mt; h-=mt+mb;
00837 
00838   // Initial clip rectangle
00839   dc.setClipRectangle(x,y,w,h);
00840 
00841   dc.setForeground(header->getTextColor());
00842   // Text width and height
00843   tw=th=iw=ih=beg=s=0;
00844   do {
00845     end=beg;
00846     while(end<label.length() && label[end]!='\n') end++;
00847     if((t=font->getTextWidth(&label[beg],end-beg))>tw) tw=t;
00848     th+=font->getFontHeight();
00849     beg=end+1;
00850   }
00851   while(end<label.length());
00852 
00853   // Icon size
00854   if(icon){
00855     iw=icon->getWidth();
00856     ih=icon->getHeight();
00857   }
00858 
00859   // Icon-text spacing
00860   if(iw && tw)
00861     s=ICON_SPACING;
00862 
00863   // Draw arrows
00864   if (state&(ARROW_UP|ARROW_DOWN)){
00865     aa=(font->getFontHeight()-5)|1;
00866     ay=y+(h-aa)/2;
00867     ax=x+w-aa-2;
00868     if(state&ARROW_UP) {
00869       dc.setForeground(header->getHiliteColor());
00870       dc.drawLine(ax+aa/2,ay,ax+aa-1,ay+aa);
00871       dc.drawLine(ax,ay+aa,ax+aa,ay+aa);
00872       dc.setForeground(header->getShadowColor());
00873       dc.drawLine(ax+aa/2,ay,ax,ay+aa);
00874     }
00875     else {
00876       dc.setForeground(header->getHiliteColor());
00877       dc.drawLine(ax+aa/2,ay+aa,ax+aa-1,ay);
00878       dc.setForeground(header->getShadowColor());
00879       dc.drawLine(ax+aa/2,ay+aa,ax,ay);
00880       dc.drawLine(ax,ay,ax+aa,ay);
00881     }
00882     w-=aa+4;
00883     dc.setClipRectangle(x,y,w,h);
00884   }
00885 
00886   // Fix x coordinate
00887   if (state&LEFT){
00888     if(state&BEFORE){
00889       ix=x; tx=ix+iw+s;
00890     }
00891     else if (state&AFTER){
00892       tx=x; ix=tx+tw+s;
00893     }
00894     else {
00895       ix=x; tx=x;
00896     }
00897   }
00898   else if(state&RIGHT){
00899     if(state&BEFORE){
00900       tx=x+w-tw;
00901       ix=tx-iw-s;
00902     }
00903     else if (state&AFTER){
00904       ix=x+w-iw;
00905       tx=ix-tw-s;
00906     }
00907     else {
00908       ix=x+w-iw; tx=x+w-tw;
00909     }
00910   }
00911   else{
00912     if (state&BEFORE){
00913       ix=x+(w-tw-iw-s)/2;
00914       tx=ix+iw+s;
00915     }
00916     else if (state&AFTER){
00917       tx=x+(w-tw-iw-s)/2;
00918       ix=tx+tw+s;
00919     }
00920     else{
00921       ix=x+(w-iw)/2;
00922       tx=x+(w-tw)/2;
00923     }
00924   }
00925 
00926   // Fix y coordinate
00927   if(state&TOP){
00928     if (state&ABOVE){
00929       iy=y;
00930       ty=iy+ih;
00931     }
00932     else if (state&BELOW){
00933       ty=y;
00934       iy=ty+th;
00935     }
00936     else {
00937       iy=y;
00938       ty=y;
00939     }
00940   }
00941   else if(state&BOTTOM){
00942     if (state&ABOVE){
00943       ty=y+h-th;
00944       iy=ty-ih;
00945     }
00946     else if (state&BELOW){
00947       iy=y+h-ih;
00948       ty=iy-th;
00949     }
00950     else{
00951       iy=y+h-ih;
00952       ty=y+h-th;
00953     }
00954   }
00955   else {
00956     if (state&ABOVE){
00957       iy=y+(h-th-ih)/2;
00958       ty=iy+ih;
00959     }
00960     else if (state&BELOW){
00961       ty=y+(h-th-ih)/2;
00962       iy=ty+th;
00963     }
00964     else {
00965       iy=y+(h-ih)/2;
00966       ty=y+(h-th)/2;
00967     }
00968   }
00969 
00970   // Offset a bit when pressed
00971   if (state&PRESSED){
00972     tx++;
00973     ty++;
00974     ix++;
00975     iy++;
00976   }
00977 
00978   // Paint icon
00979   if (icon){
00980     dc.drawIcon(icon,ix,iy);
00981   }
00982 
00983   // Text color
00984   dc.setForeground(header->getTextColor());
00985 
00986   // Draw text
00987   yy=ty+font->getFontAscent();
00988   beg=0;
00989   do {
00990     end=beg;
00991     while(end<label.length() && label[end]!='\n')
00992       end++;
00993     if (state&LEFT)
00994       xx=tx;
00995     else if(state&RIGHT)
00996       xx=tx+tw-font->getTextWidth(&label[beg],end-beg);
00997     else
00998       xx=tx+(tw-font->getTextWidth(&label[beg],end-beg))/2;
00999     dc.drawText(xx,yy,&label[beg],end-beg);
01000     yy+=font->getFontHeight();
01001     beg=end+1;
01002   }
01003   while(end<label.length());
01004 
01005   // Restore original clip path
01006   dc.clearClipRectangle();
01007 }
01008 
01009 
01010 
01011 
01012 
01013