public override void initState()
 {
     base.initState();
     _leadingController =
         new _GlowController(vsync: this, color: widget.color, axis: widget.axis);
     _trailingController =
         new _GlowController(vsync: this, color: widget.color, axis: widget.axis);
     _leadingAndTrailingListener = ListenableUtils.merge(new List <Listenable>
     {
         _leadingController, _trailingController
     });
 }
 public _GlowingOverscrollIndicatorPainter(
     _GlowController leadingController,
     _GlowController trailingController,
     AxisDirection axisDirection,
     Listenable repaint
     ) : base(
         repaint: repaint
         )
 {
     this.leadingController  = leadingController;
     this.trailingController = trailingController;
     this.axisDirection      = axisDirection;
 }
        void _paintSide(Canvas canvas, Size size, _GlowController controller, AxisDirection axisDirection,
                        GrowthDirection growthDirection)
        {
            if (controller == null)
            {
                return;
            }

            switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(axisDirection, growthDirection))
            {
            case AxisDirection.up:
                controller.paint(canvas, size);
                break;

            case AxisDirection.down:
                canvas.save();
                canvas.translate(0.0f, size.height);
                canvas.scale(1.0f, -1.0f);
                controller.paint(canvas, size);
                canvas.restore();
                break;

            case AxisDirection.left:
                canvas.save();
                canvas.rotate(piOver2);
                canvas.scale(1.0f, -1.0f);
                controller.paint(canvas, new Size(size.height, size.width));
                canvas.restore();
                break;

            case AxisDirection.right:
                canvas.save();
                canvas.translate(size.width, 0.0f);
                canvas.rotate(piOver2);
                controller.paint(canvas, new Size(size.height, size.width));
                canvas.restore();
                break;
            }
        }
        bool _handleScrollNotification(ScrollNotification notification)
        {
            if (!widget.notificationPredicate(notification))
            {
                return(false);
            }

            if (notification is OverscrollNotification)
            {
                _GlowController        controller    = null;
                OverscrollNotification _notification = notification as OverscrollNotification;
                if (_notification.overscroll < 0.0f)
                {
                    controller = _leadingController;
                }
                else if (_notification.overscroll > 0.0f)
                {
                    controller = _trailingController;
                }
                else
                {
                    D.assert(false, () => "over scroll cannot be 0.0f.");
                }

                bool isLeading = controller == _leadingController;
                if (_lastNotificationType != typeof(OverscrollNotification))
                {
                    OverscrollIndicatorNotification confirmationNotification =
                        new OverscrollIndicatorNotification(leading: isLeading);
                    confirmationNotification.dispatch(context);
                    _accepted[isLeading] = confirmationNotification._accepted;
                }

                D.assert(controller != null);
                D.assert(_notification.metrics.axis() == widget.axis);
                if (_accepted[isLeading])
                {
                    if (_notification.velocity != 0.0f)
                    {
                        D.assert(_notification.dragDetails == null);
                        controller.absorbImpact(_notification.velocity.abs());
                    }
                    else
                    {
                        D.assert(_notification.overscroll != 0.0f);
                        if (_notification.dragDetails != null)
                        {
                            D.assert(_notification.dragDetails.globalPosition != null);
                            RenderBox renderer = (RenderBox)_notification.context.findRenderObject();
                            D.assert(renderer != null);
                            D.assert(renderer.hasSize);
                            Size   size     = renderer.size;
                            Offset position = renderer.globalToLocal(_notification.dragDetails.globalPosition);
                            switch (_notification.metrics.axis())
                            {
                            case Axis.horizontal:
                                controller.pull(_notification.overscroll.abs(), size.width,
                                                position.dy.clamp(0.0f, size.height), size.height);
                                break;

                            case Axis.vertical:
                                controller.pull(_notification.overscroll.abs(), size.height,
                                                position.dx.clamp(0.0f, size.width), size.width);
                                break;
                            }
                        }
                    }
                }
            }
            else if (notification is ScrollEndNotification || notification is ScrollUpdateNotification)
            {
                if ((notification as ScrollEndNotification).dragDetails != null)
                {
                    _leadingController.scrollEnd();
                    _trailingController.scrollEnd();
                }
            }

            _lastNotificationType = notification.GetType();
            return(false);
        }