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