diff options
| author | Daniel Thompson <daniel@redfelineninja.org.uk> | 2020-05-24 13:20:02 (GMT) |
|---|---|---|
| committer | Daniel Thompson <daniel@redfelineninja.org.uk> | 2020-05-24 13:20:02 (GMT) |
| commit | de647b324cd5731eed54fe38e3efe93b26a8be42 (patch) | |
| tree | ac8f45c5fa88a44ac7424800c39527e907b430d6 /wasp/widgets.py | |
| parent | 57999226fdf8e36021c37478730084424947f604 (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.py | 77 |
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 |
