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
28 #include "wine/port.h"
37 #define M_PI 3.14159265
39 #define Black RGB(0,0,0)
40 #define Gray RGB(128,128,128)
41 #define LtGray RGB(192,192,192)
42 #define White RGB(255,255,255)
44 static const COLORREF FaceColor
= LtGray
;
45 static const COLORREF HandColor
= White
;
46 static const COLORREF TickColor
= White
;
47 static const COLORREF ShadowColor
= Black
;
48 static const COLORREF BackgroundColor
= LtGray
;
50 static const int SHADOW_DEPTH
= 2;
58 HandData HourHand
, MinuteHand
, SecondHand
;
60 static void DrawTicks(HDC dc
, const POINT
* centre
, int radius
)
64 /* Minute divisions */
68 centre
->x
+ sin(t
*M_PI
/30)*0.9*radius
,
69 centre
->y
- cos(t
*M_PI
/30)*0.9*radius
,
72 centre
->x
+ sin(t
*M_PI
/30)*0.89*radius
,
73 centre
->y
- cos(t
*M_PI
/30)*0.89*radius
);
80 centre
->x
+ sin(t
*M_PI
/6)*0.9*radius
,
81 centre
->y
- cos(t
*M_PI
/6)*0.9*radius
,
84 centre
->x
+ sin(t
*M_PI
/6)*0.8*radius
,
85 centre
->y
- cos(t
*M_PI
/6)*0.8*radius
);
89 static void DrawFace(HDC dc
, const POINT
* centre
, int radius
, int border
)
92 SelectObject(dc
, CreatePen(PS_SOLID
, 2, ShadowColor
));
93 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
94 DrawTicks(dc
, centre
, radius
);
95 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 2, TickColor
)));
96 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
97 DrawTicks(dc
, centre
, radius
);
100 SelectObject(dc
, GetStockObject(NULL_BRUSH
));
101 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 5, ShadowColor
)));
102 Ellipse(dc
, centre
->x
- radius
, centre
->y
- radius
, centre
->x
+ radius
, centre
->y
+ radius
);
104 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
107 static void DrawHand(HDC dc
,HandData
* hand
)
109 MoveToEx(dc
, hand
->Start
.x
, hand
->Start
.y
, NULL
);
110 LineTo(dc
, hand
->End
.x
, hand
->End
.y
);
113 static void DrawHands(HDC dc
, BOOL bSeconds
)
117 SelectObject(dc
, CreatePen(PS_SOLID
, 1, ShadowColor
));
118 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
119 DrawHand(dc
, &SecondHand
);
120 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
)));
121 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
123 SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
));
125 DrawHand(dc
, &SecondHand
);
126 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
129 SelectObject(dc
, CreatePen(PS_SOLID
, 4, ShadowColor
));
131 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
132 DrawHand(dc
, &MinuteHand
);
133 DrawHand(dc
, &HourHand
);
135 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 4, HandColor
)));
136 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
137 DrawHand(dc
, &MinuteHand
);
138 DrawHand(dc
, &HourHand
);
140 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
143 static void PositionHand(const POINT
* centre
, double length
, double angle
, HandData
* hand
)
145 hand
->Start
= *centre
;
146 hand
->End
.x
= centre
->x
+ sin(angle
)*length
;
147 hand
->End
.y
= centre
->y
- cos(angle
)*length
;
150 static void PositionHands(const POINT
* centre
, int radius
, BOOL bSeconds
)
153 double hour
, minute
, second
;
155 /* 0 <= hour,minute,second < 2pi */
156 /* Adding the millisecond count makes the second hand move more smoothly */
160 second
= st
.wSecond
+ st
.wMilliseconds
/1000.0;
161 minute
= st
.wMinute
+ second
/60.0;
162 hour
= st
.wHour
% 12 + minute
/60.0;
164 PositionHand(centre
, radius
* 0.5, hour
/12 * 2*M_PI
, &HourHand
);
165 PositionHand(centre
, radius
* 0.65, minute
/60 * 2*M_PI
, &MinuteHand
);
167 PositionHand(centre
, radius
* 0.79, second
/60 * 2*M_PI
, &SecondHand
);
170 void AnalogClock(HDC dc
, int x
, int y
, BOOL bSeconds
, BOOL border
)
175 radius
= min(x
, y
)/2 - SHADOW_DEPTH
;
182 DrawFace(dc
, ¢re
, radius
, border
);
184 PositionHands(¢re
, radius
, bSeconds
);
185 DrawHands(dc
, bSeconds
);
189 HFONT
SizeFont(HDC dc
, int x
, int y
, BOOL bSeconds
, const LOGFONT
* font
)
193 double xscale
, yscale
;
194 HFONT oldFont
, newFont
;
198 chars
= GetTimeFormat(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
199 NULL
, szTime
, sizeof (szTime
));
208 x
-= 2 * SHADOW_DEPTH
;
209 y
-= 2 * SHADOW_DEPTH
;
211 oldFont
= SelectObject(dc
, CreateFontIndirect(&lf
));
212 GetTextExtentPoint(dc
, szTime
, chars
, &extent
);
213 DeleteObject(SelectObject(dc
, oldFont
));
215 xscale
= (double)x
/extent
.cx
;
216 yscale
= (double)y
/extent
.cy
;
217 lf
.lfHeight
*= min(xscale
, yscale
);
218 newFont
= CreateFontIndirect(&lf
);
223 void DigitalClock(HDC dc
, int x
, int y
, BOOL bSeconds
, HFONT font
)
230 chars
= GetTimeFormat(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
231 NULL
, szTime
, sizeof (szTime
));
236 oldFont
= SelectObject(dc
, font
);
237 GetTextExtentPoint(dc
, szTime
, chars
, &extent
);
239 SetBkColor(dc
, BackgroundColor
);
240 SetTextColor(dc
, ShadowColor
);
241 TextOut(dc
, (x
- extent
.cx
)/2 + SHADOW_DEPTH
, (y
- extent
.cy
)/2 + SHADOW_DEPTH
,
243 SetBkMode(dc
, TRANSPARENT
);
245 SetTextColor(dc
, HandColor
);
246 TextOut(dc
, (x
- extent
.cx
)/2, (y
- extent
.cy
)/2, szTime
, chars
);
248 SelectObject(dc
, oldFont
);