⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 helpers.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 2 页
字号:
# 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 - 1
                # else prevent exceptions on leap seconds
                elif idx <= 0 or idx > 60:
                    idx = 59
                # and adjust idx offset for minutes and non-leap seconds 
                else:
                    idx = idx - 1
                angle = math.radians(180 - 6 * (idx + 1))

                hand.dyer.Select(dc, shadow)
                hand.Draw(dc, (self.radius, self.centre, angle), offset)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -