// widgetBox.c — VBox, HBox, and Frame container widgets #include "widgetInternal.h" // ============================================================ // widgetFramePaint // ============================================================ void widgetFramePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { int32_t fb = widgetFrameBorderWidth(w); int32_t boxY = w->y + font->charHeight / 2; int32_t boxH = w->h - font->charHeight / 2; uint32_t fg = w->fgColor ? w->fgColor : colors->contentFg; uint32_t bg = w->bgColor ? w->bgColor : colors->contentBg; if (w->as.frame.style == FrameFlatE) { // Flat: solid color rectangle outline uint32_t fc = w->as.frame.color ? w->as.frame.color : colors->windowShadow; drawHLine(d, ops, w->x, boxY, w->w, fc); drawHLine(d, ops, w->x, boxY + boxH - 1, w->w, fc); drawVLine(d, ops, w->x, boxY, boxH, fc); drawVLine(d, ops, w->x + w->w - 1, boxY, boxH, fc); } else { // Beveled groove/ridge: two nested 1px bevels BevelStyleT outer; BevelStyleT inner; if (w->as.frame.style == FrameInE) { outer.highlight = colors->windowShadow; outer.shadow = colors->windowHighlight; inner.highlight = colors->windowHighlight; inner.shadow = colors->windowShadow; } else { outer.highlight = colors->windowHighlight; outer.shadow = colors->windowShadow; inner.highlight = colors->windowShadow; inner.shadow = colors->windowHighlight; } outer.face = 0; outer.width = 1; inner.face = 0; inner.width = 1; drawBevel(d, ops, w->x, boxY, w->w, boxH, &outer); drawBevel(d, ops, w->x + 1, boxY + 1, w->w - 2, boxH - 2, &inner); } // Draw title centered vertically on the top border line if (w->as.frame.title && w->as.frame.title[0]) { int32_t titleW = (int32_t)strlen(w->as.frame.title) * font->charWidth; int32_t titleX = w->x + DEFAULT_PADDING + fb; int32_t titleY = boxY + (fb - font->charHeight) / 2; rectFill(d, ops, titleX - 2, titleY, titleW + 4, font->charHeight, bg); drawText(d, ops, font, titleX, titleY, w->as.frame.title, fg, bg, true); } } // ============================================================ // wgtFrame // ============================================================ WidgetT *wgtFrame(WidgetT *parent, const char *title) { WidgetT *w = widgetAlloc(parent, WidgetFrameE); if (w) { w->as.frame.title = title; w->as.frame.style = FrameInE; w->as.frame.color = 0; } return w; } // ============================================================ // wgtHBox // ============================================================ WidgetT *wgtHBox(WidgetT *parent) { return widgetAlloc(parent, WidgetHBoxE); } // ============================================================ // wgtVBox // ============================================================ WidgetT *wgtVBox(WidgetT *parent) { return widgetAlloc(parent, WidgetVBoxE); }