DVX_GUI/apps/dvxbasic/formrt/formrt.h

153 lines
6.8 KiB
C

// formrt.h -- DVX BASIC form runtime
//
// Bridges BASIC programs to the DVX widget system. Control types
// are resolved dynamically via WgtIfaceT interface descriptors
// registered by .wgt DXE files. Properties and methods are
// dispatched generically through descriptors. Events fire by
// looking up ControlName_EventName in the compiled module's
// procedure table and calling into the VM.
#ifndef DVXBASIC_FORMRT_H
#define DVXBASIC_FORMRT_H
#include "../runtime/vm.h"
#include "../runtime/values.h"
#include "dvxApp.h"
#include "dvxWgt.h"
// ============================================================
// Forward declarations
// ============================================================
typedef struct BasFormT BasFormT;
typedef struct BasControlT BasControlT;
// ============================================================
// Limits
// ============================================================
#define BAS_MAX_CTRL_NAME 32
// ============================================================
// Menu ID to name mapping for event dispatch
// ============================================================
typedef struct {
int32_t id;
char name[BAS_MAX_CTRL_NAME];
BasControlT *proxy; // heap-allocated proxy for property access (widget=NULL, menuId stored)
} BasMenuIdMapT;
// ============================================================
// Control instance (a widget on a form)
// ============================================================
#define BAS_MAX_TEXT_BUF 256
typedef struct BasControlT {
char name[BAS_MAX_CTRL_NAME]; // VB control name (e.g. "Command1")
char typeName[BAS_MAX_CTRL_NAME]; // VB type name (e.g. "CommandButton")
int32_t index; // control array index (-1 = not in array)
WidgetT *widget; // the DVX widget
BasFormT *form; // owning form
const WgtIfaceT *iface; // interface descriptor (from .wgt)
char textBuf[BAS_MAX_TEXT_BUF]; // persistent text for Caption/Text
char dataSource[BAS_MAX_CTRL_NAME]; // name of Data control for binding
char dataField[BAS_MAX_CTRL_NAME]; // column name for binding
int32_t menuId; // WM menu item ID (>0 for menu items, 0 for controls)
} BasControlT;
// ============================================================
// Form instance (a DVX window with controls)
// ============================================================
typedef struct BasFormT {
char name[BAS_MAX_CTRL_NAME]; // form name (e.g. "Form1")
WindowT *window; // DVX window
WidgetT *root; // widget root (from wgtInitWindow)
WidgetT *contentBox; // VBox/HBox for user controls
AppContextT *ctx; // DVX app context
BasControlT **controls; // stb_ds array of heap-allocated pointers
int32_t controlCount;
BasVmT *vm; // VM for event dispatch
BasModuleT *module; // compiled module (for SUB lookup)
// Form-level properties (accumulated during .frm parsing)
int32_t frmWidth;
int32_t frmHeight;
int32_t frmLeft;
int32_t frmTop;
bool frmResizable;
bool frmHasResizable; // true if Resizable was explicitly set
bool frmCentered;
bool frmAutoSize;
char frmLayout[32]; // "VBox", "HBox", or "WrapBox"
// Per-form variable storage (allocated at load, freed at unload)
BasValueT *formVars;
int32_t formVarCount;
// Menu ID to name mapping (for event dispatch)
BasMenuIdMapT *menuIdMap;
int32_t menuIdMapCount;
// Synthetic control entry for the form itself, so that
// FormName.Property works through the same getProp/setProp path.
BasControlT formCtrl;
} BasFormT;
// ============================================================
// Form runtime context
// ============================================================
// Cached .frm source for reload after unload
typedef struct {
char formName[BAS_MAX_CTRL_NAME];
char *frmSource; // malloc'd copy of .frm text
int32_t frmSourceLen;
} BasFrmCacheT;
typedef struct {
AppContextT *ctx; // DVX app context
BasVmT *vm; // shared VM instance
BasModuleT *module; // compiled module
BasFormT **forms; // stb_ds array of heap-allocated pointers
int32_t formCount;
BasFormT *currentForm; // form currently dispatching events
BasFrmCacheT *frmCache; // stb_ds array of cached .frm sources
int32_t frmCacheCount;
} BasFormRtT;
// ============================================================
// API
// ============================================================
// Initialize the form runtime with a DVX context and a compiled module.
BasFormRtT *basFormRtCreate(AppContextT *ctx, BasVmT *vm, BasModuleT *module);
// Destroy the form runtime and all forms/controls.
void basFormRtDestroy(BasFormRtT *rt);
// Wire up the VM's UI callbacks to this form runtime.
void basFormRtBindVm(BasFormRtT *rt);
// ---- UI callback implementations (match BasUiCallbacksT) ----
BasValueT basFormRtGetProp(void *ctx, void *ctrlRef, const char *propName);
void basFormRtSetProp(void *ctx, void *ctrlRef, const char *propName, BasValueT value);
BasValueT basFormRtCallMethod(void *ctx, void *ctrlRef, const char *methodName, BasValueT *args, int32_t argc);
void *basFormRtCreateCtrl(void *ctx, void *formRef, const char *typeName, const char *ctrlName);
void *basFormRtFindCtrl(void *ctx, void *formRef, const char *ctrlName);
void *basFormRtFindCtrlIdx(void *ctx, void *formRef, const char *ctrlName, int32_t index);
void *basFormRtLoadForm(void *ctx, const char *formName);
void basFormRtUnloadForm(void *ctx, void *formRef);
void basFormRtShowForm(void *ctx, void *formRef, bool modal);
void basFormRtHideForm(void *ctx, void *formRef);
int32_t basFormRtMsgBox(void *ctx, const char *message, int32_t flags);
// ---- Event dispatch ----
bool basFormRtFireEvent(BasFormRtT *rt, BasFormT *form, const char *ctrlName, const char *eventName);
bool basFormRtFireEventArgs(BasFormRtT *rt, BasFormT *form, const char *ctrlName, const char *eventName, const BasValueT *args, int32_t argCount);
// ---- Form file loading ----
BasFormT *basFormRtLoadFrm(BasFormRtT *rt, const char *source, int32_t sourceLen);
#endif // DVXBASIC_FORMRT_H