playbit / docs

UI

Playbit's UI library is an immediate-mode styled API. The UI is composed of a tree of rectangles.

Example

UIBox* parent = UIDiv(PBStrLit("parent"));
parent->style = UIStyleMake(
    .size = UI_size2(UI_fill(1), UI_fill(1)),
    .direction = UIAxis_X,
    .align = UI_align2(UIAlign_Center, UIAlign_Center));

UIPushParent(parent);
{
    UIDiv(PBStrLit("A"))->style = UIStyleMake(
        .size = UI_size2(UI_px(20), UI_px(20)), .backgroundColor = UI_rgb(1, 0, 0));

    UIDiv(PBStrLit("B"))->style = UIStyleMake(
        .size = UI_size2(UI_px(20), UI_px(20)), .backgroundColor = UI_rgb(0, 1, 0));

    UIDiv(PBStrLit("C"))->style = UIStyleMake(
        .size = UI_size2(UI_px(20), UI_px(20)), .backgroundColor = UI_rgb(0, 0, 1));
}
UIPopParent(parent);

Would render:

Guide


#include <playbit/app.h>

PBAppData

struct PBAppData {
    union {
        void* nullable ctx; // any data, passed to callbacks
        u64            ctx64;
    };

    u64 flags;

    // onEvent can be set to handle any event which isn't handled by another handler
    void (*nullable onEvent)(const PBEvent* event);

    /*
    onRender is called once per frame when a render has been requested. By default a render is requested on each new event (e.g. resize, input). The draw context and UI state are set up automatically before calling onRender.
    */
    void (*nullable onRender)(void);
};

PBAppResource

typedef struct PBAppResource {
    PBStrSlice name;
    PBU8Slice  data; // guaranteed to be at least 16-byte aligned
} PBAppResource;

PBAppResource is a resource embedded in the program, defined in pbapp.toml

PBAppTimerCallback

typedef void (*PBAppTimerCallback)(PBTimer, u64);

PBAppResource is a resource embedded in the program, defined in pbapp.toml

PBAppMain

void PBAppMain();

PBAppMain processes events and calls callbacks. It blocks until the calling thread exits.

PBAppName

PBStrSlice PBAppName();

PBAppName retrieves the name of the app, as defined by app_name in pbapp.toml

PBAppId

PBStrSlice PBAppId();

PBAppId retrieves the id of the app, as defined by app_id in pbapp.toml

PBAppResourceWithName

PBAppResource PBAppResourceWithName(PBStrSlice name);

PBAppResourceWithName returns an embedded resource by name, defined in pbapp.toml. Panics if the named resource is not found

PBAppResourceCount

u32 PBAppResourceCount();

PBAppResourceCount returns the number of embedded resources available

PBAppResourceAtIndex

PBAppResource PBAppResourceAtIndex(u32 index);

PBAppResourceAtIndex returns an embedded resource by index.

PBAppTimerStart

PBTimer PBAppTimerStart(PBTime             when,
                        PBTimeDuration     repeat,
                        PBTimeDuration     leeway,
                        PBAppTimerCallback callback,
                        u64                arg);

PBAppTimerStart starts a timer, which will call callback when it rings.

To cancel or stop a timer, use PBTimerStop. Returns a new timer handle.

PBAppTimeout

PBTimer PBAppTimeout(PBTimeDuration     delay,
                     PBAppTimerCallback callback,
                     u64                arg);

PBAppTimeout starts a one-shot timer which triggers delay time from now

PBAppInterval

PBTimer PBAppInterval(PBTimeDuration     interval,
                      PBAppTimerCallback callback,
                      u64                arg);

PBAppInterval starts a repeating timer which triggers interval time from now and then repeats every interval time duration.

PBAppRender

void PBAppRender(PBEvent* ev,
                 u32      eventCount);

PBAppRender converts system events to UI/draw updates and executes one render pass, calling PBApp.onRender

PBAppRequestRender

void PBAppRequestRender();

PBAppRequestRender schedules PBAppRender to be called as soon as the current frame has finished presenting (i.e. on display hardware to delivered to platform compositor.)


#include <playbit/event.h>

PBGesturePhase

typedef enum PBGesturePhase PB_ENUM_TYPE(u8){
    PBGesturePhase_CHANGED = PBSysGesturePhase_CHANGED,
    PBGesturePhase_BEGAN = PBSysGesturePhase_BEGAN,
    PBGesturePhase_ENDED = PBSysGesturePhase_ENDED,
} PBGesturePhase;

PBKeyboardFlags

typedef enum PBKeyboardFlags PB_ENUM_TYPE(u16){
    PBKeyboardFlag_REPEAT = PBSysKeyboardFlag_REPEAT,
} PBKeyboardFlags;

PBKeyboardKey

