xref: /haiku/src/preferences/time/AnalogClock.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 /*
2 	AnalogClock.cpp
3 		by Mike Berg (inseculous)
4 
5 		Notes:
6 		TOffscreen borrows heavily from the clock source.
7 
8 */
9 
10 #include <Alert.h>
11 #include <Bitmap.h>
12 #include <Debug.h>
13 #include <Dragger.h>
14 #include <Window.h>
15 
16 #include "AnalogClock.h"
17 #include "Bitmaps.h"
18 #include "TimeMessages.h"
19 
20 const BRect kClockRect(0, 0, kClockFaceWidth -1, kClockFaceHeight -1);
21 const BRect kCenterRect(0, 0, kCenterWidth -1, kCenterHeight -1);
22 const BRect kCapRect(0, 0, kCapWidth -1, kCapHeight -1);
23 
24 /*
25 	TOffscreen
26 		Analog Clock face rendering view.
27 */
28 
29 TOffscreen::TOffscreen(BRect frame, const char *name)
30 	: BView(frame, name, B_NOT_RESIZABLE, B_WILL_DRAW)
31 {
32 	f_bitmap = new BBitmap(kClockRect, kClockFaceColorSpace);
33 	f_bitmap->SetBits(kClockFaceBits, (kClockFaceWidth) *(kClockFaceHeight +3), 0, kClockFaceColorSpace);
34 
35 	ReplaceTransparentColor(f_bitmap, ui_color(B_PANEL_BACKGROUND_COLOR));
36 
37 	f_centerbmp = new BBitmap(kCenterRect, kCenterColorSpace);
38 	f_centerbmp->SetBits(kCenterBits, (kCenterWidth) *(kCenterHeight +1), 0, kCenterColorSpace);
39 
40 	f_capbmp = new BBitmap(kCapRect, kCapColorSpace);
41 	f_capbmp->SetBits(kCapBits, (kCapWidth +1) *(kCapHeight +1) +1, 0, kCapColorSpace);
42 
43 	f_center = BPoint(42, 42);
44 
45 	float counter;
46 	short index;
47 	float x, y, mRadius, hRadius;
48 
49 	mRadius = f_center.x -12;
50 	hRadius = mRadius -10;
51 	index = 0;
52 
53 	//
54 	// Generate minutes/hours points array
55 	//
56 	for (counter = 90; counter >= 0; counter -= 6,index++) {
57 		x = mRadius * cos(((360 - counter)/180.0) * 3.1415);
58 		x += f_center.x;
59 		y = mRadius * sin(((360 - counter)/180.0) * 3.1415);
60 		y += f_center.x;
61 		f_MinutePoints[index].Set(x,y);
62 		x = hRadius * cos(((360 - counter)/180.0) * 3.1415);
63 		x += f_center.x;
64 		y = hRadius * sin(((360 - counter)/180.0) * 3.1415);
65 		y += f_center.x;
66 		f_HourPoints[index].Set(x,y);
67 	}
68 	for (counter = 354; counter > 90; counter -= 6,index++) {
69 		x = mRadius * cos(((360 - counter)/180.0) * 3.1415);
70 		x += f_center.x;
71 		y = mRadius * sin(((360 - counter)/180.0) * 3.1415);
72 		y += f_center.x;
73 		f_MinutePoints[index].Set(x,y);
74 		x = hRadius * cos(((360 - counter)/180.0) * 3.1415);
75 		x += f_center.x;
76 		y = hRadius * sin(((360 - counter)/180.0) * 3.1415);
77 		y += f_center.x;
78 		f_HourPoints[index].Set(x,y);
79 	}
80 }
81 
82 
83 TOffscreen::~TOffscreen()
84 {
85 	delete f_bitmap;
86 	delete f_centerbmp;
87 	delete f_capbmp;
88 }
89 
90 
91 void
92 TOffscreen::DrawX()
93 {
94 	if (Window()->Lock()) {
95 
96 		// draw clockface
97 		SetDrawingMode(B_OP_COPY);
98 		DrawBitmap(f_bitmap, BPoint(0, 0));
99 
100 		SetHighColor(0, 0, 0, 255);
101 
102 		short hours = f_Hours;
103 		if (hours>= 12)
104 			hours -= 12;
105 
106 		hours *= 5;
107 		hours += (f_Minutes / 12);
108 
109 		// draw center hub
110 		SetDrawingMode(B_OP_OVER);
111 		DrawBitmap(f_centerbmp, f_center -BPoint(kCenterWidth/2.0, kCenterHeight/2.0));
112 
113 		// draw hands
114 		StrokeLine(f_center, f_HourPoints[hours]);
115 		StrokeLine(f_center, f_MinutePoints[f_Minutes]);
116 		SetHighColor(tint_color(HighColor(), B_LIGHTEN_1_TINT));
117 		StrokeLine(f_center, f_MinutePoints[f_Seconds]);
118 
119 		// draw center cap
120 		DrawBitmap(f_capbmp, f_center -BPoint(kCapWidth/2.0, kCapHeight/2.0));
121 
122  		Sync();
123 		Window()->Unlock();
124 	}
125 }
126 
127 
128 
129 /*
130 	TAnalogClock
131 		BView to display clock face of current time.
132 */
133 
134 TAnalogClock::TAnalogClock(BRect frame, const char *name, uint32 resizingmode, uint32 flags)
135 	: BView(frame, name, resizingmode, flags|B_DRAW_ON_CHILDREN)
136 {
137 	InitView(frame);
138 }
139 
140 
141 TAnalogClock::~TAnalogClock()
142 {
143 	delete f_bitmap;
144 	delete f_offscreen;
145 }
146 
147 
148 void
149 TAnalogClock::InitView(BRect rect)
150 {
151 
152 #if 1
153 	f_offscreen = new TOffscreen(kClockRect, "offscreen");
154 	f_bitmap = new BBitmap(kClockRect, B_COLOR_8_BIT, true);
155 	f_bitmap->Lock();
156 	f_bitmap->AddChild(f_offscreen);
157 	f_bitmap->Unlock();
158 	f_offscreen->DrawX();
159 #endif
160 
161 	// offscreen clock is kClockFaceWidth by kClockFaceHeight
162 	// which might be smaller then TAnalogClock frame so "center" it.
163 	f_drawpt = BPoint(rect.Width()/2.0 -(kClockFaceWidth/2.0),
164 			  rect.Height()/2.0 -(kClockFaceHeight/2.0));
165 }
166 
167 
168 void
169 TAnalogClock::AttachedToWindow()
170 {
171 	if (Parent()) {
172 		SetViewColor(Parent()->ViewColor());
173 	}
174 }
175 
176 
177 void
178 TAnalogClock::MessageReceived(BMessage *message)
179 {
180 	int32 change;
181 	switch(message->what) {
182 		case B_OBSERVER_NOTICE_CHANGE:
183 			message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change);
184 			switch (change) {
185 				case H_TM_CHANGED:
186 				{
187 					int32 hour = 0;
188 					int32 minute = 0;
189 					int32 second = 0;
190 					if (message->FindInt32("hour", &hour) == B_OK
191 					 && message->FindInt32("minute", &minute) == B_OK
192 					 && message->FindInt32("second", &second) == B_OK)
193 						SetTo(hour, minute, second);
194 					break;
195 				}
196 				default:
197 					BView::MessageReceived(message);
198 					break;
199 			}
200 		break;
201 		default:
202 			BView::MessageReceived(message);
203 			break;
204 	}
205 }
206 
207 
208 void
209 TAnalogClock::Draw(BRect updaterect)
210 {
211 	ASSERT(f_offscreen);
212 	ASSERT(f_bitmap);
213 	SetHighColor(0, 100, 10);
214 #ifdef DEBUG
215 	bool b =
216 #endif
217 	         f_bitmap->Lock();
218 	ASSERT(b);
219 	f_offscreen->DrawX();
220 	DrawBitmap(f_bitmap, f_drawpt);
221 	f_bitmap->Unlock();
222 
223 }
224 
225 
226 void
227 TAnalogClock::SetTo(int32 hour, int32 minute, int32 second)
228 {
229 	if (f_offscreen->f_Seconds != second
230 	 || f_offscreen->f_Minutes != minute) {
231 		f_offscreen->f_Hours = hour;
232 		f_offscreen->f_Minutes = minute;
233 		f_offscreen->f_Seconds = second;
234 		Draw(Bounds());
235 	}
236 }
237