summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorFrancesco Gazzetta <fgaz@fgaz.me>2021-09-20 14:09:47 (GMT)
committerDaniel Thompson <daniel.thompson@linaro.org>2021-11-17 15:29:08 (GMT)
commit0eabf0f109c2277c527c334b2b84eec2afec310b (patch)
tree35d4d71a0660ea182542b6a0c6006496b0188a21 /apps
parent0854adb630cc3e13d696435a0cccf79c68edf5e5 (diff)
Remove morse from default apps
Even after optimizing it, it makes the image 224 bytes too big. Signed-off-by: Francesco Gazzetta <fgaz@fgaz.me>
Diffstat (limited to 'apps')
-rw-r--r--apps/Morse.py136
1 files changed, 136 insertions, 0 deletions
diff --git a/apps/Morse.py b/apps/Morse.py
new file mode 100644
index 0000000..11c3aa5
--- /dev/null
+++ b/apps/Morse.py
@@ -0,0 +1,136 @@
+# SPDX-License-Identifier: LGPL-3.0-or-later
+# Copyright (C) 2021 Francesco Gazzetta
+
+"""Morse translator and notepad
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This app is a simple morse translator that also doubles as a notepad.
+Swipe up for a line, swipe down for a dot, tap for end letter, double tap for
+end word.
+Up to 7 lines of translation will be displayed on a 240x240 screen, and old
+lines will be deleted.
+There is a preview of the next letter at the bottom of the screen.
+
+
+.. figure:: res/MorseApp.png
+ :width: 179
+"""
+
+import wasp
+import icons
+import fonts
+from math import floor
+from micropython import const
+
+
+_WIDTH = const(240)
+_HEIGHT = const(240)
+# No easy way to make this depend on _WIDTH
+_MAXINPUT = const(16)
+
+# These two need to match
+_FONTH = const(24)
+_FONT = fonts.sans24
+
+# Precomputed for efficiency
+_LINEH = const(30) # int(_FONTH * 1.25)
+_MAXLINES = const(7) # floor(_HEIGHT / _LINEH) - 1 # the "-1" is the input line
+
+# The morse lookup table, represented as a flattened binary tree.
+# The head is the value of the node, the tail are the subtrees:
+# left half of the tail = the next symbol is a dot
+# right half of the tail = the next symbol is a line
+_CODE = " EISH54V?3UF????2ARL?????WP??J?1TNDB6?X??KC??Y??MGZ7?Q??O?8??90"
+# Or, letters only:
+#_CODE = " EISHVUF?ARL?WPJTNDBXKCYMGZQO??"
+
+class MorseApp():
+ NAME = 'Morse'
+ # 2-bit RLE, 96x64, generated from res/morse_icon.png, 143 bytes
+ ICON = (
+ b'\x02'
+ b'`@'
+ b'?\xff\xff\xff\xff\x13\xc4?\x1c\xc6?\x1b\xc6?\x1b\xc6'
+ b'?\x1a\xc8?\x19\xc8?\x18\xca?\x17\xc4\x02\xc4?\x17'
+ b'\xc4\x02\xc4?\x16\xc5\x02\xc5?\x15\xc4\x04\xc4?\x15\xc4'
+ b'\x04\xc4?\x14\xc4\x06\xc4?\x13\xc4\x06\xc4?\x12\xc5\x06'
+ b'\xc5?\x11\xc4\x08\xc4?\x11\xd0?\x10\xd2?\x0f\xd2?'
+ b'\x0e\xc5\n\xc4?\x0e\xc4\x0c\xc4?\r\xc4\x0c\xc4?\x0c'
+ b'\xc5\x0c\xc5?\x0b\xc4\x0e\xc4?\x0b\xc4\x0e\xc4?\n\xc4'
+ b'\x10\xc4?\xff\xff\xff\xff\x83\xc4\x0e\xda4\xc4\x0e\xda4'
+ b'\xc4\x0e\xda4\xc4\x0e\xda?\xff\xff\xff\xfe'
+ )
+
+ def __init__(self):
+ self.letter = ""
+ self.text = [""]
+ pass
+
+ def foreground(self):
+ self._draw()
+ wasp.system.request_event(wasp.EventMask.TOUCH |
+ wasp.EventMask.SWIPE_UPDOWN)
+
+ def swipe(self, event):
+ if len(self.letter) < _MAXINPUT:
+ self.letter += "-" if event[0] == wasp.EventType.UP else "."
+ self._update()
+
+ def touch(self, event):
+ addition = self._lookup(self.letter)
+ self.letter = ""
+ merged = self.text[-1] + addition
+ # Check if the new text overflows the screen and add a new line if that's the case
+ split = wasp.watch.drawable.wrap(merged, _WIDTH)
+ if len(split) > 2:
+ self.text.append(self.text[-1][split[1]:split[2]] + addition)
+ self.text[-2] = self.text[-2][split[0]:split[1]]
+ if len(self.text) > _MAXLINES:
+ self.text.pop(0)
+ # Ideally a full refresh should be done only when we exceed
+ # _MAXLINES, but this should be fast enough
+ self._draw()
+ else:
+ self.text[-1] = merged
+ self._update()
+
+ def _draw(self):
+ """Draw the display from scratch"""
+ draw = wasp.watch.drawable
+ draw.fill()
+ i = 0
+ for line in self.text:
+ draw.string(line, 0, _LINEH * i)
+ i += 1
+ self._update()
+
+ def _update(self):
+ """Update the dynamic parts of the application display, specifically the
+ input line and last line of the text.
+ The full text area is updated in _draw() instead."""
+ draw = wasp.watch.drawable
+ draw.string(self.text[-1], 0, _LINEH*(len(self.text)-1))
+ guess = self._lookup(self.letter)
+ draw.string("{} {}".format(self.letter, guess), 0, _HEIGHT - _FONTH, width=_WIDTH)
+
+ def _lookup(self, s):
+ i = 0 # start of the subtree (current node)
+ l = len(_CODE) # length of the subtree
+
+ for c in s:
+ # first discard the head, which represent the previous guess
+ i += 1
+ l -= 1
+
+ # Check if we can no longer bisect while there are still dots/lines
+ if l <= 0: return "?"
+
+ # Update the bounds to the appropriate subtree
+ # (left or right of the tail).
+ # The length will always be half:
+ l //= 2
+ # The index will be either at the beginning of the tail,
+ # or at its half, in which case we subtract the current length,
+ # which is half of the old length:
+ if c == "-": i += l
+ return _CODE[i]