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