153 lines
6.8 KiB
C
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
|