8 #define CORNER (BORDER * 2)
13 #define BUTTON_OFFSET 2
15 #define NAME_OFFSETX 4
20 #define MENU_HEIGHT 25
21 #define STATUS_HEIGHT 18
23 #define GRADIENT_SMOOTHNESS 1.0f
25 #define TEXT_COLOR black
28 #define GRADIENT_DIRECTION horizontal
30 static ColorKey gradient[] =
32 { Color { 128, 128, 255}, 0.00f },
33 { Color { 254, 254, 254}, 0.60f },
34 { Color { 0, 0, 255}, 1.00f }
38 #define GRADIENT_DIRECTION vertical
39 static ColorKey gradient[] =
41 { ColorAlpha { 255, { 180, 200, 220} }, 0.00f },
42 { ColorAlpha { 255, { 255, 255, 255} }, 0.60f },
43 { ColorAlpha { 255, { 128, 128, 130} }, 1.00f }
46 static ColorKey gradientInactive[] =
48 { ColorAlpha { 255, { 160, 180, 200} }, 0.00f },
49 { ColorAlpha { 255, { 220, 220, 220} }, 0.60f },
50 { ColorAlpha { 255, { 100, 100, 100} }, 1.00f }
54 #define GRADIENT_DIRECTION horizontal
55 #define TEXT_COLOR white
57 //#define TEXT_INACTIVE Color { 212,208,200 }
58 #define TEXT_INACTIVE Color { 40, 50, 60 }
60 static ColorKey gradient[] =
62 { ColorAlpha { 255, Color { 10, 36, 106 } }, 0.00f },
63 { ColorAlpha { 255, Color { 166, 202, 240 } }, 1.00f }
65 static ColorKey gradientInactive[] =
67 { ColorAlpha { 255, Color { 128, 128, 128 } }, 0.00f },
68 { ColorAlpha { 255, Color { 192, 192, 192 } }, 1.00f }
71 char * cursorsBitmaps[] =
73 "<:ecere>cursors/arrow.png",
74 "<:ecere>cursors/iBeam.png",
75 "<:ecere>cursors/cross.png",
76 "<:ecere>cursors/move.png",
77 "<:ecere>cursors/sizeNorthEastSouthWest.png",
78 "<:ecere>cursors/sizeNorthSouth.png",
79 "<:ecere>cursors/sizeNorthWestSouthEast.png",
80 "<:ecere>cursors/sizeWestEast.png",
81 "<:ecere>cursors/move.png"
84 static Point cursorsHotSpots[] =
96 static char * skinBitmaps[SkinBitmap] =
98 "<:ecere>elements/areaMinimize.png",
99 "<:ecere>elements/areaMaximize.png",
100 "<:ecere>elements/areaRestore.png",
101 "<:ecere>elements/areaClose.png"
104 class WindowsSkin : Skin
106 class_property(name) = "Windows";
107 class_property(selectionColor) = Color { 10, 36, 106 };
108 class_property(selectionText) = (Color)white;
109 class_property(disabledFrontColor) = Color { 128,128,128 };
110 class_property(disabledBackColor) = (Color)white;
112 FontResource ::SystemFont()
114 return FontResource { faceName = "Tahoma", size = 8.25f };
117 FontResource ::CaptionFont()
119 return FontResource { faceName = "Tahoma", size = 8.25f, bold = true };
122 char * ::CursorsBitmaps(uint id, int * hotSpotX, int *hotSpotY, byte ** paletteShades)
124 *hotSpotX = cursorsHotSpots[id].x;
125 *hotSpotY = cursorsHotSpots[id].y;
126 *paletteShades = null;
127 return cursorsBitmaps[id];
130 BitmapResource ::GetBitmap(SkinBitmap id)
132 return BitmapResource { fileName = skinBitmaps[id] };
135 int ::VerticalSBW() { return SB_WIDTH; }
136 int ::HorizontalSBH() { return SB_HEIGHT; }
140 public class WindowsSkin_Window : Window
142 void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h)
146 if(hasMenuBar && state != minimized)
150 if(statusBar && state != minimized)
155 if(nativeDecorations) return;
156 if((((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel) && state != minimized)
161 if(((BorderBits)borderStyle).sizable && (state == normal))
166 if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
169 if(!((BorderBits)borderStyle).sizable || state == minimized)
175 if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
182 void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh)
184 bool isNormal = (state == normal);
185 if(nativeDecorations) return;
186 if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
193 if(((BorderBits)borderStyle).sizable && isNormal)
195 // GetDecorationsSize(window, mw, mh);
201 if(hasVertScroll && hasHorzScroll)
203 *mw += 2 * SB_WIDTH + SB_WIDTH;
204 *mh += 2 * SB_HEIGHT + SB_HEIGHT;
205 if(((BorderBits)borderStyle).sizable && isNormal)
210 void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
212 bool isNormal = (state == normal);
213 MinMaxValue aw = 0, ah = 0;
222 GetDecorationsSize(&aw, &ah);
224 if(!nativeDecorations)
226 // Compute client area start
227 if(((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel)
233 if(((BorderBits)borderStyle).sizable && isNormal)
239 if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
242 if(!((BorderBits)borderStyle).sizable || state == minimized)
249 if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
256 // Reduce client area
264 void ShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving)
266 bool isNormal = (state == normal);
267 int top = 0, border = 0, bottom = 0;
269 if(nativeDecorations) return;
271 if(state == minimized)
272 top = border = bottom = DEAD_BORDER;
273 else if(((BorderBits)borderStyle).sizable)
275 top = isNormal ? TOP : 0;
276 border = isNormal ? BORDER : 0;
279 else if(((BorderBits)borderStyle).fixed)
282 border = DEAD_BORDER;
283 bottom = DEAD_BORDER;
285 else if(((BorderBits)borderStyle).contour)
292 if(((BorderBits)borderStyle).deep || ((BorderBits)borderStyle).bevel)
294 int deepTop = 0, deepBottom = 0, deepBorder = 0;
295 if(((BorderBits)borderStyle).contour)
298 deepTop = (((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar)) ? (top + CAPTION) : top;
299 deepBottom = (((BorderBits)borderStyle).sizable && isNormal) ? bottom : border;
302 surface.Bevel(((BorderBits)borderStyle).bevel ? false : true, deepBorder, deepTop,
303 size.w - deepBorder - deepBorder, size.h - deepBottom - deepTop);
306 if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
308 if(state != maximized || !((BorderBits)borderStyle).sizable)
310 // Frame for ES_CAPTION windows
311 surface.Bevel(false, 0, 0, size.w, size.h);
312 surface.SetForeground(activeBorder);
313 surface.Rectangle(2, 2, size.w-3, size.h-3);
315 // Resizeable frame is 1 pixel thicker
316 if(((BorderBits)borderStyle).sizable && isNormal)
317 surface.Rectangle(3, 3, size.w - 4, size.h - 4);
322 surface.Gradient(gradient, sizeof(gradient) / sizeof(ColorKey), GRADIENT_SMOOTHNESS, GRADIENT_DIRECTION,
323 border, top, size.w - border - 1, top + CAPTION - 2);
325 surface.Gradient(gradientInactive, sizeof(gradientInactive) / sizeof(ColorKey),
326 GRADIENT_SMOOTHNESS, GRADIENT_DIRECTION,
327 border, top, size.w - border - 1, top + CAPTION - 2);
329 surface.SetForeground(activeBorder);
330 if(state != minimized)
331 surface.HLine(border, size.w-border-1, top + CAPTION-1);
333 surface.SetForeground((active ? TEXT_COLOR : TEXT_INACTIVE));
334 surface.TextOpacity(false);
335 surface.TextFont(captionFont);
338 int buttonsSize = border +
339 ((hasMaximize || hasMinimize) ? 52 : 18);
340 surface.WriteTextDots(left, border + NAME_OFFSETX, top + NAME_OFFSET,
341 size.w - (buttonsSize + border + 4), name, strlen(name));
344 if(((BorderBits)borderStyle).contour && !((BorderBits)borderStyle).fixed)
346 surface.SetForeground(black);
347 surface.Rectangle(0, 0, size.w - 1, size.h - 1);
350 if(state != minimized && hasHorzScroll && hasVertScroll)
352 if(sbh && sbh.visible && sbv && sbv.visible)
354 surface.SetBackground(activeBorder);
356 clientStart.x + clientSize.w,
357 clientStart.y + clientSize.h,
358 clientStart.x + clientSize.w + SB_WIDTH - 1,
359 clientStart.y + clientSize.h + SB_HEIGHT - 1);
364 bool IsMouseMoving(int x, int y, int w, int h)
366 bool isNormal = (state == normal);
368 if(nativeDecorations) return false;
370 if(((BorderBits)borderStyle).fixed && (state != maximized || !parent.menuBar))
372 int corner = 0, border = 0, top = 0;
373 if(((BorderBits)borderStyle).sizable && isNormal)
379 // Special case for having caption on resize bar
381 result = Box { corner, 0, w-corner-1, TOP-1 }.IsPointInside({x,y});
383 result = Box { border, top, w-border-1, top+CAPTION-1 }.IsPointInside({x, y});
388 bool IsMouseResizing(int x, int y, int w, int h, bool *resizeX, bool *resizeY, bool *resizeEndX, bool *resizeEndY)
392 *resizeX = *resizeY = *resizeEndX = *resizeEndY = false;
393 if(nativeDecorations) return false;
395 if(((BorderBits)borderStyle).sizable && (state == normal))
398 if(Box { 0, 0,CORNER-1, TOP-1 }.IsPointInside({x, y}))
399 result = *resizeX = *resizeY = true;
401 if(Box { w-CORNER-1, 0, w-1, TOP-1 }.IsPointInside({x, y}))
402 result = *resizeEndX = *resizeY = true;
404 if(Box { 0, h-BOTTOM-1, CORNER-1, h-1 }.IsPointInside({x, y}))
405 result = *resizeX = *resizeEndY = true;
406 // BottomRight Corner
407 if(Box { w-CORNER-1, h-BOTTOM-1, w-1, h-1 }.IsPointInside({x, y}))
408 result = *resizeEndX = *resizeEndY = true;
410 if(Box { 0,TOP, BORDER, h-BOTTOM-1 }.IsPointInside({x, y}))
411 result = *resizeX = true;
413 if(Box { w-BORDER-1, TOP, w-1, h-BOTTOM-1 }.IsPointInside({x, y}))
414 result = *resizeEndX = true;
416 if(Box { CORNER, 0, w-CORNER-1, TOP-1 }.IsPointInside({x, y}))
417 result = *resizeY = true;
419 if(Box { CORNER, h-BOTTOM-1, w-CORNER-1, h-1 }.IsPointInside({x, y}))
420 result = *resizeEndY = true;
425 void UpdateNonClient()
427 bool isNormal = (state == normal);
428 int top = 0, border = 0;
429 int insideBorder = 0;
431 if(!nativeDecorations)
433 if(state == minimized)
434 top = border = DEAD_BORDER;
435 else if(((BorderBits)borderStyle).sizable)
437 if(state == maximized && parent.menuBar)
444 top = isNormal ? TOP : 0;
445 border = isNormal ? BORDER : 0;
448 else if(((BorderBits)borderStyle).fixed)
451 border = DEAD_BORDER;
453 else if(((BorderBits)borderStyle).contour)
458 insideBorder = border;
459 if(((BorderBits)borderStyle).deep)
465 if(state == minimized)
466 menuBar.visible = false;
468 menuBar.visible = true;
469 menuBar.Move(clientStart.x, clientStart.y - MENU_HEIGHT, size.w - insideBorder * 2, MENU_HEIGHT);
473 if(state == minimized)
474 statusBar.visible = false;
477 statusBar.visible = true;
478 statusBar.anchor = { left = clientStart.x, bottom = border };
479 statusBar.size.w = size.w - insideBorder * 2;
482 if(!nativeDecorations)
486 sysButtons[0].anchor = { right = 35 + border, top = top + BUTTON_OFFSET };
487 sysButtons[0].size = { 15, 15 };
488 sysButtons[0].bevel = true;
489 sysButtons[0].bitmap = { skinBitmaps[(state == minimized) ? restore : minimize] };
490 sysButtons[0].visible = true;
494 sysButtons[1].anchor = { right = 20 + border, top = top + BUTTON_OFFSET };
495 sysButtons[1].size = { 15, 15 };
496 sysButtons[1].bevel = true;
497 sysButtons[1].bitmap = { skinBitmaps[(state == maximized) ? restore : maximize] };
498 sysButtons[1].visible = true;
502 sysButtons[2].anchor = { right = 2 + border, top = top + BUTTON_OFFSET };
503 sysButtons[2].size = { 15, 15 };
504 sysButtons[2].bevel = true;
505 sysButtons[2].bitmap = { skinBitmaps[close] };
506 sysButtons[2].visible = true;