From 632ec713a40f204aabf4779a6eda83974878e66c Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Tue, 29 Dec 2020 12:32:38 +0000 Subject: [PATCH] widgets: Checkbox: Add a simple checkbox widget Signed-off-by: Daniel Thompson --- res/checkbox.png | Bin 0 -> 6114 bytes wasp/apps/testapp.py | 12 +++++++++--- wasp/icons.py | 13 +++++++++++++ wasp/widgets.py | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 res/checkbox.png diff --git a/res/checkbox.png b/res/checkbox.png new file mode 100644 index 0000000000000000000000000000000000000000..7183b2aa15fd012174a2a2929de0051f1360dc8b GIT binary patch literal 6114 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 literal 0 HcmV?d00001 diff --git a/wasp/apps/testapp.py b/wasp/apps/testapp.py index 6b813e4..841dcea 100644 --- a/wasp/apps/testapp.py +++ b/wasp/apps/testapp.py @@ -25,10 +25,12 @@ class TestApp(): ICON = icons.app def __init__(self): - self.tests = ('Alarm', 'Button', 'Crash', 'Colours', 'Fill', 'Fill-H', 'Fill-V', 'Free Mem', 'Line', 'Notifications', 'RLE', 'String', 'Touch', 'Wrap') + self.tests = ('Alarm', 'Button', 'Checkbox', 'Crash', 'Colours', 'Fill', 'Fill-H', 'Fill-V', 'Free Mem', 'Line', 'Notifications', 'RLE', 'String', 'Touch', 'Wrap') self.test = self.tests[0] self.scroll = wasp.widgets.ScrollIndicator() + self._checkbox = wasp.widgets.Checkbox(4, 104, 'Check me') + self._sliders = ( wasp.widgets.Slider(32, 10, 90, 0xf800), wasp.widgets.Slider(64, 10, 140, 0x27e4), @@ -72,7 +74,9 @@ class TestApp(): self._draw() def touch(self, event): - if self.test == 'Colours': + if self.test == 'Checkbox': + self._checkbox.touch(event) + elif self.test == 'Colours': if event[2] > 90: s = self._sliders[(event[2] - 90) // 50] s.touch(event) @@ -221,7 +225,9 @@ class TestApp(): if self.test == 'Alarm': draw.string("Press button to", 12, 24+24) draw.string("set alarm.", 12, 24+48) - if self.test == 'Crash': + elif self.test == 'Checkbox': + self._checkbox.draw() + elif self.test == 'Crash': draw.string("Press button to", 12, 24+24) draw.string("throw exception.", 12, 24+48) elif self.test == 'Colours': diff --git a/wasp/icons.py b/wasp/icons.py index c6fc5ad..7eb2e22 100644 --- a/wasp/icons.py +++ b/wasp/icons.py @@ -332,3 +332,16 @@ no_button = ( b'?\x1c\xc1\x03\xc1?\x1c\xc1\x03\xc1?\x1c\xc1\x03\xc1?' b'\x1c\xc1\x03\xff\x1e?\x83' ) + +# 2-bit RLE, generated from res/checkbox.png, 108 bytes +checkbox = ( + b'\x02' + b' ' + b'\x02\xdc\x03\xde\x01\xe4X\xc7Z\xc6Z\xc6Z\xc6T\x82' + b'D\xc6S\x84C\xc6R\x86B\xc6Q\x86C\xc6P\x86' + b'D\xc6O\x86E\xc6N\x86F\xc6M\x86G\xc6L\x86' + b'H\xc6D\x82E\x86I\xc6C\x84C\x86J\xc6B\x86' + b'A\x86K\xc6C\x8bL\xc6D\x89M\xc6E\x87N\xc6' + b'F\x85O\xc6G\x83P\xc6H\x81Q\xc6Z\xc6Z\xc6' + b'Z\xc7X\xe4\x01\xde\x03\xdc\x02' +) diff --git a/wasp/widgets.py b/wasp/widgets.py index 049cf4f..bfecbe8 100644 --- a/wasp/widgets.py +++ b/wasp/widgets.py @@ -215,6 +215,47 @@ class ScrollIndicator: if self.down: draw.blit(icons.down_arrow, self._pos[0], self._pos[1]+13, fg=color) +class Checkbox(): + """A simple (labelled) checkbox.""" + def __init__(self, x, y, label=None): + self._im = (x, y, label) + self.state = False + + def draw(self): + """Draw the checkbox and label.""" + draw = wasp.watch.drawable + im = self._im + if im[2]: + draw.string(im[2], im[0], im[1]+6) + self.update() + + def update(self): + """Draw the checkbox.""" + draw = wasp.watch.drawable + im = self._im + if self.state: + c1 = wasp.system.theme('slider-default') + c2 = draw.lighten(c1, 15) + fg = c2 + else: + c1 = 0 + c2 = 0 + fg = wasp.system.theme('accent-lo') + # Draw checkbox on the right margin if there is a label, otherwise + # draw at the natural location + x = 239 - 32 - 4 if im[2] else im[0] + draw.blit(icons.checkbox, x, im[1], fg, c1, c2) + + def touch(self, event): + """Handle touch events.""" + y = event[2] + 4 + im = self._im + if y >= im[1] and y < im[1]+40: + self.state = not self.state + self.update() + return True + return False + _SLIDER_KNOB_DIAMETER = const(40) _SLIDER_KNOB_RADIUS = const(_SLIDER_KNOB_DIAMETER // 2) _SLIDER_WIDTH = const(220)