UI Event Queue System
This module wraps libDaisy's UI event queue system for handling user input events. The event queue is thread-safe (uses ScopedIrqBlocker) and can be safely accessed from interrupt handlers.
Features:
- Button press/release events with double-click detection
- Encoder rotation events with increment tracking
- Potentiometer/slider movement events
- Activity tracking (user started/stopped interaction)
- Thread-safe FIFO queue (256 event capacity)
Wrapped Header: ui/UiEventQueue.h
Example - Basic event processing:
import nimphea_ui_events var eventQueue = initUiEventQueue() # In button interrupt handler: eventQueue.addButtonPressed(0, 1, false) # button 0, single press # In main loop: while not eventQueue.isQueueEmpty(): var evt = eventQueue.getAndRemoveNextEvent() if evt.eventType == EventType.buttonPressed: echo "Button ", evt.asButtonPressed.id, " pressed"
Example - Double-click detection:
var evt = eventQueue.getAndRemoveNextEvent() if evt.eventType == EventType.buttonPressed: if evt.asButtonPressed.numSuccessivePresses == 2: echo "Double click detected!"
Example - Encoder events:
var evt = eventQueue.getAndRemoveNextEvent() if evt.eventType == EventType.encoderTurned: let increments = evt.asEncoderTurned.increments echo "Encoder turned ", increments, " steps"Invalid button ID constantInvalid encoder ID constantInvalid potentiometer ID constantEvent type enumerationActivity state for controlsEvent structure - wraps C++ Event with union Access the union field based on eventType (e.g. evt.asButtonPressed.id)UI Event Queue
Types
ActivityType {.importcpp: "daisy::UiEventQueue::Event::ActivityType", size: 1.} = enum inactive, ## Control is actively being used active
- Control is not being used Source Edit
ButtonPressedData {.bycopy.} = object id* {.importc.}: uint16 numSuccessivePresses* {.importc.}: uint16 isRetriggering* {.importc.}: bool
- Source Edit
ButtonReleasedData {.bycopy.} = object id* {.importc.}: uint16
- Source Edit
EncoderActivityData {.bycopy.} = object id* {.importc.}: uint16 newActivityType* {.importc.}: ActivityType
- Source Edit
EncoderTurnedData {.bycopy.} = object id* {.importc.}: uint16 increments* {.importc.}: int16 stepsPerRev* {.importc.}: uint16
- Source Edit
Event {.importcpp: "daisy::UiEventQueue::Event", bycopy.} = object eventType* {.importc: "type".}: EventType asButtonPressed* {.importc.}: ButtonPressedData asButtonReleased* {.importc.}: ButtonReleasedData asEncoderTurned* {.importc.}: EncoderTurnedData asEncoderActivityChanged* {.importc.}: EncoderActivityData asPotMoved* {.importc.}: PotMovedData asPotActivityChanged* {.importc.}: PotActivityData
- Type of event (use this to determine which union field to access) Source Edit
EventType {.importcpp: "daisy::UiEventQueue::Event::EventType", size: 1.} = enum invalid, ## Button was pressed buttonPressed, ## Button was released buttonReleased, ## Encoder was turned encoderTurned, ## Encoder activity changed (user started/stopped turning) encoderActivityChanged, ## Potentiometer was moved potMoved, ## Potentiometer activity changed (user started/stopped moving) potActivityChanged
- Invalid event (returned when queue is empty) Source Edit
PotActivityData {.bycopy.} = object id* {.importc.}: uint16 newActivityType* {.importc.}: ActivityType
- Source Edit
PotMovedData {.bycopy.} = object id* {.importc.}: uint16 newPosition* {.importc.}: cfloat
- Source Edit
UiEventQueue {.importcpp: "daisy::UiEventQueue", header: "ui/UiEventQueue.h".} = object
- Thread-safe FIFO queue for UI events. Safe to add events from interrupt handlers. Source Edit
Consts
INVALID_BUTTON_ID = 65535'u16
- Source Edit
INVALID_ENCODER_ID = 65535'u16
- Source Edit
INVALID_POT_ID = 65535'u16
- Source Edit
Procs
proc addButtonPressed(this: var UiEventQueue; buttonId: uint16; numSuccessivePresses: uint16; isRetriggering = false) {. importcpp: "#.AddButtonPressed(#, #, #)", ...raises: [], tags: [], forbids: [].}
-
Add button pressed event to queue
Parameters:
- buttonId - Unique button identifier
- numSuccessivePresses - Number of successive presses (1 = single, 2 = double, etc.)
- isRetriggering - True if auto-retriggered while held down
proc addButtonReleased(this: var UiEventQueue; buttonId: uint16) {. importcpp: "#.AddButtonReleased(#)", ...raises: [], tags: [], forbids: [].}
- Add button released event to queue Source Edit
proc addEncoderActivityChanged(this: var UiEventQueue; encoderId: uint16; isActive: bool) {. importcpp: "#.AddEncoderActivityChanged(#, #)", ...raises: [], tags: [], forbids: [].}
-
Add encoder activity changed event to queue
Parameters:
- encoderId - Unique encoder identifier
- isActive - True if user started turning, false if stopped
proc addEncoderTurned(this: var UiEventQueue; encoderId: uint16; increments: int16; stepsPerRev: uint16) {. importcpp: "#.AddEncoderTurned(#, #, #)", ...raises: [], tags: [], forbids: [].}
-
Add encoder turned event to queue
Parameters:
- encoderId - Unique encoder identifier
- increments - Number of steps (positive = CW, negative = CCW)
- stepsPerRev - Total steps per full revolution
proc addPotActivityChanged(this: var UiEventQueue; potId: uint16; isActive: bool) {. importcpp: "#.AddPotActivityChanged(#, #)", ...raises: [], tags: [], forbids: [].}
-
Add potentiometer activity changed event to queue
Parameters:
- potId - Unique potentiometer identifier
- isActive - True if user started moving, false if stopped
proc addPotMoved(this: var UiEventQueue; potId: uint16; newPosition: cfloat) {. importcpp: "#.AddPotMoved(#, #)", ...raises: [], tags: [], forbids: [].}
-
Add potentiometer moved event to queue
Parameters:
- potId - Unique potentiometer identifier
- newPosition - New position (0.0 to 1.0)
proc getAndRemoveNextEvent(this: var UiEventQueue): Event {. importcpp: "#.GetAndRemoveNextEvent()", ...raises: [], tags: [], forbids: [].}
- Remove and return next event from queue. Returns event with eventType = invalid if queue is empty. Source Edit
proc initUiEventQueue(): UiEventQueue {.importcpp: "daisy::UiEventQueue()", ...raises: [], tags: [], forbids: [].}
- Create new empty event queue Source Edit
proc isQueueEmpty(this: var UiEventQueue): bool {.importcpp: "#.IsQueueEmpty()", ...raises: [], tags: [], forbids: [].}
- Returns true if no events are in the queue Source Edit