content: /*
   *  This file is part of BlackHole (https://github.com/Sangwan5688/BlackHole).
   * 
   * BlackHole is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * BlackHole is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with BlackHole.  If not, see <http://www.gnu.org/licenses/>.
   * 
   * Copyright (c) 2021-2022, Ankit Sangwan
   */
  
  import 'package:flutter/material.dart';
  
  class CustomPhysics extends ScrollPhysics {
    const CustomPhysics({super.parent});
  
    @override
    CustomPhysics applyTo(ScrollPhysics? ancestor) {
      return CustomPhysics(parent: buildParent(ancestor));
    }
  
    @override
    SpringDescription get spring => const SpringDescription(
          mass: 150,
          stiffness: 100,
          damping: 1,
        );
  }
  
  class PagingScrollPhysics extends ScrollPhysics {
    final double itemDimension;
  
    const PagingScrollPhysics({required this.itemDimension, super.parent});
  
    @override
    PagingScrollPhysics applyTo(ScrollPhysics? ancestor) {
      return PagingScrollPhysics(
        itemDimension: itemDimension,
        parent: buildParent(ancestor),
      );
    }
  
    double _getPage(ScrollMetrics position) {
      return position.pixels / itemDimension;
    }
  
    double _getPixels(double page) {
      return page * itemDimension;
    }
  
    double _getTargetPixels(
      ScrollMetrics position,
      Tolerance tolerance,
      double velocity,
    ) {
      double page = _getPage(position);
      if (velocity < -tolerance.velocity) {
        page -= 0.5;
      } else if (velocity > tolerance.velocity) {
        page += 0.5;
      }
      return _getPixels(page.roundToDouble());
    }
  
    @override
    Simulation? createBallisticSimulation(
      ScrollMetrics position,
      double velocity,
    ) {
      if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) ||
          (velocity >= 0.0 && position.pixels >= position.maxScrollExtent)) {
        return super.createBallisticSimulation(position, velocity);
      }
      final Tolerance tolerance = toleranceFor(position);
      final double target = _getTargetPixels(position, tolerance, velocity);
      if (target != position.pixels) {
        return ScrollSpringSimulation(
          spring,
          position.pixels,
          target,
          velocity,
          tolerance: tolerance,
        );
      }
      return null;
    }
  
    @override
    bool get allowImplicitScrolling => false;
  }
  