1%% options 2 3copyright owner = Dirk Krause 4copyright year = 2013-xxxx 5SPDX-License-Identifier: BSD-3-Clause 6 7 8 9%% header 10 11class DkClockView : public DkWxBufferedControl 12{ 13 private: 14 15#if wxCHECK_VERSION(3,0,0) 16 wxDECLARE_DYNAMIC_CLASS(DkClockView); 17#else 18 DECLARE_DYNAMIC_CLASS(DkClockView) 19#endif 20 21 /** Event table. 22 */ 23#if wxCHECK_VERSION(3,0,0) 24 wxDECLARE_EVENT_TABLE(); 25#else 26 DECLARE_EVENT_TABLE() 27#endif 28 29 protected: 30 31 /** Black colour for normal mode. 32 */ 33 wxColour cBlack; 34 35 /** Red colour for alert mode. 36 */ 37 wxColour cRed; 38 39 /** Clock data to show. 40 */ 41 DkClockData *cld; 42 43 /** Widget type name. 44 */ 45 static wxChar const windowtypename[]; 46 47 /** Flag: Use red colour instead of black. 48 */ 49 bool bUseRed; 50 51 public: 52 53 /** Default constructor. 54 */ 55 DkClockView(); 56 57 /** Constructor. 58 @param wParent Parent window. 59 @param wid Window ID. 60 @param clockData Clock data to show. 61 @param pos Window position. 62 @param size Window size. 63 @param style Window style. 64 */ 65 DkClockView( 66 wxWindow *wParent, 67 wxWindowID wid, 68 DkClockData *clockData, 69 const wxPoint & pos = wxDefaultPosition, 70 const wxSize & size = wxDefaultSize, 71 long style = 0L 72 ); 73 74 /** Create window after using the default constructor. 75 @param wParent Parent window. 76 @param wid Window ID. 77 @param clockData Clock data to show. 78 @param pos Window position. 79 @param size Window size. 80 @param style Window style. 81 @return true on success, false on error. 82 */ 83 bool 84 Create( 85 wxWindow *wParent, 86 wxWindowID wid, 87 DkClockData *clockData, 88 const wxPoint & pos = wxDefaultPosition, 89 const wxSize & size = wxDefaultSize, 90 long style = 0L 91 ); 92 93 /** Draw operation. 94 @param pdc Device context to draw to. 95 @param event Event to process. 96 @param buffered Flag: Drawing into bitmap buffer. 97 @param clWidth Client area width. 98 @param clHeight Client area height. 99 */ 100 void 101 PaintOperation( 102 wxDC & pdc, 103 wxPaintEvent & event, 104 bool buffered, 105 int clWidth, 106 int clHeight 107 ); 108 109 /** Handler for mouse click. 110 @param event Event to process. 111 */ 112 void 113 OnLeftDown(wxMouseEvent & event); 114 115 /** Get red component of normal clock colour. 116 @return Red value. 117 */ 118 int 119 getNormalRed(void) const; 120 121 /** Get green component of normal clock colour. 122 @return Green value. 123 */ 124 int 125 getNormalGreen(void) const; 126 127 /** Get blue component of normal clock colour. 128 @return Blue value. 129 */ 130 int 131 getNormalBlue(void) const; 132 133 /** Get red component of alert clock colour. 134 @return Red value. 135 */ 136 int 137 getAlertRed(void) const; 138 139 /** Get green component of alert clock colour. 140 @return Green value. 141 */ 142 int 143 getAlertGreen(void) const; 144 145 /** Get blue component of alert clock colour. 146 @return Blue value. 147 */ 148 int 149 getAlertBlue(void) const; 150 151 /** Set normal colour. 152 @param r Red value. 153 @param g Green value. 154 @param b Blue value. 155 */ 156 void 157 setNormal(int r, int g, int b); 158 159 /** Set alert colour. 160 @param r Red value. 161 @param g Green value. 162 @param b Blue value. 163 */ 164 void 165 setAlert(int r, int g, int b); 166}; 167 168%% module 169 170#include "dk3conf.h" 171#include <wxdkclock/wxdkclock.h> 172 173 174$!trace-include 175 176 177#if wxCHECK_VERSION(3,0,0) 178wxIMPLEMENT_DYNAMIC_CLASS(DkClockView, DkWxBufferedControl); 179#else 180IMPLEMENT_DYNAMIC_CLASS(DkClockView, DkWxBufferedControl) 181#endif 182 183 184/** Event handler table. 185*/ 186#if wxCHECK_VERSION(3,0,0) 187wxBEGIN_EVENT_TABLE(DkClockView,DkWxBufferedControl) 188#else 189BEGIN_EVENT_TABLE(DkClockView,DkWxBufferedControl) 190#endif 191 EVT_LEFT_DOWN(DkClockView::OnLeftDown) 192#if wxCHECK_VERSION(3,0,0) 193wxEND_EVENT_TABLE() 194#else 195END_EVENT_TABLE() 196#endif 197 198 199wxChar const DkClockView::windowtypename[] = { wxT("DkClockView") }; 200 201 202 203DkClockView::DkClockView() 204: 205cBlack(0, 0, 0), 206#if defined(__WXMSW__) 207cRed(127, 0, 0) 208#else 209cRed(191, 0, 0) 210#endif 211{ 212 bUseRed = false; 213 cld = NULL; 214} 215 216 217 218DkClockView::DkClockView( 219 wxWindow *wParent, 220 wxWindowID wid, 221 DkClockData *clockData, 222 const wxPoint & pos, 223 const wxSize & size, 224 long style 225) : DkWxBufferedControl( 226 wParent, 227 wid, 228 pos, 229 size, 230 (style | wxFULL_REPAINT_ON_RESIZE), 231 wxDefaultValidator, 232 wxString(windowtypename) 233), 234cBlack(0, 0, 0), 235#if defined(__WXMSW__) 236cRed(127, 0, 0) 237#else 238cRed(191, 0, 0) 239#endif 240{ 241 $? "+ DkClockView::DkClockView" 242 bUseRed = false; 243 cld = clockData; 244 $? "- DkClockView::DkClockView" 245} 246 247 248 249bool 250DkClockView::Create( 251 wxWindow *wParent, 252 wxWindowID wid, 253 DkClockData *clockData, 254 const wxPoint & pos, 255 const wxSize & size, 256 long style 257) 258{ 259 bool back; 260 back = DkWxBufferedControl::Create( 261 wParent, wid, pos, size, (style | wxFULL_REPAINT_ON_RESIZE), 262 wxDefaultValidator, wxString(windowtypename) 263 ); 264 bUseRed = false; 265 cld = clockData; 266 return back; 267} 268 269 270 271void 272DkClockView::PaintOperation( 273 wxDC & pdc, wxPaintEvent & WXUNUSED(event), 274 bool WXUNUSED(buffered), int clWidth, int clHeight 275) 276{ 277 clockview_data_t clvdata; /* Clock data. */ 278 double alpha; /* Current angle in radians. */ 279 int cx; /* Center x. */ 280 int cy; /* Center y. */ 281 int ro; /* Outer radius. */ 282 int rd; /* Radius 5-minutes dot. */ 283 int rc; /* Center points radius. */ 284 int ri; /* Inner radius. */ 285 int lw; /* Line width of minute dots. */ 286 int r1; /* Inner radius minute dots. */ 287 int r2; /* Outer radius minute dots. */ 288 int rs; /* Radius seconds arrow. */ 289 int rm; /* Radius minuts arrow. */ 290 int rh; /* Radius hours arrow. */ 291 int aw; /* Width minutes and hours. */ 292 int i; /* Current index. */ 293 int x; /* Current x. */ 294 int y; /* Current y. */ 295 $? "+ DkClockView::PaintOperation" 296 pdc.SetBackground(*wxWHITE_BRUSH); 297 pdc.Clear(); 298 cld->getData(&clvdata); 299 if(clvdata.a) { 300 bUseRed = ((bUseRed) ? false : true); 301 } else { 302 bUseRed = false; 303 } 304 cx = clWidth / 2; 305 cy = clHeight / 2; 306 ro = cx; if(cy < ro) { ro = cy; } 307 ro = (int)(0.95 * (double)ro); 308 rd = (int)(0.0497331 * (double)ro); 309 if(rd < 1) { rd = 1; } 310 rc = ro - rd; 311 if(rc < 0) { rc = 0; } 312 ri = ro - (2 * rd); 313 if(ri < 0) { ri = 0; } 314 lw = rd / 2; 315 if(lw < 1) { lw = 1; } 316 r1 = ri + (lw / 2); 317 r2 = ro - (lw / 2); 318 rs = ri - rd - (lw / 2); 319 if(rs < 1) { rs = 1; } 320 aw = rd; 321 rm = ri - (2 * rd) - (aw / 2); 322 if(rm < 1) { rm = 1; } 323 rh = (int)(0.75 * (double)rm); 324 if(rm < 1) { rh = 1; } 325 /* 326 5-minute dots. 327 */ 328 pdc.SetPen(*wxTRANSPARENT_PEN); 329 if(bUseRed) { 330 pdc.SetBrush(cRed); 331 } else { 332 pdc.SetBrush(cBlack); 333 } 334 for(i = 0; i < 12; i++) { 335 alpha = (2.0 * M_PI * (double)i) / 12.0; 336 x = cx + (int)((double)rc * cos(alpha)); 337 y = cy + (int)((double)rc * sin(alpha)); 338 pdc.DrawCircle(x, y, rd); 339 } 340 /* 341 Other minute ticks. 342 */ 343 pdc.SetBrush(wxNullBrush); 344 if(bUseRed) { 345 pdc.SetPen(wxPen(cRed, lw)); 346 } else{ 347 pdc.SetPen(wxPen(cBlack, lw)); 348 } 349 for(i = 0; i < 60; i++) { 350 if(i % 5) { 351 alpha = (2.0 * M_PI * (double)i) / 60.0; 352 pdc.DrawLine( 353 (cx + (int)((double)r1 * cos(alpha))), 354 (cy + (int)((double)r1 * sin(alpha))), 355 (cx + (int)((double)r2 * cos(alpha))), 356 (cy + (int)((double)r2 * sin(alpha))) 357 ); 358 } 359 } 360 /* 361 Hours arrow. 362 */ 363 pdc.SetBrush(wxNullBrush); 364 if(bUseRed) { 365 pdc.SetPen(wxPen(cRed, aw)); 366 } else{ 367 pdc.SetPen(wxPen(cBlack, aw)); 368 } 369 alpha = M_PI_2 - ((4.0 * M_PI * (double)(clvdata.h)) / 24.0); 370 alpha = alpha - ((M_PI * (double)(clvdata.m)) / 360.0); 371 pdc.DrawLine( 372 cx, cy, 373 (cx + (int)((double)rh * cos(alpha))), 374 (cy - (int)((double)rh * sin(alpha))) 375 ); 376 /* 377 Minutes arrow. 378 */ 379 alpha = M_PI_2 - ((2.0 * M_PI * (double)(clvdata.m)) / 60.0); 380 pdc.DrawLine( 381 cx, cy, 382 (cx + (int)((double)rm * cos(alpha))), 383 (cy - (int)((double)rm * sin(alpha))) 384 ); 385 /* 386 Seconds arrow. 387 */ 388 pdc.SetBrush(wxNullBrush); 389 if(bUseRed) { 390 pdc.SetPen(wxPen(cRed, lw)); 391 } else{ 392 pdc.SetPen(wxPen(cBlack, lw)); 393 } 394 alpha = M_PI_2 - ((2.0 * M_PI * (int)(clvdata.s)) / 60.0); 395 pdc.DrawLine( 396 cx, cy, 397 (cx + (int)((double)rs * cos(alpha))), 398 (cy - (int)((double)rs * sin(alpha))) 399 ); 400 /* 401 Before leaving the function choose stock objects. 402 */ 403 pdc.SetBrush(wxNullBrush); 404 pdc.SetBackground(wxNullBrush); 405 pdc.SetPen(wxNullPen); 406 $? "- DkClockView::PaintOperation" 407} 408 409 410 411void 412DkClockView::OnLeftDown(wxMouseEvent & WXUNUSED(event)) 413{ 414 $? "+ DkClockView::OnLeftDown" 415 if(cld) { 416 cld->endAlert(); 417 SetMustUpdate(); 418 Refresh(); 419 Update(); 420 } $? "- DkClockView::OnLeftDown" 421} 422 423 424 425int 426DkClockView::getNormalRed(void) const 427{ 428 int back; 429 back = cBlack.Red(); 430 if(back < 0) { back = back + 256; } 431 return back; 432} 433 434 435 436int 437DkClockView::getNormalGreen(void) const 438{ 439 int back; 440 back = cBlack.Green(); 441 if(back < 0) { back = back + 256; } 442 return back; 443} 444 445 446 447int 448DkClockView::getNormalBlue(void) const 449{ 450 int back; 451 back = cBlack.Blue(); 452 if(back < 0) { back = back + 256; } 453 return back; 454} 455 456 457 458int 459DkClockView::getAlertRed(void) const 460{ 461 int back; 462 back = cRed.Red(); 463 if(back < 0) { back = back + 256; } 464 return back; 465} 466 467 468 469int 470DkClockView::getAlertGreen(void) const 471{ 472 int back; 473 back = cRed.Green(); 474 if(back < 0) { back = back + 256; } 475 return back; 476} 477 478 479 480int 481DkClockView::getAlertBlue(void) const 482{ 483 int back; 484 back = cRed.Blue(); 485 if(back < 0) { back = back + 256; } 486 return back; 487} 488 489 490 491void 492DkClockView::setNormal(int r, int g, int b) 493{ 494 cBlack.Set((unsigned char)r, (unsigned char)g, (unsigned char)b); 495} 496 497 498 499void 500DkClockView::setAlert(int r, int g, int b) 501{ 502 cRed.Set((unsigned char)r, (unsigned char)g, (unsigned char)b); 503} 504 505