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
27 #include "wine/port.h"
35 #define FaceColor (GetSysColor(COLOR_3DFACE))
36 #define HandColor (GetSysColor(COLOR_3DHIGHLIGHT))
37 #define TickColor (GetSysColor(COLOR_3DHIGHLIGHT))
38 #define ShadowColor (GetSysColor(COLOR_3DDKSHADOW))
39 #define BackgroundColor (GetSysColor(COLOR_3DFACE))
41 static const int SHADOW_DEPTH
= 2;
49 static HandData HourHand
, MinuteHand
, SecondHand
;
51 static void DrawTicks(HDC dc
, const POINT
* centre
, int radius
)
55 /* Minute divisions */
59 centre
->x
+ sin(t
*M_PI
/30)*0.9*radius
,
60 centre
->y
- cos(t
*M_PI
/30)*0.9*radius
,
63 centre
->x
+ sin(t
*M_PI
/30)*0.89*radius
,
64 centre
->y
- cos(t
*M_PI
/30)*0.89*radius
);
71 centre
->x
+ sin(t
*M_PI
/6)*0.9*radius
,
72 centre
->y
- cos(t
*M_PI
/6)*0.9*radius
,
75 centre
->x
+ sin(t
*M_PI
/6)*0.8*radius
,
76 centre
->y
- cos(t
*M_PI
/6)*0.8*radius
);
80 static void DrawFace(HDC dc
, const POINT
* centre
, int radius
, int border
)
83 SelectObject(dc
, CreatePen(PS_SOLID
, 2, ShadowColor
));
84 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
85 DrawTicks(dc
, centre
, radius
);
86 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 2, TickColor
)));
87 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
88 DrawTicks(dc
, centre
, radius
);
91 SelectObject(dc
, GetStockObject(NULL_BRUSH
));
92 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 5, ShadowColor
)));
93 Ellipse(dc
, centre
->x
- radius
, centre
->y
- radius
, centre
->x
+ radius
, centre
->y
+ radius
);
95 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
98 static void DrawHand(HDC dc
,HandData
* hand
)
100 MoveToEx(dc
, hand
->Start
.x
, hand
->Start
.y
, NULL
);
101 LineTo(dc
, hand
->End
.x
, hand
->End
.y
);
104 static void DrawHands(HDC dc
, BOOL bSeconds
)
108 SelectObject(dc
, CreatePen(PS_SOLID
, 1, ShadowColor
));
109 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
110 DrawHand(dc
, &SecondHand
);
111 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
)));
112 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
114 SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
));
116 DrawHand(dc
, &SecondHand
);
117 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
120 SelectObject(dc
, CreatePen(PS_SOLID
, 4, ShadowColor
));
122 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
123 DrawHand(dc
, &MinuteHand
);
124 DrawHand(dc
, &HourHand
);
126 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 4, HandColor
)));
127 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
128 DrawHand(dc
, &MinuteHand
);
129 DrawHand(dc
, &HourHand
);
131 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
134 static void PositionHand(const POINT
* centre
, double length
, double angle
, HandData
* hand
)
136 hand
->Start
= *centre
;
137 hand
->End
.x
= centre
->x
+ sin(angle
)*length
;
138 hand
->End
.y
= centre
->y
- cos(angle
)*length
;
141 static void PositionHands(const POINT
* centre
, int radius
, BOOL bSeconds
)
144 double hour
, minute
, second
;
146 /* 0 <= hour,minute,second < 2pi */
147 /* Adding the millisecond count makes the second hand move more smoothly */
151 second
= st
.wSecond
+ st
.wMilliseconds
/1000.0;
152 minute
= st
.wMinute
+ second
/60.0;
153 hour
= st
.wHour
% 12 + minute
/60.0;
155 PositionHand(centre
, radius
* 0.5, hour
/12 * 2*M_PI
, &HourHand
);
156 PositionHand(centre
, radius
* 0.65, minute
/60 * 2*M_PI
, &MinuteHand
);
158 PositionHand(centre
, radius
* 0.79, second
/60 * 2*M_PI
, &SecondHand
);
161 void AnalogClock(HDC dc
, int x
, int y
, BOOL bSeconds
, BOOL border
)
166 radius
= min(x
, y
)/2 - SHADOW_DEPTH
;
173 DrawFace(dc
, ¢re
, radius
, border
);
175 PositionHands(¢re
, radius
, bSeconds
);
176 DrawHands(dc
, bSeconds
);
180 HFONT
SizeFont(HDC dc
, int x
, int y
, BOOL bSeconds
, const LOGFONTW
* font
)
184 double xscale
, yscale
;
185 HFONT oldFont
, newFont
;
189 chars
= GetTimeFormatW(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
190 NULL
, szTime
, sizeof(szTime
)/sizeof(WCHAR
));
199 x
-= 2 * SHADOW_DEPTH
;
200 y
-= 2 * SHADOW_DEPTH
;
202 oldFont
= SelectObject(dc
, CreateFontIndirectW(&lf
));
203 GetTextExtentPointW(dc
, szTime
, chars
, &extent
);
204 DeleteObject(SelectObject(dc
, oldFont
));
206 xscale
= (double)x
/extent
.cx
;
207 yscale
= (double)y
/extent
.cy
;
208 lf
.lfHeight
*= min(xscale
, yscale
);
209 newFont
= CreateFontIndirectW(&lf
);
214 void DigitalClock(HDC dc
, int x
, int y
, BOOL bSeconds
, HFONT font
)
221 chars
= GetTimeFormatW(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
222 NULL
, szTime
, sizeof(szTime
)/sizeof(WCHAR
));
227 oldFont
= SelectObject(dc
, font
);
228 GetTextExtentPointW(dc
, szTime
, chars
, &extent
);
230 SetBkColor(dc
, BackgroundColor
);
231 SetTextColor(dc
, ShadowColor
);
232 TextOutW(dc
, (x
- extent
.cx
)/2 + SHADOW_DEPTH
, (y
- extent
.cy
)/2 + SHADOW_DEPTH
, szTime
, chars
);
233 SetBkMode(dc
, TRANSPARENT
);
235 SetTextColor(dc
, HandColor
);
236 TextOutW(dc
, (x
- extent
.cx
)/2, (y
- extent
.cy
)/2, szTime
, chars
);
238 SelectObject(dc
, oldFont
);