1 /* 2 3 cl_view.cpp 4 5 */ 6 7 /* 8 Copyright 1999, Be Incorporated. All Rights Reserved. 9 This file may be used under the terms of the Be Sample Code License. 10 */ 11 12 #define DEBUG 1 13 #include <string.h> 14 #include <stdlib.h> 15 16 #include <time.h> 17 #include "clock.h" 18 #include "cl_view.h" 19 #include <float.h> 20 #include <math.h> 21 22 #include <Debug.h> 23 #include <Application.h> 24 #include <Roster.h> 25 #include <Alert.h> 26 #include <Entry.h> 27 #include <Resources.h> 28 29 /* ---------------------------------------------------------------- */ 30 31 TOffscreenView::TOffscreenView(BRect frame, char *name, short mRadius, 32 short hRadius, short offset, long face, bool show) 33 :BView(frame, name, B_NOT_RESIZABLE, B_WILL_DRAW) 34 { 35 BRect theRect; 36 short loop; 37 void *picH; 38 size_t len; 39 float counter; 40 short index; 41 float x,y; 42 entry_ref ref; 43 long error; 44 45 fFace = face; 46 theRect.Set(0,0,82,82); 47 48 for (index = 0; index <= 8; index++) 49 fClockFace[index] = NULL; 50 51 //+ error = get_ref_for_path("/boot/apps/Clock", &ref); 52 error = be_roster->FindApp(app_signature, &ref); 53 54 if (error == B_NO_ERROR) { 55 BFile file(&ref, O_RDONLY); 56 if (file.InitCheck() == B_NO_ERROR) { 57 BResources rsrcs(&file); 58 error = 0; 59 60 for (loop = 0; loop <= 8; loop++) { 61 if ((picH = rsrcs.FindResource('PICT', loop+4, &len))) { 62 fClockFace[loop] = new BBitmap(theRect,B_COLOR_8_BIT); 63 fClockFace[loop]->SetBits(picH,len,0,B_COLOR_8_BIT); 64 free(picH); 65 } else { 66 error = 1; 67 } 68 } 69 70 theRect.Set(0,0,15,15); 71 if ((picH = rsrcs.FindResource('MICN', "center", &len))) { 72 fCenter = new BBitmap(theRect,B_COLOR_8_BIT); 73 fCenter->SetBits(picH,len,0,B_COLOR_8_BIT); 74 free(picH); 75 } else { 76 error = 1; 77 } 78 79 theRect.Set(0,0,2,2); 80 if ((picH = rsrcs.FindResource('PICT', 13, &len))) { 81 fInner = new BBitmap(theRect,B_COLOR_8_BIT); 82 fInner->SetBits(picH,len,0,B_COLOR_8_BIT); 83 free(picH); 84 } else { 85 error = 1; 86 } 87 88 if (error) { 89 // ??? yikes. This is terrible. No good way to signal error 90 // from here. How do we properly cleanup up here? Need to 91 // make sure the app_server side also gets cleaned up! 92 93 BAlert *alert = new BAlert("Error", "Clock: Could not find necessary resources.", "Quit"); 94 alert->Go(); 95 delete this; 96 exit(1); 97 } 98 } 99 } else { 100 exit(1); 101 } 102 103 fMinutesRadius = mRadius; 104 fHoursRadius = hRadius; 105 fOffset = offset; 106 fHours = 0; 107 fMinutes = 0; 108 fSeconds = 0; 109 fShowSeconds = show; 110 111 index = 0; 112 113 // 114 // Generate minutes points array 115 // 116 for (counter = 90; counter >= 0; counter -= 6,index++) { 117 x = mRadius * cos(((360 - counter)/180.0) * 3.1415); 118 x += 41; 119 y = mRadius * sin(((360 - counter)/180.0) * 3.1415); 120 y += 41; 121 fMinutePoints[index].Set(x,y); 122 x = hRadius * cos(((360 - counter)/180.0) * 3.1415); 123 x += 41; 124 y = hRadius * sin(((360 - counter)/180.0) * 3.1415); 125 y += 41; 126 fHourPoints[index].Set(x,y); 127 } 128 for (counter = 354; counter > 90; counter -= 6,index++) { 129 x = mRadius * cos(((360 - counter)/180.0) * 3.1415); 130 x += 41; 131 y = mRadius * sin(((360 - counter)/180.0) * 3.1415); 132 y += 41; 133 fMinutePoints[index].Set(x,y); 134 x = hRadius * cos(((360 - counter)/180.0) * 3.1415); 135 x += 41; 136 y = hRadius * sin(((360 - counter)/180.0) * 3.1415); 137 y += 41; 138 fHourPoints[index].Set(x,y); 139 } 140 } 141 142 /* ---------------------------------------------------------------- */ 143 144 void TOffscreenView::NextFace() 145 { 146 fFace++; 147 if (fFace > 8) 148 fFace = 1; 149 }; 150 151 /* ---------------------------------------------------------------- */ 152 153 void TOffscreenView::AttachedToWindow() 154 { 155 SetFontSize(18); 156 SetFont(be_plain_font); 157 } 158 159 /* ---------------------------------------------------------------- */ 160 161 void TOffscreenView::DrawX() 162 { 163 //BRect bound; 164 short hours; 165 166 ASSERT(Window()); 167 168 if (Window()->Lock()) { 169 DrawBitmap(fClockFace[fFace],BPoint(0,0)); 170 171 // 172 // Draw hands 173 // 174 SetHighColor(0,0,0); 175 hours = fHours; 176 if (hours >= 12) 177 hours -= 12; 178 hours *= 5; 179 hours += (fMinutes / 12); 180 StrokeLine(BPoint(fOffset,fOffset),fHourPoints[hours]); 181 SetDrawingMode(B_OP_OVER); 182 183 DrawBitmap(fCenter,BPoint(fOffset-3,fOffset-3)); 184 SetDrawingMode(B_OP_COPY); 185 StrokeLine(BPoint(fOffset,fOffset),fMinutePoints[fMinutes]); 186 SetHighColor(180,180,180); 187 if (fShowSeconds) 188 StrokeLine(BPoint(fOffset,fOffset),fMinutePoints[fSeconds]); 189 DrawBitmap(fInner,BPoint(fOffset-1,fOffset-1)); 190 Sync(); 191 Window()->Unlock(); 192 } 193 } 194 195 /* ---------------------------------------------------------------- */ 196 197 TOffscreenView::~TOffscreenView() 198 { 199 short counter; 200 201 for (counter = 0; counter <= 8; counter++) 202 delete fClockFace[counter]; 203 }; 204 205 /* ---------------------------------------------------------------- */ 206 /* ---------------------------------------------------------------- */ 207 /* ---------------------------------------------------------------- */ 208 209 #include <Dragger.h> 210 211 /* 212 * Onscreen view object 213 */ 214 TOnscreenView::TOnscreenView(BRect rect, char *title, 215 short mRadius, short hRadius, short offset) 216 :BView(rect, title, B_NOT_RESIZABLE, 217 B_WILL_DRAW | B_PULSE_NEEDED | B_DRAW_ON_CHILDREN) 218 { 219 InitObject(rect, mRadius, hRadius, offset, 1, TRUE); 220 221 BRect r = rect; 222 r.OffsetTo(B_ORIGIN); 223 r.top = r.bottom - 7; 224 r.left = r.right - 7; 225 226 BDragger *dw = new BDragger(r, this, 0); 227 AddChild(dw); 228 } 229 230 void TOnscreenView::InitObject(BRect rect, short mRadius, short hRadius, 231 short offset, long face, bool show) 232 { 233 fmRadius = mRadius; 234 fhRadius = hRadius; 235 fOffset = offset; 236 fRect = rect; 237 OffscreenView = NULL; 238 Offscreen = NULL; 239 240 #if 1 241 OffscreenView = new TOffscreenView(rect, "freqd",mRadius,hRadius, 242 offset, face, show); 243 Offscreen = new BBitmap(rect, B_COLOR_8_BIT, TRUE); 244 Offscreen->Lock(); 245 Offscreen->AddChild(OffscreenView); 246 Offscreen->Unlock(); 247 OffscreenView->DrawX(); 248 #endif 249 } 250 251 /* ---------------------------------------------------------------- */ 252 253 TOnscreenView::~TOnscreenView() 254 { 255 delete Offscreen; 256 } 257 258 /* ---------------------------------------------------------------- */ 259 260 TOnscreenView::TOnscreenView(BMessage *data) 261 : BView(data) 262 { 263 InitObject(data->FindRect("bounds"), data->FindInt32("mRadius"), 264 data->FindInt32("hRadius"), data->FindInt32("offset"), 265 data->FindInt32("face"), data->FindBool("seconds")); 266 } 267 268 /* ---------------------------------------------------------------- */ 269 270 status_t TOnscreenView::Archive(BMessage *data, bool deep) const 271 { 272 inherited::Archive(data, deep); 273 data->AddString("add_on", app_signature); 274 //+ data->AddString("add_on_path", "/boot/apps/Clock"); 275 276 data->AddRect("bounds", Bounds()); 277 data->AddInt32("mRadius", OffscreenView->fMinutesRadius); 278 data->AddInt32("hRadius", OffscreenView->fHoursRadius); 279 data->AddInt32("offset", OffscreenView->fOffset); 280 data->AddBool("seconds", OffscreenView->fShowSeconds); 281 data->AddInt32("face", OffscreenView->fFace); 282 return 0; 283 } 284 285 /* ---------------------------------------------------------------- */ 286 287 BArchivable *TOnscreenView::Instantiate(BMessage *data) 288 { 289 if (!validate_instantiation(data, "TOnscreenView")) 290 return NULL; 291 return new TOnscreenView(data); 292 } 293 294 /* ---------------------------------------------------------------- */ 295 296 void TOnscreenView::AttachedToWindow() 297 { 298 //+ PRINT(("InitData m=%d, h=%d, offset=%d\n", fmRadius, fhRadius, fOffset)); 299 //+ PRINT_OBJECT(fRect); 300 } 301 302 /* ---------------------------------------------------------------- */ 303 304 void TOnscreenView::Pulse() 305 { 306 short hours,minutes,seconds; 307 struct tm *loctime; 308 time_t current; 309 310 ASSERT(Offscreen); 311 ASSERT(OffscreenView); 312 current = time(0); 313 loctime = localtime(¤t); 314 hours = loctime->tm_hour; 315 minutes = loctime->tm_min; 316 seconds = loctime->tm_sec; 317 318 if ((OffscreenView->fShowSeconds && (seconds != OffscreenView->fSeconds)) || 319 (minutes != OffscreenView->fMinutes)) { 320 OffscreenView->fHours = hours; 321 OffscreenView->fMinutes = minutes; 322 OffscreenView->fSeconds = seconds; 323 BRect b = Bounds(); 324 b.InsetBy(12,12); 325 Draw(b); 326 } 327 } 328 329 /* ---------------------------------------------------------------- */ 330 331 void TOnscreenView::UseFace( short face ) 332 { 333 OffscreenView->fFace = face; 334 BRect b = Bounds(); 335 b.InsetBy(12,12); 336 Draw(b); 337 } 338 339 /* ---------------------------------------------------------------- */ 340 341 void TOnscreenView::ShowSecs( bool secs ) 342 { 343 OffscreenView->fShowSeconds = secs; 344 BRect b = Bounds(); 345 b.InsetBy(12,12); 346 Invalidate(b); 347 } 348 349 /* ---------------------------------------------------------------- */ 350 351 short TOnscreenView::ReturnFace( void ) 352 { 353 return(OffscreenView->fFace); 354 } 355 356 /* ---------------------------------------------------------------- */ 357 358 short TOnscreenView::ReturnSeconds( void ) 359 { 360 return(OffscreenView->fShowSeconds); 361 } 362 363 /* ---------------------------------------------------------------- */ 364 365 void TOnscreenView::Draw(BRect rect) 366 { 367 time_t current; 368 ASSERT(Offscreen); 369 ASSERT(OffscreenView); 370 371 bool b = Offscreen->Lock(); 372 ASSERT(b); 373 OffscreenView->DrawX(); // Composite the clock offscreen... 374 DrawBitmap(Offscreen, rect, rect); 375 Offscreen->Unlock(); 376 377 current = time(0); 378 }; 379 380 /* ---------------------------------------------------------------- */ 381 382 void TOnscreenView::MouseDown( BPoint point ) 383 { 384 BPoint cursor; 385 ulong buttons; 386 BRect bounds = Bounds(); 387 388 GetMouse(&cursor,&buttons); 389 if (buttons & 0x2) { 390 OffscreenView->fShowSeconds = !OffscreenView->fShowSeconds; 391 be_app->PostMessage(SHOW_SECONDS); 392 bounds.InsetBy(12,12); 393 Draw(bounds); 394 } else { 395 OffscreenView->NextFace(); 396 Draw(bounds); 397 BView *c = ChildAt(0); 398 if (c) 399 c->Draw(c->Bounds()); 400 } 401 }; 402 403 /* ---------------------------------------------------------------- */ 404 405 void 406 TOnscreenView::MessageReceived(BMessage *msg) 407 { 408 switch(msg->what) { 409 case B_ABOUT_REQUESTED: 410 (new BAlert("About Clock", "Clock (The Replicant version)\n\n(C)2002 OpenBeOS\n\nOriginally coded by the folks at Be.\n Copyright Be Inc., 1991-1998","OK"))->Go(); 411 break; 412 default: 413 inherited::MessageReceived(msg); 414 } 415 } 416