kagura_ui

    Backend-agnostic retained UI-tree abstraction for Kagura (UINode, layout constraints, input/render adapters; extracted from kagura_engine)

    Download zip
    Author
    Version
    0.6.0
    License
    Apache-2.0
    Last updated
    15 days ago
    Downloads
    17

    Dependencies

    mizchi/kagura_ui does not have a README file

    LayoutEngine

    pub trait LayoutEngine {
    fn compute_layout(Self, root : UINodeId, constraint : LayoutConstraint) -> Array[LayoutResult] raise
    }

    UIInputAdapter

    pub trait UIInputAdapter {
    fn from_input_snapshot(Self, snapshot :
    InputSnapshot
    ) -> Array[UIEvent]
    }

    UIRenderAdapter

    pub trait UIRenderAdapter {
    fn build_draw_commands(Self, frame :
    FrameBudget
    , layouts : Array[LayoutResult], target :
    ImageHandle
    ) -> Array[
    DrawTrianglesCommand
    ] raise
    }

    JsonObjectPublisher

    pub struct JsonObjectPublisher {
    previous : Map[String, Json]
    initialized : Bool
    }

    Incremental JSON object transport. Fields are compared structurally; only changed top-level fields are encoded. Owns a deep copy of retained values, so callers may reuse mutable input maps/arrays. Receivers apply full, set and remove atomically; null is a value, not a deletion.

    JsonObjectPublisher::encode

    fn JsonObjectPublisher::encode(self : JsonObjectPublisher, fields : Map[String, Json]) -> String?

    First call (including an empty object) sends a full replacement; unchanged subsequent objects return None. reset starts a new receiver session.

    JsonObjectPublisher::new

    JsonObjectPublisher::reset

    fn JsonObjectPublisher::reset(self : JsonObjectPublisher) -> Unit

    LayoutConstraint

    pub struct LayoutConstraint {
    min_width : Double
    min_height : Double
    max_width : Double
    max_height : Double
    } derive(
    Debug
    )

    LayoutConstraint::output

    fn LayoutConstraint::output(self : LayoutConstraint, logger : &Logger) -> Unit

    LayoutConstraint::to_string

    fn LayoutConstraint::to_string(self : LayoutConstraint) -> String

    LayoutRect

    pub struct LayoutRect {
    x : Double
    y : Double
    width : Double
    height : Double
    } derive(
    Debug
    )

    impl Show for LayoutRect

    LayoutRect::output

    fn LayoutRect::output(self : LayoutRect, logger : &Logger) -> Unit

    LayoutRect::to_string

    fn LayoutRect::to_string(self : LayoutRect) -> String

    LayoutResult

    pub struct LayoutResult {
    node_id : UINodeId
    rect : LayoutRect
    } derive(
    Debug
    )

    LayoutResult::output

    fn LayoutResult::output(self : LayoutResult, logger : &Logger) -> Unit

    LayoutResult::to_string

    fn LayoutResult::to_string(self : LayoutResult) -> String

    SimpleLayoutEngine

    pub struct SimpleLayoutEngine {
    tree : UITree
    }

    SimpleLayoutEngine::compute_layout

    fn SimpleLayoutEngine::compute_layout(self : SimpleLayoutEngine, root : UINodeId, constraint : LayoutConstraint) -> Array[LayoutResult] raise

    SimpleLayoutEngine::new

    SimpleUIInputAdapter

    pub struct SimpleUIInputAdapter {
    prev_pressed_mouse : Array[Int]
    prev_cursor_x : Double
    prev_cursor_y : Double
    prev_pressed_keys : Array[Int]
    }

    SimpleUIInputAdapter::from_input_snapshot

    SimpleUIInputAdapter::new

    SimpleUIRenderAdapter

    pub struct SimpleUIRenderAdapter {
    shader :
    ShaderHandle

    pipeline_id : Int
    }

    UIAlignment

    pub(all) enum UIAlignment {
    Start
    End
    FlexStart
    FlexEnd
    Center
    SpaceBetween
    SpaceAround
    SpaceEvenly
    Stretch
    Baseline
    } derive(Eq,
    Debug
    )

    impl Show for UIAlignment

    UIAlignment::equal

    fn UIAlignment::equal(UIAlignment, UIAlignment) -> Bool

    UIAlignment::not_equal

    fn UIAlignment::not_equal(x : UIAlignment, y : UIAlignment) -> Bool

    UIAlignment::output

    fn UIAlignment::output(self : UIAlignment, logger : &Logger) -> Unit

    UIAlignment::to_string

    fn UIAlignment::to_string(self : UIAlignment) -> String

    UIDirection

    pub(all) enum UIDirection {
    Row
    Column
    } derive(
    Debug
    )

    impl Show for UIDirection

    UIDirection::output

    fn UIDirection::output(self : UIDirection, logger : &Logger) -> Unit

    UIDirection::to_string

    fn UIDirection::to_string(self : UIDirection) -> String

    UIEvent

    pub enum UIEvent {
    PointerDown(Double, Double)
    PointerUp(Double, Double)
    PointerMove(Double, Double)
    Scroll(Double, Double)
    KeyDown(Int)
    KeyUp(Int)
    } derive(
    Debug
    )

    impl Show for UIEvent

    UIEvent::output

    fn UIEvent::output(self : UIEvent, logger : &Logger) -> Unit

    UIEvent::to_repr

    UIEvent::to_string

    fn UIEvent::to_string(self : UIEvent) -> String

    UIFlexWrap

    pub(all) enum UIFlexWrap {
    NoWrap
    Wrap
    } derive(
    Debug
    )

    impl Show for UIFlexWrap

    UIFlexWrap::output

    fn UIFlexWrap::output(self : UIFlexWrap, logger : &Logger) -> Unit

    UIFlexWrap::to_string

    fn UIFlexWrap::to_string(self : UIFlexWrap) -> String

    UIFocusEvent

    pub(all) enum UIFocusEvent {
    FocusGained(UINodeId)
    FocusLost(UINodeId)
    } derive(
    Debug
    )

    UIFocusEvent::output

    fn UIFocusEvent::output(self : UIFocusEvent, logger : &Logger) -> Unit

    UIFocusEvent::to_string

    fn UIFocusEvent::to_string(self : UIFocusEvent) -> String

    UIFocusManager

    pub struct UIFocusManager {
    focused : UINodeId?
    focusable_ids : Array[UINodeId]
    }

    UIFocusManager::blur

    Remove focus. Returns blur event if something was focused.

    UIFocusManager::current_focus

    fn UIFocusManager::current_focus(self : UIFocusManager) -> UINodeId?

    UIFocusManager::focus

    Focus a specific node. Returns focus/blur events.

    UIFocusManager::focus_next

    fn UIFocusManager::focus_next(self : UIFocusManager) -> Array[UIFocusEvent]

    Move focus to the next focusable node (tab order).

    UIFocusManager::focus_prev

    fn UIFocusManager::focus_prev(self : UIFocusManager) -> Array[UIFocusEvent]

    Move focus to the previous focusable node (shift-tab order).

    UIFocusManager::handle_pointer_down

    fn UIFocusManager::handle_pointer_down(self : UIFocusManager, layouts : Array[LayoutResult], x : Double, y : Double) -> Array[UIFocusEvent]

    Handle a pointer down event: focus the hit node, or blur if no hit.

    UIFocusManager::new

    UIFocusManager::set_focusable

    fn UIFocusManager::set_focusable(self : UIFocusManager, ids : Array[UINodeId]) -> Unit

    UINode

    pub struct UINode {
    id : UINodeId
    style : UINodeStyle
    children : Array[UINodeId]
    } derive(
    Debug
    )

    impl Show for UINode

    UINode::output

    fn UINode::output(self : UINode, logger : &Logger) -> Unit

    UINode::to_repr

    UINode::to_string

    fn UINode::to_string(self : UINode) -> String

    UINodeId

    pub struct UINodeId {
    value : Int
    } derive(
    Debug
    )

    impl Show for UINodeId

    UINodeId::output

    fn UINodeId::output(self : UINodeId, logger : &Logger) -> Unit

    UINodeId::to_repr

    UINodeId::to_string

    fn UINodeId::to_string(self : UINodeId) -> String

    UINodeStyle

    pub(all) struct UINodeStyle {
    direction : UIDirection
    width : UISizing
    height : UISizing
    padding_left : Double
    padding_right : Double
    padding_top : Double
    padding_bottom : Double
    gap : Double
    align : UIAlignment
    justify_content : UIAlignment
    flex_wrap : UIFlexWrap
    } derive(
    Debug
    )

    impl Show for UINodeStyle

    UINodeStyle::output

    fn UINodeStyle::output(self : UINodeStyle, logger : &Logger) -> Unit

    UINodeStyle::to_string

    fn UINodeStyle::to_string(self : UINodeStyle) -> String

    UISafeArea

    pub(all) struct UISafeArea {
    top : Double
    right : Double
    bottom : Double
    left : Double
    } derive(
    Debug
    )

    impl Show for UISafeArea

    UISizing

    pub(all) enum UISizing {
    Fixed(Double)
    Percent(Double)
    Auto
    } derive(
    Debug
    )

    impl Show for UISizing

    UISizing::output

    fn UISizing::output(self : UISizing, logger : &Logger) -> Unit

    UISizing::to_repr

    UISizing::to_string

    fn UISizing::to_string(self : UISizing) -> String

    UISnapshot

    pub(all) struct UISnapshot {
    screen_width : Double
    screen_height : Double
    dpr : Double
    safe_area : UISafeArea
    frame : Int
    state : String
    nodes : Array[UISnapshotNode]
    focus_order : Array[String]
    } derive(
    Debug
    )

    impl Show for UISnapshot

    UISnapshot::to_json

    fn UISnapshot::to_json(self : UISnapshot) -> String

    Serialize the snapshot to the introspection JSON.

    Each node carries both role and a tag alias holding the same value, so the document is directly consumable as a vlmkit --elements-json payload (which requires tag) without a conversion step.

    UISnapshotNode

    pub(all) struct UISnapshotNode {
    path : String
    id : String
    role : String
    classes : String
    left : Double
    top : Double
    width : Double
    height : Double
    z : Int
    visible : Bool
    clip : UISnapshotRect?
    text : String?
    text_measured : UITextMetrics?
    focusable : Bool
    focus_index : Int
    focused : Bool
    hit : UISnapshotRect?
    } derive(
    Debug
    )

    One node of a UI snapshot.

    path is a stable structural address (hud[0]>bar[1]); id and classes are the author-supplied names the tooling reports defects against. clip is the effective scissor rect at draw time, hit the rect the pointer is actually tested against (they diverge when a widget's hit box drifts from what is drawn).

    UISnapshotRect

    pub(all) struct UISnapshotRect {
    left : Double
    top : Double
    width : Double
    height : Double
    } derive(
    Debug
    )

    UITextMetrics

    pub(all) struct UITextMetrics {
    width : Double
    height : Double
    } derive(
    Debug
    )

    Measured extent of a node's text, as reported by @text.TextRenderer::measure. Compared against the node rect to detect overflow the renderer will clip.

    UITree

    pub struct UITree {
    nodes : Map[Int, UINode]
    next_id : Int
    }

    UITree::add_node

    fn UITree::add_node(self : UITree, style : UINodeStyle, children : Array[UINodeId]) -> UINodeId

    UITree::get_node

    fn UITree::get_node(self : UITree, id : UINodeId) -> UINode?

    UITree::new

    fn UITree::new() -> UITree

    UITree::node_count

    fn UITree::node_count(self : UITree) -> Int

    default_layout_constraint

    fn default_layout_constraint(width : Double, height : Double) -> LayoutConstraint

    default_node_style

    fn default_node_style() -> UINodeStyle

    default_ui_snapshot

    fn default_ui_snapshot(screen_width~ : Double, screen_height~ : Double) -> UISnapshot

    default_ui_snapshot_node

    fn default_ui_snapshot_node() -> UISnapshotNode

    A node with every optional field cleared. Fill in with struct update syntax: { ..default_ui_snapshot_node(), path: "hud[0]", id: "hud", width: 640.0 }

    hit_test

    fn hit_test(layouts : Array[LayoutResult], x : Double, y : Double) -> UINodeId?

    Find the topmost node that contains the given point.

    LayoutResult carries no z, so the array order is the only ordering there is, and compute_layout emits post-order: every child before the container that holds it, the root last. The innermost node containing the point is therefore the first match, and the last match is always the outermost container -- for a full-screen root, every on-screen point.

    This used to take the last match, which meant that feeding compute_layout's own output straight into hit_test returned the root background for every point on screen. The regression test at the bottom of contracts_wbtest.mbt pins the two halves together.

    hit_test_all

    fn hit_test_all(layouts : Array[LayoutResult], x : Double, y : Double) -> Array[UINodeId]

    Every node containing the point, innermost first -- the same order hit_test picks its answer from. A caller looking for "the deepest node that is focusable" takes the first match it likes.

    point_in_rect

    fn point_in_rect(rect : LayoutRect, x : Double, y : Double) -> Bool

    ui_events_from_input_edge

    fn ui_events_from_input_edge(key_state :
    KeyInputState
    , mouse_state :
    MouseButtonInputState
    , cursor_x : Double, cursor_y : Double) -> Array[UIEvent]

    Convert inpututil edge state to UIEvents for the current frame. Uses just-pressed/just-released from the edge detection to generate PointerDown/Up and KeyDown/Up events.

    ui_snapshot_nodes_from_layouts

    fn ui_snapshot_nodes_from_layouts(layouts : Array[LayoutResult]) -> Array[UISnapshotNode]

    Derive snapshot nodes straight from layout results.

    This is the zero-effort path: it carries geometry only, which is enough for offscreen / zero-size / overlap detection and for --elements-json attribution. Text and focus metadata have to come from the caller, which is the only place that knows a node's role.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io