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;
  state.contentHeight = contentHeight;
  if (contentWidth > 0) state.contentWidth = contentWidth;

  final hasVScroll = showScrollbar && contentHeight > area.height;
  final viewportWidth =
      (area.width - (hasVScroll ? 1 : 0)).clamp(0, area.width);
  final viewportHeight = area.height;
  if (viewportWidth <= 0 || viewportHeight <= 0) return;

  final maxY = _maxOffsetY(viewportHeight);
  state.offsetY = state.offsetY.clamp(0, maxY);
  if (horizontal) {
    final maxX = _maxOffsetX(viewportWidth);
    state.offsetX = state.offsetX.clamp(0, maxX);
  } else {
    state.offsetX = 0;
  }

  final renderWidth = contentWidth > 0 ? contentWidth : viewportWidth;
  final renderHeight = contentHeight > 0 ? contentHeight : viewportHeight;

  // Render into a virtual buffer at origin (0,0), then blit window.
  final inner = Buffer(
      Size(renderWidth.clamp(1, 1 << 16), renderHeight.clamp(1, 1 << 16)));
  child.render(Rect(0, 0, inner.width, inner.height), inner, ctx);

  final srcX = state.offsetX;
  final srcY = state.offsetY;
  for (var dy = 0; dy < viewportHeight; dy++) {
    for (var dx = 0; dx < viewportWidth; dx++) {
      final cell = inner.get(srcX + dx, srcY + dy);
      buffer.set(area.x + dx, area.y + dy, cell);
    }
  }

  if (hasVScroll) {
    final track = scrollbarStyle ?? Style(fg: ctx.theme.colors.muted);
    final thumb = scrollbarThumbStyle ??
        Style(fg: ctx.theme.colors.primary, bold: true);
    final trackX = area.x + area.width - 1;
    final ratio = contentHeight == 0
        ? 0.0
        : (viewportHeight / contentHeight).clamp(0.0, 1.0);
    final thumbLen =
        (ratio * viewportHeight).round().clamp(1, viewportHeight);
    final posRatio = maxY == 0 ? 0.0 : state.offsetY / maxY;
    final thumbStart = (posRatio * (viewportHeight - thumbLen))
        .round()
        .clamp(0, viewportHeight - thumbLen);
    for (var y = 0; y < viewportHeight; y++) {
      final isThumb = y >= thumbStart && y < thumbStart + thumbLen;
      buffer.setChar(trackX, area.y + y, isThumb ? '█' : '│',
          style: isThumb ? thumb : track);
    }
  }
}