using Unity.UIWidgets.animation; using Unity.UIWidgets.foundation; using Unity.UIWidgets.rendering; using Unity.UIWidgets.ui; namespace Unity.UIWidgets.widgets { public abstract class AnimatedWidget : StatefulWidget { public readonly Listenable listenable; protected AnimatedWidget(Key key = null, Listenable listenable = null) : base(key) { D.assert(listenable != null); this.listenable = listenable; } protected internal abstract Widget build(BuildContext context); public override State createState() { return new _AnimatedState(); } public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { base.debugFillProperties(properties); properties.add(new DiagnosticsProperty("animation", this.listenable)); } } public class _AnimatedState : State { public override void initState() { base.initState(); this.widget.listenable.addListener(this._handleChange); } public override void didUpdateWidget(StatefulWidget oldWidget) { base.didUpdateWidget(oldWidget); if (this.widget.listenable != ((AnimatedWidget) oldWidget).listenable) { ((AnimatedWidget) oldWidget).listenable.removeListener(this._handleChange); this.widget.listenable.addListener(this._handleChange); } } public override void dispose() { this.widget.listenable.removeListener(this._handleChange); base.dispose(); } void _handleChange() { this.setState(() => { // The listenable's state is our build state, and it changed already. }); } public override Widget build(BuildContext context) { return this.widget.build(context); } } public class SlideTransition : AnimatedWidget { public SlideTransition(Key key = null, Animation position = null, bool transformHitTests = true, TextDirection? textDirection = null, Widget child = null) : base(key: key, listenable: position) { D.assert(position != null); this.transformHitTests = transformHitTests; this.textDirection = textDirection; this.child = child; } public Animation position { get { return (Animation) this.listenable; } } public readonly TextDirection? textDirection; public readonly bool transformHitTests; public readonly Widget child; protected internal override Widget build(BuildContext context) { var offset = this.position.value; if (this.textDirection == TextDirection.rtl) { offset = new Offset(-offset.dx, offset.dy); } return new FractionalTranslation( translation: offset, transformHitTests: this.transformHitTests, child: this.child ); } } public class FadeTransition : SingleChildRenderObjectWidget { public FadeTransition(Key key = null, Animation opacity = null, Widget child = null) : base(key: key, child: child) { this.opacity = opacity; } public readonly Animation opacity; public override RenderObject createRenderObject(BuildContext context) { return new RenderAnimatedOpacity( opacity: this.opacity ); } public override void updateRenderObject(BuildContext context, RenderObject renderObject) { ((RenderAnimatedOpacity) renderObject).opacity = this.opacity; } public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { base.debugFillProperties(properties); properties.add(new DiagnosticsProperty>("opacity", this.opacity)); } } public class AnimatedBuilder : AnimatedWidget { public readonly TransitionBuilder builder; public readonly Widget child; public AnimatedBuilder(Key key = null, Listenable animation = null, TransitionBuilder builder = null, Widget child = null) : base(key, animation) { D.assert(builder != null); this.builder = builder; this.child = child; } protected internal override Widget build(BuildContext context) { return this.builder(context, this.child); } } }