您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

757 行
26 KiB

using System;
using System.Collections.Generic;
using RSG;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.cupertino {
public class CupertinoRouteUtils {
public const float _kBackGestureWidth = 20.0f;
public const float _kMinFlingVelocity = 1.0f;
public const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds.
public const int _kMaxPageBackAnimationTime = 300; // Milliseconds.
public static readonly Color _kModalBarrierColor = new Color(0x6604040F);
public static readonly TimeSpan _kModalPopupTransitionDuration = new TimeSpan(0, 0, 0, 0, 335);
public static readonly Animatable<Offset> _kRightMiddleTween = new OffsetTween(
begin: new Offset(1.0f, 0.0f),
end: Offset.zero
);
public static readonly Animatable<Offset> _kMiddleLeftTween = new OffsetTween(
begin: Offset.zero,
end: new Offset(-1.0f / 3.0f, 0.0f)
);
public static readonly Animatable<Offset> _kBottomUpTween = new OffsetTween(
begin: new Offset(0.0f, 1.0f),
end: Offset.zero
);
public static readonly DecorationTween _kGradientShadowTween = new DecorationTween(
begin: _CupertinoEdgeShadowDecoration.none,
end: new _CupertinoEdgeShadowDecoration(
edgeGradient: new LinearGradient(
begin: new Alignment(0.9f, 0.0f),
end: Alignment.centerRight,
colors: new List<Color> {
new Color(0x00000000),
new Color(0x04000000),
new Color(0x12000000),
new Color(0x38000000),
},
stops: new List<float> {0.0f, 0.3f, 0.6f, 1.0f}
)
)
);
public static IPromise<object> showCupertinoModalPopup(
BuildContext context,
WidgetBuilder builder
) {
return Navigator.of(context, rootNavigator: true).push(
new _CupertinoModalPopupRoute(
builder: builder,
barrierLabel: "Dismiss"
)
);
}
public static readonly Animatable<float> _dialogScaleTween = new FloatTween(begin: 1.3f, end: 1.0f)
.chain(new CurveTween(curve: Curves.linearToEaseOut));
public static Widget _buildCupertinoDialogTransitions(BuildContext context, Animation<float> animation,
Animation<float>
secondaryAnimation, Widget child) {
CurvedAnimation fadeAnimation = new CurvedAnimation(
parent: animation,
curve: Curves.easeInOut
);
if (animation.status == AnimationStatus.reverse) {
return new FadeTransition(
opacity: fadeAnimation,
child: child
);
}
return new FadeTransition(
opacity: fadeAnimation,
child: new ScaleTransition(
child: child,
scale: animation.drive(_dialogScaleTween)
)
);
}
public static IPromise<object> showCupertinoDialog(
BuildContext context,
WidgetBuilder builder
) {
D.assert(builder != null);
return DialogUtils.showGeneralDialog(
context: context,
barrierDismissible: false,
barrierColor: _kModalBarrierColor,
transitionDuration: new TimeSpan(0, 0, 0, 0, 250),
pageBuilder:
(BuildContext _context, Animation<float> animation, Animation<float> secondaryAnimation) => {
return builder(_context);
},
transitionBuilder: _buildCupertinoDialogTransitions
);
}
}
class _CupertinoEdgeShadowDecoration : Decoration, IEquatable<_CupertinoEdgeShadowDecoration> {
public _CupertinoEdgeShadowDecoration(
LinearGradient edgeGradient = null
) {
this.edgeGradient = edgeGradient;
}
public static _CupertinoEdgeShadowDecoration none =
new _CupertinoEdgeShadowDecoration();
public readonly LinearGradient edgeGradient;
static _CupertinoEdgeShadowDecoration lerpCupertino(
_CupertinoEdgeShadowDecoration a,
_CupertinoEdgeShadowDecoration b,
float t
) {
if (a == null && b == null) {
return null;
}
return new _CupertinoEdgeShadowDecoration(
edgeGradient: LinearGradient.lerp(a?.edgeGradient, b?.edgeGradient, t)
);
}
public override Decoration lerpFrom(Decoration a, float t) {
if (!(a is _CupertinoEdgeShadowDecoration)) {
return lerpCupertino(null, this, t);
}
return lerpCupertino((_CupertinoEdgeShadowDecoration) a, this, t);
}
public override Decoration lerpTo(Decoration b, float t) {
if (!(b is _CupertinoEdgeShadowDecoration)) {
return lerpCupertino(this, null, t);
}
return lerpCupertino(this, (_CupertinoEdgeShadowDecoration) b, t);
}
public override BoxPainter createBoxPainter(VoidCallback onChanged = null) {
return new _CupertinoEdgeShadowPainter(this, onChanged);
}
public override int GetHashCode() {
return this.edgeGradient.GetHashCode();
}
public bool Equals(_CupertinoEdgeShadowDecoration other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return Equals(this.edgeGradient, other.edgeGradient);
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
if (obj.GetType() != this.GetType()) {
return false;
}
return this.Equals((_CupertinoEdgeShadowDecoration) obj);
}
public static bool operator ==(_CupertinoEdgeShadowDecoration left, _CupertinoEdgeShadowDecoration right) {
return Equals(left, right);
}
public static bool operator !=(_CupertinoEdgeShadowDecoration left, _CupertinoEdgeShadowDecoration right) {
return !Equals(left, right);
}
public int hashCode {
get { return this.edgeGradient.GetHashCode(); }
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<LinearGradient>("edgeGradient", this.edgeGradient));
}
}
class _CupertinoEdgeShadowPainter : BoxPainter {
public _CupertinoEdgeShadowPainter(
_CupertinoEdgeShadowDecoration decoration = null,
VoidCallback onChange = null
) : base(onChange) {
D.assert(decoration != null);
this._decoration = decoration;
}
readonly _CupertinoEdgeShadowDecoration _decoration;
public override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
LinearGradient gradient = this._decoration.edgeGradient;
if (gradient == null) {
return;
}
float deltaX = -configuration.size.width;
Rect rect = (offset & configuration.size).translate(deltaX, 0.0f);
Paint paint = new Paint();
paint.shader = gradient.createShader(rect);
canvas.drawRect(rect, paint);
}
}
public class CupertinoPageRoute : PageRoute {
public CupertinoPageRoute(
WidgetBuilder builder,
RouteSettings settings = null,
string title = "",
bool maintainState = true,
bool fullscreenDialog = false
) :
base(settings: settings, fullscreenDialog: fullscreenDialog) {
D.assert(builder != null);
D.assert(this.opaque);
this.builder = builder;
this.title = title;
this.maintainState = maintainState;
}
public readonly WidgetBuilder builder;
public readonly string title;
ValueNotifier<string> _previousTitle;
public ValueListenable<string> previousTitle {
get {
D.assert(
this._previousTitle != null,
() => "Cannot read the previousTitle for a route that has not yet been installed"
);
return this._previousTitle;
}
}
protected internal override void didChangePrevious(Route previousRoute) {
string previousTitleString = previousRoute is CupertinoPageRoute
? ((CupertinoPageRoute) previousRoute).title
: null;
if (this._previousTitle == null) {
this._previousTitle = new ValueNotifier<string>(previousTitleString);
}
else {
this._previousTitle.value = previousTitleString;
}
base.didChangePrevious(previousRoute);
}
public override bool maintainState { get; }
public override TimeSpan transitionDuration {
get { return new TimeSpan(0, 0, 0, 0, 400); }
}
public override Color barrierColor {
get { return null; }
}
public string barrierLabel {
get { return null; }
}
public override bool canTransitionFrom(TransitionRoute previousRoute) {
return previousRoute is CupertinoPageRoute;
}
public override bool canTransitionTo(TransitionRoute nextRoute) {
return nextRoute is CupertinoPageRoute && !((CupertinoPageRoute) nextRoute).fullscreenDialog;
}
static bool isPopGestureInProgress(PageRoute route) {
return route.navigator.userGestureInProgress;
}
public bool popGestureInProgress {
get { return isPopGestureInProgress(this); }
}
public bool popGestureEnabled {
get { return _isPopGestureEnabled(this); }
}
static bool _isPopGestureEnabled(PageRoute route) {
if (route.isFirst) {
return false;
}
if (route.willHandlePopInternally) {
return false;
}
if (route.hasScopedWillPopCallback) {
return false;
}
if (route.fullscreenDialog) {
return false;
}
if (route.animation.status != AnimationStatus.completed) {
return false;
}
if (route.secondaryAnimation.status != AnimationStatus.dismissed) {
return false;
}
if (isPopGestureInProgress(route)) {
return false;
}
return true;
}
public override Widget buildPage(BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation) {
Widget result = this.builder(context);
D.assert(() => {
if (result == null) {
throw new UIWidgetsError(
$"The builder for route {this.settings.name} returned null.\nRoute builders must never return null.");
}
return true;
});
return result;
}
static _CupertinoBackGestureController _startPopGesture(PageRoute route) {
D.assert(_isPopGestureEnabled(route));
return new _CupertinoBackGestureController(
navigator: route.navigator,
controller: route.controller
);
}
public static Widget buildPageTransitions(
PageRoute route,
BuildContext context,
Animation<float> animation,
Animation<float> secondaryAnimation,
Widget child
) {
if (route.fullscreenDialog) {
return new CupertinoFullscreenDialogTransition(
animation: animation,
child: child
);
}
else {
return new CupertinoPageTransition(
primaryRouteAnimation: animation,
secondaryRouteAnimation: secondaryAnimation,
linearTransition: isPopGestureInProgress(route),
child: new _CupertinoBackGestureDetector(
enabledCallback: () => _isPopGestureEnabled(route),
onStartPopGesture: () => _startPopGesture(route),
child: child
)
);
}
}
public override Widget buildTransitions(BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation, Widget child) {
return buildPageTransitions(this, context, animation, secondaryAnimation, child);
}
public new string debugLabel {
get { return $"{base.debugLabel}(${this.settings.name})"; }
}
}
class CupertinoPageTransition : StatelessWidget {
public CupertinoPageTransition(
Animation<float> primaryRouteAnimation,
Animation<float> secondaryRouteAnimation,
Widget child,
bool linearTransition,
Key key = null
) : base(key: key) {
this._primaryPositionAnimation =
(linearTransition
? primaryRouteAnimation
: new CurvedAnimation(
parent: primaryRouteAnimation,
curve: Curves.linearToEaseOut,
reverseCurve: Curves.easeInToLinear
)
).drive(CupertinoRouteUtils._kRightMiddleTween);
this._secondaryPositionAnimation =
(linearTransition
? secondaryRouteAnimation
: new CurvedAnimation(
parent: secondaryRouteAnimation,
curve: Curves.linearToEaseOut,
reverseCurve: Curves.easeInToLinear
)
).drive(CupertinoRouteUtils._kMiddleLeftTween);
this._primaryShadowAnimation =
(linearTransition
? primaryRouteAnimation
: new CurvedAnimation(
parent: primaryRouteAnimation,
curve: Curves.linearToEaseOut
)
).drive(CupertinoRouteUtils._kGradientShadowTween);
this.child = child;
}
public readonly Animation<Offset> _primaryPositionAnimation;
public readonly Animation<Offset> _secondaryPositionAnimation;
public readonly Animation<Decoration> _primaryShadowAnimation;
public readonly Widget child;
public override Widget build(BuildContext context) {
TextDirection textDirection = Directionality.of(context);
return new SlideTransition(
position: this._secondaryPositionAnimation,
textDirection: textDirection,
transformHitTests: false,
child: new SlideTransition(
position: this._primaryPositionAnimation,
textDirection: textDirection,
child: new DecoratedBoxTransition(
decoration: this._primaryShadowAnimation,
child: this.child
)
)
);
}
}
class CupertinoFullscreenDialogTransition : StatelessWidget {
public CupertinoFullscreenDialogTransition(
Animation<float> animation,
Widget child,
Key key = null
) : base(key: key) {
this._positionAnimation = new CurvedAnimation(
parent: animation,
curve: Curves.linearToEaseOut,
reverseCurve: Curves.linearToEaseOut.flipped
).drive(CupertinoRouteUtils._kBottomUpTween);
this.child = child;
}
readonly Animation<Offset> _positionAnimation;
public readonly Widget child;
public override Widget build(BuildContext context) {
return new SlideTransition(
position: this._positionAnimation,
child: this.child
);
}
}
class _CupertinoBackGestureDetector : StatefulWidget {
public _CupertinoBackGestureDetector(
Widget child,
ValueGetter<bool> enabledCallback,
ValueGetter<_CupertinoBackGestureController> onStartPopGesture,
Key key = null
) : base(key: key) {
D.assert(enabledCallback != null);
D.assert(onStartPopGesture != null);
D.assert(child != null);
this.child = child;
this.enabledCallback = enabledCallback;
this.onStartPopGesture = onStartPopGesture;
}
public readonly Widget child;
public readonly ValueGetter<bool> enabledCallback;
public readonly ValueGetter<_CupertinoBackGestureController> onStartPopGesture;
public override State createState() {
return new _CupertinoBackGestureDetectorState();
}
}
class _CupertinoBackGestureDetectorState : State<_CupertinoBackGestureDetector> {
_CupertinoBackGestureController _backGestureController;
HorizontalDragGestureRecognizer _recognizer;
public override void initState() {
base.initState();
this._recognizer = new HorizontalDragGestureRecognizer(debugOwner: this);
this._recognizer.onStart = this._handleDragStart;
this._recognizer.onUpdate = this._handleDragUpdate;
this._recognizer.onEnd = this._handleDragEnd;
this._recognizer.onCancel = this._handleDragCancel;
}
public override void dispose() {
this._recognizer.dispose();
base.dispose();
}
void _handleDragStart(DragStartDetails details) {
D.assert(this.mounted);
D.assert(this._backGestureController == null);
this._backGestureController = this.widget.onStartPopGesture();
}
void _handleDragUpdate(DragUpdateDetails details) {
D.assert(this.mounted);
D.assert(this._backGestureController != null);
this._backGestureController.dragUpdate(
this._convertToLogical(details.primaryDelta / this.context.size.width));
}
void _handleDragEnd(DragEndDetails details) {
D.assert(this.mounted);
D.assert(this._backGestureController != null);
this._backGestureController.dragEnd(
this._convertToLogical(details.velocity.pixelsPerSecond.dx / this.context.size.width) ?? 0);
this._backGestureController = null;
}
void _handleDragCancel() {
D.assert(this.mounted);
this._backGestureController?.dragEnd(0.0f);
this._backGestureController = null;
}
void _handlePointerDown(PointerDownEvent evt) {
if (this.widget.enabledCallback()) {
this._recognizer.addPointer(evt);
}
}
float? _convertToLogical(float? value) {
switch (Directionality.of(this.context)) {
case TextDirection.rtl:
return -value;
case TextDirection.ltr:
return value;
}
return value;
}
public override Widget build(BuildContext context) {
float dragAreaWidth = Directionality.of(context) == TextDirection.ltr
? MediaQuery.of(context).padding.left
: MediaQuery.of(context).padding.right;
dragAreaWidth = Mathf.Max(dragAreaWidth, CupertinoRouteUtils._kBackGestureWidth);
return new Stack(
fit: StackFit.passthrough,
children: new List<Widget> {
this.widget.child,
new Positioned(
left: 0.0f,
width: dragAreaWidth,
top: 0.0f,
bottom: 0.0f,
child: new Listener(
onPointerDown: this._handlePointerDown,
behavior: HitTestBehavior.translucent
)
)
}
);
}
}
class _CupertinoBackGestureController {
public _CupertinoBackGestureController(
NavigatorState navigator,
AnimationController controller
) {
D.assert(navigator != null);
D.assert(controller != null);
this.navigator = navigator;
this.controller = controller;
this.navigator.didStartUserGesture();
}
public readonly AnimationController controller;
public readonly NavigatorState navigator;
public void dragUpdate(float? delta) {
if (delta != null) {
this.controller.setValue(this.controller.value - (float) delta);
}
}
public void dragEnd(float velocity) {
Curve animationCurve = Curves.fastLinearToSlowEaseIn;
bool animateForward;
if (velocity.abs() >= CupertinoRouteUtils._kMinFlingVelocity) {
animateForward = velocity > 0 ? false : true;
}
else {
animateForward = this.controller.value > 0.5 ? true : false;
}
if (animateForward) {
int droppedPageForwardAnimationTime = Mathf.Min(
MathUtils.lerpFloat(CupertinoRouteUtils._kMaxDroppedSwipePageForwardAnimationTime, 0f,
this.controller.value).floor(),
CupertinoRouteUtils._kMaxPageBackAnimationTime
);
this.controller.animateTo(1.0f, duration: new TimeSpan(0, 0, 0, 0, droppedPageForwardAnimationTime),
curve: animationCurve);
}
else {
this.navigator.pop();
if (this.controller.isAnimating) {
int droppedPageBackAnimationTime =
MathUtils.lerpFloat(0f, CupertinoRouteUtils._kMaxDroppedSwipePageForwardAnimationTime,
this.controller.value).floor();
this.controller.animateBack(0.0f, duration: new TimeSpan(0, 0, 0, 0, droppedPageBackAnimationTime),
curve: animationCurve);
}
}
if (this.controller.isAnimating) {
AnimationStatusListener animationStatusCallback = null;
animationStatusCallback = (AnimationStatus status) => {
this.navigator.didStopUserGesture();
this.controller.removeStatusListener(animationStatusCallback);
};
this.controller.addStatusListener(animationStatusCallback);
}
else {
this.navigator.didStopUserGesture();
}
}
}
class _CupertinoModalPopupRoute : PopupRoute {
public _CupertinoModalPopupRoute(
WidgetBuilder builder = null,
string barrierLabel = null,
RouteSettings settings = null
) : base(settings: settings) {
this.builder = builder;
this.barrierLabel = barrierLabel;
}
public readonly WidgetBuilder builder;
public readonly string barrierLabel;
public override Color barrierColor {
get { return CupertinoRouteUtils._kModalBarrierColor; }
}
public override bool barrierDismissible {
get { return true; }
}
public bool semanticsDismissible {
get { return false; }
}
public override TimeSpan transitionDuration {
get { return CupertinoRouteUtils._kModalPopupTransitionDuration; }
}
new Animation<float> _animation;
Tween<Offset> _offsetTween;
public override Animation<float> createAnimation() {
D.assert(this._animation == null);
this._animation = new CurvedAnimation(
parent: base.createAnimation(),
curve: Curves.linearToEaseOut,
reverseCurve: Curves.linearToEaseOut.flipped
);
this._offsetTween = new OffsetTween(
begin: new Offset(0.0f, 1.0f),
end: new Offset(0.0f, 0.0f)
);
return this._animation;
}
public override Widget buildPage(BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation) {
return this.builder(context);
}
public override Widget buildTransitions(BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation, Widget child) {
return new Align(
alignment: Alignment.bottomCenter,
child: new FractionalTranslation(
translation: this._offsetTween.evaluate(this._animation),
child: child
)
);
}
}
}