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