cleaned all trailing white space from source files.
[sdk] / samples / guiAndGfx / skinning / SimSkin.ec
1 public import "ecere"
2
3 //define test = Color { 5, 4, 2 };
4 define skinMainColor = Color { 0, 71, 128 };
5 define skinOppositeColor = blue; //Color { 252, 114, 22 };
6 //define skinBackground = Color { 40, 40, 40 };
7 //define skinBackground = Color { 185, 201, 215 };
8 //define skinBackground = Color { 229, 236, 241 };
9 define skinBackground = Color { 255, 255, 255 };
10
11 #define BORDER       2
12 #define TOP          2
13 #define BOTTOM       2
14 #define CORNER       (BORDER * 2)
15 #define CAPTION      14
16 #define DEAD_BORDER  2
17 #define MIN_WIDTH    60
18 #define MIN_HEIGHT   3
19 #define BUTTON_OFFSET   0
20 #define NAME_OFFSET   2
21 #define NAME_OFFSETX  4
22
23 #define SB_WIDTH  16
24 #define SB_HEIGHT 16
25
26 #define MENU_HEIGHT     25
27 #define STATUS_HEIGHT   18
28
29 define skinForeground = skinMainColor;
30 define skinTextForeground = black;
31 define evenRowBackground = red; //Color { 80, 70, 60 };
32
33 define skinTextColor = skinMainColor;
34 define skinInactiveTextColor = Color { skinMainColor.r - 20, skinMainColor.g - 20, skinMainColor.b - 20 };
35
36 ColorKey skinGradient[3] =
37 {
38    { Color { 40,40,40 }, 0.0f },
39    { darkGray, 0.5f },
40    { Color { 40,40,40 }, 1.0f },
41 };
42
43 class SimSkin_Window : Window
44 {
45    void ShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving)
46    {
47       bool isNormal = (state == normal || state == maximized);
48       int top = 0, border = 0, bottom = 0;
49       if(state == minimized)
50          top = border = bottom = DEAD_BORDER;
51       else if(((BorderBits)borderStyle).sizable)
52       {
53          top = isNormal ? TOP : 0;
54          border = isNormal ? BORDER : 0;
55          bottom = BOTTOM;
56       }
57       else if(((BorderBits)borderStyle).fixed)
58       {
59          top = 2; //DEAD_BORDER;
60          border = DEAD_BORDER;
61          bottom = DEAD_BORDER;
62       }
63       else if(((BorderBits)borderStyle).contour)
64       {
65          top = 1;
66          border = 1;
67          bottom = 1;
68       }
69
70       if(((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel)
71       {
72          int deepTop = 0, deepBottom = 0, deepBorder = 0;
73          if(((BorderBits)borderStyle).contour)
74          {
75             deepBorder = border;
76             deepTop = (((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar)) ? (top + CAPTION) : top;
77             deepBottom = (((BorderBits)borderStyle).sizable && isNormal) ? bottom : border;
78          }
79
80          surface.Bevel(((BorderBits)borderStyle).bevel ? false : true, deepBorder, deepTop,
81             size.w - deepBorder - deepBorder, size.h - deepBottom - deepTop);
82       }
83
84       if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
85       {
86          /*
87          if(state != maximized || !((BorderBits)borderStyle).sizable)
88          {
89             // Frame for ES_CAPTION windows
90             surface.Bevel(false, 0, 0, size.w, size.h);
91             surface.SetForeground(activeBorder);
92             surface.Rectangle(2, 2, size.w-3, size.h-3);
93
94             // Resizeable frame is 1 pixel thicker
95             if(((BorderBits)borderStyle).sizable && isNormal)
96                surface.Rectangle(3, 3, size.w - 4, size.h - 4);
97          }
98
99          // Caption
100          if(active)
101             surface.Gradient(gradient, sizeof(gradient) / sizeof(ColorKey), GRADIENT_SMOOTHNESS, GRADIENT_DIRECTION,
102                border, top, size.w - border - 1, top + CAPTION - 2);
103          else
104             surface.Gradient(gradientInactive, sizeof(gradientInactive) / sizeof(ColorKey),
105             GRADIENT_SMOOTHNESS, GRADIENT_DIRECTION,
106                border, top, size.w - border - 1, top + CAPTION - 2);
107
108          surface.SetForeground(activeBorder);
109          if(state != minimized)
110             surface.HLine(border, size.w-border-1, top + CAPTION-1);
111          */
112
113          surface.SetForeground(skinBackground);
114          surface.Rectangle(0,0, size.w-1, size.h-1);
115          surface.SetForeground(active ? skinTextColor : skinInactiveTextColor);
116          surface.Rectangle(1,1, size.w-2, size.h-2);
117          surface.SetBackground(skinBackground);
118          surface.Area(2, 2, size.w-3, CAPTION + 1);
119
120          // surface.TextFont(captionFont);
121          // surface.WriteText(4,2, name, strlen(name));
122
123          surface.SetForeground((active ? skinTextColor : skinInactiveTextColor));
124          surface.TextOpacity(false);
125          surface.TextFont(captionFont);
126          if(name)
127          {
128             int buttonsSize = border +
129                ((hasMaximize || hasMinimize) ? 52 : 18);
130             surface.WriteTextDots(left, border + NAME_OFFSETX, top + NAME_OFFSET,
131                size.w - (buttonsSize + border + 4), name, strlen(name));
132          }
133       }
134       if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
135       {
136          surface.SetForeground(skinForeground /*black*/);
137          surface.Rectangle(0, 0, size.w - 1, size.h - 1);
138       }
139
140       if(state != minimized && hasHorzScroll && hasVertScroll)
141       {
142          if(sbh && sbh.visible && sbv && sbv.visible)
143          {
144             surface.SetBackground(activeBorder);
145             surface.Area(
146                clientStart.x + clientSize.w,
147                clientStart.y + clientSize.h,
148                clientStart.x + clientSize.w + SB_WIDTH - 1,
149                clientStart.y + clientSize.h + SB_HEIGHT - 1);
150          }
151       }
152    }
153
154    void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h)
155    {
156       *w = *h = 0;
157       if((((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel) && state != minimized)
158       {
159          *w += 4;
160          *h += 4;
161       }
162       if(((BorderBits)borderStyle).sizable && (state == normal || state == maximized))
163       {
164          *w += 2 * BORDER;
165          *h += TOP + BOTTOM;
166       }
167       if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
168       {
169          *h += CAPTION;
170          if(!((BorderBits)borderStyle).sizable || state == minimized)
171          {
172             *h += 2*DEAD_BORDER;
173             *w += 2*DEAD_BORDER;
174          }
175       }
176       if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
177       {
178          *w += 2;
179          *h += 2;
180       }
181       if(hasMenuBar && state != minimized)
182       {
183          *h += MENU_HEIGHT;
184       }
185       if(statusBar && state != minimized)
186       {
187          *h += STATUS_HEIGHT;
188       }
189    }
190
191    bool IsMouseMoving(int x, int y, int w, int h)
192    {
193       BorderBits style = (BorderBits)borderStyle; // TOFIX: borderStyle.fixed doesn't work
194       if(style.fixed)
195       {
196          bool resizeX, resizeY, resizeEndX, resizeEndY;
197          if(!IsMouseResizing(x, y, w, h, &resizeX, &resizeY, &resizeEndX, &resizeEndY))
198             return true;
199       }
200       return false;
201    }
202
203    bool IsMouseResizing(int x, int y, int w, int h, bool *resizeX, bool *resizeY, bool *resizeEndX, bool *resizeEndY)
204    {
205       bool result = false;
206
207       *resizeX = *resizeY = *resizeEndX = *resizeEndY = false;
208
209       if(((BorderBits)borderStyle).sizable && (state == normal))
210       {
211          // TopLeft Corner
212          if(Box { 0, 0,CORNER-1, TOP-1 }.IsPointInside({x, y}))
213             result = *resizeX = *resizeY = true;
214          // TopRight Corner
215          if(Box { w-CORNER-1, 0, w-1, TOP-1 }.IsPointInside({x, y}))
216             result = *resizeEndX = *resizeY = true;
217          // BottomLeft Corner
218          if(Box { 0, h-BOTTOM-1, CORNER-1, h-1 }.IsPointInside({x, y}))
219             result = *resizeX = *resizeEndY = true;
220          // BottomRight Corner
221          if(Box { w-CORNER-1, h-BOTTOM-1, w-1, h-1 }.IsPointInside({x, y}))
222             result = *resizeEndX = *resizeEndY = true;
223          // Left Border
224          if(Box { 0,TOP, BORDER, h-BOTTOM-1 }.IsPointInside({x, y}))
225             result = *resizeX = true;
226          // Right Border
227          if(Box { w-BORDER-1, TOP, w-1, h-BOTTOM-1 }.IsPointInside({x, y}))
228             result = *resizeEndX = true;
229          // Top Border
230          if(Box { CORNER, 0, w-CORNER-1, TOP-1 }.IsPointInside({x, y}))
231             result = *resizeY = true;
232          // Bottom Border
233          if(Box { CORNER, h-BOTTOM-1, w-CORNER-1, h-1 }.IsPointInside({x, y}))
234             result = *resizeEndY = true;
235       }
236       return result;
237    }
238
239    void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh)
240    {
241       bool isNormal = (state == normal || state == maximized);
242       if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
243       {
244          *mw = MIN_WIDTH;
245          *mh = MIN_HEIGHT;
246       }
247       else
248          *mw = *mh = 0;
249       /*
250       if(((BorderBits)borderStyle).sizable && isNormal)
251          *mw += 2*CORNER;
252       // GetDecorationsSize(window, mw, mh);
253       */
254
255       if(hasVertScroll)
256          *mw += SB_WIDTH;
257       if(hasHorzScroll)
258          *mh += SB_HEIGHT;
259       if(hasVertScroll && hasHorzScroll)
260       {
261          *mw += 2 * SB_WIDTH + SB_WIDTH;
262          *mh += 2 * SB_HEIGHT + SB_HEIGHT;
263          /*
264          if(((BorderBits)borderStyle).sizable && isNormal)
265             *mw -= 2*CORNER;
266          */
267       }
268    }
269
270    void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
271    {
272       bool isNormal = (state == normal || state == maximized);
273       MinMaxValue aw = 0, ah = 0;
274
275       *x = *y = 0;
276
277       GetDecorationsSize(&aw, &ah);
278
279       // Compute client area start
280       if(((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel)
281       {
282          *x += 2;
283          *y += 2;
284       }
285
286       if(((BorderBits)borderStyle).sizable && isNormal)
287       {
288          *x += BORDER;
289          *y += TOP;
290       }
291
292       if(hasMenuBar)
293       {
294          *y += MENU_HEIGHT;
295       }
296
297       if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
298       {
299          *y += CAPTION;
300          if(!((BorderBits)borderStyle).sizable || state == minimized)
301          {
302             *y += DEAD_BORDER;
303             *x += DEAD_BORDER;
304          }
305       }
306
307       if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
308       {
309          *x += 1;
310          *y += 1;
311       }
312
313       // Reduce client area
314       *cw = *w - aw;
315       *ch = *h - ah;
316
317       *cw = Max(*cw, 0);
318       *ch = Max(*ch, 0);
319    }
320
321    void UpdateNonClient()
322    {
323       bool isNormal = (state == normal || state == maximized);
324       int top = 0, border = 0;
325       int insideBorder;
326       if(state == minimized)
327          top = border = DEAD_BORDER;
328       else if(((BorderBits)borderStyle).sizable)
329       {
330          if(state == maximized && parent.menuBar)
331          {
332             top = 2;
333             border = 2;
334          }
335          else
336          {
337             top = isNormal ? TOP : 0;
338             border = isNormal ? BORDER : 0;
339          }
340       }
341       else if(((BorderBits)borderStyle).fixed)
342       {
343          top = 2;
344          border = 2;
345       }
346       else if(((BorderBits)borderStyle).contour)
347       {
348          top = 1;
349          border = 1;
350       }
351       insideBorder = border;
352       if(((BorderBits)borderStyle).deep)
353          insideBorder += 2;
354
355       if(menuBar)
356       {
357          if(state == minimized)
358             menuBar.visible = false;
359          else
360             menuBar.visible = true;
361          menuBar.Move(clientStart.x, clientStart.y - MENU_HEIGHT, size.w - insideBorder * 2, MENU_HEIGHT);
362       }
363       if(statusBar)
364       {
365          if(state == minimized)
366             statusBar.visible = false;
367          else
368          {
369             statusBar.visible = true;
370             statusBar.anchor = { left = clientStart.x, bottom = border };
371             statusBar.size.w = size.w - insideBorder * 2;
372          }
373       }
374
375       if(minimizeButton)
376       {
377          minimizeButton.anchor = { right = ((maximizeButton && !maximizeButton.disabled) ? 25 + 34 + 4 : 34 + 4) + border, top = top + BUTTON_OFFSET };
378          minimizeButton.size = { 20, 10 };
379          minimizeButton.foreground = skinForeground;
380          minimizeButton.background = skinBackground;
381          minimizeButton.bevel = false;
382          minimizeButton.OnRedraw = Minimize_OnRedraw;
383          minimizeButton.visible = true;
384       }
385       if(maximizeButton && !maximizeButton.disabled)
386       {
387          maximizeButton.anchor = { right = 34 + 4 + border, top = top + BUTTON_OFFSET };
388          maximizeButton.size = { 20, 10 };
389          maximizeButton.bevel = false;
390          maximizeButton.foreground = skinForeground;
391          maximizeButton.background = skinBackground;
392          maximizeButton.OnRedraw = Maximize_OnRedraw;
393          maximizeButton.visible = true;
394       }
395       if(closeButton)
396       {
397          closeButton.anchor = { right = -1 + border, top = top + BUTTON_OFFSET };
398          closeButton.size = { 34, 10 };
399          closeButton.bevel = false;
400          closeButton.foreground = skinForeground;
401          closeButton.background = skinBackground;
402          closeButton.OnRedraw = Close_OnRedraw;
403          closeButton.visible = true;
404       }
405    }
406
407    void OnApplyGraphics()
408    {
409       /*if(background)
410          background = skinBackground;
411       foreground = skinForeground;*/
412       // Find something better?
413    }
414 }
415
416 static void Button::SmallButton_OnRedraw(Surface surface)
417 {
418    surface.SetBackground(parent.active ? background : skinBackground);
419    surface.Area(0, 0, clientSize.w - 2, clientSize.w - 1);
420    surface.SetForeground(parent.active ? skinTextColor : skinInactiveTextColor);
421    surface.VLine(0, clientSize.h - 2, 0);
422    surface.VLine(0, clientSize.h - 2, clientSize.w - 1);
423    surface.HLine(1, clientSize.w - 2, clientSize.h - 1);
424 }
425
426 static void Button::Minimize_OnRedraw(Surface surface)
427 {
428    SmallButton_OnRedraw(this, surface);
429    surface.DrawLine( 5, 3, 14, 3);
430    surface.DrawLine( 5, 4, 14, 4);
431 }
432
433 static void Button::Maximize_OnRedraw(Surface surface)
434 {
435    SmallButton_OnRedraw(this, surface);
436    surface.Rectangle( 5, 2, 14, 7);
437    surface.DrawLine( 5, 3, 14, 3);
438 }
439
440 static void Button::Close_OnRedraw(Surface surface)
441 {
442    SmallButton_OnRedraw(this, surface);
443    //surface.SetForeground(black);
444    surface.DrawLine( 7+7, 2, 12+7, 7);
445    surface.DrawLine( 8+7, 2, 13+7, 7);
446    surface.DrawLine( 12+7, 2, 7+7, 7);
447    surface.DrawLine( 13+7, 2, 8+7, 7);
448 }
449
450 /*class SimSkin_StatusBar : StatusBar
451 {
452    void OnApplyGraphics()
453    {
454       background = skinBackground;
455       foreground = skinForeground;
456    }
457 }*/
458
459 /*class SimSkin_FileDialog : FileDialog
460 {
461    void OnApplyGraphics()
462    {
463       Window child;
464       background = skinBackground;
465       foreground = skinForeground;
466       for(child = firstChild; child; child = child.next)
467       {
468          if(!child.opacity)
469             child.foreground = skinForeground;
470       }
471    }
472 }*/
473
474 #define PUREVTBL(c)     ((int (**)())*(void **)((byte *)class(c).data + sizeof(void *)))
475
476 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnApplyGraphics;
477 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw;
478
479 static void Dummy()
480 {
481    Window a;
482    a.OnApplyGraphics();
483    a.OnRedraw(null);
484 }
485
486 class SimSkin_Button : Button
487 {/*
488    void OnApplyGraphics()
489    {
490       //background = skinBackground;
491       background = Color { (int)70 * 6/10, (int)130* 6/10, (int)180* 6/10 };
492       foreground = skinForeground;
493    }
494
495    void OnRedraw(Surface surface)
496    {
497       int isDefault = (int)this.isDefault;
498       ((void (*)(Window, Surface))(void *)PUREVTBL(Button)[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw])(this, surface);
499       if(bevel || (bevelOver && (buttonState == down || buttonState == over || checked)))
500       {
501          Color c = steelBlue;
502          if(buttonState == down || checked)
503          {
504             surface.SetForeground(skinMainColor);
505             surface.HLine(isDefault + 0, clientSize.w-2-isDefault, 0);
506             surface.VLine(isDefault + 1, clientSize.h-2-isDefault, 0);
507             surface.SetForeground(Color { Min((int)c.r * 16/10, 255), Min((int)c.g * 16/10, 255), Min((int)c.b * 16/10,255) });
508             surface.HLine(isDefault + 0, clientSize.w-1-isDefault, clientSize.h-1-isDefault);
509             surface.VLine(isDefault + 0, clientSize.h-2-isDefault, clientSize.w-1-isDefault);
510          }
511          else
512          {
513             surface.SetForeground(Color { Min((int)c.r * 16/10, 255), Min((int)c.g * 16/10, 255), Min((int)c.b * 16/10,255) });
514             surface.HLine(0 + isDefault, clientSize.w-2 - isDefault,  isDefault);
515             surface.VLine(1 + isDefault, clientSize.h-2 - isDefault,  isDefault);
516
517
518             surface.SetForeground(skinMainColor);
519             surface.HLine(1 + isDefault, clientSize.w-2 - isDefault, clientSize.h-2 - isDefault);
520             surface.VLine(1 + isDefault, clientSize.h-3 - isDefault, clientSize.w-2 - isDefault);
521
522             if(bevel)
523             {
524                //surface.SetForeground(skinForeground);
525                surface.SetForeground(Color { c.r * 4/10, c.g * 4/10, c.b * 4/10 });
526                surface.HLine( isDefault, clientSize.w-1 - isDefault, clientSize.h-1 - isDefault);
527                surface.VLine( isDefault, clientSize.h-2 - isDefault, clientSize.w-1 - isDefault);
528             }
529          }
530       }
531       if(isDefault)
532       {
533          surface.SetForeground(skinForeground);
534          surface.Rectangle(0,0,clientSize.w-1,clientSize.h-1);
535       }
536       if(!(bevelOver) && !isRemote)
537       {
538          if(active)
539          {
540             int x1,y1,x2,y2;
541             int offset = (buttonState == down && this.offset) ? 1 : 0;
542             surface.SetForeground(skinForeground);
543             surface.LineStipple(0x5555);
544
545             #define CAPTION_DISTANCE   18
546             if((isRadio || isCheckbox) && text)
547             {
548                //x1 = clientSize.h + CAPTION_DISTANCE;
549                x1 = CAPTION_DISTANCE;
550                y1 = 0;
551                x2 = clientSize.w-4;
552                y2 = clientSize.h-4;
553             }
554             else
555             {
556                x1 = 3+offset;
557                y1 = 3+offset;
558                x2 = clientSize.w - 5+offset;
559                y2 = clientSize.h - 5+offset;
560
561                if(isRadio || isCheckbox)
562                {
563                   x1-=3;
564                   y1-=3;
565                   x2+=1;
566                   y2+=1;
567                }
568             }
569             if((x2 - x1) & 1) x2++;
570             if((y2 - y1) & 1) y2++;
571
572             surface.Rectangle(x1, y1, x2, y2);
573             surface.LineStipple(0);
574          }
575       }
576    }
577    */
578    #define CAPTION_DISTANCE   18
579
580    void OnRedraw(Surface surface)
581    {
582       if(isRadio)
583       {
584          ((void (*)(Window, Surface))(void *)PUREVTBL(Button)[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw])(this, surface);
585          return;
586       }
587       // if(bevel)
588       {
589          ButtonState state = this.buttonState;
590          Bitmap buttonBitmap = bitmap ? bitmap.bitmap : null;
591          char * text = this.text;
592          int offset = (state == down && this.offset) ? 1 : 0;
593          Color backColor = background;
594          int isDefault = this.isDefault;
595          Font font;
596
597          font = fontObject;
598
599          if(bevelOver && checked)
600             offset = 1;
601
602          if(!isEnabled)
603             state = disabled;
604
605          // Background
606          if((bevel || bevelOver) /* && opacity && backColor*/)
607          {
608             if(!scaleBitmap || !buttonBitmap)
609             {
610                /*
611                surface.SetBackground({(byte)(opacity * 255), backColor});
612                //surface.Area(1, 1,clientSize.w-3+offset,clientSize.h-3+offset);
613                surface.Area(0, 0,clientSize.w-1,clientSize.h-1);
614                */
615                ColorKey keys[2] = { { silver, 0.0f }, { white, 1.0f } };
616                surface.Gradient(keys, sizeof(keys) / sizeof(ColorKey), 1, vertical, 0, 0, clientSize.w-1, clientSize.h-1);
617             }
618          }
619
620          // Checkbox
621          if(isCheckbox && !buttonBitmap)
622          {
623             int height = 16;
624             int start = (clientSize.h - height) / 2;
625
626             if(!isEnabled)
627                // surface.SetBackground(activeBorder);
628                surface.SetBackground(gainsboro);
629             else if(active && !text)
630                surface.SetBackground((offset ? activeBorder : Color { 0,0,170 }));
631             else
632                surface.SetBackground((offset ? activeBorder : white));
633             surface.Area(2, start+2,height-3,start+height-3);
634
635             surface.SetForeground(Color { 85, 85, 85 });
636             surface.HLine(0, height - 2, start + 0);
637             surface.VLine(start+1, start+height - 2, 0);
638
639             surface.SetForeground(Color { 64,64,64 });
640             surface.HLine(1, height - 3, start + 1);
641             surface.VLine(start+2, start+height - 3, 1);
642
643             surface.SetForeground(Color { 212,208,200 });
644             surface.HLine(1, height - 2, start + height-2);
645             surface.VLine(start+1, start+height - 3, height-2);
646
647             surface.SetForeground(white);
648             surface.HLine(0, height - 1, start + height-1);
649             surface.VLine(start+0, start+height - 2, height-1);
650
651             if(checked)
652             {
653                if(active && !text)
654                   surface.SetForeground(white);
655                else if(!isEnabled)
656                   surface.SetForeground(Color { 85, 85, 85 });
657                else
658                   surface.SetForeground(black);
659                surface.DrawLine(4, start+8, 7,start+11);
660                surface.DrawLine(4, start+9, 7,start+12);
661                surface.DrawLine(7, start+11, 11,start+3);
662                surface.DrawLine(7, start+12, 11,start+4);
663             }
664          }
665
666          // Bitmaps
667          if(buttonBitmap)
668          {
669             surface.SetForeground(white);
670             if(isRadio || isCheckbox)
671             {
672                int x = 0, y = (clientSize.h-buttonBitmap.height)/2;
673                if(bevelOver && text)
674                {
675                   x = (CAPTION_DISTANCE-buttonBitmap.width)/2 + offset;
676                   y = (clientSize.h-buttonBitmap.height)/2 + offset;
677
678
679                }
680
681                // Radio Buttons and Checkboxes
682                surface.Blit(buttonBitmap,
683                   x, y,
684                   0,0,buttonBitmap.width,buttonBitmap.height);
685             }
686             else
687             {
688                // Push Buttons
689                if(scaleBitmap)
690                {
691                   if(bevel || offset)
692                      surface.Stretch(buttonBitmap,
693                         1 + offset, 1 + offset,0,0,
694                         clientSize.w-3,clientSize.h-3,buttonBitmap.width,buttonBitmap.height);
695                   else
696                      surface.Stretch(buttonBitmap, 0,0, 0,0,
697                         clientSize.w,clientSize.h,buttonBitmap.width,buttonBitmap.height);
698                }
699                else
700                {
701                   if(bevel || offset)
702                      surface.Blit(buttonBitmap,
703                         (clientSize.w-buttonBitmap.width) /2 + offset,
704                         (clientSize.h-buttonBitmap.height)/2 + offset,
705                         0,0,buttonBitmap.width,buttonBitmap.height);
706                   else
707                      surface.Blit(buttonBitmap,
708                         (clientSize.w-buttonBitmap.width)/2,
709                         (clientSize.h-buttonBitmap.height)/2,
710                         0,0,buttonBitmap.width,buttonBitmap.height);
711                }
712             }
713          }
714
715          // Shadows
716          if(bevel || (bevelOver && (state == down || state == over || checked)))
717          {
718             if(state == down || checked)
719             {
720                surface.SetForeground(Color { 85, 85, 85 });
721                surface.HLine(isDefault + 0, clientSize.w-2-isDefault, 0);
722                surface.VLine(isDefault + 1, clientSize.h-2-isDefault, 0);
723                surface.SetForeground(white);
724                surface.HLine(isDefault + 0, clientSize.w-1-isDefault, clientSize.h-1-isDefault);
725                surface.VLine(isDefault + 0, clientSize.h-2-isDefault, clientSize.w-1-isDefault);
726             }
727             else
728             {
729                surface.SetForeground(white);
730                surface.HLine(0 + isDefault, clientSize.w-2 - isDefault,  isDefault);
731                surface.VLine(1 + isDefault, clientSize.h-2 - isDefault,  isDefault);
732                surface.SetForeground(Color { 85, 85, 85 });
733                surface.HLine(1 + isDefault, clientSize.w-2 - isDefault, clientSize.h-2 - isDefault);
734                surface.VLine(1 + isDefault, clientSize.h-3 - isDefault, clientSize.w-2 - isDefault);
735
736                if(bevel)
737                {
738                   surface.SetForeground(black);
739                   surface.HLine( isDefault, clientSize.w-1 - isDefault, clientSize.h-1 - isDefault);
740                   surface.VLine( isDefault, clientSize.h-2 - isDefault, clientSize.w-1 - isDefault);
741                }
742             }
743          }
744
745          // Text
746          surface.TextOpacity(false);
747          surface.TextFont(font);
748          surface.SetForeground(foreground);
749          if(text)
750          {
751             int tw, th;
752             surface.TextExtent(text, strlen(text),&tw, &th);
753
754             if((isRadio || isCheckbox) && !bevelOver)
755                WriteCaption(surface, /*clientSize.h +*/ CAPTION_DISTANCE + 3,
756                   (clientSize.h - th - 4)/2);
757             else
758             {
759                int x, y = (clientSize.h - th - 1)/2 + offset;
760
761                if(ellipsis)
762                {
763                   int width = clientSize.w - 2*6;
764                   int x = 6 + offset;
765
766                   surface.WriteTextDots(alignment, x, y, width, text, strlen(text));
767                }
768                else
769                {
770                   int width = clientSize.w - 2 * 6;
771                   x = 6 + offset;
772                   if(isCheckbox || ((isRadio || bevelOver) && buttonBitmap))
773                   {
774                      x += CAPTION_DISTANCE + 3;
775                   }
776
777                   if(tw < width)
778                   {
779                      if(alignment == right)
780                         x += width - tw - 1;
781                      else if(alignment == center)
782                         x += (width - tw) / 2;
783                   }
784                   WriteCaption(surface, x, y);
785                }
786             }
787          }
788
789          // Activation Highlight
790          if(isDefault)
791          {
792             surface.SetForeground(black);
793             surface.Rectangle(0,0,clientSize.w-1,clientSize.h-1);
794          }
795          if(!bevelOver && !isRemote)
796          {
797             if(active/* && (text || !(buttonStyle.radio || buttonStyle.checkBox))*/)
798             {
799                int x1,y1,x2,y2;
800                surface.SetForeground(black);
801                surface.LineStipple(0x5555);
802
803                if((isRadio || isCheckbox) && text)
804                {
805                   x1 = /*clientSize.h + */CAPTION_DISTANCE;
806                   y1 = 0;
807                   x2 = clientSize.w-4;
808                   y2 = clientSize.h-4;
809                }
810                else
811                {
812                   x1 = 3+offset;
813                   y1 = 3+offset;
814                   x2 = clientSize.w - 5+offset;
815                   y2 = clientSize.h - 5+offset;
816
817                   if(isRadio || isCheckbox)
818                   {
819                      x1-=3;
820                      y1-=3;
821                      x2+=1;
822                      y2+=1;
823                   }
824                }
825                if((x2 - x1) & 1) x2++;
826                if((y2 - y1) & 1) y2++;
827
828                surface.Rectangle(x1, y1, x2, y2);
829                surface.LineStipple(0);
830             }
831          }
832       }
833       /*else
834       {
835          Button::OnRedraw(surface);
836       }*/
837    }
838 }
839
840 class SimSkin_ScrollBar : ScrollBar
841 {
842    void OnApplyGraphics()
843    {
844       ((void (*)(Window))(void *)PUREVTBL(ScrollBar)[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnApplyGraphics])(this);
845
846       //background = { skinBackground.r * 9 / 6, skinBackground.g * 9 / 6, skinBackground.b * 9 / 6 };
847 /*
848       upBtn.background = Color {  70 * 6/10, 130* 6/10, 180* 6/10 }; //skinBackground;
849       upBtn.bitmap = { (direction == vertical) ? "<:ecere>elements/arrowUp.png" : "<:ecere>elements/arrowLeft.png", monochrome = true };
850       downBtn.background = Color {  70 * 6/10, 130* 6/10, 180* 6/10 }; //skinBackground;
851       downBtn.bitmap = { (direction == vertical) ? "<:ecere>elements/arrowDown.png" : "<:ecere>elements/arrowRight.png", monochrome = true };
852       thumb.background = Color {  70 * 6/10, 130* 6/10, 180* 6/10 }; //skinBackground;*/
853    }
854 }
855
856 /*class SimSkin_DropBox : DropBox
857 {
858    void OnApplyGraphics()
859    {
860       ((void (*)(Window))(void *)PUREVTBL(DropBox)[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnApplyGraphics])(this);
861       button.bitmap = { "<:ecere>elements/arrowDown.png", monochrome = true };
862       background = skinBackground;
863       foreground = skinForeground;
864       selectionColor = skinMainColor;
865    }
866 }*/
867
868 /*class SimSkin_ListBox : ListBox
869 {
870    void OnApplyGraphics()
871    {
872       ((void (*)(Window))(void *)PUREVTBL(ListBox)[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnApplyGraphics])(this);
873       background = skinBackground;
874       foreground = skinForeground;
875       selectionColor = skinMainColor;
876    }
877 }*/
878
879 public class SimSkin : Skin
880 {
881    class_property(name) = "Sim";
882    class_property(selectionColor) = (Color)skinMainColor;
883    class_property(disabledBackColor) = (Color)Color{ 128,128,128 };
884    class_property(disabledFrontColor) = (Color)Color{ 255,255,255 };
885
886    FontResource ::SystemFont()
887    {
888       return { faceName = "Tahoma", size = 8.25f };
889    }
890
891    FontResource ::CaptionFont()
892    {
893       return { faceName = "Verdana", size = 6.5f };
894    }
895
896    char * ::CursorsBitmaps(uint id, int *hotSpotX, int *hotSpotY, byte ** paletteShades)
897    {
898       return null;
899    }
900
901    BitmapResource ::GetBitmap(int id)
902    {
903       return null;
904    }
905
906    int ::VerticalSBW()
907    {
908       return 16;
909    }
910
911    int ::HorizontalSBH()
912    {
913       return 16;
914    }
915 }