typedef enum PBKeyboardKey PB_ENUM_TYPE(u16){
    PBKeyboardKey_None = PBSysKeyboardKey_None,
    PBKeyboardKey_Space = PBSysKeyboardKey_Space,
    PBKeyboardKey_Quote = PBSysKeyboardKey_Quote,
    PBKeyboardKey_Comma = PBSysKeyboardKey_Comma,
    PBKeyboardKey_Minus = PBSysKeyboardKey_Minus,
    PBKeyboardKey_Period = PBSysKeyboardKey_Period,
    PBKeyboardKey_Slash = PBSysKeyboardKey_Slash,
    PBKeyboardKey_0 = PBSysKeyboardKey_0,
    PBKeyboardKey_1 = PBSysKeyboardKey_1,
    PBKeyboardKey_2 = PBSysKeyboardKey_2,
    PBKeyboardKey_3 = PBSysKeyboardKey_3,
    PBKeyboardKey_4 = PBSysKeyboardKey_4,
    PBKeyboardKey_5 = PBSysKeyboardKey_5,
    PBKeyboardKey_6 = PBSysKeyboardKey_6,
    PBKeyboardKey_7 = PBSysKeyboardKey_7,
    PBKeyboardKey_8 = PBSysKeyboardKey_8,
    PBKeyboardKey_9 = PBSysKeyboardKey_9,
    PBKeyboardKey_Semicolon = PBSysKeyboardKey_Semicolon,
    PBKeyboardKey_Equal = PBSysKeyboardKey_Equal,
    PBKeyboardKey_A = PBSysKeyboardKey_A,
    PBKeyboardKey_B = PBSysKeyboardKey_B,
    PBKeyboardKey_C = PBSysKeyboardKey_C,
    PBKeyboardKey_D = PBSysKeyboardKey_D,
    PBKeyboardKey_E = PBSysKeyboardKey_E,
    PBKeyboardKey_F = PBSysKeyboardKey_F,
    PBKeyboardKey_G = PBSysKeyboardKey_G,
    PBKeyboardKey_H = PBSysKeyboardKey_H,
    PBKeyboardKey_I = PBSysKeyboardKey_I,
    PBKeyboardKey_J = PBSysKeyboardKey_J,
    PBKeyboardKey_K = PBSysKeyboardKey_K,
    PBKeyboardKey_L = PBSysKeyboardKey_L,
    PBKeyboardKey_M = PBSysKeyboardKey_M,
    PBKeyboardKey_N = PBSysKeyboardKey_N,
    PBKeyboardKey_O = PBSysKeyboardKey_O,
    PBKeyboardKey_P = PBSysKeyboardKey_P,
    PBKeyboardKey_Q = PBSysKeyboardKey_Q,
    PBKeyboardKey_R = PBSysKeyboardKey_R,
    PBKeyboardKey_S = PBSysKeyboardKey_S,
    PBKeyboardKey_T = PBSysKeyboardKey_T,
    PBKeyboardKey_U = PBSysKeyboardKey_U,
    PBKeyboardKey_V = PBSysKeyboardKey_V,
    PBKeyboardKey_W = PBSysKeyboardKey_W,
    PBKeyboardKey_X = PBSysKeyboardKey_X,
    PBKeyboardKey_Y = PBSysKeyboardKey_Y,
    PBKeyboardKey_Z = PBSysKeyboardKey_Z,
    PBKeyboardKey_LeftBracket = PBSysKeyboardKey_LeftBracket,
    PBKeyboardKey_Backslash = PBSysKeyboardKey_Backslash,
    PBKeyboardKey_RightBracket = PBSysKeyboardKey_RightBracket,
    PBKeyboardKey_Grave = PBSysKeyboardKey_Grave,
    PBKeyboardKey_Escape = PBSysKeyboardKey_Escape,
    PBKeyboardKey_Enter = PBSysKeyboardKey_Enter,
    PBKeyboardKey_Tab = PBSysKeyboardKey_Tab,
    PBKeyboardKey_Backspace = PBSysKeyboardKey_Backspace,
    PBKeyboardKey_Insert = PBSysKeyboardKey_Insert,
    PBKeyboardKey_Delete = PBSysKeyboardKey_Delete,
    PBKeyboardKey_Left = PBSysKeyboardKey_Left,
    PBKeyboardKey_Right = PBSysKeyboardKey_Right,
    PBKeyboardKey_Down = PBSysKeyboardKey_Down,
    PBKeyboardKey_Up = PBSysKeyboardKey_Up,
    PBKeyboardKey_PageUp = PBSysKeyboardKey_PageUp,
    PBKeyboardKey_PageDown = PBSysKeyboardKey_PageDown,
    PBKeyboardKey_Home = PBSysKeyboardKey_Home,
    PBKeyboardKey_End = PBSysKeyboardKey_End,
    PBKeyboardKey_CapsLock = PBSysKeyboardKey_CapsLock,
    PBKeyboardKey_LeftShift = PBSysKeyboardKey_LeftShift,
    PBKeyboardKey_LeftCtrl = PBSysKeyboardKey_LeftCtrl,
    PBKeyboardKey_LeftAlt = PBSysKeyboardKey_LeftAlt,
    PBKeyboardKey_LeftSuper = PBSysKeyboardKey_LeftSuper,
    PBKeyboardKey_MediaNext = PBSysKeyboardKey_MediaNext,
    PBKeyboardKey_MediaPrev = PBSysKeyboardKey_MediaPrev,
    PBKeyboardKey_MediaPlay = PBSysKeyboardKey_MediaPlay,
    PBKeyboardKey_MediaStop = PBSysKeyboardKey_MediaStop,
    PBKeyboardKey_World1 = PBSysKeyboardKey_World1,
    PBKeyboardKey_World2 = PBSysKeyboardKey_World2,
    PBKeyboardKey_ScrollLock = PBSysKeyboardKey_ScrollLock,
    PBKeyboardKey_NumLock = PBSysKeyboardKey_NumLock,
    PBKeyboardKey_PrintScreen = PBSysKeyboardKey_PrintScreen,
    PBKeyboardKey_Pause = PBSysKeyboardKey_Pause,
    PBKeyboardKey_F1 = PBSysKeyboardKey_F1,
    PBKeyboardKey_F2 = PBSysKeyboardKey_F2,
    PBKeyboardKey_F3 = PBSysKeyboardKey_F3,
    PBKeyboardKey_F4 = PBSysKeyboardKey_F4,
    PBKeyboardKey_F5 = PBSysKeyboardKey_F5,
    PBKeyboardKey_F6 = PBSysKeyboardKey_F6,
    PBKeyboardKey_F7 = PBSysKeyboardKey_F7,
    PBKeyboardKey_F8 = PBSysKeyboardKey_F8,
    PBKeyboardKey_F9 = PBSysKeyboardKey_F9,
    PBKeyboardKey_F10 = PBSysKeyboardKey_F10,
    PBKeyboardKey_F11 = PBSysKeyboardKey_F11,
    PBKeyboardKey_F12 = PBSysKeyboardKey_F12,
    PBKeyboardKey_F13 = PBSysKeyboardKey_F13,
    PBKeyboardKey_F14 = PBSysKeyboardKey_F14,
    PBKeyboardKey_F15 = PBSysKeyboardKey_F15,
    PBKeyboardKey_F16 = PBSysKeyboardKey_F16,
    PBKeyboardKey_F17 = PBSysKeyboardKey_F17,
    PBKeyboardKey_F18 = PBSysKeyboardKey_F18,
    PBKeyboardKey_F19 = PBSysKeyboardKey_F19,
    PBKeyboardKey_F20 = PBSysKeyboardKey_F20,
    PBKeyboardKey_F21 = PBSysKeyboardKey_F21,
    PBKeyboardKey_F22 = PBSysKeyboardKey_F22,
    PBKeyboardKey_F23 = PBSysKeyboardKey_F23,
    PBKeyboardKey_F24 = PBSysKeyboardKey_F24,
    PBKeyboardKey_Numpad0 = PBSysKeyboardKey_Numpad0,
    PBKeyboardKey_Numpad1 = PBSysKeyboardKey_Numpad1,
    PBKeyboardKey_Numpad2 = PBSysKeyboardKey_Numpad2,
    PBKeyboardKey_Numpad3 = PBSysKeyboardKey_Numpad3,
    PBKeyboardKey_Numpad4 = PBSysKeyboardKey_Numpad4,
    PBKeyboardKey_Numpad5 = PBSysKeyboardKey_Numpad5,
    PBKeyboardKey_Numpad6 = PBSysKeyboardKey_Numpad6,
    PBKeyboardKey_Numpad7 = PBSysKeyboardKey_Numpad7,
    PBKeyboardKey_Numpad8 = PBSysKeyboardKey_Numpad8,
    PBKeyboardKey_Numpad9 = PBSysKeyboardKey_Numpad9,
    PBKeyboardKey_NumpadDot = PBSysKeyboardKey_NumpadDot,
    PBKeyboardKey_NumpadDivide = PBSysKeyboardKey_NumpadDivide,
    PBKeyboardKey_NumpadMultiply = PBSysKeyboardKey_NumpadMultiply,
    PBKeyboardKey_NumpadSubtract = PBSysKeyboardKey_NumpadSubtract,
    PBKeyboardKey_NumpadAdd = PBSysKeyboardKey_NumpadAdd,
    PBKeyboardKey_NumpadEnter = PBSysKeyboardKey_NumpadEnter,
    PBKeyboardKey_NumpadEquals = PBSysKeyboardKey_NumpadEquals,
    PBKeyboardKey_NumpadClear = PBSysKeyboardKey_NumpadClear,
    PBKeyboardKey_RightShift = PBSysKeyboardKey_RightShift,
    PBKeyboardKey_RightCtrl = PBSysKeyboardKey_RightCtrl,
    PBKeyboardKey_RightAlt = PBSysKeyboardKey_RightAlt,
    PBKeyboardKey_RightSuper = PBSysKeyboardKey_RightSuper,
    PBKeyboardKey_Menu = PBSysKeyboardKey_Menu,
    PBKeyboardKey_VolumeUp = PBSysKeyboardKey_VolumeUp,
    PBKeyboardKey_VolumeDown = PBSysKeyboardKey_VolumeDown,
    PBKeyboardKey_Mute = PBSysKeyboardKey_Mute,
    PBKeyboardKey_COUNT = PBSysKeyboardKey_COUNT,
} PBKeyboardKey;

PBKeyboardModifiers

typedef enum PBKeyboardModifiers PB_ENUM_TYPE(u16){
    PBKeyboardModifier_SHIFT = PBSysKeyboardModifier_SHIFT,
    PBKeyboardModifier_CTRL = PBSysKeyboardModifier_CTRL,
    PBKeyboardModifier_ALT = PBSysKeyboardModifier_ALT,
    PBKeyboardModifier_META = PBSysKeyboardModifier_META,
    PBKeyboardModifier_CAPS_LOCK = PBSysKeyboardModifier_CAPS_LOCK,
    PBKeyboardModifier_FN = PBSysKeyboardModifier_FN,
} PBKeyboardModifiers;

PBMouseButton

typedef enum PBMouseButton PB_ENUM_TYPE(u16){
    PBMouseButton_Left = PBSysMouseButton_Left,     PBMouseButton_Right = PBSysMouseButton_Right,
    PBMouseButton_Middle = PBSysMouseButton_Middle, PBMouseButton_X1 = PBSysMouseButton_X1,
    PBMouseButton_X2 = PBSysMouseButton_X2,         PBMouseButton_COUNT = PBSysMouseButton_COUNT,
} PBMouseButton;

PBPointerFlags

typedef enum PBPointerFlags PB_ENUM_TYPE(u16){
    PBPointerFlag_PRIMARY = PBSysPointerFlag_PRIMARY,
    PBPointerFlag_IN_CONTACT = PBSysPointerFlag_IN_CONTACT,
    PBPointerFlag_ERASER = PBSysPointerFlag_ERASER,
    PBPointerFlag_INVERTED = PBSysPointerFlag_INVERTED,
    PBPointerFlag_COALESCED = PBSysPointerFlag_COALESCED,
    PBPointerFlag_PREDICTED = PBSysPointerFlag_PREDICTED,
} PBPointerFlags;

PBPointerKind

typedef enum PBPointerKind PB_ENUM_TYPE(u8){
    PBPointerKind_MOUSE = PBSysPointerKind_MOUSE,
    PBPointerKind_TOUCH = PBSysPointerKind_TOUCH,
    PBPointerKind_TRACKPAD = PBSysPointerKind_TRACKPAD,
    PBPointerKind_PEN = PBSysPointerKind_PEN,
} PBPointerKind;

PBScrollFlags

typedef enum PBScrollFlags PB_ENUM_TYPE(u16){
    PBScrollFlag_PRECISE = PBSysScrollFlag_PRECISE,
    PBScrollFlag_INVERTED = PBSysScrollFlag_INVERTED,
    PBScrollFlag_UNIT_LINES = PBSysScrollFlag_UNIT_LINES,
    PBScrollFlag_UNIT_PAGES = PBSysScrollFlag_UNIT_PAGES,
} PBScrollFlags;

PBScrollPhase

