libstp.ui ========= .. py:module:: libstp.ui .. autoapi-nested-parse:: BotUI - Dynamic UI system for robotics applications. This module provides a type-safe, event-driven system for creating UI screens in Python that are rendered by Flutter. Architecture: - UIScreen: Self-contained screens with their own events and state - UIStep: Steps that orchestrate which screens to show - Widgets: Type-safe dataclasses that serialize to JSON for Flutter ================================================================================ QUICK START - Simple one-liners (recommended for most cases) ================================================================================ class MyStep(UIStep): async def _execute_step(self, robot): # Show a message await self.message("Calibration complete!") # Ask for confirmation if await self.confirm("Start calibration?"): await self.do_calibration() # Get a number distance = await self.input_number("Enter distance:", unit="cm") # Let user choose mode = await self.choose("Select mode:", ["Fast", "Normal", "Precise"]) # Wait for button press await self.wait_for_button("Position robot and press button") ================================================================================ BLOCKING MODE - Show screen, wait for result ================================================================================ class MyStep(UIStep): async def _execute_step(self, robot): # Show screen and wait for it to close result = await self.show(MyScreen()) ================================================================================ NON-BLOCKING MODE - UI + background logic together ================================================================================ class MyStep(UIStep): async def _execute_step(self, robot): # Option 1: Context manager (recommended) async with self.showing(ProgressScreen()) as ctx: for i in range(100): ctx.screen.progress = i await ctx.screen.refresh() await asyncio.sleep(0.1) # Option 2: Manual display + pump await self.display(StatusScreen("Processing...")) for i in range(100): await self.pump_events() # Handle UI events await asyncio.sleep(0.1) await self.close_ui() # Option 3: Run task with UI result = await self.run_with_ui( LoadingScreen("Calibrating..."), self.do_calibration ) ================================================================================ CUSTOM SCREENS - Full control ================================================================================ class MyCustomScreen(UIScreen[bool]): title = "Custom" def __init__(self, message: str): super().__init__() self.message = message def build(self) -> Widget: return Center(children=[ Text(self.message, size="large"), Button("ok", "OK", style="success"), ]) @on_click("ok") async def on_ok(self): self.close(True) Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/libstp/ui/events/index /autoapi/libstp/ui/raccoon/index /autoapi/libstp/ui/screen/index /autoapi/libstp/ui/screens/index /autoapi/libstp/ui/step/index /autoapi/libstp/ui/widgets/index