performPaint method

  1. @override
void performPaint(
  1. Buffer buffer,
  2. Offset offset
)
override

Hook for subclasses to implement actual painting.

Implementation

@override
void performPaint(Buffer buffer, Offset offset) {
  final win = widget as Window;
  final w = win.width;
  final h = win.height;
  final paintOffset = offset;

  if (w < 2 || h < 2) {
    for (var y = 0; y < h; y++) {
      for (var x = 0; x < w; x++) {
        if (buffer.getCharacter(paintOffset.dx + x, paintOffset.dy + y) !=
            '') {
          buffer.setAttributes(
            paintOffset.dx + x,
            paintOffset.dy + y,
            char: ' ',
            fg: win.borderStyle.foreground?.argb,
            bg: win.borderStyle.background?.argb,
            modifiers: win.borderStyle.modifiers,
          );
        }
      }
    }
    return;
  }

  // Draw top border
  final topBorder =
      win.borderChars[0] + win.borderChars[1] * (w - 2) + win.borderChars[2];
  buffer.writeString(
    paintOffset.dx,
    paintOffset.dy,
    topBorder,
    win.borderStyle,
  );

  // Draw close button [x] at the top right of the window border, e.g. at w - 4, w - 3, w - 2.
  if (win.showCloseButton && w >= 6) {
    buffer.writeString(
      paintOffset.dx + w - 4,
      paintOffset.dy,
      '[x]',
      win.borderStyle,
    );
  }

  // Overlay title
  if (win.title.isNotEmpty) {
    final titleChars = win.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 = ' ${win.title} ';
    }

    if (displayedTitle.isNotEmpty) {
      final dispChars = displayedTitle.characters;
      final titleX = max(1, min(w - 2, ((w - dispChars.length) / 2).floor()));
      buffer.writeString(
        paintOffset.dx + titleX,
        paintOffset.dy,
        displayedTitle,
        win.titleStyle,
      );
    }
  }

  // Side borders
  for (var y = 1; y < h - 1; y++) {
    buffer.writeString(
      paintOffset.dx,
      paintOffset.dy + y,
      win.borderChars[3],
      win.borderStyle,
    );
    buffer.writeString(
      paintOffset.dx + w - 1,
      paintOffset.dy + y,
      win.borderChars[5],
      win.borderStyle,
    );
  }

  // Bottom border
  final bottomBorder =
      win.borderChars[6] + win.borderChars[7] * (w - 2) + win.borderChars[8];
  buffer.writeString(
    paintOffset.dx,
    paintOffset.dy + h - 1,
    bottomBorder,
    win.borderStyle,
  );

  // Render child content viewport
  final contentArea = Rect(
    paintOffset.dx + 1,
    paintOffset.dy + 1,
    w - 2,
    h - 2,
  );
  final contentViewport = Viewport(buffer, contentArea);
  contentViewport.fillAttributes(
    char: ' ',
    fg: win.backgroundStyle.foreground?.argb,
    bg: win.backgroundStyle.background?.argb,
    modifiers: win.backgroundStyle.modifiers,
  );

  if (childElement != null) {
    childElement!.paint(contentViewport, Offset.zero);
  }
}