using System; using System.Collections.Generic; using Unity.UIWidgets.animation; using Unity.UIWidgets.foundation; using Unity.UIWidgets.painting; using Unity.UIWidgets.ui; using Unity.UIWidgets.widgets; namespace UIWidgetsSample { public static class ModalPage { public static void popup( BuildContext context, Widget child, Widget overlay = null, VoidCallback onPop = null, bool justFade = false ) { PopupRoute route; if (justFade) { route = new _FadePopupRoute( cxt => child, overlay == null ? (WidgetBuilder) null : ctx => overlay, "Dismiss" ); } else { route = new _ModalPopupRoute( cxt => child, overlay == null ? (WidgetBuilder) null : ctx => overlay, "Dismiss" ); } Navigator.push(context, route).then_(_ => onPop?.Invoke()); } public static void dismiss(BuildContext context) { // if (Navigator.canPop(context)) { Navigator.pop(context); } } } internal class _ModalPopupRoute : PopupRoute { public _ModalPopupRoute( WidgetBuilder builder = null, WidgetBuilder overlayBuilder = null, string barrierLabel = "", RouteSettings settings = null ) : base(settings) { this.builder = builder; this.barrierLabel = barrierLabel; this.overlayBuilder = overlayBuilder; } private readonly WidgetBuilder builder; private readonly WidgetBuilder overlayBuilder; public string barrierLabel { get; } public override Color barrierColor => new Color(0x6604040F); public override bool barrierDismissible => true; public override TimeSpan transitionDuration => TimeSpan.FromMilliseconds(335); private AnimationController _animationController; private Animation _animation; private Tween _offsetTween; private Tween _opacityTween; public override Animation createAnimation() { D.assert(_animation == null); _animation = new CurvedAnimation( base.createAnimation(), Curves.linearToEaseOut, Curves.linearToEaseOut.flipped ); _offsetTween = new OffsetTween( new Offset(0, 1), new Offset(0, 0) ); _opacityTween = new FloatTween(0, 1); return _animation; } public override Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { return builder(context); } public override Widget buildTransitions(BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { Widget result = new Align( alignment: Alignment.bottomCenter, child: new FractionalTranslation( translation: _offsetTween.evaluate(_animation), child: child ) ); if (overlayBuilder != null) { result = new Stack( children: new List { Positioned.fill( new Opacity( opacity: _opacityTween.evaluate(_animation), child: overlayBuilder(context) ) ), result }); } return result; } } internal class _FadePopupRoute : PopupRoute { public _FadePopupRoute( WidgetBuilder builder = null, WidgetBuilder overlayBuilder = null, string barrierLabel = "", RouteSettings settings = null ) : base(settings) { this.builder = builder; this.barrierLabel = barrierLabel; this.overlayBuilder = overlayBuilder; } private readonly WidgetBuilder builder; private readonly WidgetBuilder overlayBuilder; public string barrierLabel { get; } public override Color barrierColor => new Color(0x6604040F); public override bool barrierDismissible => true; public override TimeSpan transitionDuration => TimeSpan.FromMilliseconds(335); private AnimationController _animationController; private Animation _animation; private Tween _opacityTween; public override Animation createAnimation() { D.assert(_animation == null); _animation = new CurvedAnimation( base.createAnimation(), Curves.linearToEaseOut, Curves.linearToEaseOut.flipped ); _opacityTween = new FloatTween(0, 1); return _animation; } public override Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { return builder(context); } public override Widget buildTransitions(BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { Widget result = new Align( alignment: Alignment.bottomCenter, child: new Opacity( opacity: _opacityTween.evaluate(_animation), child: child ) ); if (overlayBuilder != null) { result = new Stack( children: new List { Positioned.fill( new Opacity( opacity: _opacityTween.evaluate(_animation), child: overlayBuilder(context) ) ), result }); } return result; } } }