# DVX Widget Modules Individual widget type implementations for the DVX GUI, each built as a separate `.wgt` DXE module. The loader scans the `WIDGETS/` directory recursively at startup and loads every `.wgt` file it finds, calling `wgtRegister()` on each to fill the widget class table. Drop a new `.wgt` file in the directory and it is automatically available -- no loader or core library changes needed. ## How Widget DXEs Work Each `.wgt` module contains: 1. The widget implementation (paint, layout, mouse/key handlers) 2. A `static const WidgetClassT` vtable definition 3. A `wgtRegister()` function that writes the vtable pointer into `widgetClassTable[]` at the widget's enum slot 4. The public API functions (e.g. `wgtTreeView()`, `wgtTreeViewGetSelected()`) At load time, the module resolves its dependencies against: - The loader's `dlregsym` table (platform functions, libc) - `libtasks.lib` exports (stb_ds dynamic arrays) - `libdvx.lib` exports (widget infrastructure: `widgetAlloc`, `widgetClassTable`, `widgetScrollbarThumb`, shared state, etc.) - Other widget modules loaded earlier (via `RTLD_GLOBAL`) ## Widget Catalog | Module | Widget Types | Description | |--------|-------------|-------------| | `box.wgt` | VBox, HBox, Frame | Containers: vertical/horizontal box layout, titled frame | | `button.wgt` | Button | Push button with text and keyboard accelerator | | `canvas.wgt` | Canvas | Freeform drawing surface with mouse callbacks | | `checkbox.wgt` | Checkbox | Toggle checkbox with label | | `combobox.wgt` | ComboBox | Editable text input with dropdown list | | `dropdown.wgt` | Dropdown | Non-editable dropdown selector | | `image.wgt` | Image | Static image display (BMP/PNG/JPEG/GIF) | | `imgbtn.wgt` | ImageButton | Button with icon image | | `label.wgt` | Label | Static text display with optional accelerator | | `listbox.wgt` | ListBox | Scrollable string list with single/multi select | | `listview.wgt` | ListView | Multi-column list with headers, sorting, column resize | | `progress.wgt` | ProgressBar | Horizontal or vertical progress indicator | | `radio.wgt` | RadioGroup, Radio | Mutually exclusive option buttons | | `scrlpane.wgt` | ScrollPane | Scrollable viewport for oversized content | | `separatr.wgt` | Separator | Horizontal or vertical divider line | | `slider.wgt` | Slider | Horizontal value slider with thumb | | `spacer.wgt` | Spacer | Invisible layout spacer | | `spinner.wgt` | Spinner | Numeric input with up/down buttons | | `splitter.wgt` | Splitter | Resizable two-pane divider | | `statbar.wgt` | StatusBar | Horizontal bar at window bottom | | `tabctrl.wgt` | TabControl, TabPage | Tabbed page container | | `terminal.wgt` | AnsiTerm | VT100 terminal emulator with scrollback | | `textinpt.wgt` | TextInput, TextArea | Single-line and multi-line text editing | | `timer.wgt` | Timer | Periodic callback (no visual) | | `toolbar.wgt` | Toolbar | Horizontal button/widget bar | | `treeview.wgt` | TreeView, TreeItem | Hierarchical tree with expand/collapse | 26 modules implementing 32 widget types (some modules register multiple related types). ## Writing a New Widget 1. Create `widgets/myWidget.c` 2. Include `"widgetInternal.h"` for infrastructure access 3. Implement paint, calcMinSize, and event handlers as needed 4. Define a `static const WidgetClassT` with your vtable 5. Add a `wgtRegister()` function: ```c void wgtRegister(void) { widgetClassTable[MyWidgetTypeE] = &sClassMyWidget; } ``` 6. Add the new enum value to `WidgetTypeE` in `core/dvxWidget.h` (or use `wgtRegisterClass()` for a fully dynamic type ID) 7. Add public API functions (e.g. `wgtMyWidget()`) that call `widgetAlloc(parent, MyWidgetTypeE)` 8. Add a build rule in `widgets/Makefile` 9. Build -- the loader discovers and loads it automatically ## Building ``` make # compiles all widget .c files, creates .wgt modules in ../bin/widgets/ make clean ``` Each `.wgt` is created with `dxe3gen -E _wgt -U`, which exports all symbols starting with `wgt` (public API + `wgtRegister`) and allows unresolved symbols (resolved at load time from other modules).