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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
)
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
);
95 DeleteObject(SelectObject(dc
, GetStockObject(NULL_BRUSH
)));
96 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
99 static void DrawHand(HDC dc
,HandData
* hand
)
101 MoveToEx(dc
, hand
->Start
.x
, hand
->Start
.y
, NULL
);
102 LineTo(dc
, hand
->End
.x
, hand
->End
.y
);
105 static void DrawHands(HDC dc
, BOOL bSeconds
)
109 SelectObject(dc
, CreatePen(PS_SOLID
, 1, ShadowColor
));
110 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
111 DrawHand(dc
, &SecondHand
);
112 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
)));
113 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
115 SelectObject(dc
, CreatePen(PS_SOLID
, 1, HandColor
));
117 DrawHand(dc
, &SecondHand
);
118 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
121 SelectObject(dc
, CreatePen(PS_SOLID
, 4, ShadowColor
));
123 OffsetWindowOrgEx(dc
, -SHADOW_DEPTH
, -SHADOW_DEPTH
, NULL
);
124 DrawHand(dc
, &MinuteHand
);
125 DrawHand(dc
, &HourHand
);
127 DeleteObject(SelectObject(dc
, CreatePen(PS_SOLID
, 4, HandColor
)));
128 OffsetWindowOrgEx(dc
, SHADOW_DEPTH
, SHADOW_DEPTH
, NULL
);
129 DrawHand(dc
, &MinuteHand
);
130 DrawHand(dc
, &HourHand
);
132 DeleteObject(SelectObject(dc
, GetStockObject(NULL_PEN
)));
135 static void PositionHand(const POINT
* centre
, double length
, double angle
, HandData
* hand
)
137 hand
->Start
= *centre
;
138 hand
->End
.x
= centre
->x
+ sin(angle
)*length
;
139 hand
->End
.y
= centre
->y
- cos(angle
)*length
;
142 static void PositionHands(const POINT
* centre
, int radius
, BOOL bSeconds
)
145 double hour
, minute
, second
;
147 /* 0 <= hour,minute,second < 2pi */
148 /* Adding the millisecond count makes the second hand move more smoothly */
152 second
= st
.wSecond
+ st
.wMilliseconds
/1000.0;
153 minute
= st
.wMinute
+ second
/60.0;
154 hour
= st
.wHour
% 12 + minute
/60.0;
156 PositionHand(centre
, radius
* 0.5, hour
/12 * 2*M_PI
, &HourHand
);
157 PositionHand(centre
, radius
* 0.65, minute
/60 * 2*M_PI
, &MinuteHand
);
159 PositionHand(centre
, radius
* 0.79, second
/60 * 2*M_PI
, &SecondHand
);
162 void AnalogClock(HDC dc
, int x
, int y
, BOOL bSeconds
)
167 radius
= min(x
, y
)/2 - SHADOW_DEPTH
;
174 DrawFace(dc
, ¢re
, radius
);
176 PositionHands(¢re
, radius
, bSeconds
);
177 DrawHands(dc
, bSeconds
);
181 HFONT
SizeFont(HDC dc
, int x
, int y
, BOOL bSeconds
, const LOGFONT
* font
)
185 double xscale
, yscale
;
186 HFONT oldFont
, newFont
;
190 chars
= GetTimeFormat(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
191 NULL
, szTime
, sizeof (szTime
));
200 x
-= 2 * SHADOW_DEPTH
;
201 y
-= 2 * SHADOW_DEPTH
;
203 oldFont
= SelectObject(dc
, CreateFontIndirect(&lf
));
204 GetTextExtentPoint(dc
, szTime
, chars
, &extent
);
205 DeleteObject(SelectObject(dc
, oldFont
));
207 xscale
= (double)x
/extent
.cx
;
208 yscale
= (double)y
/extent
.cy
;
209 lf
.lfHeight
*= min(xscale
, yscale
);
210 newFont
= CreateFontIndirect(&lf
);
215 void DigitalClock(HDC dc
, int x
, int y
, BOOL bSeconds
, HFONT font
)
222 chars
= GetTimeFormat(LOCALE_USER_DEFAULT
, bSeconds
? 0 : TIME_NOSECONDS
, NULL
,
223 NULL
, szTime
, sizeof (szTime
));
228 oldFont
= SelectObject(dc
, font
);
229 GetTextExtentPoint(dc
, szTime
, chars
, &extent
);
231 SetBkColor(dc
, BackgroundColor
);
232 SetTextColor(dc
, ShadowColor
);
233 TextOut(dc
, (x
- extent
.cx
)/2 + SHADOW_DEPTH
, (y
- extent
.cy
)/2 + SHADOW_DEPTH
,
235 SetBkMode(dc
, TRANSPARENT
);
237 SetTextColor(dc
, HandColor
);
238 TextOut(dc
, (x
- extent
.cx
)/2, (y
- extent
.cy
)/2, szTime
, chars
);
240 SelectObject(dc
, oldFont
);