Updated the analogclock.py module to the new analogclock package from

E. A. Tacao.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38120 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn 2006-03-15 23:17:54 +00:00
parent 5f3c9dc69c
commit caeac82e4d
13 changed files with 2927 additions and 1419 deletions

View File

@ -0,0 +1,139 @@
# AnalogClock demo
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 12 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
import wx
import wx.lib.analogclock as ac
#----------------------------------------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent)
# A mostly default clock
c1 = ac.AnalogClock(self)
# A plain clock, with square hour and round minute marks, no
# shadow, static border
c2 = ac.AnalogClock(self, style=wx.STATIC_BORDER,
hoursStyle=ac.TICKS_SQUARE,
minutesStyle=ac.TICKS_CIRCLE,
clockStyle=ac.SHOW_HOURS_TICKS| \
ac.SHOW_MINUTES_TICKS|
ac.SHOW_HOURS_HAND| \
ac.SHOW_MINUTES_HAND| \
ac.SHOW_SECONDS_HAND)
c2.SetTickSize(12, target=ac.HOUR)
# No minute tick marks
c3 = ac.AnalogClock(self, hoursStyle=ac.TICKS_CIRCLE,
clockStyle=ac.SHOW_HOURS_TICKS| \
ac.SHOW_HOURS_HAND| \
ac.SHOW_MINUTES_HAND| \
ac.SHOW_SECONDS_HAND| \
ac.SHOW_SHADOWS)
c3.SetTickSize(12)
# A clock with hex numbers no seconds hand and different colours.
c4 = ac.AnalogClock(self, hoursStyle=ac.TICKS_HEX,
clockStyle=ac.SHOW_HOURS_TICKS| \
ac.SHOW_HOURS_HAND| \
ac.SHOW_MINUTES_HAND| \
ac.SHOW_SHADOWS)
colour = wx.Colour(0, 255, 255)
c4.SetForegroundColour(colour)
colour = wx.Colour(0, 132, 132)
c4.SetShadowColour(colour)
c4.SetTickFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.BOLD))
c4.SetBackgroundColour(wx.BLACK)
c4.SetFaceBorderColour(wx.BLACK)
c4.SetFaceFillColour(wx.BLACK)
# A clock with binary numbers shown only at the quarter tick marks,
# no minutes ticks and different colours.
c5 = ac.AnalogClock(self, style = wx.RAISED_BORDER,
hoursStyle=ac.TICKS_BINARY,
clockStyle=ac.SHOW_QUARTERS_TICKS| \
ac.SHOW_HOURS_HAND| \
ac.SHOW_MINUTES_HAND| \
ac.SHOW_SECONDS_HAND| \
ac.SHOW_SHADOWS)
colour = wx.Colour(0, 128, 0)
c5.SetHandFillColour(colour, target=ac.SECOND)
c5.SetHandBorderColour(colour, target=ac.SECOND)
c5.SetBackgroundColour(colour)
colour = wx.Colour(128, 0, 64)
c5.SetTickFillColour(colour)
c5.SetFaceBorderColour(colour)
c5.SetFaceBorderWidth(1)
colour = wx.Colour(0, 198, 0)
c5.SetFaceFillColour(colour)
c5.SetShadowColour(wx.WHITE)
# A clock with a sunken border, roman numerals shown only at the
# quarter tick marks with a roman font, circular minutes ticks,
# no seconds hand, no shadows, tick overlapping and different colours.
c6 = ac.AnalogClock(self, style = wx.SUNKEN_BORDER,
hoursStyle=ac.TICKS_ROMAN,
minutesStyle=ac.TICKS_CIRCLE,
clockStyle=ac.SHOW_QUARTERS_TICKS| \
ac.SHOW_MINUTES_TICKS| \
ac.SHOW_HOURS_HAND| \
ac.SHOW_MINUTES_HAND| \
ac.OVERLAP_TICKS)
colour = wx.Colour(128, 0, 0)
c6.SetHandFillColour(colour)
colour = wx.Colour(179, 0, 89)
c6.SetHandBorderColour(colour)
c6.SetTickFillColour(colour)
c6.SetTickBorderColour(colour)
colour = wx.Colour(225, 255, 255)
c6.SetFaceBorderColour(colour)
c6.SetBackgroundColour(colour)
colour = wx.Colour(249, 255, 255)
c6.SetFaceFillColour(colour)
colour = wx.Colour(255, 213, 213)
c6.SetShadowColour(colour)
c6.SetTickFont(wx.Font(10, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.BOLD))
# layout the clocks in a grid
gs = wx.GridSizer(2, 3, 4, 4)
gs.Add(c1, 0, wx.EXPAND)
gs.Add(c2, 0, wx.EXPAND)
gs.Add(c3, 0, wx.EXPAND)
gs.Add(c4, 0, wx.EXPAND)
gs.Add(c5, 0, wx.EXPAND)
gs.Add(c6, 0, wx.EXPAND)
# put it in another sizer for a border
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(gs, 1, wx.EXPAND|wx.ALL, 10)
self.SetSizerAndFit(sizer)
#----------------------------------------------------------------------
def runTest(frame, nb, log):
win = TestPanel(nb, log)
return win
#----------------------------------------------------------------------
overview = """<html>
<PRE><FONT SIZE=-1>
""" + ac.__doc__.replace("<", "").replace(">", "") + """
</FONT></PRE>"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])

View File

@ -1,106 +0,0 @@
import wx
from wx.lib import analogclock as ac
#----------------------------------------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
# A mostly default clock
c1 = ac.AnalogClockWindow(self)
c1.SetBackgroundColour("RED")
c1.SetHandColours("BLUE")
c1.SetTickColours("WHITE")
c1.SetTickSizes(h=5, m=2)
# A clock with roman numerals, shown only at the quarter
# marks, and a separatly coloured watch face.
c2 = ac.AnalogClockWindow(self)
c2.SetBackgroundColour("WHITE")
c2.SetHandColours("RED")
c2.SetTickColours("BLUE")
c2.SetTickStyles(ac.TICKS_ROMAN)
c2.SetClockStyle(ac.SHOW_QUARTERS_TICKS | ac.SHOW_SHADOWS)
c2.SetWatchPenBrush(p=wx.Pen((238, 238, 227), 1, wx.SOLID),
b=wx.Brush("CADET BLUE", wx.SOLID))
c2.SetTickSizes(h=12)
# A clock with rotated decimal numbers, shown at all twelve
# hour marks
c3 = ac.AnalogClockWindow(self)
c3.SetBackgroundColour("BLUE")
c3.SetHandColours("WHITE")
c3.SetTickColours("RED")
c3.SetTickStyles(h=ac.TICKS_DECIMAL)
c3.SetClockStyle(ac.SHOW_HOURS_TICKS | ac.ROTATE_TICKS)
c3.SetTickSizes(h=14)
# a plain clock, with square hour and round minute marks, no
# shadow raised border
c4 = ac.AnalogClockWindow(self, style=wx.RAISED_BORDER)
c4.SetTickStyles(h=ac.TICKS_SQUARE, m=ac.TICKS_CIRCLE)
c4.SetClockStyle(ac.SHOW_HOURS_TICKS | ac.SHOW_MINUTES_TICKS)
c4.SetTickSizes(h=5, m=2)
# no minute tick marks
c5 = ac.AnalogClockWindow(self)
c5.SetTickStyles(h=ac.TICKS_CIRCLE)
c5.SetClockStyle(ac.SHOW_HOURS_TICKS | ac.SHOW_SHADOWS | ac.ROTATE_TICKS)
c5.SetTickSizes(h=5, m=2)
# sunken border
c6 = ac.AnalogClockWindow(self, style=wx.SUNKEN_BORDER)
c6.SetTickSizes(h=5, m=2)
# layout the clocks in a grid
gs = wx.GridSizer(2, 3, 4, 4)
gs.Add(c1, 0, wx.EXPAND)
gs.Add(c2, 0, wx.EXPAND)
gs.Add(c3, 0, wx.EXPAND)
gs.Add(c4, 0, wx.EXPAND)
gs.Add(c5, 0, wx.EXPAND)
gs.Add(c6, 0, wx.EXPAND)
# put it in another sizer for a border
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(gs, 1, wx.EXPAND | wx.ALL, 10)
self.SetSizer(sizer)
#----------------------------------------------------------------------
def runTest(frame, nb, log):
win = TestPanel(nb, log)
return win
#----------------------------------------------------------------------
overview = """<html><body>
<h2><center>AnalogClockWindow</center></h2>
This is a nice little clock class that was contributed to by several
members of the wxPython-users group.
<p>
Check the options available by right-clicking the clock.
</body></html>
"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])

View File

