2 #define WIN32_LEAN_AND_MEAN
15 bool gui::drivers::XGetBorderWidths(Window window, Box box);
23 #define CORNER (BORDER * 2)
25 #define BUTTON_SIZE 45
28 #define BUTTON_SIZE 15
34 #define BUTTON_OFFSET 2
36 #define NAME_OFFSET 12
40 #define NAME_OFFSETX 4
46 #define GRADIENT_SMOOTHNESS 1.0f
48 #define TEXT_COLOR black
51 #define GRADIENT_DIRECTION horizontal
53 static ColorKey gradient[] =
55 { Color { 128, 128, 255}, 0.00f },
56 { Color { 254, 254, 254}, 0.60f },
57 { Color { 0, 0, 255}, 1.00f }
61 #define GRADIENT_DIRECTION vertical
62 static ColorKey gradient[] =
64 //{ ColorAlpha { 255, { 180, 200, 220} }, 0.00f },
65 { ColorAlpha { 255, menuBarColor }, 0.00f },
66 { ColorAlpha { 255, { 255, 255, 255} }, 0.60f },
67 { ColorAlpha { 255, { 158, 158, 160} }, 1.00f }
70 static ColorKey gradientInactive[] =
72 //{ ColorAlpha { 255, { 160, 180, 200} }, 0.00f },
73 { ColorAlpha { 255, popupMenuColor }, 0.00f },
74 { ColorAlpha { 255, { 220, 220, 220} }, 0.60f },
75 { ColorAlpha { 255, { 120, 120, 120} }, 1.00f }
79 #define GRADIENT_DIRECTION horizontal
80 #define TEXT_COLOR white
82 //#define TEXT_INACTIVE Color { 212,208,200 }
83 #define TEXT_INACTIVE Color { 40, 50, 60 }
85 static ColorKey gradient[] =
87 { ColorAlpha { 255, Color { 10, 36, 106 } }, 0.00f },
88 { ColorAlpha { 255, Color { 166, 202, 240 } }, 1.00f }
90 static ColorKey gradientInactive[] =
92 { ColorAlpha { 255, Color { 128, 128, 128 } }, 0.00f },
93 { ColorAlpha { 255, Color { 192, 192, 192 } }, 1.00f }
96 static const char * cursorsBitmaps[] =
98 "<:ecere>cursors/arrow.png",
99 "<:ecere>cursors/iBeam.png",
100 "<:ecere>cursors/cross.png",
101 "<:ecere>cursors/move.png",
102 "<:ecere>cursors/sizeNorthEastSouthWest.png",
103 "<:ecere>cursors/sizeNorthSouth.png",
104 "<:ecere>cursors/sizeNorthWestSouthEast.png",
105 "<:ecere>cursors/sizeWestEast.png",
106 "<:ecere>cursors/move.png"
109 static Point cursorsHotSpots[] =
121 static const char * skinBitmaps[SkinBitmap] =
123 "<:ecere>elements/areaMinimize.png",
124 "<:ecere>elements/areaMaximize.png",
125 "<:ecere>elements/areaRestore.png",
126 "<:ecere>elements/areaClose.png"
129 class WindowsSkin : Skin
131 class_property(name) = "Windows";
132 class_property(selectionColor) = Color { 10, 36, 106 };
133 class_property(selectionText) = (Color)white;
134 class_property(disabledFrontColor) = Color { 128,128,128 };
135 class_property(disabledBackColor) = (Color)white;
137 FontResource ::SystemFont()
139 #if defined(HIGH_DPI)
140 return FontResource { faceName = $"Tahoma", size = 18.25f };
142 return FontResource { faceName = $"Tahoma", size = 8.25f };
146 FontResource ::CaptionFont()
148 #if defined(HIGH_DPI)
149 return FontResource { faceName = $"Tahoma", size = 18.25f, bold = true };
151 return FontResource { faceName = $"Tahoma", size = 8.25f, bold = true };
155 const char * ::CursorsBitmaps(uint id, int * hotSpotX, int *hotSpotY, byte ** paletteShades)
157 *hotSpotX = cursorsHotSpots[id].x;
158 *hotSpotY = cursorsHotSpots[id].y;
159 *paletteShades = null;
160 return cursorsBitmaps[id];
163 BitmapResource ::GetBitmap(SkinBitmap id)
165 return BitmapResource { fileName = skinBitmaps[id] };
168 int ::VerticalSBW() { return SB_WIDTH; }
169 int ::HorizontalSBH() { return SB_HEIGHT; }
173 public class WindowsSkin_Window : Window
175 void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h)
179 if(hasMenuBar && state != minimized)
181 *h += skinMenuHeight;
183 if(statusBar && state != minimized)
185 *h += statusBarHeight;
188 if(nativeDecorations && rootWindow == this && windowHandle && !is3D)
191 RECT rcClient = { 0 }, rcWindow = { 0 };
192 if(GetClientRect(windowHandle, &rcClient) && GetWindowRect(windowHandle, &rcWindow))
194 *w += (rcWindow.right - rcWindow.left) - rcClient.right;
195 *h += (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
198 // PrintLn(_class.name, " is at l = ", rcWindow.left, ", r = ", rcWindow.right);
201 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
202 XGetBorderWidths(this, widths);
204 *w += widths.left + widths.right;
205 *h += widths.top + widths.bottom;
209 if((((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel) && state != minimized)
214 if(((BorderBits)borderStyle).sizable && (state == normal))
219 if(((BorderBits)borderStyle).fixed && (state != maximized || !GetParentMenuBar()))
222 if(!((BorderBits)borderStyle).sizable || state == minimized)
228 if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
235 void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh)
237 bool isNormal = (state == normal);
238 if(nativeDecorations && rootWindow == this && windowHandle && !is3D) return;
239 if(((BorderBits)borderStyle).fixed && (state != maximized || !GetParentMenuBar()))
246 if(((BorderBits)borderStyle).sizable && isNormal)
248 // GetDecorationsSize(window, mw, mh);
254 if(hasVertScroll && hasHorzScroll)
256 *mw += 2 * SB_WIDTH + SB_WIDTH;
257 *mh += 2 * SB_HEIGHT + SB_HEIGHT;
258 if(((BorderBits)borderStyle).sizable && isNormal)
263 void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
265 bool isNormal = (state == normal);
266 MinMaxValue aw = 0, ah = 0;
272 *y += skinMenuHeight;
275 GetDecorationsSize(&aw, &ah);
277 if(nativeDecorations && rootWindow == this && windowHandle && !is3D)
280 RECT rcWindow = { 0, 0, 0, 0 };
281 POINT client00 = { 0, 0 };
282 ClientToScreen(windowHandle, &client00);
283 GetWindowRect(windowHandle, &rcWindow);
284 *x += client00.x - rcWindow.left;
285 *y += client00.y - rcWindow.top;
288 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
289 XGetBorderWidths(this, widths);
297 // Compute client area start
298 if(((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel)
304 if(((BorderBits)borderStyle).sizable && isNormal)
310 if(((BorderBits)borderStyle).fixed && (state != maximized || !GetParentMenuBar()))
313 if(!((BorderBits)borderStyle).sizable || state == minimized)
320 if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
327 // Reduce client area
335 void ShowDecorations(Font captionFont, Surface surface, const char * name, bool active, bool moving)
337 bool isNormal = (state == normal);
338 int top = 0, border = 0, bottom = 0;
339 Window parentMenuBar = GetParentMenuBar();
341 if(nativeDecorations && rootWindow == this && windowHandle && !is3D) return;
343 if(state == minimized)
344 top = border = bottom = DEAD_BORDER;
345 else if(((BorderBits)borderStyle).sizable)
347 top = isNormal ? TOP : 0;
348 border = isNormal ? BORDER : 0;
351 else if(((BorderBits)borderStyle).fixed)
354 border = DEAD_BORDER;
355 bottom = DEAD_BORDER;
357 else if(((BorderBits)borderStyle).contour)
364 if(((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel)
366 int deepTop = 0, deepBottom = 0, deepBorder = 0;
367 if(((BorderBits)borderStyle).contour)
370 deepTop = (((BorderBits)borderStyle).fixed && (state != maximized || !parentMenuBar)) ? (top + CAPTION) : top;
371 deepBottom = (((BorderBits)borderStyle).sizable && isNormal) ? bottom : border;
374 surface.Bevel(((BorderBits)borderStyle).bevel ? false : true, deepBorder, deepTop,
375 size.w - deepBorder - deepBorder, size.h - deepBottom - deepTop);
378 if(((BorderBits)borderStyle).fixed && (state != maximized || !parentMenuBar))
380 if(state != maximized || !((BorderBits)borderStyle).sizable)
382 // Frame for ES_CAPTION windows
383 surface.Bevel(false, 0, 0, size.w, size.h);
384 surface.SetForeground(formColor);
385 surface.Rectangle(2, 2, size.w-3, size.h-3);
387 // Resizeable frame is 1 pixel thicker
388 if(((BorderBits)borderStyle).sizable && isNormal)
389 surface.Rectangle(3, 3, size.w - 4, size.h - 4);
394 surface.Gradient(gradient, sizeof(gradient) / sizeof(ColorKey), GRADIENT_SMOOTHNESS, GRADIENT_DIRECTION,
395 border, top, size.w - border - 1, top + CAPTION - 2);
397 surface.Gradient(gradientInactive, sizeof(gradientInactive) / sizeof(ColorKey),
398 GRADIENT_SMOOTHNESS, GRADIENT_DIRECTION,
399 border, top, size.w - border - 1, top + CAPTION - 2);
401 surface.SetForeground(formColor);
402 if(state != minimized)
403 surface.HLine(border, size.w-border-1, top + CAPTION-1);
405 surface.SetForeground((active ? TEXT_COLOR : TEXT_INACTIVE));
406 surface.TextOpacity(false);
407 surface.TextFont(captionFont);
410 int buttonsSize = border +
411 ((hasMaximize || hasMinimize) ? (BUTTON_SIZE*3)+7 : (BUTTON_SIZE+3));
412 surface.WriteTextDots(left, border + NAME_OFFSETX, top + NAME_OFFSET,
413 size.w - (buttonsSize + border + 4), name, strlen(name));
416 if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
418 surface.SetForeground(black);
419 surface.Rectangle(0, 0, size.w - 1, size.h - 1);
422 if(state != minimized && hasHorzScroll && hasVertScroll)
424 if(sbh && sbh.visible && sbv && sbv.visible)
426 surface.SetBackground(formColor);
428 clientStart.x + clientSize.w,
429 clientStart.y + clientSize.h,
430 clientStart.x + clientSize.w + SB_WIDTH - 1,
431 clientStart.y + clientSize.h + SB_HEIGHT - 1);
436 bool IsMouseMoving(int x, int y, int w, int h)
438 bool isNormal = (state == normal);
440 if(nativeDecorations && rootWindow == this && windowHandle && !is3D) return false;
442 if(((BorderBits)borderStyle).fixed && (state != maximized || !GetParentMenuBar()))
444 int corner = 0, border = 0, top = 0;
445 if(((BorderBits)borderStyle).sizable && isNormal)
451 // Special case for having caption on resize bar
453 result = Box { corner, 0, w-corner-1, TOP-1 }.IsPointInside({x,y});
455 result = Box { border, top, w-border-1, top+CAPTION-1 }.IsPointInside({x, y});
460 bool IsMouseResizing(int x, int y, int w, int h, bool *resizeX, bool *resizeY, bool *resizeEndX, bool *resizeEndY)
464 *resizeX = *resizeY = *resizeEndX = *resizeEndY = false;
465 if(nativeDecorations && rootWindow == this && windowHandle && !is3D) return false;
467 if(((BorderBits)borderStyle).sizable && (state == normal))
470 if(Box { 0, 0,CORNER-1, TOP-1 }.IsPointInside({x, y}))
471 result = *resizeX = *resizeY = true;
473 if(Box { w-CORNER-1, 0, w-1, TOP-1 }.IsPointInside({x, y}))
474 result = *resizeEndX = *resizeY = true;
476 if(Box { 0, h-BOTTOM-1, CORNER-1, h-1 }.IsPointInside({x, y}))
477 result = *resizeX = *resizeEndY = true;
478 // BottomRight Corner
479 if(Box { w-CORNER-1, h-BOTTOM-1, w-1, h-1 }.IsPointInside({x, y}))
480 result = *resizeEndX = *resizeEndY = true;
482 if(Box { 0,TOP, BORDER, h-BOTTOM-1 }.IsPointInside({x, y}))
483 result = *resizeX = true;
485 if(Box { w-BORDER-1, TOP, w-1, h-BOTTOM-1 }.IsPointInside({x, y}))
486 result = *resizeEndX = true;
488 if(Box { CORNER, 0, w-CORNER-1, TOP-1 }.IsPointInside({x, y}))
489 result = *resizeY = true;
491 if(Box { CORNER, h-BOTTOM-1, w-CORNER-1, h-1 }.IsPointInside({x, y}))
492 result = *resizeEndY = true;
497 void UpdateNonClient()
499 bool isNormal = (state == normal);
500 int top = 0, border = 0;
501 int insideBorder = 0;
503 if(!nativeDecorations || rootWindow != this || !windowHandle || is3D)
505 if(state == minimized)
506 top = border = DEAD_BORDER;
507 else if(((BorderBits)borderStyle).sizable)
509 if(state == maximized && GetParentMenuBar())
516 top = isNormal ? TOP : 0;
517 border = isNormal ? BORDER : 0;
520 else if(((BorderBits)borderStyle).fixed)
523 border = DEAD_BORDER;
525 else if(((BorderBits)borderStyle).contour)
530 insideBorder = border;
531 if(((BorderBits)borderStyle).deep)
536 border = clientStart.x;
537 insideBorder = border;
542 if(state == minimized)
543 menuBar.visible = false;
545 menuBar.visible = true;
546 menuBar.Move(clientStart.x, clientStart.y - skinMenuHeight, size.w - insideBorder * 2, skinMenuHeight);
550 if(state == minimized)
551 statusBar.visible = false;
554 statusBar.visible = true;
555 if(nativeDecorations && rootWindow == this && windowHandle && !is3D)
557 statusBar.anchor = { left = clientStart.x, bottom = (int)(size.h - clientSize.h - clientStart.y - statusBarHeight ) };
558 statusBar.size.w = size.w - insideBorder * 2;
562 statusBar.anchor = { left = clientStart.x, bottom = border };
563 statusBar.size.w = size.w - insideBorder * 2;
567 if(!nativeDecorations || rootWindow != this || !windowHandle || is3D)
571 sysButtons[0].anchor = { right = 2+(2*BUTTON_SIZE+3) + border, top = top + BUTTON_OFFSET };
572 sysButtons[0].size = { BUTTON_SIZE, BUTTON_SIZE };
573 sysButtons[0].bevel = true;
574 sysButtons[0].bitmap = { skinBitmaps[(state == minimized) ? restore : minimize] };
575 sysButtons[0].visible = true;
579 sysButtons[1].anchor = { right = 2+(BUTTON_SIZE+3) + border, top = top + BUTTON_OFFSET };
580 sysButtons[1].size = { BUTTON_SIZE, BUTTON_SIZE };
581 sysButtons[1].bevel = true;
582 sysButtons[1].bitmap = { skinBitmaps[(state == maximized) ? restore : maximize] };
583 sysButtons[1].visible = true;
587 sysButtons[2].anchor = { right = 2 + border, top = top + BUTTON_OFFSET };
588 sysButtons[2].size = { BUTTON_SIZE, BUTTON_SIZE };
589 sysButtons[2].bevel = true;
590 sysButtons[2].bitmap = { skinBitmaps[close] };
591 sysButtons[2].visible = true;
597 sysButtons[0].visible = false;
599 sysButtons[1].visible = false;
601 sysButtons[2].visible = false;
607 #define PUREVTBL(c) (*(void ***)((byte *)class(c).data + sizeof(uintptr)))
608 #if defined(HIGH_DPI)
609 #define CAPTION_DISTANCE 36
611 #define CAPTION_DISTANCE 18
615 static __attribute__((unused)) void Dummy()
622 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnApplyGraphics;
623 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw;
626 public class WindowsSkin_Button : Button
628 void OnRedraw(Surface surface)
632 ((void (*)(Window, Surface))PUREVTBL(Button)[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw])(this, surface);
637 ButtonState state = this.buttonState;
638 Bitmap buttonBitmap = bitmap ? bitmap.bitmap : null;
639 const char * text = this.text;
640 int offset = (state == down && this.offset) ? 1 : 0;
641 Color backColor = background;
642 int isDefault = this.isDefault;
648 surface.TextFont(font);
650 surface.TextExtent(text, strlen(text),&tw, &th);
652 if(bevelOver && checked)
657 if(bitmaps[disabled]) buttonBitmap = bitmaps[disabled].bitmap;
661 if(buttonBitmap && buttonStyle.bevelOver && !buttonStyle.checkBox && !buttonStyle.radio && text)
665 if((bevel /*|| bevelOver*/) && opacity && backColor)
667 if(!scaleBitmap || !buttonBitmap)
669 ColorKey keys[2] = { { silver, 0.0f }, { white, 1.0f } };
670 surface.Gradient(keys, sizeof(keys) / sizeof(ColorKey), 1, vertical, 0, 0, clientSize.w-1, clientSize.h-1);
675 if(isCheckbox && !buttonBitmap)
677 #if defined(HIGH_DPI)
682 int start = (clientSize.h - height) / 2;
685 // surface.SetBackground(formColor);
686 surface.SetBackground(gainsboro);
687 else if(active && !text)
688 surface.SetBackground((offset ? formColor : Color { 0,0,170 }));
690 surface.SetBackground((offset ? formColor : white));
691 surface.Area(2, start+2,height-3,start+height-3);
693 surface.SetForeground(Color { 85, 85, 85 });
694 surface.HLine(0, height - 2, start + 0);
695 surface.VLine(start+1, start+height - 2, 0);
697 surface.SetForeground(Color { 64,64,64 });
698 surface.HLine(1, height - 3, start + 1);
699 surface.VLine(start+2, start+height - 3, 1);
701 surface.SetForeground(Color { 212,208,200 });
702 surface.HLine(1, height - 2, start + height-2);
703 surface.VLine(start+1, start+height - 3, height-2);
705 surface.SetForeground(white);
706 surface.HLine(0, height - 1, start + height-1);
707 surface.VLine(start+0, start+height - 2, height-1);
712 surface.SetForeground(white);
714 surface.SetForeground(Color { 85, 85, 85 });
716 surface.SetForeground(black);
718 surface.DrawLine(8, start+16, 14,start+22);
719 surface.DrawLine(8, start+18, 14,start+24);
720 surface.DrawLine(14, start+22, 19,start+6);
721 surface.DrawLine(14, start+24, 19,start+8);
723 surface.DrawLine(4, start+8, 7,start+11);
724 surface.DrawLine(4, start+9, 7,start+12);
725 surface.DrawLine(7, start+11, 11,start+3);
726 surface.DrawLine(7, start+12, 11,start+4);
734 surface.SetForeground(white);
735 if(isRadio || isCheckbox)
737 int x = 0, y = (clientSize.h-buttonBitmap.height)/2;
738 if(bevelOver && text)
740 x = (CAPTION_DISTANCE-buttonBitmap.width)/2 + offset;
741 y = (clientSize.h-buttonBitmap.height)/2 + offset;
746 // Radio Buttons and Checkboxes
747 surface.Blit(buttonBitmap,
749 0,0,buttonBitmap.width,buttonBitmap.height);
757 surface.Stretch(buttonBitmap,
758 1 + offset, 1 + offset,0,0,
759 clientSize.w-3,clientSize.h-3,buttonBitmap.width,buttonBitmap.height);
761 surface.Stretch(buttonBitmap, 0,0, 0,0,
762 clientSize.w,clientSize.h,buttonBitmap.width,buttonBitmap.height);
767 bw = buttonBitmap.width;
768 bh = buttonBitmap.height;
770 if(bitmapAlignment == left || bitmapAlignment == right)
772 if(bitmapAlignment == left)
775 x = clientSize.w-bw-2;
776 y = (clientSize.h-bh)/2;
778 else if(bitmapAlignment == top || bitmapAlignment == bottom)
780 x = (clientSize.w-bw)/2;
781 if(bitmapAlignment == top)
784 y = clientSize.h-bh-2;
788 x = (clientSize.w-bw)/2;
789 y = (clientSize.h-bh - (int)(buttonStyle.bevelOver && text) * th)/2;
791 if(buttonStyle.bevel || buttonStyle.offset)
796 surface.Blit(buttonBitmap, x,y, 0,0, bw,bh);
802 if(bevel || (bevelOver && (state == down || state == over || checked)))
804 if(state == down || checked)
806 surface.SetForeground(Color { 85, 85, 85 });
807 surface.HLine(isDefault + 0, clientSize.w-2-isDefault, 0);
808 surface.VLine(isDefault + 1, clientSize.h-2-isDefault, 0);
809 surface.SetForeground(white);
810 surface.HLine(isDefault + 0, clientSize.w-1-isDefault, clientSize.h-1-isDefault);
811 surface.VLine(isDefault + 0, clientSize.h-2-isDefault, clientSize.w-1-isDefault);
815 surface.SetForeground(white);
816 surface.HLine(0 + isDefault, clientSize.w-2 - isDefault, isDefault);
817 surface.VLine(1 + isDefault, clientSize.h-2 - isDefault, isDefault);
818 surface.SetForeground(Color { 85, 85, 85 });
819 surface.HLine(1 + isDefault, clientSize.w-2 - isDefault, clientSize.h-2 - isDefault);
820 surface.VLine(1 + isDefault, clientSize.h-3 - isDefault, clientSize.w-2 - isDefault);
824 surface.SetForeground(black);
825 surface.HLine( isDefault, clientSize.w-1 - isDefault, clientSize.h-1 - isDefault);
826 surface.VLine( isDefault, clientSize.h-2 - isDefault, clientSize.w-1 - isDefault);
832 surface.TextOpacity(false);
833 surface.SetForeground(foreground);
837 surface.TextExtent(text, strlen(text),&tw, &th);
839 if((isRadio || isCheckbox) && !bevelOver)
840 WriteCaption(surface, CAPTION_DISTANCE + 3, // + clientSize.h,
841 (clientSize.h - th - 4)/2);
844 int x, y = (clientSize.h - th - 1)/2 + offset;
846 if(buttonStyle.bevelOver && buttonBitmap && !buttonStyle.checkBox && !buttonStyle.radio)
848 if(bitmapAlignment == top)
849 y = (clientSize.h - bh - 4 - th - 5)/2 + offset + bh + 4;
850 else if(bitmapAlignment == bottom)
851 y = (clientSize.h - bh - 4 - th - 5)/2 + offset;
852 else//if(bitmapAlignment == left || bitmapAlignment == right)
853 y = clientSize.h - th - 5 + offset;
856 y = (clientSize.h - th - 1)/2 + offset;
860 int width = clientSize.w - 2*6;
863 surface.WriteTextDots(alignment, x, y, width, text, strlen(text));
867 int width = clientSize.w - 2 * 6;
869 if(bitmapAlignment == left || bitmapAlignment == right)
871 if(bitmapAlignment == left)
875 if(isCheckbox || ((isRadio /*|| bevelOver*/) && buttonBitmap))
877 x += CAPTION_DISTANCE + 3;
882 if(alignment == right)
884 else if(alignment == center)
885 x += (width - tw) / 2;
887 WriteCaption(surface, x, y);
892 // Activation Highlight
895 surface.SetForeground(black);
896 surface.Rectangle(0,0,clientSize.w-1,clientSize.h-1);
898 if(!bevelOver && !isRemote)
900 if(active) // && (text || !(buttonStyle.radio || buttonStyle.checkBox)))
903 surface.SetForeground(black);
904 surface.LineStipple(0x5555);
906 if((isRadio || isCheckbox) && text)
908 x1 = CAPTION_DISTANCE; // + clientSize.h;
917 x2 = clientSize.w - 5+offset;
918 y2 = clientSize.h - 5+offset;
920 if(isRadio || isCheckbox)
928 if((x2 - x1) & 1) x2++;
929 if((y2 - y1) & 1) y2++;
931 surface.Rectangle(x1, y1, x2, y2);
932 surface.LineStipple(0);