gwenhywfar  5.10.1
theme.cpp
Go to the documentation of this file.
1 /* These widgets have initially been created by Martin Oberzalek who gave them into
2  * the public domain via an email to the mailing list foxgui-users on 17th of June, 2010
3  * ("here the source. Free to use for alll.").
4  * I (Martin Preuss) adapted them to be usable with FOX 1.6 and also added some widgets of
5  * my own (for now: ThemeHeaderItem).
6  */
7 
8 #ifdef HAVE_CONFIG_H
9 # include <config.h>
10 #endif
11 
12 
13 #include "theme.h"
14 
15 #define ICON_SPACING 4
16 
17 
18 // Draw rectangle
19 static void drawRectangle(FXDC& dc,FXColor lower,FXColor upper,FXint x,FXint y,FXint w,FXint h) {
20  register FXint rr,gg,bb,dr,dg,db,r1,g1,b1,r2,g2,b2,yl,yh,yy,dy,n,t;
21  const FXint MAXSTEPS=128;
22 
23  if(0<w && 0<h) {
24  dc.setStipple(STIPPLE_NONE);
25  dc.setFillStyle(FILL_SOLID);
26 
27  r1=FXREDVAL(lower);
28  r2=FXREDVAL(upper);
29  dr=r2-r1;
30  g1=FXGREENVAL(lower);
31  g2=FXGREENVAL(upper);
32  dg=g2-g1;
33  b1=FXBLUEVAL(lower);
34  b2=FXBLUEVAL(upper);
35  db=b2-b1;
36 
37  n=FXABS(dr);
38  if((t=FXABS(dg))>n) n=t;
39  if((t=FXABS(db))>n) n=t;
40  n++;
41  if(n>h) n=h;
42  if(n>MAXSTEPS) n=MAXSTEPS;
43  rr=(r1<<16)+32767;
44  gg=(g1<<16)+32767;
45  bb=(b1<<16)+32767;
46  yy=32767;
47 
48  dr=(dr<<16)/n;
49  dg=(dg<<16)/n;
50  db=(db<<16)/n;
51  dy=(h<<16)/n;
52 
53  do {
54  yl=yy>>16;
55  yy+=dy;
56  yh=yy>>16;
57  dc.setForeground(FXRGB(rr>>16,gg>>16,bb>>16));
58  dc.fillRectangle(x,y+yl,w,yh-yl);
59  rr+=dr;
60  gg+=dg;
61  bb+=db;
62  }
63  while(yh<h);
64  }
65 }
66 
67 
68 
69 
70 FXDEFMAP(ThemeButton) ThemeButtonMap[]= {
71  FXMAPFUNC( SEL_PAINT, 0, ThemeButton::onPaint)
72 };
73 
74 FXIMPLEMENT( ThemeButton, FXButton, ThemeButtonMap, ARRAYNUMBER(ThemeButtonMap) );
75 
76 
77 ThemeButton::ThemeButton(FXComposite* p, const FXString& text, FXIcon* ic,
78  FXObject* tgt, FXSelector sel, FXuint opts,
79  FXint x, FXint y, FXint w, FXint h,
80  FXint pl, FXint pr, FXint pt, FXint pb)
81  : FXButton( p, text, ic, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb )
82 {}
83 
84 // Handle repaint
85 long ThemeButton::onPaint(FXObject*,FXSelector,void* ptr) {
86  FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy;
87  FXEvent*ev=(FXEvent*)ptr;
88  FXDCWindow dc(this,ev);
89 
90 
91  FXColor top = FXRGB(0xfe,0xfd,0xfd);
92  FXColor bottom = FXRGB(0xdd,0xd7,0xce);
93  FXColor shade = FXRGB(0xdc,0xd9,0xd4);
94 
95 // FXColor bordercolor = FXRGB(0x78,0x70,0x63);
96 
97  FXColor bordercolor = FXRGB(123,158,189);
98 
99  /*
100  FXPoint borderbackground[12]={FXPoint(0,0),FXPoint(0,1),FXPoint(1,0),
101  FXPoint(width-1,0),FXPoint(width-2,0),FXPoint(width-1,1),
102  FXPoint(0,height-1),FXPoint(0,height-2),FXPoint(1,height-1),
103  FXPoint(width-1,height-1),FXPoint(width-1,height-2),FXPoint(width-2,height-1)};
104  */
105  FXPoint basebackground[4]= {FXPoint(0,0),FXPoint(width-1,0),FXPoint(0,height-1),FXPoint(width-1,height-1)};
106 
107  FXPoint bordershade[16]= {
108  FXPoint(0,1),FXPoint(1,0),FXPoint(1,2),FXPoint(2,1),
109  FXPoint(width-2,0),FXPoint(width-1,1),FXPoint(width-3,1),FXPoint(width-2,2),
110  FXPoint(0,height-2),FXPoint(1,height-1),FXPoint(1,height-3),FXPoint(2,height-2),
111  FXPoint(width-1,height-2),FXPoint(width-2,height-1),FXPoint(width-2,height-3),FXPoint(width-3,height-2)
112  };
113  FXPoint bordercorners[4]= {
114  FXPoint(1,1),FXPoint(1,height-2),FXPoint(width-2,1),FXPoint(width-2,height-2)
115  };
116 
117 
118  if (options&BUTTON_TOOLBAR && !underCursor()) {
119  dc.setForeground(baseColor);
120  dc.fillRectangle(0,0,width,height);
121  }
122  else if (state==STATE_UP && ((options&BUTTON_TOOLBAR)==0 || (options&BUTTON_TOOLBAR && underCursor()))) {
124  dc.setForeground(baseColor);
125  dc.drawPoints(basebackground,4);
127  dc.setForeground(bordercolor);
128  dc.drawRectangle(2,0,width-5,0);
129  dc.drawRectangle(2,height-1,width-5,height-1);
130  dc.drawRectangle(0,2,0,height-5);
131  dc.drawRectangle(width-1,2,width-1,height-5);
132  dc.drawPoints(bordercorners,4);
133  dc.setForeground(shade);
134  dc.drawPoints(bordershade,16);
136  drawRectangle(dc,top,bottom,2,1,width-4,height-2);
137  dc.setForeground(top);
138  dc.drawRectangle(1,3,0,height-7);
139  dc.setForeground(bottom);
140  dc.drawRectangle(width-2,3,0,height-7);
141  }
142  else {
144  dc.setForeground(baseColor);
145  dc.drawPoints(basebackground,4);
147  dc.setForeground(bordercolor);
148  dc.drawRectangle(2,0,width-5,0);
149  dc.drawRectangle(2,height-1,width-5,height-1);
150  dc.drawRectangle(0,2,0,height-5);
151  dc.drawRectangle(width-1,2,width-1,height-5);
152  dc.drawPoints(bordercorners,4);
153  dc.setForeground(shade);
154  dc.drawPoints(bordershade,16);
155 
156  dc.setForeground(FXRGB(0xdc,0xd4,0xc9));
157  dc.fillRectangle(2,1,width-4,height-2);
158  }
159 
160  // Place text & icon
161  if(!label.empty()) {
162  tw=labelWidth(label);
163  th=labelHeight(label);
164  }
165  if(icon) {
166  iw=icon->getWidth();
167  ih=icon->getHeight();
168  }
169 
170  just_x(tx,ix,tw,iw);
171  just_y(ty,iy,th,ih);
172 
173  // Shift a bit when pressed
174  if (state && (options&(FRAME_RAISED|FRAME_SUNKEN))) {
175  ++tx;
176  ++ty;
177  ++ix;
178  ++iy;
179  }
180 
181  // Draw enabled state
182  if(isEnabled()) {
183  if(icon) {
184  dc.drawIcon(icon,ix,iy);
185  }
186  if(!label.empty()) {
187  dc.setFont(font);
188  dc.setForeground(textColor);
189  drawLabel(dc,label,hotoff,tx,ty,tw,th);
190  }
191  if(hasFocus()) {
192  dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2);
193  }
194  }
195 
196  // Draw grayed-out state
197  else {
198  if (icon) {
199  dc.drawIconSunken(icon,ix,iy);
200  }
201  if(!label.empty()) {
202  dc.setFont(font);
203  dc.setForeground(hiliteColor);
204  drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th);
205  dc.setForeground(shadowColor);
206  drawLabel(dc,label,hotoff,tx,ty,tw,th);
207  }
208  }
209  return 1;
210 }
211 
212 
213 
214 
215 FXDEFMAP(ThemeTextField) ThemeTextFieldMap[]= {
216  FXMAPFUNC( SEL_PAINT, 0, ThemeTextField::onPaint)
217 };
218 
219 FXIMPLEMENT( ThemeTextField, FXTextField, ThemeTextFieldMap, ARRAYNUMBER(ThemeTextFieldMap) );
220 
221 ThemeTextField::ThemeTextField(FXComposite* p,FXint ncols,FXObject* tgt,FXSelector sel,
222  FXuint opts,FXint x,FXint y,FXint w,FXint h,
223  FXint pl,FXint pr,FXint pt,FXint pb)
224  : FXTextField( p, ncols, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb ) {
225 
226 }
227 
228 static void drawFrame(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h) {
229  if(0<w && 0<h) {
230  dc.setForeground(FXRGB(123,158,189));
231  dc.fillRectangle(x,y,w,1);
232  dc.fillRectangle(x,y,1,h);
233  // dc.setForeground(hiliteColor);
234  dc.fillRectangle(x,y+h-1,w,1);
235  dc.fillRectangle(x+w-1,y,1,h);
236  }
237 }
238 
239 
240 
241 
242 static void drawSunkenFrame(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h) {
243  if(0<w && 0<h) {
244  dc.setForeground(FXRGB(255,158,100));
245  dc.fillRectangle(x,y,w,1);
246  dc.fillRectangle(x,y,1,h);
247  // dc.setForeground(hiliteColor);
248  dc.fillRectangle(x,y+h-1,w,1);
249  dc.fillRectangle(x+w-1,y,1,h);
250 
251  if(1<w && 1<h) {
252  dc.fillRectangle(x+1,y+1,w-3,1);
253  dc.fillRectangle(x+1,y+1,1,h-3);
254  dc.fillRectangle(x+1,y+h-2,w-2,1);
255  dc.fillRectangle(x+w-2,y+1,1,h-2);
256  }
257  }
258 }
259 
260 
261 
262 static void drawHighlightFrame(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h) {
263  if (0<w && 0<h) {
264  dc.setForeground(FXRGB(123,158,255));
265  dc.fillRectangle(x,y,w,1);
266  dc.fillRectangle(x,y,1,h);
267  // dc.setForeground(hiliteColor);
268  dc.fillRectangle(x,y+h-1,w,1);
269  dc.fillRectangle(x+w-1,y,1,h);
270 
271  if (1<w && 1<h) {
272  dc.fillRectangle(x+1,y+1,w-3,1);
273  dc.fillRectangle(x+1,y+1,1,h-3);
274  dc.fillRectangle(x+1,y+h-2,w-2,1);
275  dc.fillRectangle(x+w-2,y+1,1,h-2);
276  }
277  }
278 }
279 
280 
281 
282 long ThemeTextField::onPaint(FXObject*,FXSelector,void* ptr) {
283  FXEvent *ev=(FXEvent*)ptr;
284  FXDCWindow dc(this,ev);
285 
286  // Set font
287  dc.setFont(font);
288 
289  // Draw frame
290  ::drawFrame(dc,0,0,width,height);
291 
292  // Gray background if disabled
293  dc.setForeground(isEnabled() ? backColor : baseColor);
294 
295  // Draw background
296  dc.fillRectangle(border,border,width-(border<<1),height-(border<<1));
297 
298  // Draw text, clipped against frame interior
299  dc.setClipRectangle(border,border,width-(border<<1),height-(border<<1));
300  drawTextRange(dc,0,contents.length());
301 
302  // Draw caret
303  if (flags&FLAG_CARET) {
304  int xx=coord(cursor)-1;
305  dc.setForeground(cursorColor);
306  dc.fillRectangle(xx,padtop+border,1,height-padbottom-padtop-(border<<1));
307  dc.fillRectangle(xx-2,padtop+border,5,1);
308  dc.fillRectangle(xx-2,height-border-padbottom-1,5,1);
309  }
310  return 1;
311 }
312 
313 
314 
315 struct ColorTheme {
316  const FXchar* name;
317  FXColor base;
318  FXColor border;
319  FXColor back;
320  FXColor fore;
321  FXColor selback;
322  FXColor selfore;
323  FXColor tipback;
324  FXColor tipfore;
325  FXColor menuback;
326  FXColor menufore;
327 };
328 
329 
331  {"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)}
332 };
333 
334 
335 
336 void init_theme(FXApp *app) {
337  app->setBaseColor( ColorThemes[0].base );
338  app->setBorderColor( ColorThemes[0].border );
339  app->setBackColor( ColorThemes[0].back );
340  app->setForeColor( ColorThemes[0].fore );
341  app->setSelforeColor( ColorThemes[0].selfore );
342  app->setSelbackColor( ColorThemes[0].selback );
343  app->setTipforeColor( ColorThemes[0].tipfore );
344  app->setTipbackColor( ColorThemes[0].tipback );
345  app->setSelMenuTextColor( ColorThemes[0].menufore );
346  app->setSelMenuBackColor( ColorThemes[0].menuback );
347  // app->setHiliteColor(FXRGB(123,158,189));
348 }
349 
350 
351 
352 
353 FXDEFMAP(ThemeComboBox) ThemeComboBoxMap[]= {
354  FXMAPFUNC( SEL_PAINT, 0, ThemeComboBox::onPaint)
355 };
356 
357 FXIMPLEMENT( ThemeComboBox, FXComboBox, ThemeComboBoxMap, ARRAYNUMBER(ThemeComboBoxMap) );
358 
359 ThemeComboBox::ThemeComboBox(FXComposite *p,FXint cols,FXObject* tgt,FXSelector sel,FXuint opts,
360  FXint x,FXint y,FXint w,FXint h,
361  FXint pl,FXint pr,FXint pt,FXint pb)
362  : FXComboBox(p,cols, tgt, sel, opts,x,y,w,h, pl,pr,pt,pb) {
363  delete button;
364 
365  button=new ThemeMenuButton(this,FXString::null, NULL, pane,
366  FRAME_RAISED|MENUBUTTON_DOWN|MENUBUTTON_ATTACH_RIGHT,
367  0,0,0,0, 0,0,0,0);
368  button->setXOffset(border);
369  button->setYOffset(border);
370 }
371 
372 
373 
374 long ThemeComboBox::onPaint(FXObject*,FXSelector,void* ptr) {
375  FXEvent *ev=(FXEvent*)ptr;
376  FXDCWindow dc(this,ev);
377 
378  dc.setForeground(backColor);
379  dc.fillRectangle(ev->rect.x,ev->rect.y,ev->rect.w,ev->rect.h);
380  drawFrame(dc,0,0,width,height);
381  return 1;
382 }
383 
384 
385 
386 
387 
388 FXDEFMAP(ThemeLabel) ThemeLabelMap[]= {
389  FXMAPFUNC( SEL_PAINT, 0, ThemeLabel::onPaint )
390 };
391 
392 FXIMPLEMENT( ThemeLabel, FXLabel, ThemeLabelMap, ARRAYNUMBER( ThemeLabelMap ));
393 
394 ThemeLabel::ThemeLabel(FXComposite* p,const FXString& text,FXIcon* ic,FXuint opts,
395  FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb)
396  : FXLabel( p, text, ic, opts, x, y, w, h, pl, pr, pt, pb ) {
397 
398 }
399 
400 
401 
402 // Handle repaint
403 long ThemeLabel::onPaint(FXObject*,FXSelector,void* ptr) {
404  FXEvent *ev=(FXEvent*)ptr;
405  FXDCWindow dc(this,ev);
406  FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy;
407  dc.setForeground(backColor);
408  dc.fillRectangle(0,0,width,height);
409  if (!label.empty()) {
410  tw=labelWidth(label);
411  th=labelHeight(label);
412  }
413  if (icon) {
414  iw=icon->getWidth();
415  ih=icon->getHeight();
416  }
417  just_x(tx,ix,tw,iw);
418  just_y(ty,iy,th,ih);
419  if(icon) {
420  if(isEnabled())
421  dc.drawIcon(icon,ix,iy);
422  else
423  dc.drawIconSunken(icon,ix,iy);
424  }
425  if (!label.empty()) {
426  dc.setFont(font);
427  if(isEnabled()) {
428  dc.setForeground(textColor);
429  drawLabel(dc,label,hotoff,tx,ty,tw,th);
430  }
431  else {
432  dc.setForeground(hiliteColor);
433  drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th);
434  dc.setForeground(shadowColor);
435  drawLabel(dc,label,hotoff,tx,ty,tw,th);
436  }
437  }
438  if (options & (FRAME_THICK|FRAME_RAISED|FRAME_SUNKEN)) {
439  if( options & (FRAME_SUNKEN) )
440  drawSunkenFrame(dc,0,0,width,height);
441  else if( options & (FRAME_RAISED) )
442  drawHighlightFrame(dc,0,0,width,height);
443  else
444  drawFrame(dc,0,0,width,height);
445  }
446 
447  return 1;
448 }
449 
450 
451 
452 
453 FXDEFMAP(ThemeTabItem) ThemeTabItemMap[]= {
454 // FXMAPFUNC( SEL_PAINT, 0, ThemeTabItem::onPaint )
455 };
456 
457 FXIMPLEMENT( ThemeTabItem, FXTabItem, ThemeTabItemMap, ARRAYNUMBER( ThemeTabItemMap ));
458 
459 ThemeTabItem::ThemeTabItem(FXTabBar* p,const FXString& text,FXIcon* ic,FXuint opts,
460  FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb)
461  : FXTabItem(p,text,ic,opts,x,y,w,h,pl,pr,pt,pb) {
462  shadowColor = FXRGB(123,158,189);
463  borderColor = FXRGB(123,158,189);
464  hiliteColor = FXRGB(123,158,189);
465 }
466 
467 
468 
469 
470 ThemeVerticalFrame::ThemeVerticalFrame(FXComposite* p,FXuint opts,FXint x,FXint y,FXint w,FXint h,
471  FXint pl,FXint pr,FXint pt,FXint pb,FXint hs,FXint vs)
472  : FXVerticalFrame( p, opts, x, y, w, h, pl, pr, pt, pb, hs, vs ) {
473  setHiliteColor( FXRGB(123,158,189) );
474 }
475 
476 
477 ThemeHorizontalFrame::ThemeHorizontalFrame(FXComposite* p,FXuint opts,FXint x,FXint y,FXint w,FXint h,
478  FXint pl,FXint pr,FXint pt,FXint pb,FXint hs,FXint vs)
479  : FXHorizontalFrame( p, opts, x, y, w, h, pl, pr, pt, pb, hs, vs ) {
480  setHiliteColor( FXRGB(123,158,189) );
481 }
482 
483 
484 
485 
486 #define MENUBUTTONARROW_WIDTH 13
487 #define MENUBUTTONARROW_HEIGHT 5
488 
489 FXDEFMAP(ThemeMenuButton) ThemeMenuButtonMap[]= {
490  FXMAPFUNC( SEL_PAINT, 0, ThemeMenuButton::onPaint)
491 };
492 
493 FXIMPLEMENT( ThemeMenuButton, FXMenuButton, ThemeMenuButtonMap, ARRAYNUMBER(ThemeMenuButtonMap) );
494 
495 
496 ThemeMenuButton::ThemeMenuButton(FXComposite* p,const FXString& text,
497  FXIcon* ic,FXPopup* pup,FXuint opts,
498  FXint x,FXint y,FXint w,FXint h,
499  FXint pl,FXint pr,FXint pt,FXint pb )
500  : FXMenuButton( p, text, ic, pup, opts, x, y, w, h,
501  pl, pr, pt, pb) {
502 }
503 
504 
505 
506 // Handle repaint
507 long ThemeMenuButton::onPaint(FXObject*,FXSelector,void* ptr) {
508  FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy;
509  FXEvent *ev=(FXEvent*)ptr;
510  FXPoint points[6];
511  FXDCWindow dc(this,ev);
512  /*
513  FXColor top = FXRGB(0xfe,0xfd,0xfd);
514  FXColor bottom = FXRGB(0xdd,0xd7,0xce);
515  FXColor shade = FXRGB(0xdc,0xd9,0xd4);
516  */
517  FXColor top = FXRGB(0xde,0xe7,0xff);
518  FXColor bottom = FXRGB(0xbd,0xcf,0xff);
519  FXColor shade = FXRGB(0xbd,0xcb,0xf7);
520 
521  FXColor buttoncolor = FXRGB(0x4a,0x61,0x84);
522 
523  // FXColor bordercolor = FXRGB(123,158,189);
524  FXColor bordercolor = shade;
525 
526  FXPoint basebackground[4]= {
527  FXPoint(0,0),FXPoint(width-1,0),FXPoint(0,height-1),FXPoint(width-1,height-1)
528  };
529  FXPoint bordershade[16]= {
530  FXPoint(0,1),FXPoint(1,0),FXPoint(1,2),FXPoint(2,1),
531  FXPoint(width-2,0),FXPoint(width-1,1),FXPoint(width-3,1),FXPoint(width-2,2),
532  FXPoint(0,height-2),FXPoint(1,height-1),FXPoint(1,height-3),FXPoint(2,height-2),
533  FXPoint(width-1,height-2),FXPoint(width-2,height-1),FXPoint(width-2,height-3),FXPoint(width-3,height-2)
534  };
535  FXPoint bordercorners[4]= {
536  FXPoint(1,1),FXPoint(1,height-2),FXPoint(width-2,1),FXPoint(width-2,height-2)
537  };
538 
539 
540  // Got a border at all?
541  if (options&(FRAME_RAISED|FRAME_SUNKEN)) {
542 
543  // Toolbar style
544  if (options&MENUBUTTON_TOOLBAR) {
545 
546  // Enabled and cursor inside, and not popped up
547  if (isEnabled() && underCursor() && !state) {
548  dc.setForeground(backColor);
549  dc.fillRectangle(border,border,width-border*2,height-border*2);
550  if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height);
551  else drawRaisedRectangle(dc,0,0,width,height);
552  }
553 
554  // Enabled and popped up
555  else if (isEnabled() && state) {
556  dc.setForeground(hiliteColor);
557  dc.fillRectangle(border,border,width-border*2,height-border*2);
558  if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height);
559  else drawSunkenRectangle(dc,0,0,width,height);
560  }
561 
562  // Disabled or unchecked or not under cursor
563  else {
564  dc.setForeground(backColor);
565  dc.fillRectangle(0,0,width,height);
566  }
567  }
568 
569  // Normal style
570  else {
571  // Draw in up state if disabled or up
572  if (!isEnabled() || !state) {
573  /*
574  * dc.setForeground(backColor);
575  dc.fillRectangle(border,border,width-border*2,height-border*2);
576  if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height);
577  else drawRaisedRectangle(dc,0,0,width,height);
578  */
580  dc.setForeground(baseColor);
581  dc.drawPoints(basebackground,4);
583  dc.setForeground(bordercolor);
584  dc.drawRectangle(2,0,width-5,0);
585  dc.drawRectangle(2,height-1,width-5,height-1);
586  dc.drawRectangle(0,2,0,height-5);
587  dc.drawRectangle(width-1,2,0,height-5);
588  dc.drawPoints(bordercorners,4);
589  dc.setForeground(shade);
590  dc.drawPoints(bordershade,16);
592  drawRectangle(dc,top,bottom,2,1,width-4,height-2);
593  dc.setForeground(top);
594  dc.drawRectangle(1,3,0,height-7);
595  dc.setForeground(bottom);
596  dc.drawRectangle(width-2,3,0,height-7);
597  }
598 
599  // Draw sunken if enabled and either checked or pressed
600  else {
601  dc.setForeground(baseColor);
602  dc.drawPoints(basebackground,4);
604  dc.setForeground(bordercolor);
605  dc.drawRectangle(2,0,width-5,0);
606  dc.drawRectangle(2,height-1,width-5,height-1);
607  dc.drawRectangle(0,2,0,height-5);
608  dc.drawRectangle(width-1,2,0,height-5);
609  dc.drawPoints(bordercorners,4);
610  dc.setForeground(shade);
611  dc.drawPoints(bordershade,16);
612 
613  dc.setForeground(FXRGB(0xdc,0xd4,0xc9));
614  dc.fillRectangle(2,1,width-4,height-2);
615  }
616  }
617  }
618 
619  // No borders
620  else {
621  if(isEnabled() && state) {
622  dc.setForeground(hiliteColor);
623  dc.fillRectangle(0,0,width,height);
624  }
625  else {
626  dc.setForeground(backColor);
627  dc.fillRectangle(0,0,width,height);
628  }
629  }
630 
631  // Position text & icon
632  if (!label.empty()) {
633  tw=labelWidth(label);
634  th=labelHeight(label);
635  }
636 
637  // Icon?
638  if (icon) {
639  iw=icon->getWidth();
640  ih=icon->getHeight();
641  }
642 
643  // Arrows?
644  else if(!(options&MENUBUTTON_NOARROWS)) {
645  if(options&MENUBUTTON_LEFT) {
648  }
649  else {
652  }
653  }
654 
655  // Keep some room for the arrow!
656  just_x(tx,ix,tw,iw);
657  just_y(ty,iy,th,ih);
658 
659  // Move a bit when pressed
660  if (state) {
661  ++tx;
662  ++ty;
663  ++ix;
664  ++iy;
665  }
666 
667  // Draw icon
668  if (icon) {
669  if (isEnabled())
670  dc.drawIcon(icon,ix,iy);
671  else
672  dc.drawIconSunken(icon,ix,iy);
673  }
674 
675  // Draw arrows
676  else if (!(options&MENUBUTTON_NOARROWS)) {
677 
678  // Right arrow
679  if ((options&MENUBUTTON_RIGHT)==MENUBUTTON_RIGHT) {
680  if (isEnabled())
681  dc.setForeground(buttoncolor);
682  else
683  dc.setForeground(shadowColor);
684  points[0].x=ix;
685  points[0].y=iy;
686  points[1].x=ix;
687  points[1].y=iy+MENUBUTTONARROW_WIDTH-1;
688  points[2].x=ix+MENUBUTTONARROW_HEIGHT;
689  points[2].y=(FXshort)(iy+(MENUBUTTONARROW_WIDTH>>1));
690  dc.fillPolygon(points,3);
691  }
692 
693  // Left arrow
694  else if (options&MENUBUTTON_LEFT) {
695  if (isEnabled())
696  dc.setForeground(buttoncolor);
697  else
698  dc.setForeground(shadowColor);
699  points[0].x=ix+MENUBUTTONARROW_HEIGHT;
700  points[0].y=iy;
701  points[1].x=ix+MENUBUTTONARROW_HEIGHT;
702  points[1].y=iy+MENUBUTTONARROW_WIDTH-1;
703  points[2].x=ix;
704  points[2].y=(FXshort)(iy+(MENUBUTTONARROW_WIDTH>>1));
705  dc.fillPolygon(points,3);
706  }
707 
708  // Up arrow
709  else if (options&MENUBUTTON_UP) {
710  if(isEnabled())
711  dc.setForeground(buttoncolor);
712  else
713  dc.setForeground(shadowColor);
714  points[0].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1));
715  points[0].y=iy-1;
716  points[1].x=ix;
717  points[1].y=iy+MENUBUTTONARROW_HEIGHT;
718  points[2].x=ix+MENUBUTTONARROW_WIDTH;
719  points[2].y=iy+MENUBUTTONARROW_HEIGHT;
720  dc.fillPolygon(points,3);
721  }
722 
723  // Down arrow
724  else {
725  if(isEnabled())
726  dc.setForeground(buttoncolor);
727  else
728  dc.setForeground(shadowColor);
729  points[0].x=ix+1;
730  points[0].y=iy;
731  points[2].x=ix+MENUBUTTONARROW_WIDTH-1;
732  points[2].y=iy;
733  points[1].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1));
734  points[1].y=iy+MENUBUTTONARROW_HEIGHT;
735  points[3].x=ix+MENUBUTTONARROW_WIDTH-3;
736  points[3].y=iy;
737  points[4].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1));
738  points[4].y=iy+MENUBUTTONARROW_HEIGHT-3;
739  points[5].x=ix+3;
740  points[5].y=iy;
741  dc.fillConcavePolygon(points,6);
742  }
743  }
744 
745  // Draw text
746  if (!label.empty()) {
747  dc.setFont(font);
748  if(isEnabled()) {
749  dc.setForeground(textColor);
750  drawLabel(dc,label,hotoff,tx,ty,tw,th);
751  }
752  else {
753  dc.setForeground(hiliteColor);
754  drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th);
755  dc.setForeground(shadowColor);
756  drawLabel(dc,label,hotoff,tx,ty,tw,th);
757  }
758  }
759 
760  // Draw focus
761  if (hasFocus()) {
762  if (isEnabled()) {
763  dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2);
764  }
765  }
766  return 1;
767 }
768 
769 
770 
771 // Get default width
773  FXint tw=0,iw=0,s=0,w,pw;
774 
775  if (!label.empty()) {
776  tw=labelWidth(label);
777  s=4;
778  }
779  if (!(options&MENUBUTTON_NOARROWS)) {
780  if (options&MENUBUTTON_LEFT)
782  else
784  }
785  if(icon)
786  iw=icon->getWidth();
787  if (!(options&(ICON_AFTER_TEXT|ICON_BEFORE_TEXT)))
788  w=FXMAX(tw,iw);
789  else
790  w=tw+iw+s;
791  w=padleft+padright+(border<<1)+w;
792  if (!(options&MENUBUTTON_LEFT) &&
793  (options&MENUBUTTON_ATTACH_RIGHT) &&
794  (options&MENUBUTTON_ATTACH_CENTER)) {
795  if (pane) {
796  pw=pane->getDefaultWidth();
797  if(pw>w)
798  w=pw;
799  }
800  }
801  return w;
802 }
803 
804 
805 
806 
807 #if 0
808 FXDEFMAP(ThemeHeaderItem) ThemeHeaderItemMap[]= {
809  FXMAPFUNC(SEL_PAINT, 0, ThemeHeaderItem::onPaint)
810 };
811 
812 FXIMPLEMENT(ThemeHeaderItem, FXHeaderItem, ThemeHeaderItemMap, ARRAYNUMBER(ThemeHeaderItemMap));
813 #endif
814 
815 
816 ThemeHeaderItem::ThemeHeaderItem(const FXString& text, FXIcon* ic, FXint s, void* ptr)
817  :FXHeaderItem(text, ic, s, ptr) {
818 }
819 
820 
821 
822 void ThemeHeaderItem::draw(const FXHeader* header,FXDC& dc,FXint x,FXint y,FXint w,FXint h) {
823  register FXint tx,ty,tw,th,ix,iy,iw,ih,s,ml,mr,mt,mb,beg,end,t,xx,yy,bb,aa,ax,ay;
824  register FXFont *font=header->getFont();
825  FXColor top = FXRGB(0xfe,0xfd,0xfd);
826  FXColor bottom = FXRGB(0xdd,0xd7,0xce);
827  FXColor shade = FXRGB(0xdc,0xd9,0xd4);
828 
829  // Get border width and padding
830  bb=header->getBorderWidth();
831  ml=header->getPadLeft()+bb;
832  mr=header->getPadRight()+bb;
833  mt=header->getPadTop()+bb;
834  mb=header->getPadBottom()+bb;
835 
836  dc.setForeground(shade);
838  drawRectangle(dc,top, bottom, x+2, y+1, w-4, h-2);
839 
840  // Shrink by margins
841  x+=ml;
842  w-=ml+mr;
843  y+=mt;
844  h-=mt+mb;
845 
846  // Initial clip rectangle
847  dc.setClipRectangle(x,y,w,h);
848 
849  dc.setForeground(header->getTextColor());
850  // Text width and height
851  tw=th=iw=ih=beg=s=0;
852  do {
853  end=beg;
854  while(end<label.length() && label[end]!='\n') end++;
855  if((t=font->getTextWidth(&label[beg],end-beg))>tw) tw=t;
856  th+=font->getFontHeight();
857  beg=end+1;
858  }
859  while(end<label.length());
860 
861  // Icon size
862  if(icon) {
863  iw=icon->getWidth();
864  ih=icon->getHeight();
865  }
866 
867  // Icon-text spacing
868  if(iw && tw)
869  s=ICON_SPACING;
870 
871  // Draw arrows
872  if (state&(ARROW_UP|ARROW_DOWN)) {
873  aa=(font->getFontHeight()-5)|1;
874  ay=y+(h-aa)/2;
875  ax=x+w-aa-2;
876  if(state&ARROW_UP) {
877  dc.setForeground(header->getHiliteColor());
878  dc.drawLine(ax+aa/2,ay,ax+aa-1,ay+aa);
879  dc.drawLine(ax,ay+aa,ax+aa,ay+aa);
880  dc.setForeground(header->getShadowColor());
881  dc.drawLine(ax+aa/2,ay,ax,ay+aa);
882  }
883  else {
884  dc.setForeground(header->getHiliteColor());
885  dc.drawLine(ax+aa/2,ay+aa,ax+aa-1,ay);
886  dc.setForeground(header->getShadowColor());
887  dc.drawLine(ax+aa/2,ay+aa,ax,ay);
888  dc.drawLine(ax,ay,ax+aa,ay);
889  }
890  w-=aa+4;
891  dc.setClipRectangle(x,y,w,h);
892  }
893 
894  // Fix x coordinate
895  if (state&LEFT) {
896  if(state&BEFORE) {
897  ix=x;
898  tx=ix+iw+s;
899  }
900  else if (state&AFTER) {
901  tx=x;
902  ix=tx+tw+s;
903  }
904  else {
905  ix=x;
906  tx=x;
907  }
908  }
909  else if(state&RIGHT) {
910  if(state&BEFORE) {
911  tx=x+w-tw;
912  ix=tx-iw-s;
913  }
914  else if (state&AFTER) {
915  ix=x+w-iw;
916  tx=ix-tw-s;
917  }
918  else {
919  ix=x+w-iw;
920  tx=x+w-tw;
921  }
922  }
923  else {
924  if (state&BEFORE) {
925  ix=x+(w-tw-iw-s)/2;
926  tx=ix+iw+s;
927  }
928  else if (state&AFTER) {
929  tx=x+(w-tw-iw-s)/2;
930  ix=tx+tw+s;
931  }
932  else {
933  ix=x+(w-iw)/2;
934  tx=x+(w-tw)/2;
935  }
936  }
937 
938  // Fix y coordinate
939  if(state&TOP) {
940  if (state&ABOVE) {
941  iy=y;
942  ty=iy+ih;
943  }
944  else if (state&BELOW) {
945  ty=y;
946  iy=ty+th;
947  }
948  else {
949  iy=y;
950  ty=y;
951  }
952  }
953  else if(state&BOTTOM) {
954  if (state&ABOVE) {
955  ty=y+h-th;
956  iy=ty-ih;
957  }
958  else if (state&BELOW) {
959  iy=y+h-ih;
960  ty=iy-th;
961  }
962  else {
963  iy=y+h-ih;
964  ty=y+h-th;
965  }
966  }
967  else {
968  if (state&ABOVE) {
969  iy=y+(h-th-ih)/2;
970  ty=iy+ih;
971  }
972  else if (state&BELOW) {
973  ty=y+(h-th-ih)/2;
974  iy=ty+th;
975  }
976  else {
977  iy=y+(h-ih)/2;
978  ty=y+(h-th)/2;
979  }
980  }
981 
982  // Offset a bit when pressed
983  if (state&PRESSED) {
984  tx++;
985  ty++;
986  ix++;
987  iy++;
988  }
989 
990  // Paint icon
991  if (icon) {
992  dc.drawIcon(icon,ix,iy);
993  }
994 
995  // Text color
996  dc.setForeground(header->getTextColor());
997 
998  // Draw text
999  yy=ty+font->getFontAscent();
1000  beg=0;
1001  do {
1002  end=beg;
1003  while(end<label.length() && label[end]!='\n')
1004  end++;
1005  if (state&LEFT)
1006  xx=tx;
1007  else if(state&RIGHT)
1008  xx=tx+tw-font->getTextWidth(&label[beg],end-beg);
1009  else
1010  xx=tx+(tw-font->getTextWidth(&label[beg],end-beg))/2;
1011  dc.drawText(xx,yy,&label[beg],end-beg);
1012  yy+=font->getFontHeight();
1013  beg=end+1;
1014  }
1015  while(end<label.length());
1016 
1017  // Restore original clip path
1018  dc.clearClipRectangle();
1019 }
1020 
1021 
1022 
1023 
1024 
1025 
const FXchar * name
Definition: theme.cpp:316
#define MENUBUTTONARROW_HEIGHT
Definition: theme.cpp:487
long onPaint(FXObject *, FXSelector, void *ptr)
Definition: theme.cpp:85
#define NULL
Definition: binreloc.c:300
FXDEFMAP(ThemeButton) ThemeButtonMap[]
FXColor fore
Definition: theme.cpp:320
FXColor menufore
Definition: theme.cpp:326
FXColor base
Definition: theme.cpp:317
long onPaint(FXObject *, FXSelector, void *ptr)
Definition: theme.cpp:282
FXColor tipback
Definition: theme.cpp:323
#define ICON_SPACING
Definition: theme.cpp:15
FXint getDefaultWidth()
Definition: theme.cpp:772
ThemeTextField()
Definition: theme.h:56
long onPaint(FXObject *, FXSelector, void *ptr)
Definition: theme.cpp:507
FXColor menuback
Definition: theme.cpp:325
void draw(const FXHeader *header, FXDC &dc, FXint x, FXint y, FXint w, FXint h)
Definition: theme.cpp:822
#define MENUBUTTONARROW_WIDTH
Definition: theme.cpp:486
FXColor selfore
Definition: theme.cpp:322
static void drawSunkenFrame(FXDCWindow &dc, FXint x, FXint y, FXint w, FXint h)
Definition: theme.cpp:242
ThemeHeaderItem()
Definition: theme.h:178
const ColorTheme ColorThemes[]
Definition: theme.cpp:330
FXColor back
Definition: theme.cpp:319
FXColor tipfore
Definition: theme.cpp:324
void init_theme(FXApp *app)
Definition: theme.cpp:336
FXIMPLEMENT(ThemeButton, FXButton, ThemeButtonMap, ARRAYNUMBER(ThemeButtonMap))
long onPaint(FXObject *, FXSelector, void *ptr)
Definition: theme.cpp:374
static void drawHighlightFrame(FXDCWindow &dc, FXint x, FXint y, FXint w, FXint h)
Definition: theme.cpp:262
void drawFrame(FXDCWindow &dc, FXint x, FXint y, FXint w, FXint h)
FXColor border
Definition: theme.cpp:318
long onPaint(FXObject *, FXSelector, void *ptr)
Definition: theme.cpp:403
static void drawFrame(FXDCWindow &dc, FXint x, FXint y, FXint w, FXint h)
Definition: theme.cpp:228
FXColor selback
Definition: theme.cpp:321
static void drawRectangle(FXDC &dc, FXColor lower, FXColor upper, FXint x, FXint y, FXint w, FXint h)
Definition: theme.cpp:19
ThemeMenuButton()
Definition: theme.h:158
ThemeTabItem()
Definition: theme.h:115
ThemeComboBox()
Definition: theme.h:81
ThemeButton()
Definition: theme.h:39
ThemeLabel()
Definition: theme.h:98