@ -1,812 +0,0 @@
# -*- coding: iso-8859-1 -*-
#----------------------------------------------------------------------
# Name: wx.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.
#
# 15-February-2004 - E. A. Tacao
#
# o Many ehnacements
#
"""
`AnalogClockWindow` is a simple analog clock class.
"""
import math
import sys
import string
import time
import wx
from analogclockopts import ACCustomizationFrame
# self.clockStyle:
SHOW_QUARTERS_TICKS = 1
SHOW_HOURS_TICKS = 2
SHOW_MINUTES_TICKS = 4
ROTATE_TICKS = 8
SHOW_HOURS_HAND = 16
SHOW_MINUTES_HAND = 32
SHOW_SECONDS_HAND = 64
SHOW_SHADOWS = 128
OVERLAP_TICKS = 256
# self.tickMarkHoursStyle and self.tickMarkMinutesStyle:
TICKS_NONE = 1
TICKS_SQUARE = 2
TICKS_CIRCLE = 4
TICKS_POLY = 8
TICKS_DECIMAL = 16
TICKS_ROMAN = 32
class AnalogClockWindow(wx.PyWindow):
"""An analog clock window"""
def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=0, name="clock"):
# Initialize the wxWindow...
wx.PyWindow.__init__(self, parent, ID, pos, size, style, name)
# Initialize some variables and defaults...
self.clockStep = 1
self.prefs_open = False
self.tickShapeHours = self.tickShapeMinutes= [[0,0],
[1,-1],
[2,0],
[1,4]]
self.handHoursThickness = 5
self.handHoursColour = (0, 0, 0)
self.handMinutesThickness = 3
self.handMinutesColour = (0, 0, 0)
self.handSecondsThickness = 1
self.handSecondsColour = (0, 0, 0)
self.tickMarkHoursPen = wx.Pen((0, 0, 0), 1, wx.SOLID)
self.tickMarkHoursBrush = wx.Brush((0, 0, 0), wx.SOLID)
self.markSizeHour = 10
self.tickMarkHoursFont = wx.Font(1, wx.SWISS, wx.NORMAL, wx.BOLD)
self.tickMarkHoursFont.SetPointSize(self.markSizeHour)
self.tickMarkMinutesPen = wx.Pen((0, 0, 0), 1, wx.SOLID)
self.tickMarkMinutesBrush = wx.Brush((0, 0, 0), wx.SOLID)
self.markSizeMin = 6
self.tickMarkMinutesFont = wx.Font(self.markSizeMin, wx.SWISS, wx.NORMAL, wx.BOLD)
self.offM = 0
self.shadowPenColour = self.shadowBrushColour = (128,128,128)
self.watchPen = None
self.watchBrush = None
self.clockStyle = SHOW_HOURS_TICKS | SHOW_MINUTES_TICKS | SHOW_SHADOWS | ROTATE_TICKS
self.handsStyle = SHOW_SECONDS_HAND
self.tickMarkHoursStyle = TICKS_POLY
self.tickMarkMinutesStyle = TICKS_CIRCLE
self.currentTime=None
size = wx.Size(*size)
bestSize = self.GetBestSize()
size.x = max(size.x, bestSize.x)
size.y = max(size.y, bestSize.y)
self.SetSize(size)
# 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))
# 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)
self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
# 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)
def DoGetBestSize(self):
return wx.Size(25,25)
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self)
if hasattr(self, 'coords'):
self._doDrawHands(dc, True)
def OnTimerExpire(self, event):
size = self.GetClientSize()
dc = wx.BufferedDC(wx.ClientDC(self), size)
self._doDrawHands(dc, True)
def OnQuit(self, event):
self.timer.Stop()
del self.timer
def OnRightDown(self, event):
self.x = event.GetX()
self.y = event.GetY()
event.Skip()
def OnRightClick(self, event):
# only do this part the first time so the events are only bound once
if not hasattr(self, "popupID1"):
self.popupID1 = wx.NewId()
self.popupID2 = wx.NewId()
self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
# make a menu
sm = wx.Menu()
sm.Append(self.popupID1, "Customize...")
sm.Append(self.popupID2, "About...")
# If there already a setup window open, we must not appear...
if not self.prefs_open:
# Popup the menu. If an item is selected then its handler
# will be called before PopupMenu returns.
self.PopupMenu(sm, (self.x,self.y))
sm.Destroy()
def OnPopupOne(self, event):
self.prefs_open=True
frame = ACCustomizationFrame(self, -1, "AnalogClock Preferences")
frame.Show(True)
def OnPopupTwo(self, event):
dlg = wx.MessageDialog(self, "AnalogClockWindow\n\nby Several folks on wxPython-users\nwith enhancements from E. A. Tacão",
'About', wx.OK | wx.ICON_INFORMATION)
dlg.ShowModal()
dlg.Destroy()
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()
if size.x < 1 or size.y < 1:
return
self.faceBitmap = wx.EmptyBitmap(size.width, size.height)
# Update drawing coordinates...
new_dim = size.Get()
if not hasattr(self,"dim"):
self.dim = new_dim
x,y=[0,1]
self.scale = min([float(new_dim[x]) / self.dim[x],
float(new_dim[y]) / self.dim[y]])
self.centerX = self.faceBitmap.GetWidth() / 2
self.centerY = self.faceBitmap.GetHeight() / 2
self.shadowDistance = 2 * self.scale
self.radius_watch = min(self.centerX, self.centerY)
self._doDrawFace()
def _doDrawHands(self, drawDC, force=0):
currentTime = list(time.localtime(time.time())[3:6])
if not (self.handsStyle & SHOW_SECONDS_HAND):
currentTime[2]=-1
if not (force or currentTime != self.currentTime):
return
self.currentTime = currentTime
hour, minutes, seconds = currentTime
# Start by drawing the face bitmap
drawDC.DrawBitmap(self.faceBitmap, 0,0)
# NOTE: All this hand drawing code below should be refactored into a helper function.
# Draw hours hand shadow
mStep = 6 * self.clockStep
angle = hour * 30
if angle > 360:
angle = angle - 360
angle = angle + round(minutes/(mStep*2)) * mStep
x,y,f = self._getCoords("hand_hours", angle)
if f and self.clockStyle & SHOW_SHADOWS:
drawDC.SetPen(wx.Pen(self.shadowPenColour,
int(self.handHoursThickness * self.scale),
wx.SOLID))
drawDC.DrawLine(self.centerX + self.shadowDistance,
self.centerY + self.shadowDistance,
x + self.shadowDistance,
y + self.shadowDistance)
# Draw minutes hand shadow
angle = minutes * 6
x,y,f = self._getCoords("hand_minutes", angle)
if f and self.clockStyle & SHOW_SHADOWS:
drawDC.SetPen(wx.Pen(self.shadowPenColour,
int(self.handMinutesThickness * self.scale),
wx.SOLID))
drawDC.DrawLine(self.centerX + self.shadowDistance,
self.centerY + self.shadowDistance,
x + self.shadowDistance,
y + self.shadowDistance)
# Draw seconds hand shadow if required
if seconds >= 0:
angle = seconds * 6
x,y,f = self._getCoords("hand_seconds", angle)
if f and self.clockStyle & SHOW_SHADOWS:
drawDC.SetPen(wx.Pen(self.shadowPenColour,
int(self.handSecondsThickness * self.scale),
wx.SOLID))
drawDC.DrawLine(self.centerX + self.shadowDistance,
self.centerY + self.shadowDistance,
x + self.shadowDistance,
y + self.shadowDistance)
# Draw hours hand
angle = hour * 30
if angle > 360:
angle = angle - 360
angle = angle + round(minutes/(mStep*2)) * mStep
x,y,f = self._getCoords("hand_hours", angle)
if f:
drawDC.SetPen(wx.Pen(self.handHoursColour,
int(self.handHoursThickness * self.scale),
wx.SOLID))
drawDC.DrawLine(self.centerX, self.centerY, x, y)
# Draw minutes hand
angle = minutes * 6
x,y,f = self._getCoords("hand_minutes", angle)
if f:
drawDC.SetPen(wx.Pen(self.handMinutesColour,
int(self.handMinutesThickness * self.scale),
wx.SOLID))
drawDC.DrawLine(self.centerX, self.centerY, x, y)
# Draw seconds hand if required
if seconds >= 0:
angle = seconds * 6
x,y,f = self._getCoords("hand_seconds", angle)
if f:
drawDC.SetPen(wx.Pen(self.handSecondsColour,
int(self.handSecondsThickness * self.scale),
wx.SOLID))
drawDC.DrawLine(self.centerX, self.centerY, x, y)
def _doDrawFace(self):
backgroundBrush = wx.Brush(self.GetBackgroundColour(), wx.SOLID)
drawDC = wx.MemoryDC()
drawDC.SelectObject(self.faceBitmap)
drawDC.SetBackground(backgroundBrush)
drawDC.Clear()
self.handHoursLength = 0.65 * (self.radius_watch - self._getMarkMaxSize("ticks_hours", drawDC))
self.handMinutesLength = 0.85 * (self.radius_watch - self._getMarkMaxSize("ticks_hours", drawDC))
self.handSecondsLength = 0.85 * (self.radius_watch - self._getMarkMaxSize("ticks_hours", drawDC))
self.radius_ticks_hours = self.radius_watch - self.shadowDistance - self._getMarkMaxSize("ticks_hours", drawDC)
self.radius_ticks_minutes = self.radius_ticks_hours
self._calcSteps()
# Draw the watch...
self._drawWatch(drawDC)
# Draw the marks for hours and minutes...
circle = 360
mStep = 6 * self.clockStep
if self.clockStyle & SHOW_SHADOWS:
for i in range(0, circle, mStep):
for t in self.coords.keys():
if t.find("ticks") > -1:
x,y,f = self._getCoords(t, i)
if f:
self._doDrawTickMark(i, drawDC, t,
x + self.shadowDistance,
y + self.shadowDistance,
True)
for i in range(0, circle, mStep):
for t in self.coords.keys():
if t.find("ticks") > -1:
x,y,f = self._getCoords(t, i)
if f:
self._doDrawTickMark(i, drawDC, t, x, y)
def _doDrawTickMark(self, angle, drawDC, tipo, x, y, is_a_shadow=None):
opts = {"ticks_hours": [self.tickMarkHoursPen, self.tickMarkHoursBrush, self.markSizeHour, self.tickMarkHoursStyle],
"ticks_quarters": [self.tickMarkHoursPen, self.tickMarkHoursBrush, self.markSizeHour, self.tickMarkHoursStyle],
"ticks_minutes": [self.tickMarkMinutesPen, self.tickMarkMinutesBrush, self.markSizeMin, self.tickMarkMinutesStyle]}
pen, brush, size, style = opts[tipo];
size = size * self.scale
if is_a_shadow:
drawDC.SetPen(wx.Pen(self.shadowPenColour, 1, wx.SOLID))
drawDC.SetBrush(wx.Brush(self.shadowBrushColour, wx.SOLID))
drawDC.SetTextForeground(self.shadowBrushColour)
else:
drawDC.SetPen(pen)
drawDC.SetBrush(brush)
drawDC.SetTextForeground(brush.GetColour())
if style & TICKS_CIRCLE:
x, y = self._center2corner(x, y, tipo)
drawDC.DrawEllipse(x, y, size, size)
elif style & TICKS_SQUARE:
x, y = self._center2corner(x, y, tipo)
drawDC.DrawRectangle(x, y, size, size)
elif (style & TICKS_DECIMAL) or (style & TICKS_ROMAN):
self._draw_rotate_text(drawDC, x, y, tipo, angle)
elif style & TICKS_POLY:
self._draw_rotate_polygon(drawDC, x, y, tipo, angle)
def _draw_rotate_text(self, drawDC, x, y, tipo, angle):
text = self._build_text(angle, tipo)
lX, lY = self._center2corner(x, y, tipo, drawDC)
lX = lX * len(text)
angle = 360 - angle
if self.clockStyle & ROTATE_TICKS:
radiansPerDegree = math.pi / 180
x = int(x -
((math.cos((angle) * radiansPerDegree)*lX) +
(math.sin((angle) * radiansPerDegree)*lY)))
y = int(y -
((math.cos((angle) * radiansPerDegree)*lY) -
(math.sin((angle) * radiansPerDegree)*lX)))
drawDC.DrawRotatedText(text, x,y, angle)
else:
x = x - lX
y = y - lY
drawDC.DrawText(text, x, y)
def _draw_rotate_polygon(self, drawDC, x, y, tipo, angle):
if tipo=="ticks_quarters":
tipo="ticks_hours"
# Add to empty list to prevent system-wide hard freezes under XP...
points = {"ticks_hours":self.tickShapeHours+[], "ticks_minutes":self.tickShapeMinutes+[]}[tipo]
size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
maxX = max(map(lambda x:x[0],points))
minX = min(map(lambda x:x[0],points))
maxY = max(map(lambda x:x[0],points))
minY = min(map(lambda x:x[0],points))
maxB = abs(max(maxX, maxY));
f = size / maxB
orgX = (maxX - minX) / 2.
orgY = (maxY - minY) / 2.
radiansPerDegree = math.pi / 180
scaledX = x
scaledY = y
for z in range(0, len(points)):
x,y = points[z]
x = x * f - orgX * f
y = y * f - orgY * f
if self.clockStyle & ROTATE_TICKS:
m,t = self._rect2pol(x,y)
t = t + angle
x,y = self._pol2rect(m,t)
x = x + scaledX
y = y + scaledY
points[z] = [int(x), int(y)]
drawDC.DrawPolygon(points)
def _pol2rect(self, r, w, deg=1): # radian if deg=0; degree if deg=1
if deg:
w = math.pi * w / 180.0
return r * math.cos(w), r * math.sin(w)
def _rect2pol(self, x, y, deg=1): # radian if deg=0; degree if deg=1
if deg:
return math.hypot(x, y), 180.0 * math.atan2(y, x) / math.pi
else:
return math.hypot(x, y), math.atan2(y, x)
def _center2corner(self, x, y, tipo, drawDC=None):
if tipo == "ticks_quarters":
tipo = "ticks_hours"
style = {"ticks_hours":self.tickMarkHoursStyle, "ticks_minutes":self.tickMarkMinutesStyle}[tipo]
size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
if style & TICKS_DECIMAL or style & TICKS_ROMAN:
font = {"ticks_hours":self.tickMarkHoursFont, "ticks_minutes":self.tickMarkMinutesFont}[tipo]
font.SetPointSize(int(size));
drawDC.SetFont(font)
lX = drawDC.GetCharWidth() / 2.
lY = drawDC.GetCharHeight() / 2.
x = lX
y = lY
else:
size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
x=x-size/2.;y=y-size/2.
return x, y
def _build_text(self, angle, tipo):
if tipo == "ticks_quarters":
tipo = "ticks_hours"
a = angle
if a <= 0:
a = a + 360
divider = {"ticks_hours":30,"ticks_minutes":6}[tipo]
a = int(a / divider)
style = {"ticks_hours":self.tickMarkHoursStyle," ticks_minutes":self.tickMarkMinutesStyle}[tipo]
if style & TICKS_ROMAN:
text=["I","II","III","IV","V","VI","VII","VIII","IX","X", \
"XI","XII","XIII","XIV","XV","XVI","XVII","XVIII","XIX","XX", \
"XXI","XXII","XXIII","XXIV","XXV","XXVI","XXVII","XXVIII","XXIX","XXX", \
"XXXI","XXXII","XXXIII","XXXIV","XXXV","XXXVI","XXXVII","XXXVIII","XXXIX","XL", \
"XLI","XLII","XLIII","XLIV","XLV","XLVI","XLVII","XLVIII","XLIX","L", \
"LI","LII","LIII","LIV","LV","LVI","LVII","LVIII","LIX","LX"][a-1]
else:
text = "%s" % a
return text
def _getMarkMaxSize(self, tipo, drawDC=None):
if tipo == "ticks_quarters":
tipo = "ticks_hours"
style = {"ticks_hours":self.tickMarkHoursStyle, "ticks_minutes":self.tickMarkMinutesStyle}[tipo]
size = self.scale * {"ticks_hours":self.markSizeHour, "ticks_minutes":self.markSizeMin}[tipo]
if style & TICKS_DECIMAL or style & TICKS_ROMAN:
lX = 2 * drawDC.GetCharWidth()
lY = drawDC.GetCharHeight()
size = math.sqrt(lX**2 + lY**2) * self.scale
else:
size=math.sqrt(2) * size
return size
def _drawWatch(self, drawDC):
# Draw the watch...
if self.watchPen or self.watchBrush:
if self.watchPen:
drawDC.SetPen(self.watchPen)
if self.watchBrush:
drawDC.SetBrush(self.watchBrush)
else:
drawDC.SetBrush(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
drawDC.DrawCircle(self.centerX, self.centerY, self.radius_watch)
def _calcSteps(self):
# Calcule todos os pontos para:
# - marcas de horas
# - marcas de minutos
# - ponteiro de horas
# - ponteiro de minutos
# - ponteiro de segundos
circle = 360
mStep = 6 * self.clockStep # Step in degrees...
vq = 90 * (self.clockStyle & SHOW_QUARTERS_TICKS) / SHOW_QUARTERS_TICKS
vh = 30 * (self.clockStyle & SHOW_HOURS_TICKS) / SHOW_HOURS_TICKS
vm = 1 * (self.clockStyle & SHOW_MINUTES_TICKS) / SHOW_MINUTES_TICKS
coords = {"ticks_quarters": [self.radius_ticks_hours, 60,vq,{}],
"ticks_hours": [self.radius_ticks_hours, 60,vh,{}],
"ticks_minutes": [self.radius_ticks_minutes,60,vm,{}],
"hand_hours": [self.handHoursLength, 60,1, {}],
"hand_minutes": [self.handMinutesLength, 60,1, {}],
"hand_seconds": [self.handSecondsLength, 60,1, {}]}
radiansPerDegree = math.pi / 180
for t in coords.keys():
for i in range(0, circle+mStep, mStep):
radius = coords[t][0]
if t == "ticks_minutes":
radius = radius - self.offM
step_angle = 360. / coords[t][1]
pre = coords[t][2]
x = self.centerX + radius * math.sin(i * radiansPerDegree)
y = self.centerY + radius * math.cos(i * radiansPerDegree)
f = (pre and (i/step_angle == int(i/step_angle)) and (float(i)/pre == int(i/pre)))
coords[t][3][i] = [x,y,f]
if not self.clockStyle & OVERLAP_TICKS:
for i in range(0, circle + mStep, mStep):
f=coords["ticks_minutes"][3][i][2]
if f and \
(coords["ticks_hours"][3].get(i,[0,0,0])[2] or coords["ticks_quarters"][3].get(i,[0,0,0])[2]):
f=False
coords["ticks_minutes"][3][i][2]=f
self.coords = coords
def _getCoords(self, tipo, angle):
# Returns coords and 'use flag' based on current angle...
k = 360 - (angle + 180)
if k <= 0:
k = k + 360
return self.coords[tipo][3][k]
# -----------------------------------------------------
#
def SetTickShapes(self, tsh, tsm=None):
"""
tsh, tsm: [[x0,y0], [x1,y1], ... [xn,yn]]
Sets lists of lists of points to be used as polygon shapes
when using the TICKS_POLY style. If tsm is ommitted,
we'll use tsh for both shapes.
"""
if not tsm:
tsm=tsh
self.tickShapeHours = tsh
self.tickShapeMinutes = tsm
def SetHandWeights(self, h=None, m=None, s=None):
"""
h, m, s: value
Sets thickness of hands.
"""
if h:
self.handHoursThickness = h
if m:
self.handMinutesThickness = m
if s:
self.handSecondsThickness = s
def SetHandColours(self, h=None, m=None, s=None):
"""
h, m, s: wx.Colour
Sets colours of hands. If m and s are ommitted,
we'll use h for all.
"""
if h and not m and not s:
m=h
s=h
if h:
self.handHoursColour = h
if m:
self.handMinutesColour = m
if s:
self.handSecondsColour = s
def SetTickColours(self, h=None, m=None):
"""
h, m: wx.Colour
Sets colours of ticks. If m is ommitted,
we'll use h for both.
"""
if not m:
m=h
if h:
self.tickMarkHoursPen = wx.Pen(h, 1, wx.SOLID)
self.tickMarkHoursBrush = wx.Brush(h, wx.SOLID)
if m:
self.tickMarkMinutesPen = wx.Pen(m, 1, wx.SOLID)
self.tickMarkMinutesBrush = wx.Brush(m, wx.SOLID)
def SetTickSizes(self, h=None, m=None):
"""
h, m: value
Sizes for tick marks.
"""
if h:
self.markSizeHour = h
if m:
self.markSizeMin = m
def SetTickFonts(self, h=None, m=None):
"""
h, m: wx.Font
Fonts for tick marks when using TICKS_DECIMAL or TICKS_ROMAN style.
If m is ommitted, we'll use h for both.
"""
if not m:
m=h
if h:
self.tickMarkHoursFont = h
self.tickMarkHoursFont.SetPointSize(self.markSizeHour)
if m:
self.tickMarkMinutesFont = m
self.tickMarkMinutesFont.SetPointSize(self.markSizeMin)
def SetMinutesOffset(self, o):
"""
s = value
Sets the distance between tick marks for hours and minutes.
"""
self.offM = o
def SetShadowColour(self, s):
"""
s = wx.Colour or (r,g,b) tuple.
Sets the colour to be used to draw shadows.
"""
self.shadowPenColour = self.shadowBrushColour = s
def SetWatchPenBrush(self, p=None, b=None):
"""
p = wx.Pen; b = wx.Brush
Set the pen and brush for the watch.
"""
if p:
self.watchPen = p
if b:
self.watchBrush = b
def SetClockStyle(self, style):
"""
Set the clock style, acording to these options:
==================== ================================
SHOW_QUARTERS_TICKS Show marks for hours 3, 6, 9, 12
SHOW_HOURS_TICKS Show marks for all hours
SHOW_MINUTES_TICKS Show marks for minutes
SHOW_HOURS_HAND Show hours hand
SHOW_MINUTES_HAND Show minutes hand
SHOW_SECONDS_HAND Show seconds hand
SHOW_SHADOWS Show hands and marks shadows
ROTATE_TICKS Align tick marks to watch
OVERLAP_TICKS Draw tick marks for minutes even
when they match the hours marks.
==================== ================================
"""
self.clockStyle = style
def SetTickStyles(self, h=None, m=None):
"""
Set the ticks styles, acording to the options below.
================= =====================================
TICKS_NONE Don't show tick marks.
TICKS_SQUARE Use squares as tick marks.
TICKS_CIRCLE Use circles as tick marks.
TICKS_POLY Use a polygon as tick marks. The
polygon must be passed using
SetTickShapes, otherwise the default
polygon will be used.
TICKS_DECIMAL Use decimal numbers.
TICKS_ROMAN Use Roman numbers.
================= =====================================
"""
if h:
self.tickMarkHoursStyle = h
if m:
self.tickMarkMinutesStyle = m
#
# -----------------------------------------------------
if __name__ == "__main__":
print wx.VERSION_STRING
class App(wx.App):
def OnInit(self):
frame = wx.Frame(None, -1, "AnalogClockWindow", size=(375,375))
clock = AnalogClockWindow(frame)
# Settings below are used by default...
#clock.SetClockStyle(SHOW_HOURS_TICKS|SHOW_MINUTES_TICKS|SHOW_SHADOWS|ROTATE_TICKS)
#clock.SetTickStyles(TICKS_POLY, TICKS_CIRCLE)
frame.Centre(wx.BOTH)
frame.Show(True)
self.SetTopWindow(frame)
return True
theApp = App(0)
theApp.MainLoop()
#
##
### eof

View File

@ -0,0 +1,144 @@
__author__ = "E. A. Tacao <e.a.tacao |at| estadao.com.br>"
__date__ = "15 Fev 2006, 22:00 GMT-03:00"
__version__ = "0.02"
__doc__ = """
AnalogClock - an analog clock.
This control creates an analog clock window. Its features include shadowing,
the ability to render numbers as well as any arbitrary polygon as tick marks,
resize marks and hands proportionally as the widget itself is resized, rotate
marks in a way the get aligned to the watch. It also has a dialog, accessed
via a context menu item, allowing one to change on the fly all of its settings.
Usage:
AnalogClock(parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.NO_BORDER, name="AnalogClock",
clockStyle=DEFAULT_CLOCK_STYLE,
minutesStyle=TICKS_CIRCLE, hoursStyle=TICKS_POLY)
- parent, id, pos, size, style and name are used as in a wx.Window. Please
refer to the wx.Window docs for more details.
- clockStyle defines the clock style, according to the options below:
==================== ================================
SHOW_QUARTERS_TICKS Show marks for hours 3, 6, 9, 12
SHOW_HOURS_TICKS Show marks for all hours
SHOW_MINUTES_TICKS Show marks for minutes
SHOW_HOURS_HAND Show hours hand
SHOW_MINUTES_HAND Show minutes hand
SHOW_SECONDS_HAND Show seconds hand
SHOW_SHADOWS Show hands and marks shadows
ROTATE_TICKS Align tick marks to watch
OVERLAP_TICKS Draw tick marks for minutes even
when they match the hours marks.
DEFAULT_CLOCK_STYLE The same as SHOW_HOURS_TICKS|
SHOW_MINUTES_TICKS|
SHOW_HOURS_HAND|
SHOW_MINUTES_HAND|
SHOW_SECONDS_HAND|
SHOW_SHADOWS|ROTATE_TICKS
==================== ================================
- minutesStyle and hoursStyle define the the tick styles, according to the
options below:
================= ======================================
TICKS_NONE Don't show tick marks.
TICKS_SQUARE Use squares as tick marks.
TICKS_CIRCLE Use circles as tick marks.
TICKS_POLY Use a polygon as tick marks. A
polygon can be passed using
SetTickPolygon, otherwise the default
polygon will be used.
TICKS_DECIMAL Use decimal numbers as tick marks.
TICKS_ROMAN Use Roman numbers as tick marks.
TICKS_BINARY Use binary numbers as tick marks.
TICKS_HEX Use hexadecimal numbers as tick marks.
================= ======================================
Notes:
The 'target' keyword that's present in various of the AnalogClock methods may
accept one (or more, combined using '|') of the following values:
========= ===========================================
HOUR The values passed/retrieved are related to
the hours hand/ticks
MINUTE The values passed/retrieved are related to
the minutes hand/ticks
SECOND The values passed/retrieved are related to
the seconds hand/ticks
ALL The same as HOUR|MINUTE|SECOND, i. e., the
values passed/retrieved are related to all
of the hours hands/ticks. This is the
default value in all methods.
========= ===========================================
It is legal to pass target=ALL to methods that don't handle seconds (tick
mark related methods). In such cases, ALL will be equivalent to HOUR|MINUTE.
All of the 'Get' AnalogClock methods that allow the 'target' keyword
will always return a tuple, e. g.:
================================= ========================================
GetHandSize(target=HOUR) Returns a 1 element tuple, containing
the size of the hours hand.
GetHandSize(target=HOUR|MINUTE) Returns a 2 element tuple, containing
the sizes of the hours and the minutes
hands, respectively.
GetHandSize(target=ALL) Returns a 3 element tuple, containing
or the sizes of the hours, minutes and
GetHandSize() seconds hands, respectively.
================================= ========================================
About:
Most of the ideas and part of the code of AnalogClock were based on the
original wxPython's AnalogClock module, which was created by several folks on
the wxPython-users list.
AnalogClock is distributed under the wxWidgets license.
This code should meet the wxPython Coding Guidelines
<http://www.wxpython.org/codeguidelines.php> and the wxPython Style Guide
<http://wiki.wxpython.org/index.cgi/wxPython_20Style_20Guide>.
For all kind of problems, requests, enhancements, bug reports, etc,
please drop me an e-mail.
For updates please visit <http://j.domaindlx.com/elements28/wxpython/>.
"""
# History:
#
# Version 0.02:
# - Module/namespace rearranges;
# - All '-1' occurrences meaning "use any id" were eliminated or replaced
# to 'wx.ID_ANY'.
# - Better names to the methods triggered by the context menu events.
# - Included small demo class code in analogclock.py.
# Version 0.01:
# - Initial release.
#----------------------------------------------------------------------
from analogclock import AnalogClock, AnalogClockWindow
from styles import *
#
##
### eof

View File

@ -0,0 +1,644 @@
# AnalogClock's main class
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 15 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
#
# For more info please see the __init__.py file.
import wx
from styles import *
from helpers import Dyer, Face, Hand, HandSet, TickSet, Box
from setup import Setup
#----------------------------------------------------------------------
class AnalogClock(wx.PyWindow):
"""An analog clock."""
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.NO_BORDER, name="AnalogClock",
clockStyle=DEFAULT_CLOCK_STYLE,
minutesStyle=TICKS_CIRCLE, hoursStyle=TICKS_POLY):
wx.PyWindow.__init__(self, parent, id, pos, size, style, name)
# Base size for scale calc purposes.
self.basesize = wx.Size(348, 348)
# Store some references.
self.clockStyle = clockStyle
self.minutesStyle = minutesStyle
self.hoursStyle = hoursStyle
self.DrawHands = self._drawHands
self.DrawBox = self._drawBox
self.RecalcCoords = self._recalcCoords
self.shadowOffset = 3
self.allHandStyles = [SHOW_HOURS_HAND,
SHOW_MINUTES_HAND,
SHOW_SECONDS_HAND]
# Initialize clock face.
#
# By default we don't use colours or borders on the clock face.
bg = self.GetBackgroundColour()
face = Face(dyer=Dyer(bg, 0, bg))
# Initialize tick marks.
#
# TickSet is a set of tick marks; there's always two TickSets defined
# regardless whether they're being shown or not.
ticksM = TickSet(self, style=minutesStyle, size=5, kind="minutes")
ticksH = TickSet(self, style=hoursStyle, size=25, kind="hours",
rotate=clockStyle&ROTATE_TICKS)
# Box holds the clock face and tick marks.
self.Box = Box(self, face, ticksM, ticksH)
# Initialize hands.
#
# HandSet is the set of hands; there's always one HandSet defined
# regardless whether hands are being shown or not.
#
# A 'lenfac = 0.95', e.g., means that the lenght of that hand will
# be 95% of the maximum allowed hand lenght ('nice' maximum lenght).
handH = Hand(size=7, lenfac=0.7)
handM = Hand(size=5, lenfac=0.95)
handS = Hand(size=1, lenfac=0.95)
self.Hands = HandSet(self, handH, handM, handS)
# Create the customization dialog.
self.Setup = None
# Make a context menu.
popup1 = wx.NewId()
popup2 = wx.NewId()
cm = self.cm = wx.Menu()
cm.Append(popup1, "Customize...")
cm.Append(popup2, "About...")
# Set event handlers.
self.Bind(wx.EVT_SIZE, self._OnSize)
self.Bind(wx.EVT_PAINT, self._OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, lambda evt: None)
self.Bind(wx.EVT_TIMER, self._OnTimer)
self.Bind(wx.EVT_WINDOW_DESTROY, self._OnDestroyWindow)
self.Bind(wx.EVT_CONTEXT_MENU, self._OnContextMenu)
self.Bind(wx.EVT_MENU, self._OnShowSetup, id=popup1)
self.Bind(wx.EVT_MENU, self._OnShowAbout, id=popup2)
# Set initial size based on given size, or best size
self.SetBestFittingSize(size)
# Do initial drawing (in case there is not an initial size event)
self.RecalcCoords(self.GetSize())
self.DrawBox()
# 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)
def DoGetBestSize(self):
# Just pull a number out of the air. If there is a way to
# calculate this then it should be done...
size = wx.Size(50,50)
self.CacheBestSize(size)
return size
def _OnSize(self, evt):
size = self.GetClientSize()
if size.x < 1 or size.y < 1:
return
self.RecalcCoords(size)
self.DrawBox()
def _OnPaint(self, evt):
dc = wx.BufferedPaintDC(self)
self.DrawHands(dc)
def _OnTimer(self, evt):
dc = wx.BufferedDC(wx.ClientDC(self), self.GetClientSize())
self.DrawHands(dc)
def _OnDestroyWindow(self, evt):
self.timer.Stop()
del self.timer
def _OnContextMenu(self, evt):
self.PopupMenu(self.cm)
def _OnShowSetup(self, evt):
if self.Setup is None:
self.Setup = Setup(self)
self.Setup.Show()
self.Setup.Raise()
def _OnShowAbout(self, evt):
msg = "AnalogClock\n\n" \
"by Several folks on wxPython-users\n" \
"with enhancements from E. A. Tacao."
title = "About..."
style = wx.OK|wx.ICON_INFORMATION
dlg = wx.MessageDialog(self, msg, title, style)
dlg.ShowModal()
dlg.Destroy()
def _recalcCoords(self, size):
"""
Recalculates all coordinates/geometry and inits the faceBitmap
to make sure the buffer is always the same size as the window.
"""
self.faceBitmap = wx.EmptyBitmap(*size.Get())
# Recalc all coords.
scale = min([float(size.width) / self.basesize.width,
float(size.height) / self.basesize.height])
centre = wx.Point(size.width / 2., size.height / 2.)
self.Box.RecalcCoords(size, centre, scale)
self.Hands.RecalcCoords(size, centre, scale)
# Try to find a 'nice' maximum length for the hands so that they won't
# overlap the tick marks. OTOH, if you do want to allow overlapping the
# lenfac value (defined on __init__ above) has to be set to
# something > 1.
niceradius = self.Box.GetNiceRadiusForHands(centre)
self.Hands.SetMaxRadius(niceradius)
def _drawBox(self):
"""Draws clock face and tick marks."""
dc = wx.BufferedDC(wx.ClientDC(self), self.GetClientSize())
dc.BeginDrawing()
dc.SelectObject(self.faceBitmap)
dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
dc.Clear()
self.Box.Draw(dc)
dc.EndDrawing()
def _drawHands(self, dc):
"""
Draws the face bitmap, created on the last DrawBox call, and
clock hands.
"""
dc.BeginDrawing()
dc.DrawBitmap(self.faceBitmap, 0, 0)
self.Hands.Draw(dc)
dc.EndDrawing()
# Public methods --------------------------------------------------
def GetHandSize(self, target=ALL):
"""Gets thickness of hands."""
return self.Hands.GetSize(target)
def GetHandFillColour(self, target=ALL):
"""Gets fill colours of hands."""
return self.Hands.GetFillColour(target)
def GetHandBorderColour(self, target=ALL):
"""Gets border colours of hands."""
return self.Hands.GetBorderColour(target)
def GetHandBorderWidth(self, target=ALL):
"""Gets border widths of hands."""
return self.Hands.GetBorderWidth(target)
def GetTickSize(self, target=ALL):
"""Gets sizes of ticks."""
return self.Box.GetTickSize(target)
def GetTickFillColour(self, target=ALL):
"""Gets fill colours of ticks."""
return self.Box.GetTickFillColour(target)
def GetTickBorderColour(self, target=ALL):
"""Gets border colours of ticks."""
return self.Box.GetTickBorderColour(target)
def GetTickBorderWidth(self, target=ALL):
"""Gets border widths of ticks."""
return self.Box.GetTickBorderWidth(target)
def GetTickPolygon(self, target=ALL):
"""
Gets lists of points to be used as polygon shapes
when using the TICKS_POLY style.
"""
return self.Box.GetTickPolygon(target)
def GetTickFont(self, target=ALL):
"""
Gets fonts for tick marks when using TICKS_DECIMAL or
TICKS_ROMAN style.
"""
return self.Box.GetTickFont(target)
def GetTickOffset(self, target=ALL):
"""Gets the distance of tick marks for hours from border."""
return self.Box.GetTickOffset(target)
def GetFaceFillColour(self):
"""Gets fill colours of watch."""
return self.Box.Face.GetFillColour()
def GetFaceBorderColour(self):
"""Gets border colours of watch."""
return self.Box.Face.GetBorderColour()
def GetFaceBorderWidth(self):
"""Gets border width of watch."""
return self.Box.Face.GetBorderWidth()
def GetShadowColour(self):
"""Gets the colour to be used to draw shadows."""
a_clock_part = self.Box
return a_clock_part.GetShadowColour()
def GetClockStyle(self):
"""Returns the current clock style."""
return self.clockStyle
def GetTickStyle(self, target=ALL):
"""Gets the tick style(s)."""
return self.Box.GetTickStyle(target)
def Refresh(self):
"""
Overriden base wx.Window method. Forces an immediate
recalculation and redraw of all clock elements.
"""
size = self.GetClientSize()
if size.x < 1 or size.y < 1:
return
self.Freeze()
self.RecalcCoords(size)
self.DrawBox()
dc = wx.BufferedDC(wx.ClientDC(self), self.GetClientSize())
self.DrawHands(dc)
self.Thaw()
def SetHandSize(self, size, target=ALL):
"""Sets thickness of hands."""
self.Hands.SetSize(size, target)
def SetHandFillColour(self, colour, target=ALL):
"""Sets fill colours of hands."""
self.Hands.SetFillColour(colour, target)
def SetHandBorderColour(self, colour, target=ALL):
"""Sets border colours of hands."""
self.Hands.SetBorderColour(colour, target)
def SetHandBorderWidth(self, width, target=ALL):
"""Sets border widths of hands."""
self.Hands.SetBorderWidth(width, target)
def SetTickSize(self, size, target=ALL):
"""Sets sizes of ticks."""
self.Box.SetTickSize(size, target)
self.Refresh()
def SetTickFillColour(self, colour, target=ALL):
"""Sets fill colours of ticks."""
self.Box.SetTickFillColour(colour, target)
self.Refresh()
def SetTickBorderColour(self, colour, target=ALL):
"""Sets border colours of ticks."""
self.Box.SetTickBorderColour(colour, target)
self.Refresh()
def SetTickBorderWidth(self, width, target=ALL):
"""Sets border widths of ticks."""
self.Box.SetTickBorderWidth(width, target)
self.Refresh()
def SetTickPolygon(self, polygon, target=ALL):
"""
Sets lists of points to be used as polygon shapes
when using the TICKS_POLY style.
"""
self.Box.SetTickPolygon(polygon, target)
self.Refresh()
def SetTickFont(self, font, target=ALL):
"""
Sets fonts for tick marks when using text-based tick styles
such as TICKS_DECIMAL or TICKS_ROMAN.
"""
self.Box.SetTickFont(font, target)
self.Refresh()
def SetTickOffset(self, offset, target=ALL):
"""Sets the distance of tick marks for hours from border."""
self.Box.SetTickOffset(offset, target)
self.Refresh()
def SetFaceFillColour(self, colour):
"""Sets fill colours of watch."""
self.Box.Face.SetFillColour(colour)
self.Refresh()
def SetFaceBorderColour(self, colour):
"""Sets border colours of watch."""
self.Box.Face.SetBorderColour(colour)
self.Refresh()
def SetFaceBorderWidth(self, width):
"""Sets border width of watch."""
self.Box.Face.SetBorderWidth(width)
self.Refresh()
def SetShadowColour(self, colour):
"""Sets the colour to be used to draw shadows."""
self.Hands.SetShadowColour(colour)
self.Box.SetShadowColour(colour)
self.Refresh()
def SetClockStyle(self, style):
"""
Set the clock style, according to the options below.
==================== ================================
SHOW_QUARTERS_TICKS Show marks for hours 3, 6, 9, 12
SHOW_HOURS_TICKS Show marks for all hours
SHOW_MINUTES_TICKS Show marks for minutes
SHOW_HOURS_HAND Show hours hand
SHOW_MINUTES_HAND Show minutes hand
SHOW_SECONDS_HAND Show seconds hand
SHOW_SHADOWS Show hands and marks shadows
ROTATE_TICKS Align tick marks to watch
OVERLAP_TICKS Draw tick marks for minutes even
when they match the hours marks.
==================== ================================
"""
self.clockStyle = style
self.Box.SetIsRotated(style & ROTATE_TICKS)
self.Refresh()
def SetTickStyle(self, style, target=ALL):
"""
Set the tick style, according to the options below.
================= ======================================
TICKS_NONE Don't show tick marks.
TICKS_SQUARE Use squares as tick marks.
TICKS_CIRCLE Use circles as tick marks.
TICKS_POLY Use a polygon as tick marks. A
polygon can be passed using
SetTickPolygon, otherwise the default
polygon will be used.
TICKS_DECIMAL Use decimal numbers as tick marks.
TICKS_ROMAN Use Roman numbers as tick marks.
TICKS_BINARY Use binary numbers as tick marks.
TICKS_HEX Use hexadecimal numbers as tick marks.
================= ======================================
"""
self.Box.SetTickStyle(style, target)
self.Refresh()
def SetBackgroundColour(self, colour):
"""Overriden base wx.Window method."""
wx.Window.SetBackgroundColour(self, colour)
self.Refresh()
def SetForegroundColour(self, colour):
"""
Overriden base wx.Window method. This method sets a colour for
all hands and ticks at once.
"""
wx.Window.SetForegroundColour(self, colour)
self.SetHandFillColour(colour)
self.SetHandBorderColour(colour)
self.SetTickFillColour(colour)
self.SetTickBorderColour(colour)
self.Refresh()
def SetWindowStyle(self, *args, **kwargs):
"""Overriden base wx.Window method."""
size = self.GetSize()
self.Freeze()
wx.Window.SetWindowStyle(self, *args, **kwargs)
self.SetSize((10, 10))
self.SetSize(size)
self.Thaw()
def SetWindowStyleFlag(self, *args, **kwargs):
"""Overriden base wx.Window method."""
self.SetWindowStyle(*args, **kwargs)
# For backwards compatibility -----------------------------------------
class AnalogClockWindow(AnalogClock):
"""
A simple derived class that provides some backwards compatibility
with the old analogclock module.
"""
def SetTickShapes(self, tsh, tsm=None):
self.SetTickPolygon(tsh)
def SetHandWeights(self, h=None, m=None, s=None):
if h:
self.SetHandSize(h, HOUR)
if m:
self.SetHandSize(m, MINUTE)
if s:
self.SetHandSize(h, SECOND)
def SetHandColours(self, h=None, m=None, s=None):
if h and not m and not s:
m=h
s=h
if h:
self.SetHandBorderColour(h, HOUR)
self.SetHandFillColour(h, HOUR)
if m:
self.SetHandBorderColour(m, MINUTE)
self.SetHandFillColour(m, MINUTE)
if s:
self.SetHandBorderColour(h, SECOND)
self.SetHandFillColour(h, SECOND)
def SetTickColours(self, h=None, m=None):
if not m:
m=h
if h:
self.SetTickBorderColour(h, HOUR)
self.SetTickFillColour(h, HOUR)
if m:
self.SetTickBorderColour(m, MINUTE)
self.SetTickFillColour(m, MINUTE)
def SetTickSizes(self, h=None, m=None):
if h:
self.SetTickSize(h, HOUR)
if m:
self.SetTickSize(h, MINUTE)
def SetTickFontss(self, h=None, m=None):
if h:
self.SetTickFont(h, HOUR)
if m:
self.SetTickFont(h, MINUTE)
def SetMinutesOffset(self, o):
pass
def SetShadowColour(self, s):
pass
def SetWatchPenBrush(self, p=None, b=None):
if p:
self.SetFaceBorderColour(p.GetColour())
self.SetFaceBorderWidth(p.GetWidth())
if b:
self.SetFaceFillColour(b.GetColour())
def SetClockStyle(self, style):
style |= SHOW_HOURS_HAND|SHOW_MINUTES_HAND|SHOW_SECONDS_HAND
AnalogClock.SetClockStyle(self, style)
def SetTickStyles(self, h=None, m=None):
if h:
self.SetTickStyle(h, HOUR)
if m:
self.SetTickStyle(h, MINUTE)
# Test stuff ----------------------------------------------------------
if __name__ == "__main__":
print wx.VERSION_STRING
class AcDemoApp(wx.App):
def OnInit(self):
frame = wx.Frame(None, -1, "AnalogClock", size=(375, 375))
clock = AnalogClock(frame)
frame.CentreOnScreen()
frame.Show()
return True
acApp = AcDemoApp(0)
acApp.MainLoop()
#
##
### eof

