render method
Implementation
@override
void render(Rect area, Buffer buffer, RenderContext ctx) {
if (area.isEmpty) return;
_clampCursor();
final focused = ctx.isFocused(id);
// Keep cursor in viewport.
if (state.cursorLine < state.scrollOffset) {
state.scrollOffset = state.cursorLine;
} else if (state.cursorLine >= state.scrollOffset + area.height) {
state.scrollOffset = state.cursorLine - area.height + 1;
}
state.scrollOffset = state.scrollOffset.clamp(0, state.lines.length);
final showPlaceholder = state.lines.length == 1 &&
state.lines.first.isEmpty &&
placeholder != null &&
!focused;
final txtStyle = textStyle ?? ctx.theme.text.body;
final phStyle =
placeholderStyle ?? Style(fg: ctx.theme.colors.muted, italic: true);
final curStyle = cursorStyle ??
Style(
fg: ctx.theme.colors.background,
bg: focused ? ctx.theme.colors.primary : ctx.theme.colors.foreground,
);
if (showPlaceholder) {
buffer.writeText(area.x, area.y, placeholder!,
style: phStyle, maxWidth: area.width);
return;
}
for (var i = 0; i < area.height; i++) {
final lineIdx = state.scrollOffset + i;
if (lineIdx >= state.lines.length) break;
final line = state.lines[lineIdx];
final visible =
line.length > area.width ? line.substring(0, area.width) : line;
buffer.writeText(area.x, area.y + i, visible,
style: txtStyle, maxWidth: area.width);
// Draw the cursor on the line containing it.
if (focused && lineIdx == state.cursorLine) {
final cx = area.x + state.cursorCol;
if (cx < area.right) {
final ch =
state.cursorCol < line.length ? line[state.cursorCol] : ' ';
buffer.setChar(cx, area.y + i, ch, style: curStyle);
}
}
}
}