]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/analogclock.py
bugfix
[wxWidgets.git] / wxPython / wx / lib / analogclock.py
1 # -*- coding: iso-8859-1 -*-
2 #----------------------------------------------------------------------
3 # Name: wx.lib.analogclock
4 # Purpose: A simple analog clock window
5 #
6 # Author: several folks on wxPython-users
7 #
8 # Created: 16-April-2003
9 # RCS-ID: $Id$
10 # Copyright: (c) 2003 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------
13 # 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
14 #
15 # o Updated for wx namespace
16 # o Tested with updated demo and with builtin test.
17 #
18 # 15-February-2004 - E. A. Tacao
19 #
20 # o Many ehnacements
21 #
22
23
24 import math
25 import sys
26 import string
27 import time
28
29 import wx
30
31 from analogclockopts import ACCustomizationFrame
32
33
34 # self.clockStyle:
35 SHOW_QUARTERS_TICKS = 1
36 SHOW_HOURS_TICKS = 2
37 SHOW_MINUTES_TICKS = 4
38 ROTATE_TICKS = 8
39 SHOW_HOURS_HAND = 16
40 SHOW_MINUTES_HAND = 32
41 SHOW_SECONDS_HAND = 64
42 SHOW_SHADOWS = 128
43 OVERLAP_TICKS = 256
44
45 # self.tickMarkHoursStyle and self.tickMarkMinutesStyle:
46 TICKS_NONE = 1
47 TICKS_SQUARE = 2
48 TICKS_CIRCLE = 4
49 TICKS_POLY = 8
50 TICKS_DECIMAL = 16
51 TICKS_ROMAN = 32
52
53
54 class AnalogClockWindow(wx.PyWindow):
55 """An analog clock window"""
56
57 def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
58 style=0, name="clock"):
59
60 # Initialize the wxWindow...
61 wx.PyWindow.__init__(self, parent, ID, pos, size, style, name)
62
63 # Initialize some variables and defaults...
64 self.clockStep = 1
65 self.prefs_open = False
66
67 self.tickShapeHours = self.tickShapeMinutes= [[0,0],
68 [1,-1],
69 [2,0],
70 [1,4]]
71 self.handHoursThickness = 5
72 self.handHoursColour = (0, 0, 0)
73
74 self.handMinutesThickness = 3
75 self.handMinutesColour = (0, 0, 0)
76
77 self.handSecondsThickness = 1
78 self.handSecondsColour = (0, 0, 0)
79
80 self.tickMarkHoursPen = wx.Pen((0, 0, 0), 1, wx.SOLID)
81 self.tickMarkHoursBrush = wx.Brush((0, 0, 0), wx.SOLID)
82 self.markSizeHour = 10
83 self.tickMarkHoursFont = wx.Font(0, wx.SWISS, wx.NORMAL, wx.BOLD)
84 self.tickMarkHoursFont.SetPointSize(self.markSizeHour)
85
86 self.tickMarkMinutesPen = wx.Pen((0, 0, 0), 1, wx.SOLID)
87 self.tickMarkMinutesBrush = wx.Brush((0, 0, 0), wx.SOLID)
88 self.markSizeMin = 6
89 self.tickMarkMinutesFont = wx.Font(self.markSizeMin, wx.SWISS, wx.NORMAL, wx.BOLD)
90
91 self.offM = 0
92
93 self.shadowPenColour = self.shadowBrushColour = (128,128,128)
94
95 self.watchPen = None
96 self.watchBrush = None
97
98 self.clockStyle = SHOW_HOURS_TICKS | SHOW_MINUTES_TICKS | SHOW_SHADOWS | ROTATE_TICKS
99 self.handsStyle = SHOW_SECONDS_HAND
100
101 self.tickMarkHoursStyle = TICKS_POLY
102 self.tickMarkMinutesStyle = TICKS_CIRCLE
103
104 self.currentTime=None
105
106 # Make an initial bitmap for the face, it will be updated and
107 # painted at the first EVT_SIZE event.
108 W, H = size
109 self.faceBitmap = wx.EmptyBitmap(max(W,1), max(H,1))
110
111 # Set event handlers...
112 self.Bind(wx.EVT_PAINT, self.OnPaint)
113 self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
114 self.Bind(wx.EVT_SIZE, self.OnSize)
115 self.Bind(wx.EVT_TIMER, self.OnTimerExpire)
116 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnQuit)
117 self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
118 self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
119
120
121 # Initialize the timer that drives the update of the clock
122 # face. Update every half second to ensure that there is at
123 # least one true update during each realtime second.
124 self.timer = wx.Timer(self)
125 self.timer.Start(500)
126
127 def DoGetBestSize(self):
128 return wx.Size(25,25)
129
130 def OnPaint(self, event):
131 self._doDrawHands(wx.BufferedPaintDC(self), True)
132
133
134 def OnTimerExpire(self, event):
135 size = self.GetClientSize()
136 dc = wx.BufferedDC(wx.ClientDC(self), size)
137 self._doDrawHands(dc, True)
138
139
140 def OnQuit(self, event):
141 self.timer.Stop()
142 del self.timer
143
144
145 def OnRightDown(self, event):
146 self.x = event.GetX()
147 self.y = event.GetY()
148 event.Skip()
149
150
151 def OnRightClick(self, event):
152 # only do this part the first time so the events are only bound once
153 if not hasattr(self, "popupID1"):
154 self.popupID1 = wx.NewId()
155 self.popupID2 = wx.NewId()
156 self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
157 self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
158
159 # make a menu
160 sm = wx.Menu()
161
162 sm.Append(self.popupID1, "Customize...")
163 sm.Append(self.popupID2, "About...")
164
165 # If there already a setup window open, we must not appear...
166 if not self.prefs_open:
167 # Popup the menu. If an item is selected then its handler
168 # will be called before PopupMenu returns.
169 self.PopupMenu(sm, (self.x,self.y))
170 sm.Destroy()
171
172
173 def OnPopupOne(self, event):
174 self.prefs_open=True
175 frame = ACCustomizationFrame(self, -1, "AnalogClock Preferences")
176 frame.Show(True)
177
178
179 def OnPopupTwo(self, event):
180 dlg = wx.MessageDialog(self, "AnalogClockWindow\n\nby Several folks on wxPython-users\nwith enhancements from E. A. Tacão",
181 'About', wx.OK | wx.ICON_INFORMATION)
182 dlg.ShowModal()
183 dlg.Destroy()
184
185
186 def OnSize(self, event):
187 # The faceBitmap init is done here, to make sure the buffer is always
188 # the same size as the Window
189 size = self.GetClientSize()
190 self.faceBitmap = wx.EmptyBitmap(size.width, size.height)
191
192 # Update drawing coordinates...
193 new_dim = size.Get()
194 if not hasattr(self,"dim"):
195 self.dim = new_dim
196
197 x,y=[0,1]
198 self.scale = min([float(new_dim[x]) / self.dim[x],
199 float(new_dim[y]) / self.dim[y]])
200
201 self.centerX = self.faceBitmap.GetWidth() / 2
202 self.centerY = self.faceBitmap.GetHeight() / 2
203
204 self.shadowDistance = 2 * self.scale
205
206 self.radius_watch = min(self.centerX, self.centerY)
207
208 self._doDrawFace()
209
210
211
212 def _doDrawHands(self, drawDC, force=0):
213 currentTime = list(time.localtime(time.time())[3:6])
214
215 if not (self.handsStyle & SHOW_SECONDS_HAND):
216 currentTime[2]=-1
217
218 if not (force or currentTime != self.currentTime):
219 return
220 self.currentTime = currentTime
221 hour, minutes, seconds = currentTime
222
223 # Start by drawing the face bitmap
224 drawDC.DrawBitmap(self.faceBitmap, (0,0))
225
226
227 # NOTE: All this hand drawing code below should be refactored into a helper function.
228
229
230 # Draw hours hand shadow
231 mStep = 6 * self.clockStep
232 angle = hour * 30
233 if angle > 360:
234 angle = angle - 360
235 angle = angle + round(minutes/(mStep*2)) * mStep
236
237 x,y,f = self._getCoords("hand_hours", angle)
238
239 if f and self.clockStyle & SHOW_SHADOWS:
240 drawDC.SetPen(wx.Pen(self.shadowPenColour,
241 int(self.handHoursThickness * self.scale),
242 wx.SOLID))
243 drawDC.DrawLineXY(int(self.centerX + self.shadowDistance),
244 int(self.centerY + self.shadowDistance),
245 int(x + self.shadowDistance),
246 int(y + self.shadowDistance))
247
248 # Draw minutes hand shadow
249 angle = minutes * 6
250 x,y,f = self._getCoords("hand_minutes", angle)
251
252 if f and self.clockStyle & SHOW_SHADOWS:
253 drawDC.SetPen(wx.Pen(self.shadowPenColour,
254 int(self.handMinutesThickness * self.scale),
255 wx.SOLID))
256 drawDC.DrawLineXY(int(self.centerX + self.shadowDistance),
257 int(self.centerY + self.shadowDistance),
258 int(x + self.shadowDistance),
259 int(y + self.shadowDistance))
260
261 # Draw seconds hand shadow if required
262 if seconds >= 0:
263 angle = seconds * 6
264 x,y,f = self._getCoords("hand_seconds", angle)
265
266 if f and self.clockStyle & SHOW_SHADOWS:
267 drawDC.SetPen(wx.Pen(self.shadowPenColour,
268 int(self.handSecondsThickness * self.scale),
269 wx.SOLID))
270 drawDC.DrawLineXY(int(self.centerX + self.shadowDistance),
271 int(self.centerY + self.shadowDistance),
272 int(x + self.shadowDistance),
273 int(y + self.shadowDistance))
274
275
276 # Draw hours hand
277 angle = hour * 30
278 if angle > 360:
279 angle = angle - 360
280 angle = angle + round(minutes/(mStep*2)) * mStep
281
282 x,y,f = self._getCoords("hand_hours", angle)
283
284 if f:
285 drawDC.SetPen(wx.Pen(self.handHoursColour,
286 int(self.handHoursThickness * self.scale),
287 wx.SOLID))
288 drawDC.DrawLineXY(int(self.centerX), int(self.centerY), int(x), int(y))
289
290 # Draw minutes hand
291 angle = minutes * 6
292 x,y,f = self._getCoords("hand_minutes", angle)
293
294 if f:
295 drawDC.SetPen(wx.Pen(self.handMinutesColour,
296 int(self.handMinutesThickness * self.scale),
297 wx.SOLID))
298 drawDC.DrawLineXY(int(self.centerX), int(self.centerY), int(x), int(y))
299
300 # Draw seconds hand if required
301 if seconds >= 0:
302 angle = seconds * 6
303 x,y,f = self._getCoords("hand_seconds", angle)
304 if f:
305 drawDC.SetPen(wx.Pen(self.handSecondsColour,
306 int(self.handSecondsThickness * self.scale),
307 wx.SOLID))
308 drawDC.DrawLineXY(int(self.centerX), int(self.centerY), int(x), int(y))
309
310
311
312 def _doDrawFace(self):
313 backgroundBrush = wx.Brush(self.GetBackgroundColour(), wx.SOLID)
314 drawDC = wx.MemoryDC()
315 drawDC.SelectObject(self.faceBitmap)
316 drawDC.SetBackground(backgroundBrush)
317 drawDC.Clear()
318
319 self.handHoursLength = 0.65 * (self.radius_watch - self._getMarkMaxSize("ticks_hours", drawDC))
320 self.handMinutesLength = 0.85 * (self.radius_watch - self._getMarkMaxSize("ticks_hours", drawDC))
321 self.handSecondsLength = 0.85 * (self.radius_watch - self._getMarkMaxSize("ticks_hours", drawDC))
322
323 self.radius_ticks_hours = self.radius_watch - self.shadowDistance - self._getMarkMaxSize("ticks_hours", drawDC)
324 self.radius_ticks_minutes = self.radius_ticks_hours
325
326 self._calcSteps()
327
328 # Draw the watch...
329 self._drawWatch(drawDC)
330
331 # Draw the marks for hours and minutes...
332 circle = 360
333 mStep = 6 * self.clockStep
334
335 if self.clockStyle & SHOW_SHADOWS:
336 for i in range(0, circle, mStep):
337 for t in self.coords.keys():
338 if t.find("ticks") > -1:
339 x,y,f = self._getCoords(t, i)
340 if f:
341 self._doDrawTickMark(i, drawDC, t,
342 x + self.shadowDistance,
343 y + self.shadowDistance,
344 True)
345
346 for i in range(0, circle, mStep):
347 for t in self.coords.keys():
348 if t.find("ticks") > -1:
349 x,y,f = self._getCoords(t, i)
350 if f:
351 self._doDrawTickMark(i, drawDC, t, x, y)
352
353
354
355 def _doDrawTickMark(self, angle, drawDC, tipo, x, y, is_a_shadow=None):
356 opts = {"ticks_hours": [self.tickMarkHoursPen, self.tickMarkHoursBrush, self.markSizeHour, self.tickMarkHoursStyle],
357 "ticks_quarters": [self.tickMarkHoursPen, self.tickMarkHoursBrush, self.markSizeHour, self.tickMarkHoursStyle],
358 "ticks_minutes": [self.tickMarkMinutesPen, self.tickMarkMinutesBrush, self.markSizeMin, self.tickMarkMinutesStyle]}
359
360 pen, brush, size, style = opts[tipo];
361 size = size * self.scale
362
363 if is_a_shadow:
364 drawDC.SetPen(wx.Pen(self.shadowPenColour, 1, wx.SOLID))
365 drawDC.SetBrush(wx.Brush(self.shadowBrushColour, wx.SOLID))
366 drawDC.SetTextForeground(self.shadowBrushColour)
367 else:
368 drawDC.SetPen(pen)
369 drawDC.SetBrush(brush)
370 drawDC.SetTextForeground(brush.GetColour())
371
372 if style & TICKS_CIRCLE:
373 x, y = self._center2corner(x, y, tipo)
374 drawDC.DrawEllipse((x, y), (int(size), int(size)))
375
376 elif style & TICKS_SQUARE:
377 x, y = self._center2corner(x, y, tipo)
378 drawDC.DrawRectangle((x, y), (int(size), int(size)))
379
380 elif (style & TICKS_DECIMAL) or (style & TICKS_ROMAN):
381 self._draw_rotate_text(drawDC, x, y, tipo, angle)
382
383 elif style & TICKS_POLY:
384 self._draw_rotate_polygon(drawDC, x, y, tipo, angle)
385
386
387 def _draw_rotate_text(self, drawDC, x, y, tipo, angle):
388 text = self._build_text(angle, tipo)
389 lX, lY = self._center2corner(x, y, tipo, drawDC)
390 lX = lX * len(text)
391 angle = 360 - angle
392
393 if self.clockStyle & ROTATE_TICKS:
394 radiansPerDegree = math.pi / 180
395 x = int(x -
396 ((math.cos((angle) * radiansPerDegree)*lX) +
397 (math.sin((angle) * radiansPerDegree)*lY)))
398 y = int(y -
399 ((math.cos((angle) * radiansPerDegree)*lY) -
400 (math.sin((angle) * radiansPerDegree)*lX)))
401 drawDC.DrawRotatedText(text, (x,y), angle)
402
403 else:
404 x = x - lX
405 y = y - lY
406 drawDC.DrawText(text, (x, y))
407
408
409 def _draw_rotate_polygon(self, drawDC, x, y, tipo, angle):
410 if tipo=="ticks_quarters":
411 tipo="ticks_hours"
412
413 # Add to empty list to prevent system-wide hard freezes under XP...
414 points = {"ticks_hours":self.tickShapeHours+[], "ticks_minutes":self.tickShapeMinutes+[]}[tipo]
415 size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
416
417 maxX = max(map(lambda x:x[0],points))
418 minX = min(map(lambda x:x[0],points))
419 maxY = max(map(lambda x:x[0],points))
420 minY = min(map(lambda x:x[0],points))
421
422 maxB = abs(max(maxX, maxY));
423 f = size / maxB
424
425 orgX = (maxX - minX) / 2.
426 orgY = (maxY - minY) / 2.
427
428 radiansPerDegree = math.pi / 180
429 scaledX = x
430 scaledY = y
431
432 for z in range(0, len(points)):
433 x,y = points[z]
434 x = x * f - orgX * f
435 y = y * f - orgY * f
436 if self.clockStyle & ROTATE_TICKS:
437 m,t = self._rect2pol(x,y)
438 t = t + angle
439 x,y = self._pol2rect(m,t)
440 x = x + scaledX
441 y = y + scaledY
442 points[z] = [int(x), int(y)]
443
444 drawDC.DrawPolygon(points)
445
446
447 def _pol2rect(self, r, w, deg=1): # radian if deg=0; degree if deg=1
448 if deg:
449 w = math.pi * w / 180.0
450 return r * math.cos(w), r * math.sin(w)
451
452
453 def _rect2pol(self, x, y, deg=1): # radian if deg=0; degree if deg=1
454 if deg:
455 return math.hypot(x, y), 180.0 * math.atan2(y, x) / math.pi
456 else:
457 return math.hypot(x, y), math.atan2(y, x)
458
459
460 def _center2corner(self, x, y, tipo, drawDC=None):
461 if tipo == "ticks_quarters":
462 tipo = "ticks_hours"
463
464 style = {"ticks_hours":self.tickMarkHoursStyle, "ticks_minutes":self.tickMarkMinutesStyle}[tipo]
465 size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
466
467 if style & TICKS_DECIMAL or style & TICKS_ROMAN:
468 font = {"ticks_hours":self.tickMarkHoursFont, "ticks_minutes":self.tickMarkMinutesFont}[tipo]
469 font.SetPointSize(int(size));
470 drawDC.SetFont(font)
471 lX = drawDC.GetCharWidth() / 2.
472 lY = drawDC.GetCharHeight() / 2.
473 x = lX
474 y = lY
475 else:
476 size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
477 x=x-size/2.;y=y-size/2.
478 return x, y
479
480
481 def _build_text(self, angle, tipo):
482 if tipo == "ticks_quarters":
483 tipo = "ticks_hours"
484 a = angle
485 if a <= 0:
486 a = a + 360
487 divider = {"ticks_hours":30,"ticks_minutes":6}[tipo]
488 a = int(a / divider)
489
490 style = {"ticks_hours":self.tickMarkHoursStyle," ticks_minutes":self.tickMarkMinutesStyle}[tipo]
491 if style & TICKS_ROMAN:
492 text=["I","II","III","IV","V","VI","VII","VIII","IX","X", \
493 "XI","XII","XIII","XIV","XV","XVI","XVII","XVIII","XIX","XX", \
494 "XXI","XXII","XXIII","XXIV","XXV","XXVI","XXVII","XXVIII","XXIX","XXX", \
495 "XXXI","XXXII","XXXIII","XXXIV","XXXV","XXXVI","XXXVII","XXXVIII","XXXIX","XL", \
496 "XLI","XLII","XLIII","XLIV","XLV","XLVI","XLVII","XLVIII","XLIX","L", \
497 "LI","LII","LIII","LIV","LV","LVI","LVII","LVIII","LIX","LX"][a-1]
498 else:
499 text = "%s" % a
500
501 return text
502
503
504 def _getMarkMaxSize(self, tipo, drawDC=None):
505 if tipo == "ticks_quarters":
506 tipo = "ticks_hours"
507
508 style = {"ticks_hours":self.tickMarkHoursStyle, "ticks_minutes":self.tickMarkMinutesStyle}[tipo]
509 size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
510
511 if style & TICKS_DECIMAL or style & TICKS_ROMAN:
512 lX = 2 * drawDC.GetCharWidth()
513 lY = drawDC.GetCharHeight()
514 size = math.sqrt(lX**2 + lY**2) * self.scale
515 else:
516 size=math.sqrt(2) * size
517
518 return size
519
520
521 def _drawWatch(self, drawDC):
522 # Draw the watch...
523 if self.watchPen or self.watchBrush:
524 if self.watchPen:
525 drawDC.SetPen(self.watchPen)
526 if self.watchBrush:
527 drawDC.SetBrush(self.watchBrush)
528 else:
529 drawDC.SetBrush(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
530 drawDC.DrawCircle((self.centerX, self.centerY), self.radius_watch)
531
532
533 def _calcSteps(self):
534 # Calcule todos os pontos para:
535 # - marcas de horas
536 # - marcas de minutos
537 # - ponteiro de horas
538 # - ponteiro de minutos
539 # - ponteiro de segundos
540
541 circle = 360
542 mStep = 6 * self.clockStep # Step in degrees...
543
544 vq = 90 * (self.clockStyle & SHOW_QUARTERS_TICKS) / SHOW_QUARTERS_TICKS
545 vh = 30 * (self.clockStyle & SHOW_HOURS_TICKS) / SHOW_HOURS_TICKS
546 vm = 1 * (self.clockStyle & SHOW_MINUTES_TICKS) / SHOW_MINUTES_TICKS
547
548 coords = {"ticks_quarters": [self.radius_ticks_hours, 60,vq,{}],
549 "ticks_hours": [self.radius_ticks_hours, 60,vh,{}],
550 "ticks_minutes": [self.radius_ticks_minutes,60,vm,{}],
551 "hand_hours": [self.handHoursLength, 60,1, {}],
552 "hand_minutes": [self.handMinutesLength, 60,1, {}],
553 "hand_seconds": [self.handSecondsLength, 60,1, {}]}
554
555 radiansPerDegree = math.pi / 180
556
557 for t in coords.keys():
558 for i in range(0, circle+mStep, mStep):
559 radius = coords[t][0]
560 if t == "ticks_minutes":
561 radius = radius - self.offM
562 step_angle = 360. / coords[t][1]
563 pre = coords[t][2]
564 x = self.centerX + radius * math.sin(i * radiansPerDegree)
565 y = self.centerY + radius * math.cos(i * radiansPerDegree)
566 f = (pre and (i/step_angle == int(i/step_angle)) and (float(i)/pre == int(i/pre)))
567 coords[t][3][i] = [x,y,f]
568
569 if not self.clockStyle & OVERLAP_TICKS:
570 for i in range(0, circle + mStep, mStep):
571 f=coords["ticks_minutes"][3][i][2]
572 if f and \
573 (coords["ticks_hours"][3].get(i,[0,0,0])[2] or coords["ticks_quarters"][3].get(i,[0,0,0])[2]):
574 f=False
575 coords["ticks_minutes"][3][i][2]=f
576
577 self.coords=coords
578
579
580 def _getCoords(self, tipo, angle):
581 # Returns coords and 'use flag' based on current angle...
582 k = 360 - (angle + 180)
583 if k <= 0:
584 k = k + 360
585 return self.coords[tipo][3][k]
586
587
588 # -----------------------------------------------------
589 #
590 def SetTickShapes(self, tsh, tsm=None):
591 """
592 tsh, tsm: [[x0,y0], [x1,y1], ... [xn,yn]]
593
594 Sets lists of lists of points to be used as polygon shapes
595 when using the TICKS_POLY style. If tsm is ommitted,
596 we'll use tsh for both shapes.
597 """
598
599 if not tsm:
600 tsm=tsh
601
602 self.tickShapeHours = tsh
603 self.tickShapeMinutes = tsm
604
605
606 def SetHandWeights(self, h=None, m=None, s=None):
607 """
608 h, m, s: value
609
610 Sets thickness of hands.
611 """
612
613 if h:
614 self.handHoursThickness = h
615 if m:
616 self.handMinutesThickness = m
617 if s:
618 self.handSecondsThickness = s
619
620
621 def SetHandColours(self, h=None, m=None, s=None):
622 """
623 h, m, s: wx.Colour
624
625 Sets colours of hands. If m and s are ommitted,
626 we'll use h for all.
627 """
628
629 if h and not m and not s:
630 m=h
631 s=h
632
633 if h:
634 self.handHoursColour = h
635 if m:
636 self.handMinutesColour = m
637 if s:
638 self.handSecondsColour = s
639
640
641 def SetTickColours(self, h=None, m=None):
642 """
643 h, m: wx.Colour
644
645 Sets colours of ticks. If m is ommitted,
646 we'll use h for both.
647 """
648
649 if not m:
650 m=h
651
652 if h:
653 self.tickMarkHoursPen = wx.Pen(h, 1, wx.SOLID)
654 self.tickMarkHoursBrush = wx.Brush(h, wx.SOLID)
655
656 if m:
657 self.tickMarkMinutesPen = wx.Pen(m, 1, wx.SOLID)
658 self.tickMarkMinutesBrush = wx.Brush(m, wx.SOLID)
659
660
661 def SetTickSizes(self, h=None, m=None):
662 """
663 h, m: value
664
665 Sizes for tick marks.
666 """
667
668 if h:
669 self.markSizeHour = h
670 if m:
671 self.markSizeMin = m
672
673
674 def SetTickFonts(self, h=None, m=None):
675 """
676 h, m: wx.Font
677
678 Fonts for tick marks when using TICKS_DECIMAL or TICKS_ROMAN style.
679 If m is ommitted, we'll use h for both.
680 """
681
682 if not m:
683 m=h
684
685 if h:
686 self.tickMarkHoursFont = h
687 self.tickMarkHoursFont.SetPointSize(self.markSizeHour)
688 if m:
689 self.tickMarkMinutesFont = m
690 self.tickMarkMinutesFont.SetPointSize(self.markSizeMin)
691
692
693 def SetMinutesOffset(self, o):
694 """
695 s = value
696
697 Sets the distance between tick marks for hours and minutes.
698 """
699 self.offM = o
700
701
702 def SetShadowColour(self, s):
703 """
704 s = wx.Colour or (r,g,b) tuple.
705
706 Sets the colour to be used to draw shadows.
707 """
708
709 self.shadowPenColour = self.shadowBrushColour = s
710
711
712 def SetWatchPenBrush(self, p=None, b=None):
713 """
714 p = wx.Pen; b = wx.Brush
715
716 Set the pen and brush for the watch.
717 """
718
719 if p:
720 self.watchPen = p
721 if b:
722 self.watchBrush = b
723
724
725 def SetClockStyle(self, style):
726 """
727 Set the clock style, acording to the options:
728
729 SHOW_QUARTERS_TICKS - Show marks for hours 3, 6, 9, 12
730 SHOW_HOURS_TICKS - Show marks for all hours
731 SHOW_MINUTES_TICKS - Show marks for minutes
732
733 SHOW_HOURS_HAND - Show hours hand
734 SHOW_MINUTES_HAND - Show minutes hand
735 SHOW_SECONDS_HAND - Show seconds hand
736
737 SHOW_SHADOWS - Show hands and marks shadows
738
739 ROTATE_TICKS - Align tick marks to watch
740 OVERLAP_TICKS - Draw tick marks for minutes even
741 when they match the hours marks.
742 """
743
744 self.clockStyle = style
745
746
747 def SetTickStyles(self, h=None, m=None):
748 """
749 Set the ticks styles, acording to the options below.
750
751 TICKS_NONE = Don't show tick marks.
752 TICKS_SQUARE = Use squares as tick marks.
753 TICKS_CIRCLE = Use circles as tick marks.
754 TICKS_POLY = Use a polygon as tick marks. The polygon
755 must be passed using SetTickShapes,
756 otherwise the default polygon will be used.
757 TICKS_DECIMAL = Use decimal numbers.
758 TICKS_ROMAN = Use Roman numbers.
759 """
760
761 if h:
762 self.tickMarkHoursStyle = h
763 if m:
764 self.tickMarkMinutesStyle = m
765 #
766 # -----------------------------------------------------
767
768
769 if __name__ == "__main__":
770 print wx.VERSION_STRING
771 class App(wx.App):
772 def OnInit(self):
773 frame = wx.Frame(None, -1, "AnalogClockWindow", size=(375,375))
774
775 clock = AnalogClockWindow(frame)
776
777 # Settings below are used by default...
778 #clock.SetClockStyle(SHOW_HOURS_TICKS|SHOW_MINUTES_TICKS|SHOW_SHADOWS|ROTATE_TICKS)
779 #clock.SetTickStyles(TICKS_POLY, TICKS_CIRCLE)
780
781 frame.Centre(wx.BOTH)
782 frame.Show(True)
783 self.SetTopWindow(frame)
784 return True
785
786 theApp = App(0)
787 theApp.MainLoop()
788
789
790 #
791 ##
792 ### eof