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);