From 5f3aec3144ccf44947f98b14422ef237a2201f53 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Thu, 12 Mar 2026 22:12:25 -0500 Subject: [PATCH] Documentation update. --- dvx/README.md | 115 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/dvx/README.md b/dvx/README.md index d2313c9..3f251c7 100644 --- a/dvx/README.md +++ b/dvx/README.md @@ -53,6 +53,24 @@ Supporting files: | `thirdparty/stb_image.h` | Third-party single-header image loader | | `thirdparty/stb_image_write.h` | Third-party single-header image writer | +The widget system lives in `widgets/`: + +| File | Purpose | +|------|---------| +| `widgets/widgetInternal.h` | Shared internal header: vtable type, constants, cross-widget prototypes | +| `widgets/widgetClass.c` | Widget class table: one `WidgetClassT` vtable entry per widget type | +| `widgets/widgetCore.c` | Allocation, tree ops, hit testing, flag-based type queries | +| `widgets/widgetLayout.c` | Two-pass layout engine (measure + arrange) | +| `widgets/widgetEvent.c` | Mouse, keyboard, scroll, resize, and paint event dispatch | +| `widgets/widgetOps.c` | Paint dispatcher, public operations (`wgtFind`, `wgtDestroy`, etc.) | +| `widgets/widget*.c` | One file per widget type (button, checkbox, slider, etc.) | + +Each widget type is self-contained in its own `.c` file. Dispatch for +paint, layout, mouse, keyboard, getText/setText, and destroy is driven +by a per-type vtable (`WidgetClassT`) rather than switch statements in +the core files. Adding a new widget type requires only a new `.c` file +and an entry in the class table. + ## Quick start ```c @@ -343,6 +361,54 @@ int32_t textWidth(const BitmapFontT *font, const char *text); Draw text using the built-in 8-pixel-wide bitmap font. `opaque` controls whether background pixels are drawn. `drawChar` returns the advance width. +```c +void drawTermRow(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, + int32_t x, int32_t y, int32_t cols, + const uint8_t *lineData, const uint32_t *palette, + bool blinkVisible, int32_t cursorCol); +``` +Bulk-render a row of terminal character cells. `lineData` points to +`(char, attr)` byte pairs (2 bytes per cell). `palette` is a 16-entry +packed-color table. `blinkVisible` controls blink attribute visibility. +`cursorCol` is the column to draw inverted (-1 for no cursor). This is +much faster than calling `drawChar` per cell because clip bounds are +computed once for the whole row and there is no per-character function +call overhead. + +```c +char accelParse(const char *text); +``` +Parse an accelerator key from text with `&` markers (e.g. `"E&xit"` returns +`'x'`). Returns the lowercase accelerator character, or 0 if none found. + +```c +void drawTextAccel(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, + int32_t x, int32_t y, const char *text, + uint32_t fg, uint32_t bg, bool opaque); +int32_t textWidthAccel(const BitmapFontT *font, const char *text); +``` +Draw/measure text with `&` accelerator processing. The character after `&` +is underlined. `&&` produces a literal `&`. `textWidthAccel` returns the +width in pixels, excluding `&` markers. + +```c +void drawFocusRect(DisplayT *d, const BlitOpsT *ops, + int32_t x, int32_t y, int32_t w, int32_t h, + uint32_t color); +``` +Draw a dotted rectangle outline (every other pixel). Used to indicate +keyboard focus on widgets. + +```c +void drawMaskedBitmap(DisplayT *d, const BlitOpsT *ops, + int32_t x, int32_t y, int32_t w, int32_t h, + const uint16_t *andMask, const uint16_t *xorData, + uint32_t fgColor, uint32_t bgColor); +``` +Draw a 1-bit bitmap with AND/XOR masks (used for mouse cursors). Each row +is a `uint16_t`. Pixels where the AND mask is 0 are drawn using the XOR +data to select `fgColor` or `bgColor`. + ```c void drawHLine(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, uint32_t color); @@ -545,6 +611,8 @@ WidgetT *wgtTreeView(WidgetT *parent); WidgetT *wgtTreeItem(WidgetT *parent, const char *text); void wgtTreeItemSetExpanded(WidgetT *w, bool expanded); bool wgtTreeItemIsExpanded(const WidgetT *w); +WidgetT *wgtTreeViewGetSelected(const WidgetT *w); +void wgtTreeViewSetSelected(WidgetT *w, WidgetT *item); ``` Hierarchical tree with expand/collapse support. Create a tree view, then add items as children. Nest items by adding them as children of other @@ -559,6 +627,9 @@ scrolling on trough clicks. Default weight is 100. Set `onClick` on individual tree items to handle selection, or `onChange` to be notified of expand/collapse. +`wgtTreeViewGetSelected` returns the currently selected tree item (or NULL). +`wgtTreeViewSetSelected` sets the selection programmatically. + ### Image ```c @@ -683,9 +754,22 @@ via `writeFn` (arrows become `ESC[A`..`ESC[D`, etc.). int32_t wgtAnsiTermPoll(WidgetT *w); ``` Poll the comm interface for incoming data and process it through the -ANSI parser. Returns the number of bytes read. Call this from your -event loop or idle handler, then `wgtInvalidate()` if the return -value is nonzero. +ANSI parser. Also handles cursor blink and text blink timers. Returns +the number of bytes read. When using `dvxUpdate()`, terminal polling +is handled automatically -- call this manually only when running your +own event loop. + +```c +int32_t wgtAnsiTermRepaint(WidgetT *w, int32_t *outY, int32_t *outH); +``` +Fast repaint: renders only dirty rows directly into the window's content +buffer, bypassing the full widget paint pipeline (no clear, no relayout, +no other widgets). Returns the number of rows repainted (0 if nothing +was dirty). If `outY` and `outH` are non-NULL, they receive the +content-buffer-relative Y coordinate and height of the repainted region, +for targeted dirty-rect invalidation. Uses `drawTermRow()` internally +for efficient bulk rendering. When using `dvxUpdate()`, this is called +automatically after `wgtAnsiTermPoll()`. ```c void wgtAnsiTermSetScrollback(WidgetT *w, int32_t maxLines); @@ -777,6 +861,31 @@ When enabled, draws 1px neon-colored borders around all layout containers so their bounds are visible. Each container gets a distinct color derived from its pointer. +### Layout and paint internals + +These are called automatically by `wgtInvalidate()`, but are available +for manual use when embedding the widget system in a custom event loop. + +```c +int32_t wgtResolveSize(int32_t taggedSize, int32_t parentSize, int32_t charWidth); +``` +Convert a tagged size (from `wgtPixels`, `wgtChars`, or `wgtPercent`) to +a pixel value given the parent's size and the font's character width. + +```c +void wgtLayout(WidgetT *root, int32_t availW, int32_t availH, + const BitmapFontT *font); +``` +Run the two-pass layout engine on the widget tree: measure minimum sizes +bottom-up, then distribute available space top-down. Sets `x`, `y`, `w`, +`h` on every widget. + +```c +void wgtPaint(WidgetT *root, DisplayT *d, const BlitOpsT *ops, + const BitmapFontT *font, const ColorSchemeT *colors); +``` +Paint the entire widget tree into the window's content buffer. + ### List box operations ```c