4 * Copyright 1998 by Marcel Baur <mbaur@g26.ethz.ch>
6 * This file is based on rolex.c by Jim Peterson.
8 * I just managed to move the relevant parts into the Clock application
9 * and made it look like the original Windows one. You can find the original
10 * rolex.c in the wine /libtest directory.
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #define FaceColor (GetSysColor(COLOR_3DFACE))
34 #define HandColor (GetSysColor(COLOR_3DHIGHLIGHT))
35 #define TickColor (GetSysColor(COLOR_3DHIGHLIGHT))
36 #define ShadowColor (GetSysColor(COLOR_3DDKSHADOW))
37 #define BackgroundColor (GetSysColor(COLOR_3DFACE))
39 static const int SHADOW_DEPTH
= 2;
47 static HandData HourHand
, MinuteHand
, SecondHand
;
49 static void DrawTicks(HDC dc
, const POINT
* centre
, int radius
)
53 /* Minute divisions */
57 centre
->x
+ sin(t
*M_PI
/30)*0.9*radius
,
58 centre
->y
- cos(t
*M_PI
/30)*0.9*radius
,
61 centre
->x
+ sin(t
*M_PI
/30)*0.89*radius
,
62 centre
->y
- cos(t
*M_PI
/30)*0.89*radius
);
69 centre
->x
+ sin(t
*M_PI
/6)*0.9*radius
,
70 centre
->y
- cos(t
*M_PI
/6)*0.9*radius
,
73 centre
->x
+ sin(t
*M_PI
/6)*0.8*radius
,
74 centre
->y
- cos(t
*M_PI
/6)*0.8*radius
);
78 static void DrawFace(HDC dc
, const POINT
* centre
, int radius
, int border
)
81 SelectObject(dc
, CreatePen(PS_SOLID
, 2, ShadowColor
));
82 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
83 DrawTicks(dc
, centre
, radius
);
84 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 2, TickColor
)));
85 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
86 DrawTicks(dc
, centre
, radius
);
89 SelectObject(dc
, GetStockObject(NULL_BRUSH
));
90 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 5, ShadowColor
)));
91 Ellipse(dc
, centre
->x
- radius
, centre
->y
- radius
, centre
->x
+ radius
, centre
->y
+ radius
);
93 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
96 static void DrawHand(HDC dc
,HandData
* hand
)
98 MoveToEx(dc
, hand
->Start
.x
, hand
->Start
.y
, NULL
);
99 LineTo(dc
, hand
->End
.x
, hand
->End
.y
);
102 static void DrawHands(HDC dc
, BOOL bSeconds
)
106 SelectObject(dc
, CreatePen(PS_SOLID
, 1, ShadowColor
));
107 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
108 DrawHand(dc
, &SecondHand
);
109 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
)));
110 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
112 SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
));
114 DrawHand(dc
, &SecondHand
);
115 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
118 SelectObject(dc
, CreatePen(PS_SOLID
, 4, ShadowColor
));
120 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
121 DrawHand(dc
, &MinuteHand
);
122 DrawHand(dc
, &HourHand
);
124 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 4, HandColor
)));
125 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
126 DrawHand(dc
, &MinuteHand
);
127 DrawHand(dc
, &HourHand
);
129 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
132 static void PositionHand(const POINT
* centre
, double length
, double angle
, HandData
* hand
)
134 hand
->Start
= *centre
;
135 hand
->End
.x
= centre
->x
+ sin(angle
)*length
;
136 hand
->End
.y
= centre
->y
- cos(angle
)*length
;
139 static void PositionHands(const POINT
* centre
, int radius
, BOOL bSeconds
)
142 double hour
, minute
, second
;
144 /* 0 <= hour,minute,second < 2pi */
145 /* Adding the millisecond count makes the second hand move more smoothly */
149 second
= st
.wSecond
+ st
.wMilliseconds
/1000.0;
150 minute
= st
.wMinute
+ second
/60.0;
151 hour
= st
.wHour
% 12 + minute
/60.0;
153 PositionHand(centre
, radius
* 0.5, hour
/12 * 2*M_PI
, &HourHand
);
154 PositionHand(centre
, radius
* 0.65, minute
/60 * 2*M_PI
, &MinuteHand
);
156 PositionHand(centre
, radius
* 0.79, second
/60 * 2*M_PI
, &SecondHand
);
159 void AnalogClock(HDC dc
, int x
, int y
, BOOL bSeconds
, BOOL border
)
164 radius
= min(x
, y
)/2 - SHADOW_DEPTH
;
171 DrawFace(dc
, ¢re
, radius
, border
);
173 PositionHands(¢re
, radius
, bSeconds
);
174 DrawHands(dc
, bSeconds
);
178 HFONT
SizeFont(HDC dc
, int x
, int y
, BOOL bSeconds
, const LOGFONTW
* font
)
182 double xscale
, yscale
;
183 HFONT oldFont
, newFont
;
187 chars
= GetTimeFormatW(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
188 NULL
, szTime
, ARRAY_SIZE(szTime
));
197 x
-= 2 * SHADOW_DEPTH
;
198 y
-= 2 * SHADOW_DEPTH
;
200 oldFont
= SelectObject(dc
, CreateFontIndirectW(&lf
));
201 GetTextExtentPointW(dc
, szTime
, chars
, &extent
);
202 DeleteObject(SelectObject(dc
, oldFont
));
204 xscale
= (double)x
/extent
.cx
;
205 yscale
= (double)y
/extent
.cy
;
206 lf
.lfHeight
*= min(xscale
, yscale
);
207 newFont
= CreateFontIndirectW(&lf
);
212 void DigitalClock(HDC dc
, int x
, int y
, BOOL bSeconds
, HFONT font
)
219 chars
= GetTimeFormatW(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
220 NULL
, szTime
, ARRAY_SIZE(szTime
));
225 oldFont
= SelectObject(dc
, font
);
226 GetTextExtentPointW(dc
, szTime
, chars
, &extent
);
228 SetBkColor(dc
, BackgroundColor
);
229 SetTextColor(dc
, ShadowColor
);
230 TextOutW(dc
, (x
- extent
.cx
)/2 + SHADOW_DEPTH
, (y
- extent
.cy
)/2 + SHADOW_DEPTH
, szTime
, chars
);
231 SetBkMode(dc
, TRANSPARENT
);
233 SetTextColor(dc
, HandColor
);
234 TextOutW(dc
, (x
- extent
.cx
)/2, (y
- extent
.cy
)/2, szTime
, chars
);
236 SelectObject(dc
, oldFont
);