118 lines
3.7 KiB
C
118 lines
3.7 KiB
C
#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 = {
|
|
.flags = WCLASS_BOX_CONTAINER | WCLASS_HORIZ_CONTAINER,
|
|
.paint = widgetStatusBarPaint,
|
|
.paintOverlay = NULL,
|
|
.calcMinSize = NULL,
|
|
.layout = NULL,
|
|
.onMouse = NULL,
|
|
.onKey = NULL,
|
|
.destroy = NULL,
|
|
.getText = NULL,
|
|
.setText = NULL,
|
|
.getLayoutMetrics = 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
|
|
};
|
|
|
|
void wgtRegister(void) {
|
|
sTypeId = wgtRegisterClass(&sClassStatusBar);
|
|
wgtRegisterApi("statusbar", &sApi);
|
|
}
|