From f280186ccea642d606a85f1a0847fcfcbec11875 Mon Sep 17 00:00:00 2001
From: Sebastian Krzyszkowiak <dos@dosowisko.net>
Date: Mon, 20 Nov 2023 02:57:20 +0100
Subject: [PATCH] py,st3m: Split SunMenu and MainMenu

SunMenu is just a presentation layer that doesn't concern itself with
any kind of logic. It could be simply replaced with (already existing)
SimpleMenu and FlowerMenu or, in the future, may even become customizable
by the user.

Split the main menu's logic into a separate entity that delegates
the presentation to the class it inherits from, like all the other
uses of the menu system.
---
 .../{ui/elements/sun_menu.py => main_menu.py} | 56 +------------------
 python_payload/st3m/run.py                    |  4 +-
 python_payload/st3m/ui/elements/menus.py      | 56 ++++++++++++++++++-
 3 files changed, 59 insertions(+), 57 deletions(-)
 rename python_payload/st3m/{ui/elements/sun_menu.py => main_menu.py} (75%)

diff --git a/python_payload/st3m/ui/elements/sun_menu.py b/python_payload/st3m/main_menu.py
similarity index 75%
rename from python_payload/st3m/ui/elements/sun_menu.py
rename to python_payload/st3m/main_menu.py
index 3110f05c4f..b962754561 100644
--- a/python_payload/st3m/ui/elements/sun_menu.py
+++ b/python_payload/st3m/main_menu.py
@@ -7,14 +7,11 @@ from ctx import Context
 
 from st3m.goose import Optional, List, Set
 from st3m.ui.view import ViewManager, ViewTransitionDirection
-from st3m.ui.elements.visuals import Sun
 from st3m import InputState
 from st3m import settings_menu as settings
