diff --git a/python_payload/apps/cap_touch_demo.py b/python_payload/apps/cap_touch_demo.py index b7006f60a39ae882dcdc58a4131b197d9a66ff6e..c1d9c89eb7e8f2220c7fce0edfe03ff358e90cd0 100644 --- a/python_payload/apps/cap_touch_demo.py +++ b/python_payload/apps/cap_touch_demo.py @@ -7,9 +7,8 @@ import cmath import math import time -import captouch - -from st3m import utils, application, ui, event +import hardware +from st4m import application class Dot: @@ -32,24 +31,26 @@ class Dot: class CapTouchDemo(application.Application): - def on_init(self): + def __init__(self, name): + super().__init__(name) self.dots = [] self.last_calib = None - self.ui_autocalib = ui.IconLabel("Autocalib done", size=30) - - self.add_event( - event.Event( - name="captouch_autocalib", - action=self.do_autocalib, - condition=lambda data: data["type"] == "button" - and data["index"] == 0 - and data["change"] - and data["from"] == 2, - enabled=True, - ) - ) - - def main_foreground(self): + # self.ui_autocalib = ui.IconLabel("Autocalib done", size=30) + + # self.add_event( + # event.Event( + # name="captouch_autocalib", + # action=self.do_autocalib, + # condition=lambda data: data["type"] == "button" + # and data["index"] == 0 + # and data["change"] + # and data["from"] == 2, + # enabled=True, + # ) + # ) + + def think(self, ins: InputState, delta_ms: int) -> None: + super().think(ins, delta_ms) self.dots = [] cps = captouch.read() for i in range(10): @@ -65,13 +66,17 @@ class CapTouchDemo(application.Application): self.dots.append(Dot(size, x.imag, x.real)) - def on_draw(self, ctx): + def draw(self, ctx): + # print(self.last_calib) + + # TODO (q3k) bug: we have to do this, otherwise we have horrible blinking + ctx.rgb(1, 1, 1) + ctx.rgb(0, 0, 0).rectangle(-120, -120, 240, 240).fill() - for i, dot in enumerate(self.dots): dot.draw(i, ctx) - if not self.last_calib is None and self.last_calib > 0: - self.last_calib -= 1 - self.ui_autocalib.draw(ctx) + # if not self.last_calib is None and self.last_calib > 0: + # self.last_calib -= 1 + # self.ui_autocalib.draw(ctx) def do_autocalib(self, data): log.info("Performing captouch autocalibration") diff --git a/python_payload/apps/demo_worms4.py b/python_payload/apps/demo_worms4.py index 4f2e8766719ee90c9f8c5c4fc072ce7cd39a2c47..74261e3a9f8756bd2ff61f89548c40b4a7df64c2 100644 --- a/python_payload/apps/demo_worms4.py +++ b/python_payload/apps/demo_worms4.py @@ -44,10 +44,23 @@ class AppWorms(application.Application): self.just_shown = True def draw(self, ctx): - if self.bufn == 0 or self.bufn == 1: + if self.bufn <= 5: + # TODO (q3k) bug: we have to do this, otherwise we have horrible blinking + + ctx.rgb(*ui.BLUE).rectangle( + -ui.WIDTH / 2, -ui.HEIGHT / 2, ui.WIDTH, ui.HEIGHT + ).fill() + ctx.rgb(1, 1, 1) + ctx.rgb(*ui.BLUE).rectangle( -ui.WIDTH / 2, -ui.HEIGHT / 2, ui.WIDTH, ui.HEIGHT ).fill() + ctx.rgb(1, 1, 1) + + ctx.rgb(*ui.BLUE).rectangle( + -ui.WIDTH / 2, -ui.HEIGHT / 2, ui.WIDTH, ui.HEIGHT + ).fill() + ctx.text_align = ctx.CENTER ctx.text_baseline = ctx.MIDDLE ctx.move_to(0, 0).rgb(*ui.WHITE).text("touch me :)") @@ -63,10 +76,10 @@ class AppWorms(application.Application): super().think(ins, delta_ms) # Simulation is currently locked to FPS. - if self.bufn > 3: + if self.bufn > 7: for w in self.worms: w.move() - self.bufn = 2 + self.bufn = 6 for index, petal in enumerate(self.input.captouch.petals): if petal.pressed or petal.repeated: self.worms.append(Worm(tau * index / 10 + math.pi)) @@ -74,7 +87,7 @@ class AppWorms(application.Application): def handle_input(self, data): worms = self.worms worms.append(Worm(data.get("index", 0) * 2 * math.pi / 10 + math.pi)) - if len(worms) > 10: + while len(worms) > 10: worms.pop(0) diff --git a/python_payload/apps/harmonic_demo.py b/python_payload/apps/harmonic_demo.py index f62e963e4f0a21c8a6a7fac7ae2b16d47bf38007..ec9ac5305bbc24e2a16b92129b13f7874000fa31 100644 --- a/python_payload/apps/harmonic_demo.py +++ b/python_payload/apps/harmonic_demo.py @@ -3,7 +3,6 @@ from hardware import * import captouch import leds - chords = [ [-4, 0, 3, 8, 10], [-3, 0, 5, 7, 12], @@ -13,11 +12,13 @@ chords = [ ] -from st3m.application import Application +from st4m.application import Application class HarmonicApp(Application): - def on_init(self): + def __init__(self, name): + super().__init__(name) + self.color_intensity = 0 self.chord_index = None self.chord = None @@ -52,10 +53,7 @@ class HarmonicApp(Application): self.chord = chords[i] leds.update() - def on_foreground(self): - pass - - def on_draw(self, ctx): + def draw(self, ctx): i = self.color_intensity ctx.rgb(i, i, i).rectangle(-120, -120, 240, 240).fill() @@ -63,7 +61,8 @@ class HarmonicApp(Application): scope_draw(ctx) ctx.fill() - def main_foreground(self): + def think(self, ins: InputState, delta_ms: int) -> None: + super().think(ins, delta_ms) if self.color_intensity > 0: self.color_intensity -= self.color_intensity / 20 cts = captouch.read() diff --git a/python_payload/apps/melodic_demo.py b/python_payload/apps/melodic_demo.py index ce7dce09cd907bcf28fea27e14a81f59aaeed56d..c1496508385418ecfd5bbd649cc5a2c34c897222 100644 --- a/python_payload/apps/melodic_demo.py +++ b/python_payload/apps/melodic_demo.py @@ -75,23 +75,25 @@ def foreground(): adjust_playing_field_to_octave() -from st3m.application import Application +from st4m.application import Application class MelodicApp(Application): - def on_init(self): + def __init__(self, name): + super().__init__(name) init() - def on_draw(self, ctx): + def draw(self, ctx): ctx.rgb(1, 1, 1).rectangle(-120, -120, 240, 240).fill() ctx.rgb(0, 0, 0) scope_draw(ctx) ctx.fill() - def on_foreground(self): + def on_enter(self): foreground() - def main_foreground(self): + def think(self, ins: InputState, delta_ms: int) -> None: + super().think(ins, delta_ms) run() diff --git a/python_payload/apps/nick.py b/python_payload/apps/nick.py new file mode 100644 index 0000000000000000000000000000000000000000..fcfbcba50988259a6d0e14a181f1859d88a1f77c --- /dev/null +++ b/python_payload/apps/nick.py @@ -0,0 +1,57 @@ +from st4m.application import Application +from st4m.property import PUSH_RED, GO_GREEN, BLACK +import leds + + +class NickApp(Application): + def __init__(self, name): + super().__init__(name) + self._nick = self._read_nick_from_file() + self._scale = 1 + self._dir = 1 + self._led = 0.0 + + def draw(self, ctx): + ctx.text_align = ctx.CENTER + ctx.text_baseline = ctx.MIDDLE + ctx.font_size = 75 + ctx.font = ctx.get_font_name(5) + + # TODO (q3k) bug: we have to do this, otherwise we have horrible blinking + ctx.rgb(1, 1, 1) + + # TODO (q3k) bug: we have to do this two times, otherwise we have horrible blinking + ctx.rgb(0, 0, 0).rectangle(-120, -120, 240, 240).fill() + ctx.rgb(*GO_GREEN) + + ctx.move_to(0, 0) + ctx.save() + ctx.scale(self._scale, 1) + ctx.text(self._nick) + ctx.restore() + + leds.set_hsv(int(self._led), abs(self._scale) * 360, 1, 0.2) + + leds.update() + # ctx.fill() + + def on_enter(self): + super().on_enter() + + def think(self, ins: InputState, delta_ms: int) -> None: + super().think(ins, delta_ms) + + self._scale += delta_ms / 1000 * self._dir + + if abs(self._scale) > 1 and self._scale * self._dir > 0: + self._dir *= -1 + + self._led += delta_ms / 45 + if self._led >= 40: + self._led = 0 + + def _read_nick_from_file(self): + return "iggy" + + +app = NickApp("nick") diff --git a/python_payload/main.py b/python_payload/main.py index 405c4abfada62eb0fe378bed4cedf15c62b04553..c4aeba5a2187deb77fd8c25a3d91ff32b280c984 100644 --- a/python_payload/main.py +++ b/python_payload/main.py @@ -18,7 +18,7 @@ from st4m.ui.menu import ( MenuItemNoop, ) -from st4m.ui.elements.menus import FlowerMenu, SimpleMenu +from st4m.ui.elements.menus import FlowerMenu, SimpleMenu, SunMenu log.info("import apps done") log.info(f"free memory: {gc.mem_free()}") @@ -32,35 +32,60 @@ log.info("calibrating captouch, reset volume") captouch.calibration_request() audio.set_volume_dB(0) +import leds + +leds.set_rgb(0, 255, 0, 0) + vm = ViewManager(ViewTransitionBlend()) -menu_music = SimpleMenu( + +from apps.demo_worms4 import app as worms + +from apps.harmonic_demo import app as harmonic +from apps.melodic_demo import app as melodic +from apps.nick import app as nick +from apps.cap_touch_demo import app as captouch + + +# Set the view_managers for the apps, otherwise leaving the app (back) will not work +worms._view_manager = vm +harmonic._view_manager = vm +melodic._view_manager = vm +nick._view_manager = vm +captouch._view_manager = vm + +menu_music = SunMenu( [ MenuItemBack(), - MenuItemNoop("Harmonic"), - MenuItemNoop("Melodic"), - MenuItemNoop("TinySynth"), - MenuItemNoop("CrazySynth"), - MenuItemNoop("Sequencer"), + MenuItemForeground("Harmonic", harmonic), + MenuItemForeground("Melodic", melodic), + # MenuItemNoop("TinySynth"), + # MenuItemNoop("CrazySynth"), + MenuItemNoop("NOOP Sequencer"), ], vm, ) -from apps.demo_worms4 import app as worms - -worms._view_manager = vm -menu_apps = SimpleMenu( +menu_apps = SunMenu( [ MenuItemBack(), - MenuItemNoop("captouch"), + MenuItemForeground("captouch", captouch), MenuItemForeground("worms", worms), ], vm, ) -menu_main = FlowerMenu( +menu_badge = SunMenu( + [ + MenuItemBack(), + MenuItemForeground("nick", nick), + ], + vm, +) +menu_main = SunMenu( [ + MenuItemForeground("Badge", menu_badge), MenuItemForeground("Music", menu_music), MenuItemForeground("Apps", menu_apps), MenuItemNoop("Settings"), @@ -68,114 +93,6 @@ menu_main = FlowerMenu( vm, ) - -from st4m.input import PetalController -import math - - -from st3m.system import hardware - - -class PetalResponder(st4m.Responder): - def __init__(self): - self.petal = PetalController(0) - self.ts = 0.0 - self._last = "" - self.speed = 0.0 - self.value = 0.0 - self.speedbuffer = [0.0] - self._ignore = 0 - - def think(self, ins: InputState, delta_ms: int) -> None: - self.ts += delta_ms - self.petal.think(ins, delta_ms) - - if self._ignore: - self._ignore -= 1 - return - - dx = self.petal._input._dx - dphi = self.petal._input._dphi - - phase = self.petal._input.phase() - speed = sum(self.speedbuffer) / len(self.speedbuffer) - if abs(speed) < 0.00001: - speed = 0 - - max = 50 - - if speed > max: - speed = max - if speed < -max: - speed = -max - - if len(self.speedbuffer) > 10: - self.speedbuffer.pop(0) - - if phase == self.petal._input.ENDED: - self.speedbuffer = [0 if abs(speed) < 0.001 else speed] - elif phase == self.petal._input.UP: - self.speedbuffer.append(speed * 0.85) - elif phase == self.petal._input.BEGIN: - self._ignore = 5 - self.speedbuffer = [0.0] - elif phase == self.petal._input.RESTING: - self.speedbuffer.append(0.0) - elif phase == self.petal._input.MOVED: - self.speedbuffer.append(dphi / delta_ms) - # self.speed *= 0.3 - - # print(speed, phase, self.speedbuffer) - - self.value += speed * delta_ms - self.speed = speed - - def draw(self, ctx: Ctx) -> None: - tau = math.pi * 2 - - dx = self.petal._input._dx - dy = self.petal._input._dy - - sum = abs(dx) + abs(dy) - pos = self.petal._input._pos - # ang = -math.atan2(*pos) - tau / 6 * 2 - ang = self.value - p = self.petal._input.phase() - self._last = p - # if p == "up" and self._last != "up": - # print(p) - # if p != "up" and p != "resting": - # print(p, dx, dy, sum, ang) - - ctx.gray(0) - ctx.rectangle(-120, -120, 240, 240).fill() - - ctx.text_align = ctx.CENTER - ctx.text_baseline = ctx.MIDDLE - ctx.font_size = 20 - ctx.gray(1) - # ctx.rectangle(-20, -20, 40, 40).fill() - ctx.move_to(0, 0).text(p) - ctx.move_to(0, 60).text(f"value: {self.value:.2f}") - - dir = "stop" - if self.speed > 0: - dir = "ccw" - if self.speed < 0: - dir = "cw" - - ctx.move_to(0, 90).text(f"{dir}: {self.speed*1000:.2f}") - - # if p != "up": - ctx.rectangle(math.sin(ang) * 100, math.cos(ang) * 100, 20, 20).fill() - - (r, phi) = self.petal._input._polar - p = (math.sin(phi) * r, math.cos(phi) * r) - - ctx.rgb(1, 0, 0).rectangle(p[0], p[1], 10, 10).fill() - - -pr = PetalResponder() vm.push(menu_main) reactor = st4m.Reactor()