getPath method

Path getPath(
  1. Size size,
  2. AllDayEventLayoutInfo info
)

Implementation

Path getPath(Size size, AllDayEventLayoutInfo info) {
  final maxTipWidth = size.height / 4;
  final leftTipWidth = info.hiddenStartDays.coerceAtMost(1) * maxTipWidth;
  final rightTipWidth = info.hiddenEndDays.coerceAtMost(1) * maxTipWidth;

  final maximumRadius = size.height / 2;
  final radii = AllDayEventBorderRadii(
    cornerRadius: BorderRadius.only(
      topLeft: Radius.elliptical(
        cornerRadius.topLeft.x,
        cornerRadius.topLeft.y.coerceAtMost(maximumRadius),
      ),
      bottomLeft: Radius.elliptical(
        cornerRadius.bottomLeft.x,
        cornerRadius.bottomLeft.y.coerceAtMost(maximumRadius),
      ),
      topRight: Radius.elliptical(
        cornerRadius.topRight.x,
        cornerRadius.topRight.y.coerceAtMost(maximumRadius),
      ),
      bottomRight: Radius.elliptical(
        cornerRadius.bottomRight.x,
        cornerRadius.bottomRight.y.coerceAtMost(maximumRadius),
      ),
    ),
    leftTipRadius: leftTipRadius.coerceAtMost(maximumRadius),
    rightTipRadius: rightTipRadius.coerceAtMost(maximumRadius),
  );

  final minWidth = radii.leftTipRadius +
      leftTipWidth +
      radii.rightTipRadius +
      rightTipWidth +
      math.min(
        radii.cornerRadius.topLeft.x + radii.cornerRadius.topRight.x,
        radii.cornerRadius.bottomLeft.x + radii.cornerRadius.bottomRight.x,
      );

  // ignore: omit_local_variable_types
  final double left =
      info.hiddenStartDays == 0 ? 0 : math.min(0, size.width - minWidth);
  // ignore: omit_local_variable_types
  final double right =
      info.hiddenEndDays == 0 ? size.width : math.max(size.width, minWidth);

  // no tip:   0      ≈  0°
  // full tip: PI / 4 ≈ 45°
  final leftTipAngle =
      math.pi / 2 - math.atan2(size.height / 2, leftTipWidth);
  final rightTipAngle =
      math.pi / 2 - math.atan2(size.height / 2, rightTipWidth);

  Size toSize(Radius radius) => Size(radius.x, radius.y) * 2;

  final topLeftTipBase = left + leftTipWidth + radii.cornerRadius.topLeft.x;

  return Path()
    ..moveTo(topLeftTipBase, 0)
    // Right top
    ..arcTo(
      Offset(right - rightTipWidth - radii.cornerRadius.topRight.x * 2, 0) &
          toSize(radii.cornerRadius.topRight),
      math.pi * 3 / 2,
      math.pi / 2 - rightTipAngle,
      false,
    )
    // Right tip
    ..arcTo(
      Offset(
            right - radii.rightTipRadius * 2,
            size.height / 2 - radii.rightTipRadius,
          ) &
          Size.square(radii.rightTipRadius * 2),
      -rightTipAngle,
      rightTipAngle * 2,
      false,
    )
    // Right bottom
    ..arcTo(
      Offset(
            right - rightTipWidth - radii.cornerRadius.bottomRight.x * 2,
            size.height - radii.cornerRadius.bottomRight.y * 2,
          ) &
          toSize(radii.cornerRadius.bottomRight),
      rightTipAngle,
      math.pi / 2 - rightTipAngle,
      false,
    )
    // Left bottom
    ..arcTo(
      Offset(
            left + leftTipWidth,
            size.height - radii.cornerRadius.bottomLeft.y * 2,
          ) &
          toSize(radii.cornerRadius.bottomLeft),
      math.pi / 2,
      math.pi / 2 - leftTipAngle,
      false,
    )
    // Left tip
    ..arcTo(
      Offset(left, size.height / 2 - radii.leftTipRadius) &
          Size.square(radii.leftTipRadius * 2),
      math.pi - leftTipAngle,
      leftTipAngle * 2,
      false,
    )
    // Left top
    ..arcTo(
      Offset(topLeftTipBase - radii.cornerRadius.topLeft.x, 0) &
          toSize(radii.cornerRadius.topLeft),
      math.pi + leftTipAngle,
      math.pi / 2 - leftTipAngle,
      false,
    );
}