DVX_GUI/dvx/dvxWidget.h
2026-03-09 20:55:12 -05:00

273 lines
8 KiB
C

// dvxWidget.h — Widget system for DV/X GUI
#ifndef DVX_WIDGET_H
#define DVX_WIDGET_H
#include "dvxTypes.h"
// Forward declaration
struct AppContextT;
// ============================================================
// Size specifications
// ============================================================
//
// Tagged size values encode both a unit type and a numeric value.
// Use wgtPixels(), wgtChars(), or wgtPercent() to create them.
// A raw 0 means "auto" (use the widget's natural size).
#define WGT_SIZE_TYPE_MASK 0xC0000000
#define WGT_SIZE_VAL_MASK 0x3FFFFFFF
#define WGT_SIZE_PIXELS 0x00000000
#define WGT_SIZE_CHARS 0x40000000
#define WGT_SIZE_PERCENT 0x80000000
static inline int32_t wgtPixels(int32_t v) {
return (int32_t)(WGT_SIZE_PIXELS | ((uint32_t)v & WGT_SIZE_VAL_MASK));
}
static inline int32_t wgtChars(int32_t v) {
return (int32_t)(WGT_SIZE_CHARS | ((uint32_t)v & WGT_SIZE_VAL_MASK));
}
static inline int32_t wgtPercent(int32_t v) {
return (int32_t)(WGT_SIZE_PERCENT | ((uint32_t)v & WGT_SIZE_VAL_MASK));
}
// ============================================================
// Widget type enum
// ============================================================
typedef enum {
WidgetVBoxE,
WidgetHBoxE,
WidgetLabelE,
WidgetButtonE,
WidgetCheckboxE,
WidgetRadioGroupE,
WidgetRadioE,
WidgetTextInputE,
WidgetTextAreaE,
WidgetListBoxE,
WidgetSpacerE,
WidgetSeparatorE,
WidgetFrameE
} WidgetTypeE;
// ============================================================
// Alignment enum
// ============================================================
//
// Controls main-axis alignment of children within a container.
// HBox: AlignStartE=left, AlignCenterE=center, AlignEndE=right
// VBox: AlignStartE=top, AlignCenterE=center, AlignEndE=bottom
typedef enum {
AlignStartE,
AlignCenterE,
AlignEndE
} WidgetAlignE;
// ============================================================
// Widget structure
// ============================================================
#define MAX_WIDGET_NAME 32
typedef struct WidgetT {
WidgetTypeE type;
char name[MAX_WIDGET_NAME];
// Tree linkage
struct WidgetT *parent;
struct WidgetT *firstChild;
struct WidgetT *lastChild;
struct WidgetT *nextSibling;
WindowT *window;
// Computed geometry (relative to window content area)
int32_t x;
int32_t y;
int32_t w;
int32_t h;
// Computed minimum size (set by layout engine)
int32_t calcMinW;
int32_t calcMinH;
// Size hints (tagged: wgtPixels/wgtChars/wgtPercent, 0 = auto)
int32_t minW;
int32_t minH;
int32_t maxW; // 0 = no limit
int32_t maxH;
int32_t prefW; // preferred size, 0 = auto
int32_t prefH;
int32_t weight; // extra-space distribution (0 = fixed, 100 = normal)
// Container properties
WidgetAlignE align; // main-axis alignment for children
int32_t spacing; // tagged size for spacing between children (0 = default)
int32_t padding; // tagged size for internal padding (0 = default)
// State
bool visible;
bool enabled;
bool focused;
// User data and callbacks
void *userData;
void (*onClick)(struct WidgetT *w);
void (*onChange)(struct WidgetT *w);
// Type-specific data
union {
struct {
const char *text;
} label;
struct {
const char *text;
bool pressed;
} button;
struct {
const char *text;
bool checked;
} checkbox;
struct {
int32_t selectedIdx;
} radioGroup;
struct {
const char *text;
int32_t index;
} radio;
struct {
char *buf;
int32_t bufSize;
int32_t len;
int32_t cursorPos;
int32_t scrollOff;
} textInput;
struct {
char *buf;
int32_t bufSize;
int32_t len;
int32_t cursorRow;
int32_t cursorCol;
int32_t scrollRow;
} textArea;
struct {
const char **items;
int32_t itemCount;
int32_t selectedIdx;
int32_t scrollPos;
} listBox;
struct {
bool vertical;
} separator;
struct {
const char *title;
} frame;
} as;
} WidgetT;
// ============================================================
// Window integration
// ============================================================
// Set up a window for widgets. Returns the root container (VBox).
// Automatically installs onPaint, onMouse, onKey, and onResize handlers.
WidgetT *wgtInitWindow(struct AppContextT *ctx, WindowT *win);
// ============================================================
// Container creation
// ============================================================
WidgetT *wgtVBox(WidgetT *parent);
WidgetT *wgtHBox(WidgetT *parent);
WidgetT *wgtFrame(WidgetT *parent, const char *title);
// ============================================================
// Basic widgets
// ============================================================
WidgetT *wgtLabel(WidgetT *parent, const char *text);
WidgetT *wgtButton(WidgetT *parent, const char *text);
WidgetT *wgtCheckbox(WidgetT *parent, const char *text);
WidgetT *wgtTextInput(WidgetT *parent, int32_t maxLen);
// ============================================================
// Radio buttons
// ============================================================
WidgetT *wgtRadioGroup(WidgetT *parent);
WidgetT *wgtRadio(WidgetT *parent, const char *text);
// ============================================================
// Spacing and visual dividers
// ============================================================
WidgetT *wgtSpacer(WidgetT *parent);
WidgetT *wgtHSeparator(WidgetT *parent);
WidgetT *wgtVSeparator(WidgetT *parent);
// ============================================================
// Complex widgets
// ============================================================
WidgetT *wgtListBox(WidgetT *parent);
WidgetT *wgtTextArea(WidgetT *parent, int32_t maxLen);
// ============================================================
// Operations
// ============================================================
// Mark a widget (and ancestors) for relayout and repaint
void wgtInvalidate(WidgetT *w);
// Set/get widget text (label, button, textInput, etc.)
void wgtSetText(WidgetT *w, const char *text);
const char *wgtGetText(const WidgetT *w);
// Enable/disable a widget
void wgtSetEnabled(WidgetT *w, bool enabled);
// Show/hide a widget
void wgtSetVisible(WidgetT *w, bool visible);
// Find a widget by name (searches the subtree rooted at root)
WidgetT *wgtFind(WidgetT *root, const char *name);
// Destroy a widget and all its children (removes from parent)
void wgtDestroy(WidgetT *w);
// ============================================================
// List box operations
// ============================================================
void wgtListBoxSetItems(WidgetT *w, const char **items, int32_t count);
int32_t wgtListBoxGetSelected(const WidgetT *w);
void wgtListBoxSetSelected(WidgetT *w, int32_t idx);
// ============================================================
// Layout (called internally; available for manual trigger)
// ============================================================
// Resolve a tagged size to pixels
int32_t wgtResolveSize(int32_t taggedSize, int32_t parentSize, int32_t charWidth);
// Run layout on the entire widget tree
void wgtLayout(WidgetT *root, int32_t availW, int32_t availH,
const BitmapFontT *font);
// Paint the entire widget tree
void wgtPaint(WidgetT *root, DisplayT *d, const BlitOpsT *ops,
const BitmapFontT *font, const ColorSchemeT *colors);
#endif // DVX_WIDGET_H