commit c26f9dbc35f1d06f4bf799e62948c5dd4a897cd3 Author: Anna_updn Date: Fri Aug 18 15:45:06 2023 +0200 Initial commit of the prototype code base. diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..0506fcc --- /dev/null +++ b/__init__.py @@ -0,0 +1,172 @@ +from st3m.application import Application, ApplicationContext +from st3m.ui.colours import PUSH_RED, GO_GREEN, BLACK, WHITE +from st3m.goose import Dict, Any +from st3m.input import InputState +from ctx import Context +import leds +import captouch + +import json +import math + + +class Configuration: + def __init__(self) -> None: + # Add up to 5 items with custom header + self.hdrs: list = ['name', 'handel', 'lang', 'pronouns', 'empty'] + self.strs: list = ['flow3r', '', 'noLang', '', ''] + self.size: int = 75 + self.font: int = 5 + self.colour: int = 0 # (0.5, 0.5, 0.5) # index or tuple + self.delay: int = 8 + + @classmethod + def load(cls, path: str) -> "Configuration": + res = cls() + #return res # for debug + try: + with open(path) as f: + jsondata = f.read() + data = json.loads(jsondata) + except OSError: + data = {} + for i in range(len(res.hdrs)): + hdr = res.hdrs[i] + if hdr in data and type(data[hdr]) == str: + res.strs[i] = data[hdr] + if "delay" in data and type(data["delay"]) == int: + res.delay = data["delay"] + if "size" in data: + if type(data["size"]) == float: + res.size = int(data["size"]) + if type(data["size"]) == int: + res.size = data["size"] + if "font" in data and type(data["font"]) == int: + res.font = data["font"] + if "color" in data: + if type(data["color"]) == int: + res.colour = data["color"] + if type(data["color"]) == str and len(data["color"]) == 7 and data["color"][0] == '#': + res.colour = ( + int(data["color"][1:3], 16)/256.0, + int(data["color"][3:5], 16)/256.0, + int(data["color"][5:], 16)/256.0 + ) + return res + + def save(self, path: str) -> None: + d = { + "size": self.size, + "font": self.font, + "color": self.colour if type(self.colour) == int else 0, + "delay": self.delay, + } + for i in range(len(self.hdrs)): + d[self.hdrs[i]] = self.strs[i] + jsondata = json.dumps(d) + with open(path, "w") as f: + f.write(jsondata) + f.close() + + +class SensibleNickApp(Application): + state: int = 0 + since_state_change: int = 0 + + def __init__(self, app_ctx: ApplicationContext) -> None: + super().__init__(app_ctx) + self._scale = 1.0 + self._led = 0.0 + self._led_bg = BLACK + self._phase = 0.0 + self._en_scale = False + self._en_scale_pressed = False + self._en_iter = True + self._en_iter_pressed = False + self._filename = "/flash/nick.json" + self._config = Configuration.load(self._filename) + self._colours: list = [GO_GREEN, PUSH_RED, WHITE] + if type(self._config.colour) == int: + self._en_colour = self._config.colour + else: + self._colours[2] = self._config.colour + self._en_colour = 2 + self.varprint: list(str) = [str for str in self._config.strs if len(str) > 0] + + def draw(self, ctx: Context) -> None: + ctx.text_align = ctx.CENTER + ctx.text_baseline = ctx.MIDDLE + #ctx.font_size = self._config.size + ctx.font = ctx.get_font_name(self._config.font) + + ctx.rgb(*BLACK).rectangle(-120, -120, 240, 240).fill() + ctx.rgb(*self._colours[self._en_colour]) + ctx.move_to(0, 0) + ctx.save() + if not self._en_scale: + ctx.scale(1.0, 1) + else: + ctx.scale(self._scale, 1) + ctx.font_size = 100 + pre = ctx.text_width(self.varprint[self.state]) + ctx.font_size = 98*240/pre + if ctx.font_size > 150: + ctx.font_size = 150 + post = ctx.text_width(self.varprint[self.state]) + ctx.text(self.varprint[self.state]) + ctx.restore() + + leds.set_all_rgb(*self._led_bg) + leds.set_hsv(int(self._led), abs(self._scale) * 360, 1, 1.0) + + leds.update() + #ctx.fill() + + def on_exit(self) -> None: + self._config.save(self._filename) + + def think(self, ins: InputState, delta_ms: int) -> None: + super().think(ins, delta_ms) + + self._phase += delta_ms / 900 + self._scale = math.sin(self._phase) + self._led += delta_ms / 100 + if self._led >= 40: + self._led = 0 + self.since_state_change += delta_ms + if (self.since_state_change / 1000) > self._config.delay: + self.since_state_change = 0 + if self._en_iter: + self.state += 1 + if self.state >= len(self.varprint): + self.state = 0 + + petals = captouch.read().petals + for i in range(5): + if petals[2*i].pressed and i < len(self.varprint): + self.state = i + self.since_state_change = 0 + + for i in range(3): + if petals[2*i+3].pressed: + self._en_colour = i + + if petals[1].pressed: + if not self._en_iter_pressed: + self._en_iter = not self._en_iter + self._led_bg = GO_GREEN if self._en_iter else PUSH_RED + elif petals[9].pressed: + if not self._en_scale_pressed: + self._en_scale = not self._en_scale + self._phase = 0.0 + self._led_bg = GO_GREEN if self._en_scale else PUSH_RED + else: + self._led_bg = BLACK + self._en_iter_pressed = petals[1].pressed + self._en_scale_pressed = petals[9].pressed + +# For running with `mpremote run`: +if __name__ == "__main__": + import st3m.run + + st3m.run.run_view(SensibleNickApp(ApplicationContext())) diff --git a/flow3r.toml b/flow3r.toml new file mode 100644 index 0000000..1e05f67 --- /dev/null +++ b/flow3r.toml @@ -0,0 +1,13 @@ +[app] +name = "SensibleNick" +menu = "Badge" + +[entry] +class = "SensibleNickApp" + +[metadata] +author = "Anna_updn, Flow3r Badge Authors" +license = "LGPL-3.0-only" +url = "https://git.flow3r.garden/updn/sensiblenickapp" +description = "A sensible nickname app using touch to show up to 5 strings with some quality of life features." +version = 1