1 /* 2 * Copyright 1999, Be Incorporated. All Rights Reserved. 3 * This file may be used under the terms of the Be Sample Code License. 4 * 5 */ 6 7 #include "clock.h" 8 #include "cl_view.h" 9 10 11 #include <Alert.h> 12 #include <Bitmap.h> 13 #include <Debug.h> 14 #include <Dragger.h> 15 #include <Entry.h> 16 #include <Resources.h> 17 #include <Roster.h> 18 19 20 #include <time.h> 21 22 23 TOffscreenView::TOffscreenView(BRect frame, const char *name, short mRadius, 24 short hRadius, short offset, long face, bool show) 25 : BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW), 26 fHours(0), 27 fMinutes(0), 28 fSeconds(0), 29 fOffset(offset), 30 fHoursRadius(hRadius), 31 fMinutesRadius(mRadius), 32 fFace(face), 33 fShowSeconds(show), 34 fInner(NULL), 35 fCenter(NULL) 36 { 37 for (short i = 0; i <= 8; i++) 38 fClockFace[i] = NULL; 39 40 status_t error; 41 BResources rsrcs; 42 error = rsrcs.SetToImage(&&dummy_label); 43 dummy_label: 44 if (error == B_OK) { 45 size_t len; 46 void *picH; 47 BRect theRect(0, 0, 82, 82); 48 for (short loop = 0; loop <= 8; loop++) { 49 if ((picH = rsrcs.FindResource('PICT', loop + 4, &len))) { 50 fClockFace[loop] = new BBitmap(theRect, B_CMAP8); 51 fClockFace[loop]->SetBits(picH, len, 0, B_CMAP8); 52 free(picH); 53 } 54 } 55 56 theRect.Set(0,0,15,15); 57 if ((picH = rsrcs.FindResource(B_MINI_ICON_TYPE, "center", &len))) { 58 fCenter = new BBitmap(theRect, B_CMAP8); 59 fCenter->SetBits(picH, len, 0, B_CMAP8); 60 free(picH); 61 } 62 63 theRect.Set(0,0,2,2); 64 if ((picH = rsrcs.FindResource('PICT', 13, &len))) { 65 fInner = new BBitmap(theRect, B_CMAP8); 66 fInner->SetBits(picH, len, 0, B_CMAP8); 67 free(picH); 68 } 69 } 70 71 float x, y; 72 float counter; 73 short index = 0; 74 75 // Generate minutes points array 76 for (counter = 90; counter >= 0; counter -= 6, index++) { 77 x = mRadius * cos(((360 - counter)/180.0) * 3.1415); 78 x += 41; 79 y = mRadius * sin(((360 - counter)/180.0) * 3.1415); 80 y += 41; 81 fMinutePoints[index].Set(x,y); 82 x = hRadius * cos(((360 - counter)/180.0) * 3.1415); 83 x += 41; 84 y = hRadius * sin(((360 - counter)/180.0) * 3.1415); 85 y += 41; 86 fHourPoints[index].Set(x,y); 87 } 88 89 for (counter = 354; counter > 90; counter -= 6,index++) { 90 x = mRadius * cos(((360 - counter)/180.0) * 3.1415); 91 x += 41; 92 y = mRadius * sin(((360 - counter)/180.0) * 3.1415); 93 y += 41; 94 fMinutePoints[index].Set(x,y); 95 x = hRadius * cos(((360 - counter)/180.0) * 3.1415); 96 x += 41; 97 y = hRadius * sin(((360 - counter)/180.0) * 3.1415); 98 y += 41; 99 fHourPoints[index].Set(x,y); 100 } 101 } 102 103 104 void 105 TOffscreenView::NextFace() 106 { 107 fFace++; 108 if (fFace > 8) 109 fFace = 1; 110 }; 111 112 113 void 114 TOffscreenView::DrawX() 115 { 116 ASSERT(Window()); 117 118 if (Window()->Lock()) { 119 if (fClockFace[fFace] != NULL) 120 DrawBitmap(fClockFace[fFace], BPoint(0, 0)); 121 122 // 123 // Draw hands 124 // 125 SetHighColor(0, 0, 0); 126 int32 hours = fHours; 127 if (hours >= 12) 128 hours -= 12; 129 hours *= 5; 130 hours += (fMinutes / 12); 131 SetDrawingMode(B_OP_OVER); 132 StrokeLine(BPoint(fOffset, fOffset), fHourPoints[hours]); 133 134 if (fCenter != NULL) 135 DrawBitmap(fCenter, BPoint(fOffset - 3, fOffset - 3)); 136 StrokeLine(BPoint(fOffset, fOffset), fMinutePoints[fMinutes]); 137 SetHighColor(180, 180, 180); 138 if (fShowSeconds) 139 StrokeLine(BPoint(fOffset, fOffset), fMinutePoints[fSeconds]); 140 SetDrawingMode(B_OP_COPY); 141 if (fInner != NULL) 142 DrawBitmap(fInner, BPoint(fOffset - 1, fOffset - 1)); 143 Sync(); 144 Window()->Unlock(); 145 } 146 } 147 148 149 TOffscreenView::~TOffscreenView() 150 { 151 for (int32 counter = 0; counter <= 8; counter++) 152 delete fClockFace[counter]; 153 }; 154 155 156 // #pragma mark - 157 158 159 TOnscreenView::TOnscreenView(BRect rect, const char *title, short mRadius, 160 short hRadius, short offset) 161 : BView(rect, title, B_FOLLOW_NONE, 162 B_WILL_DRAW | B_PULSE_NEEDED | B_DRAW_ON_CHILDREN), 163 fOffscreen(NULL), 164 fOffscreenView(NULL) 165 { 166 InitObject(rect, mRadius, hRadius, offset, 1, TRUE); 167 168 rect.OffsetTo(B_ORIGIN); 169 rect.top = rect.bottom - 7; 170 rect.left = rect.right - 7; 171 BDragger *dw = new BDragger(rect, this); 172 AddChild(dw); 173 } 174 175 176 void 177 TOnscreenView::InitObject(BRect rect, short mRadius, short hRadius, 178 short offset, long face, bool show) 179 { 180 fOffscreenView = new TOffscreenView(rect, "freqd", mRadius, hRadius, offset, face, show); 181 fOffscreen = new BBitmap(rect, B_CMAP8, true); 182 if (fOffscreen != NULL && fOffscreen->Lock()) { 183 fOffscreen->AddChild(fOffscreenView); 184 fOffscreen->Unlock(); 185 186 fOffscreenView->DrawX(); 187 } 188 } 189 190 191 TOnscreenView::~TOnscreenView() 192 { 193 delete fOffscreen; 194 } 195 196 197 TOnscreenView::TOnscreenView(BMessage *data) 198 : BView(data), 199 fOffscreen(NULL), 200 fOffscreenView(NULL) 201 { 202 InitObject(data->FindRect("bounds"), data->FindInt32("mRadius"), 203 data->FindInt32("hRadius"), data->FindInt32("offset"), 204 data->FindInt32("face"), data->FindBool("seconds")); 205 } 206 207 208 status_t 209 TOnscreenView::Archive(BMessage *data, bool deep) const 210 { 211 status_t status = BView::Archive(data, deep); 212 if (status == B_OK) 213 status = data->AddString("add_on", kAppSignature); 214 215 if (status == B_OK) 216 status = data->AddRect("bounds", Bounds()); 217 218 if (status == B_OK) 219 status = data->AddInt32("mRadius", fOffscreenView->fMinutesRadius); 220 221 if (status == B_OK) 222 status = data->AddInt32("hRadius", fOffscreenView->fHoursRadius); 223 224 if (status == B_OK) 225 status = data->AddInt32("offset", fOffscreenView->fOffset); 226 227 if (status == B_OK) 228 status = data->AddBool("seconds", fOffscreenView->fShowSeconds); 229 230 if (status == B_OK) 231 status = data->AddInt32("face", fOffscreenView->fFace); 232 233 return status; 234 } 235 236 237 BArchivable * 238 TOnscreenView::Instantiate(BMessage *data) 239 { 240 if (!validate_instantiation(data, "TOnscreenView")) 241 return NULL; 242 return new TOnscreenView(data); 243 } 244 245 246 void 247 TOnscreenView::Pulse() 248 { 249 ASSERT(fOffscreen); 250 ASSERT(fOffscreenView); 251 252 time_t current = time(0); 253 struct tm *loctime = localtime(¤t); 254 255 short hours = loctime->tm_hour; 256 short minutes = loctime->tm_min; 257 short seconds = loctime->tm_sec; 258 259 if ((fOffscreenView->fShowSeconds && (seconds != fOffscreenView->fSeconds)) 260 || (minutes != fOffscreenView->fMinutes)) { 261 fOffscreenView->fHours = hours; 262 fOffscreenView->fMinutes = minutes; 263 fOffscreenView->fSeconds = seconds; 264 BRect b = Bounds(); 265 b.InsetBy(12,12); 266 Draw(b); 267 } 268 } 269 270 271 void 272 TOnscreenView::UseFace(short face) 273 { 274 fOffscreenView->fFace = face; 275 BRect b = Bounds(); 276 b.InsetBy(12,12); 277 Draw(b); 278 } 279 280 281 void 282 TOnscreenView::ShowSecs(bool secs) 283 { 284 fOffscreenView->fShowSeconds = secs; 285 BRect b = Bounds(); 286 b.InsetBy(12,12); 287 Invalidate(b); 288 } 289 290 291 short 292 TOnscreenView::ReturnFace() 293 { 294 return fOffscreenView->fFace; 295 } 296 297 298 short 299 TOnscreenView::ReturnSeconds() 300 { 301 return fOffscreenView->fShowSeconds; 302 } 303 304 305 void 306 TOnscreenView::Draw(BRect rect) 307 { 308 ASSERT(fOffscreen); 309 ASSERT(fOffscreenView); 310 311 if (fOffscreen->Lock()) { 312 // Composite the clock offscreen... 313 fOffscreenView->DrawX(); 314 DrawBitmap(fOffscreen, rect, rect); 315 fOffscreen->Unlock(); 316 } 317 }; 318 319 320 void 321 TOnscreenView::MouseDown( BPoint point ) 322 { 323 BPoint cursor; 324 uint32 buttons; 325 BRect bounds = Bounds(); 326 327 GetMouse(&cursor,&buttons); 328 if (buttons & B_SECONDARY_MOUSE_BUTTON) { 329 fOffscreenView->fShowSeconds = !fOffscreenView->fShowSeconds; 330 bounds.InsetBy(12,12); 331 Invalidate(bounds); 332 } else { 333 fOffscreenView->NextFace(); 334 Invalidate(bounds); 335 BView *child = ChildAt(0); 336 if (child) 337 child->Invalidate(); 338 } 339 }; 340 341 342 void 343 TOnscreenView::MessageReceived(BMessage *msg) 344 { 345 switch(msg->what) { 346 case B_ABOUT_REQUESTED: 347 { 348 BAlert *alert = new BAlert("About Clock", 349 "Clock (The Replicant version)\n\n(C)2002, 2003 OpenBeOS,\n" 350 "2004 - 2007, Haiku, Inc.\n\nOriginally coded by the folks " 351 "at Be.\n Copyright Be Inc., 1991 - 1998", "OK"); 352 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 353 alert->Go(); 354 } break; 355 356 default: 357 BView::MessageReceived(msg); 358 } 359 } 360 361