typedef enum PBScrollPhase PB_ENUM_TYPE(u8){
    PBScrollPhase_CHANGED = PBSysScrollPhase_CHANGED,
    PBScrollPhase_BEGAN = PBSysScrollPhase_BEGAN,
    PBScrollPhase_ENDED = PBSysScrollPhase_ENDED,
    PBScrollPhase_MOMENTUM = PBSysScrollPhase_MOMENTUM,
} PBScrollPhase;

PBEventType

typedef enum PBEventType PB_ENUM_TYPE(u16){
    PBEventType_INVALID = PBSysEventType_INVALID,
    PBEventType_SIGNAL = PBSysEventType_SIGNAL,

    // pointer
    PBEventType_POINTER_ENTER =
        PBSysEventType_POINTER_ENTER, // pointer started being "in" the surface/window
    PBEventType_POINTER_LEAVE = PBSysEventType_POINTER_LEAVE, // pointer left the surface/window
    PBEventType_POINTER_DOWN = PBSysEventType_POINTER_DOWN,
    PBEventType_POINTER_UP = PBSysEventType_POINTER_UP,
    PBEventType_POINTER_MOVE = PBSysEventType_POINTER_MOVE,
    PBEventType_POINTER_CANCEL = PBSysEventType_POINTER_CANCEL, // system canceled a sequence

    // scroll
    PBEventType_SCROLL = PBSysEventType_SCROLL,

    // gesture
    PBEventType_GESTURE_PAN = PBSysEventType_GESTURE_PAN,
    PBEventType_GESTURE_PINCH = PBSysEventType_GESTURE_PINCH,
    PBEventType_GESTURE_ROTATE = PBSysEventType_GESTURE_ROTATE,

    // keyboard
    PBEventType_KEY_DOWN = PBSysEventType_KEY_DOWN,
    PBEventType_KEY_UP = PBSysEventType_KEY_UP,

    // timer
    PBEventType_TIMER = 0x8000,
} PBEventType;

PBEventType defines the type of a PBEvent

PBEvent

typedef struct PBEvent {
    u16         size;     // size of the event
    PBEventType type;     // PBEventType
    u32         objectId; // originating object ID, e.g. window (0 means "unknown")
} PB_ATTR_ALIGNED(8) PBEvent;

PBEvent is the common header for all events. Events are variable-sized.

PBSignalEvent

typedef struct PBSignalEvent {
    PBEvent      event;
    PBSysHandle  handle;
    PBSysSignals signals;
    PBSysSignals pulseSignals;
    u16          objectType; // PBSysObjectType
    u16          _reserved;
} PBSignalEvent;

PBInputEvent

typedef struct PBInputEvent {
    PBEvent event;
    PBTime  timestamp; // time the event occurred
    u32     clientId;  // originating client ID (0 for "local")
    u32     deviceId;  // stable per HID
    u16     modifiers; // PBKeyboardModifiers
    u16     _reserved;
} PBInputEvent;

PBPointerEvent

typedef struct PBPointerEvent {
    PBInputEvent  inputEvent;
    u32           pointerId;  // logical; stable per active contact/stream
    u16           flags;      // PBPointerFlags
    u16           buttons;    // current button bitmask (mouse/pen)
    u8            button;     // "changed" button for DOWN/UP/CLICK (0 if n/a)
    PBPointerKind kind;       //
    u8            clickCount; // for CLICK (and optionally DOWN/UP if platform provides)
    u8            _reserved;  //
    f32           x, y;       // position in window coords (dp)
    f32           dx, dy;     // delta since last event for this pointerId (dp). 0 if unknown.
} PBPointerEvent;

PBPenPointerEvent

typedef struct PBPenPointerEvent {
    PBPointerEvent pointerEvent;
    f32            pressure;           // [0..1]
    f32            tangentialPressure; // [0..1] barrel pressure (pen)
    f32            tiltX, tiltY;       // [-1, +1] 0 = perpendicular
    f32            twist;              // degrees [0, 359]; barrel rotation (pen)
    f32            width, height;      // contact ellipse in dp (touch/pen)
    f32            altitudeAngle;      // [0, π/2] radians (0 = parallel, π/2 = perpendicular)
    f32            azimuthAngle;       // [0, π/2] radians, direction in the screen plane
} PBPenPointerEvent;

PBPenPointerEvent is the shape of a PBPointerEvent when kind==PBPointerKind_PEN

PBScrollEvent

typedef struct PBScrollEvent {
    PBInputEvent  inputEvent;
    PBPointerKind kind;
    PBScrollPhase phase;
    u16           flags;  // PBScrollFlags
    f32           x, y;   // focus point in window coords if known, else 0
    f32           dx, dy; // scroll delta (dp or lines/pages depending on flags)
    f32           wheelZ; // optional for 3D wheels; else 0
} PBScrollEvent;

PBGestureEvent

typedef struct PBGestureEvent {
    PBInputEvent   inputEvent;
    PBGesturePhase phase;
    u8             _reserved;
    u16            flags;    // currenty unused
    f32            x, y;     // gesture center in window coords (dp) if known
    f32            dx, dy;   // pan delta (dp) for PAN; else 0
    f32            scale;    // relative scale delta for PINCH (1.0 means no change; e.g. 1.02)
    f32            rotation; // relative rotation delta in radians for ROTATE
} PBGestureEvent;

PBKeyboardEvent

typedef struct PBKeyboardEvent {
    PBInputEvent  inputEvent;
    PBKeyboardKey keyCode;    // logical code for the key, i.e. "the A key"
    PBKeyboardKey deviceCode; // physical key, i.e. "3rd key on 4th row"
    u32           text[8];    // Unicode representation
    u8            textLen;    // number of codepoints in text array
    u8            _reserved;  //
    u16           flags;      // PBKeyboardFlags
} PBKeyboardEvent;

PBTimerEvent

typedef struct PBTimerEvent {
    PBEvent event;
    PBTimer timer;
    u64     arg1;
    u64     arg2;
} PBTimerEvent;

PBEventAny

typedef union PBEventAny {
    struct { // PBEvent
        u16         size;
        PBEventType type;
        u32         objectId;
    };
    PBEvent           event;
    PBSignalEvent     signal;
    PBInputEvent      input;
    PBPointerEvent    pointer;
    PBPenPointerEvent penPointer;
    PBScrollEvent     scroll;
    PBGestureEvent    gesture;
    PBKeyboardEvent   keyboard;
    PBTimerEvent      timer;
    u8                _maxSize[PBSysEventSize_MAX];
} PBEventAny;

PBEventPoll

i32 PBEventPoll(PBEvent* events,
                u32      eventsSize,
                u32      maxCount);

PBEventPoll retrieves events for the calling thread.

PBEventNext

PBEvent* PBEventNext(PBEvent* event);

PBEventNext returns the next event in an array of events returned from PBEventPoll

PBEventAnyNext

PBEventAny* PBEventAnyNext(PBEventAny* event);

PBEventAnyNext returns the next event in an array of events returned from PBEventPoll

PBEventTypeStr

const char* PBEventTypeStr(PBEventType arg);

PBEventTypeStr returns a short string representation of an event type, e.g. "SIGNAL"

PBEventStr

u32 PBEventStr(const PBEvent* event,
               char*          buf,
               u32            bufCap);

PBEventStr writes a string representation of a PBEvent to buf.

PBEventOfSysEvent

usize PBEventOfSysEvent(PBEvent*          event,
                        usize             eventSize,
                        const PBSysEvent* sysEvent);

PBEventOfSysEvent copies a PBSysEvent entry to a PBEvent.

PBLogEvent

void PBLogEvent(const PBEvent* event);

PBLogEvent is a convenience function which calls PBLog with the result of passing event to PBEventStr


#include <playbit/window.h>

PBWindow

typedef struct {
    PBSysHandle handle;
} PBWindow;

PBWindow is a handle to a UI window

PBWindowOpt

typedef PBOpt(PBWindow) PBWindowOpt;

PBWindow is a handle to a UI window

PBWindowMain

PBWindow PBWindowMain();

PBWindowMain retrieves the main window, or PBWindow_NONE if there's no main window.

PBWindowClose

PBSysErr PBWindowClose(PBWindow window);

PBWindowClose closes window handle and destroys the associated window.

PBWindowOpen

PBWindow PBWindowOpen(const char* title,
                      f32         width,
                      f32         height);

PBWindowOpen creates a window on the current thread with title and size.

PBWindowOpenWithConfig

PBWindowOpt PBWindowOpenWithConfig(PBThread                 thread,
                                   const PBSysWindowConfig* config);

PBWindowOpenWithConfig creates a window on thread using detailed system configuration.

PBWindowCopyTitle

PBSysErr PBWindowCopyTitle(PBWindow window,
                           PBStr*   titleOut,
                           PBMem    ma);

PBWindowCopyTitle copies the title of a window to title, allocating memory with ma

PBWindowSetTitle

void PBWindowSetTitle(PBWindow   window,
                      PBStrSlice title);

