nimphea/nimphea_ui_core

Search:
Group by:
Source   Edit  

UI Core System

This module wraps libDaisy's UI core system which manages page stacks, event routing, and display management for complex user interfaces.

Features:

  • Page stack management (up to 32 pages)
  • Event routing from UiEventQueue to pages
  • Multiple canvas support (up to 8 displays)
  • Special control ID mapping (OK, Cancel, arrows, encoders, pots)
  • Automatic refresh rate management per canvas
  • Page visibility and focus management
  • Input muting with optional event queuing

Wrapped Header: ui/UI.h

Example - Simple UI with one page:

import nimphea_ui_core
import nimphea_ui_events
import nimphea_menu

# Create event queue
var eventQueue = initUiEventQueue()

# Configure special controls
var controlIds = initUiSpecialControlIds()
controlIds.okBttnId = 0
controlIds.cancelBttnId = 1
controlIds.upBttnId = 2
controlIds.downBttnId = 3

# Create canvas descriptor
var canvas = createCanvasDescriptor(0, displayPtr, 50)

# Initialize UI
var ui = initUI()
ui.init(eventQueue, controlIds, [canvas], 0)

# Add page
ui.openPage(myPage)

# Main loop
while true:
  ui.process()  # Handle events and redraw
  hw.delay(10)

Example - Multi-page menu system:

# Create menu pages
var mainMenu: FullScreenItemMenu
var settingsMenu: FullScreenItemMenu
# ... configure menus ...

# Add main menu
ui.openPage(cast[ptr UiPage](addr mainMenu))

# Later, open settings (adds to stack)
ui.openPage(cast[ptr UiPage](addr settingsMenu))

# Close settings (returns to main)
ui.closePage(cast[ptr UiPage](addr settingsMenu))

Maximum number of pages in the UI stackMaximum number of canvases (displays) supportedInvalid canvas ID constant
Configuration for special button/encoder/pot IDs
Set to INVALID_*_ID constants if control is not available
Main UI coordinator class

Types

CanvasClearFunc = proc (canvas: ptr UiCanvasDescriptor) {.cdecl.}
Source   Edit  
CanvasFlushFunc = proc (canvas: ptr UiCanvasDescriptor) {.cdecl.}
Source   Edit  
UI {.importcpp: "daisy::UI", header: "ui/UI.h".} = object
Source   Edit  
UiSpecialControlIds {.importcpp: "daisy::UI::SpecialControlIds", bycopy.} = object
  funcBttnId* {.importc.}: uint16 ## OK/Enter button ID
  okBttnId* {.importc.}: uint16 ## Cancel/Back button ID
  cancelBttnId* {.importc.}: uint16 ## Up arrow button ID
  upBttnId* {.importc.}: uint16 ## Down arrow button ID
  downBttnId* {.importc.}: uint16 ## Left arrow button ID
  leftBttnId* {.importc.}: uint16 ## Right arrow button ID
  rightBttnId* {.importc.}: uint16 ## Menu navigation encoder ID
  menuEncoderId* {.importc.}: uint16 ## Value editing encoder ID
  valueEncoderId* {.importc.}: uint16 ## Value potentiometer/slider ID
  valuePotId* {.importc.}: uint16
Function button ID (for coarse stepping) Source   Edit  

Consts

INVALID_CANVAS_ID = 65535'u16
Source   Edit  
UI_MAX_PAGES = 32
Source   Edit  

Procs

proc addButtonEvent(eventQueue: var UiEventQueue; ui: var UI; buttonId: uint16;
                    isPressed: bool; numPresses: uint16 = 1;
                    isRetriggering: bool = false) {....raises: [], tags: [],
    forbids: [].}
Helper to add button event to queue Automatically uses correct event type based on state Source   Edit  
proc addEncoderEvent(eventQueue: var UiEventQueue; encoderId: uint16;
                     increments: int16; stepsPerRev: uint16 = 24) {....raises: [],
    tags: [], forbids: [].}
Helper to add encoder rotation event Source   Edit  
proc addPotEvent(eventQueue: var UiEventQueue; potId: uint16; position: cfloat) {.
    ...raises: [], tags: [], forbids: [].}
Helper to add potentiometer movement event Position should be 0.0-1.0 Source   Edit  
proc closePage(this: var UI; page: var UiPage) {.importcpp: "#.ClosePage(@)",
    header: "ui/UI.h", ...raises: [], tags: [], forbids: [].}
