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 <float.h> 14 #include <math.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <time.h> 18 19 #include <Alert.h> 20 #include <Application.h> 21 #include <Debug.h> 22 #include <Dragger.h> 23 #include <Entry.h> 24 #include <Resources.h> 25 #include <Roster.h> 26 27 #include "clock.h" 28 #include "cl_view.h" 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 #ifdef __HAIKU__ 52 BResources rsrcs; 53 error = rsrcs.SetToImage(&&dummy_label); 54 dummy_label: 55 if (error == B_OK) { 56 { 57 #else // !__HAIKU__ 58 // Note: Since we can be run as replicant, we get our resources this way, 59 // not via be_app->AppResources(). 60 error = be_roster->FindApp(app_signature, &ref); 61 printf("be_roster->FindApp() returned %s\n", strerror(error)); 62 if (error == B_NO_ERROR) { 63 BFile file(&ref, O_RDONLY); 64 error = file.InitCheck(); 65 if (error == B_NO_ERROR) { 66 BResources rsrcs(&file); 67 #endif // !__HAIKU__ 68 69 for (loop = 0; loop <= 8; loop++) { 70 if ((picH = rsrcs.FindResource('PICT', loop+4, &len))) { 71 fClockFace[loop] = new BBitmap(theRect, B_CMAP8); 72 fClockFace[loop]->SetBits(picH,len,0, B_CMAP8); 73 free(picH); 74 } 75 } 76 77 theRect.Set(0,0,15,15); 78 if ((picH = rsrcs.FindResource('MICN', "center", &len))) { 79 fCenter = new BBitmap(theRect, B_CMAP8); 80 fCenter->SetBits(picH,len,0, B_CMAP8); 81 free(picH); 82 } 83 84 theRect.Set(0,0,2,2); 85 if ((picH = rsrcs.FindResource('PICT', 13, &len))) { 86 fInner = new BBitmap(theRect, B_CMAP8); 87 fInner->SetBits(picH,len,0, B_CMAP8); 88 free(picH); 89 } 90 } 91 } 92 93 fMinutesRadius = mRadius; 94 fHoursRadius = hRadius; 95 fOffset = offset; 96 fHours = 0; 97 fMinutes = 0; 98 fSeconds = 0; 99 fShowSeconds = show; 100 101 index = 0; 102 103 // 104 // Generate minutes points array 105 // 106 for (counter = 90; counter >= 0; counter -= 6,index++) { 107 x = mRadius * cos(((360 - counter)/180.0) * 3.1415); 108 x += 41; 109 y = mRadius * sin(((360 - counter)/180.0) * 3.1415); 110 y += 41; 111 fMinutePoints[index].Set(x,y); 112 x = hRadius * cos(((360 - counter)/180.0) * 3.1415); 113 x += 41; 114 y = hRadius * sin(((360 - counter)/180.0) * 3.1415); 115 y += 41; 116 fHourPoints[index].Set(x,y); 117 } 118 for (counter = 354; counter > 90; counter -= 6,index++) { 119 x = mRadius * cos(((360 - counter)/180.0) * 3.1415); 120 x += 41; 121 y = mRadius * sin(((360 - counter)/180.0) * 3.1415); 122 y += 41; 123 fMinutePoints[index].Set(x,y); 124 x = hRadius * cos(((360 - counter)/180.0) * 3.1415); 125 x += 41; 126 y = hRadius * sin(((360 - counter)/180.0) * 3.1415); 127 y += 41; 128 fHourPoints[index].Set(x,y); 129 } 130 } 131 132 133 void 134 TOffscreenView::NextFace() 135 { 136 fFace++; 137 if (fFace > 8) 138 fFace = 1; 139 }; 140 141 142 void 143 TOffscreenView::AttachedToWindow() 144 { 145 SetFontSize(18); 146 SetFont(be_plain_font); 147 } 148 149 150 void 151 TOffscreenView::DrawX() 152 { 153 ASSERT(Window()); 154 155 if (Window()->Lock()) { 156 if (fClockFace != NULL) 157 DrawBitmap(fClockFace[fFace], BPoint(0, 0)); 158 159 // 160 // Draw hands 161 // 162 SetHighColor(0, 0, 0); 163 int32 hours = fHours; 164 if (hours >= 12) 165 hours -= 12; 166 hours *= 5; 167 hours += (fMinutes / 12); 168 SetDrawingMode(B_OP_OVER); 169 StrokeLine(BPoint(fOffset, fOffset), fHourPoints[hours]); 170 171 if (fCenter != NULL) 172 DrawBitmap(fCenter, BPoint(fOffset - 3, fOffset - 3)); 173 StrokeLine(BPoint(fOffset, fOffset), fMinutePoints[fMinutes]); 174 SetHighColor(180, 180, 180); 175 if (fShowSeconds) 176 StrokeLine(BPoint(fOffset, fOffset), fMinutePoints[fSeconds]); 177 SetDrawingMode(B_OP_COPY); 178 if (fInner != NULL) 179 DrawBitmap(fInner, BPoint(fOffset - 1, fOffset - 1)); 180 Sync(); 181 Window()->Unlock(); 182 } 183 } 184 185 186 TOffscreenView::~TOffscreenView() 187 { 188 for (int32 counter = 0; counter <= 8; counter++) 189 delete fClockFace[counter]; 190 }; 191 192 193 /* 194 * Onscreen view object 195 */ 196 TOnscreenView::TOnscreenView(BRect rect, char *title, 197 short mRadius, short hRadius, short offset) 198 :BView(rect, title, B_NOT_RESIZABLE, 199 B_WILL_DRAW | B_PULSE_NEEDED | B_DRAW_ON_CHILDREN) 200 { 201 InitObject(rect, mRadius, hRadius, offset, 1, TRUE); 202 203 BRect r = rect; 204 r.OffsetTo(B_ORIGIN); 205 r.top = r.bottom - 7; 206 r.left = r.right - 7; 207 208 BDragger *dw = new BDragger(r, this, 0); 209 AddChild(dw); 210 } 211 212 213 void 214 TOnscreenView::InitObject(BRect rect, short mRadius, short hRadius, 215 short offset, long face, bool show) 216 { 217 fmRadius = mRadius; 218 fhRadius = hRadius; 219 fOffset = offset; 220 fRect = rect; 221 fOffscreenView = NULL; 222 fOffscreen = NULL; 223 224 fOffscreenView = new TOffscreenView(rect, "freqd",mRadius,hRadius, offset, face, show); 225 fOffscreen = new BBitmap(rect, B_CMAP8, true); 226 if (fOffscreen != NULL && fOffscreen->Lock()) { 227 fOffscreen->AddChild(fOffscreenView); 228 fOffscreen->Unlock(); 229 230 fOffscreenView->DrawX(); 231 } 232 } 233 234 235 TOnscreenView::~TOnscreenView() 236 { 237 delete fOffscreen; 238 } 239 240 241 TOnscreenView::TOnscreenView(BMessage *data) 242 : BView(data) 243 { 244 InitObject(data->FindRect("bounds"), data->FindInt32("mRadius"), 245 data->FindInt32("hRadius"), data->FindInt32("offset"), 246 data->FindInt32("face"), data->FindBool("seconds")); 247 } 248 249 250 status_t 251 TOnscreenView::Archive(BMessage *data, bool deep) const 252 { 253 inherited::Archive(data, deep); 254 data->AddString("add_on", app_signature); 255 //+ data->AddString("add_on_path", "/boot/apps/Clock"); 256 257 data->AddRect("bounds", Bounds()); 258 data->AddInt32("mRadius", fOffscreenView->fMinutesRadius); 259 data->AddInt32("hRadius", fOffscreenView->fHoursRadius); 260 data->AddInt32("offset", fOffscreenView->fOffset); 261 data->AddBool("seconds", fOffscreenView->fShowSeconds); 262 data->AddInt32("face", fOffscreenView->fFace); 263 return 0; 264 } 265 266 267 BArchivable * 268 TOnscreenView::Instantiate(BMessage *data) 269 { 270 if (!validate_instantiation(data, "TOnscreenView")) 271 return NULL; 272 return new TOnscreenView(data); 273 } 274 275 276 void 277 TOnscreenView::AttachedToWindow() 278 { 279 //+ PRINT(("InitData m=%d, h=%d, offset=%d\n", fmRadius, fhRadius, fOffset)); 280 //+ PRINT_OBJECT(fRect); 281 } 282 283 284 void 285 TOnscreenView::Pulse() 286 { 287 short hours,minutes,seconds; 288 struct tm *loctime; 289 time_t current; 290 291 ASSERT(fOffscreen); 292 ASSERT(fOffscreenView); 293 current = time(0); 294 loctime = localtime(¤t); 295 hours = loctime->tm_hour; 296 minutes = loctime->tm_min; 297 seconds = loctime->tm_sec; 298 299 if ((fOffscreenView->fShowSeconds && (seconds != fOffscreenView->fSeconds)) || 300 (minutes != fOffscreenView->fMinutes)) { 301 fOffscreenView->fHours = hours; 302 fOffscreenView->fMinutes = minutes; 303 fOffscreenView->fSeconds = seconds; 304 BRect b = Bounds(); 305 b.InsetBy(12,12); 306 Draw(b); 307 } 308 } 309 310 311 void 312 TOnscreenView::UseFace( short face ) 313 { 314 fOffscreenView->fFace = face; 315 BRect b = Bounds(); 316 b.InsetBy(12,12); 317 Draw(b); 318 } 319 320 321 void 322 TOnscreenView::ShowSecs( bool secs ) 323 { 324 fOffscreenView->fShowSeconds = secs; 325 BRect b = Bounds(); 326 b.InsetBy(12,12); 327 Invalidate(b); 328 } 329 330 331 short 332 TOnscreenView::ReturnFace( void ) 333 { 334 return(fOffscreenView->fFace); 335 } 336 337 338 short 339 TOnscreenView::ReturnSeconds( void ) 340 { 341 return(fOffscreenView->fShowSeconds); 342 } 343 344 345 void 346 TOnscreenView::Draw(BRect rect) 347 { 348 ASSERT(fOffscreen); 349 ASSERT(fOffscreenView); 350 351 if (fOffscreen->Lock()) { 352 fOffscreenView->DrawX(); // Composite the clock offscreen... 353 DrawBitmap(fOffscreen, rect, rect); 354 fOffscreen->Unlock(); 355 } 356 }; 357 358 359 void 360 TOnscreenView::MouseDown( BPoint point ) 361 { 362 BPoint cursor; 363 ulong buttons; 364 BRect bounds = Bounds(); 365 366 GetMouse(&cursor,&buttons); 367 if (buttons & B_SECONDARY_MOUSE_BUTTON) { 368 fOffscreenView->fShowSeconds = !fOffscreenView->fShowSeconds; 369 be_app->PostMessage(SHOW_SECONDS); 370 bounds.InsetBy(12,12); 371 Invalidate(bounds); 372 } else { 373 fOffscreenView->NextFace(); 374 Invalidate(bounds); 375 BView *child = ChildAt(0); 376 if (child) 377 child->Invalidate(); 378 } 379 }; 380 381 382 void 383 TOnscreenView::MessageReceived(BMessage *msg) 384 { 385 switch(msg->what) { 386 case B_ABOUT_REQUESTED: 387 (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(); 388 break; 389 default: 390 inherited::MessageReceived(msg); 391 } 392 } 393