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 Black RGB(0,0,0)
36 #define Gray RGB(128,128,128)
37 #define LtGray RGB(192,192,192)
38 #define White RGB(255,255,255)
40 static const COLORREF FaceColor
= LtGray
;
41 static const COLORREF HandColor
= White
;
42 static const COLORREF TickColor
= White
;
43 static const COLORREF ShadowColor
= Black
;
44 static const COLORREF BackgroundColor
= LtGray
;
46 static const int SHADOW_DEPTH
= 2;
54 HandData HourHand
, MinuteHand
, SecondHand
;
56 static void DrawTicks(HDC dc
, const POINT
* centre
, int radius
)
60 /* Minute divisions */
64 centre
->x
+ sin(t
*M_PI
/30)*0.9*radius
,
65 centre
->y
- cos(t
*M_PI
/30)*0.9*radius
,
68 centre
->x
+ sin(t
*M_PI
/30)*0.89*radius
,
69 centre
->y
- cos(t
*M_PI
/30)*0.89*radius
);
76 centre
->x
+ sin(t
*M_PI
/6)*0.9*radius
,
77 centre
->y
- cos(t
*M_PI
/6)*0.9*radius
,
80 centre
->x
+ sin(t
*M_PI
/6)*0.8*radius
,
81 centre
->y
- cos(t
*M_PI
/6)*0.8*radius
);
85 static void DrawFace(HDC dc
, const POINT
* centre
, int radius
, int border
)
88 SelectObject(dc
, CreatePen(PS_SOLID
, 2, ShadowColor
));
89 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
90 DrawTicks(dc
, centre
, radius
);
91 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 2, TickColor
)));
92 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
93 DrawTicks(dc
, centre
, radius
);
96 SelectObject(dc
, GetStockObject(NULL_BRUSH
));
97 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 5, ShadowColor
)));
98 Ellipse(dc
, centre
->x
- radius
, centre
->y
- radius
, centre
->x
+ radius
, centre
->y
+ radius
);
100 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
103 static void DrawHand(HDC dc
,HandData
* hand
)
105 MoveToEx(dc
, hand
->Start
.x
, hand
->Start
.y
, NULL
);
106 LineTo(dc
, hand
->End
.x
, hand
->End
.y
);
109 static void DrawHands(HDC dc
, BOOL bSeconds
)
113 SelectObject(dc
, CreatePen(PS_SOLID
, 1, ShadowColor
));
114 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
115 DrawHand(dc
, &SecondHand
);
116 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
)));
117 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
119 SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
));
121 DrawHand(dc
, &SecondHand
);
122 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
125 SelectObject(dc
, CreatePen(PS_SOLID
, 4, ShadowColor
));
127 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
128 DrawHand(dc
, &MinuteHand
);
129 DrawHand(dc
, &HourHand
);
131 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 4, HandColor
)));
132 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
133 DrawHand(dc
, &MinuteHand
);
134 DrawHand(dc
, &HourHand
);
136 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
139 static void PositionHand(const POINT
* centre
, double length
, double angle
, HandData
* hand
)
141 hand
->Start
= *centre
;
142 hand
->End
.x
= centre
->x
+ sin(angle
)*length
;
143 hand
->End
.y
= centre
->y
- cos(angle
)*length
;
146 static void PositionHands(const POINT
* centre
, int radius
, BOOL bSeconds
)
149 double hour
, minute
, second
;
151 /* 0 <= hour,minute,second < 2pi */
152 /* Adding the millisecond count makes the second hand move more smoothly */
156 second
= st
.wSecond
+ st
.wMilliseconds
/1000.0;
157 minute
= st
.wMinute
+ second
/60.0;
158 hour
= st
.wHour
% 12 + minute
/60.0;
160 PositionHand(centre
, radius
* 0.5, hour
/12 * 2*M_PI
, &HourHand
);
161 PositionHand(centre
, radius
* 0.65, minute
/60 * 2*M_PI
, &MinuteHand
);
163 PositionHand(centre
, radius
* 0.79, second
/60 * 2*M_PI
, &SecondHand
);
166 void AnalogClock(HDC dc
, int x
, int y
, BOOL bSeconds
, BOOL border
)
171 radius
= min(x
, y
)/2 - SHADOW_DEPTH
;
178 DrawFace(dc
, ¢re
, radius
, border
);
180 PositionHands(¢re
, radius
, bSeconds
);
181 DrawHands(dc
, bSeconds
);
185 HFONT
SizeFont(HDC dc
, int x
, int y
, BOOL bSeconds
, const LOGFONT
* font
)
189 double xscale
, yscale
;
190 HFONT oldFont
, newFont
;
194 chars
= GetTimeFormat(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
195 NULL
, szTime
, sizeof (szTime
));
204 x
-= 2 * SHADOW_DEPTH
;
205 y
-= 2 * SHADOW_DEPTH
;
207 oldFont
= SelectObject(dc
, CreateFontIndirect(&lf
));
208 GetTextExtentPoint(dc
, szTime
, chars
, &extent
);
209 DeleteObject(SelectObject(dc
, oldFont
));
211 xscale
= (double)x
/extent
.cx
;
212 yscale
= (double)y
/extent
.cy
;
213 lf
.lfHeight
*= min(xscale
, yscale
);
214 newFont
= CreateFontIndirect(&lf
);
219 void DigitalClock(HDC dc
, int x
, int y
, BOOL bSeconds
, HFONT font
)
226 chars
= GetTimeFormat(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
227 NULL
, szTime
, sizeof (szTime
));
232 oldFont
= SelectObject(dc
, font
);
233 GetTextExtentPoint(dc
, szTime
, chars
, &extent
);
235 SetBkColor(dc
, BackgroundColor
);
236 SetTextColor(dc
, ShadowColor
);
237 TextOut(dc
, (x
- extent
.cx
)/2 + SHADOW_DEPTH
, (y
- extent
.cy
)/2 + SHADOW_DEPTH
,
239 SetBkMode(dc
, TRANSPARENT
);
241 SetTextColor(dc
, HandColor
);
242 TextOut(dc
, (x
- extent
.cx
)/2, (y
- extent
.cy
)/2, szTime
, chars
);
244 SelectObject(dc
, oldFont
);