render method
Renders the widget onto the provided buffer within the specified area.
Implementation
@override
void render(Buffer buffer, Rect area) {
if (bounds.width <= 0 || bounds.height <= 0) return;
// Render window inside parent buffer at this window's bounds.
final absoluteBounds = Rect(
area.x + bounds.x,
area.y + bounds.y,
bounds.width,
bounds.height,
);
final windowViewport = Viewport(buffer, absoluteBounds);
final w = bounds.width;
final h = bounds.height;
if (w < 2 || h < 2) {
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
final cell = windowViewport.getCell(x, y);
if (cell != null) {
cell.char = ' ';
cell.style = borderStyle;
}
}
}
return;
}
// Draw top border
final topBorder =
borderChars[0] + borderChars[1] * (w - 2) + borderChars[2];
windowViewport.writeString(0, 0, topBorder, borderStyle);
// Overlay title
if (title.isNotEmpty) {
final titleChars = title.characters;
final maxTitleLen = w - 4;
String displayedTitle;
if (titleChars.length > maxTitleLen) {
final cutLen = w - 7;
if (cutLen > 0) {
displayedTitle = ' ${titleChars.take(cutLen).toString()}... ';
} else {
displayedTitle = '';
}
} else {
displayedTitle = ' $title ';
}
if (displayedTitle.isNotEmpty) {
final dispChars = displayedTitle.characters;
final titleX = max(1, min(w - 2, ((w - dispChars.length) / 2).floor()));
windowViewport.writeString(titleX, 0, displayedTitle, titleStyle);
}
}
// Side borders
for (var y = 1; y < h - 1; y++) {
windowViewport.writeString(0, y, borderChars[3], borderStyle);
windowViewport.writeString(w - 1, y, borderChars[5], borderStyle);
}
// Bottom border
final bottomBorder =
borderChars[6] + borderChars[7] * (w - 2) + borderChars[8];
windowViewport.writeString(0, h - 1, bottomBorder, borderStyle);
// Render child content viewport
final contentArea = Rect(1, 1, w - 2, h - 2);
final contentViewport = Viewport(windowViewport, contentArea);
contentViewport.fill(Cell(' ', backgroundStyle));
child.render(
contentViewport,
Rect(0, 0, contentArea.width, contentArea.height),
);
}