PBWindowSetTitle sets the title of a window

PBWindowStyle

PBSysWindowStyle PBWindowStyle(PBWindow window);

PBWindowStyle retrieves the current style of a window

PBWindowSetStyle

void PBWindowSetStyle(PBWindow         window,
                      PBSysWindowStyle style);

WindowSetStyle sets the style of a window

PBWindowSetSizeLimits

void PBWindowSetSizeLimits(PBWindow window,
                           PBSize   min,
                           PBSize   max);

PBWindowSetSizeLimits sets lower and upper limits for window frame size

PBWindowSetMinSize

void PBWindowSetMinSize(PBWindow window,
                        f32      minWidth,
                        f32      minHeight);

PBWindowSetMinSize sets lower limit for window frame size

PBWindowSetMaxSize

void PBWindowSetMaxSize(PBWindow window,
                        f32      maxWidth,
                        f32      maxHeight);

PBWindowSetMinSize sets upper limit for window frame size

PBWindowRect

PBRect PBWindowRect(PBWindow window);

PBWindowFrame returns the origin and size of a window. The origin is the top-left corner of the window in screen coordinates. The size includes OS window decorations.

PBWindowSetFrame

PBSysErr PBWindowSetFrame(PBWindow window,
                          PBRect   frame);

PBWindowSetFrame adjusts the origin and (outer) size of a window

PBWindowSetOrigin

PBSysErr PBWindowSetOrigin(PBWindow window,
                           f32      x,
                           f32      y);

PBWindowSetOrigin repositions the window on screen

PBWindowSetSize

PBSysErr PBWindowSetSize(PBWindow window,
                         f32      width,
                         f32      height);

PBWindowSetSize sets the (outer) size of a window

PBWindowSetSizeCentered

PBSysErr PBWindowSetSizeCentered(PBWindow window,
                                 f32      width,
                                 f32      height);

PBWindowSetSizeCentered sets the size of a window and positions it at the center of the screen

PBWindowContentRect

PBRect PBWindowContentRect(PBWindow window);

PBWindowContentRect returns the size and position (relative to the window``s frame) of a window``s content. The origin is the top-left corner of the contents relative to the window's outer frame.

PBWindowContentSize

PBSize PBWindowContentSize(PBWindow window);

PBWindowContentSize returns the size of a window's content

PBWindowSetContentSizeCentered

PBSysErr PBWindowSetContentSizeCentered(PBWindow window,
                                        f32      width,
                                        f32      height);

PBWindowSetContentSizeCentered adjusts the size of a window so that its content size is {wodth, height}, and positions the window at the center of the screen.

PBWindowScaleFactor

f32 PBWindowScaleFactor(PBWindow window);

PBWindowScaleFactor returns the dp scale factor for a window (pixels per dp.)

PBWindowGetSize

PBVector2 PBWindowGetSize(PBWindow window);

PBWindowGetSize returns current window's content size in dp

PBWindowGetScale

f32 PBWindowGetScale(PBWindow window);

PBWindowGetScale returns current device-pixel scale factor for window.

PBCursorSetStyle

int PBCursorSetStyle(u32 windowId,
                     u32 style);

#include <playbit/ui.h>

PBUIFont

struct PBUIFont {
    PBStrSlice family; // font family name (e.g. PBStrLit("sans") or PBStrLit("mono"))
    f32        size;   // font size in pixels (e.g. 16.0)
    f32        weight; // font weight between 100-900
};

Font descriptor used for text rendering. Passed to PBUIStyle.font and PBUIText().

PBUIKey

struct PBUIKey {
    u64 v;
};

Opaque 64-bit identity key that uniquely identifies a box across frames. Keys are derived by hashing a string, optionally seeded by a parent key. Use PBUIKeyFromString() or PBUIKeyFromStringAndIndex() to construct.

PBUIBoxFlags

typedef enum PBUIBoxFlags PB_ENUM_TYPE(u32){
    // Events
    PBUIBoxFlag_Clickable = (1 << 0), // whether or not boxes should receive clicks

    // Layout
    PBUIBoxFlag_FixedWidth = (1 << 1),  // box width must be _exactly_ fixedSize.x
    PBUIBoxFlag_FixedHeight = (1 << 2), // box height must be _exactly_ fixedSize.y
    PBUIBoxFlag_FloatingX = (1 << 3),   // remove box from layout along the X-axis and position
                                        // absolutely with fixedPosition.x
    PBUIBoxFlag_FloatingY = (1 << 4),   // remove box from layout along the Y-axis and position
                                        // absolutely with fixedPosition.y

    // Overflow
    PBUIBoxFlag_AllowOverflowX = (1 << 5),  // allow children to overflow on the X-axis
    PBUIBoxFlag_AllowOverflowY = (1 << 6),  // allow children to overflow on the Y-axis
    PBUIBoxFlag_SkipViewOffsetX = (1 << 7), // ignore parent's scroll offset along the X-axis
    PBUIBoxFlag_SkipViewOffsetY = (1 << 8), // ignore parent's scroll offset along the Y-axis

    // Drawing
    PBUIBoxFlag_DrawText = (1 << 9),        // draw box text
    PBUIBoxFlag_DrawBackground = (1 << 10), // draw box background
    PBUIBoxFlag_DrawBorder = (1 << 11),     // draw box border
    PBUIBoxFlag_DrawShadow = (1 << 12),     // draw box shadow

    // Clip
    PBUIBoxFlag_Clip = (1 << 13), // clip children contents to the parent's viewport

    // Scroll
    PBUIBoxFlag_ScrollX = (1 << 14), // scroll along X-axis
    PBUIBoxFlag_ScrollY = (1 << 15), // scroll along Y-axis

    // These are only used by components and can be moved
    PBUIBoxFlag_AutoHideScrollX = (1 << 16), // only show a scrollbar if one would be necessary
    PBUIBoxFlag_AutoHideScrollY = (1 << 17), // only show a scrollbar if one would be necessary
    PBUIBoxFlag_InvertScrollX = (1 << 18),   // only show a scrollbar if one would be necessary
    PBUIBoxFlag_InvertScrollY = (1 << 19),   // only show a scrollbar if one would be necessary

    PBUIBoxFlag_FixedViewSizeX = (1 << 20), // do not store bounds, instead use a fixed-view size
    PBUIBoxFlag_FixedViewSizeY = (1 << 21), // do not store bounds, instead use a fixed-view size

    PBUIBoxFlag_ViewClampX = (1 << 22),
    PBUIBoxFlag_ViewClampY = (1 << 23),
    PBUIBoxFlag_ScreenClampX = (1 << 24),
    PBUIBoxFlag_ScreenClampY = (1 << 25),

    PBUIBoxFlag_Focusable = (1 << 26),

    PBUIBoxFlag_Hidden = (1 << 27),
} PBUIBoxFlags;

Bit flags that control a box's layout, drawing, event handling, and scrolling. Combine with bitwise OR. Composite convenience macros are defined below the enum.

PBUIBoxFlag_Draw

#define PBUIBoxFlag_Draw

all draw flags turned on

PBUISizeKind

typedef enum PBUISizeKind PB_ENUM_TYPE(u32){
    PBUISizeKind_Null,
    PBUISizeKind_Pixels,          // size by pixels
    PBUISizeKind_TextContent,     // size of text content
    PBUISizeKind_PercentOfParent, // size as a percentage of the parent
    PBUISizeKind_ChildrenSum,     // size according to the total sum of the children
    PBUISizeKind_Ratio,           // size proportional to the size on the alternate axis
    PBUISizeKind_COUNT
} PBUISizeKind;

Determines how a box's preferred size is computed along one axis. Set via PBUIStyle.width / .height using the PBUI_px(), PBUI_fill(), etc. macros.

PBUIAxis

typedef enum PBUIAxis PB_ENUM_TYPE(u32){ PBUIAxis_X, PBUIAxis_Y, PBUIAxis_COUNT } PBUIAxis;

The primary direction in which a box lays out its children. Set via PBUIStyle.direction.

PBUIAlign

typedef enum PBUIAlign PB_ENUM_TYPE(u32){
    PBUIAlign_Null,
    PBUIAlign_Start,        // start of layout axis (similar to CSS flex-start)
    PBUIAlign_End,          // end of layout axis (similar to CSS flex-end)
    PBUIAlign_Center,       // center of layout axis (similar to CSS center)
    PBUIAlign_Stretch,      // stretch all children (similar to CSS stretch)
    PBUIAlign_SpaceBetween, // space children flush to the edges (similar to CSS space-between)
    PBUIAlign_SpaceAround,  // space children with 1/2 spacing on the start and end (similar to CSS
                            // space-around)
    PBUIAlign_SpaceEvenly,  // space children evenly everywhere (similar to CSS space-evenly)
    PBUIAlign_COUNT
} PBUIAlign;

Controls child alignment along a layout axis. Analogous to CSS flex-box justify-content / align-items values. Set via PBUIStyle.align (a PBUIAlign2 for both axes independently).

PBUIAlign2

