From 76ffbc759f993750399acb5523dfef2ff22b9d2a Mon Sep 17 00:00:00 2001 From: iggy <iggy@muc.ccc.de> Date: Tue, 13 Jun 2023 11:13:01 +0200 Subject: [PATCH] py: captouch menu rotation and small fixes --- python_payload/apps/flow3r/__init__.py | 60 ++++++++++++++++++--- python_payload/apps/flow3r/menu_main.py | 5 +- python_payload/apps/flow3r/menu_settings.py | 41 +++----------- python_payload/st3m/application.py | 1 + python_payload/st3m/control.py | 1 - python_payload/st3m/event.py | 28 +++++++--- python_payload/st3m/menu.py | 46 ++++++++++++---- python_payload/st3m/ui.py | 8 ++- 8 files changed, 124 insertions(+), 66 deletions(-) diff --git a/python_payload/apps/flow3r/__init__.py b/python_payload/apps/flow3r/__init__.py index 4f18a15a63..d0be5aa665 100644 --- a/python_payload/apps/flow3r/__init__.py +++ b/python_payload/apps/flow3r/__init__.py @@ -1,21 +1,69 @@ -from st3m import logging +import math + +from st3m import logging, event, ui log = logging.Log(__name__, level=logging.INFO) log.info(f"running {__name__}") -from st3m.application import Application -log.info(f"import app") +from st3m.application import Application from . import menu_main -log.info(f"import menu") - class myApp(Application): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.event_input_overlay = event.Event( + name="show input overlay", + group_id="input-overlay", + # condition=lambda d: d['type'] in ["captouch","button"], + condition=lambda d: d["type"] in ["captouch"] and d["value"] == 1, + action=self.update_input_data, + enabled=False, + ) + self.ui_input = ui.Viewport() + for i in range(2): + self.ui_input.add(ui.IconLabel(label="", size=25)) + self.set_input_overlay(False) + def on_init(self): - self.menu = menu_main.get_menu() + self.menu = menu_main.get_menu(self) def on_foreground(self): self.menu.start() + def update_input_data(self, data): + # label = self.ui_input.children[2] + phi = data["angle"] / 600 + # deg = data["angle"]/(2*3.14)*180 + + idx = data["index"] + r = -data["radius"] / 600 + + angle = math.atan2(r, phi) + deg = int(angle / math.pi * 180) + (x, y) = (int(r), int(phi)) # ui.xy_from_polar(r, phi) + + p1 = self.ui_input.children[0] + p1.label = f"{idx} {(x,y)}" + p1.origin = (x, y) + + p2 = self.ui_input.children[1] + p2.label = f"{idx} {deg}" + p2.origin = ui.xy_from_polar(110, angle) + # my_petal.s = f"{idx}: phi{phi:1} r{r:1}" + + # label.label = f"{idx}: {int(x)},{int(y)} r{int(r)} phi{int(phi)}" + # label.label = f"{idx}: {int(x)},{int(y)} angle{angle:1}" + + def set_input_overlay(self, value): + self.event_input_overlay.set_enabled(value) + if value: + event.the_engine.overlay = self.ui_input + else: + event.the_engine.overlay = None + + def get_input_overlay(self): + return self.event_input_overlay.enabled + app = myApp("flow3r", exit_on_menu_enter=False) diff --git a/python_payload/apps/flow3r/menu_main.py b/python_payload/apps/flow3r/menu_main.py index 3378e26721..ac2a47aacf 100644 --- a/python_payload/apps/flow3r/menu_main.py +++ b/python_payload/apps/flow3r/menu_main.py @@ -8,7 +8,8 @@ from apps.flow3r import menu_settings, menu_tinysynth, menu_crazysynth import time -def get_menu(): + +def get_menu(app): menu_main = menu.Menu("flow3r", has_back=False) menu_badge = menu.Menu("badge") menu_apps = menu.Menu("apps") @@ -42,7 +43,7 @@ def get_menu(): menu_main.add(menu.MenuItemSubmenu(menu_badge)) menu_main.add(menu.MenuItemSubmenu(menu_apps)) menu_main.add(menu.MenuItemSubmenu(menu_music)) - menu_main.add(menu.MenuItemSubmenu(menu_settings.get_menu())) + menu_main.add(menu.MenuItemSubmenu(menu_settings.get_menu(app))) menu_music.add(menu.MenuItemSubmenu(menu_tinysynth.get_menu())) menu_music.add(menu.MenuItemSubmenu(menu_crazysynth.get_menu())) diff --git a/python_payload/apps/flow3r/menu_settings.py b/python_payload/apps/flow3r/menu_settings.py index 60d180f7fc..e24783693f 100644 --- a/python_payload/apps/flow3r/menu_settings.py +++ b/python_payload/apps/flow3r/menu_settings.py @@ -2,41 +2,15 @@ from st3m import menu, event, control, ui from st3m.system import audio, hardware -ui_input = ui.Icon("") - - -def render_input_data(data): - ui_input.label = str(data["angle"]) - print("xxx") - ui_input.draw() - - -def set_controls_overlay(value): - print("set_controls_overlay") - if value: - event_input_overlay = event.Event( - name="show input overlay", - group_id="input-overlay", - # condition=lambda d: d['type'] in ["captouch","button"], - condition=lambda d: d["type"] in ["captouch"] and d["value"] == 1, - action=render_input_data, - ) - else: - print("REMOVE") - event.the_engine.remove("input-overlay") - - -def set_volume(value): - db = int(value * 60 - 40) - print("DB", db) - audio.set_volume_dB(db) - - -def get_menu(): +def get_menu(app): m = menu.Menu("settings") control_debug_input = control.ControlSwitch( - name="show inputs", on_set=set_controls_overlay, default=False + name="show inputs", + # TODO (iggy) think about a better way to get our app + on_set=app.set_input_overlay, + on_get=app.get_input_overlay, + default=False, ) item_input_overlay = menu.MenuItemControl("input overlay", control_debug_input) @@ -173,6 +147,3 @@ def get_menu(): m_audio.add(menu.MenuItemSubmenu(m_head)) return m - - -m = get_menu() diff --git a/python_payload/st3m/application.py b/python_payload/st3m/application.py index b5f57c697a..9a6a6ec49d 100644 --- a/python_payload/st3m/application.py +++ b/python_payload/st3m/application.py @@ -131,6 +131,7 @@ class Application: self._set_events(self._events_foreground, False) self.engine.foreground_app = None + menu.menu_back() if self.has_background: self.state = STATE_BACKGROUND self.on_background() diff --git a/python_payload/st3m/control.py b/python_payload/st3m/control.py index 56322afa7d..3ae6a59928 100644 --- a/python_payload/st3m/control.py +++ b/python_payload/st3m/control.py @@ -57,7 +57,6 @@ class Control: class ControlSwitch(Control): def enter(self): self.set_value(not self.get_value()) - self.draw() def scroll(self, delta): self.enter() diff --git a/python_payload/st3m/event.py b/python_payload/st3m/event.py index 6abeac12f8..017526a304 100644 --- a/python_payload/st3m/event.py +++ b/python_payload/st3m/event.py @@ -28,6 +28,7 @@ class Engine: self.is_running = False self.foreground_app = None self.active_menu = None + self.overlay = None self._draw_started = None self._draw_ended = None @@ -41,8 +42,12 @@ class Engine: st = kernel.heap_stats() g = st.general d = st.dma - log.info(f"Heap: General: {g.total_free_bytes:d}B free, {g.total_allocated_bytes:d}B allocated, {g.largest_free_block:d}B largest free block") - log.info(f"Heap: DMA: {d.total_free_bytes:d}B free, {d.total_allocated_bytes:d}B allocated, {d.largest_free_block:d}B largest free block") + log.info( + f"Heap: General: {g.total_free_bytes:d}B free, {g.total_allocated_bytes:d}B allocated, {g.largest_free_block:d}B largest free block" + ) + log.info( + f"Heap: DMA: {d.total_free_bytes:d}B free, {d.total_allocated_bytes:d}B allocated, {d.largest_free_block:d}B largest free block" + ) def _report(self): now = time.ticks_ms() @@ -106,6 +111,7 @@ class Engine: self.next_timed = None def _handle_input(self, delta): + # log.info("input {delta}") input_state = [] # buttons @@ -125,13 +131,12 @@ class Engine: "index": i, "value": hardware.get_captouch(i), "radius": hardware.captouch_get_petal_rad(i), - "angle": hardware.captouch_get_petal_phi(i) / 10000, + "angle": hardware.captouch_get_petal_phi(i), } ) if not self.last_input_state: self.last_input_state = input_state - # tprint (input_state) return for i in range(len(input_state)): @@ -154,7 +159,7 @@ class Engine: triggered_events = list( filter(lambda e: e.enabled and e.condition(entry), self.events_input) ) - # print (triggered_events) + # log.info(triggered_events) # map(lambda e: e.trigger(d), triggered_events) for e in triggered_events: e.trigger(entry) @@ -172,6 +177,8 @@ class Engine: self.foreground_app.draw(ctx) if self.active_menu: self.active_menu.draw(ctx) + if self.overlay: + self.overlay.draw(ctx) self._draw_ended = time.ticks_ms() @@ -196,7 +203,7 @@ class Engine: ctx = None while self.is_running: start = time.ticks_ms() - deadline = start + 20 + deadline = start + 100 self._report() if last_eventloop is not None: @@ -218,6 +225,7 @@ class Engine: if ctx is not None and not hardware.display_pipe_full(): hardware.display_update(ctx) + # log.info("update") ctx = None post_submit = time.ticks_ms() @@ -226,8 +234,12 @@ class Engine: if wait > 0: hardware.freertos_sleep(wait) else: - log.warning(f'Application took too long too process! Slack {wait}ms.') - log.warning(f'Think: {post_think-start}ms, Draw: {post_draw-post_think}ms, Submit: {post_submit-post_draw}ms') + log.warning(f"Application took too long too process! Slack {wait}ms.") + log.warning( + f"Think: {post_think-start}ms, Draw: {post_draw-post_think}ms, Submit: {post_submit-post_draw}ms" + ) + hardware.freertos_sleep(1) + class Event: def __init__( diff --git a/python_payload/st3m/menu.py b/python_payload/st3m/menu.py index 96017c98fb..ee4e0d1dde 100644 --- a/python_payload/st3m/menu.py +++ b/python_payload/st3m/menu.py @@ -1,4 +1,5 @@ from st3m import logging +import math log = logging.Log(__name__, level=logging.INFO) log.info("import") @@ -236,15 +237,41 @@ def on_scroll(d): active_menu.scroll_menu(d["value"] * 10.0 * d["delta"]) +menu_offset = None +last = time.ticks_ms() def on_scroll_captouch(d): active_menu = get_active_menu() if active_menu is None: return + global menu_offset + global last + #if abs(d["radius"]) < 10000: + # return + + a = math.atan2(-d["radius"]/600,d["angle"]/600) + + z = 0 + if d["change"]: + if d["value"] == 1: + z = 1 + else: + z = -1 + + if z==1: + menu_offset = active_menu.angle-a + last = time.ticks_ms() + if z==0: + active_menu.rotate_to(menu_offset+a) + + if z==-1: + diff = time.ticks_diff(time.ticks_ms(),last) + print(diff) + if diff<300: + active_menu.enter_menu() - return - if abs(d["radius"]) < 10000: - return - active_menu.rotate_to(d["angle"] + math.pi) + + + #active_menu.rotate_to(a) def on_release(d): @@ -309,10 +336,11 @@ event.Event( enabled=True, ) -# event.Event(name="menu rotation captouch",group_id="menu", -# condition=lambda e: e["type"] =="captouch" and not e["change"] and abs(e["value"])==1 and e["index"]==2, -# action=on_scroll_captouch, enabled=True -# ) +event.Event(name="menu rotation captouch",group_id="menu", + condition=lambda e: e["type"] =="captouch" and (e["value"] == 1 or e["change"]) and e["index"]==2, + action=on_scroll_captouch, + enabled=True +) event.Event( @@ -330,7 +358,7 @@ event.Event( and (e["value"] == 1 or e["change"]) and e["index"] % 2 == 1, action=on_touch_1d, - enabled=True, + enabled=False, ) event.Event( diff --git a/python_payload/st3m/ui.py b/python_payload/st3m/ui.py index bbb17458b6..a2f8836d65 100644 --- a/python_payload/st3m/ui.py +++ b/python_payload/st3m/ui.py @@ -246,13 +246,11 @@ class IconValue(Icon): ).fill() ctx.rgb(0, 0, 0).move_to(x, y).text(self.label) - self.ctx.move_to(x, y).rgb(*PUSH_RED).arc( - x, y, self.size / 2, -pi, pi, True - ).fill() - self.ctx.move_to(x, y).rgb(*GO_GREEN).arc( + ctx.move_to(x, y).rgb(*PUSH_RED).arc(x, y, self.size / 2, -pi, pi, True).fill() + ctx.move_to(x, y).rgb(*GO_GREEN).arc( x, y, self.size / 2 - 5, v * 2 * pi, 0, 1 ).fill() - self.ctx.rgb(0, 0, 0).move_to(x, y).text(self.label) + ctx.rgb(0, 0, 0).move_to(x, y).text(self.label) class GroupStackedVertical(UIElement): -- GitLab