moveSide method

Rect moveSide({
  1. required double delta,
  2. required Side side,
  3. required Size shortest,
  4. required Size? longest,
  5. required double? largest,
  6. required Rect boundaries,
  7. required double? aspectRatio,
})

Implementation

Rect moveSide({
  required double delta,
  required Side side,
  required Size shortest,
  required Size? longest,
  required double? largest,
  required Rect boundaries,
  required double? aspectRatio,
}) {
  double l = left, t = top, r = right, b = bottom;
  switch (side) {
    case .left:
      l = left + delta;
      if (delta < 0) {
        l = [l, boundaries.left, if (longest != null) right - longest.width, if (largest != null) right - largest/height].reduce(max);
        if (aspectRatio != null) {
          final newWidthPrediction = width - l + left;
          final newHeightPrediction = newWidthPrediction / aspectRatio;
          final boundaryHeight = longest == null ? boundaries.height : min(boundaries.height, longest.height);
          if (newHeightPrediction > boundaryHeight) {
            l = right - boundaryHeight * aspectRatio;
            t = boundaries.top;
            b = boundaries.bottom;
          } else {
            t = center.dy - newHeightPrediction/2;
            b = t + newHeightPrediction;
            if (t < boundaries.top) {
              t = boundaries.top;
              b = boundaries.top + newHeightPrediction;
            } else if (b > boundaries.bottom) {
              t = boundaries.bottom - newHeightPrediction;
              b = boundaries.bottom;
            }
          }
        }
      } else {
        l = min(l, right - shortest.width);
        if (aspectRatio != null) {
          final newWidthPrediction = width - l + left;
          final newHeightPrediction = newWidthPrediction / aspectRatio;
          if (newHeightPrediction < shortest.height) {
            l = right - shortest.height * aspectRatio;
            t = center.dy - shortest.height/2;
            b = t + shortest.height;
          } else {
            t = center.dy - newHeightPrediction/2;
            b = t + newHeightPrediction;
          }
        }
      }
    case .top:
      t = top + delta;
      if (delta < 0) {
        t = [t, boundaries.top, if (longest != null) bottom - longest.height, if (largest != null) bottom - largest/width].reduce(max);
        if (aspectRatio != null) {
          final newHeightPrediction = height - t + top;
          final newWidthPrediction = newHeightPrediction * aspectRatio;
          final boundaryWidth = longest == null ? boundaries.width : min(boundaries.width, longest.width);
          if (newWidthPrediction > boundaryWidth) {
            t = bottom - boundaryWidth / aspectRatio;
            l = boundaries.left;
            r = boundaries.right;
          } else {
            l = center.dx - newWidthPrediction/2;
            r = l + newWidthPrediction;
            if (l < boundaries.left) {
              l = boundaries.left;
              r = boundaries.left + newWidthPrediction;
            } else if (r > boundaries.right) {
              l = boundaries.right - newWidthPrediction;
              r = boundaries.right;
            }
          }
        }
      } else {
        t = min(t, bottom - shortest.height);
        if (aspectRatio != null) {
          final newHeightPrediction = height - t + top;
          final newWidthPrediction = newHeightPrediction * aspectRatio;
          if (newWidthPrediction < shortest.width) {
            t = bottom - shortest.width / aspectRatio;
            l = center.dx - shortest.width/2;
            r = l + shortest.width;
          } else {
            l = center.dx - newWidthPrediction/2;
            r = l + newWidthPrediction;
          }
        }
      }
    case .right:
      r = right + delta;
      if (delta > 0) {
        r = [r, boundaries.right, if (longest != null) left + longest.width, if (largest != null) left + largest/height].reduce(min);
        if (aspectRatio != null) {
          final newWidthPrediction = width + r - right;
          final newHeightPrediction = newWidthPrediction / aspectRatio;
          final boundaryHeight = longest == null ? boundaries.height : min(boundaries.height, longest.height);
          if (newHeightPrediction > boundaryHeight) {
            r = left + boundaryHeight * aspectRatio;
            t = boundaries.top;
            b = boundaries.bottom;
          } else {
            t = center.dy - newHeightPrediction/2;
            b = t + newHeightPrediction;
            if (t < boundaries.top) {
              t = boundaries.top;
              b = boundaries.top + newHeightPrediction;
            } else if (b > boundaries.bottom) {
              t = boundaries.bottom - newHeightPrediction;
              b = boundaries.bottom;
            }
          }
        }
      } else {
        r = max(r, left + shortest.width);
        if (aspectRatio != null) {
          final newWidthPrediction = width + r - right;
          final newHeightPrediction = newWidthPrediction / aspectRatio;
          if (newHeightPrediction < shortest.height) {
            r = left + shortest.height * aspectRatio;
            t = center.dy - shortest.height/2;
            b = t + shortest.height;
          } else {
            t = center.dy - newHeightPrediction/2;
            b = t + newHeightPrediction;
          }
        }
      }
    case .bottom:
      b = bottom + delta;
      if (delta > 0) {
        b = [b, boundaries.bottom, if (longest != null) top + longest.height, if (largest != null) top + largest/width].reduce(min);
        if (aspectRatio != null) {
          final newHeightPrediction = height + b - bottom;
          final newWidthPrediction = newHeightPrediction * aspectRatio;
          final boundaryWidth = longest == null ? boundaries.width : min(boundaries.width, longest.width);
          if (newWidthPrediction > boundaryWidth) {
            b = top + boundaryWidth / aspectRatio;
            l = boundaries.left;
            r = boundaries.right;
          } else {
            l = center.dx - newWidthPrediction/2;
            r = l + newWidthPrediction;
            if (l < boundaries.left) {
              l = boundaries.left;
              r = boundaries.left + newWidthPrediction;
            } else if (r > boundaries.right) {
              l = boundaries.right - newWidthPrediction;
              r = boundaries.right;
            }
          }
        }
      } else {
        b = max(b, top + shortest.height);
        if (aspectRatio != null) {
          final newHeightPrediction = height + b - bottom;
          final newWidthPrediction = newHeightPrediction * aspectRatio;
          if (newWidthPrediction < shortest.width) {
            b = top + shortest.width / aspectRatio;
            l = center.dx - shortest.width/2;
            r = l + shortest.width;
          } else {
            l = center.dx - newWidthPrediction/2;
            r = l + newWidthPrediction;
          }
        }
      }
  }
  return Rect.fromLTRB(l, t, r, b);
}