union PBUIAlign2 {
    struct {
        PBUIAlign x, y;
    };
    PBUIAlign e[2];
};

Alignment for both axes in a single struct. x aligns children along the main axis, y along the cross axis.

PBUISize

struct PBUISize {
    PBUISizeKind kind;
    f32          value;
    f32          strictness;
};

Preferred size specification for one axis.

PBUISize2

union PBUISize2 {
    struct {
        PBUISize width, height;
    };
    struct {
        PBUISize x, y;
    };
    PBUISize e[2];
};

Preferred size for both axes. Accessible as .width/.height, .x/.y, or .e[i].

PBUIShadow

struct PBUIShadow {
    PBVector2 offset; // in pixels
    f32       blur;   // blur radius, in pixels
    f32       spread; // spread radius, in pixels
    PBColor   color;
    bool      inset; // whether the shadow should be inset or outset
};

Drop or inset shadow applied to a box's background. Requires PBUIBoxFlag_DrawShadow.

PBUIBorderGrow

typedef enum PBUIBorderGrow {
    PBUIBorderGrow_CENTER = 0,
    PBUIBorderGrow_INNER = 1,
    PBUIBorderGrow_OUTER = 2,
} PBUIBorderGrow;

PBUIBorderGrow determines how a border grows

PBUIBorder

struct PBUIBorder {
    PBUIBorderGrow grow;
    f32            width;
    PBColor        color;
};

Uniform border rendered inset, on top of a box's content. Requires PBUIBoxFlag_DrawBorder.

PBUIPadding

struct PBUIPadding {
    f32 left, top, right, bottom;
};

Inner spacing between a box's edges and its children/content, in pixels.

PBUICornerRadius

struct PBUICornerRadius {
    f32 topLeft, topRight, bottomRight, bottomLeft;
};

Per-corner rounding radii in pixels. Passed via PBUIStyle.cornerRadius or PBUICornerRadiusMake().

PBUITextAlign

typedef enum PBUITextAlign PB_ENUM_TYPE(u32){
    PBUITextAlign_None,        PBUITextAlign_TopLeft,    PBUITextAlign_TopCenter,
    PBUITextAlign_TopRight,    PBUITextAlign_CenterLeft, PBUITextAlign_Center,
    PBUITextAlign_CenterRight, PBUITextAlign_BottomLeft, PBUITextAlign_BottomCenter,
    PBUITextAlign_BottomRight, PBUITextAlign_COUNT,
} PBUITextAlign;

9-position text alignment within a box's content area. Requires PBUIBoxFlag_DrawText.

PBUITextWrap

typedef enum PBUITextWrap PB_ENUM_TYPE(u32){
    PBUITextWrap_None,
    PBUITextWrap_Word,
    PBUITextWrap_COUNT,
} PBUITextWrap;

Controls whether text wraps to the next line when it exceeds the box width. @Incomplete: Not implemented yet.

PBUIDrawCommandType

typedef enum PBUIDrawCommandType PB_ENUM_TYPE(u32){
    PBUIDrawCommand_Null,       PBUIDrawCommand_Rectangle, PBUIDrawCommand_Text,
    PBUIDrawCommand_SetScissor, PBUIDrawCommand_Image,     PBUIDrawCommand_Custom,
    PBUIDrawCommand_COUNT,
} PBUIDrawCommandType;

Type tag for a draw command. The renderer iterates the draw list and dispatches on this.

PBUIDrawCommand

struct PBUIDrawCommand {
    PBUIDrawCommandType type;
    PBRectangle         rect;

    PBVector4 cornerRadius;
    f32       borderWidth;
    u8        borderGrow; // 0=center, 1=inner, 2=outer
    f32       edgeSoftness;

    PBColor color;
    PBColor colors[4];

    PBUIFont   font;
    PBStrSlice text;
    void*      data;
};

A single renderer-agnostic draw instruction produced by the UI system. Consume by switching on .type in your renderer backend. Rectangle, Text, Image, and SetScissor commands cover the built-in cases; Custom commands pass arbitrary data via .data for user-defined rendering.

PBUIDrawCommandArray

struct PBUIDrawCommandArray {
    PBUIDrawCommand* data;
    u64              count;
    u64              capacity;
};

Dynamic array of draw commands. Produced by PBUIOutputDrawCommands() each frame.

PBUIDrawCallback

#define PBUIDrawCallback(name)

Signature for a custom per-box draw callback. Attach via PBUIBoxSetDrawCallback(). Called during draw command generation with the box's computed rect and the command array to append to.

PBUIDrawCallbackProc

typedef void (PBUIBox * _Nonnull, PBRectangle, PBUIDrawCommandArray * _Nonnull) PBUIDrawCallbackProc;

Dynamic array of draw commands. Produced by PBUIOutputDrawCommands() each frame.

PBUIPushDrawCommand

bool PBUIPushDrawCommand(PBUIDrawCommandArray* cmds,
                         PBUIDrawCommand       cmd);

Append a single draw command, an array of commands, or a filled rect to a draw list.

PBUIPushDrawCommandArray

bool PBUIPushDrawCommandArray(PBUIDrawCommandArray* cmds,
                              PBUIDrawCommandArray  push_cmds);

Appends an array of draw commands to another array

PBUIPushDrawRect

bool PBUIPushDrawRect(PBUIDrawCommandArray* cmds,
                      PBRectangle           rect,
                      PBColor               color);

Pushes a single draw rectangle command

PBUIBoxEquipDraw

void PBUIBoxEquipDraw(PBUIBox* box,
                      u64      capacity);

Allocate a per-box draw command list (required before PBUIBoxDraw), or append a command to it.

PBUIBoxDraw

void PBUIBoxDraw(PBUIBox*        box,
                 PBUIDrawCommand cmd);

Makes sure the box is equipped with a draw-command list, and then pushes the draw command onto that list

PBUIStyle

struct PBUIStyle {
    // sizing and positioning
    union {
        PBVector2 minSize; // in pixels
        struct {
            f32 minWidth, minHeight;
        };
    };
    union {
        PBVector2 maxSize; // in pixels
        struct {
            f32 maxWidth, maxHeight;
        };
    };
    union {
        PBUISize2 size; // preferred box sizing (before layout constraints)
        struct {
            PBUISize width, height;
        };
    };

    // visuals
    union {
        PBVector4 cornerRadius; // in pixels
        struct {
            f32 cornerRadiusTopLeft, cornerRadiusTopRight, cornerRadiusBottomRight,
                cornerRadiusBottomLeft;
        };
    };
    PBColor color;
    PBColor backgroundColor;
    union {
        PBColor backgroundColors[4];
        struct {
            PBColor backgroundColorTopLeft, backgroundColorTopRight, backgroundColorBottomRight,
                backgroundColorBottomLeft;
        };
    };
    PBUIBorder border;
    // TODO: gradients

    // layout
    PBUIAxis   direction;  // UIAxis_X or UIAxis_Y
    PBUIAlign2 align;      // e.g. UIAlign_Start, etc.
    f32        childSpace; // in pixels

    union {
        PBVector4 padding; // the padding inside the box's content, in pixels
        struct {
            f32 paddingLeft, paddingTop, paddingRight, paddingBottom;
        };
    };

    // font and text
    PBUIFont      font;
    PBUITextAlign textAlign;
    PBUITextWrap  textWrap;

    // shadow
    PBUIShadow shadow;
    // TODO: shadow stacks

    // PBCursorStyleLegacy cursor;
};

Visual and layout properties for a PBUIBox. Set directly on box->style after creation.

PBUIBox

struct PBUIBox {
    // persistent links
    PBUIBox* nextHash;
    PBUIBox* prevHash;

    // per-frame links and data
    PBUIBox* next;
    PBUIBox* prev;
    PBUIBox* firstChild;
    PBUIBox* lastChild;
    PBUIBox* parent;
    u64      childCount;

    PBUIBox* scissor;

    // per-frame data
    PBUIKey      key;
    PBStrSlice   text;
    PBStrSlice   debugString;
    PBUIBoxFlags flags;
    PBUIStyle    style;
    PBVector2    fixedPosition;
    PBVector2    fixedSize;
    PBVector2    textSize;
    i64          order;

    // per-frame custom rendering data
    PBUIDrawCommandArray* drawCommands;
    PBUIDrawCallbackProc* drawCallback;

    void* imageData;
    void* customData;

    // per-frame computed values
    PBRectangle rect;
    PBVector2   viewSize;

    // persistent data
    u64       id;
    PBVector2 scroll; // viewOffset
    u64       firstFrameTouched;
    u64       lastFrameTouched;
    f32       hoverTime;
    f32       activeTime;
    u32       keyConflictsThisFrame;

    u64 state;
};

The fundamental UI node. Every visible element — text, panels, buttons — is a PBUIBox.

Boxes form a tree (firstChild / next / parent) rebuilt each frame. Persistent state (scroll offsets, hover/active timers, custom .state) is carried across frames via the key. Do not allocate directly; use PBUIBoxMakeFromString / PBUIBoxMakeFromKey.

