Initial commit of the prototype code base.
This commit is contained in:
commit
c26f9dbc35
172
__init__.py
Normal file
172
__init__.py
Normal file
@ -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()))
|
13
flow3r.toml
Normal file
13
flow3r.toml
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user