View File

@ -0,0 +1,983 @@
# AnalogClock's base classes
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 15 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
from time import strftime, localtime
import math
import wx
from styles import *
#----------------------------------------------------------------------
_targets = [HOUR, MINUTE, SECOND]
#----------------------------------------------------------------------
class Element:
"""Base class for face, hands and tick marks."""
def __init__(self, idx=0, pos=None, size=None, offset=0, clocksize=None,
scale=1, rotate=False, kind=""):
self.idx = idx
self.pos = pos
self.size = size
self.offset = offset
self.clocksize = clocksize
self.scale = scale
self.rotate = rotate
self.kind = kind
self.text = None
self.angfac = [6, 30][self.kind == "hours"]
def _pol2rect(self, m, t):
return m * math.cos(math.radians(t)), m * math.sin(math.radians(t))
def _rect2pol(self, x, y):
return math.hypot(x, y), math.degrees(math.atan2(y, x))
def DrawRotated(self, dc, offset=0):
pass
def DrawStraight(self, dc, offset=0):
pass
def Draw(self, dc, offset=0):
if self.rotate:
self.DrawRotated(dc, offset)
else:
self.DrawStraight(dc, offset)
def RecalcCoords(self, clocksize, centre, scale):
pass
def GetSize(self):
return self.size
def GetOffset(self):
return self.offset
def GetIsRotated(self, rotate):
return self.rotate
def GetMaxSize(self, scale=1):
return self.size * scale
def GetScale(self):
return self.scale
def SetIsRotated(self, rotate):
self.rotate = rotate
def GetMaxSize(self, scale=1):
return self.size * scale
def GetPolygon(self):
return self.polygon
def SetPosition(self, pos):
self.pos = pos
def SetSize(self, size):
self.size = size
def SetOffset(self, offset):
self.offset = offset
def SetClockSize(self, clocksize):
self.clocksize = clocksize
def SetScale(self, scale):
self.scale = scale
def SetIsRotated(self, rotate):
self.rotate = rotate
def SetPolygon(self, polygon):
self.polygon = polygon
#----------------------------------------------------------------------
class ElementWithDyer(Element):
"""Base class for clock face and hands."""
def __init__(self, **kwargs):
self.dyer = kwargs.pop("dyer", Dyer())
Element.__init__(self, **kwargs)
def GetFillColour(self):
return self.dyer.GetFillColour()
def GetBorderColour(self):
return self.dyer.GetBorderColour()
def GetBorderWidth(self):
return self.dyer.GetBorderWidth()
def GetShadowColour(self):
return self.dyer.GetShadowColour()
def SetFillColour(self, colour):
self.dyer.SetFillColour(colour)
def SetBorderColour(self, colour):
self.dyer.SetBorderColour(colour)
def SetBorderWidth(self, width):
self.dyer.SetBorderWidth(width)
def SetShadowColour(self, colour):
self.dyer.SetShadowColour(colour)
#----------------------------------------------------------------------
class Face(ElementWithDyer):
"""Holds info about the clock face."""
def __init__(self, **kwargs):
ElementWithDyer.__init__(self, **kwargs)
def Draw(self, dc):
self.dyer.Select(dc)
dc.DrawCircle(self.pos.x, self.pos.y, self.radius)
def RecalcCoords(self, clocksize, centre, scale):
self.radius = min(clocksize.Get()) / 2. - self.dyer.width / 2.
self.pos = centre
#----------------------------------------------------------------------
class Hand(ElementWithDyer):
"""Holds info about a clock hand."""
def __init__(self, **kwargs):
self.lenfac = kwargs.pop("lenfac")
ElementWithDyer.__init__(self, **kwargs)
self.SetPolygon([[-1, 0], [0, -1], [1, 0], [0, 4]])
def Draw(self, dc, end, offset=0):
radius, centre, r = end
angle = math.degrees(r)
polygon = self.polygon[:]
vscale = radius / max([y for x, y in polygon])
for i, (x, y) in enumerate(polygon):
x *= self.scale * self.size
y *= vscale * self.lenfac
m, t = self._rect2pol(x, y)
polygon[i] = self._pol2rect(m, t - angle)
dc.DrawPolygon(polygon, centre.x + offset, centre.y + offset)
def RecalcCoords(self, clocksize, centre, scale):
self.pos = centre
self.scale = scale
#----------------------------------------------------------------------
class TickSquare(Element):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
Element.__init__(self, **kwargs)
def Draw(self, dc, offset=0):
width = height = self.size * self.scale
x = self.pos.x - width / 2.
y = self.pos.y - height / 2.
dc.DrawRectangle(x + offset, y + offset, width, height)
#----------------------------------------------------------------------
class TickCircle(Element):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
Element.__init__(self, **kwargs)
def Draw(self, dc, offset=0):
radius = self.size * self.scale / 2.
x = self.pos.x
y = self.pos.y
dc.DrawCircle(x + offset, y + offset, radius)
#----------------------------------------------------------------------
class TickPoly(Element):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
Element.__init__(self, **kwargs)
self.SetPolygon([[0, 1], [1, 0], [2, 1], [1, 5]])
def _calcPolygon(self):
width = max([x for x, y in self.polygon])
height = max([y for x, y in self.polygon])
tscale = self.size / max(width, height) * self.scale
polygon = [(x * tscale, y * tscale) for x, y in self.polygon]
width = max([x for x, y in polygon])
height = max([y for x, y in polygon])
return polygon, width, height
def DrawStraight(self, dc, offset=0):
polygon, width, height = self._calcPolygon()
x = self.pos.x - width / 2.
y = self.pos.y - height / 2.
dc.DrawPolygon(polygon, x + offset, y + offset)
def DrawRotated(self, dc, offset=0):
polygon, width, height = self._calcPolygon()
angle = 360 - self.angfac * (self.idx + 1)
r = math.radians(angle)
for i in range(len(polygon)):
m, t = self._rect2pol(*polygon[i])
t -= angle
polygon[i] = self._pol2rect(m, t)
x = self.pos.x - math.cos(r) * width / 2. - math.sin(r) * height / 2.
y = self.pos.y - math.cos(r) * height / 2. + math.sin(r) * width / 2.
dc.DrawPolygon(polygon, x + offset, y + offset)
#----------------------------------------------------------------------
class TickDecimal(Element):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
Element.__init__(self, **kwargs)
self.text = "%s" % (self.idx + 1)
def DrawStraight(self, dc, offset=0):
width, height = dc.GetTextExtent(self.text)
x = self.pos.x - width / 2.
y = self.pos.y - height / 2.
dc.DrawText(self.text, x + offset, y + offset)
def DrawRotated(self, dc, offset=0):
width, height = dc.GetTextExtent(self.text)
angle = 360 - self.angfac * (self.idx + 1)
r = math.radians(angle)
x = self.pos.x - math.cos(r) * width / 2. - math.sin(r) * height / 2.
y = self.pos.y - math.cos(r) * height / 2. + math.sin(r) * width / 2.
dc.DrawRotatedText(self.text, x + offset, y + offset, angle)
#----------------------------------------------------------------------
class TickRoman(TickDecimal):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
TickDecimal.__init__(self, **kwargs)
self.text = ["I","II","III","IV","V", \
"VI","VII","VIII","IX","X", \
"XI","XII","XIII","XIV","XV", \
"XVI","XVII","XVIII","XIX","XX", \
"XXI","XXII","XXIII","XXIV","XXV", \
"XXVI","XXVII","XXVIII","XXIX","XXX", \
"XXXI","XXXII","XXXIII","XXXIV","XXXV", \
"XXXVI","XXXVII","XXXVIII","XXXIX","XL", \
"XLI","XLII","XLIII","XLIV","XLV", \
"XLVI","XLVII","XLVIII","XLIX","L", \
"LI","LII","LIII","LIV","LV", \
"LVI","LVII","LVIII","LIX","LX"][self.idx]
#----------------------------------------------------------------------
class TickBinary(TickDecimal):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
TickDecimal.__init__(self, **kwargs)
def d2b(n, b=""):
while n > 0:
b = str(n % 2) + b; n = n >> 1
return b.zfill(4)
self.text = d2b(self.idx + 1)
#----------------------------------------------------------------------
class TickHex(TickDecimal):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
TickDecimal.__init__(self, **kwargs)
self.text = hex(self.idx + 1)[2:].upper()
#----------------------------------------------------------------------
class TickNone(Element):
"""Holds info about a tick mark."""
def __init__(self, **kwargs):
Element.__init__(self, **kwargs)
def Draw(self, dc, offset=0):
pass
#----------------------------------------------------------------------
class Dyer:
"""Stores info about colours and borders of clock Elements."""
def __init__(self, border=None, width=0, fill=None, shadow=None):
"""
self.border (wx.Colour) border colour
self.width (int) border width
self.fill (wx.Colour) fill colour
self.shadow (wx.Colour) shadow colour
"""
self.border = border or \
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
self.fill = fill or \
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
self.shadow = shadow or \
wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DSHADOW)
self.width = width
def Select(self, dc, shadow=False):
"""Selects the current settings into the dc."""
if not shadow:
dc.SetPen(wx.Pen(self.border, self.width, wx.SOLID))
dc.SetBrush(wx.Brush(self.fill, wx.SOLID))
dc.SetTextForeground(self.fill)
else:
dc.SetPen(wx.Pen(self.shadow, self.width, wx.SOLID))
dc.SetBrush(wx.Brush(self.shadow, wx.SOLID))
dc.SetTextForeground(self.shadow)
def GetFillColour(self):
return self.fill
def GetBorderColour(self):
return self.border
def GetBorderWidth(self):
return self.width
def GetShadowColour(self):
return self.shadow
def SetFillColour(self, colour):
self.fill = colour
def SetBorderColour(self, colour):
self.border = colour
def SetBorderWidth(self, width):
self.width = width
def SetShadowColour(self, colour):
self.shadow = colour
#----------------------------------------------------------------------
class HandSet:
"""Manages the set of hands."""
def __init__(self, parent, h, m, s):
self.parent = parent
self.hands = [h, m, s]
self.radius = 1
self.centre = wx.Point(1, 1)
def _draw(self, dc, shadow=False):
ends = [int(x) for x in strftime("%I %M %S", localtime()).split()]
flags = [self.parent.clockStyle & flag \
for flag in self.parent.allHandStyles]
a_hand = self.hands[0]
if shadow:
offset = self.parent.shadowOffset * a_hand.GetScale()
else:
offset = 0
for i, hand in enumerate(self.hands):
# Is this hand supposed to be drawn?
if flags[i]:
idx = ends[i]
# Is this the hours hand?
if i == 0:
idx = idx * 5 + ends[1] / 12
# Adjust idx offset and prevent exceptions on leap seconds.
idx = idx - 1
if idx < 0 or idx > 59:
idx = 59
angle = math.radians(180 - 6 * (idx + 1))
hand.dyer.Select(dc, shadow)
hand.Draw(dc, (self.radius, self.centre, angle), offset)
def Draw(self, dc):
if self.parent.clockStyle & SHOW_SHADOWS:
self._draw(dc, True)
self._draw(dc)
def RecalcCoords(self, clocksize, centre, scale):
self.centre = centre
[hand.RecalcCoords(clocksize, centre, scale) for hand in self.hands]
def SetMaxRadius(self, radius):
self.radius = radius
def GetSize(self, target):
r = []
for i, hand in enumerate(self.hands):
if _targets[i] & target:
r.append(hand.GetSize())
return tuple(r)
def GetFillColour(self, target):
r = []
for i, hand in enumerate(self.hands):
if _targets[i] & target:
r.append(hand.GetFillColour())
return tuple(r)
def GetBorderColour(self, target):
r = []
for i, hand in enumerate(self.hands):
if _targets[i] & target:
r.append(hand.GetBorderColour())
return tuple(r)
def GetBorderWidth(self, target):
r = []
for i, hand in enumerate(self.hands):
if _targets[i] & target:
r.append(hand.GetBorderWidth())
return tuple(r)
def GetShadowColour(self):
r = []
for i, hand in enumerate(self.hands):
if _targets[i] & target:
r.append(hand.GetShadowColour())
return tuple(r)
def SetSize(self, size, target):
for i, hand in enumerate(self.hands):
if _targets[i] & target:
hand.SetSize(size)
def SetFillColour(self, colour, target):
for i, hand in enumerate(self.hands):
if _targets[i] & target:
hand.SetFillColour(colour)
def SetBorderColour(self, colour, target):
for i, hand in enumerate(self.hands):
if _targets[i] & target:
hand.SetBorderColour(colour)
def SetBorderWidth(self, width, target):
for i, hand in enumerate(self.hands):
if _targets[i] & target:
hand.SetBorderWidth(width)
def SetShadowColour(self, colour):
for i, hand in enumerate(self.hands):
hand.SetShadowColour(colour)
#----------------------------------------------------------------------
class TickSet:
"""Manages a set of tick marks."""
def __init__(self, parent, **kwargs):
self.parent = parent
self.dyer = Dyer()
self.noe = {"minutes": 60, "hours": 12}[kwargs["kind"]]
self.font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
style = kwargs.pop("style")
self.kwargs = kwargs
self.SetStyle(style)
def _draw(self, dc, shadow=False):
dc.SetFont(self.font)
a_tick = self.ticks[0]
if shadow:
offset = self.parent.shadowOffset * a_tick.GetScale()
else:
offset = 0
clockStyle = self.parent.clockStyle
for idx, tick in self.ticks.items():
draw = False
# Are we a set of hours?
if self.noe == 12:
# Should we show all hours ticks?
if clockStyle & SHOW_HOURS_TICKS:
draw = True
# Or is this tick a quarter and should we show only quarters?
elif clockStyle & SHOW_QUARTERS_TICKS and not (idx + 1) % 3.:
draw = True
# Are we a set of minutes and minutes should be shown?
elif self.noe == 60 and clockStyle & SHOW_MINUTES_TICKS:
# If this tick occupies the same position of an hour/quarter
# tick, should we still draw it anyway?
if clockStyle & OVERLAP_TICKS:
draw = True
# Right, sir. I promise I won't overlap any tick.
else:
# Ensure that this tick won't overlap an hour tick.
if clockStyle & SHOW_HOURS_TICKS:
if (idx + 1) % 5.:
draw = True
# Ensure that this tick won't overlap a quarter tick.
elif clockStyle & SHOW_QUARTERS_TICKS:
if (idx + 1) % 15.:
draw = True
# We're not drawing quarters nor hours, so we can draw all
# minutes ticks.
else:
draw = True
if draw:
tick.Draw(dc, offset)
def Draw(self, dc):
if self.parent.clockStyle & SHOW_SHADOWS:
self.dyer.Select(dc, True)
self._draw(dc, True)
self.dyer.Select(dc)
self._draw(dc)
def RecalcCoords(self, clocksize, centre, scale):
a_tick = self.ticks[0]
size = a_tick.GetMaxSize(scale)
self.font.SetPointSize(size)
maxsize = size
# Try to find a 'good' max size for text-based ticks.
if a_tick.text is not None:
dc = wx.MemoryDC()
dc.SelectObject(wx.EmptyBitmap(*clocksize.Get()))
dc.SetFont(self.font)
maxsize = size
for tick in self.ticks.values():
maxsize = max(*(dc.GetTextExtent(tick.text) + (maxsize,)))
radius = self.radius = min(clocksize.Get()) / 2. - \
self.dyer.width / 2. - \
maxsize / 2. - \
a_tick.GetOffset() * scale - \
self.parent.shadowOffset * scale
# If we are a set of hours, the number of elements of this tickset is
# 12 and ticks are separated by a distance of 30 degrees;
# if we are a set of minutes, the number of elements of this tickset is
# 60 and ticks are separated by a distance of 6 degrees.
angfac = [6, 30][self.noe == 12]
for i, tick in self.ticks.items():
tick.SetClockSize(clocksize)
tick.SetScale(scale)
deg = 180 - angfac * (i + 1)
angle = math.radians(deg)
x = centre.x + radius * math.sin(angle)
y = centre.y + radius * math.cos(angle)
tick.SetPosition(wx.Point(x, y))
def GetSize(self):
return self.kwargs["size"]
def GetFillColour(self):
return self.dyer.GetFillColour()
def GetBorderColour(self):
return self.dyer.GetBorderColour()
def GetBorderWidth(self):
return self.dyer.GetBorderWidth()
def GetPolygon(self):
a_tick = self.ticks.values()[0]
return a_tick.GetPolygon()
def GetFont(self):
return self.font
def GetOffset(self):
a_tick = self.ticks[0]
return a_tick.GetOffset()
def GetShadowColour(self):
return self.dyer.GetShadowColour()
def GetIsRotated(self):
a_tick = self.ticks[0]
return a_tick.GetIsRotated()
def GetStyle(self):
return self.style
def SetSize(self, size):
self.kwargs["size"] = size
[tick.SetSize(size) for tick in self.ticks.values()]
def SetFillColour(self, colour):
self.dyer.SetFillColour(colour)
def SetBorderColour(self, colour):
self.dyer.SetBorderColour(colour)
def SetBorderWidth(self, width):
self.dyer.SetBorderWidth(width)
def SetPolygon(self, polygon):
[tick.SetPolygon(polygon) for tick in self.ticks.values()]
def SetFont(self, font):
self.font = font
def SetOffset(self, offset):
self.kwargs["offset"] = offset
[tick.SetOffset(offset) for tick in self.ticks.values()]
def SetShadowColour(self, colour):
self.dyer.SetShadowColour(colour)
def SetIsRotated(self, rotate):
self.kwargs["rotate"] = rotate
[tick.SetIsRotated(rotate) for tick in self.ticks.values()]
def SetStyle(self, style):
self.style = style
tickclass = allTickStyles[style]
self.kwargs["rotate"] = self.parent.clockStyle & ROTATE_TICKS
self.ticks = {}
for i in range(self.noe):
self.kwargs["idx"] = i
self.ticks[i] = tickclass(**self.kwargs)
#----------------------------------------------------------------------
class Box:
"""Gathers info about the clock face and tick sets."""
def __init__(self, parent, Face, TicksM, TicksH):
self.parent = parent
self.Face = Face
self.TicksH = TicksH
self.TicksM = TicksM
def GetNiceRadiusForHands(self, centre):
a_tick = self.TicksM.ticks[0]
scale = a_tick.GetScale()
bw = max(self.TicksH.dyer.width / 2. * scale,
self.TicksM.dyer.width / 2. * scale)
mgt = self.TicksM.ticks[59]
my = mgt.pos.y + mgt.GetMaxSize(scale) + bw
hgt = self.TicksH.ticks[11]
hy = hgt.pos.y + hgt.GetMaxSize(scale) + bw
niceradius = centre.y - max(my, hy)
return niceradius
def Draw(self, dc):
[getattr(self, attr).Draw(dc) \
for attr in ["Face", "TicksM", "TicksH"]]
def RecalcCoords(self, size, centre, scale):
[getattr(self, attr).RecalcCoords(size, centre, scale) \
for attr in ["Face", "TicksH", "TicksM"]]
def GetTickSize(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetSize())
return tuple(r)
def GetTickFillColour(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetFillColour())
return tuple(r)
def GetTickBorderColour(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetBorderColour())
return tuple(r)
def GetTickBorderWidth(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetBorderWidth())
return tuple(r)
def GetTickPolygon(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetPolygon())
return tuple(r)
def GetTickFont(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetFont())
return tuple(r)
def GetIsRotated(self):
a_tickset = self.TicksH
return a_tickset.GetIsRotated()
def GetTickOffset(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetOffset())
return tuple(r)
def GetShadowColour(self):
a_tickset = self.TicksH
return a_tickset.GetShadowColour()
def GetTickStyle(self, target):
r = []
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
r.append(tick.GetStyle())
return tuple(r)
def SetTickSize(self, size, target):
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetSize(size)
def SetTickFillColour(self, colour, target):
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetFillColour(colour)
def SetTickBorderColour(self, colour, target):
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetBorderColour(colour)
def SetTickBorderWidth(self, width, target):
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetBorderWidth(width)
def SetTickPolygon(self, polygon, target):
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetPolygon(polygon)
def SetTickFont(self, font, target):
fs = font.GetNativeFontInfoDesc()
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetFont(wx.FontFromNativeInfoString(fs))
def SetIsRotated(self, rotate):
[getattr(self, attr).SetIsRotated(rotate) \
for attr in ["TicksH", "TicksM"]]
def SetTickOffset(self, offset, target):
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetOffset(offset)
def SetShadowColour(self, colour):
for attr in ["TicksH", "TicksM"]:
tick = getattr(self, attr)
tick.SetShadowColour(colour)
def SetTickStyle(self, style, target):
for i, attr in enumerate(["TicksH", "TicksM"]):
if _targets[i] & target:
tick = getattr(self, attr)
tick.SetStyle(style)
#----------------------------------------------------------------------
# Relationship between styles and ticks class names.
allTickStyles = {TICKS_BINARY: TickBinary,
TICKS_CIRCLE: TickCircle,
TICKS_DECIMAL: TickDecimal,
TICKS_HEX: TickHex,
TICKS_NONE: TickNone,
TICKS_POLY: TickPoly,
TICKS_ROMAN: TickRoman,
TICKS_SQUARE: TickSquare}
#
##
### eof