Fields marked "per-frame" are reset each frame; "persistent" fields survive.

PBUIBoxSlot

struct PBUIBoxSlot {
    PBUIBox* firstHash;
    PBUIBox* lastHash;
};

Internal hash-table bucket for fast box lookup by key. Not intended for direct use.

PBUIBoxIter

struct PBUIBoxIter {
    PBUIBox* next;
    u32      pushCount;
    u32      popCount;
};

Iterator state for depth-first box tree traversal. Use with PBUIBoxIterDepthFirstPre/Post.

PBUISignal

struct PBUISignal {
    PBUIBox*  box;
    bool      hover;       // is the box being hovered by a pointer
    bool      click;       // was the box clicked (fires exactly once per pointer click)
    bool      drag;        // is the box being dragged?
    bool      down;        // is the pointer being held over the box?
    bool      pressed;     // was the pointer pressed this frame?
    bool      released;    // was the pointer released this frame?
    bool      doubleClick; // is this event a double-click?
    bool      tripleClick; // is this event a triple-click?
    u32       clickCount;  // the click count [0, 1 or 2]
    PBVector2 mouse;       // the mouse position relative to this box
    PBVector2 scroll;      // the scroll amount that on this box
    bool      changed;     // custom boolean
};

Aggregated pointer-interaction state for a box, returned by PBUISignalFromBox(). Query this each frame after PBUIEndBuild() to drive widget logic.

PBUIMeasureTextFunction

#define PBUIMeasureTextFunction(name)

Callback to measure the pixel dimensions of a text string in a given font. Required for TextContent sizing (PBUI_text_size). Supply via PBUIWindowInput.measureTextProc.

PBUIMeasureTextProc

typedef PBVector2 (PBUIFont, PBStrSlice, f32, void * _Nonnull) PBUIMeasureTextProc;

Aggregated pointer-interaction state for a box, returned by PBUISignalFromBox(). Query this each frame after PBUIEndBuild() to drive widget logic.

PBUIWindowInput

struct PBUIWindowInput {
    const PBEvent* events;
    u32            eventCount;
    f32            dt;
    PBVector2      mouse;

    PBUIMeasureTextProc* measureTextProc;
    void*                userData;
};

Per-frame input snapshot passed to PBUIBeginBuild(). Supply all events, delta time, current mouse position, and a text measure callback for TextContent sizing

PBUIState

struct PBUIState {
    PBArena* arena;
    PBArena* frameArenas[2];
    PBArena* dragArena;

    u64 frameIndex;
    u64 boxMakeCount;
    u64 nextBoxId;
    u64 subFrameIndex;

    PBUIBox* firstFreeBox;

    struct {
        PBUIBoxSlot* data;
        u64          size;
    } boxTable;

    // input
    PBRectangle     window;
    PBUIWindowInput input;
    PBVector2       mouse;
    u32             keyStates[PBKeyboardKey_COUNT];
    u32             mouseStates[PBMouseButton_COUNT];
    PBVector2       dragStartPos;

    // double and triple click handling
    PBVector2 lastMousePos;
    u32       mouseClickCount;
    f32       lastClickTimer;
    // scrolling with mouse wheel click+drag
    bool middleMouseScroll;

    bool usingKeyboardNavigation;

    PBUIBox* root;

    PBUIKey activeKey;
    PBUIKey hoverKey;
    PBUIKey clickKey;
    PBUIKey nextHoverKey;
    PBUIKey focusKey;

    PBUIDrawCommandArray commands;

    // PBCursorStyleLegacy cursor;
    PBVector2 syntheticScroll; // injected scroll (e.g. from middle-mouse drag)

    struct {
        PBUIBox* data[PBUI_STACK_MAX];
        u64      count;
    } parentStack;
};

All mutable state for one UI context. Allocate with PBUIStateAlloc(), activate with PBUISetState(). Multiple independent UI contexts are supported by swapping state pointers. Do not access internal fields directly; use the provided API functions.

PBUI_px

#define PBUI_px(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_dp

#define PBUI_dp(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_text_size

#define PBUI_text_size(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_fill

#define PBUI_fill(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_child_size

#define PBUI_child_size(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_ratio

#define PBUI_ratio(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_em

#define PBUI_em(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_rem

#define PBUI_rem(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_vw

#define PBUI_vw(x)

Size literal macros. Assign to PBUIStyle.width / .height to specify box sizing.

PBUI_px(n) — exactly n pixels PBUI_dp(n) — alias for PBUI_px(n) PBUI_text_size(n) — n × the box's text content size (requires measureTextProc) PBUI_fill(n) — n × parent size, e.g. PBUI_fill(1) = 100% of parent PBUI_child_size(n) — n × sum of children sizes PBUI_ratio(n) — n × size on the alternate axis (enforces an aspect ratio) PBUI_em(n) — n × nearest parent's font size PBUI_rem(n) — n × root box's font size PBUI_vw(n) — n × viewport width PBUI_vh(n) — n × viewport height

PBUI_vh

#define PBUI_vh(x)

a fraction of the current view height [0-1]

PBUI_size2

#define PBUI_size2(x, y)

Shorthand constructors for two-component size and alignment types.

PBUI_v2

#define PBUI_v2(x, y)

Shorthand vector constructors.

PBUI_rgb

#define PBUI_rgb(r, g, b)

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(r,g,b) — opaque RGB color PBUI_rgba(r,g,b,a) — RGBA color with explicit alpha PBUI_hex(0xRRGGBB) — opaque color from 24-bit hex PBUI_hexa(0xRRGGBBAA) — color with alpha from 32-bit hex

PBUI_rgba

#define PBUI_rgba(r, g, b, a)

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(r,g,b) — opaque RGB color PBUI_rgba(r,g,b,a) — RGBA color with explicit alpha PBUI_hex(0xRRGGBB) — opaque color from 24-bit hex PBUI_hexa(0xRRGGBBAA) — color with alpha from 32-bit hex

PBUI_hex

#define PBUI_hex(hex)

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(r,g,b) — opaque RGB color PBUI_rgba(r,g,b,a) — RGBA color with explicit alpha PBUI_hex(0xRRGGBB) — opaque color from 24-bit hex PBUI_hexa(0xRRGGBBAA) — color with alpha from 32-bit hex

PBUI_hexa

#define PBUI_hexa(hex)

Color literal macros. All component values are in [0, 1] unless noted.

PBUI_rgb(r,g,b) — opaque RGB color PBUI_rgba(r,g,b,a) — RGBA color with explicit alpha PBUI_hex(0xRRGGBB) — opaque color from 24-bit hex PBUI_hexa(0xRRGGBBAA) — color with alpha from 32-bit hex

PBUIBoxEach

#define PBUIBoxEach(box)

Iterate over a linked list of sibling boxes starting at box. Usage: for PBUIBoxEach(root->firstChild) { ... it ... }

PBStringWordScan

i64 PBStringWordScan(PBStrSlice str,
                     i64        index,
                     i64        move);

PBStringCodepointScan

i64 PBStringCodepointScan(PBStrSlice str,
                          i64        index,
                          i64        move);

PBStringReplace

PBStrSlice PBStringReplace(PBArena*   arena,
                           PBStrSlice text,
                           i64        index,
                           i64        remove_count,
                           PBStrSlice insert);

Applies a splice operation to the string, starting at index and removing up to remove_count, and inserting the insert text

PBStringFromCodepoint

PBStrSlice PBStringFromCodepoint(PBArena* arena,
                                 u32      codepoint);

PBStringFind

u64 PBStringFind(PBStrSlice str,
                 PBStrSlice search,
                 u64        start_index);

Find the offset of a substring, only looking for matches from start_index. Returns the length of the string if the substring is not found.

PBUISizeMake

PBUISize PBUISizeMake(PBUISizeKind kind,
                      f32          value,
                      f32          strictness);

Construct a PBUISize

PBUISize2Make

PBUISize2 PBUISize2Make(PBUISize x,
                        PBUISize y);

Construct a PBUISize2

PBUIFontMake

PBUIFont PBUIFontMake(PBStrSlice family,
                      f32        size,
                      f32        weight);

Construct a PBUIFont

PBUIAlign2Make

PBUIAlign2 PBUIAlign2Make(PBUIAlign x,
                          PBUIAlign y);

Construct a PBUIAlign2

PBUIShadowMake

PBUIShadow PBUIShadowMake(PBVector2 offset,
                          f32       blur,
                          f32       spread,
                          PBColor   color,
                          bool      inset);

Construct a PBUIShadow

PBUIBorderMake

PBUIBorder PBUIBorderMake(f32     width,
                          PBColor color);

Construct a PBUIBorder

PBUIPaddingMake

PBVector4 PBUIPaddingMake(f32 paddingLeft,
                          f32 paddingTop,
                          f32 paddingRight,
                          f32 paddingBottom);

Construct a PBVector4 which represents the inner padding of a box: (left, top, right, bottom)

PBUICornerRadiusMake

