micropython-nano-gui/extras/widgets/clock.py

60 wiersze
2.0 KiB
Python

# clock.py Analog clock widget for nanogui
# Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2023 Peter Hinch
from gui.core.nanogui import DObject
from gui.widgets.dial import Dial, Pointer
from gui.core.colors import *
from cmath import rect, pi
class Clock(DObject):
def __init__(
self,
writer,
row,
col,
height,
fgcolor=None,
bgcolor=None,
bdcolor=RED,
pointers=(CYAN, CYAN, RED),
label=None,
):
super().__init__(writer, row, col, height, height, fgcolor, bgcolor, bdcolor)
dial = Dial(writer, row, col, height=height, ticks=12, bdcolor=None, label=label)
self._dial = dial
self._pcolors = pointers
self._hrs = Pointer(dial)
self._mins = Pointer(dial)
if pointers[2] is not None:
self._secs = Pointer(dial)
def value(self, t):
super().value(t)
self.show()
def show(self):
super().show()
t = super().value()
# Return a unit vector of phase phi. Multiplying by this will
# rotate a vector anticlockwise which is mathematically correct.
# Alas clocks, modelled on sundials, were invented in the northern
# hemisphere. Otherwise they would have rotated widdershins like
# the maths. Hence negative sign when called.
def uv(phi):
return rect(1, phi)
hc, mc, sc = self._pcolors # Colors for pointers
hstart = 0 + 0.7j # Pointer lengths. Will rotate relative to top.
mstart = 0 + 1j
sstart = 0 + 1j
self._hrs.value(hstart * uv(-t[3] * pi / 6 - t[4] * pi / 360), hc)
self._mins.value(mstart * uv(-t[4] * pi / 30), mc)
if sc is not None:
self._secs.value(sstart * uv(-t[5] * pi / 30), sc)
if self._dial.label is not None:
v = f"{t[3]:02d}.{t[4]:02d}" if sc is None else f"{t[3]:02d}.{t[4]:02d}.{t[5]:02d}"
self._dial.label.value(v)