View File

@ -0,0 +1,350 @@
__author__ = "E. A. Tacao <e.a.tacao |at| estadao.com.br>"
__date__ = "12 Fev 2006, 22:00 GMT-03:00"
__version__ = "0.03"
__doc__ = """
ButtonTreeCtrlPanel is a widget where one can place check buttons, tri-state
check buttons, radio buttons, both, and the ability to display them
hierarchically.
About:
ButtonTreeCtrlPanel is distributed under the wxWidgets license.
For all kind of problems, requests, enhancements, bug reports, etc,
please drop me an e-mail.
For updates please visit <http://j.domaindlx.com/elements28/wxpython/>.
"""
import cStringIO
import wx
from wx.lib.newevent import NewEvent
#----------------------------------------------------------------------------
(ButtonTreeCtrlPanelEvent, EVT_BUTTONTREECTRLPANEL) = NewEvent()
EVT_CHANGED = EVT_BUTTONTREECTRLPANEL
#----------------------------------------------------------------------------
class ButtonTreeCtrlPanel(wx.Panel):
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.WANTS_CHARS):
wx.Panel.__init__(self, parent, id, pos, size, style)
self.tree = wx.TreeCtrl(self, style=wx.TR_NO_LINES|wx.TR_HIDE_ROOT)
il = self.il = wx.ImageList(16, 16)
self.tree.SetImageList(il)
for bl in ["checkbox_checked", "checkbox_unchecked", "checkbox_tri",
"radiobox_checked", "radiobox_unchecked"]:
setattr(self, bl, il.Add(getattr(self, "get%sBitmap" % bl)()))
bmp = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_TOOLBAR, (16, 16))
self.empty_bitmap = il.Add(bmp)
self.root = self.tree.AddRoot("Root Item for ButtonTreeCtrlPanel")
self.Bind(wx.EVT_SIZE, self.OnSize)
self.tree.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftClicks)
self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftClicks)
self.tree.Bind(wx.EVT_RIGHT_DOWN, self.OnRightClick)
self.allitems = []
wx.CallAfter(self.OnSize)
def _doLogicTest(self, style, value, item):
if style in [wx.CHK_2STATE, wx.CHK_3STATE]:
n = [self.checkbox_unchecked, self.checkbox_checked, \
self.checkbox_tri][value]
self.tree.SetPyData(item, (value, style))
self.tree.SetItemImage(item, n, wx.TreeItemIcon_Normal)
elif style == wx.RB_SINGLE:
if value:
parent = self.tree.GetItemParent(item)
(child, cookie) = self.tree.GetFirstChild(parent)
if self.tree.GetPyData(child):
self.tree.SetPyData(child, (False, wx.RB_SINGLE))
self.tree.SetItemImage(child, self.radiobox_unchecked, \
wx.TreeItemIcon_Normal)
for x in range(1, self.tree.GetChildrenCount(parent, False)):
(child, cookie) = self.tree.GetNextChild(parent, cookie)
if self.tree.GetPyData(child):
self.tree.SetPyData(child, (False, wx.RB_SINGLE))
self.tree.SetItemImage(child, self.radiobox_unchecked, \
wx.TreeItemIcon_Normal)
self.tree.SetPyData(item, (True, wx.RB_SINGLE))
self.tree.SetItemImage(item, self.radiobox_checked, \
wx.TreeItemIcon_Normal)
else:
self.tree.SetPyData(item, (False, wx.RB_SINGLE))
self.tree.SetItemImage(item, self.radiobox_unchecked, \
wx.TreeItemIcon_Normal)
def _getItems(self, parent=None, value=None):
if not parent:
parent = self.root
cil = []
(child, cookie) = self.tree.GetFirstChild(parent)
if child.IsOk():
d = self.tree.GetPyData(child)
if value is None or (d and d[0] == value):
cil.append(child)
for x in range(1, self.tree.GetChildrenCount(parent, False)):
(child, cookie) = self.tree.GetNextChild(parent, cookie)
if child.IsOk():
d = self.tree.GetPyData(child)
if value is None or (d and d[0] == value):
cil.append(child)
return cil
def AddItem(self, label, bmp=None, parent=None, style=None, value=False):
v = None
if bmp:
n = self.il.Add(bmp)
if not parent:
parent = self.root
if style is not None:
v = (value, style)
this_item = self.tree.AppendItem(parent, label)
self.tree.SetPyData(this_item, v)
if v:
self._doLogicTest(style, value, this_item)
else:
if bmp is None:
bmp = self.empty_bitmap
else:
bmp = self.il.Add(bmp)
self.tree.SetItemImage(this_item, bmp, wx.TreeItemIcon_Normal)
self.allitems.append(this_item)
[self.tree.Expand(x) for x in self.allitems]
return this_item
def ExpandItem(self, item):
self.tree.Expand(item)
def CollapseItem(self, item):
self.tree.Collapse(item)
def EnsureFirstVisible(self):
(child, cookie) = self.tree.GetFirstChild(self.root)
if child.IsOk():
self.tree.SelectItem(child)
self.tree.EnsureVisible(child)
def SetItemValue(self, item, value):
data = self.tree.GetPyData(item)
if data:
self._doLogicTest(data[1], value, item)
def GetItemValue(self, item):
data = self.tree.GetPyData(item)
if data:
return data[0]
else:
return None
def GetItemByLabel(self, label, parent=None):
r = None
for item in self._getItems(parent):
if self.tree.GetItemText(item) == label:
r = item; break
return r
def GetAllItems(self):
return self.allitems
def GetRootItems(self):
cil = []
for x in range(0, len(self.allitems)):
d = self.tree.GetPyData(self.allitems[x])
if not d:
cil.append(self.allitems[x])
return cil
def GetStringRootItems(self):
return [self.tree.GetItemText(x) for x in self.GetRootItems]
def GetItemsUnchecked(self, parent=None):
return self._getItems(parent, 0)
def GetItemsChecked(self, parent=None):
return self._getItems(parent, 1)
def GetItemsTri(self, parent=None):
return self._getItems(parent, 2)
def GetStringItemsUnchecked(self, parent=None):
return [self.tree.GetItemText(x) \
for x in self.GetItemsUnchecked(parent)]
def GetStringItemsChecked(self, parent=None):
return [self.tree.GetItemText(x) for x in self.GetItemsChecked(parent)]
def GetStringItemsTri(self, parent=None):
return [self.tree.GetItemText(x) for x in self.GetItemsTri(parent)]
def OnRightClick(self, evt):
item, flags = self.tree.HitTest(evt.GetPosition())
self.tree.SelectItem(item)
def OnLeftClicks(self, evt):
item, flags = self.tree.HitTest(evt.GetPosition())
if item:
text, data = self.tree.GetItemText(item), self.tree.GetPyData(item)
if data:
style = data[1]
if style == wx.CHK_2STATE:
value = not data[0]
elif style == wx.CHK_3STATE:
value = data[0] + 1
if value == 3: value = 0
else:
value = True
self._doLogicTest(style, value, item)
if value <> data[0]:
nevt = ButtonTreeCtrlPanelEvent(obj=self, id=self.GetId(),
item=item, val=value)
wx.PostEvent(self, nevt)
evt.Skip()
def OnSize(self, evt=None):
self.tree.SetSize(self.GetClientSize())
# # Images generated by encode_bitmaps.py -----------------------------
def getcheckbox_uncheckedData(self):
return \
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
\x00\x00AIDAT8\x8d\xed\x93;\x0e\x00 \x14\xc2\xca\xd3\xfb\xdf\xd8\xcf\xac\x83\
\x89\xe2dd\xa7\xe9\x00R$\x9c\x84\xd5\x062@\xab\xa5\xed\x16\x15I\xf7\x0cf\xea\
*\xb3\xadm\xf0\x01O\x00\x86!\x9dL\xda6\x90{\xe7\x0e\xbf\x98\x0c*\xf3\x13\xe2\
e\x00\x00\x00\x00IEND\xaeB`\x82'
def getcheckbox_uncheckedBitmap(self):
return wx.BitmapFromImage(self.getcheckbox_uncheckedImage())
def getcheckbox_uncheckedImage(self):
stream = cStringIO.StringIO(self.getcheckbox_uncheckedData())
return wx.ImageFromStream(stream)
#----------------------------------------------------------------------
def getradiobox_checkedData(self):
return \
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
\x00\x00qIDAT8\x8d\xadR\xd1\x12\x80 \x08\x03\xed\xff\xffX\xe9\xa9n\xd1\xe6\
\xd9\x11o\xca6\x18\xe0\xde\xbaU\xa2\x95\xd8fv\xa8D\xcc\x11\xf8\xf6\xd6\x9d\
\xe1<[\xc8\xc4\x17!\t=\x04\x90\x9c\x81*Gg\xc0\xdaU\x16n\x81\xab\x02\x02c\x8e\
`\x95\xf1On\x01A\xab\xb9\x94\xd7(\x05\xd0\x8a\xf2o&\xb6\xa0\x08,O;`\x9e\xd5\
\x1c\xfe=\xa4\x95\xd0\xf6)\x7f\x8d\xf2\x1aO_y@8\xb08r\xf9\x00\x00\x00\x00IEN\
D\xaeB`\x82'
def getradiobox_checkedBitmap(self):
return wx.BitmapFromImage(self.getradiobox_checkedImage())
def getradiobox_checkedImage(self):
stream = cStringIO.StringIO(self.getradiobox_checkedData())
return wx.ImageFromStream(stream)
#----------------------------------------------------------------------
def getradiobox_uncheckedData(self):
return \
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
\x00\x00gIDAT8\x8d\xcd\x92K\x12\x800\x08C\x81z\xff\x1bk\xbb\xd2\xc1\x98t\xea\
\xe0Bv\x1d\xc8k\xf8\xb8G\xb3JDImf\x9bJ\xf4c\xef\xf9\xed\xd1\x9c\xd59\xb6\x80\
\xc2\x87\x00@7@\x16c\xa1\xca\xd1\x190\xbb\xaa\x85\x0bp\xfe\xa0\ns.\xbb)o\xe1\
G\x00\xd6\x1f\x06\x9b\x13u\xc0 \n\xfc\xed!\xcd@\xcb\xa7\xfc6\xca[\x18\xdf\
\x0e0Ao\x7fq\xe8\x00\x00\x00\x00IEND\xaeB`\x82'
def getradiobox_uncheckedBitmap(self):
return wx.BitmapFromImage(self.getradiobox_uncheckedImage())
def getradiobox_uncheckedImage(self):
stream = cStringIO.StringIO(self.getradiobox_uncheckedData())
return wx.ImageFromStream(stream)
#----------------------------------------------------------------------
def getcheckbox_checkedData(self):
return \
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
\x00\x00gIDAT8\x8d\xad\x93Q\x0e\x800\x08C[\xe6\xfdo\xac\xf3k\x89\xa9\xb01\
\x91o^S\xa0\x90\xd6P)+\xd1\x00\x0e\x00\xe8\xd7\xd9wAZ\xe3\x7f\x0eTuV\xea6\
\xed \x1a3%0\xdb\xd1K@\x9bW\x0bv\x1d\x0c\xe8\tG\xfb\tG\xc8\xc0\xae\x806\xaf.\
\xe3:\x18P\xe6\xac\xe1\x08\x19\x18\x90 }\x89t9\xca\xac\xbe\xf3\r?\xc9(*%&\
\xec\x9b\x00\x00\x00\x00IEND\xaeB`\x82'
def getcheckbox_checkedBitmap(self):
return wx.BitmapFromImage(self.getcheckbox_checkedImage())
def getcheckbox_checkedImage(self):
stream = cStringIO.StringIO(self.getcheckbox_checkedData())
return wx.ImageFromStream(stream)
#----------------------------------------------------------------------
def getcheckbox_triData(self):
return \
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
\x00\x00pIDAT8\x8d\xad\x93A\x0e\x800\x08\x04\x97\xea\xab\xd4\xa3\xfah\xf5h\
\xfdV{jb\x08 \x8a\x9c\x99\xcd\xd0l\x89R\x87\xc8\xa4\x10\r\xa0\x07\x80i\x1c\
\xca[\xf0\xcc\x17\xfdg\xc0S\xad\xe1\xb6n\x83c\xdf\xc43]\x01\x1a,\x06\xf0e\
\x0bV\r\x1at\x87\xe7e\x15\xdfG=\xc1\x03\x8b\x01|\xd9\x82U\x83\x06=\xc1j\x80\
\x17\x06X\x91\xbeT:\\e\x8a~\xe7\nM\x85%\xe1\xceT8v\x00\x00\x00\x00IEND\xaeB`\
\x82'
def getcheckbox_triBitmap(self):
return wx.BitmapFromImage(self.getcheckbox_triImage())
def getcheckbox_triImage(self):
stream = cStringIO.StringIO(self.getcheckbox_triData())
return wx.ImageFromStream(stream)
#
##
### eof

View File

@ -0,0 +1,80 @@
# AnalogClock's colour selector for setup dialog
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 15 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
import wx
from wx.lib.newevent import NewEvent
from wx.lib.buttons import GenBitmapButton
#----------------------------------------------------------------------------
(ColourSelectEvent, EVT_COLOURSELECT) = NewEvent()
#----------------------------------------------------------------------------
class ColourSelect(GenBitmapButton):
def __init__(self, parent, size=(21, 21), value=wx.BLACK):
w, h = size[0] - 5, size[1] - 5
GenBitmapButton.__init__(self, parent, wx.ID_ANY, wx.EmptyBitmap(w, h),
size=size)
self.SetBezelWidth(1)
self.parent = parent
self.SetValue(value)
self.parent.Bind(wx.EVT_BUTTON, self.OnClick, self)
def _makeBitmap(self):
bdr = 8; w, h = self.GetSize()
bmp = wx.EmptyBitmap(w - bdr, h - bdr)
dc = wx.MemoryDC()
dc.SelectObject(bmp)
dc.SetBackground(wx.Brush(self.value, wx.SOLID))
dc.Clear()
dc.SelectObject(wx.NullBitmap)
self.SetBitmapLabel(bmp)
self.Refresh()
def GetValue(self):
return self.value
def SetValue(self, value):
self.value = value
self._makeBitmap()
def OnClick(self, event):
win = wx.GetTopLevelParent(self)
data = wx.ColourData()
data.SetChooseFull(True)
data.SetColour(self.value)
[data.SetCustomColour(colour_index, win.customcolours[colour_index])
for colour_index in range(0, 16)]
dlg = wx.ColourDialog(win, data)
dlg.SetTitle("Select Colour")
changed = dlg.ShowModal() == wx.ID_OK
if changed:
data = dlg.GetColourData()
self.SetValue(data.GetColour())
win.customcolours = [data.GetCustomColour(colour_index) \
for colour_index in range(0, 16)]
dlg.Destroy()
if changed:
nevt = ColourSelectEvent(id=self.GetId(), obj=self, val=self.value)
wx.PostEvent(self.parent, nevt)
#
##
### eof

View File

@ -0,0 +1,61 @@
# AnalogClock's font selector for setup dialog
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 15 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
import wx
from wx.lib.newevent import NewEvent
from wx.lib.buttons import GenButton
#----------------------------------------------------------------------------
(FontSelectEvent, EVT_FONTSELECT) = NewEvent()
#----------------------------------------------------------------------------
class FontSelect(GenButton):
def __init__(self, parent, size=(75, 21), value=None):
GenButton.__init__(self, parent, wx.ID_ANY, label="Select...",
size=size)
self.SetBezelWidth(1)
self.parent = parent
self.SetValue(value)
self.parent.Bind(wx.EVT_BUTTON, self.OnClick, self)
def GetValue(self):
return self.value
def SetValue(self, value):
if value is None:
value = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
self.value = value
def OnClick(self, event):
data = wx.FontData()
data.EnableEffects(False)
font = self.value; font.SetPointSize(10)
data.SetInitialFont(font)
dlg = wx.FontDialog(self, data)
changed = dlg.ShowModal() == wx.ID_OK
if changed:
data = dlg.GetFontData()
self.value = data.GetChosenFont()
self.Refresh()
dlg.Destroy()
if changed:
nevt = FontSelectEvent(id=self.GetId(), obj=self, val=self.value)
wx.PostEvent(self.parent, nevt)
#
##
### eof

View File

@ -0,0 +1,479 @@
# AnalogClock setup dialog
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 15 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
import wx
import styles
import lib_setup.colourselect as csel
import lib_setup.fontselect as fsel
import lib_setup.buttontreectrlpanel as bt
#----------------------------------------------------------------------
_window_styles = ['wx.SIMPLE_BORDER', 'wx.DOUBLE_BORDER', 'wx.SUNKEN_BORDER',
'wx.RAISED_BORDER', 'wx.STATIC_BORDER', 'wx.NO_BORDER']
#----------------------------------------------------------------------
class _GroupBase(wx.Panel):
def __init__(self, parent, title, group):
wx.Panel.__init__(self, parent)
self.parent = parent
self.clock = self.parent.clock
self.group = group
self.target = {"Hours": styles.HOUR,
"Minutes": styles.MINUTE,
"Seconds": styles.SECOND}.get(title)
self.Bind(fsel.EVT_FONTSELECT, self.OnSelectFont)
self.Bind(csel.EVT_COLOURSELECT, self.OnSelectColour)
self.Bind(wx.EVT_SPINCTRL, self.OnSpin)
self.Bind(wx.EVT_TEXT_ENTER, self.OnSpin)
self.Bind(wx.EVT_CHOICE, self.OnChoice)
def OnSelectFont(self, evt):
self.clock.SetTickFont(evt.val, self.target)
def OnSelectColour(self, evt):
obj = evt.obj; val = evt.val
if hasattr(self, "fc") and obj == self.fc:
if self.group == "Hands":
self.clock.SetHandFillColour(val, self.target)
elif self.group == "Ticks":
self.clock.SetTickFillColour(val, self.target)
elif self.group == "Face":
self.clock.SetFaceFillColour(val)
elif hasattr(self, "bc") and obj == self.bc:
if self.group == "Hands":
self.clock.SetHandBorderColour(val, self.target)
elif self.group == "Ticks":
self.clock.SetTickBorderColour(val, self.target)
elif self.group == "Face":
self.clock.SetFaceBorderColour(val)
elif hasattr(self, "sw") and obj == self.sw:
self.clock.SetShadowColour(val)
elif hasattr(self, "bg") and obj == self.bg:
self.clock.SetBackgroundColour(val)
elif hasattr(self, "fg") and obj == self.fg:
self.clock.SetForegroundColour(val)
self.parent.GetGrandParent().UpdateControls()
def OnSpin(self, evt):
obj = evt.GetEventObject(); val = evt.GetInt()
if hasattr(self, "bw") and obj == self.bw:
if self.group == "Hands":
self.clock.SetHandBorderWidth(val, self.target)
elif self.group == "Ticks":
self.clock.SetTickBorderWidth(val, self.target)
elif self.group == "Face":
self.clock.SetFaceBorderWidth(val)
elif hasattr(self, "sz") and obj == self.sz:
if self.group == "Hands":
self.clock.SetHandSize(val, self.target)
elif self.group == "Ticks":
self.clock.SetTickSize(val, self.target)
elif hasattr(self, "of") and obj == self.of:
self.clock.SetTickOffset(val, self.target)
def OnChoice(self, evt):
self.clock.SetWindowStyle(eval(evt.GetString()))
def UpdateControls(self):
if hasattr(self, "ft"):
self.ft.SetValue(self.clock.GetTickFont(self.target)[0])
if hasattr(self, "fc"):
if self.group == "Hands":
self.fc.SetValue(self.clock.GetHandFillColour(self.target)[0])
elif self.group == "Ticks":
self.fc.SetValue(self.clock.GetTickFillColour(self.target)[0])
elif self.group == "Face":
self.fc.SetValue(self.clock.GetFaceFillColour())
if hasattr(self, "bc"):
if self.group == "Hands":
self.bc.SetValue(self.clock.GetHandBorderColour(self.target)[0])
elif self.group == "Ticks":
self.bc.SetValue(self.clock.GetTickBorderColour(self.target)[0])
elif self.group == "Face":
self.bc.SetValue(self.clock.GetFaceBorderColour())
if hasattr(self, "sw"):
self.sw.SetValue(self.clock.GetShadowColour())
if hasattr(self, "bg"):
self.bg.SetValue(self.clock.GetBackgroundColour())
if hasattr(self, "fg"):
self.fg.SetValue(self.clock.GetForegroundColour())
if hasattr(self, "bw"):
if self.group == "Hands":
self.bw.SetValue(self.clock.GetHandBorderWidth(self.target)[0])
elif self.group == "Ticks":
self.bw.SetValue(self.clock.GetTickBorderWidth(self.target)[0])
elif self.group == "Face":
self.bw.SetValue(self.clock.GetFaceBorderWidth())
if hasattr(self, "sz"):
if self.group == "Hands":
self.sz.SetValue(self.clock.GetHandSize(self.target)[0])
elif self.group == "Ticks":
self.sz.SetValue(self.clock.GetTickSize(self.target)[0])
if hasattr(self, "of"):
self.of.SetValue(self.clock.GetTickOffset(self.target)[0])
if hasattr(self, "ws"):
for style in _window_styles:
if self.clock.GetWindowStyleFlag() & eval(style):
self.ws.SetStringSelection(style)
break
#----------------------------------------------------------------------
class _Group_1(_GroupBase):
def __init__(self, parent, title, group="Hands"):
_GroupBase.__init__(self, parent, title, group)
box = wx.StaticBoxSizer(wx.StaticBox(self, label=title), wx.VERTICAL)
sizer = self.sizer = wx.GridBagSizer(2, 6)
p = wx.StaticText(self, label="Border:")
sizer.Add(p, pos=(0, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.bc = csel.ColourSelect(self)
sizer.Add(p, pos=(0, 1), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.bw = wx.SpinCtrl(self, size=(75, 21),
min=0, max=100, value="75")
sizer.Add(p, pos=(0, 2), span=(1, 2), flag=wx.ALIGN_CENTRE_VERTICAL)
p = wx.StaticText(self, label="Fill:")
sizer.Add(p, pos=(1, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.fc = csel.ColourSelect(self)
sizer.Add(p, pos=(1, 1), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.ls = wx.StaticText(self, label="Size:")
sizer.Add(p, pos=(2, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.sz = wx.SpinCtrl(self, size=(75, 21),
min=0, max=100, value="75")
sizer.Add(p, pos=(2, 1), span=(1, 3), flag=wx.ALIGN_CENTRE_VERTICAL)
box.Add(sizer)
self.SetSizer(box)
#----------------------------------------------------------------------
class _Group_2(_Group_1):
def __init__(self, parent, title, group="Ticks"):
_Group_1.__init__(self, parent, title, group)
sizer = self.sizer
p = wx.StaticText(self, label="Offset:")
sizer.Add(p, pos=(3, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.of = wx.SpinCtrl(self, size=(75, 21),
min=0, max=100, value="75")
sizer.Add(p, pos=(3, 1), span=(1, 3), flag=wx.ALIGN_CENTRE_VERTICAL)
p = wx.StaticText(self, label="Font:")
sizer.Add(p, pos=(4, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.ft = fsel.FontSelect(self)
sizer.Add(p, pos=(4, 1), span=(1, 3), flag=wx.ALIGN_CENTRE_VERTICAL)
self.GetSizer().Layout()
#----------------------------------------------------------------------
class _Group_3(_Group_1):
def __init__(self, parent, title, group="Face"):
_Group_1.__init__(self, parent, title, group)
sizer = self.sizer
for widget in [self.ls, self.sz]:
sizer.Detach(widget)
widget.Destroy()
sizer.Layout()
p = wx.StaticText(self, label="Shadow:")
sizer.Add(p, pos=(2, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.sw = csel.ColourSelect(self)
sizer.Add(p, pos=(2, 1), span=(1, 3), flag=wx.ALIGN_CENTRE_VERTICAL)
self.GetSizer().Layout()
#----------------------------------------------------------------------
class _Group_4(_GroupBase):
def __init__(self, parent, title, group="Window"):
_GroupBase.__init__(self, parent, title, group)
box = wx.StaticBoxSizer(wx.StaticBox(self, label=title), wx.VERTICAL)
sizer = self.sizer = wx.GridBagSizer(2, 6)
p = wx.StaticText(self, label="Foreground:")
sizer.Add(p, pos=(0, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.fg = csel.ColourSelect(self)
sizer.Add(p, pos=(0, 1), span=(1, 3), flag=wx.ALIGN_CENTRE_VERTICAL)
p = wx.StaticText(self, label="Background:")
sizer.Add(p, pos=(1, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.bg = csel.ColourSelect(self)
sizer.Add(p, pos=(1, 1), span=(1, 3), flag=wx.ALIGN_CENTRE_VERTICAL)
p = wx.StaticText(self, label="Style:")
sizer.Add(p, pos=(2, 0), flag=wx.ALIGN_CENTRE_VERTICAL)
p = self.ws = wx.Choice(self, choices=_window_styles)
sizer.Add(p, pos=(2, 1), span=(1, 3), flag=wx.ALIGN_CENTRE_VERTICAL)
box.Add(sizer)
self.SetSizer(box)
#----------------------------------------------------------------------
class _PageBase(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.clock = self.GetGrandParent().GetParent()
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self.sizer)
def UpdateControls(self):
[group.UpdateControls() for group in self.GetChildren()]
#----------------------------------------------------------------------
class StylesPanel(bt.ButtonTreeCtrlPanel):
def __init__(self, parent):
bt.ButtonTreeCtrlPanel.__init__(self, parent)
self.clock = self.GetGrandParent().GetParent()
root = self.AddItem("Styles")
g1 = self.AddItem("General", parent=root)
g2 = self.AddItem("Hours", parent=root)
g3 = self.AddItem("Minutes", parent=root)
self.groups = [g1, g2, g3]
clockStyle = self.clock.GetClockStyle()
hourStyle, minuteStyle = self.clock.GetTickStyle()
for label in dir(styles):
if label.startswith("TICKS_"):
value = bool(getattr(styles, label) & hourStyle)
self.AddItem(label, parent=g2, style=wx.RB_SINGLE, value=value)
value = bool(getattr(styles, label) & minuteStyle)
self.AddItem(label, parent=g3, style=wx.RB_SINGLE, value=value)
elif not (label.startswith("DEFAULT_") or \
label.startswith("_") or \
label in ["HOUR", "MINUTE", "SECOND", "ALL"]):
value = bool(getattr(styles, label) & clockStyle)
self.AddItem(label, parent=g1, style=wx.CHK_2STATE, value=value)
self.EnsureFirstVisible()
self.Bind(bt.EVT_CHANGED, self.OnChanged)
def OnChanged(self, evt):
clockStyle, hourStyle, minuteStyle = \
[reduce(lambda x, y: x | y,
[getattr(styles, item) \
for item in self.GetStringItemsChecked(group)], 0) \
for group in self.groups]
self.clock.SetClockStyle(clockStyle)
self.clock.SetTickStyle(hourStyle, styles.HOUR)
self.clock.SetTickStyle(minuteStyle, styles.MINUTE)
def UpdateControls(self):
clockStyle = self.clock.GetClockStyle()
hourStyle, minuteStyle = self.clock.GetTickStyle()
[g1, g2, g3] = self.groups
for label in dir(styles):
if label.startswith("TICKS_"):
item = self.GetItemByLabel(label, g2)
value = bool(getattr(styles, label) & hourStyle)
self.SetItemValue(item, value)
item = self.GetItemByLabel(label, g3)
value = bool(getattr(styles, label) & minuteStyle)
self.SetItemValue(item, value)
elif not (label.startswith("DEFAULT_") or \
label.startswith("_") or \
label in ["HOUR", "MINUTE", "SECOND", "ALL"]):
item = self.GetItemByLabel(label, g1)
value = bool(getattr(styles, label) & clockStyle)
self.SetItemValue(item, value)
#----------------------------------------------------------------------
class HandsPanel(_PageBase):
def __init__(self, parent):
_PageBase.__init__(self, parent)
[self.sizer.Add(_Group_1(self, title), 1,
flag=wx.EXPAND|wx.ALL, border=6) \
for title in ["Hours", "Minutes", "Seconds"]]
#----------------------------------------------------------------------
class TicksPanel(_PageBase):
def __init__(self, parent):
_PageBase.__init__(self, parent)
[self.sizer.Add(_Group_2(self, title), 1,
flag=wx.EXPAND|wx.ALL, border=6) \
for title in ["Hours", "Minutes"]]
#----------------------------------------------------------------------
class MiscPanel(_PageBase):
def __init__(self, parent):
_PageBase.__init__(self, parent)
self.sizer.Add(_Group_3(self, "Face"), 1,
flag=wx.EXPAND|wx.ALL, border=6)
self.sizer.Add(_Group_4(self, "Window"), 1,
flag=wx.EXPAND|wx.ALL, border=6)
#----------------------------------------------------------------------
class Setup(wx.Dialog):
"""AnalogClock customization dialog."""
def __init__(self, parent):
wx.Dialog.__init__(self, parent, title="AnalogClock Setup")
sizer = wx.BoxSizer(wx.VERTICAL)
nb = self.nb = wx.Notebook(self)
for s in ["Styles", "Hands", "Ticks", "Misc"]:
page = eval(s + "Panel(nb)"); page.Fit()
nb.AddPage(page, s)
nb.Fit()
sizer.Add(nb, 1, flag = wx.EXPAND|wx.ALL, border=6)
bsizer = wx.BoxSizer(wx.HORIZONTAL)
bsizer.Add(wx.Button(self, label="Reset"),
flag = wx.LEFT|wx.RIGHT, border=6)
bsizer.Add(wx.Button(self, wx.ID_OK),
flag = wx.LEFT|wx.RIGHT, border=6)
sizer.Add(bsizer, 0, flag=wx.ALIGN_RIGHT|wx.ALL, border=6)
self.Bind(wx.EVT_SHOW, self.OnShow)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_BUTTON, self.OnButton)
self.customcolours = [None] * 16
self.SetSizerAndFit(sizer)
def OnShow(self, evt):
if self.IsShown():
self.UpdateControls()
evt.Skip()
def OnClose(self, evt):
self.Hide()
def OnButton(self, evt):
if evt.GetEventObject().GetLabel() == "Reset":
self.ResetClock()
evt.Skip()
def UpdateControls(self):
wx.BeginBusyCursor()
for i in range(self.nb.GetPageCount()):
self.nb.GetPage(i).UpdateControls()
wx.EndBusyCursor()
def ResetClock(self):
clock = self.GetParent()
wx.BeginBusyCursor()
clock.SetClockStyle(styles.DEFAULT_CLOCK_STYLE)
clock.SetTickStyle(styles.TICKS_POLY, styles.HOUR)
clock.SetTickStyle(styles.TICKS_CIRCLE, styles.MINUTE)
clock.SetTickFont(wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT))
clock.SetHandBorderWidth(0)
clock.SetTickBorderWidth(0)
clock.SetFaceBorderWidth(0)
clock.SetHandSize(7, styles.HOUR)
clock.SetHandSize(5, styles.MINUTE)
clock.SetHandSize(1, styles.SECOND)
clock.SetTickSize(25, styles.HOUR)
clock.SetTickSize(5, styles.MINUTE)
clock.SetTickOffset(0)
clock.SetWindowStyle(wx.NO_BORDER)
sw = wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DSHADOW)
clock.SetShadowColour(sw)
no_color = wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE)
clock.SetFaceFillColour(no_color)
clock.SetFaceBorderColour(no_color)
clock.SetBackgroundColour(no_color)
fg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
clock.SetForegroundColour(fg)
self.UpdateControls()
wx.EndBusyCursor()
#
#
### eof

View File

@ -0,0 +1,47 @@
# AnalogClock constants
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 15 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
# Style options that control the general clock appearance,
# chosen via SetClockStyle.
SHOW_QUARTERS_TICKS = 1
SHOW_HOURS_TICKS = 2
SHOW_MINUTES_TICKS = 4
ROTATE_TICKS = 8
SHOW_HOURS_HAND = 16
SHOW_MINUTES_HAND = 32
SHOW_SECONDS_HAND = 64
SHOW_SHADOWS = 128
OVERLAP_TICKS = 256
DEFAULT_CLOCK_STYLE = SHOW_HOURS_TICKS|SHOW_MINUTES_TICKS| \
SHOW_HOURS_HAND|SHOW_MINUTES_HAND|SHOW_SECONDS_HAND| \
SHOW_SHADOWS|ROTATE_TICKS
# Style options that control the appearance of tick marks,
# chosen via SetTickStyle.
TICKS_NONE = 1
TICKS_SQUARE = 2
TICKS_CIRCLE = 4
TICKS_POLY = 8
TICKS_DECIMAL = 16
TICKS_ROMAN = 32
TICKS_BINARY = 64
TICKS_HEX = 128
# Constants that may be used as 'target' keyword value in
# the various Get/Set methods.
HOUR = 1
MINUTE = 2
SECOND = 4
ALL = HOUR|MINUTE|SECOND
#
##
### eof

View File

@ -1,501 +0,0 @@
#----------------------------------------------------------------------
# Name: wx.lib.analogclockopts
# Purpose: An analog clock window - setup frame
#
# Author: E. A. Tacao
#
# Created: 15-February-2004
#----------------------------------------------------------------------
# Originally generated by wx.Glade 0.3.1 on Wed Feb 18 00:05:35 2004
# Converted to wx namespace by Peter Damoc
"""
A configuration dialog (frame actually) for the AnalogClockWindow
"""
import wx
import wx.lib.colourselect as csel
import wx.lib.dialogs as dlgs
import string
class ACCustomizationFrame(wx.Frame):
def __init__(self, parent, id, name, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.DEFAULT_FRAME_STYLE | wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT | wx.WANTS_CHARS):
# k=wx.NewId();ide=map(lambda x: x+k, range(0,100))
ide = [wx.NewId() for i in range(100)]
#kwds["style"] = wx.CAPTION|wx.SYSTEM_MENU
#wx.Frame.__init__(self, *args, **kwds)
wx.Frame.__init__(self, parent, id, name, pos, size, style)
self.parent=parent
self.panel_1 = wx.Panel(self, -1)
self.notebook_1 = wx.Notebook(self.panel_1, -1, style=0)
self.notebook_1_pane_3 = wx.Panel(self.notebook_1, -1)
self.notebook_1_pane_2 = wx.Panel(self.notebook_1, -1)
self.notebook_1_pane_1 = wx.Panel(self.notebook_1, -1)
self.label_top = wx.StaticText(self.panel_1, -1, "Use the options below to change the clock;\nthe main buttons on top of each category reset to its defaults.")
self.static_line_1 = wx.StaticLine(self.panel_1, -1)
self.button_1 = wx.Button(self.notebook_1_pane_1, ide[1], "SetClockStyle")
self.static_line_2 = wx.StaticLine(self.notebook_1_pane_1, -1)
self.button_2 = wx.Button(self.notebook_1_pane_1, ide[3], "styles...")
self.static_line_3 = wx.StaticLine(self.notebook_1_pane_1, -1, style=wx.LI_VERTICAL)
self.button_3 = wx.Button(self.notebook_1_pane_1, ide[2], "SetTickStyles")
self.static_line_4 = wx.StaticLine(self.notebook_1_pane_1, -1)
self.button_4 = wx.Button(self.notebook_1_pane_1, ide[4], "styles...")
self.button_22 = wx.Button(self.notebook_1_pane_1, ide[22], "minutes...")
self.static_line_5 = wx.StaticLine(self.notebook_1_pane_1, -1)
self.button_5 = wx.Button(self.notebook_1_pane_1, ide[5], "SetShadowColour")
self.static_line_6 = wx.StaticLine(self.notebook_1_pane_1, -1)
self.button_6 = csel.ColourSelect(self.notebook_1_pane_1, ide[6], "all...")
self.static_line_7 = wx.StaticLine(self.notebook_1_pane_1, -1, style=wx.LI_VERTICAL)
self.button_7 = wx.Button(self.notebook_1_pane_1, ide[7], "SetWatchPenBrush")
self.static_line_8 = wx.StaticLine(self.notebook_1_pane_1, -1)
self.button_8 = csel.ColourSelect(self.notebook_1_pane_1, ide[8], "Pen colour...")
self.button_9 = csel.ColourSelect(self.notebook_1_pane_1, ide[9], "Brush colour...")
self.button_10 = wx.Button(self.notebook_1_pane_2, ide[10], "SetTickColours")
self.static_line_8 = wx.StaticLine(self.notebook_1_pane_2, -1)
self.button_11 = csel.ColourSelect(self.notebook_1_pane_2, ide[11], "hours...", colour=self.parent.tickMarkHoursPen.GetColour())
self.button_12 = csel.ColourSelect(self.notebook_1_pane_2, ide[12], "minutes...", colour=self.parent.tickMarkMinutesPen.GetColour())
self.static_line_10 = wx.StaticLine(self.notebook_1_pane_2, -1, style=wx.LI_VERTICAL)
self.button_13 = wx.Button(self.notebook_1_pane_2, ide[13], "SetTickSizes")
self.static_line_11 = wx.StaticLine(self.notebook_1_pane_2, -1)
self.label_1 = wx.StaticText(self.notebook_1_pane_2, -1, "hours")
self.spin_ctrl_1 = wx.SpinCtrl(self.notebook_1_pane_2, ide[71], "10", min=1, max=100)
self.label_2 = wx.StaticText(self.notebook_1_pane_2, -1, "minutes")
self.spin_ctrl_2 = wx.SpinCtrl(self.notebook_1_pane_2, ide[72], "5", min=0, max=100)
self.label_3 = wx.StaticText(self.notebook_1_pane_2, -1, "offset")
self.spin_ctrl_3 = wx.SpinCtrl(self.notebook_1_pane_2, ide[73], "0", min=0, max=100)
self.static_line_12 = wx.StaticLine(self.notebook_1_pane_2, -1, style=wx.LI_VERTICAL)
self.button_14 = wx.Button(self.notebook_1_pane_2, ide[14], "SetTickFonts")
self.static_line_13 = wx.StaticLine(self.notebook_1_pane_2, -1)
self.button_15 = wx.Button(self.notebook_1_pane_2, ide[15], "hours...")
self.button_16 = wx.Button(self.notebook_1_pane_2, ide[16], "minutes...")
self.button_17 = wx.Button(self.notebook_1_pane_3, ide[17], "SetHandWeights")
self.static_line_14 = wx.StaticLine(self.notebook_1_pane_3, -1)
self.label_4 = wx.StaticText(self.notebook_1_pane_3, -1, "hours")
self.spin_ctrl_4 = wx.SpinCtrl(self.notebook_1_pane_3, ide[74], "5", min=0, max=100)
self.label_5 = wx.StaticText(self.notebook_1_pane_3, -1, "minutes")
self.spin_ctrl_5 = wx.SpinCtrl(self.notebook_1_pane_3, ide[75], "3", min=0, max=100)
self.label_6 = wx.StaticText(self.notebook_1_pane_3, -1, "seconds")
self.spin_ctrl_6 = wx.SpinCtrl(self.notebook_1_pane_3, ide[76], "1", min=0, max=100)
self.static_line_15 = wx.StaticLine(self.notebook_1_pane_3, -1, style=wx.LI_VERTICAL)
self.button_18 = wx.Button(self.notebook_1_pane_3, ide[18], "SetHandColours")
self.static_line_16 = wx.StaticLine(self.notebook_1_pane_3, -1)
self.button_19 = csel.ColourSelect(self.notebook_1_pane_3, ide[19], "hours...")
self.button_20 = csel.ColourSelect(self.notebook_1_pane_3, ide[20], "minutes...")
self.button_21 = csel.ColourSelect(self.notebook_1_pane_3, ide[21], "seconds...")
self.__set_properties()
self.__do_layout()
self.Bind(wx.EVT_BUTTON, self.OnEventsHook, id=ide[0], id2=ide[29])
self.Bind(csel.EVT_COLOURSELECT, self.OnEventsHook, id=ide[0], id2=ide[29])
self.Bind(wx.EVT_SPINCTRL, self.OnEventsHook, id=ide[71], id2=ide[80])
self.Bind(wx.EVT_RADIOBUTTON, self.OnEventsHook, id=ide[51], id2=ide[60])
self.Bind(wx.EVT_WINDOW_DESTROY, self.OnQuit)
self.ide=ide
def __set_properties(self):
#self.SetTitle("AnalogClock Test")
self.spin_ctrl_1.SetSize((50, -1))
self.spin_ctrl_2.SetSize((50, -1))
self.spin_ctrl_3.SetSize((50, -1))
self.spin_ctrl_4.SetSize((50, -1))
self.spin_ctrl_5.SetSize((50, -1))
self.spin_ctrl_6.SetSize((50, -1))
def __do_layout(self):
sizer_frame = wx.BoxSizer(wx.HORIZONTAL)
sizer_main = wx.BoxSizer(wx.VERTICAL)
sizer_25 = wx.BoxSizer(wx.HORIZONTAL)
sizer_26 = wx.StaticBoxSizer(wx.StaticBox(self.notebook_1_pane_3, -1, ""), wx.VERTICAL)
sizer_27 = wx.BoxSizer(wx.HORIZONTAL)
sizer_31 = wx.BoxSizer(wx.VERTICAL)
sizer_33 = wx.BoxSizer(wx.HORIZONTAL)
sizer_32 = wx.BoxSizer(wx.HORIZONTAL)
sizer_28 = wx.BoxSizer(wx.VERTICAL)
sizer_30 = wx.BoxSizer(wx.HORIZONTAL)
sizer_29 = wx.BoxSizer(wx.HORIZONTAL)
sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
sizer_13 = wx.StaticBoxSizer(wx.StaticBox(self.notebook_1_pane_2, -1, ""), wx.VERTICAL)
sizer_14 = wx.BoxSizer(wx.HORIZONTAL)
sizer_22 = wx.BoxSizer(wx.VERTICAL)
sizer_24 = wx.BoxSizer(wx.HORIZONTAL)
sizer_23 = wx.BoxSizer(wx.HORIZONTAL)
sizer_18 = wx.BoxSizer(wx.VERTICAL)
sizer_21 = wx.BoxSizer(wx.HORIZONTAL)
sizer_20 = wx.BoxSizer(wx.HORIZONTAL)
sizer_19 = wx.BoxSizer(wx.HORIZONTAL)
sizer_15 = wx.BoxSizer(wx.VERTICAL)
sizer_17 = wx.BoxSizer(wx.HORIZONTAL)
sizer_16 = wx.BoxSizer(wx.HORIZONTAL)
sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
sizer_2 = wx.StaticBoxSizer(wx.StaticBox(self.notebook_1_pane_1, -1, ""), wx.VERTICAL)
sizer_8 = wx.BoxSizer(wx.HORIZONTAL)
sizer_11 = wx.BoxSizer(wx.VERTICAL)
sizer_12b = wx.BoxSizer(wx.HORIZONTAL)
sizer_9 = wx.BoxSizer(wx.VERTICAL)
sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
sizer_6 = wx.BoxSizer(wx.VERTICAL)
sizer_7 = wx.BoxSizer(wx.HORIZONTAL)
sizer_4 = wx.BoxSizer(wx.VERTICAL)
sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
sizer_main.Add(self.label_top, 0, wx.LEFT|wx.TOP, 5)
sizer_main.Add(self.static_line_1, 0, wx.TOP|wx.BOTTOM|wx.EXPAND, 10)
sizer_4.Add(self.button_1, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_4.Add(self.static_line_2, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_5.Add(self.button_2, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_4.Add(sizer_5, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_3.Add(sizer_4, 1, wx.EXPAND, 0)
sizer_3.Add(self.static_line_3, 0, wx.EXPAND, 0)
sizer_6.Add(self.button_3, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_6.Add(self.static_line_4, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_7.Add(self.button_4, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_7.Add(self.button_22, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_6.Add(sizer_7, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_3.Add(sizer_6, 1, wx.EXPAND, 0)
sizer_2.Add(sizer_3, 1, wx.EXPAND, 0)
sizer_2.Add(self.static_line_5, 0, wx.EXPAND, 0)
sizer_9.Add(self.button_5, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_9.Add(self.static_line_6, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_10.Add(self.button_6, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_9.Add(sizer_10, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_8.Add(sizer_9, 1, wx.EXPAND, 0)
sizer_8.Add(self.static_line_7, 0, wx.EXPAND, 0)
sizer_11.Add(self.button_7, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_11.Add(self.static_line_8, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_12b.Add(self.button_8, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_12b.Add(self.button_9, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_11.Add(sizer_12b, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_8.Add(sizer_11, 1, wx.EXPAND, 0)
sizer_2.Add(sizer_8, 1, wx.EXPAND, 0)
sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
self.notebook_1_pane_1.SetAutoLayout(1)
self.notebook_1_pane_1.SetSizer(sizer_1)
sizer_1.Fit(self.notebook_1_pane_1)
sizer_1.SetSizeHints(self.notebook_1_pane_1)
sizer_15.Add(self.button_10, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_15.Add(self.static_line_8, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_16.Add(self.button_11, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_15.Add(sizer_16, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_17.Add(self.button_12, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_15.Add(sizer_17, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_14.Add(sizer_15, 1, wx.EXPAND, 0)
sizer_14.Add(self.static_line_10, 0, wx.EXPAND, 0)
sizer_18.Add(self.button_13, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_18.Add(self.static_line_11, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_19.Add(self.label_1, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_19.Add(self.spin_ctrl_1, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_18.Add(sizer_19, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_20.Add(self.label_2, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_20.Add(self.spin_ctrl_2, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_18.Add(sizer_20, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_21.Add(self.label_3, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_21.Add(self.spin_ctrl_3, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_18.Add(sizer_21, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_14.Add(sizer_18, 1, wx.EXPAND, 0)
sizer_14.Add(self.static_line_12, 0, wx.EXPAND, 0)
sizer_22.Add(self.button_14, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_22.Add(self.static_line_13, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_23.Add(self.button_15, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_22.Add(sizer_23, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_24.Add(self.button_16, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_22.Add(sizer_24, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_14.Add(sizer_22, 1, wx.EXPAND, 0)
sizer_13.Add(sizer_14, 1, wx.EXPAND, 0)
sizer_12.Add(sizer_13, 1, wx.EXPAND, 0)
self.notebook_1_pane_2.SetAutoLayout(1)
self.notebook_1_pane_2.SetSizer(sizer_12)
sizer_12.Fit(self.notebook_1_pane_2)
sizer_12.SetSizeHints(self.notebook_1_pane_2)
sizer_28.Add(self.button_17, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_28.Add(self.static_line_14, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_29.Add(self.label_4, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_29.Add(self.spin_ctrl_4, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_29.Add(self.label_5, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_29.Add(self.spin_ctrl_5, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_28.Add(sizer_29, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_30.Add(self.label_6, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_30.Add(self.spin_ctrl_6, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_28.Add(sizer_30, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_27.Add(sizer_28, 1, wx.EXPAND, 0)
sizer_27.Add(self.static_line_15, 0, wx.EXPAND, 0)
sizer_31.Add(self.button_18, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_31.Add(self.static_line_16, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20)
sizer_32.Add(self.button_19, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_32.Add(self.button_20, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_31.Add(sizer_32, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_33.Add(self.button_21, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
sizer_31.Add(sizer_33, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
sizer_27.Add(sizer_31, 1, wx.EXPAND, 0)
sizer_26.Add(sizer_27, 1, wx.EXPAND, 0)
sizer_25.Add(sizer_26, 1, wx.EXPAND, 0)
self.notebook_1_pane_3.SetAutoLayout(1)
self.notebook_1_pane_3.SetSizer(sizer_25)
sizer_25.Fit(self.notebook_1_pane_3)
sizer_25.SetSizeHints(self.notebook_1_pane_3)
self.notebook_1.AddPage(self.notebook_1_pane_1, "Clock")
self.notebook_1.AddPage(self.notebook_1_pane_2, "Ticks")
self.notebook_1.AddPage(self.notebook_1_pane_3, "Hands")
sizer_main.Add(wx.NotebookSizer(self.notebook_1), 1, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 5)
self.panel_1.SetAutoLayout(1)
self.panel_1.SetSizer(sizer_main)
sizer_main.Fit(self.panel_1)
sizer_main.SetSizeHints(self.panel_1)
sizer_frame.Add(self.panel_1, 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
self.SetAutoLayout(1)
self.SetSizer(sizer_frame)
sizer_frame.Fit(self)
sizer_frame.SetSizeHints(self)
self.Layout()
self.UpdateWidgets()
def UpdateAll(self):
self.UpdateWidgets()
self.parent.OnSize(None)
def UpdateWidgets(self):
self.button_6.SetColour(self.parent.shadowPenColour)
bc=self.parent.watchPen
if bc:
bc=bc.GetColour()
else:
bc=self.parent.GetBackgroundColour()
self.button_8.SetColour(bc)
bc=self.parent.watchBrush
if bc:
bc=bc.GetColour()
else:
bc=self.parent.GetBackgroundColour()
self.button_9.SetColour(bc)
self.button_11.SetColour(self.parent.tickMarkHoursPen.GetColour())
self.button_12.SetColour(self.parent.tickMarkMinutesPen.GetColour())
self.button_19.SetColour(self.parent.handHoursColour)
self.button_20.SetColour(self.parent.handMinutesColour)
self.button_21.SetColour(self.parent.handSecondsColour)
self.spin_ctrl_1.SetValue(self.parent.markSizeHour)
self.spin_ctrl_2.SetValue(self.parent.markSizeMin)
self.spin_ctrl_3.SetValue(self.parent.offM)
self.spin_ctrl_4.SetValue(self.parent.handHoursThickness)
self.spin_ctrl_5.SetValue(self.parent.handMinutesThickness)
self.spin_ctrl_6.SetValue(self.parent.handSecondsThickness)
def gfid(self, id, lista):
return self.ide.index(id) in lista
# for x in lista:
# if id==self.ide[x]:
# f=True
# break
# else:
# f=False
# return f
def OnEventsHook(self, evt):
id=evt.GetId()
if self.gfid(id, [6,8,9,11,12,19,20,21,23]):
self.OnSelectColour(evt)
elif self.gfid(id, [15,16]):
self.OnSelectFont(evt)
elif self.gfid(id, [71,72,73,74,75,76]):
self.OnSpinChange(evt)
elif self.gfid(id, [3,4,22]):
self.OnChangeStyle(evt)
elif self.gfid(id, [1,2,5,7,10,13,14,17,18]):
self.OnDefaults(evt)
def OnSelectColour(self, evt):
id=evt.GetId();colour=evt.GetValue()
if id==self.ide[6]:
self.parent.SetShadowColour(colour)
elif id==self.ide[8]:
self.parent.SetWatchPenBrush(p=wx.Pen(colour, 1, wx.SOLID))
elif id==self.ide[9]:
self.parent.SetWatchPenBrush(b=wx.Brush(colour, wx.SOLID))
elif id==self.ide[11]:
self.parent.SetTickColours(h=colour)
elif id==self.ide[12]:
self.parent.SetTickColours(m=colour)
elif id==self.ide[19]:
self.parent.SetHandColours(h=colour)
elif id==self.ide[20]:
self.parent.SetHandColours(m=colour)
elif id==self.ide[21]:
self.parent.SetHandColours(s=colour)
self.UpdateAll()
def OnSelectFont(self, evt):
id=evt.GetId()
if id==self.ide[15]:
font=self.parent.tickMarkHoursFont;font.SetPointSize(self.parent.markSizeHour)
colour=self.parent.tickMarkHoursPen.GetColour()
else:
font=self.parent.tickMarkMinutesFont;font.SetPointSize(self.parent.markSizeMin)
colour=self.parent.tickMarkMinutesPen.GetColour()
data = wx.FontData()
data.EnableEffects(True)
data.SetColour(colour)
data.SetInitialFont(font)
dlg = wx.FontDialog(self, data)
if dlg.ShowModal() == wx.ID_OK:
data = dlg.GetFontData()
font = data.GetChosenFont()
colour = data.GetColour()
if id==self.ide[15]:
self.parent.SetTickFonts(h=font)
self.parent.SetTickColours(h=colour.Get())
else:
self.parent.SetTickFonts(m=font)
self.parent.SetTickColours(m=colour.Get())
dlg.Destroy()
self.UpdateAll()
def OnSpinChange(self, evt):
id=evt.GetId();v=evt.GetInt()
if id==self.ide[71]:
self.parent.SetTickSizes(h=v)
if id==self.ide[72]:
self.parent.SetTickSizes(m=v)
if id==self.ide[73]:
self.parent.SetMinutesOffset(v)
if id==self.ide[74]:
self.parent.SetHandWeights(h=v)
if id==self.ide[75]:
self.parent.SetHandWeights(m=v)
if id==self.ide[76]:
self.parent.SetHandWeights(s=v)
self.UpdateAll()
def OnChangeStyle(self, evt):
id=evt.GetId()
if id==self.ide[3]:
x="""SHOW_QUARTERS_TICKS
SHOW_HOURS_TICKS
SHOW_MINUTES_TICKS
ROTATE_TICKS
SHOW_HOURS_HAND
SHOW_MINUTES_HAND
SHOW_SECONDS_HAND
SHOW_SHADOWS
OVERLAP_TICKS""".split()
m=map(lambda f: (self.parent.clockStyle & f)/f, map(lambda f: 2**x.index(f),x))
dlg = dlgs.MultipleChoiceDialog(self,
"Select some styles for the clock:",
"Styles", x)
for i in range(0,len(m)):
if m[i]:
dlg.lbox.SetSelection(i)
if (dlg.ShowModal() == wx.ID_OK):
v=reduce(lambda x,y:x+y,map(lambda f: 2**f,dlg.GetValue()))
self.parent.SetClockStyle(v)
elif id==self.ide[4]:
x="""TICKS_NONE
TICKS_SQUARE
TICKS_CIRCLE
TICKS_POLY
TICKS_DECIMAL
TICKS_ROMAN""".split()
m=map(lambda f: (self.parent.tickMarkHoursStyle & f)/f, map(lambda f: 2**x.index(f),x))
dlg = wx.SingleChoiceDialog(self,
"Select a style for the hours:",
"Styles", x, wx.CHOICEDLG_STYLE)
for i in range(0,len(m)):
if m[i]:
dlg.SetSelection(i)
if dlg.ShowModal() == wx.ID_OK:
v=2**dlg.GetSelection()
self.parent.SetTickStyles(h=v)
dlg.Destroy()
elif id==self.ide[22]:
tipo="for the minutes"
x="""TICKS_NONE
TICKS_SQUARE
TICKS_CIRCLE
TICKS_POLY
TICKS_DECIMAL
TICKS_ROMAN""".split()
m=map(lambda f: (self.parent.tickMarkMinutesStyle & f)/f, map(lambda f: 2**x.index(f),x))
dlg = wx.SingleChoiceDialog(self,
"Select a style for the minutes:",
"Styles", x, wx.CHOICEDLG_STYLE)
for i in range(0,len(m)):
if m[i]:
dlg.SetSelection(i)
if dlg.ShowModal() == wx.ID_OK:
v=2**dlg.GetSelection()
self.parent.SetTickStyles(m=v)
dlg.Destroy()
self.UpdateAll()
def OnDefaults(self, evt):
id=evt.GetId()
if id==self.ide[1]:
self.parent.SetClockStyle(142)
elif id==self.ide[2]:
self.parent.SetTickStyles(8, 4)
elif id==self.ide[5]:
self.parent.SetShadowColour((128,128,128))
elif id==self.ide[7]:
colour=self.parent.GetBackgroundColour()
self.parent.SetWatchPenBrush(p=wx.Pen(colour, 1, wx.SOLID), b=wx.Brush(colour, wx.SOLID))
elif id==self.ide[10]:
colour=(0, 0, 0)
self.parent.SetTickColours(h=colour, m=colour)
elif id==self.ide[13]:
self.parent.SetTickSizes(h=10, m=5)
self.parent.SetMinutesOffset(0)
elif id==self.ide[14]:
self.parent.SetTickFonts(wx.Font(1, wx.SWISS, wx.NORMAL, wx.BOLD))
elif id==self.ide[17]:
self.parent.SetHandWeights(h=5, m=3, s=1)
elif id==self.ide[18]:
colour=(0, 0, 0)
self.parent.SetHandColours(h=colour, m=colour, s=colour)
self.UpdateAll()
def OnQuit(self, evt):
self.parent.prefs_open=False
#
##
### eof