wxWidgets/wxPython/wx/lib/analogclock.py
Robin Dunn b881fc787d Lots of wx namespace updates for the wx.lib package and the demo from
Jeff Grimmett with some tweaks and changes from Robin


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2003-12-17 00:34:40 +00:00

210 lines
6.8 KiB
Python

#----------------------------------------------------------------------
# Name: wxPython.lib.analogclock
# Purpose: A simple analog clock window
#
# Author: several folks on wxPython-users
#
# Created: 16-April-2003
# RCS-ID: $Id$
# Copyright: (c) 2003 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o Updated for wx namespace
# o Tested with updated demo and with builtin test.
#
import math
import string
import sys
import time
import wx
class AnalogClockWindow(wx.Window):
"""A simple analog clock window"""
TICKS_NONE = 0
TICKS_SQUARE = 1
TICKS_CIRCLE = 2
def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=0, name="clock"):
# Initialize the wxWindow...
wx.Window.__init__(self, parent, ID, pos, size, style, name)
# Initialize the default clock settings...
self.minuteMarks = 60
self.hourMarks = 12
self.tickMarksBrushC = self.GetForegroundColour()
self.tickMarksPenC = self.GetForegroundColour()
self.tickMarkStyle = self.TICKS_SQUARE
# Make an initial bitmap for the face, it will be updated and
# painted at the first EVT_SIZE event.
W, H = size
self.faceBitmap = wx.EmptyBitmap(max(W,1), max(H,1))
# Initialize the timer that drives the update of the clock
# face. Update every half second to ensure that there is at
# least one true update during each realtime second.
self.timer = wx.Timer(self)
self.timer.Start(500)
# Set event handlers...
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_TIMER, self.OnTimerExpire)
self.Bind(wx.EVT_WINDOW_DESTROY, self.OnQuit)
def SetTickMarkStyle(self, style):
"""
Set the style of the marks around the edge of the clock.
Options are TICKS_NONE, TICKS_SQUARE, and TICKS_CIRCLE
"""
self.tickMarkStyle = style
def SetTickMarkColours(self, brushC, penC="BLACK"):
"""
Set the brush colour and optionally the pen colour of
the marks around the edge of the clock.
"""
self.tickMarksBrushC = brushC
self.tickMarksPenC = penC
SetTickMarkColour = SetTickMarkColours
def SetHandsColour(self, c):
"""An alias for SetForegroundColour"""
self.SetForegroundColour(c) # the hands just use the foreground colour
# Using the current settings, render the points and line endings for the
# circle inside the specified device context. In this case, the DC is
# a memory based device context that will be blitted to the actual
# display DC inside the OnPaint() event handler.
def OnSize(self, event):
# The faceBitmap init is done here, to make sure the buffer is always
# the same size as the Window
size = self.GetClientSize()
self.faceBitmap = wx.EmptyBitmap(size.width, size.height)
self.DrawFace()
def OnPaint(self, event):
self.DrawHands(wx.PaintDC(self))
def OnQuit(self, event):
self.timer.Stop()
del self.timer
def OnTimerExpire(self, event):
self.DrawHands(wx.ClientDC(self))
def DrawHands(self, drawDC):
# Start by drawing the face bitmap
drawDC.DrawBitmap(self.faceBitmap, (0,0))
currentTime = time.localtime(time.time())
hour, minutes, seconds = currentTime[3:6]
W,H = self.faceBitmap.GetWidth(), self.faceBitmap.GetHeight()
centerX = W / 2
centerY = H / 2
radius = min(centerX, centerY)
hour += minutes / 60.0 # added so the hour hand moves continuously
x, y = self.point(hour, 12, (radius * .65))
hourX, hourY = (x + centerX), (centerY - y)
x, y = self.point(minutes, 60, (radius * .85))
minutesX, minutesY = (x + centerX), (centerY - y)
x, y = self.point(seconds, 60, (radius * .85))
secondsX, secondsY = (x + centerX), (centerY - y)
# Draw the hour hand...
drawDC.SetPen(wx.Pen(self.GetForegroundColour(), 5, wx.SOLID))
drawDC.DrawLine((centerX, centerY), (hourX, hourY))
# Draw the minutes hand...
drawDC.SetPen(wx.Pen(self.GetForegroundColour(), 3, wx.SOLID))
drawDC.DrawLine((centerX, centerY), (minutesX, minutesY))
# Draw the seconds hand...
drawDC.SetPen(wx.Pen(self.GetForegroundColour(), 1, wx.SOLID))
drawDC.DrawLine((centerX, centerY), (secondsX, secondsY))
# Draw the specified set of line marks inside the clock face for the
# hours or minutes...
def DrawFace(self):
backgroundBrush = wx.Brush(self.GetBackgroundColour(), wx.SOLID)
drawDC = wx.MemoryDC()
drawDC.SelectObject(self.faceBitmap)
drawDC.SetBackground(backgroundBrush)
drawDC.Clear()
W,H = self.faceBitmap.GetWidth(), self.faceBitmap.GetHeight()
centerX = W / 2
centerY = H / 2
# Draw the marks for hours and minutes...
self.DrawTimeMarks(drawDC, self.minuteMarks, centerX, centerY, 4)
self.DrawTimeMarks(drawDC, self.hourMarks, centerX, centerY, 9)
def DrawTimeMarks(self, drawDC, markCount, centerX, centerY, markSize):
for i in range(markCount):
x, y = self.point(i + 1, markCount, min(centerX,centerY) - 16)
scaledX = x + centerX - markSize/2
scaledY = centerY - y - markSize/2
drawDC.SetBrush(wx.Brush(self.tickMarksBrushC, wx.SOLID))
drawDC.SetPen(wx.Pen(self.tickMarksPenC, 1, wx.SOLID))
if self.tickMarkStyle != self.TICKS_NONE:
if self.tickMarkStyle == self.TICKS_CIRCLE:
drawDC.DrawEllipse((scaledX - 2, scaledY), (markSize, markSize))
else:
drawDC.DrawRectangle((scaledX - 3, scaledY), (markSize, markSize))
def point(self, tick, range, radius):
angle = tick * (360.0 / range)
radiansPerDegree = math.pi / 180
pointX = int(round(radius * math.sin(angle * radiansPerDegree)))
pointY = int(round(radius * math.cos(angle * radiansPerDegree)))
return wx.Point(pointX, pointY)
if __name__ == "__main__":
class App(wx.App):
def OnInit(self):
frame = wx.Frame(None, -1, "AnalogClockWindow Test", size=(375,375))
clock = AnalogClockWindow(frame)
clock.SetTickMarkColours("RED")
clock.SetHandsColour("WHITE")
clock.SetBackgroundColour("BLUE")
frame.Centre(wx.BOTH)
frame.Show(True)
self.SetTopWindow(frame)
return True
theApp = App(0)
theApp.MainLoop()