PBVector4 PBUICornerRadiusMake(f32 cornerRadiusTopLeft,
                               f32 cornerRadiusTopRight,
                               f32 cornerRadiusBottomRight,
                               f32 cornerRadiusBottomLeft);

Construct a PBVector4 which represents the corner radius of a box: (top left, top right, bottom right, bottom left)

PBUI__Vector4FromPadding

PBVector4 PBUI__Vector4FromPadding(PBUIPadding padding);

PBUI__Vector4FromCornerRadius

PBVector4 PBUI__Vector4FromCornerRadius(PBUICornerRadius cornerRadius);

PBUI__TextAlignToAnchor

PBVector2 PBUI__TextAlignToAnchor(PBUITextAlign align);

@Internal: converts PBUITextAlign to a normalized anchor vector.

PBUIAxisToString

PBStrSlice PBUIAxisToString(PBUIAxis axis);

Convert PBUIAxis to string

PBUIAlignToString

PBStrSlice PBUIAlignToString(PBUIAlign align);

Convert PBUIAlign to string

PBUITextAlignToString

PBStrSlice PBUITextAlignToString(PBUITextAlign textAlign);

Convert PBUITextAlign to string

PBUIKeyZero

PBUIKey PBUIKeyZero();

PBUIKeyEquals

bool PBUIKeyEquals(PBUIKey a,
                   PBUIKey b);

PBUIKeyIsZero

bool PBUIKeyIsZero(PBUIKey a);

PBUIKeyFromString

PBUIKey PBUIKeyFromString(PBUIKey    seedKey,
                          PBStrSlice string);

PBUIKeyFromStringAndIndex

PBUIKey PBUIKeyFromStringAndIndex(PBUIKey    seedKey,
                                  PBStrSlice string,
                                  u32        index);

PBUIBoxNil

PBUIBox* PBUIBoxNil();

PBUIBoxIsNil

bool PBUIBoxIsNil(PBUIBox* it);

PBUIBoxFromKey

PBUIBox* PBUIBoxFromKey(PBUIKey key);

look up a box from the previous frame by key (may return nil)

PBUIBoxFindScrollableParent

PBUIBox* PBUIBoxFindScrollableParent(PBUIBox* parent);

finds the nearest parent with a scroll flag set

PBUIBoxIterDepthFirstPre

PBUIBoxIter PBUIBoxIterDepthFirstPre(PBUIBox* box,
                                     PBUIBox* root);

use for iterating a box tree in pre-order

PBUIBoxIterDepthFirstPost

PBUIBoxIter PBUIBoxIterDepthFirstPost(PBUIBox* box,
                                      PBUIBox* root);

use for iterating a box tree in post-order

PBUITopParent

PBUIBox* PBUITopParent();

PBUIPushParent

void PBUIPushParent(PBUIBox* box);

pushes a new box onto the parent stack (new boxes will be created as children of this)

PBUIPopParent

PBUIBox* PBUIPopParent(PBUIBox* box);

pops a box off the parent stack, optionally asserts that the popped box matches (or just pass 0 otherwise)

PBDeferLoop

#define PBDeferLoop(begin, end)

Generic scope-guard loop: runs begin, executes the loop body once, then runs end.

PBUIParent

macro Scope-guarded parent push/pop. Use as: PBUIParent(box) { ... children ... }

PBUIBoxMakeFromKey

PBUIBox* PBUIBoxMakeFromKey(PBUIBoxFlags flags,
                            PBUIKey      key);

Create or reuse a box for this frame. If a box with the same key existed last frame its persistent state (scroll, hover timers, .state) is retained.

It is recommended to use PBUIBoxMakeFromString instead of this function.

PBUIBoxMakeFromString

PBUIBox* PBUIBoxMakeFromString(PBUIBoxFlags flags,
                               PBStrSlice   string);

Construct a box and add it as a child to the current parent

PBUIBoxMakeFromStringF

PBUIBox* PBUIBoxMakeFromStringF(PBUIBoxFlags flags,
                                const char*  fmt,
                                ...);

Same as PBUIBoxMakeFromString, but takes a format string instead

PBUIBoxKey

PBUIKey PBUIBoxKey(PBStrSlice string,
                   u64        index);

Shorthand for: PBUIKeyFromStringAndIndex(PBUIActiveSeedKey(), string, index)

PBUIBoxSetText

void PBUIBoxSetText(PBUIBox*   box,
                    PBStrSlice string);

Set the display text on a box (requires PBUIBoxFlag_DrawText).

PBUIBoxSetFixedPosition

void PBUIBoxSetFixedPosition(PBUIBox*  box,
                             PBVector2 pos);

Override a box's position absolutely in pixels (requires PBUIBoxFlag_FloatingX/Y).

PBUIBoxSetFixedSize

void PBUIBoxSetFixedSize(PBUIBox*  box,
                         PBVector2 size);

Force a box to an exact pixel size (requires PBUIBoxFlag_FixedWidth/Height).

PBUISignalFromBox

PBUISignal PBUISignalFromBox(PBUIBox* box);

Query all pointer-interaction state for a box in a single call.

PBUIBoxFindAtPoint

PBUIBox* PBUIBoxFindAtPoint(PBUIBox*     root,
                            PBVector2    pos,
                            PBUIBoxFlags flags);

Walk the box tree from root and return the topmost box under pos matching flags.

PBUIBoxSetParent

void PBUIBoxSetParent(PBUIBox* box,
                      PBUIBox* parent);

Reparent a box or insert it after a sibling in the child list.

PBUIBoxInsertAfter

void PBUIBoxInsertAfter(PBUIBox* box,
                        PBUIBox* sibling);

PBUIBoxScrollIntoView

void PBUIBoxScrollIntoView(PBUIBox* box);

Request the nearest scrollable ancestor to scroll this box into view.

PBUIBoxSetDrawCallback

void PBUIBoxSetDrawCallback(PBUIBox*              box,
                            PBUIDrawCallbackProc* callback);

Attach a custom draw callback; called during draw-command generation. Requires PBUIBoxEquipDraw().

PBUIBoxGetComputedRect

PBRectangle PBUIBoxGetComputedRect(PBUIBox* box);

Returns the box's computed screen-space rectangle after layout. Call after PBUIEndBuild().

PBUISetState

void PBUISetState(PBUIState* it);

Sets the current global UI state

PBUIGetState

PBUIState* PBUIGetState();

Gets the current global UI state

PBUIRoot

PBUIBox* PBUIRoot();

The root-most box of the current UI state

PBUITopBox

PBUIBox* PBUITopBox();

The last box created in the tree

PBUIStateGetMemorySize

u64 PBUIStateGetMemorySize();

Returns the minimum initial arena size for a UI state allocation

PBUIStateAlloc

PBUIState* PBUIStateAlloc(PBArena* arena);

Allocates and initializes a new UI state

PBUIStateFree

void PBUIStateFree(PBUIState* statePtr);

Frees the UI state and its arena, and sets *statePtr to NULL

PBUIFrameArena

PBArena* PBUIFrameArena();

Returns an arena that is valid for the lifetime of this frame

PBUIfmt

PBStrSlice PBUIfmt(const char* fmt, ...);

Prints a C-style formatted string into the frame arena

PBUIMeasureText

PBVector2 PBUIMeasureText(PBUIFont   font,
                          PBStrSlice text,
                          f32        maxWidth);

Measures the text size with the given font, optionally with a maxWidth (set to 0 for none)

PBUIBeginBuild

void PBUIBeginBuild(PBRectangle     window,
                    PBUIWindowInput input);

Equivalent to calling PBUIBeginFrame then PBUIBeginLayout

PBUIEndBuild

void PBUIEndBuild();

Equivalent to calling PBUIEndFrame then PBUIEndLayout

PBUIBeginFrame

void PBUIBeginFrame(PBRectangle     window,
                    PBUIWindowInput input);

Starts a UI tree build (call this once per frame/build)

PBUIEndFrame

void PBUIEndFrame();

Ends a UI tree build (call this once per frame/build)

PBUIBeginLayout

void PBUIBeginLayout();

Begins a layout pass, can be called multiple times per frame/build

PBUIEndLayout

void PBUIEndLayout();

Ends a layout pass, can be called multiple times per frame/build

PBUICalcSizesStandalone

void PBUICalcSizesStandalone(PBUIBox* root,
                             PBUIAxis axis);

PBUICalcSizesUpwardsDependent

void PBUICalcSizesUpwardsDependent(PBUIBox* root,
                                   PBUIAxis axis);

PBUICalcSizesDownwardsDepenedent

void PBUICalcSizesDownwardsDepenedent(PBUIBox* root,
                                      PBUIAxis axis);

PBUILayoutEnforceConstraints

void PBUILayoutEnforceConstraints(PBUIBox* root,
                                  PBUIAxis axis);

PBUILayoutPosition

void PBUILayoutPosition(PBUIBox* root,
                        PBUIAxis axis);

PBUILayoutRoot

void PBUILayoutRoot(PBUIBox* root,
                    PBUIAxis axis);

