calculateTaskRects method

void calculateTaskRects(
  1. double canvasWidth,
  2. double canvasHeight
)

Calculates and caches the screen rectangles and handle positions for all visible tasks. Coordinates are relative to the top-left of this painter's canvas.

Implementation

void calculateTaskRects(double canvasWidth, double canvasHeight) {
  // Ensure dayWidth is calculated and valid
  if (_dayWidth <= 0) {
    if (calculateDayWidth(canvasWidth) <= 0) {
      // if (kDebugMode) print("Warning: Cannot calculate task rects with invalid dayWidth.");
      for (var task in tasks) {
        task.clearRects();
      }
      return;
    }
  }

  final viewStart =
      DateTime(viewStartDate.year, viewStartDate.month, viewStartDate.day);

  for (int i = 0; i < tasks.length; i++) {
    final task = tasks[i];
    // Calculate Y position relative to the top of the task area (y=0)
    final taskY = i * rowHeight; // *** REMOVED headerHeight offset ***

    // Check if task is vertically within the drawable area (0 to canvasHeight)
    // *** REMOVED check against headerHeight ***
    if (taskY + taskHeight < 0 || taskY > canvasHeight) {
      task.clearRects(); // Task is completely outside vertical bounds
      continue;
    }

    final taskStart =
        DateTime(task.start.year, task.start.month, task.start.day);
    final taskEnd = DateTime(task.end.year, task.end.month, task.end.day);

    final startDayIndex = _getDaysDifference(viewStart, taskStart);
    final endDayIndex =
        _getDaysDifference(viewStart, taskEnd); // Inclusive end day

    // Calculate raw x positions relative to the start of the grid
    final taskStartX = gridStartX + startDayIndex * _dayWidth;
    // Task visually ends at the start of the next day's column
    final taskEndX = gridStartX + (endDayIndex + 1) * _dayWidth;

    // Clamp visual coordinates to the grid boundaries
    final clampedStartX = taskStartX.clamp(gridStartX, _gridEndX);
    final clampedEndX = taskEndX.clamp(gridStartX, _gridEndX);

    final taskWidth = clampedEndX - clampedStartX;

    // Create rect only if width is positive
    if (taskWidth > 0) {
      // Use the calculated taskY (relative to 0)
      final rect = Rect.fromLTWH(clampedStartX, taskY, taskWidth, taskHeight);
      task.taskRect = rect;

      // --- Handle calculation remains the same relative to the task rect ---
      final double visibleStartHandleX = max(rect.left, taskStartX);
      final double visibleEndHandleX = min(rect.right, taskEndX);

      if (visibleStartHandleX + handleWidth * 2 <= visibleEndHandleX) {
        task.startHandleRect = Rect.fromLTWH(
            visibleStartHandleX, rect.top, handleWidth, rect.height);
        task.endHandleRect = Rect.fromLTWH(visibleEndHandleX - handleWidth,
            rect.top, handleWidth, rect.height);
      } else if (visibleStartHandleX + handleWidth <= visibleEndHandleX) {
        task.startHandleRect = Rect.fromLTWH(
            visibleStartHandleX, rect.top, handleWidth, rect.height);
        task.endHandleRect = null;
      } else {
        task.startHandleRect = null;
        task.endHandleRect = null;
      }
      // --- End Handle calculation ---

      // Connector circle position remains relative to the task rect
      task.connectorCirclePos = Offset(rect.right, rect.center.dy);
    } else {
      task.clearRects();
    }
  }
}