#define DVX_WIDGET_IMPL // widgetStatusBar.c -- StatusBar widget // // A horizontal container that draws a sunken border around each visible // child to create the classic segmented status bar appearance. Children // are typically labels or other simple widgets, laid out by the generic // horizontal box layout. The status bar itself has no special layout // logic -- it's a standard HBox with tight padding/spacing and the // extra per-child sunken border decorations. // // The border drawing is done as an overlay on top of children rather // than as part of the child's own paint, because it wraps around // the child's allocated area (extending 1px past each edge). This // keeps the sunken-panel effect consistent regardless of the child // widget type. // // No mouse/key handlers -- the status bar is purely display. Children // that are interactive (e.g., a clickable label) handle their own events. #include "dvxWidgetPlugin.h" #define TOOLBAR_PAD 2 #define TOOLBAR_GAP 2 static int32_t sTypeId = -1; // ============================================================ // widgetStatusBarPaint // ============================================================ // Draws a 1px sunken bevel (reversed highlight/shadow) around each // child. The bevel.face=0 with width=1 means only the border lines // are drawn, not a filled interior -- the child paints its own content. void widgetStatusBarPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { (void)font; // Draw sunken border around each child for (WidgetT *c = w->firstChild; c; c = c->nextSibling) { if (!c->visible) { continue; } BevelStyleT bevel; bevel.highlight = colors->windowShadow; bevel.shadow = colors->windowHighlight; bevel.face = 0; bevel.width = 1; drawBevel(d, ops, c->x - 1, c->y - 1, c->w + 2, c->h + 2, &bevel); } } // ============================================================ // widgetStatusBarGetLayoutMetrics // ============================================================ void widgetStatusBarGetLayoutMetrics(const WidgetT *w, const BitmapFontT *font, int32_t *pad, int32_t *gap, int32_t *extraTop, int32_t *borderW) { (void)w; (void)font; *pad = TOOLBAR_PAD; *gap = TOOLBAR_GAP; *extraTop = 0; *borderW = 0; } // ============================================================ // DXE registration // ============================================================ static const WidgetClassT sClassStatusBar = { .version = WGT_CLASS_VERSION, .flags = WCLASS_BOX_CONTAINER | WCLASS_HORIZ_CONTAINER, .handlers = { [WGT_METHOD_PAINT] = (void *)widgetStatusBarPaint, [WGT_METHOD_GET_LAYOUT_METRICS] = (void *)widgetStatusBarGetLayoutMetrics, } }; // ============================================================ // Widget creation functions // ============================================================ WidgetT *wgtStatusBar(WidgetT *parent) { WidgetT *w = widgetAlloc(parent, sTypeId); if (w) { w->padding = wgtPixels(2); w->spacing = wgtPixels(2); } return w; } // ============================================================ // DXE registration // ============================================================ static const struct { WidgetT *(*create)(WidgetT *parent); } sApi = { .create = wgtStatusBar }; static const WgtIfaceT sIface = { .basName = "StatusBar", .props = NULL, .propCount = 0, .methods = NULL, .methodCount = 0, .events = NULL, .eventCount = 0 }; void wgtRegister(void) { sTypeId = wgtRegisterClass(&sClassStatusBar); wgtRegisterApi("statusbar", &sApi); wgtRegisterIface("statusbar", &sIface); }