]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/analogclock/analogclock.py
added missing button state
[wxWidgets.git] / wxPython / wx / lib / analogclock / analogclock.py
CommitLineData
caeac82e
RD
1# AnalogClock's main class
2# E. A. Tacao <e.a.tacao |at| estadao.com.br>
3# http://j.domaindlx.com/elements28/wxpython/
4# 15 Fev 2006, 22:00 GMT-03:00
5# Distributed under the wxWidgets license.
6#
7# For more info please see the __init__.py file.
8
9import wx
10
11from styles import *
12from helpers import Dyer, Face, Hand, HandSet, TickSet, Box
13from setup import Setup
14
15#----------------------------------------------------------------------
16
17class AnalogClock(wx.PyWindow):
18 """An analog clock."""
19
20 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
21 size=wx.DefaultSize, style=wx.NO_BORDER, name="AnalogClock",
22 clockStyle=DEFAULT_CLOCK_STYLE,
23 minutesStyle=TICKS_CIRCLE, hoursStyle=TICKS_POLY):
24
25 wx.PyWindow.__init__(self, parent, id, pos, size, style, name)
26
27 # Base size for scale calc purposes.
28 self.basesize = wx.Size(348, 348)
29
30 # Store some references.
31 self.clockStyle = clockStyle
32 self.minutesStyle = minutesStyle
33 self.hoursStyle = hoursStyle
34
35 self.DrawHands = self._drawHands
36 self.DrawBox = self._drawBox
37 self.RecalcCoords = self._recalcCoords
38
39 self.shadowOffset = 3
40
41 self.allHandStyles = [SHOW_HOURS_HAND,
42 SHOW_MINUTES_HAND,
43 SHOW_SECONDS_HAND]
44
45 # Initialize clock face.
46 #
47 # By default we don't use colours or borders on the clock face.
48 bg = self.GetBackgroundColour()
49 face = Face(dyer=Dyer(bg, 0, bg))
50
51 # Initialize tick marks.
52 #
53 # TickSet is a set of tick marks; there's always two TickSets defined
54 # regardless whether they're being shown or not.
55 ticksM = TickSet(self, style=minutesStyle, size=5, kind="minutes")
56 ticksH = TickSet(self, style=hoursStyle, size=25, kind="hours",
57 rotate=clockStyle&ROTATE_TICKS)
58
59 # Box holds the clock face and tick marks.
60 self.Box = Box(self, face, ticksM, ticksH)
61
62 # Initialize hands.
63 #
64 # HandSet is the set of hands; there's always one HandSet defined
65 # regardless whether hands are being shown or not.
66 #
67 # A 'lenfac = 0.95', e.g., means that the lenght of that hand will
68 # be 95% of the maximum allowed hand lenght ('nice' maximum lenght).
69 handH = Hand(size=7, lenfac=0.7)
70 handM = Hand(size=5, lenfac=0.95)
71 handS = Hand(size=1, lenfac=0.95)
72 self.Hands = HandSet(self, handH, handM, handS)
73
74 # Create the customization dialog.
75 self.Setup = None
76
77 # Make a context menu.
78 popup1 = wx.NewId()
79 popup2 = wx.NewId()
80 cm = self.cm = wx.Menu()
81 cm.Append(popup1, "Customize...")
82 cm.Append(popup2, "About...")
83
84 # Set event handlers.
85 self.Bind(wx.EVT_SIZE, self._OnSize)
86 self.Bind(wx.EVT_PAINT, self._OnPaint)
87 self.Bind(wx.EVT_ERASE_BACKGROUND, lambda evt: None)
88 self.Bind(wx.EVT_TIMER, self._OnTimer)
89 self.Bind(wx.EVT_WINDOW_DESTROY, self._OnDestroyWindow)
90 self.Bind(wx.EVT_CONTEXT_MENU, self._OnContextMenu)
91 self.Bind(wx.EVT_MENU, self._OnShowSetup, id=popup1)
92 self.Bind(wx.EVT_MENU, self._OnShowAbout, id=popup2)
93
94 # Set initial size based on given size, or best size
170acdc9 95 self.SetInitialSize(size)
caeac82e
RD
96
97 # Do initial drawing (in case there is not an initial size event)
98 self.RecalcCoords(self.GetSize())
99 self.DrawBox()
100
101 # Initialize the timer that drives the update of the clock face.
102 # Update every half second to ensure that there is at least one true
103 # update during each realtime second.
104 self.timer = wx.Timer(self)
105 self.timer.Start(500)
106
107
108 def DoGetBestSize(self):
109 # Just pull a number out of the air. If there is a way to
110 # calculate this then it should be done...
111 size = wx.Size(50,50)
112 self.CacheBestSize(size)
113 return size
114
115
116 def _OnSize(self, evt):
117 size = self.GetClientSize()
118 if size.x < 1 or size.y < 1:
119 return
120
121 self.RecalcCoords(size)
122 self.DrawBox()
123
124
125 def _OnPaint(self, evt):
126 dc = wx.BufferedPaintDC(self)
127 self.DrawHands(dc)
128
129
130 def _OnTimer(self, evt):
84752aa5
RD
131 self.Refresh(False)
132 self.Update()
133
caeac82e
RD
134
135 def _OnDestroyWindow(self, evt):
136 self.timer.Stop()
137 del self.timer
138
139
140 def _OnContextMenu(self, evt):
141 self.PopupMenu(self.cm)
142
143
144 def _OnShowSetup(self, evt):
145 if self.Setup is None:
146 self.Setup = Setup(self)
147 self.Setup.Show()
148 self.Setup.Raise()
149
150
151 def _OnShowAbout(self, evt):
152 msg = "AnalogClock\n\n" \
153 "by Several folks on wxPython-users\n" \
154 "with enhancements from E. A. Tacao."
155 title = "About..."
156 style = wx.OK|wx.ICON_INFORMATION
157
158 dlg = wx.MessageDialog(self, msg, title, style)
159 dlg.ShowModal()
160 dlg.Destroy()
161
162
163 def _recalcCoords(self, size):
164 """
165 Recalculates all coordinates/geometry and inits the faceBitmap
166 to make sure the buffer is always the same size as the window.
167 """
168
169 self.faceBitmap = wx.EmptyBitmap(*size.Get())
170
171 # Recalc all coords.
172 scale = min([float(size.width) / self.basesize.width,
173 float(size.height) / self.basesize.height])
174
175 centre = wx.Point(size.width / 2., size.height / 2.)
176
177 self.Box.RecalcCoords(size, centre, scale)
178 self.Hands.RecalcCoords(size, centre, scale)
179
180 # Try to find a 'nice' maximum length for the hands so that they won't
181 # overlap the tick marks. OTOH, if you do want to allow overlapping the
182 # lenfac value (defined on __init__ above) has to be set to
183 # something > 1.
184 niceradius = self.Box.GetNiceRadiusForHands(centre)
185 self.Hands.SetMaxRadius(niceradius)
186
187
188 def _drawBox(self):
84752aa5
RD
189 """Draws clock face and tick marks onto the faceBitmap."""
190 dc = wx.BufferedDC(None, self.faceBitmap)
caeac82e
RD
191 dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
192 dc.Clear()
193 self.Box.Draw(dc)
caeac82e
RD
194
195
196 def _drawHands(self, dc):
197 """
198 Draws the face bitmap, created on the last DrawBox call, and
199 clock hands.
200 """
caeac82e
RD
201 dc.DrawBitmap(self.faceBitmap, 0, 0)
202 self.Hands.Draw(dc)
caeac82e
RD
203
204
205 # Public methods --------------------------------------------------
206
207 def GetHandSize(self, target=ALL):
208 """Gets thickness of hands."""
209
210 return self.Hands.GetSize(target)
211
212
213 def GetHandFillColour(self, target=ALL):
214 """Gets fill colours of hands."""
215
216 return self.Hands.GetFillColour(target)
217
218
219 def GetHandBorderColour(self, target=ALL):
220 """Gets border colours of hands."""
221
222 return self.Hands.GetBorderColour(target)
223
224
225 def GetHandBorderWidth(self, target=ALL):
226 """Gets border widths of hands."""
227
228 return self.Hands.GetBorderWidth(target)
229
230
231 def GetTickSize(self, target=ALL):
232 """Gets sizes of ticks."""
233
234 return self.Box.GetTickSize(target)
235
236
237
238 def GetTickFillColour(self, target=ALL):
239 """Gets fill colours of ticks."""
240
241 return self.Box.GetTickFillColour(target)
242
243
244
245 def GetTickBorderColour(self, target=ALL):
246 """Gets border colours of ticks."""
247
248 return self.Box.GetTickBorderColour(target)
249
250
251
252 def GetTickBorderWidth(self, target=ALL):
253 """Gets border widths of ticks."""
254
255 return self.Box.GetTickBorderWidth(target)
256
257
258
259 def GetTickPolygon(self, target=ALL):
260 """
261 Gets lists of points to be used as polygon shapes
262 when using the TICKS_POLY style.
263 """
264
265 return self.Box.GetTickPolygon(target)
266
267
268
269 def GetTickFont(self, target=ALL):
270 """
271 Gets fonts for tick marks when using TICKS_DECIMAL or
272 TICKS_ROMAN style.
273 """
274
275 return self.Box.GetTickFont(target)
276
277
278
279 def GetTickOffset(self, target=ALL):
280 """Gets the distance of tick marks for hours from border."""
281
282 return self.Box.GetTickOffset(target)
283
284
285
286 def GetFaceFillColour(self):
287 """Gets fill colours of watch."""
288
289 return self.Box.Face.GetFillColour()
290
291
292
293 def GetFaceBorderColour(self):
294 """Gets border colours of watch."""
295
296 return self.Box.Face.GetBorderColour()
297
298
299
300 def GetFaceBorderWidth(self):
301 """Gets border width of watch."""
302
303 return self.Box.Face.GetBorderWidth()
304
305
306
307 def GetShadowColour(self):
308 """Gets the colour to be used to draw shadows."""
309
310 a_clock_part = self.Box
311 return a_clock_part.GetShadowColour()
312
313
314
315 def GetClockStyle(self):
316 """Returns the current clock style."""
317
318 return self.clockStyle
319
320
321 def GetTickStyle(self, target=ALL):
322 """Gets the tick style(s)."""
323
324 return self.Box.GetTickStyle(target)
325
326
84752aa5 327 def Reset(self):
caeac82e 328 """
84752aa5
RD
329 Forces an immediate recalculation and redraw of all clock
330 elements.
caeac82e 331 """
caeac82e
RD
332 size = self.GetClientSize()
333 if size.x < 1 or size.y < 1:
334 return
caeac82e
RD
335 self.RecalcCoords(size)
336 self.DrawBox()
84752aa5
RD
337 self.Refresh(False)
338
caeac82e
RD
339
340 def SetHandSize(self, size, target=ALL):
341 """Sets thickness of hands."""
342
343 self.Hands.SetSize(size, target)
344
345
346 def SetHandFillColour(self, colour, target=ALL):
347 """Sets fill colours of hands."""
348
349 self.Hands.SetFillColour(colour, target)
350
351
352 def SetHandBorderColour(self, colour, target=ALL):
353 """Sets border colours of hands."""
354
355 self.Hands.SetBorderColour(colour, target)
356
357
358 def SetHandBorderWidth(self, width, target=ALL):
359 """Sets border widths of hands."""
360
361 self.Hands.SetBorderWidth(width, target)
362
363
364 def SetTickSize(self, size, target=ALL):
365 """Sets sizes of ticks."""
366
367 self.Box.SetTickSize(size, target)
84752aa5 368 self.Reset()
caeac82e
RD
369
370
371 def SetTickFillColour(self, colour, target=ALL):
372 """Sets fill colours of ticks."""
373
374 self.Box.SetTickFillColour(colour, target)
84752aa5 375 self.Reset()
caeac82e
RD
376
377
378 def SetTickBorderColour(self, colour, target=ALL):
379 """Sets border colours of ticks."""
380
381 self.Box.SetTickBorderColour(colour, target)
84752aa5 382 self.Reset()
caeac82e
RD
383
384
385 def SetTickBorderWidth(self, width, target=ALL):
386 """Sets border widths of ticks."""
387
388 self.Box.SetTickBorderWidth(width, target)
84752aa5 389 self.Reset()
caeac82e
RD
390
391
392 def SetTickPolygon(self, polygon, target=ALL):
393 """
394 Sets lists of points to be used as polygon shapes
395 when using the TICKS_POLY style.
396 """
397
398 self.Box.SetTickPolygon(polygon, target)
84752aa5 399 self.Reset()
caeac82e
RD
400
401
402 def SetTickFont(self, font, target=ALL):
403 """
404 Sets fonts for tick marks when using text-based tick styles
405 such as TICKS_DECIMAL or TICKS_ROMAN.
406 """
407
408 self.Box.SetTickFont(font, target)
84752aa5 409 self.Reset()
caeac82e
RD
410
411
412 def SetTickOffset(self, offset, target=ALL):
413 """Sets the distance of tick marks for hours from border."""
414
415 self.Box.SetTickOffset(offset, target)
84752aa5 416 self.Reset()
caeac82e
RD
417
418
419 def SetFaceFillColour(self, colour):
420 """Sets fill colours of watch."""
421
422 self.Box.Face.SetFillColour(colour)
84752aa5 423 self.Reset()
caeac82e
RD
424
425
426 def SetFaceBorderColour(self, colour):
427 """Sets border colours of watch."""
428
429 self.Box.Face.SetBorderColour(colour)
84752aa5 430 self.Reset()
caeac82e
RD
431
432
433 def SetFaceBorderWidth(self, width):
434 """Sets border width of watch."""
435
436 self.Box.Face.SetBorderWidth(width)
84752aa5 437 self.Reset()
caeac82e
RD
438
439
440 def SetShadowColour(self, colour):
441 """Sets the colour to be used to draw shadows."""
442
443 self.Hands.SetShadowColour(colour)
444 self.Box.SetShadowColour(colour)
84752aa5 445 self.Reset()
caeac82e
RD
446
447
448 def SetClockStyle(self, style):
449 """
450 Set the clock style, according to the options below.
451
452 ==================== ================================
453 SHOW_QUARTERS_TICKS Show marks for hours 3, 6, 9, 12
454 SHOW_HOURS_TICKS Show marks for all hours
455 SHOW_MINUTES_TICKS Show marks for minutes
456
457 SHOW_HOURS_HAND Show hours hand
458 SHOW_MINUTES_HAND Show minutes hand
459 SHOW_SECONDS_HAND Show seconds hand
460
461 SHOW_SHADOWS Show hands and marks shadows
462
463 ROTATE_TICKS Align tick marks to watch
464 OVERLAP_TICKS Draw tick marks for minutes even
465 when they match the hours marks.
466 ==================== ================================
467 """
468
469 self.clockStyle = style
470 self.Box.SetIsRotated(style & ROTATE_TICKS)
84752aa5 471 self.Reset()
caeac82e
RD
472
473
474 def SetTickStyle(self, style, target=ALL):
475 """
476 Set the tick style, according to the options below.
477
478 ================= ======================================
479 TICKS_NONE Don't show tick marks.
480 TICKS_SQUARE Use squares as tick marks.
481 TICKS_CIRCLE Use circles as tick marks.
482 TICKS_POLY Use a polygon as tick marks. A
483 polygon can be passed using
484 SetTickPolygon, otherwise the default
485 polygon will be used.
486 TICKS_DECIMAL Use decimal numbers as tick marks.
487 TICKS_ROMAN Use Roman numbers as tick marks.
488 TICKS_BINARY Use binary numbers as tick marks.
489 TICKS_HEX Use hexadecimal numbers as tick marks.
490 ================= ======================================
491 """
492
493 self.Box.SetTickStyle(style, target)
84752aa5 494 self.Reset()
caeac82e
RD
495
496
497 def SetBackgroundColour(self, colour):
498 """Overriden base wx.Window method."""
499
500 wx.Window.SetBackgroundColour(self, colour)
84752aa5 501 self.Reset()
caeac82e
RD
502
503
504 def SetForegroundColour(self, colour):
505 """
506 Overriden base wx.Window method. This method sets a colour for
507 all hands and ticks at once.
508 """
509
510 wx.Window.SetForegroundColour(self, colour)
511 self.SetHandFillColour(colour)
512 self.SetHandBorderColour(colour)
513 self.SetTickFillColour(colour)
514 self.SetTickBorderColour(colour)
84752aa5 515 self.Reset()
caeac82e
RD
516
517
518 def SetWindowStyle(self, *args, **kwargs):
519 """Overriden base wx.Window method."""
520
521 size = self.GetSize()
522 self.Freeze()
523 wx.Window.SetWindowStyle(self, *args, **kwargs)
524 self.SetSize((10, 10))
525 self.SetSize(size)
526 self.Thaw()
527
528
529 def SetWindowStyleFlag(self, *args, **kwargs):
530 """Overriden base wx.Window method."""
531
532 self.SetWindowStyle(*args, **kwargs)
533
534
535# For backwards compatibility -----------------------------------------
536
537class AnalogClockWindow(AnalogClock):
538 """
539 A simple derived class that provides some backwards compatibility
540 with the old analogclock module.
541 """
542 def SetTickShapes(self, tsh, tsm=None):
543 self.SetTickPolygon(tsh)
544
545 def SetHandWeights(self, h=None, m=None, s=None):
546 if h:
547 self.SetHandSize(h, HOUR)
548 if m:
549 self.SetHandSize(m, MINUTE)
550 if s:
99ceaa26 551 self.SetHandSize(s, SECOND)
caeac82e
RD
552
553 def SetHandColours(self, h=None, m=None, s=None):
554 if h and not m and not s:
555 m=h
556 s=h
557 if h:
558 self.SetHandBorderColour(h, HOUR)
559 self.SetHandFillColour(h, HOUR)
560 if m:
561 self.SetHandBorderColour(m, MINUTE)
562 self.SetHandFillColour(m, MINUTE)
563 if s:
99ceaa26
RD
564 self.SetHandBorderColour(s, SECOND)
565 self.SetHandFillColour(s, SECOND)
caeac82e
RD
566
567 def SetTickColours(self, h=None, m=None):
568 if not m:
569 m=h
570 if h:
571 self.SetTickBorderColour(h, HOUR)
572 self.SetTickFillColour(h, HOUR)
573 if m:
574 self.SetTickBorderColour(m, MINUTE)
575 self.SetTickFillColour(m, MINUTE)
576
577 def SetTickSizes(self, h=None, m=None):
578 if h:
579 self.SetTickSize(h, HOUR)
580 if m:
99ceaa26 581 self.SetTickSize(m, MINUTE)
caeac82e
RD
582
583 def SetTickFontss(self, h=None, m=None):
584 if h:
585 self.SetTickFont(h, HOUR)
586 if m:
99ceaa26 587 self.SetTickFont(m, MINUTE)
caeac82e
RD
588
589
590 def SetMinutesOffset(self, o):
591 pass
592
593 def SetShadowColour(self, s):
594 pass
595
596 def SetWatchPenBrush(self, p=None, b=None):
597 if p:
598 self.SetFaceBorderColour(p.GetColour())
599 self.SetFaceBorderWidth(p.GetWidth())
600 if b:
601 self.SetFaceFillColour(b.GetColour())
602
603 def SetClockStyle(self, style):
604 style |= SHOW_HOURS_HAND|SHOW_MINUTES_HAND|SHOW_SECONDS_HAND
605 AnalogClock.SetClockStyle(self, style)
606
607 def SetTickStyles(self, h=None, m=None):
608 if h:
609 self.SetTickStyle(h, HOUR)
610 if m:
611 self.SetTickStyle(h, MINUTE)
612
613
614# Test stuff ----------------------------------------------------------
615
616if __name__ == "__main__":
617 print wx.VERSION_STRING
618
619 class AcDemoApp(wx.App):
620 def OnInit(self):
621 frame = wx.Frame(None, -1, "AnalogClock", size=(375, 375))
622 clock = AnalogClock(frame)
623 frame.CentreOnScreen()
624 frame.Show()
625 return True
626
627 acApp = AcDemoApp(0)
628 acApp.MainLoop()
629
630
631#
632##
633### eof