Remove page from stack Source   Edit  
proc cppUiInitHelper(ui: ptr UI; eventQueue: var UiEventQueue;
                     controlIds: UiSpecialControlIds;
                     canvases: ptr UiCanvasDescriptor; numCanvases: csize_t;
                     primaryDisplayId: uint16) {.importcpp: "UI_Init_Helper(@)",
    header: "ui/UI.h", ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc createCanvasDescriptor(id: uint8; handle: pointer; updateRateMs: uint32;
                            clearFunc: CanvasClearFunc = nil;
                            flushFunc: CanvasFlushFunc = nil;
                            screenSaverTimeout: uint32 = 0): UiCanvasDescriptor {.
    ...raises: [], tags: [], forbids: [].}

Create a canvas descriptor

Parameters:

  • id - Unique canvas ID
  • handle - Pointer to display object (cast to specific type in Draw)
  • updateRateMs - Refresh rate in milliseconds
  • clearFunc - Optional function to clear display before drawing
  • flushFunc - Optional function to flush/update display after drawing
  • screenSaverTimeout - Timeout in ms before screensaver (0=disabled)
Source   Edit  
proc getPrimaryOneBitGraphicsDisplayId(this: var UI): uint16 {.
    importcpp: "#.GetPrimaryOneBitGraphicsDisplayId()", header: "ui/UI.h",
    ...raises: [], tags: [], forbids: [].}
Get canvas ID of primary graphics display Returns INVALID_CANVAS_ID if none configured Source   Edit  
proc getSpecialControlIds(this: var UI): UiSpecialControlIds {.
    importcpp: "#.GetSpecialControlIds()", header: "ui/UI.h", ...raises: [],
    tags: [], forbids: [].}
Get special control ID configuration Source   Edit  
proc init(this: var UI; eventQueue: var UiEventQueue;
          controlIds: UiSpecialControlIds;
          canvases: openArray[UiCanvasDescriptor];
          primaryDisplayId: uint16 = INVALID_CANVAS_ID) {.inline,
    header: "ui/UI.h", ...raises: [], tags: [], forbids: [].}

Initialize UI system

Parameters:

  • eventQueue - UiEventQueue to read input events from
  • controlIds - Special control ID configuration
  • canvases - Array of canvas descriptors for displays
  • primaryDisplayId - Canvas ID for primary display (menus, etc.)
Source   Edit  
proc initUI(): UI {.importcpp: "daisy::UI()", header: "ui/UI.h", ...raises: [],
                    tags: [], forbids: [].}
Create new UI instance Source   Edit  
proc initUiSpecialControlIds(): UiSpecialControlIds {.
    importcpp: "daisy::UI::SpecialControlIds()", header: "ui/UI.h", ...raises: [],
    tags: [], forbids: [].}
Create SpecialControlIds with all IDs set to invalid Source   Edit  
proc initUiWithDefaults(eventQueue: var UiEventQueue;
                        okButton: uint16 = INVALID_BUTTON_ID;
                        cancelButton: uint16 = INVALID_BUTTON_ID;
                        upButton: uint16 = INVALID_BUTTON_ID;
                        downButton: uint16 = INVALID_BUTTON_ID): UI {.
    ...raises: [], tags: [], forbids: [].}

Create and initialize UI with common button configuration

Sets up a basic UI with optional OK, Cancel, Up, Down buttons. Other controls default to invalid IDs.

Source   Edit  
proc mute(this: var UI; shouldBeMuted: bool; queueEvents: bool = false) {.
    importcpp: "#.Mute(@)", header: "ui/UI.h", ...raises: [], tags: [], forbids: [].}

Mute/unmute user input processing

Parameters:

  • shouldBeMuted - true to mute, false to unmute
  • queueEvents - If true, queue events while muted; if false, discard them
Source   Edit  
proc openPage(this: var UI; page: var UiPage) {.importcpp: "#.OpenPage(@)",
    header: "ui/UI.h", ...raises: [], tags: [], forbids: [].}
Add page to top of page stack Page must remain alive until removed from UI Source   Edit  
proc process(this: var UI) {.importcpp: "#.Process()", header: "ui/UI.h",
                             ...raises: [], tags: [], forbids: [].}
Process events and update displays Call this regularly from main loop (low priority context) Source   Edit