-from st3m.utils import lerp
 import st3m.wifi
 from st3m.ui import led_patterns
 from st3m.ui.menu import (
-    MenuController,
     MenuItem,
     MenuItemBack,
     MenuItemForeground,
@@ -27,7 +24,7 @@ from st3m.application import (
     MenuItemAppLaunch,
 )
 from st3m.about import About
-from st3m.ui.elements.menus import SimpleMenu
+from st3m.ui.elements.menus import SimpleMenu, SunMenu
 
 
 class ApplicationMenu(SimpleMenu):
@@ -84,19 +81,8 @@ def _yeet_local_changes() -> None:
     machine.reset()
 
 
-class SunMenu(MenuController):
-    """
-    A circular menu with a rotating sun.
-    """
-
-    __slots__ = (
-        "_ts",
-        "_sun",
-    )
-
+class MainMenu(SunMenu):
     def __init__(self, bundles: Optional[list] = None) -> None:
-        self._ts = 0
-        self._sun = Sun()
         if bundles:
             self._bundles = bundles
         else:
@@ -148,41 +134,3 @@ class SunMenu(MenuController):
         self._items = categories
         # # self._scroll_controller = ScrollController()
         # self._scroll_controller.set_item_count(len(categories))
-
-    def think(self, ins: InputState, delta_ms: int) -> None:
-        super().think(ins, delta_ms)
-        self._sun.think(ins, delta_ms)
-        self._ts += delta_ms
-
-    def _draw_item_angled(
-        self, ctx: Context, item: MenuItem, angle: float, activity: float
-    ) -> None:
-        size = lerp(20, 40, activity)
-        color = lerp(0, 1, activity)
-        if color < 0.01:
-            return
-
-        ctx.save()
-        ctx.translate(-120, 0).rotate(angle).translate(140, 0)
-        ctx.font_size = size
-        ctx.rgba(1.0, 1.0, 1.0, color).move_to(0, 0)
-        item.draw(ctx)
-        ctx.restore()
-
-    def draw(self, ctx: Context) -> None:
-        ctx.gray(0)
-        ctx.rectangle(-120, -120, 240, 240).fill()
-
-        self._sun.draw(ctx)
-
-        ctx.font_size = 40
-        ctx.text_align = ctx.CENTER
-        ctx.text_baseline = ctx.MIDDLE
-
-        angle_per_item = 0.4
-
-        current = self._scroll_controller.current_position()
-
-        for ix, item in enumerate(self._items):
-            rot = (ix - current) * angle_per_item
-            self._draw_item_angled(ctx, item, rot, 1 - abs(rot))
diff --git a/python_payload/st3m/run.py b/python_payload/st3m/run.py
index 15f8fbd721..55e465f074 100644
--- a/python_payload/st3m/run.py
+++ b/python_payload/st3m/run.py
@@ -2,7 +2,7 @@ from st3m.reactor import Reactor, Responder
 from st3m.goose import Optional
 from st3m.ui.elements import overlays
 from st3m.ui.view import View, ViewManager, ViewTransitionBlend
-from st3m.ui.elements.sun_menu import SunMenu
+from st3m.main_menu import MainMenu
 from st3m.application import (
     BundleManager,
     ApplicationContext,
@@ -197,7 +197,7 @@ def run_main() -> None:
             raise Exception(f"Requested bundle {override_main_app} not found")
         run_view(requested[0].load(), debug_vm=True)
     else:
-        menu_main = SunMenu(bundles)
+        menu_main = MainMenu(bundles)
         run_view(menu_main, debug_vm=False)
 
 
diff --git a/python_payload/st3m/ui/elements/menus.py b/python_payload/st3m/ui/elements/menus.py
index 898494ba82..4b2a5d19e7 100644
--- a/python_payload/st3m/ui/elements/menus.py
+++ b/python_payload/st3m/ui/elements/menus.py
@@ -1,5 +1,5 @@
 from st3m.goose import List
-from st3m.ui.elements.visuals import GroupRing, FlowerIcon
+from st3m.ui.elements.visuals import Sun, GroupRing, FlowerIcon
 from st3m.ui.menu import MenuController, MenuItem
 
 from st3m import InputState
@@ -43,6 +43,60 @@ class SimpleMenu(MenuController):
             ctx.restore()
 
 
+class SunMenu(MenuController):
+    """
+    A circular menu with a rotating sun.
+    """
+
+    __slots__ = (
+        "_ts",
+        "_sun",
+    )
+
+    def __init__(self, items: List[MenuItem]) -> None:
+        self._ts = 0
+        self._sun = Sun()
+        super().__init__(items)
+
+    def think(self, ins: InputState, delta_ms: int) -> None:
+        super().think(ins, delta_ms)
+        self._sun.think(ins, delta_ms)
+        self._ts += delta_ms
+
+    def _draw_item_angled(
+        self, ctx: Context, item: MenuItem, angle: float, activity: float
+    ) -> None:
+        size = lerp(20, 40, activity)
+        color = lerp(0, 1, activity)
+        if color < 0.01:
+            return
+
+        ctx.save()
+        ctx.translate(-120, 0).rotate(angle).translate(140, 0)
+        ctx.font_size = size
+        ctx.rgba(1.0, 1.0, 1.0, color).move_to(0, 0)
+        item.draw(ctx)
+        ctx.restore()
+
+    def draw(self, ctx: Context) -> None:
+        ctx.gray(0)
+        ctx.rectangle(-120, -120, 240, 240).fill()
+
+        self._sun.draw(ctx)
+
+        ctx.font_size = 40
+        ctx.text_align = ctx.CENTER
+        ctx.text_baseline = ctx.MIDDLE
+
+        angle_per_item = 0.4
+
+        current = self._scroll_controller.current_position()
+
+        for ix, item in enumerate(self._items):
+            rot = (ix - current) * angle_per_item
+            self._draw_item_angled(ctx, item, rot, 1 - abs(rot))
+
+
 class FlowerMenu(MenuController):
     """
     A circular menu with flowers.
-- 
GitLab