DVX_GUI/widgets/README.md
2026-03-22 21:03:10 -05:00

4.1 KiB

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:
    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).