)
) ;
}
public override Widget build ( BuildContext context ) {
List < Widget > widgets = new List < Widget > ( ) ;
widgets . Add ( new AnimatedBuilder (
builder : _buildAnimation ,
animation : widget . controller
) ) ;
return new Stack (
children : widgets
) ;
public override Widget build ( BuildContext context ) {
List < Widget > widgets = new List < Widget > ( ) ;
widgets . Add ( new AnimatedBuilder (
builder : _buildAnimation ,
animation : widget . controller )
) ;
return new Stack (
children : widgets
) ;
public class _ContextMenuRoute : PopupRoute {
public _ContextMenuRoute (
List < Widget > actions = null ,
_ContextMenuLocation contextMenuLocation = default ,
string barrierLabel = null ,
_ContextMenuPreviewBuilderChildless builder = null ,
ImageFilter filter = null ,
Rect previousChildRect = null ,
RouteSettings settings = null
) : base (
filter : filter ,
settings : settings
) {
D . assert ( actions ! = null & & actions . isNotEmpty ( ) ) ;
D . assert ( contextMenuLocation ! = null ) ;
this . barrierLabel = barrierLabel ;
_actions = actions ;
_builder = builder ;
_contextMenuLocation = contextMenuLocation ;
_previousChildRect = previousChildRect ;
}
public readonly static Color _kModalBarrierColor = new Color ( 0 x6604040F ) ;
public readonly TimeSpan _kModalPopupTransitionDuration = new TimeSpan ( 0 , 0 , 0 , 0 , 3 3 5 ) ;
public readonly List < Widget > _actions ;
public readonly _ContextMenuPreviewBuilderChildless _builder ;
public readonly GlobalKey _childGlobalKey = new LabeledGlobalKey < State < StatefulWidget > > ( ) ;
public readonly _ContextMenuLocation _contextMenuLocation ;
public bool _externalOffstage = false ;
public bool _internalOffstage = false ;
public Orientation _lastOrientation ;
public readonly Rect _previousChildRect ;
public float _scale = 1.0f ;
public readonly GlobalKey _sheetGlobalKey = new LabeledGlobalKey < State < StatefulWidget > > ( ) ; //GlobalKey();
public readonly static CurveTween _curve = new CurveTween (
curve : Curves . easeOutBack
) ;
public readonly static CurveTween _curveReverse = new CurveTween (
curve : Curves . easeInBack
) ;
public readonly static RectTween _rectTween = new RectTween ( ) ;
public readonly static Animatable < Rect > _rectAnimatable = _rectTween . chain ( _curve ) ;
public readonly static RectTween _rectTweenReverse = new RectTween ( ) ;
public readonly static Animatable < Rect > _rectAnimatableReverse = _rectTweenReverse . chain ( _curveReverse ) ;
public class _ContextMenuRoute : PopupRoute {
public _ContextMenuRoute (
List < Widget > actions = null ,
_ContextMenuLocation contextMenuLocation = default ,
string barrierLabel = null ,
_ContextMenuPreviewBuilderChildless builder = null ,
ImageFilter filter = null ,
Rect previousChildRect = null ,
RouteSettings settings = null
) : base ( filter : filter , settings : settings ) {
D . assert ( actions ! = null & & actions . isNotEmpty ( ) ) ;
D . assert ( contextMenuLocation ! = null ) ;
this . barrierLabel = barrierLabel ;
_actions = actions ;
_builder = builder ;
_contextMenuLocation = contextMenuLocation ;
_previousChildRect = previousChildRect ;
}
public readonly static Color _kModalBarrierColor = new Color ( 0 x6604040F ) ;
public readonly TimeSpan _kModalPopupTransitionDuration = new TimeSpan ( 0 , 0 , 0 , 0 , 3 3 5 ) ;
public readonly List < Widget > _actions ;
public readonly _ContextMenuPreviewBuilderChildless _builder ;
public readonly GlobalKey _childGlobalKey = new LabeledGlobalKey < State < StatefulWidget > > ( ) ;
public readonly _ContextMenuLocation _contextMenuLocation ;
public bool _externalOffstage = false ;
public bool _internalOffstage = false ;
public Orientation _lastOrientation ;
public readonly Rect _previousChildRect ;
public float _scale = 1.0f ;
public readonly GlobalKey _sheetGlobalKey = new LabeledGlobalKey < State < StatefulWidget > > ( ) ; //GlobalKey();
public readonly static CurveTween _curve = new CurveTween (
curve : Curves . easeOutBack
) ;
public readonly static CurveTween _curveReverse = new CurveTween (
curve : Curves . easeInBack
) ;
public readonly static RectTween _rectTween = new RectTween ( ) ;
public readonly static Animatable < Rect > _rectAnimatable = _rectTween . chain ( _curve ) ;
public readonly static RectTween _rectTweenReverse = new RectTween ( ) ;
public readonly static Animatable < Rect > _rectAnimatableReverse = _rectTweenReverse . chain ( _curveReverse ) ;
public readonly static RectTween _sheetRectTween = new RectTween ( ) ;
public readonly Animatable < Rect > _sheetRectAnimatable = _sheetRectTween . chain ( _curve ) ;
public readonly Animatable < Rect > _sheetRectAnimatableReverse = _sheetRectTween . chain ( _curveReverse ) ;
public readonly static Tween < float > _sheetScaleTween = new FloatTween ( 0.0f , 0.0f ) ;
public readonly static Animatable < float > _sheetScaleAnimatable = _sheetScaleTween . chain ( _curve ) ;
public readonly static Animatable < float > _sheetScaleAnimatableReverse = _sheetScaleTween . chain ( _curveReverse ) ;
public readonly Tween < float > _opacityTween = new FloatTween ( begin : 0.0f , end : 1.0f ) ;
public Animation < float > _sheetOpacity ;
public readonly static RectTween _sheetRectTween = new RectTween ( ) ;
public readonly Animatable < Rect > _sheetRectAnimatable = _sheetRectTween . chain ( _curve ) ;
public readonly Animatable < Rect > _sheetRectAnimatableReverse = _sheetRectTween . chain ( _curveReverse ) ;
public readonly static Tween < float > _sheetScaleTween = new FloatTween ( 0.0f , 0.0f ) ;
public readonly static Animatable < float > _sheetScaleAnimatable = _sheetScaleTween . chain ( _curve ) ;
public readonly static Animatable < float > _sheetScaleAnimatableReverse = _sheetScaleTween . chain ( _curveReverse ) ;
public readonly Tween < float > _opacityTween = new FloatTween ( begin : 0.0f , end : 1.0f ) ;
public Animation < float > _sheetOpacity ;
public readonly string barrierLabel ;
public readonly string barrierLabel ;
public Color barrierColor {
get { return _kModalBarrierColor ; }
}
public bool barrierDismissible {
get { return false ; }
}
public Color barrierColor {
get { return _kModalBarrierColor ; }
}
public bool barrierDismissible {
get { return false ; }
}
public bool semanticsDismissible {
get { return true ; }
}
public bool semanticsDismissible {
get { return true ; }
}
public TimeSpan transitionDuration {
get {
return _kModalPopupTransitionDuration ;
public TimeSpan transitionDuration {
get {
return _kModalPopupTransitionDuration ;
}
}
/ * public static AlignmentDirectional getSheetAlignment ( _ContextMenuLocation contextMenuLocation ) {
switch ( contextMenuLocation ) {
case _ContextMenuLocation . center :
return AlignmentDirectional . topCenter ;
case _ContextMenuLocation . right :
return AlignmentDirectional . topEnd ;
default :
return AlignmentDirectional . topStart ;
}
} * /
public static Rect _getScaledRect ( GlobalKey globalKey , float scale ) {
Rect childRect = CupertinoContextMenuUtils . _getRect ( globalKey ) ;
Size sizeScaled = childRect . size * scale ;
Offset offsetScaled = new Offset (
childRect . left + ( childRect . size . width - sizeScaled . width ) / 2 ,
childRect . top + ( childRect . size . height - sizeScaled . height ) / 2
) ;
return offsetScaled & sizeScaled ;
}
public static Rect _getSheetRectBegin ( Orientation orientation , _ContextMenuLocation contextMenuLocation , Rect childRect , Rect sheetRect ) {
switch ( contextMenuLocation ) {
case _ContextMenuLocation . center :
Offset target1 = ( orientation = = Orientation . portrait )
? childRect . bottomCenter
: childRect . topCenter ;
Offset centered = target1 - new Offset ( sheetRect . width / 2 , 0.0f ) ;
return centered & sheetRect . size ;
case _ContextMenuLocation . right :
Offset target2 = ( ( orientation = = Orientation . portrait )
? childRect . bottomRight
: childRect . topRight ) ;
return ( target2 - new Offset ( sheetRect . width , 0.0f ) ) & sheetRect . size ;
default :
Offset target3 = orientation = = Orientation . portrait
? childRect . bottomLeft
: childRect . topLeft ;
return target3 & sheetRect . size ;
}
}
public void _onDismiss ( BuildContext context , float scale , float opacity ) {
_scale = scale ;
_opacityTween . end = opacity ;
_sheetOpacity = _opacityTween . animate (
new CurvedAnimation (
parent : animation ,
curve : new Interval ( 0.9f , 1.0f )
) ) ;
Navigator . of ( context ) . pop < object > ( ) ;
}
public void _updateTweenRects ( ) {
Rect childRect = _scale = = null
? CupertinoContextMenuUtils . _getRect ( _childGlobalKey )
: _getScaledRect ( _childGlobalKey , _scale ) ;
_rectTween . begin = _previousChildRect ;
_rectTween . end = childRect ;
Rect childRectOriginal = CupertinoContextMenuUtils . fromCenter (
center : _previousChildRect . center ,
width : _previousChildRect . width / CupertinoContextMenuUtils . _kOpenScale ,
height : _previousChildRect . height / CupertinoContextMenuUtils . _kOpenScale
) ;
Rect sheetRect = CupertinoContextMenuUtils . _getRect ( _sheetGlobalKey ) ;
Rect sheetRectBegin = _getSheetRectBegin (
_lastOrientation ,
_contextMenuLocation ,
childRectOriginal ,
sheetRect
) ;
_sheetRectTween . begin = sheetRectBegin ;
_sheetRectTween . end = sheetRect ;
_sheetScaleTween . begin = 0.0f ;
_sheetScaleTween . end = _scale ;
_rectTweenReverse . begin = childRectOriginal ;
_rectTweenReverse . end = childRect ;
}
public static Rect _getScaledRect ( GlobalKey globalKey , float scale ) {
Rect childRect = CupertinoContextMenuUtils . _getRect ( globalKey ) ;
Size sizeScaled = childRect . size * scale ;
Offset offsetScaled = new Offset (
childRect . left + ( childRect . size . width - sizeScaled . width ) / 2 ,
childRect . top + ( childRect . size . height - sizeScaled . height ) / 2
) ;
return offsetScaled & sizeScaled ;
}
/ * public static AlignmentDirectional getSheetAlignment ( _ContextMenuLocation contextMenuLocation ) {
switch ( contextMenuLocation ) {
case _ContextMenuLocation . center :
return AlignmentDirectional . topCenter ;
case _ContextMenuLocation . right :
return AlignmentDirectional . topEnd ;
default :
return AlignmentDirectional . topStart ;
public void _setOffstageInternally ( ) {
base . offstage = _externalOffstage | | _internalOffstage ;
changedInternalState ( ) ;
} * /
public static Rect _getSheetRectBegin ( Orientation orientation , _ContextMenuLocation contextMenuLocation , Rect childRect , Rect sheetRect ) {
switch ( contextMenuLocation ) {
case _ContextMenuLocation . center :
Offset target1 = ( orientation = = Orientation . portrait )
? childRect . bottomCenter
: childRect . topCenter ;
Offset centered = target1 - new Offset ( sheetRect . width / 2 , 0.0f ) ;
return centered & sheetRect . size ;
case _ContextMenuLocation . right :
Offset target2 = ( ( orientation = = Orientation . portrait )
? childRect . bottomRight
: childRect . topRight ) ;
return ( target2 - new Offset ( sheetRect . width , 0.0f ) ) & sheetRect . size ;
default :
Offset target3 = orientation = = Orientation . portrait
? childRect . bottomLeft
: childRect . topLeft ;
return target3 & sheetRect . size ;
public bool didPop ( object result ) {
_updateTweenRects ( ) ;
return base . didPop ( result ) ;
}
public void _onDismiss ( BuildContext context , float scale , float opacity ) {
_scale = scale ;
_opacityTween . end = opacity ;
_sheetOpacity = _opacityTween . animate (
new CurvedAnimation (
parent : animation ,
curve : new Interval ( 0.9f , 1.0f )
) ) ;
Navigator . of ( context ) . pop < object > ( ) ;
}
public void _updateTweenRects ( ) {
Rect childRect = _scale = = null
? CupertinoContextMenuUtils . _getRect ( _childGlobalKey )
: _getScaledRect ( _childGlobalKey , _scale ) ;
_rectTween . begin = _previousChildRect ;
_rectTween . end = childRect ;
Rect childRectOriginal = CupertinoContextMenuUtils . fromCenter (
center : _previousChildRect . center ,
width : _previousChildRect . width / CupertinoContextMenuUtils . _kOpenScale ,
height : _previousChildRect . height / CupertinoContextMenuUtils . _kOpenScale
) ;
Rect sheetRect = CupertinoContextMenuUtils . _getRect ( _sheetGlobalKey ) ;
Rect sheetRectBegin = _getSheetRectBegin (
_lastOrientation ,
_contextMenuLocation ,
childRectOriginal ,
sheetRect
) ;
_sheetRectTween . begin = sheetRectBegin ;
_sheetRectTween . end = sheetRect ;
_sheetScaleTween . begin = 0.0f ;
_sheetScaleTween . end = _scale ;
_rectTweenReverse . begin = childRectOriginal ;
_rectTweenReverse . end = childRect ;
}
public void _setOffstageInternally ( ) {
base . offstage = _externalOffstage | | _internalOffstage ;
changedInternalState ( ) ;
}
public bool didPop ( object result ) {
_updateTweenRects ( ) ;
return base . didPop ( result ) ;
}
public bool offstage {
set {
}
public TickerFuture didPush ( ) {
_internalOffstage = true ;
_setOffstageInternally ( ) ;
SchedulerBinding . instance . addPostFrameCallback ( ( TimeSpan timeSpan ) = > {
_updateTweenRects ( ) ;
_internalOffstage = false ;
_setOffstageInternally ( ) ;
} ) ;
return base . didPush ( ) ;
}
public Animation < float > createAnimation ( ) {
Animation < float > animation = base . createAnimation ( ) ;
_sheetOpacity = _opacityTween . animate ( new CurvedAnimation (
parent : animation ,
curve : Curves . linear
) ) ;
return animation ;
}
public override Widget buildPage ( BuildContext context , Animation < float > animation , Animation < float > secondaryAnimation ) {
return null ;
}
public override Widget buildTransitions ( BuildContext context1 , Animation < float > animation , Animation < float > secondaryAnimation , Widget child ) {
return new OrientationBuilder (
builder : ( BuildContext context2 , Orientation orientation ) = > {
_lastOrientation = orientation ;
if ( ! animation . isCompleted ) {
bool reverse = animation . status = = AnimationStatus . reverse ;
Rect rect = reverse
? _rectAnimatableReverse . evaluate ( animation )
: _rectAnimatable . evaluate ( animation ) ;
Rect sheetRect = reverse
? _sheetRectAnimatableReverse . evaluate ( animation )
: _sheetRectAnimatable . evaluate ( animation ) ;
float sheetScale = reverse
? _sheetScaleAnimatableReverse . evaluate ( animation )
: _sheetScaleAnimatable . evaluate ( animation ) ;
List < Widget > widgets = new List < Widget > ( ) ;
widgets . Add (
Positioned . fromRect (
rect : sheetRect ,
child : new Opacity (
opacity : _sheetOpacity . value ,
child : Transform . scale (
//alignment: getSheetAlignment(_contextMenuLocation),
scale : sheetScale ,
child : new _ContextMenuSheet (
key : _sheetGlobalKey ,
public TickerFuture didPush ( ) {
_internalOffstage = true ;
_setOffstageInternally ( ) ;
SchedulerBinding . instance . addPostFrameCallback ( ( TimeSpan timeSpan ) = > {
_updateTweenRects ( ) ;
_internalOffstage = false ;
_setOffstageInternally ( ) ;
} ) ;
return base . didPush ( ) ;
}
public Animation < float > createAnimation ( ) {
Animation < float > animation = base . createAnimation ( ) ;
_sheetOpacity = _opacityTween . animate ( new CurvedAnimation (
parent : animation ,
curve : Curves . linear
) ) ;
return animation ;
}
public override Widget buildPage ( BuildContext context , Animation < float > animation , Animation < float > secondaryAnimation ) {
return null ;
}
public override Widget buildTransitions ( BuildContext context1 , Animation < float > animation , Animation < float > secondaryAnimation , Widget child ) {
return new OrientationBuilder (
builder : ( BuildContext context2 , Orientation orientation ) = > {
_lastOrientation = orientation ;
if ( ! animation . isCompleted ) {
bool reverse = animation . status = = AnimationStatus . reverse ;
Rect rect = reverse
? _rectAnimatableReverse . evaluate ( animation )
: _rectAnimatable . evaluate ( animation ) ;
Rect sheetRect = reverse
? _sheetRectAnimatableReverse . evaluate ( animation )
: _sheetRectAnimatable . evaluate ( animation ) ;
float sheetScale = reverse
? _sheetScaleAnimatableReverse . evaluate ( animation )
: _sheetScaleAnimatable . evaluate ( animation ) ;
List < Widget > widgets = new List < Widget > ( ) ;
widgets . Add (
Positioned . fromRect (
rect : sheetRect ,
child : new Opacity (
opacity : _sheetOpacity . value ,
child : Transform . scale (
//alignment: getSheetAlignment(_contextMenuLocation),
scale : sheetScale ,
child : new _ContextMenuSheet (
key : _sheetGlobalKey ,
actions : _actions ,
contextMenuLocation : _contextMenuLocation ,
orientation : orientation
)
)
)
)
) ;
widgets . Add (
Positioned . fromRect (
key : _childGlobalKey ,
rect : rect ,
child : _builder ( context2 , animation )
) ) ;
return new Stack (
children : widgets
) ;
}
return new _ContextMenuRouteStatic (
child : _builder ( context1 , animation ) ,
childGlobalKey : _childGlobalKey ,
orientation : orientation
)
)
)
)
) ;
widgets . Add (
Positioned . fromRect (
key : _childGlobalKey ,
rect : rect ,
child : _builder ( context2 , animation )
)
) ;
return new Stack (
children : widgets
) ;
}
return new _ContextMenuRouteStatic (
actions : _actions ,
child : _builder ( context1 , animation ) ,
childGlobalKey : _childGlobalKey ,
contextMenuLocation : _contextMenuLocation ,
onDismiss : _onDismiss ,
orientation : orientation ,
sheetGlobalKey : _sheetGlobalKey
) ;
onDismiss : _onDismiss ,
orientation : orientation ,
sheetGlobalKey : _sheetGlobalKey
) ;
}
) ;
) ;
}
public class _ContextMenuRouteStatic : StatefulWidget {
public _ContextMenuRouteStatic (
Key key = null ,
List < Widget > actions = null ,
Widget child = null ,
GlobalKey childGlobalKey = null ,
_ContextMenuLocation contextMenuLocation = default ,
_DismissCallback onDismiss = default ,
Orientation orientation = default ,
GlobalKey sheetGlobalKey = null
) : base ( key : key ) {
D . assert ( contextMenuLocation ! = null ) ;
D . assert ( orientation ! = null ) ;
this . actions = actions ;
this . child = child ;
this . childGlobalKey = childGlobalKey ;
this . contextMenuLocation = contextMenuLocation ;
this . onDismiss = onDismiss ;
this . orientation = orientation ;
this . sheetGlobalKey = sheetGlobalKey ;
}
public readonly List < Widget > actions ;
public readonly Widget child ;
public readonly GlobalKey childGlobalKey ;
public readonly _ContextMenuLocation contextMenuLocation ;
public readonly _DismissCallback onDismiss ;
public readonly Orientation orientation ;
public readonly GlobalKey sheetGlobalKey ;
public class _ContextMenuRouteStatic : StatefulWidget {
public _ContextMenuRouteStatic (
Key key = null ,
List < Widget > actions = null ,
Widget child = null ,
GlobalKey childGlobalKey = null ,
_ContextMenuLocation contextMenuLocation = default ,
_DismissCallback onDismiss = default ,
Orientation orientation = default ,
GlobalKey sheetGlobalKey = null
) : base ( key : key ) {
D . assert ( contextMenuLocation ! = default ) ;
D . assert ( orientation ! = default ) ;
this . actions = actions ;
this . child = child ;
this . childGlobalKey = childGlobalKey ;
this . contextMenuLocation = contextMenuLocation ;
this . onDismiss = onDismiss ;
this . orientation = orientation ;
this . sheetGlobalKey = sheetGlobalKey ;
}
public readonly List < Widget > actions ;
public readonly Widget child ;
public readonly GlobalKey childGlobalKey ;
public readonly _ContextMenuLocation contextMenuLocation ;
public readonly _DismissCallback onDismiss ;
public readonly Orientation orientation ;
public readonly GlobalKey sheetGlobalKey ;
public override State createState ( ) {
return new _ContextMenuRouteStaticState ( ) ;
public override State createState ( ) {
return new _ContextMenuRouteStaticState ( ) ;
}
}
public class _ContextMenuRouteStaticState : TickerProviderStateMixin < _ContextMenuRouteStatic > {
public readonly static float _kMinScale = 0.8f ;
public readonly static float _kSheetScaleThreshold = 0.9f ;
public readonly static float _kPadding = 2 0.0f ;
public readonly static float _kDamping = 4 0 0.0f ;
public readonly static TimeSpan _kMoveControllerDuration = new TimeSpan ( 0 , 0 , 0 , 6 0 0 ) ;
public Offset _dragOffset ;
public float _lastScale = 1.0f ;
public AnimationController _moveController ;
public AnimationController _sheetController ;
public Animation < Offset > _moveAnimation ;
public Animation < float > _sheetScaleAnimation ;
public Animation < float > _sheetOpacityAnimation ;
public static float _getScale ( Orientation orientation , float maxDragDistance , float dy ) {
float dyDirectional = dy < = 0.0 ? dy : - dy ;
return Mathf . Max (
_kMinScale ,
( maxDragDistance + dyDirectional ) / maxDragDistance
) ;
}
void _onPanStart ( DragStartDetails details ) {
_moveController . setValue ( 1.0f ) ;
_setDragOffset ( Offset . zero ) ;
}
void _onPanUpdate ( DragUpdateDetails details ) {
_setDragOffset ( _dragOffset + details . delta ) ;
}
void _onPanEnd ( DragEndDetails details ) {
if ( details . velocity . pixelsPerSecond . dy . abs ( ) > = CupertinoContextMenuUtils . kMinFlingVelocity ) {
bool flingIsAway = details . velocity . pixelsPerSecond . dy > 0 ;
float finalPosition = flingIsAway
? _moveAnimation . value . dy + 1 0 0.0f
: 0.0f ;
if ( flingIsAway & & _sheetController . status ! = AnimationStatus . forward ) {
_sheetController . forward ( ) ;
} else if ( ! flingIsAway & & _sheetController . status ! = AnimationStatus . reverse ) {
_sheetController . reverse ( ) ;
}
public class _ContextMenuRouteStaticState : TickerProviderStateMixin < _ContextMenuRouteStatic > {
public readonly static float _kMinScale = 0.8f ;
public readonly static float _kSheetScaleThreshold = 0.9f ;
public readonly static float _kPadding = 2 0.0f ;
public readonly static float _kDamping = 4 0 0.0f ;
public readonly static TimeSpan _kMoveControllerDuration = TimeSpan . FromMilliseconds ( 6 0 0 ) ;
Offset _dragOffset ;
public float _lastScale = 1.0f ;
public AnimationController _moveController ;
public AnimationController _sheetController ;
public Animation < Offset > _moveAnimation ;
public Animation < float > _sheetScaleAnimation ;
public Animation < float > _sheetOpacityAnimation ;
public static float _getScale ( Orientation orientation , float maxDragDistance , float dy ) {
float dyDirectional = dy < = 0.0f ? dy : - dy ;
return Mathf . Max (
_kMinScale ,
( maxDragDistance + dyDirectional ) / maxDragDistance
) ;
}
void _onPanStart ( DragStartDetails details ) {
_moveController . setValue ( 1.0f ) ;
_setDragOffset ( Offset . zero ) ;
}
void _onPanUpdate ( DragUpdateDetails details ) {
_setDragOffset ( _dragOffset + details . delta ) ;
}
void _onPanEnd ( DragEndDetails details ) {
if ( details . velocity . pixelsPerSecond . dy . abs ( ) > = CupertinoContextMenuUtils . kMinFlingVelocity ) {
bool flingIsAway = details . velocity . pixelsPerSecond . dy > 0 ;
float finalPosition = flingIsAway
? _moveAnimation . value . dy + 1 0 0.0f
: 0.0f ;
if ( flingIsAway & & _sheetController . status ! = AnimationStatus . forward ) {
_sheetController . forward ( ) ;
} else if ( ! flingIsAway & & _sheetController . status ! = AnimationStatus . reverse ) {
_sheetController . reverse ( ) ;
}
_moveAnimation = new OffsetTween (
begin : new Offset ( 0.0f , _moveAnimation . value . dy ) ,
end : new Offset ( 0.0f , finalPosition )
) . animate ( _moveController ) ;
_moveController . reset ( ) ;
_moveController . duration = new TimeSpan ( 0 , 0 , 0 , 6 4 ) ;
_moveController . forward ( ) ;
_moveController . addStatusListener ( _flingStatusListener ) ;
return ;
}
if ( _lastScale = = _kMinScale ) {
widget . onDismiss ( context , _lastScale , _sheetOpacityAnimation . value ) ;
return ;
}
// Otherwise animate back home.
_moveController . addListener ( _moveListener ) ;
_moveController . reverse ( ) ;
_moveAnimation = new OffsetTween (
begin : new Offset ( 0.0f , _moveAnimation . value . dy ) ,
end : new Offset ( 0.0f , finalPosition )
) . animate ( _moveController ) ;
_moveController . reset ( ) ;
_moveController . duration = TimeSpan . FromMilliseconds ( 6 4 ) ;
_moveController . forward ( ) ;
_moveController . addStatusListener ( _flingStatusListener ) ;
return ;
}
if ( _lastScale = = _kMinScale ) {
widget . onDismiss ( context , _lastScale , _sheetOpacityAnimation . value ) ;
return ;
}
_moveController . addListener ( _moveListener ) ;
_moveController . reverse ( ) ;
void _moveListener ( ) {
if ( _lastScale > _kSheetScaleThreshold ) {
_moveController . removeListener ( _moveListener ) ;
if ( _sheetController . status ! = AnimationStatus . dismissed ) {
_sheetController . reverse ( ) ;
void _moveListener ( ) {
if ( _lastScale > _kSheetScaleThreshold ) {
_moveController . removeListener ( _moveListener ) ;
if ( _sheetController . status ! = AnimationStatus . dismissed ) {
_sheetController . reverse ( ) ;
}
}
void _flingStatusListener ( AnimationStatus status ) {
if ( status ! = AnimationStatus . completed ) {
return ;
}
_moveController . duration = _kMoveControllerDuration ;
_moveController . removeStatusListener ( _flingStatusListener ) ;
if ( _moveAnimation . value . dy = = 0.0 ) {
return ;
}
widget . onDismiss ( context , _lastScale , _sheetOpacityAnimation . value ) ;
void _flingStatusListener ( AnimationStatus status ) {
if ( status ! = AnimationStatus . completed ) {
return ;
}
_moveController . duration = _kMoveControllerDuration ;
_moveController . removeStatusListener ( _flingStatusListener ) ;
if ( _moveAnimation . value . dy = = 0.0 ) {
return ;
}
widget . onDismiss ( context , _lastScale , _sheetOpacityAnimation . value ) ;
Alignment _getChildAlignment ( Orientation orientation , _ContextMenuLocation contextMenuLocation ) {
switch ( contextMenuLocation ) {
case _ContextMenuLocation . center :
return orientation = = Orientation . portrait
? Alignment . bottomCenter
: Alignment . topRight ;
case _ContextMenuLocation . right :
return orientation = = Orientation . portrait
? Alignment . bottomCenter
: Alignment . topLeft ;
default :
return orientation = = Orientation . portrait
? Alignment . bottomCenter
: Alignment . topRight ;
}
Alignment _getChildAlignment ( Orientation orientation , _ContextMenuLocation contextMenuLocation ) {
switch ( contextMenuLocation ) {
case _ContextMenuLocation . center :
return orientation = = Orientation . portrait
? Alignment . bottomCenter
: Alignment . topRight ;
case _ContextMenuLocation . right :
return orientation = = Orientation . portrait
? Alignment . bottomCenter
: Alignment . topLeft ;
default :
return orientation = = Orientation . portrait
? Alignment . bottomCenter
: Alignment . topRight ;
}
// Allow horizontal and negative vertical movement, but damp it.
float endX = _kPadding * dragOffset . dx / _kDamping ;
float endY = dragOffset . dy > = 0.0
? dragOffset . dy
: _kPadding * dragOffset . dy / _kDamping ;
setState ( ( ) = > {
_dragOffset = dragOffset ;
_moveAnimation = new OffsetTween (
begin : Offset . zero ,
end : new Offset (
endX . clamp ( - _kPadding , _kPadding ) ,
endY
)
) . animate (
new CurvedAnimation (
parent : _moveController ,
curve : Curves . elasticIn
)
float endX = _kPadding * dragOffset . dx / _kDamping ;
float endY = dragOffset . dy > = 0.0
? dragOffset . dy
: _kPadding * dragOffset . dy / _kDamping ;
setState ( ( ) = > {
_dragOffset = dragOffset ;
_moveAnimation = new OffsetTween (
begin : Offset . zero ,
end : new Offset (
endX . clamp ( - _kPadding , _kPadding ) ,
endY
) ) . animate (
new CurvedAnimation (
parent : _moveController ,
curve : Curves . elasticIn
)
if ( _lastScale < = _kSheetScaleThreshold
& & _sheetController . status ! = AnimationStatus . forward
& & _sheetScaleAnimation . value ! = 0.0f ) {
_sheetController . forward ( ) ;
} else if ( _lastScale > _kSheetScaleThreshold
& & _sheetController . status ! = AnimationStatus . reverse
& & _sheetScaleAnimation . value ! = 1.0f ) {
_sheetController . reverse ( ) ;
}
} ) ;
if ( _lastScale < = _kSheetScaleThreshold & & _sheetController . status ! = AnimationStatus . forward
& & _sheetScaleAnimation . value ! = 0.0f ) {
_sheetController . forward ( ) ;
} else if ( _lastScale > _kSheetScaleThreshold & & _sheetController . status ! = AnimationStatus . reverse
& & _sheetScaleAnimation . value ! = 1.0f ) {
_sheetController . reverse ( ) ;
}
} ) ;
List < Widget > _getChildren ( Orientation orientation , _ContextMenuLocation contextMenuLocation ) {
Expanded child = new Expanded (
child : new Align (
alignment : _getChildAlignment (
widget . orientation ,
widget . contextMenuLocation
) ,
child : new AnimatedBuilder (
animation : _moveController ,
builder : _buildChildAnimation ,
child : widget . child
)
)
) ;
Container spacer = new Container (
width : _kPadding ,
height : _kPadding
) ;
Expanded sheet = new Expanded (
child : new AnimatedBuilder (
animation : _sheetController ,
builder : _buildSheetAnimation ,
child : new _ContextMenuSheet (
key : widget . sheetGlobalKey ,
actions : widget . actions ,
contextMenuLocation : widget . contextMenuLocation ,
orientation : widget . orientation
)
)
) ;
List < Widget > centerWidgets = new List < Widget > ( ) ;
centerWidgets . Add ( child ) ;
centerWidgets . Add ( spacer ) ;
centerWidgets . Add ( sheet ) ;
List < Widget > rightWidgets = new List < Widget > ( ) ;
rightWidgets . Add ( sheet ) ;
rightWidgets . Add ( spacer ) ;
rightWidgets . Add ( child ) ;
List < Widget > _getChildren ( Orientation orientation , _ContextMenuLocation contextMenuLocation ) {
Expanded child = new Expanded (
child : new Align (
alignment : _getChildAlignment (
widget . orientation ,
widget . contextMenuLocation
) ,
child : new AnimatedBuilder (
animation : _moveController ,
builder : _buildChildAnimation ,
child : widget . child
)
)
) ;
Container spacer = new Container (
width : _kPadding ,
height : _kPadding
) ;
Expanded sheet = new Expanded (
child : new AnimatedBuilder (
animation : _sheetController ,
builder : _buildSheetAnimation ,
child : new _ContextMenuSheet (
key : widget . sheetGlobalKey ,
actions : widget . actions ,
contextMenuLocation : widget . contextMenuLocation ,
orientation : widget . orientation
)
)
) ;
List < Widget > centerWidgets = new List < Widget > ( ) ;
centerWidgets . Add ( child ) ;
centerWidgets . Add ( spacer ) ;
centerWidgets . Add ( sheet ) ;
List < Widget > rightWidgets = new List < Widget > ( ) ;
rightWidgets . Add ( sheet ) ;
rightWidgets . Add ( spacer ) ;
rightWidgets . Add ( child ) ;
switch ( contextMenuLocation ) {
case _ContextMenuLocation . center :
return new List < Widget > { child , spacer , sheet } ;
vsync : this
) ;
_sheetController = new AnimationController (
duration : new TimeSpan ( 0 , 0 , 0 , 1 0 0 ) ,
//reverseDuration: new TimeSpan(0,0,0,300), /// TBC ???
duration : TimeSpan . FromMilliseconds ( 1 0 0 ) ,
reverseDuration : TimeSpan . FromMilliseconds ( 3 0 0 ) , /// TBC ???
vsync : this
) ;
_sheetScaleAnimation = new FloatTween (
T offValue = default ,
float? intervalOn = null ,
float? intervalOff = null
) / * : super (
first : new Tween < T > ( begin : offValue , end : onValue ) . animate (
new CurvedAnimation (
parent : controller ,
curve : new Interval ( intervalOn , intervalOn )
)
) ,
next : new Tween < T > ( begin : onValue , end : offValue ) . animate (
new CurvedAnimation (
parent : controller ,
curve : new Interval ( intervalOff , intervalOff )
)
)
) * ////?????
) : base (
first : new Tween < T > ( begin : offValue , end : onValue ) . animate (
new CurvedAnimation (
parent : controller ,
curve : new Interval ( intervalOn = = null ? 0.0f : ( float ) intervalOn , intervalOn = = null ? 0.0f : ( float ) intervalOn )
)
) ,
next : new Tween < T > ( begin : onValue , end : offValue ) . animate (
new CurvedAnimation (
parent : controller ,
curve : new Interval ( intervalOff = = null ? 0.0f : ( float ) intervalOff , intervalOff = = null ? 0.0f : ( float ) intervalOff )
)
)
)
{
D . assert ( intervalOn ! = null & & intervalOn > = 0.0 & & intervalOn < = 1.0 ) ;
D . assert ( intervalOff ! = null & & intervalOff > = 0.0 & & intervalOff < = 1.0 ) ;
public override T value {
get {
return next . value ; // == _offValue ? next.value : first.value; ????/
return next . value . Equals ( _offValue ) ? next . value : first . value ;
}
}