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 || area.height < 1) return;
  final focused = ctx.isFocused(id);

  final c = state.cursor;
  final monthName = monthNames[c.month - 1];
  final header = '$monthName ${c.year}';

  final hStyle = headerStyle ??
      Style(
        fg: focused ? ctx.theme.colors.primary : ctx.theme.colors.foreground,
        bold: true,
      );
  buffer.writeText(area.x, area.y, header,
      style: hStyle, maxWidth: area.width);

  if (area.height < 2) return;

  final wkStyle = weekdayStyle ?? Style(fg: ctx.theme.colors.muted);
  final orderedWeekdays = [
    for (var i = 0; i < 7; i++) weekdayNames[(firstDayOfWeek - 1 + i) % 7]
  ];
  for (var i = 0; i < 7; i++) {
    final wx = area.x + i * 3;
    if (wx + 2 > area.x + area.width) break;
    buffer.writeText(wx, area.y + 1, orderedWeekdays[i],
        style: wkStyle, maxWidth: 2);
  }

  final firstOfMonth = DateTime(c.year, c.month, 1);
  final colOffset = _firstColumnOffset(firstOfMonth.weekday);
  final daysInMonth = DateTime(c.year, c.month + 1, 0).day;
  final selected = state.selected != null ? _dateOnly(state.selected!) : null;
  final cursorDate = _dateOnly(c);

  final defaultDay = dayStyle ?? ctx.theme.text.body;
  final defaultSelected =
      selectedStyle ?? Style(fg: ctx.theme.colors.success, bold: true);
  final defaultCursor = cursorStyle ??
      Style(
        fg: ctx.theme.colors.background,
        bg: focused ? ctx.theme.colors.primary : ctx.theme.colors.foreground,
        bold: true,
      );
  final defaultDisabled =
      disabledStyle ?? Style(fg: ctx.theme.colors.muted, dim: true);

  for (var day = 1; day <= daysInMonth; day++) {
    final cellIndex = colOffset + day - 1;
    final row = cellIndex ~/ 7;
    final col = cellIndex % 7;
    final yPos = area.y + 2 + row;
    if (yPos >= area.y + area.height) break;
    final xPos = area.x + col * 3;
    if (xPos + 2 > area.x + area.width) continue;

    final date = DateTime(c.year, c.month, day);
    final disabled = _isDisabled(date);
    final isCursor = date == cursorDate;
    final isSelected = selected != null && date == selected;

    Style s;
    if (disabled) {
      s = defaultDisabled;
    } else if (isCursor) {
      s = defaultCursor;
    } else if (isSelected) {
      s = defaultSelected;
    } else {
      s = defaultDay;
    }

    final label = day.toString().padLeft(2);
    buffer.writeText(xPos, yPos, label, style: s, maxWidth: 2);
  }
}