]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/analogclock.py
1.
[wxWidgets.git] / wxPython / wx / lib / analogclock.py
CommitLineData
d14a1e28
RD
1#----------------------------------------------------------------------
2# Name: wxPython.lib.analogclock
3# Purpose: A simple analog clock window
4#
5# Author: several folks on wxPython-users
6#
7# Created: 16-April-2003
8# RCS-ID: $Id$
9# Copyright: (c) 2003 by Total Control Software
10# Licence: wxWindows license
11#----------------------------------------------------------------------
b881fc78
RD
12# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
13#
14# o Updated for wx namespace
15# o Tested with updated demo and with builtin test.
16#
d14a1e28 17
b881fc78
RD
18import math
19import string
20import sys
21import time
d14a1e28 22
b881fc78 23import wx
d14a1e28 24
b881fc78 25class AnalogClockWindow(wx.Window):
d14a1e28
RD
26 """A simple analog clock window"""
27
28 TICKS_NONE = 0
29 TICKS_SQUARE = 1
30 TICKS_CIRCLE = 2
31
b881fc78 32 def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
d14a1e28 33 style=0, name="clock"):
b881fc78 34
d14a1e28 35 # Initialize the wxWindow...
b881fc78 36 wx.Window.__init__(self, parent, ID, pos, size, style, name)
d14a1e28
RD
37
38 # Initialize the default clock settings...
39 self.minuteMarks = 60
40 self.hourMarks = 12
41 self.tickMarksBrushC = self.GetForegroundColour()
42 self.tickMarksPenC = self.GetForegroundColour()
43 self.tickMarkStyle = self.TICKS_SQUARE
44
45 # Make an initial bitmap for the face, it will be updated and
46 # painted at the first EVT_SIZE event.
47 W, H = size
b881fc78 48 self.faceBitmap = wx.EmptyBitmap(max(W,1), max(H,1))
d14a1e28
RD
49
50 # Initialize the timer that drives the update of the clock
51 # face. Update every half second to ensure that there is at
52 # least one true update during each realtime second.
b881fc78 53 self.timer = wx.Timer(self)
d14a1e28
RD
54 self.timer.Start(500)
55
56 # Set event handlers...
b881fc78
RD
57 self.Bind(wx.EVT_PAINT, self.OnPaint)
58 self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
59 self.Bind(wx.EVT_SIZE, self.OnSize)
60 self.Bind(wx.EVT_TIMER, self.OnTimerExpire)
61 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnQuit)
d14a1e28
RD
62
63
64 def SetTickMarkStyle(self, style):
65 """
66 Set the style of the marks around the edge of the clock.
67 Options are TICKS_NONE, TICKS_SQUARE, and TICKS_CIRCLE
68 """
69 self.tickMarkStyle = style
70
71
72 def SetTickMarkColours(self, brushC, penC="BLACK"):
73 """
74 Set the brush colour and optionally the pen colour of
75 the marks around the edge of the clock.
76 """
77 self.tickMarksBrushC = brushC
78 self.tickMarksPenC = penC
79
80 SetTickMarkColour = SetTickMarkColours
81
82
83 def SetHandsColour(self, c):
84 """An alias for SetForegroundColour"""
85 self.SetForegroundColour(c) # the hands just use the foreground colour
86
87
d14a1e28
RD
88 # Using the current settings, render the points and line endings for the
89 # circle inside the specified device context. In this case, the DC is
90 # a memory based device context that will be blitted to the actual
91 # display DC inside the OnPaint() event handler.
92 def OnSize(self, event):
93 # The faceBitmap init is done here, to make sure the buffer is always
94 # the same size as the Window
95 size = self.GetClientSize()
b881fc78 96 self.faceBitmap = wx.EmptyBitmap(size.width, size.height)
d14a1e28
RD
97 self.DrawFace()
98
99
100 def OnPaint(self, event):
b881fc78 101 self.DrawHands(wx.PaintDC(self))
d14a1e28
RD
102
103
104 def OnQuit(self, event):
105 self.timer.Stop()
106 del self.timer
107
108
109 def OnTimerExpire(self, event):
b881fc78 110 self.DrawHands(wx.ClientDC(self))
d14a1e28
RD
111
112
113 def DrawHands(self, drawDC):
114 # Start by drawing the face bitmap
115 drawDC.DrawBitmap(self.faceBitmap, (0,0))
116
117 currentTime = time.localtime(time.time())
118 hour, minutes, seconds = currentTime[3:6]
119
120 W,H = self.faceBitmap.GetWidth(), self.faceBitmap.GetHeight()
121 centerX = W / 2
122 centerY = H / 2
123
124 radius = min(centerX, centerY)
125 hour += minutes / 60.0 # added so the hour hand moves continuously
126 x, y = self.point(hour, 12, (radius * .65))
127 hourX, hourY = (x + centerX), (centerY - y)
128 x, y = self.point(minutes, 60, (radius * .85))
129 minutesX, minutesY = (x + centerX), (centerY - y)
130 x, y = self.point(seconds, 60, (radius * .85))
131 secondsX, secondsY = (x + centerX), (centerY - y)
132
133 # Draw the hour hand...
b881fc78 134 drawDC.SetPen(wx.Pen(self.GetForegroundColour(), 5, wx.SOLID))
d14a1e28
RD
135 drawDC.DrawLine((centerX, centerY), (hourX, hourY))
136
137 # Draw the minutes hand...
b881fc78 138 drawDC.SetPen(wx.Pen(self.GetForegroundColour(), 3, wx.SOLID))
d14a1e28
RD
139 drawDC.DrawLine((centerX, centerY), (minutesX, minutesY))
140
141 # Draw the seconds hand...
b881fc78 142 drawDC.SetPen(wx.Pen(self.GetForegroundColour(), 1, wx.SOLID))
d14a1e28
RD
143 drawDC.DrawLine((centerX, centerY), (secondsX, secondsY))
144
145
146 # Draw the specified set of line marks inside the clock face for the
147 # hours or minutes...
148 def DrawFace(self):
b881fc78
RD
149 backgroundBrush = wx.Brush(self.GetBackgroundColour(), wx.SOLID)
150 drawDC = wx.MemoryDC()
d14a1e28
RD
151 drawDC.SelectObject(self.faceBitmap)
152 drawDC.SetBackground(backgroundBrush)
153 drawDC.Clear()
154
155 W,H = self.faceBitmap.GetWidth(), self.faceBitmap.GetHeight()
156 centerX = W / 2
157 centerY = H / 2
158
159 # Draw the marks for hours and minutes...
160 self.DrawTimeMarks(drawDC, self.minuteMarks, centerX, centerY, 4)
161 self.DrawTimeMarks(drawDC, self.hourMarks, centerX, centerY, 9)
162
163
164 def DrawTimeMarks(self, drawDC, markCount, centerX, centerY, markSize):
165 for i in range(markCount):
166 x, y = self.point(i + 1, markCount, min(centerX,centerY) - 16)
167 scaledX = x + centerX - markSize/2
168 scaledY = centerY - y - markSize/2
169
b881fc78
RD
170 drawDC.SetBrush(wx.Brush(self.tickMarksBrushC, wx.SOLID))
171 drawDC.SetPen(wx.Pen(self.tickMarksPenC, 1, wx.SOLID))
172
d14a1e28
RD
173 if self.tickMarkStyle != self.TICKS_NONE:
174 if self.tickMarkStyle == self.TICKS_CIRCLE:
175 drawDC.DrawEllipse((scaledX - 2, scaledY), (markSize, markSize))
176 else:
177 drawDC.DrawRectangle((scaledX - 3, scaledY), (markSize, markSize))
178
179
180 def point(self, tick, range, radius):
181 angle = tick * (360.0 / range)
182 radiansPerDegree = math.pi / 180
183 pointX = int(round(radius * math.sin(angle * radiansPerDegree)))
184 pointY = int(round(radius * math.cos(angle * radiansPerDegree)))
b881fc78 185 return wx.Point(pointX, pointY)
d14a1e28
RD
186
187
188
189
190if __name__ == "__main__":
b881fc78 191 class App(wx.App):
d14a1e28 192 def OnInit(self):
b881fc78 193 frame = wx.Frame(None, -1, "AnalogClockWindow Test", size=(375,375))
d14a1e28
RD
194
195 clock = AnalogClockWindow(frame)
196 clock.SetTickMarkColours("RED")
197 clock.SetHandsColour("WHITE")
198 clock.SetBackgroundColour("BLUE")
199
b881fc78 200 frame.Centre(wx.BOTH)
d14a1e28
RD
201 frame.Show(True)
202 self.SetTopWindow(frame)
b881fc78 203 return True
d14a1e28
RD
204
205 theApp = App(0)
206 theApp.MainLoop()
207
1fded56b 208
1fded56b 209