render method

  1. @override
void render(
  1. Rect area,
  2. Buffer buffer,
  3. RenderContext ctx
)
override

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);
      }
    }
  }
}