diff --git a/python_payload/st3m/ui/elements/overlays.py b/python_payload/st3m/ui/elements/overlays.py index 8562baf1a3296a2a5e5d8f6374b1c169deb25797..ad245151e179deb5af252eeee0723b43cab266fd 100644 --- a/python_payload/st3m/ui/elements/overlays.py +++ b/python_payload/st3m/ui/elements/overlays.py @@ -11,6 +11,7 @@ from st3m.goose import Dict, Enum, List, ABCBase, abstractmethod, Optional from st3m.utils import tau from st3m.ui.view import ViewManager from st3m.input import power +from st3m.power import approximate_battery_percentage from ctx import Context import st3m.wifi @@ -347,6 +348,8 @@ class Icon(Responder): that contains it. """ + WIDTH: int = 25 + @abstractmethod def visible(self) -> bool: ... @@ -359,6 +362,8 @@ class USBIcon(Icon): Might or might not be related to a certain serial bus. """ + WIDTH: int = 20 + def visible(self) -> bool: return sys_kernel.usb_connected() @@ -378,6 +383,8 @@ class USBIcon(Icon): class WifiIcon(Icon): + WIDTH: int = 15 + def __init__(self) -> None: super().__init__() self._rssi: float = -120 @@ -404,6 +411,50 @@ class WifiIcon(Icon): self._rssi = st3m.wifi.rssi() +class BatteryIcon(Icon): + def __init__(self) -> None: + super().__init__() + self._percent = 100.0 + self._charging = False + + def visible(self) -> bool: + return True + + def draw(self, ctx: Context) -> None: + if self._percent > 30: + ctx.rgb(0.17, 0.55, 0.04) + else: + ctx.rgb(0.52, 0.04, 0.17) + + height = 160 * self._percent / 100 + ctx.rectangle(-80, -50, height, 100) + ctx.fill() + + ctx.gray(0.8) + ctx.line_width = 10.0 + ctx.rectangle(80, -50, -160, 100) + ctx.stroke() + ctx.rectangle(100, -30, -20, 60) + ctx.fill() + + if self._charging: + ctx.gray(1) + ctx.line_width = 20 + ctx.move_to(10, -65 - 10) + ctx.line_to(-30, 20 - 10) + ctx.line_to(30, -20 - 10) + ctx.line_to(-10, 65 - 10) + ctx.line_to(-20, 35 - 10) + ctx.stroke() + ctx.move_to(-10, 65 - 10) + ctx.line_to(40, 35 - 10) + ctx.stroke() + + def think(self, ins: InputState, delta_ms: int) -> None: + self._percent = approximate_battery_percentage(power.battery_voltage) + self._charging = power.battery_charging + + class IconTray(Overlay): """ An overlay which renders Icons. @@ -413,6 +464,7 @@ class IconTray(Overlay): def __init__(self) -> None: self.icons = [ + BatteryIcon(), USBIcon(), WifiIcon(), ] @@ -424,14 +476,16 @@ class IconTray(Overlay): v.think(ins, delta_ms) def draw(self, ctx: Context) -> None: - nicons = len(self.visible) - dist = 25 - width = (nicons - 1) * dist - x0 = width / -2 + if len(self.visible) < 1: + return + width = 0 + for icon in self.visible: + width += icon.WIDTH + x0 = width / -2 + self.visible[0].WIDTH / 2 for i, v in enumerate(self.visible): - x = x0 + i * dist ctx.save() - ctx.translate(x, -100) + ctx.translate(x0, -100) ctx.scale(0.1, 0.1) v.draw(ctx) ctx.restore() + x0 = x0 + v.WIDTH