Applies a full layout pass along the given axis

PBUIOutputDrawCommands

PBUIDrawCommandArray PBUIOutputDrawCommands(PBArena*   arena,
                                            PBUIState* state);

Outputs a list of draw commands for the UI tree

PBUIKeyPressed

bool PBUIKeyPressed(PBKeyboardKey key);

PBUIKeyReleased

bool PBUIKeyReleased(PBKeyboardKey key);

PBUIKeyRepeat

bool PBUIKeyRepeat(PBKeyboardKey key);

PBUIKeyPressedOrRepeat

bool PBUIKeyPressedOrRepeat(PBKeyboardKey key);

PBUIKeyDown

bool PBUIKeyDown(PBKeyboardKey key);

PBUIEventOfType

const PBEvent* PBUIEventOfType(PBEventType    type,
                               const PBEvent* after);

Returns the first event of the given type this frame, optionally starting after a given event. Pass NULL for after to start from the beginning. Returns NULL if no matching event is found.

PBUIGetEvent

const PBEvent* PBUIGetEvent(PBUIBox* box);

Returns the first event this frame if the mouse is within box's rect, or any event if box is NULL. Returns NULL if there are no events or the mouse is outside the box.

PBUIMousePressed

bool PBUIMousePressed(PBMouseButton button);

PBUIMouseReleased

bool PBUIMouseReleased(PBMouseButton button);

PBUIMouseDown

bool PBUIMouseDown(PBMouseButton button);

PBUIMousePosition

PBVector2 PBUIMousePosition();

PBUIDragStart

PBVector2 PBUIDragStart();

PBUIDragDelta

PBVector2 PBUIDragDelta();

PBUIScrollAmount

PBVector2 PBUIScrollAmount();

PBUIBoxIsHover

bool PBUIBoxIsHover(PBUIBox* box);

PBUIBoxIsActive

bool PBUIBoxIsActive(PBUIBox* box);

PBUIBoxIsDown

bool PBUIBoxIsDown(PBUIBox* box);

PBUIBoxOnPressed

bool PBUIBoxOnPressed(PBUIBox* box);

PBUIBoxOnReleased

bool PBUIBoxOnReleased(PBUIBox* box);

PBUIBoxIsFocused

bool PBUIBoxIsFocused(PBUIBox* box);

PBUIBoxOnClick

bool PBUIBoxOnClick(PBUIBox* box);

PBUIBoxIsDrag

bool PBUIBoxIsDrag(PBUIBox* box);

PBUIBoxOnDrop

bool PBUIBoxOnDrop(PBUIBox* box);

PBUIBoxIsDropTarget

bool PBUIBoxIsDropTarget(PBUIBox* box);

PBUIBoxClick

void PBUIBoxClick(PBUIBox* box);

Programmatically click a box

PBUIBoxFocus

void PBUIBoxFocus(PBUIBox* box);

Programmatically focus a box

PBUISetDragDataSize

void PBUISetDragDataSize(u8* data,
                         u64 size);

Set global drag data

PBUIGetDragDataSize

void* PBUIGetDragDataSize(u64 size);

Get global drag data

PBUIBoxOnMount

bool PBUIBoxOnMount(PBUIBox* box);

PBUIBoxPointToLocal

PBVector2 PBUIBoxPointToLocal(PBUIBox*  box,
                              PBVector2 point);

Converts a point in UI-space to local box-space

PBUIBoxGetScroll

PBVector2 PBUIBoxGetScroll(PBUIBox* box);

PBUIGetActiveBox

PBUIBox* PBUIGetActiveBox();

PBUIGetHoverBox

PBUIBox* PBUIGetHoverBox();

PBUISpacer

PBUIBox* PBUISpacer(PBUISize size);

Create a gap between two boxes (similar to "margin" in some UI systems)

PBUIText

PBUIBox* PBUIText(PBUIFont   font,
                  PBStrSlice text);

A simple text element

PBUIDiv

PBUIBox* PBUIDiv(PBStrSlice label);

A simple divider that expands to fill it's child contents

PBUIDrawCommmands

void PBUIDrawCommmands(PBUIDrawCommandArray cmds);

PBUIDrawState

void PBUIDrawState(PBArena*   scratch,
                   PBUIState* state);

#include <playbit/ui_components.h>

PBUINamedRowBegin

int* PBUINamedRowBegin(PBStrSlice name);

Begin a named parent row. Must be paired with PBUINamedRowEnd

PBUINamedRowEnd

void PBUINamedRowEnd();

End a named parent row

PBUIRowBegin

int* PBUIRowBegin();

Begin a row. Must be paired with PBUIRowEnd

PBUIRowEnd

void PBUIRowEnd();

End a row

PBUINamedColumnBegin

int* PBUINamedColumnBegin(PBStrSlice name);

Begin a named parent column. Must be paired with PBUINamedColumnEnd

PBUINamedColumnEnd

void PBUINamedColumnEnd();

End a named parent column

PBUIColumnBegin

int* PBUIColumnBegin();

Begin a column. Must be paired with PBUIColumnEnd

PBUIColumnEnd

void PBUIColumnEnd();

End a column

PBUIButtonProps

struct PBUIButtonProps {
    PBStrSlice text;
    bool       disabled;
};
Clickable button. Returns the box; check PBUISignalFromBox(box).click for activation.

Use `UIButtonP(.text = PBStrLit("OK"))` for named-field construction.

PBUIButton

int* PBUIButton(PBUIButtonProps props);

Construct a button

PBUISlider

int* PBUISlider(f32* value);

Horizontal slider that reads and writes a float value in [0, 1]. Check .changed on the signal.

PBUILabel

int* PBUILabel(PBStrSlice text);

Non-interactive text label. Sized to text content.

PBUICheckbox

int* PBUICheckbox(bool* value);

Toggle checkbox. Reads and writes *value; check PBUISignalFromBox(box).changed for updates.

PBUIColorPicker

int* PBUIColorPicker(int* color);

Inline HSV color picker panel, writes to color on change

PBUIColorSwatch

int* PBUIColorSwatch(int color);

Non-interactive color preview rectangle

PBUIColorPickerSwatch

int* PBUIColorPickerSwatch(int*  color,
                           bool* open);

Swatch that toggles a picker popover; *open controls visibility

PBUIScrollViewBegin

int* PBUIScrollViewBegin(u32 flags);

Begin a scrollable container. Pass PBUIBoxFlag_ScrollX / PBUIBoxFlag_ScrollY to enable axes. Must be paired with PBUIScrollViewEnd.

PBUIScrollViewEnd

void PBUIScrollViewEnd(int* scroll);

Ends a scroll view

PBUIVirtualListCursor

struct PBUIVirtualListCursor {
    PBUIBox* box;
    i64      start; // first item index to render (inclusive)
    i64      end;   // last item index to render (exclusive)
};

Virtual list with Y-only scrolling. Only the visible items need to be rendered each frame.

Returns the scroll view box so you can set its size and style. Must be paired with PBUIVirtualListEnd.

Usage:
    PBUIVirtualListCursor cursor = PBUIVirtualListBegin(1000, 24.0f);
    list->style.size = ...; // size the viewport
    for (i64 index = cursor.start; index < cursor.end; index += 1)
    {
        // build item i as a child box
    }
    PBUIVirtualListEnd(list);

PBUIVirtualListBegin

PBUIVirtualListCursor PBUIVirtualListBegin(i64 itemCount,
                                           f32 itemHeight);

PBUIVirtualListEnd

void PBUIVirtualListEnd(PBUIVirtualListCursor cursor);

PBUITooltipExt

int* PBUITooltipExt(int*       box,
                    int        anchor,
                    int        align,
                    PBStrSlice text);

Tooltip overlay rendered on top of all other content. Positions tooltip at a custom anchor/alignment, relative to an explicit box.

PBUITooltip

int* PBUITooltip(PBStrSlice text);

Construct a tooltip that attaches to the most recently built box

PBUIImage

int* PBUIImage(u64 imageID);

Render an image identified by an opaque backend image ID. Size the box with FixedSize flags.

PBUITextInputProps

struct PBUITextInputProps {
    PBStrSlice key;         // unique string key for persistent state (cursor position, selection)
    PBStrSlice text;        // current string value; read box->state after edits for updated content
    PBStrSlice placeholder; // hint text shown when the field is empty
    bool       disabled;    // prevents editing when true
};

PBUITextInput

int* PBUITextInput(PBUITextInputProps props);

Single-line text input field with full keyboard editing support.

Use with: `UITextInputP(.key = PBStrLit("search"), .placeholder = PBStrLit("Search..."))`

PBUITextInputP

macro PBUIBox* PBUITextInputP(props...)

Ergonomic helper for PBUITextInput((PBUITextInputProps){ props... })

PBUIDevTools

int* PBUIDevTools(int* inspect);
Developer tools overlay. Pass the PBUIState to inspect for an interactive box-tree viewer
with live style, size, and rect information. Useful for debugging layout issues.