summaryrefslogtreecommitdiff
path: root/wasp/widgets.py
diff options
context:
space:
mode:
authorDaniel Thompson <daniel@redfelineninja.org.uk>2020-05-24 13:20:02 (GMT)
committerDaniel Thompson <daniel@redfelineninja.org.uk>2020-05-24 13:20:02 (GMT)
commitde647b324cd5731eed54fe38e3efe93b26a8be42 (patch)
treeac8f45c5fa88a44ac7424800c39527e907b430d6 /wasp/widgets.py
parent57999226fdf8e36021c37478730084424947f604 (diff)
widgets: Introduce a slider widget
Currently the slider doesn't actually slide (because we process touch events rather than swipe events) but we've called is a slider anyway.
Diffstat (limited to 'wasp/widgets.py')
-rw-r--r--wasp/widgets.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/wasp/widgets.py b/wasp/widgets.py
index 9271fe6..97410b0 100644
--- a/wasp/widgets.py
+++ b/wasp/widgets.py
@@ -10,6 +10,7 @@ shared between applications.
import icons
import watch
+from micropython import const
class BatteryMeter(object):
"""Battery meter widget.
@@ -94,3 +95,79 @@ class ScrollIndicator():
draw.rleblit(icons.up_arrow, pos=self._pos, fg=0x7bef)
if self.down:
draw.rleblit(icons.down_arrow, pos=(self._pos[0], self._pos[1] + 13), fg=0x7bef)
+
+_SLIDER_KNOB_DIAMETER = const(40)
+_SLIDER_KNOB_RADIUS = const(_SLIDER_KNOB_DIAMETER // 2)
+_SLIDER_WIDTH = const(220)
+_SLIDER_TRACK = const(_SLIDER_WIDTH - _SLIDER_KNOB_DIAMETER)
+_SLIDER_TRACK_HEIGHT = const(8)
+_SLIDER_TRACK_Y1 = const(_SLIDER_KNOB_RADIUS - (_SLIDER_TRACK_HEIGHT // 2))
+_SLIDER_TRACK_Y2 = const(_SLIDER_TRACK_Y1 + _SLIDER_TRACK_HEIGHT)
+
+class Slider():
+ """A slider to select values."""
+ def __init__(self, steps, x=10, y=90, color=0x39ff):
+ self.value = 0
+ self._steps = steps
+ self._stepsize = _SLIDER_TRACK / (steps-1)
+ self._x = x
+ self._y = y
+ self._color = color
+
+ # Automatically generate a lowlight color
+ if color < 0b10110_000000_00000:
+ color = (color | 0b10110_000000_00000) & 0b10110_111111_11111
+ if (color & 0b111111_00000) < 0b101100_00000:
+ color = (color | 0b101100_00000) & 0b11111_101100_11111
+ if (color & 0b11111) < 0b10110:
+ color = (color | 0b11000) & 0b11111_111111_10110
+ self._lowlight = color
+
+ def draw(self):
+ """Draw the slider."""
+ draw = watch.drawable
+ x = self._x
+ y = self._y
+ color = self._color
+ light = self._lowlight
+
+ knob_x = x + ((_SLIDER_TRACK * self.value) // (self._steps-1))
+ draw.blit(icons.knob2, knob_x, y, color)
+
+ w = knob_x - x
+ if w > 0:
+ draw.fill(0, x, y, w, _SLIDER_TRACK_Y1)
+ if w > _SLIDER_KNOB_RADIUS:
+ draw.fill(0, x, y+_SLIDER_TRACK_Y1,
+ _SLIDER_KNOB_RADIUS, _SLIDER_TRACK_HEIGHT)
+ draw.fill(color, x+_SLIDER_KNOB_RADIUS, y+_SLIDER_TRACK_Y1,
+ w-_SLIDER_KNOB_RADIUS, _SLIDER_TRACK_HEIGHT)
+ else:
+ draw.fill(0, x, y+_SLIDER_TRACK_Y1, w, _SLIDER_TRACK_HEIGHT)
+ draw.fill(0, x, y+_SLIDER_TRACK_Y2, w, _SLIDER_TRACK_Y1)
+
+ sx = knob_x + _SLIDER_KNOB_DIAMETER
+ w = _SLIDER_WIDTH - _SLIDER_KNOB_DIAMETER - w
+ if w > 0:
+ draw.fill(0, sx, y, w, _SLIDER_TRACK_Y1)
+ if w > _SLIDER_KNOB_RADIUS:
+ draw.fill(0, sx+w-_SLIDER_KNOB_RADIUS, y+_SLIDER_TRACK_Y1,
+ _SLIDER_KNOB_RADIUS, _SLIDER_TRACK_HEIGHT)
+ draw.fill(light, sx, y+_SLIDER_TRACK_Y1,
+ w-_SLIDER_KNOB_RADIUS, _SLIDER_TRACK_HEIGHT)
+ else:
+ draw.fill(0, sx, y+_SLIDER_TRACK_Y1, w, _SLIDER_TRACK_HEIGHT)
+ draw.fill(0, sx, y+_SLIDER_TRACK_Y2, w, _SLIDER_TRACK_Y1)
+
+ def update(self):
+ self.draw()
+
+ def touch(self, event):
+ tx = event[1]
+ threshold = self._x + 20 - (self._stepsize / 2)
+ v = int((tx - threshold) / self._stepsize)
+ if v < 0:
+ v = 0
+ elif v >= self._steps:
+ v = self._steps - 1
+ self.value = v