浏览代码

Merge remote-tracking branch 'origin/master' into text

/main
fzhangtj 6 年前
当前提交
cd624f79
共有 74 个文件被更改,包括 4840 次插入23 次删除
  1. 2
      Assets/UIWidgets/foundation/basic_types.cs
  2. 65
      Assets/UIWidgets/foundation/change_notifier.cs
  3. 11
      Assets/UIWidgets/gestures/recognizer.cs
  4. 6
      Assets/UIWidgets/painting/image_provider.cs
  5. 25
      Assets/UIWidgets/painting/image_stream.cs
  6. 36
      Assets/UIWidgets/rendering/viewport_offset.cs
  7. 18
      Assets/UIWidgets/scheduler/binding.cs
  8. 62
      Assets/UIWidgets/ui/geometry.cs
  9. 27
      Assets/UIWidgets/ui/painting/painting.cs
  10. 14
      Assets/UIWidgets/ui/window.cs
  11. 144
      Assets/UIWidgets/widgets/framework.cs
  12. 2
      ProjectSettings/ProjectSettings.asset
  13. 7
      Assets/UIWidgets/gestures/drag.cs
  14. 3
      Assets/UIWidgets/gestures/drag.cs.meta
  15. 298
      Assets/UIWidgets/scheduler/ticker.cs
  16. 3
      Assets/UIWidgets/scheduler/ticker.cs.meta
  17. 57
      Assets/UIWidgets/widgets/basic.cs
  18. 3
      Assets/UIWidgets/widgets/basic.cs.meta
  19. 52
      Assets/UIWidgets/widgets/binding.cs
  20. 3
      Assets/UIWidgets/widgets/binding.cs.meta
  21. 178
      Assets/UIWidgets/widgets/image.cs
  22. 3
      Assets/UIWidgets/widgets/image.cs.meta
  23. 70
      Assets/UIWidgets/widgets/notification_listener.cs
  24. 3
      Assets/UIWidgets/widgets/notification_listener.cs.meta
  25. 361
      Assets/UIWidgets/widgets/scroll_activity.cs
  26. 3
      Assets/UIWidgets/widgets/scroll_activity.cs.meta
  27. 18
      Assets/UIWidgets/widgets/scroll_context.cs
  28. 3
      Assets/UIWidgets/widgets/scroll_context.cs.meta
  29. 75
      Assets/UIWidgets/widgets/scroll_matrics.cs
  30. 3
      Assets/UIWidgets/widgets/scroll_matrics.cs.meta
  31. 139
      Assets/UIWidgets/widgets/scroll_notification.cs
  32. 3
      Assets/UIWidgets/widgets/scroll_notification.cs.meta
  33. 53
      Assets/UIWidgets/widgets/scroll_notification.mixin.gen.cs
  34. 11
      Assets/UIWidgets/widgets/scroll_notification.mixin.gen.cs.meta
  35. 32
      Assets/UIWidgets/widgets/scroll_notification.mixin.njk
  36. 3
      Assets/UIWidgets/widgets/scroll_notification.mixin.njk.meta
  37. 352
      Assets/UIWidgets/widgets/scroll_physics.cs
  38. 3
      Assets/UIWidgets/widgets/scroll_physics.cs.meta
  39. 7
      Assets/UIWidgets/widgets/scroll_position.cs
  40. 3
      Assets/UIWidgets/widgets/scroll_position.cs.meta
  41. 169
      Assets/UIWidgets/widgets/scroll_simulation.cs
  42. 3
      Assets/UIWidgets/widgets/scroll_simulation.cs.meta
  43. 318
      Assets/UIWidgets/animation/curves.cs
  44. 3
      Assets/UIWidgets/animation/animation.cs.meta
  45. 3
      Assets/UIWidgets/animation/animation_controller.cs.meta
  46. 3
      Assets/UIWidgets/animation/animations.cs.meta
  47. 11
      Assets/UIWidgets/animation/curves.cs.meta
  48. 2
      Assets/UIWidgets/animation/listener_helpers.cs
  49. 3
      Assets/UIWidgets/animation/listener_helpers.cs.meta
  50. 11
      Assets/UIWidgets/animation/listener_helpers.mixin.gen.cs.meta
  51. 3
      Assets/UIWidgets/animation/listener_helpers.mixin.njk.meta
  52. 3
      Assets/UIWidgets/animation/tween.cs.meta
  53. 60
      Assets/UIWidgets/animation/animation.cs
  54. 417
      Assets/UIWidgets/animation/animation_controller.cs
  55. 591
      Assets/UIWidgets/animation/animations.cs
  56. 245
      Assets/UIWidgets/animation/listener_helpers.mixin.gen.cs
  57. 141
      Assets/UIWidgets/animation/listener_helpers.mixin.njk
  58. 216
      Assets/UIWidgets/animation/tween.cs
  59. 44
      Assets/UIWidgets/physics/clamped_simulation.cs
  60. 3
      Assets/UIWidgets/physics/clamped_simulation.cs.meta
  61. 96
      Assets/UIWidgets/physics/friction_simulation.cs
  62. 3
      Assets/UIWidgets/physics/friction_simulation.cs.meta
  63. 36
      Assets/UIWidgets/physics/gravity_simulation.cs
  64. 3
      Assets/UIWidgets/physics/gravity_simulation.cs.meta
  65. 15
      Assets/UIWidgets/physics/simulation.cs
  66. 11
      Assets/UIWidgets/physics/simulation.cs.meta
  67. 238
      Assets/UIWidgets/physics/spring_simulation.cs
  68. 3
      Assets/UIWidgets/physics/spring_simulation.cs.meta
  69. 28
      Assets/UIWidgets/physics/tolerance.cs
  70. 3
      Assets/UIWidgets/physics/tolerance.cs.meta
  71. 14
      Assets/UIWidgets/physics/utils.cs
  72. 3
      Assets/UIWidgets/physics/utils.cs.meta

2
Assets/UIWidgets/foundation/basic_types.cs


public static bool isNotEmpty<TKey, TValue>(this IDictionary<TKey, TValue> it) {
return it.Count != 0;
}
public static bool isEmpty(this string it) {
return string.IsNullOrEmpty(it);
}

65
Assets/UIWidgets/foundation/change_notifier.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.ui;
using UnityEngine;

}
public static class ListenableUtils {
public static Listenable merge(List<Listenable> listenables) {
public static Listenable merge(this List<Listenable> listenables) {
return new _MergingListenable(listenables);
}
}

}
public class ChangeNotifier : Listenable {
public ObserverList<VoidCallback> _listeners = new ObserverList<VoidCallback>();
public class ChangeNotifier : Listenable, IDisposable {
ObserverList<VoidCallback> _listeners = new ObserverList<VoidCallback>();
bool _debugAssertNotDisposed() {
D.assert(() => {
if (this._listeners == null) {
throw new UIWidgetsError(
string.Format("A {0} was used after being disposed.\n" +
"Once you have called dispose() on a {0}, it can no longer be used.",
this.GetType()));
}
return true;
});
public bool hasListeners {
get { return this._listeners.Count > 0; }
return true;
}
protected bool hasListeners {
get {
D.assert(this._debugAssertNotDisposed());
return this._listeners.isNotEmpty();
}
D.assert(this._debugAssertNotDisposed());
D.assert(this._debugAssertNotDisposed());
public void Dispose() {
this.dispose();
}
D.assert(this._debugAssertNotDisposed());
public void notifyListeners() {
protected void notifyListeners() {
D.assert(this._debugAssertNotDisposed());
if (this._listeners != null) {
var localListeners = new List<VoidCallback>(this._listeners);
foreach (VoidCallback listener in localListeners) {

}
}
catch (Exception ex) {
Debug.LogError("error while dispatching notifications: " + ex);
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: ex,
library: "foundation library",
context: "while dispatching notifications for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " sending notification was:");
information.Append(" " + this);
}
));
}
}
}

public class _MergingListenable : ChangeNotifier {
public _MergingListenable(List<Listenable> _children) {
class _MergingListenable : ChangeNotifier {
internal _MergingListenable(List<Listenable> _children) {
this._children = _children;
foreach (Listenable child in _children) {

}
}
public readonly List<Listenable> _children;
readonly List<Listenable> _children;
public override void dispose() {
foreach (Listenable child in this._children) {

base.dispose();
}
public override string ToString() {
return "Listenable.merge([" + string.Join(", ", this._children.Select(c => c.ToString()).ToArray()) + "])";
}
}
public class ValueNotifier<T> : ChangeNotifier, ValueListenable<T> {

}
}
public T _value;
T _value;
public override string ToString() {
return Diagnostics.describeIdentity(this) + "(" + this._value + ")";
}
}
}

11
Assets/UIWidgets/gestures/recognizer.cs


result = callback();
}
catch (Exception ex) {
Debug.LogError("Error while handling a gesture [" + name + "]: " + ex);
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: ex,
library: "gesture",
context: "while handling a gesture",
informationCollector: information => {
information.AppendLine("Handler: " + name);
information.AppendLine("Recognizer:");
information.AppendLine(" " + this);
}
));
}
return result;

6
Assets/UIWidgets/painting/image_provider.cs


using UnityEngine;
namespace UIWidgets.painting {
public abstract class ImageProvider<T> {
public interface IImageProvider<out T> {
ImageStream resolve(ImageConfiguration configuration);
}
public abstract class ImageProvider<T> : IImageProvider<T> {
public ImageStream resolve(ImageConfiguration configuration) {
ImageStream stream = new ImageStream();
T obtainedKey;

25
Assets/UIWidgets/painting/image_stream.cs


private ImageStreamCompleter _completer;
private List<_ImageListenerPair> _listeners;
public System.Object key {
get {
return _completer != null ? (object) _completer : this;
}
}
public ImageStreamCompleter completer {
get { return _completer; }
}

listenerPair.errorListener
);
}
}
}
public void addListener(ImageListener listener, ImageErrorListerner onError = null) {
if (_completer != null) {
_completer.addListener(listener, onError);
} else {
if (_listeners == null) {
_listeners = new List<_ImageListenerPair>();
}
_listeners.Add(new _ImageListenerPair(listener, onError));
}
}
public void removeListener(ImageListener listener) {
if (_completer != null) {
_completer.removeListener(listener);
} else {
_listeners.RemoveAll(listenerPair => listenerPair.listener == listener);
}
}
}

36
Assets/UIWidgets/rendering/viewport_offset.cs


using System;
using System.Collections.Generic;
using RSG;
using UIWidgets.animation;
using UIWidgets.foundation;
namespace UIWidgets.rendering {

return ScrollDirection.forward;
}
throw new Exception("unknown direction");
D.assert(false);
return default(ScrollDirection);
}
}

public abstract void correctBy(double correction);
public abstract void jumpTo(double pixels);
public abstract IPromise<object> animateTo(double to, TimeSpan duration, Curve curve);
public abstract bool allowImplicitScrolling { get; }
public override string ToString() {
var description = new List<string>();
this.debugFillDescription(description);
return Diagnostics.describeIdentity(this) + "(" + string.Join(", ", description.ToArray()) + ")";
}
protected virtual void debugFillDescription(List<String> description) {
description.Add("offset: " + this.pixels.ToString("F1"));
}
public class _FixedViewportOffset : ViewportOffset {
public _FixedViewportOffset(double _pixels) {
class _FixedViewportOffset : ViewportOffset {
internal _FixedViewportOffset(double _pixels) {
public new static _FixedViewportOffset zero() {
internal new static _FixedViewportOffset zero() {
public double _pixels;
double _pixels;
public override double pixels {
get { return this._pixels; }

public override void jumpTo(double pixels) {
}
public override IPromise<object> animateTo(double to, TimeSpan duration, Curve curve) {
return Promise<object>.Resolved(null);
}
}
public override bool allowImplicitScrolling {
get { return false; }
}
}
}

18
Assets/UIWidgets/scheduler/binding.cs


SchedulerPhase _schedulerPhase = SchedulerPhase.idle;
public bool framesEnabled {
get { return this._framesEnabled; }
set {
if (this._framesEnabled == value) {
return;
}
this._framesEnabled = value;
if (value) {
this.scheduleFrame();
}
}
}
bool _framesEnabled = true; // todo: set it to false when app switched to background
public void ensureVisualUpdate() {
switch (this.schedulerPhase) {
case SchedulerPhase.idle:

}
public void scheduleFrame() {
if (this._hasScheduledFrame) {
if (this._hasScheduledFrame || !this._framesEnabled) {
return;
}

62
Assets/UIWidgets/ui/geometry.cs


return value;
}
public static double abs(this double value) {
return Math.Abs(value);
}
public static int sign(this double value) {
return Math.Sign(value);
}
public static bool isFinite(this double it) {
return !double.IsInfinity(it);
}
public static double lerpDouble(double a, double b, double t) {
return a + (b - a) * t;
}
public static int round(this double value) {
return (int) Math.Round(value);
}
public static int floor(this double value) {
return (int) Math.Floor(value);
}
}
public abstract class OffsetBase : IEquatable<OffsetBase> {

return offset.dx >= 0.0 && offset.dx < this.width && offset.dy >= 0.0 && offset.dy < this.height;
}
public static Size lerp(Size a, Size b, double t) {
if (a == null && b == null) {
return null;
}
if (a == null) {
return b * t;
}
if (b == null) {
return a * (1.0 - t);
}
return new Size(MathUtils.lerpDouble(a.width, b.width, t), MathUtils.lerpDouble(a.height, b.height, t));
}
public bool Equals(Size other) {
return this._dx.Equals(other._dx) && this._dy.Equals(other._dy);
}

public bool contains(Rect rect) {
return this.contains(rect.topLeft) && this.contains(rect.bottomRight);
}
public static Rect lerp(Rect a, Rect b, double t) {
if (a == null && b == null) {
return null;
}
if (a == null) {
return Rect.fromLTRB(b.left * t, b.top * t, b.right * t, b.bottom * t);
}
if (b == null) {
double k = 1.0 - t;
return Rect.fromLTRB(a.left * k, a.top * k, a.right * k, a.bottom * k);
}
return Rect.fromLTRB(
MathUtils.lerpDouble(a.left, b.left, t),
MathUtils.lerpDouble(a.top, b.top, t),
MathUtils.lerpDouble(a.right, b.right, t),
MathUtils.lerpDouble(a.bottom, b.bottom, t)
);
}
public bool Equals(Rect other) {

27
Assets/UIWidgets/ui/painting/painting.cs


using UnityEngine;
namespace UIWidgets.ui {
public static class PaintingUtils {
internal static Color _scaleAlpha(this Color a, double factor) {
return a.withAlpha((a.alpha * factor).round().clamp(0, 255));
}
}
public class Color : IEquatable<Color> {
public Color(long value) {
this.value = value & 0xFFFFFFFF;

public Color withBlue(int b) {
return Color.fromARGB(this.alpha, this.red, this.green, b);
}
public static Color lerp(Color a, Color b, double t) {
if (a == null && b == null) {
return null;
}
if (a == null) {
return b._scaleAlpha(t);
}
if (b == null) {
return a._scaleAlpha(1.0 - t);
}
return Color.fromARGB(
((int) MathUtils.lerpDouble(a.alpha, b.alpha, t)).clamp(0, 255),
((int) MathUtils.lerpDouble(a.red, b.red, t)).clamp(0, 255),
((int) MathUtils.lerpDouble(a.green, b.green, t)).clamp(0, 255),
((int) MathUtils.lerpDouble(a.blue, b.blue, t)).clamp(0, 255)
);
}
public bool Equals(Color other) {

14
Assets/UIWidgets/ui/window.cs


VoidCallback _onMetricsChanged;
public VoidCallback onLocaleChanged {
get { return this._onLocaleChanged; }
set { this._onLocaleChanged = value; }
}
private VoidCallback _onLocaleChanged;
public VoidCallback onAccessibilityFeaturesChanged {
get { return this._onAccessibilityFeaturesChanged; }
set { this._onAccessibilityFeaturesChanged = value; }
}
private VoidCallback _onAccessibilityFeaturesChanged;
public FrameCallback onBeginFrame {
get { return this._onBeginFrame; }
set { this._onBeginFrame = value; }

144
Assets/UIWidgets/widgets/framework.cs


public abstract Widget build(BuildContext context);
}
public abstract class StatefulWidget : Widget {
protected StatefulWidget(string key) : base(key) {
}
public override Element createElement() {
return new StatefulElement(this);
}
public abstract State createState();
}
enum _StateLifecycle {
created,
initialized,
ready,
defunct,
}
public abstract class State : Diagnosticable {
public StatefulWidget widget {
get { return _widget; }
set { _widget = value; }
}
private StatefulWidget _widget;
_StateLifecycle _debugLifecycleState = _StateLifecycle.created;
public BuildContext context {
get { return _element; }
}
public StatefulElement element {
get { return _element; }
set { _element = value; }
}
private StatefulElement _element;
public bool mounted {
get { return _element != null; }
}
public virtual void initState() {
D.assert(_debugLifecycleState == _StateLifecycle.created);
}
public abstract void didChangeDependencies();
public abstract void didUpdateWidget(StatefulWidget oldWidget);
public abstract void reassemble();
public void setState(VoidCallback fn) {
fn();
_element.markNeedsBuild();
}
public abstract Widget build(BuildContext context);
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
}
}
public abstract class RenderObjectWidget : Widget {
protected RenderObjectWidget(string key) : base(key) {
}

}
}
public abstract class LeafRenderObjectWidget : RenderObjectWidget {
protected LeafRenderObjectWidget(string key) : base(key) {
}
public override Element createElement() {
return new LeafRenderObjectElement(this);
}
}
public abstract class SingleChildRenderObjectWidget : RenderObjectWidget {
protected SingleChildRenderObjectWidget(string key) : base(key) {
}
public Widget child;
public override Element createElement() {
return new SingleChildRenderObjectElement(this);
}
}
public abstract class Element : BuildContext {
protected Element(Widget widget) {
Assert.IsNotNull(widget);

public bool _active = false;
public virtual void _reassemble() {
markNeedsBuild();
ElementVisitor visit = null;
visit = child => { child._reassemble(); };
visitChildren(visit);
}
public RenderObject renderObject {
get {
RenderObject result = null;

Assert.IsNull(result);
if (element is RenderObjectElement) {
result = element.renderObject;
} else {
}
else {
element.visitChildren(visit);
}
};

return result;
}
}
public void visitAncestorElements(Func<Element, bool> visitor) {
}
public virtual void visitChildren(ElementVisitor visitor) {

this._firstBuild();
}
public void _firstBuild() {
public virtual void _firstBuild() {
this.rebuild();
}

}
}
public class StatefulElement : ComponentElement {
public StatefulElement(StatefulWidget widget) : base(widget) {
_state = widget.createState();
_state.element = this;
_state.widget = widget;
}
public State state {
get { return _state; }
}
private State _state;
public override Widget build() {
return state.build(this);
}
public override void _reassemble() {
state.reassemble();
base._reassemble();
}
public override void _firstBuild() {
base._firstBuild();
}
}
public abstract class RenderObjectElement : Element {
protected RenderObjectElement(RenderObjectWidget widget) : base(widget) {
}

public interface BuildContext {
Widget widget { get; }
void visitAncestorElements(Func<Element, bool> visitor);
}
public class BuildOwner {

public void finalizeTree() {
this._inactiveElements._unmountAll();
}
}
public class LeafRenderObjectElement : RenderObjectElement {
public LeafRenderObjectElement(LeafRenderObjectWidget widget) : base(widget) {
}
public override void forgetChild(Element child) {
}
}
public class SingleChildRenderObjectElement : RenderObjectElement {
public SingleChildRenderObjectElement(SingleChildRenderObjectWidget widget) : base(widget) {
}
public override void forgetChild(Element child) {
}
}

2
ProjectSettings/ProjectSettings.asset


useOnDemandResources: 0
accelerometerFrequency: 60
companyName: DefaultCompany
productName: test
productName: UIWidgets
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}

7
Assets/UIWidgets/gestures/drag.cs


namespace UIWidgets.gestures {
public interface Drag {
void update(DragUpdateDetails details);
void end(DragEndDetails details);
void cancel();
}
}

3
Assets/UIWidgets/gestures/drag.cs.meta


fileFormatVersion: 2
guid: 2f59e34cb2654a9c9b2ce3b7df07ab22
timeCreated: 1536665218

298
Assets/UIWidgets/scheduler/ticker.cs


using System;
using System.Diagnostics;
using System.Text;
using RSG;
using RSG.Promises;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.scheduler {
public delegate void TickerCallback(TimeSpan elapsed);
public interface TickerProvider {
Ticker createTicker(TickerCallback onTick);
}
public class Ticker {
public Ticker(SchedulerBinding binding, TickerCallback onTick, string debugLabel = null) {
D.assert(() => {
this._debugCreationStack = new StackTrace();
return true;
});
this._binding = binding;
this._onTick = onTick;
this.debugLabel = debugLabel;
}
readonly SchedulerBinding _binding;
TickerFutureImpl _future;
public bool muted {
get { return this._muted; }
set {
if (value == this._muted) {
return;
}
this._muted = value;
if (value) {
this.unscheduleTick();
} else if (this.shouldScheduleTick) {
this.scheduleTick();
}
}
}
bool _muted = false;
public bool isTicking {
get {
if (this._future == null) {
return false;
}
if (this.muted) {
return false;
}
if (this._binding.framesEnabled) {
return true;
}
if (this._binding.schedulerPhase != SchedulerPhase.idle) {
return true;
}
return false;
}
}
public bool isActive {
get { return this._future != null; }
}
TimeSpan? _startTime;
public TickerFuture start() {
D.assert(() => {
if (this.isActive) {
throw new UIWidgetsError(
"A ticker that is already active cannot be started again without first stopping it.\n" +
"The affected ticker was: " + this.toString(debugIncludeStack: true));
}
return true;
});
D.assert(this._startTime == null);
this._future = new TickerFutureImpl();
if (this.shouldScheduleTick) {
this.scheduleTick();
}
if (this._binding.schedulerPhase > SchedulerPhase.idle &&
this._binding.schedulerPhase < SchedulerPhase.postFrameCallbacks) {
this._startTime = this._binding.currentFrameTimeStamp;
}
return this._future;
}
public void stop(bool canceled = false) {
if (!this.isActive) {
return;
}
var localFuture = this._future;
this._future = null;
this._startTime = null;
D.assert(!this.isActive);
this.unscheduleTick();
if (canceled) {
localFuture._cancel(this);
} else {
localFuture._complete();
}
}
readonly TickerCallback _onTick;
int? _animationId;
protected bool scheduled {
get { return this._animationId != null; }
}
protected bool shouldScheduleTick {
get { return !this.muted && this.isActive && !this.scheduled; }
}
void _tick(TimeSpan timeStamp) {
D.assert(this.isTicking);
D.assert(this.scheduled);
this._animationId = null;
this._startTime = this._startTime ?? timeStamp;
this._onTick(timeStamp - this._startTime.Value);
if (this.shouldScheduleTick) {
this.scheduleTick(rescheduling: true);
}
}
protected void scheduleTick(bool rescheduling = false) {
D.assert(!this.scheduled);
D.assert(this.shouldScheduleTick);
this._animationId = this._binding.scheduleFrameCallback(this._tick, rescheduling: rescheduling);
}
protected void unscheduleTick() {
if (this.scheduled) {
this._binding.cancelFrameCallbackWithId(this._animationId.Value);
this._animationId = null;
}
D.assert(!this.shouldScheduleTick);
}
public void absorbTicker(Ticker originalTicker) {
D.assert(!this.isActive);
D.assert(this._future == null);
D.assert(this._startTime == null);
D.assert(this._animationId == null);
D.assert((originalTicker._future == null) == (originalTicker._startTime == null),
"Cannot absorb Ticker after it has been disposed.");
if (originalTicker._future != null) {
this._future = originalTicker._future;
this._startTime = originalTicker._startTime;
if (this.shouldScheduleTick) {
this.scheduleTick();
}
originalTicker._future = null;
originalTicker.unscheduleTick();
}
originalTicker.dispose();
}
public virtual void dispose() {
if (this._future != null) {
var localFuture = this._future;
this._future = null;
D.assert(!this.isActive);
this.unscheduleTick();
localFuture._cancel(this);
}
D.assert(() => {
this._startTime = default(TimeSpan);
return true;
});
}
public readonly String debugLabel;
StackTrace _debugCreationStack;
public override string ToString() {
return this.toString(debugIncludeStack: false);
}
public string toString(bool debugIncludeStack = false) {
var buffer = new StringBuilder();
buffer.Append(this.GetType() + "(");
D.assert(() => {
buffer.Append(this.debugLabel ?? "");
return true;
});
buffer.Append(')');
D.assert(() => {
if (debugIncludeStack) {
buffer.AppendLine();
buffer.AppendLine("The stack trace when the " + this.GetType() + " was actually created was:");
UIWidgetsError.defaultStackFilter(this._debugCreationStack.ToString().TrimEnd().Split('\n'))
.Each(line => buffer.AppendLine(line));
}
return true;
});
return buffer.ToString();
}
}
public interface TickerFuture : IPromise {
void whenCompleteOrCancel(VoidCallback callback);
IPromise orCancel { get; }
}
public class TickerFutureImpl : Promise, TickerFuture {
public static TickerFuture complete() {
var result = new TickerFutureImpl();
result._complete();
return result;
}
Promise _secondaryCompleter;
bool? _completed;
internal void _complete() {
D.assert(this._completed == null);
this._completed = true;
this.Resolve();
if (this._secondaryCompleter != null) {
this._secondaryCompleter.Resolve();
}
}
internal void _cancel(Ticker ticker) {
D.assert(this._completed == null);
this._completed = false;
if (this._secondaryCompleter != null) {
this._secondaryCompleter.Reject(new TickerCanceled(ticker));
}
}
public void whenCompleteOrCancel(VoidCallback callback) {
this.orCancel.Then(() => callback(), ex => callback());
}
public IPromise orCancel {
get {
if (this._secondaryCompleter == null) {
this._secondaryCompleter = new Promise();
if (this._completed != null) {
if (this._completed.Value) {
this._secondaryCompleter.Resolve();
} else {
this._secondaryCompleter.Reject(new TickerCanceled());
}
}
}
return this._secondaryCompleter;
}
}
}
public class TickerCanceled : Exception {
public TickerCanceled(Ticker ticker = null) {
this.ticker = ticker;
}
public readonly Ticker ticker;
public override string ToString() {
if (this.ticker != null) {
return "This ticker was canceled: " + this.ticker;
}
return "The ticker was canceled before the \"orCancel\" property was first used.";
}
}
}

3
Assets/UIWidgets/scheduler/ticker.cs.meta


fileFormatVersion: 2
guid: 3fb425debd2a441cadf8ad4a4fed3aa1
timeCreated: 1536717302

57
Assets/UIWidgets/widgets/basic.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.rendering;
using UIWidgets.ui;
using UnityEngine.Assertions;
namespace UIWidgets.widgets {
public class RawImage : LeafRenderObjectWidget {
public RawImage(string key, ui.Image image, double width, double height, double scale, Color color,
BlendMode colorBlendMode, BoxFit fit, Rect centerSlice, Alignment alignment = null,
ImageRepeat repeat = ImageRepeat.noRepeat) : base(key) {
this.image = image;
this.width = width;
this.height = height;
this.scale = scale;
this.color = color;
this.blendMode = colorBlendMode;
this.centerSlice = centerSlice;
this.fit = fit;
this.alignment = alignment == null ? Alignment.center : alignment;
this.repeat = repeat;
}
public override Element createElement() {
throw new NotImplementedException();
}
public override RenderObject createRenderObject(BuildContext context) {
return new RenderImage(
this.image,
this.width,
this.height,
this.color,
this.blendMode,
this.fit,
this.repeat,
this.centerSlice,
this.alignment
);
}
public ui.Image image;
public double width;
public double height;
public double scale;
public Color color;
public BlendMode blendMode;
public BoxFit fit;
public Alignment alignment;
public ImageRepeat repeat;
public Rect centerSlice;
}
}

3
Assets/UIWidgets/widgets/basic.cs.meta


fileFormatVersion: 2
guid: 69241aaa538e4e2baa651ffa39d6f355
timeCreated: 1536564821

52
Assets/UIWidgets/widgets/binding.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.rendering;
using UIWidgets.ui;
using UnityEngine.Assertions;
namespace UIWidgets.widgets {
abstract class WidgetsBinding : RendererBinding {
protected WidgetsBinding(Window window) : base(window) {
this.buildOwner.onBuildScheduled = this._handleBuildScheduled;
window.onLocaleChanged += this.handleLocaleChanged;
window.onAccessibilityFeaturesChanged += handleAccessibilityFeaturesChanged;
}
public BuildOwner buildOwner {
get { return this._buildOwner; }
}
readonly BuildOwner _buildOwner;
public Element renderViewElement {
get { return this._renderViewElement; }
}
Element _renderViewElement;
void _handleBuildScheduled() {
ensureVisualUpdate();
}
void handleLocaleChanged() {
// todo
// dispatchLocaleChanged(window.locale);
}
void handleAccessibilityFeaturesChanged() {
// for (WidgetsBindingObserver observer in _observers) {
// observer.didChangeAccessibilityFeatures();
// }
}
public void drawFrame() {
if (renderViewElement != null) {
buildOwner.buildScope(renderViewElement);
}
base.drawFrame();
buildOwner.finalizeTree();
}
}
}

3
Assets/UIWidgets/widgets/binding.cs.meta


fileFormatVersion: 2
guid: 39d3379616cb4c64afdedd889e3ac2a2
timeCreated: 1536213633

178
Assets/UIWidgets/widgets/image.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.painting;
using UIWidgets.foundation;
using UIWidgets.rendering;
using UIWidgets.ui;
using UnityEngine;
using UnityEngine.Assertions;
using Color = UIWidgets.ui.Color;
using Rect = UnityEngine.Rect;
namespace UIWidgets.widgets {
internal class Util {
public static ImageConfiguration createLocalImageConfiguration(BuildContext context, Size size) {
return new ImageConfiguration(
size: size
);
}
}
public class Image<T> : StatefulWidget {
public IImageProvider<System.Object> image;
public double width;
public double height;
public Color color;
public BoxFit fit;
public Alignment alignment;
public BlendMode colorBlendMode;
public ImageRepeat repeat;
public ui.Rect centerSlice;
public bool gaplessPlayback;
public Image(
string key,
ImageProvider<System.Object> image,
double width,
double height,
Color color,
BlendMode colorBlendMode,
BoxFit fit,
ui.Rect centerSlice,
Alignment alignment,
ImageRepeat repeat = ImageRepeat.noRepeat,
bool gaplessPlayback = false
) : base(key) {
this.image = image;
this.width = width;
this.height = height;
this.color = color;
this.colorBlendMode = colorBlendMode;
this.fit = fit;
this.alignment = alignment == null ? Alignment.center : alignment;
this.repeat = repeat;
this.centerSlice = centerSlice;
this.gaplessPlayback = gaplessPlayback;
}
// Network Image
public Image(
string src,
string key,
double width,
double height,
Color color,
BlendMode colorBlendMode,
BoxFit fit,
Alignment alignment,
ui.Rect centerSlice,
Dictionary<String, String> headers,
ImageRepeat repeat = ImageRepeat.noRepeat,
bool gaplessPlayback = false,
double scale = 1.0
) : base(key) {
this.image = new NetworkImage(src, headers, scale);
this.width = width;
this.height = height;
this.color = color;
this.colorBlendMode = colorBlendMode;
this.fit = fit;
this.alignment = alignment;
this.centerSlice = centerSlice;
this.repeat = repeat;
this.gaplessPlayback = gaplessPlayback;
}
public override State createState() {
return new _ImageState<T>();
}
}
public class _ImageState<T> : State {
ImageStream _imageStream;
ImageInfo _imageInfo;
bool _isListeningToStream = false;
public override void didChangeDependencies() {
_resolveImage();
// if (TickerMode.of(context))
// _listenToStream();
// else
// _stopListeningToStream();
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
if (((Image<T>) widget).image != ((Image<T>) oldWidget).image)
_resolveImage();
}
public override void reassemble() {
_resolveImage(); // in case the image cache was flushed
}
void _resolveImage() {
var imageWidget = (Image<T>) widget;
ImageStream newStream =
imageWidget.image.resolve(Util.createLocalImageConfiguration(
context,
size: new Size(imageWidget.width, imageWidget.height)
));
_updateSourceStream(newStream);
}
void _handleImageChanged(ImageInfo imageInfo, bool synchronousCall) {
setState(() => { _imageInfo = imageInfo; });
}
void _updateSourceStream(ImageStream newStream) {
if ((_imageStream == null ? null : _imageStream.key) == (newStream == null ? null : newStream.key))
return;
if (_isListeningToStream && _imageStream != null)
_imageStream.removeListener(_handleImageChanged);
if (!((Image<T>) widget).gaplessPlayback) {
setState(() => { _imageInfo = null; });
_imageStream = newStream;
if (_isListeningToStream && _imageStream != null)
_imageStream.addListener(_handleImageChanged);
}
}
void _listenToStream() {
if (_isListeningToStream)
return;
_imageStream.addListener(_handleImageChanged);
_isListeningToStream = true;
}
void _stopListeningToStream() {
if (!_isListeningToStream)
return;
_imageStream.removeListener(_handleImageChanged);
_isListeningToStream = false;
}
public override Widget build(BuildContext context) {
var imageWidget = (Image<T>) widget;
RawImage image = new RawImage(
"", // todo
_imageInfo == null ? null : _imageInfo.image,
imageWidget.width,
imageWidget.height,
_imageInfo == null ? 1.0 : _imageInfo.scale,
imageWidget.color,
imageWidget.colorBlendMode,
imageWidget.fit,
imageWidget.centerSlice,
imageWidget.alignment,
imageWidget.repeat
);
return image;
}
}
}

3
Assets/UIWidgets/widgets/image.cs.meta


fileFormatVersion: 2
guid: d1d313d74f6044198caad151f52721b8
timeCreated: 1536219326

70
Assets/UIWidgets/widgets/notification_listener.cs


using System.Collections.Generic;
using UIWidgets.foundation;
namespace UIWidgets.widgets {
public delegate bool NotificationListenerCallback<T>(T notification) where T : Notification;
public abstract class Notification {
protected virtual bool visitAncestor(Element element) {
if (element is StatelessElement) {
StatelessWidget widget = (StatelessWidget) element.widget;
var listener = widget as _NotificationListener;
if (listener != null) {
if (listener._dispatch(this, element)) {
return false;
}
}
}
return true;
}
public void dispatch(BuildContext target) {
D.assert(target != null);
target.visitAncestorElements(this.visitAncestor);
}
public override string ToString() {
var description = new List<string>();
this.debugFillDescription(description);
return string.Format("{0}({1})", this.GetType(), string.Join(", ", description.ToArray()));
}
protected virtual void debugFillDescription(List<string> description) {
}
}
interface _NotificationListener {
bool _dispatch(Notification notification, Element element);
}
public class NotificationListener<T> : StatelessWidget, _NotificationListener where T : Notification {
public NotificationListener(
string key = null,
Widget child = null,
NotificationListenerCallback<T> onNotification = null) : base(key) {
this.child = child;
this.onNotification = onNotification;
}
public readonly Widget child;
public readonly NotificationListenerCallback<T> onNotification;
bool _NotificationListener._dispatch(Notification notification, Element element) {
if (this.onNotification != null && notification is T) {
bool result = this.onNotification((T) notification);
return result;
}
return false;
}
public override Widget build(BuildContext context) {
return this.child;
}
}
public class LayoutChangedNotification : Notification {
}
}

3
Assets/UIWidgets/widgets/notification_listener.cs.meta


fileFormatVersion: 2
guid: 647bb259966f4e4e8196f7c9c4ef56dc
timeCreated: 1536582324

361
Assets/UIWidgets/widgets/scroll_activity.cs


using System;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.physics;
using UIWidgets.scheduler;
using UIWidgets.ui;
namespace UIWidgets.widgets {
public interface ScrollActivityDelegate {
AxisDirection axisDirection { get; }
double setPixels(double pixels);
void applyUserOffset(double delta);
void goIdle();
void goBallistic(double velocity);
}
public abstract class ScrollActivity {
public ScrollActivity(ScrollActivityDelegate @delegate) {
this._delegate = @delegate;
}
public ScrollActivityDelegate @delegate {
get { return this._delegate; }
}
ScrollActivityDelegate _delegate;
public void updateDelegate(ScrollActivityDelegate value) {
D.assert(this._delegate != value);
this._delegate = value;
}
public virtual void resetActivity() {
}
public virtual void dispatchScrollStartNotification(ScrollMetrics metrics, BuildContext context) {
new ScrollStartNotification(metrics: metrics, context: context).dispatch(context);
}
public virtual void dispatchScrollUpdateNotification(ScrollMetrics metrics, BuildContext context,
double scrollDelta) {
new ScrollUpdateNotification(metrics: metrics, context: context, scrollDelta: scrollDelta)
.dispatch(context);
}
public virtual void dispatchOverscrollNotification(ScrollMetrics metrics, BuildContext context,
double overscroll) {
new OverscrollNotification(metrics: metrics, context: context, overscroll: overscroll).dispatch(context);
}
public virtual void dispatchScrollEndNotification(ScrollMetrics metrics, BuildContext context) {
new ScrollEndNotification(metrics: metrics, context: context).dispatch(context);
}
public virtual void applyNewDimensions() {
}
public abstract bool shouldIgnorePointer { get; }
public abstract bool isScrolling { get; }
public abstract double velocity { get; }
public virtual void dispose() {
this._delegate = null;
}
public override string ToString() {
return Diagnostics.describeIdentity(this);
}
}
public class IdleScrollActivity : ScrollActivity {
public IdleScrollActivity(ScrollActivityDelegate @delegate) : base(@delegate) {
}
public override void applyNewDimensions() {
this.@delegate.goBallistic(0.0);
}
public override bool shouldIgnorePointer {
get { return false; }
}
public override bool isScrolling {
get { return false; }
}
public override double velocity {
get { return 0.0; }
}
}
public interface ScrollHoldController {
void cancel();
}
public class HoldScrollActivity : ScrollActivity, ScrollHoldController {
public HoldScrollActivity(
ScrollActivityDelegate @delegate = null,
VoidCallback onHoldCanceled = null
) : base(@delegate) {
this.onHoldCanceled = onHoldCanceled;
}
public readonly VoidCallback onHoldCanceled;
public override bool shouldIgnorePointer {
get { return false; }
}
public override bool isScrolling {
get { return false; }
}
public override double velocity {
get { return 0.0; }
}
public void cancel() {
this.@delegate.goBallistic(0.0);
}
public override void dispose() {
if (this.onHoldCanceled != null)
this.onHoldCanceled();
base.dispose();
}
}
public class ScrollDragController : Drag {
public ScrollDragController(
ScrollActivityDelegate @delegate = null,
DragStartDetails details = null,
VoidCallback onDragCanceled = null,
double? carriedVelocity = null,
double? motionStartDistanceThreshold = null
) {
D.assert(@delegate != null);
D.assert(details != null);
D.assert(
motionStartDistanceThreshold == null || motionStartDistanceThreshold > 0.0,
"motionStartDistanceThreshold must be a positive number or null"
);
this._delegate = @delegate;
this._lastDetails = details;
this._retainMomentum = carriedVelocity != null && carriedVelocity != 0.0;
this._lastNonStationaryTimestamp = details.sourceTimeStamp;
this._offsetSinceLastStop = motionStartDistanceThreshold == null ? (double?) null : 0.0;
this.onDragCanceled = onDragCanceled;
this.carriedVelocity = carriedVelocity;
this.motionStartDistanceThreshold = motionStartDistanceThreshold;
}
public ScrollActivityDelegate @delegate {
get { return this._delegate; }
}
ScrollActivityDelegate _delegate;
public readonly VoidCallback onDragCanceled;
public readonly double? carriedVelocity;
public readonly double? motionStartDistanceThreshold;
DateTime _lastNonStationaryTimestamp;
bool _retainMomentum;
double? _offsetSinceLastStop;
public static readonly TimeSpan momentumRetainStationaryDurationThreshold = new TimeSpan(0, 0, 0, 0, 20);
public static readonly TimeSpan motionStoppedDurationThreshold = new TimeSpan(0, 0, 0, 0, 50);
const double _bigThresholdBreakDistance = 24.0;
bool _reversed {
get { return AxisUtils.axisDirectionIsReversed(this.@delegate.axisDirection); }
}
public void updateDelegate(ScrollActivityDelegate value) {
D.assert(this._delegate != value);
this._delegate = value;
}
void _maybeLoseMomentum(double offset, DateTime? timestamp) {
if (this._retainMomentum &&
offset == 0.0 &&
(timestamp == null ||
timestamp - this._lastNonStationaryTimestamp > momentumRetainStationaryDurationThreshold)) {
this._retainMomentum = false;
}
}
double _adjustForScrollStartThreshold(double offset, DateTime? timestamp) {
if (timestamp == null) {
return offset;
}
if (offset == 0.0) {
if (this.motionStartDistanceThreshold != null &&
this._offsetSinceLastStop == null &&
timestamp - this._lastNonStationaryTimestamp > motionStoppedDurationThreshold) {
this._offsetSinceLastStop = 0.0;
}
return 0.0;
} else {
if (this._offsetSinceLastStop == null) {
return offset;
} else {
this._offsetSinceLastStop += offset;
if (this._offsetSinceLastStop.Value.abs() > this.motionStartDistanceThreshold) {
this._offsetSinceLastStop = null;
if (offset.abs() > _bigThresholdBreakDistance) {
return offset;
} else {
return Math.Min(
this.motionStartDistanceThreshold.Value / 3.0,
offset.abs()
) * offset.sign();
}
} else {
return 0.0;
}
}
}
}
public void update(DragUpdateDetails details) {
D.assert(details.primaryDelta != null);
this._lastDetails = details;
double offset = details.primaryDelta.Value;
if (offset != 0.0) {
this._lastNonStationaryTimestamp = details.sourceTimeStamp;
}
this._maybeLoseMomentum(offset, details.sourceTimeStamp);
offset = this._adjustForScrollStartThreshold(offset, details.sourceTimeStamp);
if (offset == 0.0) {
return;
}
if (this._reversed) {
offset = -offset;
}
this.@delegate.applyUserOffset(offset);
}
public void end(DragEndDetails details) {
D.assert(details.primaryVelocity != null);
double velocity = -details.primaryVelocity.Value;
if (this._reversed) {
velocity = -velocity;
}
this._lastDetails = details;
if (this._retainMomentum && velocity.sign() == this.carriedVelocity.Value.sign()) {
velocity += this.carriedVelocity.Value;
}
this.@delegate.goBallistic(velocity);
}
public void cancel() {
this.@delegate.goBallistic(0.0);
}
public virtual void dispose() {
this._lastDetails = null;
if (this.onDragCanceled != null) {
this.onDragCanceled();
}
}
public object lastDetails {
get { return this._lastDetails; }
}
object _lastDetails;
public override string ToString() {
return Diagnostics.describeIdentity(this);
}
}
public class DragScrollActivity : ScrollActivity {
public DragScrollActivity(
ScrollActivityDelegate @delegate,
ScrollDragController controller
) : base(@delegate) {
this._controller = controller;
}
ScrollDragController _controller;
public override void dispatchScrollStartNotification(ScrollMetrics metrics, BuildContext context) {
object lastDetails = this._controller.lastDetails;
D.assert(lastDetails is DragStartDetails);
new ScrollStartNotification(metrics: metrics, context: context, dragDetails: (DragStartDetails) lastDetails)
.dispatch(context);
}
public override void dispatchScrollUpdateNotification(ScrollMetrics metrics, BuildContext context,
double scrollDelta) {
object lastDetails = this._controller.lastDetails;
D.assert(lastDetails is DragUpdateDetails);
new ScrollUpdateNotification(metrics: metrics, context: context, scrollDelta: scrollDelta,
dragDetails: (DragUpdateDetails) lastDetails).dispatch(context);
}
public override void dispatchOverscrollNotification(ScrollMetrics metrics, BuildContext context,
double overscroll) {
object lastDetails = this._controller.lastDetails;
D.assert(lastDetails is DragUpdateDetails);
new OverscrollNotification(metrics: metrics, context: context, overscroll: overscroll,
dragDetails: (DragUpdateDetails) lastDetails).dispatch(context);
}
public override void dispatchScrollEndNotification(ScrollMetrics metrics, BuildContext context) {
object lastDetails = this._controller.lastDetails;
new ScrollEndNotification(
metrics: metrics,
context: context,
dragDetails: lastDetails is DragEndDetails ? (DragEndDetails) lastDetails : null
).dispatch(context);
}
public override bool shouldIgnorePointer {
get { return true; }
}
public override bool isScrolling {
get { return true; }
}
public override double velocity {
get { return 0.0; }
}
public override void dispose() {
this._controller = null;
base.dispose();
}
public override string ToString() {
return string.Format("{0}({1})", Diagnostics.describeIdentity(this), this._controller);
}
}
}

3
Assets/UIWidgets/widgets/scroll_activity.cs.meta


fileFormatVersion: 2
guid: 6f4554d0588f42cfbef25f404ead887a
timeCreated: 1536667809

18
Assets/UIWidgets/widgets/scroll_context.cs


using UIWidgets.painting;
using UIWidgets.scheduler;
namespace UIWidgets.widgets {
public interface ScrollContext {
BuildContext notificationContext { get; }
BuildContext storageContext { get; }
TickerProvider vsync { get; }
AxisDirection axisDirection { get; }
void setIgnorePointer(bool value);
void setCanDrag(bool value);
}
}

3
Assets/UIWidgets/widgets/scroll_context.cs.meta


fileFormatVersion: 2
guid: ffa0043fe4ac45479630806085f547a9
timeCreated: 1536670059

75
Assets/UIWidgets/widgets/scroll_matrics.cs


using System;
using UIWidgets.painting;
namespace UIWidgets.widgets {
public interface ScrollMetrics {
double minScrollExtent { get; }
double maxScrollExtent { get; }
double pixels { get; }
double viewportDimension { get; }
AxisDirection axisDirection { get; }
}
public static class ScrollMetricsUtils {
public static Axis axis(this ScrollMetrics it) {
return AxisUtils.axisDirectionToAxis(it.axisDirection);
}
public static bool outOfRange(this ScrollMetrics it) {
return it.pixels < it.minScrollExtent || it.pixels > it.maxScrollExtent;
}
public static bool atEdge(this ScrollMetrics it) {
return it.pixels == it.minScrollExtent || it.pixels == it.maxScrollExtent;
}
public static double extentBefore(this ScrollMetrics it) {
return Math.Max(it.pixels - it.minScrollExtent, 0.0);
}
public static double extentInside(this ScrollMetrics it) {
return Math.Min(it.pixels, it.maxScrollExtent) -
Math.Max(it.pixels, it.minScrollExtent) +
Math.Min(it.viewportDimension, it.maxScrollExtent - it.minScrollExtent);
}
public static double extentAfter(this ScrollMetrics it) {
return Math.Max(it.maxScrollExtent - it.pixels, 0.0);
}
}
public class FixedScrollMetrics : ScrollMetrics {
public FixedScrollMetrics(
double minScrollExtent = 0.0,
double maxScrollExtent = 0.0,
double pixels = 0.0,
double viewportDimension = 0.0,
AxisDirection axisDirection = AxisDirection.down
) {
this.minScrollExtent = minScrollExtent;
this.maxScrollExtent = maxScrollExtent;
this.pixels = pixels;
this.viewportDimension = viewportDimension;
this.axisDirection = axisDirection;
}
public double minScrollExtent { get; private set; }
public double maxScrollExtent { get; private set; }
public double pixels { get; private set; }
public double viewportDimension { get; private set; }
public AxisDirection axisDirection { get; private set; }
public override string ToString() {
return string.Format("{0}({1:F1})..[{2:F1}]..{3:F1})",
this.GetType(), this.extentBefore(), this.extentInside(), this.extentAfter());
}
}
}

3
Assets/UIWidgets/widgets/scroll_matrics.cs.meta


fileFormatVersion: 2
guid: 25e09958cead4597adacd8c3dbf7b12f
timeCreated: 1536561228

139
Assets/UIWidgets/widgets/scroll_notification.cs


using System.Collections.Generic;
using UIWidgets.gestures;
using UIWidgets.rendering;
namespace UIWidgets.widgets {
public abstract class ScrollNotification : ViewportNotificationMixinLayoutChangedNotification {
protected ScrollNotification(
ScrollMetrics metrics = null,
BuildContext context = null
) {
this.metrics = metrics;
this.context = context;
}
public readonly ScrollMetrics metrics;
public readonly BuildContext context;
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add(this.metrics.ToString());
}
public static bool defaultScrollNotificationPredicate(ScrollNotification notification) {
return notification.depth == 0;
}
}
public class ScrollStartNotification : ScrollNotification {
public ScrollStartNotification(
ScrollMetrics metrics = null,
BuildContext context = null,
DragStartDetails dragDetails = null
) : base(metrics: metrics, context: context) {
this.dragDetails = dragDetails;
}
public readonly DragStartDetails dragDetails;
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
if (this.dragDetails != null)
description.Add(this.dragDetails.ToString());
}
}
public class ScrollUpdateNotification : ScrollNotification {
public ScrollUpdateNotification(
ScrollMetrics metrics = null,
BuildContext context = null,
DragUpdateDetails dragDetails = null,
double scrollDelta = 0
) : base(metrics: metrics, context: context) {
this.dragDetails = dragDetails;
this.scrollDelta = scrollDelta;
}
public readonly DragUpdateDetails dragDetails;
public readonly double scrollDelta;
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add(string.Format("scrollDelta: {0}", this.scrollDelta));
if (this.dragDetails != null) {
description.Add(this.dragDetails.ToString());
}
}
}
public class OverscrollNotification : ScrollNotification {
public OverscrollNotification(
ScrollMetrics metrics = null,
BuildContext context = null,
DragUpdateDetails dragDetails = null,
double overscroll = 0,
double velocity = 0
) : base(metrics: metrics, context: context) {
this.dragDetails = dragDetails;
this.overscroll = overscroll;
this.velocity = velocity;
}
public readonly DragUpdateDetails dragDetails;
public readonly double overscroll;
public readonly double velocity;
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add(string.Format("overscroll: {0:F1}", this.overscroll));
description.Add(string.Format("velocity: {0:F1}", this.velocity));
if (this.dragDetails != null) {
description.Add(this.dragDetails.ToString());
}
}
}
public class ScrollEndNotification : ScrollNotification {
public ScrollEndNotification(
ScrollMetrics metrics = null,
BuildContext context = null,
DragEndDetails dragDetails = null,
double overscroll = 0,
double velocity = 0
) : base(metrics: metrics, context: context) {
this.dragDetails = dragDetails;
}
public readonly DragEndDetails dragDetails;
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
if (this.dragDetails != null) {
description.Add(this.dragDetails.ToString());
}
}
}
public class UserScrollNotification : ScrollNotification {
public UserScrollNotification(
ScrollMetrics metrics = null,
BuildContext context = null,
ScrollDirection direction = ScrollDirection.idle
) : base(metrics: metrics, context: context) {
this.direction = direction;
}
public readonly ScrollDirection direction;
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add(string.Format("direction: {0}", this.direction));
}
}
public delegate bool ScrollNotificationPredicate(ScrollNotification notification);
}

3
Assets/UIWidgets/widgets/scroll_notification.cs.meta


fileFormatVersion: 2
guid: 76d5830e8d5948e8a312ac1699cbfcb1
timeCreated: 1536583483

53
Assets/UIWidgets/widgets/scroll_notification.mixin.gen.cs


using System.Collections.Generic;
using UIWidgets.rendering;
namespace UIWidgets.widgets {
public abstract class ViewportNotificationMixinNotification : Notification {
public int depth {
get { return _depth; }
}
int _depth = 0;
protected override bool visitAncestor(Element element) {
if (element is RenderObjectElement && element.renderObject is RenderAbstractViewport) {
this._depth += 1;
}
return base.visitAncestor(element);
}
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add(string.Format("depth: {0} ({1})",
this._depth, this._depth == 0 ? "local" : "remote"));
}
}
public abstract class ViewportNotificationMixinLayoutChangedNotification : LayoutChangedNotification {
public int depth {
get { return _depth; }
}
int _depth = 0;
protected override bool visitAncestor(Element element) {
if (element is RenderObjectElement && element.renderObject is RenderAbstractViewport) {
this._depth += 1;
}
return base.visitAncestor(element);
}
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add(string.Format("depth: {0} ({1})",
this._depth, this._depth == 0 ? "local" : "remote"));
}
}
}

11
Assets/UIWidgets/widgets/scroll_notification.mixin.gen.cs.meta


fileFormatVersion: 2
guid: 76fcf9dfb96bf49579e29af4f80c2d52
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

32
Assets/UIWidgets/widgets/scroll_notification.mixin.njk


using System.Collections.Generic;
using UIWidgets.rendering;
namespace UIWidgets.widgets {
{% macro ViewportNotificationMixin(with) %}
public abstract class ViewportNotificationMixin{{with}} : {{with}} {
public int depth {
get { return _depth; }
}
int _depth = 0;
protected override bool visitAncestor(Element element) {
if (element is RenderObjectElement && element.renderObject is RenderAbstractViewport) {
this._depth += 1;
}
return base.visitAncestor(element);
}
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add(string.Format("depth: {0} ({1})",
this._depth, this._depth == 0 ? "local" : "remote"));
}
}
{% endmacro %}
{{ ViewportNotificationMixin('Notification') }}
{{ ViewportNotificationMixin('LayoutChangedNotification') }}
}

3
Assets/UIWidgets/widgets/scroll_notification.mixin.njk.meta


fileFormatVersion: 2
guid: 50050e438a664e30957959a7a1da310c
timeCreated: 1536583983

352
Assets/UIWidgets/widgets/scroll_physics.cs


using System;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.physics;
using UIWidgets.ui;
namespace UIWidgets.widgets {
public class ScrollPhysics {
public ScrollPhysics(ScrollPhysics parent) {
this.parent = parent;
}
public readonly ScrollPhysics parent;
protected ScrollPhysics buildParent(ScrollPhysics ancestor) {
if (this.parent == null) {
return ancestor;
}
return this.parent.applyTo(ancestor) ?? ancestor;
}
public virtual ScrollPhysics applyTo(ScrollPhysics ancestor) {
return new ScrollPhysics(parent: this.buildParent(ancestor));
}
public virtual double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
if (this.parent == null) {
return offset;
}
return this.parent.applyPhysicsToUserOffset(position, offset);
}
public virtual bool shouldAcceptUserOffset(ScrollMetrics position) {
if (this.parent == null) {
return position.pixels != 0.0 || position.minScrollExtent != position.maxScrollExtent;
}
return this.parent.shouldAcceptUserOffset(position);
}
public virtual double applyBoundaryConditions(ScrollMetrics position, double value) {
if (this.parent == null) {
return 0.0;
}
return this.parent.applyBoundaryConditions(position, value);
}
public virtual Simulation createBallisticSimulation(ScrollMetrics position, double velocity) {
if (parent == null) {
return null;
}
return this.parent.createBallisticSimulation(position, velocity);
}
static readonly SpringDescription _kDefaultSpring = SpringDescription.withDampingRatio(
mass: 0.5,
stiffness: 100.0,
ratio: 1.1
);
public virtual SpringDescription spring {
get {
if (this.parent == null) {
return ScrollPhysics._kDefaultSpring;
}
return this.parent.spring ?? _kDefaultSpring;
}
}
// todo: Handle the case of the device pixel ratio changing. use 1 as devicePixelRatio for now.
static readonly Tolerance _kDefaultTolerance = new Tolerance(
velocity: 1.0 / (0.050 * 1),
distance: 1.0 / 1
);
public virtual Tolerance tolerance {
get {
if (this.parent == null) {
return _kDefaultTolerance;
}
return this.parent.tolerance ?? _kDefaultTolerance;
}
}
public virtual double minFlingDistance {
get {
if (this.parent == null) {
return Constants.kTouchSlop;
}
return this.parent.minFlingDistance;
}
}
public virtual double carriedMomentum(double existingVelocity) {
if (this.parent == null) {
return 0.0;
}
return this.parent.carriedMomentum(existingVelocity);
}
public virtual double minFlingVelocity {
get {
if (this.parent == null) {
return Constants.kMinFlingVelocity;
}
return this.parent.minFlingVelocity;
}
}
public virtual double maxFlingVelocity {
get {
if (this.parent == null) {
return Constants.kMaxFlingVelocity;
}
return this.parent.maxFlingVelocity;
}
}
public virtual double dragStartDistanceMotionThreshold {
get {
if (this.parent == null) {
return 0.0;
}
return this.parent.dragStartDistanceMotionThreshold;
}
}
public virtual bool allowImplicitScrolling {
get { return true; }
}
public override string ToString() {
if (this.parent == null) {
return string.Format("{0}", this.GetType());
}
return string.Format("{0} -> {1}", this.GetType(), this.parent);
}
}
public class BouncingScrollPhysics : ScrollPhysics {
public BouncingScrollPhysics(ScrollPhysics parent = null) : base(parent: parent) {
}
public override ScrollPhysics applyTo(ScrollPhysics ancestor) {
return new BouncingScrollPhysics(parent: this.buildParent(ancestor));
}
public double frictionFactor(double overscrollFraction) {
return 0.52 * Math.Pow(1 - overscrollFraction, 2);
}
public override double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
D.assert(position.minScrollExtent <= position.maxScrollExtent);
if (!position.outOfRange()) {
return offset;
}
double overscrollPastStart = Math.Max(position.minScrollExtent - position.pixels, 0.0);
double overscrollPastEnd = Math.Max(position.pixels - position.maxScrollExtent, 0.0);
double overscrollPast = Math.Max(overscrollPastStart, overscrollPastEnd);
bool easing = (overscrollPastStart > 0.0 && offset < 0.0) || (overscrollPastEnd > 0.0 && offset > 0.0);
double friction = easing
? this.frictionFactor((overscrollPast - offset.abs()) / position.viewportDimension)
: this.frictionFactor(overscrollPast / position.viewportDimension);
double direction = offset.sign();
return direction * _applyFriction(overscrollPast, offset.abs(), friction);
}
static double _applyFriction(double extentOutside, double absDelta, double gamma) {
D.assert(absDelta > 0);
double total = 0.0;
if (extentOutside > 0) {
double deltaToLimit = extentOutside / gamma;
if (absDelta < deltaToLimit) {
return absDelta * gamma;
}
total += extentOutside;
absDelta -= deltaToLimit;
}
return total + absDelta;
}
public override double applyBoundaryConditions(ScrollMetrics position, double value) {
return 0.0;
}
public override Simulation createBallisticSimulation(ScrollMetrics position, double velocity) {
Tolerance tolerance = this.tolerance;
if (velocity.abs() >= tolerance.velocity || position.outOfRange()) {
return new BouncingScrollSimulation(
spring: spring,
position: position.pixels,
velocity: velocity * 0.91,
leadingExtent: position.minScrollExtent,
trailingExtent: position.maxScrollExtent,
tolerance: tolerance
);
}
return null;
}
public override double minFlingVelocity {
get { return Constants.kMinFlingVelocity * 2.0; }
}
public override double carriedMomentum(double existingVelocity) {
return existingVelocity.sign() * Math.Min(0.000816 * Math.Pow(existingVelocity.abs(), 1.967), 40000.0);
}
public override double dragStartDistanceMotionThreshold {
get { return 3.5; }
}
}
public class ClampingScrollPhysics : ScrollPhysics {
public ClampingScrollPhysics(ScrollPhysics parent = null) : base(parent: parent) {
}
public override ScrollPhysics applyTo(ScrollPhysics ancestor) {
return new ClampingScrollPhysics(parent: this.buildParent(ancestor));
}
public override double applyBoundaryConditions(ScrollMetrics position, double value) {
D.assert(() => {
if (value == position.pixels) {
throw new UIWidgetsError(
string.Format(
"{0}.applyBoundaryConditions() was called redundantly.\n" +
"The proposed new position, {1}, is exactly equal to the current position of the " +
"given {2}, {3}.\n" +
"The applyBoundaryConditions method should only be called when the value is " +
"going to actually change the pixels, otherwise it is redundant.\n" +
"The physics object in question was:\n" +
" {4}\n" +
"The position object in question was:\n" +
" {5}\n",
this.GetType(), value, position.GetType(), position.pixels, this, position));
}
return true;
});
if (value < position.pixels && position.pixels <= position.minScrollExtent) {
return value - position.pixels;
}
if (position.maxScrollExtent <= position.pixels && position.pixels < value) {
return value - position.pixels;
}
if (value < position.minScrollExtent && position.minScrollExtent < position.pixels) {
return value - position.minScrollExtent;
}
if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) {
return value - position.maxScrollExtent;
}
return 0.0;
}
public override Simulation createBallisticSimulation(ScrollMetrics position, double velocity) {
Tolerance tolerance = this.tolerance;
if (position.outOfRange()) {
double? end = null;
if (position.pixels > position.maxScrollExtent) {
end = position.maxScrollExtent;
}
if (position.pixels < position.minScrollExtent) {
end = position.minScrollExtent;
}
D.assert(end != null);
return new ScrollSpringSimulation(
this.spring,
position.pixels,
position.maxScrollExtent,
Math.Min(0.0, velocity),
tolerance: tolerance
);
}
if (velocity.abs() < tolerance.velocity) {
return null;
}
if (velocity > 0.0 && position.pixels >= position.maxScrollExtent) {
return null;
}
if (velocity < 0.0 && position.pixels <= position.minScrollExtent) {
return null;
}
return new ClampingScrollSimulation(
position: position.pixels,
velocity: velocity,
tolerance: tolerance
);
}
}
public class AlwaysScrollableScrollPhysics : ScrollPhysics {
public AlwaysScrollableScrollPhysics(ScrollPhysics parent = null) : base(parent: parent) {
}
public override ScrollPhysics applyTo(ScrollPhysics ancestor) {
return new AlwaysScrollableScrollPhysics(parent: this.buildParent(ancestor));
}
public override bool shouldAcceptUserOffset(ScrollMetrics position) {
return true;
}
}
public class NeverScrollableScrollPhysics : ScrollPhysics {
public NeverScrollableScrollPhysics(ScrollPhysics parent = null) : base(parent: parent) {
}
public override ScrollPhysics applyTo(ScrollPhysics ancestor) {
return new NeverScrollableScrollPhysics(parent: this.buildParent(ancestor));
}
public override bool shouldAcceptUserOffset(ScrollMetrics position) {
return false;
}
public override bool allowImplicitScrolling {
get { return false; }
}
}
}

3
Assets/UIWidgets/widgets/scroll_physics.cs.meta


fileFormatVersion: 2
guid: f58c175eda22408f95d902db1c4eec03
timeCreated: 1536563659

7
Assets/UIWidgets/widgets/scroll_position.cs


using UIWidgets.rendering;
namespace UIWidgets.widgets {
// public abstract class ScrollPosition : ViewportOffset, ScrollMetrics {
//
// }
}

3
Assets/UIWidgets/widgets/scroll_position.cs.meta


fileFormatVersion: 2
guid: d1ce64af14b4434b8850b299aae20240
timeCreated: 1536563588

169
Assets/UIWidgets/widgets/scroll_simulation.cs


using System;
using UIWidgets.foundation;
using UIWidgets.physics;
using UIWidgets.ui;
namespace UIWidgets.widgets {
public class BouncingScrollSimulation : Simulation {
public BouncingScrollSimulation(
double position,
double velocity,
double leadingExtent,
double trailingExtent,
SpringDescription spring,
Tolerance tolerance = null
) : base(tolerance: tolerance) {
D.assert(leadingExtent <= trailingExtent);
D.assert(spring != null);
this.leadingExtent = leadingExtent;
this.trailingExtent = trailingExtent;
this.spring = spring;
if (position < leadingExtent) {
this._springSimulation = this._underscrollSimulation(position, velocity);
this._springTime = double.NegativeInfinity;
} else if (position > trailingExtent) {
this._springSimulation = this._overscrollSimulation(position, velocity);
this._springTime = double.NegativeInfinity;
} else {
this._frictionSimulation = new FrictionSimulation(0.135, position, velocity);
double finalX = this._frictionSimulation.finalX;
if (velocity > 0.0 && finalX > trailingExtent) {
this._springTime = this._frictionSimulation.timeAtX(trailingExtent);
this._springSimulation = this._overscrollSimulation(
trailingExtent,
Math.Min(this._frictionSimulation.dx(this._springTime), maxSpringTransferVelocity)
);
D.assert(this._springTime.isFinite());
} else if (velocity < 0.0 && finalX < leadingExtent) {
this._springTime = this._frictionSimulation.timeAtX(leadingExtent);
this._springSimulation = this._underscrollSimulation(
leadingExtent,
Math.Min(this._frictionSimulation.dx(this._springTime), maxSpringTransferVelocity)
);
D.assert(this._springTime.isFinite());
} else {
this._springTime = double.PositiveInfinity;
}
}
}
const double maxSpringTransferVelocity = 5000.0;
public readonly double leadingExtent;
public readonly double trailingExtent;
public readonly SpringDescription spring;
readonly FrictionSimulation _frictionSimulation;
readonly Simulation _springSimulation;
readonly double _springTime;
double _timeOffset = 0.0;
Simulation _underscrollSimulation(double x, double dx) {
return new ScrollSpringSimulation(this.spring, x, this.leadingExtent, dx);
}
Simulation _overscrollSimulation(double x, double dx) {
return new ScrollSpringSimulation(this.spring, x, this.trailingExtent, dx);
}
Simulation _simulation(double time) {
Simulation simulation;
if (time > this._springTime) {
this._timeOffset = this._springTime.isFinite() ? this._springTime : 0.0;
simulation = this._springSimulation;
} else {
this._timeOffset = 0.0;
simulation = this._frictionSimulation;
}
simulation.tolerance = this.tolerance;
return simulation;
}
public override double x(double time) {
return this._simulation(time).x(time - this._timeOffset);
}
public override double dx(double time) {
return this._simulation(time).dx(time - this._timeOffset);
}
public override bool isDone(double time) {
return this._simulation(time).isDone(time - this._timeOffset);
}
public override string ToString() {
return string.Format("{0}(leadingExtent: {1}, trailingExtent: {2})",
this.GetType(), this.leadingExtent, this.trailingExtent);
}
}
public class ClampingScrollSimulation : Simulation {
public ClampingScrollSimulation(
double position,
double velocity,
double friction = 0.015,
Tolerance tolerance = null
) : base(tolerance: tolerance) {
D.assert(_flingVelocityPenetration(0.0) == _initialVelocityPenetration);
this.position = position;
this.velocity = velocity;
this.friction = friction;
this._duration = this._flingDuration(velocity);
this._distance = (velocity * this._duration / _initialVelocityPenetration).abs();
}
public readonly double position;
public readonly double velocity;
public readonly double friction;
readonly double _duration;
readonly double _distance;
static readonly double _kDecelerationRate = Math.Log(0.78) / Math.Log(0.9);
static double _decelerationForFriction(double friction) {
return friction * 61774.04968;
}
double _flingDuration(double velocity) {
double scaledFriction = this.friction * _decelerationForFriction(0.84);
double deceleration = Math.Log(0.35 * velocity.abs() / scaledFriction);
return Math.Exp(deceleration / (_kDecelerationRate - 1.0));
}
const double _initialVelocityPenetration = 3.065;
static double _flingDistancePenetration(double t) {
return (1.2 * t * t * t) - (3.27 * t * t) + (_initialVelocityPenetration * t);
}
static double _flingVelocityPenetration(double t) {
return (3.6 * t * t) - (6.54 * t) + _initialVelocityPenetration;
}
public override double x(double time) {
double t = (time / this._duration).clamp(0.0, 1.0);
return this.position + this._distance * _flingDistancePenetration(t) * this.velocity.sign();
}
public override double dx(double time) {
double t = (time / this._duration).clamp(0.0, 1.0);
return this._distance * _flingVelocityPenetration(t) * this.velocity.sign() / this._duration;
}
public override bool isDone(double time) {
return time >= this._duration;
}
}
}

3
Assets/UIWidgets/widgets/scroll_simulation.cs.meta


fileFormatVersion: 2
guid: c2459448f9d744ec8e3240a0e1a88754
timeCreated: 1536573658

318
Assets/UIWidgets/animation/curves.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.animation {
public abstract class Curve {
public abstract double transform(double t);
public Curve flipped {
get { return new FlippedCurve(this); }
}
public override string ToString() {
return this.GetType().ToString();
}
}
class _Linear : Curve {
public override double transform(double t) {
return t;
}
}
public class SawTooth : Curve {
public SawTooth(int count) {
this.count = count;
}
public readonly int count;
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
if (t == 1.0) {
return 1.0;
}
t *= this.count;
return t - (int) t;
}
public override string ToString() {
return string.Format("{0}({1})", this.GetType(), this.count);
}
}
public class Interval : Curve {
public Interval(double begin, double end, Curve curve = null) {
this.begin = begin;
this.end = end;
this.curve = curve ?? Curves.linear;
}
public readonly double begin;
public readonly double end;
public readonly Curve curve;
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
D.assert(this.begin >= 0.0);
D.assert(this.begin <= 1.0);
D.assert(this.end >= 0.0);
D.assert(this.end <= 1.0);
D.assert(this.end >= this.begin);
if (t == 0.0 || t == 1.0) {
return t;
}
t = ((t - this.begin) / (this.end - this.begin)).clamp(0.0, 1.0);
if (t == 0.0 || t == 1.0) {
return t;
}
return this.curve.transform(t);
}
public override string ToString() {
if (!(this.curve is _Linear)) {
return string.Format("{0}({1}\u22EF{2}\u27A9{3}", this.GetType(), this.begin, this.end, this.curve);
}
return string.Format("{0}({1}\u22EF{2})", this.GetType(), this.begin, this.end);
}
}
public class Threshold : Curve {
public Threshold(double threshold) {
this.threshold = threshold;
}
public readonly double threshold;
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
D.assert(this.threshold >= 0.0);
D.assert(this.threshold <= 1.0);
if (t == 0.0 || t == 1.0) {
return t;
}
return t < this.threshold ? 0.0 : 1.0;
}
}
public class Cubic : Curve {
public Cubic(double a, double b, double c, double d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
public readonly double a;
public readonly double b;
public readonly double c;
public readonly double d;
const double _cubicErrorBound = 0.001;
double _evaluateCubic(double a, double b, double m) {
return 3 * a * (1 - m) * (1 - m) * m +
3 * b * (1 - m) * m * m +
m * m * m;
}
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
double start = 0.0;
double end = 1.0;
while (true) {
double midpoint = (start + end) / 2;
double estimate = this._evaluateCubic(this.a, this.c, midpoint);
if ((t - estimate).abs() < _cubicErrorBound) {
return this._evaluateCubic(this.b, this.d, midpoint);
}
if (estimate < t) {
start = midpoint;
} else {
end = midpoint;
}
}
}
public override string ToString() {
return string.Format("{0}({1:F2}, {2:F2}, {3:F2}, {4:F2})", this.GetType(), this.a, this.b, this.c, this.d);
}
}
public class FlippedCurve : Curve {
public FlippedCurve(Curve curve) {
D.assert(curve != null);
this.curve = curve;
}
public readonly Curve curve;
public override double transform(double t) {
return 1.0 - this.curve.transform(1.0 - t);
}
public override string ToString() {
return string.Format("{0}({1})", this.GetType(), this.curve);
}
}
class _DecelerateCurve : Curve {
internal _DecelerateCurve() {
}
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
t = 1.0 - t;
return 1.0 - t * t;
}
}
class _BounceInCurve : Curve {
internal _BounceInCurve() {
}
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
return 1.0 - Curves._bounce(1.0 - t);
}
}
class _BounceOutCurve : Curve {
internal _BounceOutCurve() {
}
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
return Curves._bounce(t);
}
}
class _BounceInOutCurve : Curve {
internal _BounceInOutCurve() {
}
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
if (t < 0.5) {
return (1.0 - Curves._bounce(1.0 - t)) * 0.5;
} else {
return Curves._bounce(t * 2.0 - 1.0) * 0.5 + 0.5;
}
}
}
public class ElasticInCurve : Curve {
public ElasticInCurve(double period = 0.4) {
this.period = period;
}
public readonly double period;
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
double s = this.period / 4.0;
t = t - 1.0;
return -Math.Pow(2.0, 10.0 * t) * Math.Sin((t - s) * (Math.PI * 2.0) / this.period);
}
public override String ToString() {
return string.Format("{0}({1})", this.GetType(), this.period);
}
}
public class ElasticOutCurve : Curve {
public ElasticOutCurve(double period = 0.4) {
this.period = period;
}
public readonly double period;
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
double s = this.period / 4.0;
return Math.Pow(2.0, -10.0 * t) * Math.Sin((t - s) * (Math.PI * 2.0) / this.period) + 1.0;
}
public override String ToString() {
return string.Format("{0}({1})", this.GetType(), this.period);
}
}
public class ElasticInOutCurve : Curve {
public ElasticInOutCurve(double period = 0.4) {
this.period = period;
}
public readonly double period;
public override double transform(double t) {
D.assert(t >= 0.0 && t <= 1.0);
double s = this.period / 4.0;
t = 2.0 * t - 1.0;
if (t < 0.0) {
return -0.5 * Math.Pow(2.0, 10.0 * t) * Math.Sin((t - s) * (Math.PI * 2.0) / this.period);
} else {
return Math.Pow(2.0, -10.0 * t) * Math.Sin((t - s) * (Math.PI * 2.0) / this.period) * 0.5 + 1.0;
}
}
public override String ToString() {
return string.Format("{0}({1})", this.GetType(), this.period);
}
}
public static class Curves {
public static readonly Curve linear = new _Linear();
public static readonly Curve decelerate = new _DecelerateCurve();
public static readonly Curve ease = new Cubic(0.25, 0.1, 0.25, 1.0);
public static readonly Curve easeIn = new Cubic(0.42, 0.0, 1.0, 1.0);
public static readonly Curve easeOut = new Cubic(0.0, 0.0, 0.58, 1.0);
public static readonly Curve easeInOut = new Cubic(0.42, 0.0, 0.58, 1.0);
public static readonly Curve fastOutSlowIn = new Cubic(0.4, 0.0, 0.2, 1.0);
public static readonly Curve bounceIn = new _BounceInCurve();
public static readonly Curve bounceOut = new _BounceOutCurve();
public static readonly Curve bounceInOut = new _BounceInOutCurve();
public static readonly Curve elasticIn = new ElasticInCurve();
public static readonly Curve elasticOut = new ElasticOutCurve();
public static readonly Curve elasticInOut = new ElasticInOutCurve();
internal static double _bounce(double t) {
if (t < 1.0 / 2.75) {
return 7.5625 * t * t;
} else if (t < 2 / 2.75) {
t -= 1.5 / 2.75;
return 7.5625 * t * t + 0.75;
} else if (t < 2.5 / 2.75) {
t -= 2.25 / 2.75;
return 7.5625 * t * t + 0.9375;
}
t -= 2.625 / 2.75;
return 7.5625 * t * t + 0.984375;
}
}
}

3
Assets/UIWidgets/animation/animation.cs.meta


fileFormatVersion: 2
guid: dacb0a58278b41d585c256badb6f6a5c
timeCreated: 1536727284

3
Assets/UIWidgets/animation/animation_controller.cs.meta


fileFormatVersion: 2
guid: f1417c6a32c94895b551503b8ea7a464
timeCreated: 1536734209

3
Assets/UIWidgets/animation/animations.cs.meta


fileFormatVersion: 2
guid: 6a1fb4f1aff742c98f8e4e27a03e45f2
timeCreated: 1536728596

11
Assets/UIWidgets/animation/curves.cs.meta


fileFormatVersion: 2
guid: 020ec64cb65c14f6493309339667afee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

2
Assets/UIWidgets/animation/listener_helpers.cs


namespace UIWidgets.animation {
}

3
Assets/UIWidgets/animation/listener_helpers.cs.meta


fileFormatVersion: 2
guid: 904fcf341bef44a191cf4674c42334a8
timeCreated: 1536731860

11
Assets/UIWidgets/animation/listener_helpers.mixin.gen.cs.meta


fileFormatVersion: 2
guid: fc158b938e74644e0ba73d8e95247892
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

3
Assets/UIWidgets/animation/listener_helpers.mixin.njk.meta


fileFormatVersion: 2
guid: 3bad423f035f41e0a5dbb75dc244a06b
timeCreated: 1536731953

3
Assets/UIWidgets/animation/tween.cs.meta


fileFormatVersion: 2
guid: ca9370be0eef47e2aa0fcc3a9d4b4c46
timeCreated: 1536728064

60
Assets/UIWidgets/animation/animation.cs


using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.animation {
public enum AnimationStatus {
dismissed,
forward,
reverse,
completed,
}
public delegate void AnimationStatusListener(AnimationStatus status);
public abstract class Animation<T> : ValueListenable<T> {
public abstract void addListener(VoidCallback listener);
public abstract void removeListener(VoidCallback listener);
public abstract void addStatusListener(AnimationStatusListener listener);
public abstract void removeStatusListener(AnimationStatusListener listener);
public abstract AnimationStatus status { get; }
public abstract T value { get; }
public bool isDismissed {
get { return this.status == AnimationStatus.dismissed; }
}
public bool isCompleted {
get { return this.status == AnimationStatus.completed; }
}
public override string ToString() {
return string.Format("{0}({1})", Diagnostics.describeIdentity(this), this.toStringDetails());
}
public virtual string toStringDetails() {
string icon = null;
switch (this.status) {
case AnimationStatus.forward:
icon = "\u25B6"; // >
break;
case AnimationStatus.reverse:
icon = "\u25C0"; // <
break;
case AnimationStatus.completed:
icon = "\u23ED"; // >>|
break;
case AnimationStatus.dismissed:
icon = "\u23EE"; // |<<
break;
}
D.assert(icon != null);
return icon;
}
}
}

417
Assets/UIWidgets/animation/animation_controller.cs


using System;
using UIWidgets.foundation;
using UIWidgets.physics;
using UIWidgets.scheduler;
using UIWidgets.ui;
namespace UIWidgets.animation {
enum _AnimationDirection {
forward,
reverse,
}
public class AnimationController :
AnimationLocalStatusListenersMixinAnimationLocalListenersMixinAnimationEagerListenerMixinAnimation<double> {
public AnimationController(
double? value = null,
TimeSpan? duration = null,
string debugLabel = null,
double lowerBound = 0.0,
double upperBound = 1.0,
TickerProvider vsync = null
) {
D.assert(upperBound >= lowerBound);
D.assert(vsync != null);
this._direction = _AnimationDirection.forward;
this.duration = duration;
this.debugLabel = debugLabel;
this.lowerBound = lowerBound;
this.upperBound = upperBound;
this._ticker = vsync.createTicker(this._tick);
this._internalSetValue(value ?? lowerBound);
}
private AnimationController(
double value = 0.0,
TimeSpan? duration = null,
string debugLabel = null,
TickerProvider vsync = null
) {
D.assert(vsync != null);
this.lowerBound = double.NegativeInfinity;
this.upperBound = double.PositiveInfinity;
this._direction = _AnimationDirection.forward;
this.duration = duration;
this.debugLabel = debugLabel;
this._ticker = vsync.createTicker(this._tick);
this._internalSetValue(value);
}
public static AnimationController unbounded(
double value = 0.0,
TimeSpan? duration = null,
string debugLabel = null,
TickerProvider vsync = null
) {
return new AnimationController(value, duration, debugLabel, vsync);
}
public readonly double lowerBound;
public readonly double upperBound;
public readonly string debugLabel;
public Animation<double> view {
get { return this; }
}
public TimeSpan? duration;
Ticker _ticker;
public void resync(TickerProvider vsync) {
Ticker oldTicker = this._ticker;
this._ticker = vsync.createTicker(_tick);
this._ticker.absorbTicker(oldTicker);
}
Simulation _simulation;
public override double value {
get { return this._value; }
}
double _value;
public void setValue(double newValue) {
this.stop();
this._internalSetValue(newValue);
this.notifyListeners();
this._checkStatusChanged();
}
public void reset() {
this.setValue(this.lowerBound);
}
public double velocity {
get {
if (!this.isAnimating) {
return 0.0;
}
return this._simulation.dx((double) this.lastElapsedDuration.Value.Ticks / TimeSpan.TicksPerSecond);
}
}
void _internalSetValue(double newValue) {
this._value = newValue.clamp(this.lowerBound, this.upperBound);
if (this._value == this.lowerBound) {
this._status = AnimationStatus.dismissed;
} else if (this._value == this.upperBound) {
this._status = AnimationStatus.completed;
} else {
this._status = (this._direction == _AnimationDirection.forward)
? AnimationStatus.forward
: AnimationStatus.reverse;
}
}
TimeSpan? lastElapsedDuration {
get { return this._lastElapsedDuration; }
}
TimeSpan? _lastElapsedDuration;
public bool isAnimating {
get { return this._ticker != null && this._ticker.isActive; }
}
_AnimationDirection _direction;
public override AnimationStatus status {
get { return this._status; }
}
AnimationStatus _status;
public TickerFuture forward(double? from = null) {
D.assert(() => {
if (this.duration == null) {
throw new UIWidgetsError(
"AnimationController.forward() called with no default Duration.\n" +
"The \"duration\" property should be set, either in the constructor or later, before " +
"calling the forward() function."
);
}
return true;
});
this._direction = _AnimationDirection.forward;
if (from != null) {
this.setValue(from.Value);
}
return this._animateToInternal(this.upperBound);
}
public TickerFuture reverse(double? from = null) {
D.assert(() => {
if (this.duration == null) {
throw new UIWidgetsError(
"AnimationController.reverse() called with no default Duration.\n" +
"The \"duration\" property should be set, either in the constructor or later, before " +
"calling the reverse() function."
);
}
return true;
});
this._direction = _AnimationDirection.reverse;
if (from != null) {
this.setValue(from.Value);
}
return this._animateToInternal(this.lowerBound);
}
public TickerFuture animateTo(double target, TimeSpan? duration = null, Curve curve = null) {
curve = curve ?? Curves.linear;
this._direction = _AnimationDirection.forward;
return this._animateToInternal(target, duration: duration, curve: curve);
}
TickerFuture _animateToInternal(double target, TimeSpan? duration = null, Curve curve = null) {
curve = curve ?? Curves.linear;
TimeSpan? simulationDuration = duration;
if (simulationDuration == null) {
D.assert(() => {
if (this.duration == null) {
throw new UIWidgetsError(
"AnimationController.animateTo() called with no explicit Duration and no default Duration.\n" +
"Either the \"duration\" argument to the animateTo() method should be provided, or the " +
"\"duration\" property should be set, either in the constructor or later, before " +
"calling the animateTo() function."
);
}
return true;
});
double range = this.upperBound - this.lowerBound;
double remainingFraction = range.isFinite() ? (target - this._value).abs() / range : 1.0;
simulationDuration = TimeSpan.FromTicks((long) (this.duration.Value.Ticks * remainingFraction));
} else if (target == this.value) {
simulationDuration = TimeSpan.Zero;
}
this.stop();
if (simulationDuration == TimeSpan.Zero) {
if (this._value != target) {
this._value = target.clamp(this.lowerBound, this.upperBound);
this.notifyListeners();
}
this._status = (this._direction == _AnimationDirection.forward)
? AnimationStatus.completed
: AnimationStatus.dismissed;
this._checkStatusChanged();
return TickerFutureImpl.complete();
}
D.assert(simulationDuration > TimeSpan.Zero);
D.assert(!this.isAnimating);
return this._startSimulation(
new _InterpolationSimulation(this._value, target, simulationDuration.Value, curve));
}
public TickerFuture repeat(double? min = null, double? max = null, TimeSpan? period = null) {
min = min ?? this.lowerBound;
max = max ?? this.upperBound;
period = period ?? this.duration;
D.assert(() => {
if (period == null) {
throw new UIWidgetsError(
"AnimationController.repeat() called without an explicit period and with no default Duration.\n" +
"Either the \"period\" argument to the repeat() method should be provided, or the " +
"\"duration\" property should be set, either in the constructor or later, before " +
"calling the repeat() function."
);
}
return true;
});
return this.animateWith(new _RepeatingSimulation(min.Value, max.Value, period.Value));
}
public TickerFuture fling(double velocity = 1.0) {
this._direction = velocity < 0.0 ? _AnimationDirection.reverse : _AnimationDirection.forward;
double target = velocity < 0.0
? this.lowerBound - _kFlingTolerance.distance
: this.upperBound + _kFlingTolerance.distance;
Simulation simulation = new SpringSimulation(_kFlingSpringDescription, this.value, target, velocity);
simulation.tolerance = _kFlingTolerance;
return this.animateWith(simulation);
}
public TickerFuture animateWith(Simulation simulation) {
this.stop();
return this._startSimulation(simulation);
}
TickerFuture _startSimulation(Simulation simulation) {
D.assert(simulation != null);
D.assert(!this.isAnimating);
this._simulation = simulation;
this._lastElapsedDuration = TimeSpan.Zero;
this._value = simulation.x(0.0).clamp(this.lowerBound, this.upperBound);
var result = this._ticker.start();
this._status = (this._direction == _AnimationDirection.forward)
? AnimationStatus.forward
: AnimationStatus.reverse;
this._checkStatusChanged();
return result;
}
public void stop(bool canceled = true) {
this._simulation = null;
this._lastElapsedDuration = null;
this._ticker.stop(canceled: canceled);
}
public override void dispose() {
D.assert(() => {
if (this._ticker == null) {
throw new UIWidgetsError(
"AnimationController.dispose() called more than once.\n" +
"A given " + this.GetType() + " cannot be disposed more than once.\n" +
"The following " + this.GetType() + " object was disposed multiple times:\n" +
" " + this);
}
return true;
});
this._ticker.dispose();
this._ticker = null;
base.dispose();
}
AnimationStatus _lastReportedStatus = AnimationStatus.dismissed;
void _checkStatusChanged() {
AnimationStatus newStatus = this.status;
if (this._lastReportedStatus != newStatus) {
this._lastReportedStatus = newStatus;
this.notifyStatusListeners(newStatus);
}
}
void _tick(TimeSpan elapsed) {
this._lastElapsedDuration = elapsed;
double elapsedInSeconds = (double) elapsed.Ticks / TimeSpan.TicksPerSecond;
D.assert(elapsedInSeconds >= 0.0);
this._value = this._simulation.x(elapsedInSeconds).clamp(this.lowerBound, this.upperBound);
if (this._simulation.isDone(elapsedInSeconds)) {
this._status = (this._direction == _AnimationDirection.forward)
? AnimationStatus.completed
: AnimationStatus.dismissed;
this.stop(canceled: false);
}
this.notifyListeners();
this._checkStatusChanged();
}
public override string toStringDetails() {
string paused = this.isAnimating ? "" : "; paused";
string ticker = this._ticker == null ? "; DISPOSED" : (this._ticker.muted ? "; silenced" : "");
string label = this.debugLabel == null ? "" : "; for " + this.debugLabel;
string more = string.Format("{0} {1:F3}", base.toStringDetails(), this.value);
return more + paused + ticker + label;
}
static readonly SpringDescription _kFlingSpringDescription = SpringDescription.withDampingRatio(
mass: 1.0,
stiffness: 500.0,
ratio: 1.0
);
static readonly Tolerance _kFlingTolerance = new Tolerance(
velocity: double.PositiveInfinity,
distance: 0.01
);
}
class _InterpolationSimulation : Simulation {
internal _InterpolationSimulation(double _begin, double _end, TimeSpan duration, Curve _curve) {
this._begin = _begin;
this._end = _end;
this._curve = _curve;
D.assert(duration.Ticks > 0);
this._durationInSeconds = (double) duration.Ticks / TimeSpan.TicksPerSecond;
}
readonly double _durationInSeconds;
readonly double _begin;
readonly double _end;
readonly Curve _curve;
public override double x(double timeInSeconds) {
double t = (timeInSeconds / this._durationInSeconds).clamp(0.0, 1.0);
if (t == 0.0) {
return this._begin;
} else if (t == 1.0) {
return this._end;
} else {
return this._begin + (this._end - this._begin) * this._curve.transform(t);
}
}
public override double dx(double timeInSeconds) {
double epsilon = this.tolerance.time;
return (this.x(timeInSeconds + epsilon) - this.x(timeInSeconds - epsilon)) / (2 * epsilon);
}
public override bool isDone(double timeInSeconds) {
return timeInSeconds > this._durationInSeconds;
}
}
class _RepeatingSimulation : Simulation {
internal _RepeatingSimulation(double min, double max, TimeSpan period) {
this.min = min;
this.max = max;
this._periodInSeconds = (double) period.Ticks / TimeSpan.TicksPerSecond;
D.assert(this._periodInSeconds > 0.0);
}
readonly double min;
readonly double max;
readonly double _periodInSeconds;
public override double x(double timeInSeconds) {
D.assert(timeInSeconds >= 0.0);
double t = (timeInSeconds / this._periodInSeconds) % 1.0;
return MathUtils.lerpDouble(this.min, this.max, t);
}
public override double dx(double timeInSeconds) {
return (this.max - this.min) / this._periodInSeconds;
}
public override bool isDone(double timeInSeconds) {
return false;
}
}
}

591
Assets/UIWidgets/animation/animations.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.animation {
class _AlwaysCompleteAnimation : Animation<double> {
internal _AlwaysCompleteAnimation() {
}
public override void addListener(VoidCallback listener) {
}
public override void removeListener(VoidCallback listener) {
}
public override void addStatusListener(AnimationStatusListener listener) {
}
public override void removeStatusListener(AnimationStatusListener listener) {
}
public override AnimationStatus status {
get { return AnimationStatus.completed; }
}
public override double value {
get { return 1.0; }
}
public override string ToString() {
return "kAlwaysCompleteAnimation";
}
}
class _AlwaysDismissedAnimation : Animation<double> {
internal _AlwaysDismissedAnimation() {
}
public override void addListener(VoidCallback listener) {
}
public override void removeListener(VoidCallback listener) {
}
public override void addStatusListener(AnimationStatusListener listener) {
}
public override void removeStatusListener(AnimationStatusListener listener) {
}
public override AnimationStatus status {
get { return AnimationStatus.dismissed; }
}
public override double value {
get { return 0.0; }
}
public override string ToString() {
return "kAlwaysDismissedAnimation";
}
}
public class AlwaysStoppedAnimation<T> : Animation<T> {
public AlwaysStoppedAnimation(T value) {
this._value = value;
}
public override T value {
get { return this._value; }
}
readonly T _value;
public override void addListener(VoidCallback listener) {
}
public override void removeListener(VoidCallback listener) {
}
public override void addStatusListener(AnimationStatusListener listener) {
}
public override void removeStatusListener(AnimationStatusListener listener) {
}
public override AnimationStatus status {
get { return AnimationStatus.forward; }
}
public override string toStringDetails() {
return string.Format("{0} {1}; paused", base.toStringDetails(), this.value);
}
}
public abstract class AnimationWithParentMixin<TParent, T> : Animation<T> {
public abstract Animation<TParent> parent { get; }
public override void addListener(VoidCallback listener) {
this.parent.addListener(listener);
}
public override void removeListener(VoidCallback listener) {
this.parent.removeListener(listener);
}
public override void addStatusListener(AnimationStatusListener listener) {
this.parent.addStatusListener(listener);
}
public override void removeStatusListener(AnimationStatusListener listener) {
this.parent.removeStatusListener(listener);
}
public override AnimationStatus status {
get { return this.parent.status; }
}
}
public class ProxyAnimation :
AnimationLocalStatusListenersMixinAnimationLocalListenersMixinAnimationLazyListenerMixinAnimation<double> {
public ProxyAnimation(Animation<double> animation = null) {
this._parent = animation;
if (this._parent == null) {
this._status = AnimationStatus.dismissed;
this._value = 0.0;
}
}
AnimationStatus _status;
double _value;
public Animation<double> parent {
get { return this._parent; }
set {
if (value == this._parent) {
return;
}
if (this._parent != null) {
this._status = this._parent.status;
this._value = this._parent.value;
if (this.isListening) {
this.didStopListening();
}
}
this._parent = value;
if (this._parent != null) {
if (this.isListening) {
this.didStartListening();
}
if (this._value != this._parent.value) {
this.notifyListeners();
}
if (this._status != this._parent.status) {
this.notifyStatusListeners(this._parent.status);
}
this._status = AnimationStatus.dismissed;
this._value = 0;
}
}
}
Animation<double> _parent;
protected override void didStartListening() {
if (this._parent != null) {
this._parent.addListener(this.notifyListeners);
this._parent.addStatusListener(this.notifyStatusListeners);
}
}
protected override void didStopListening() {
if (this._parent != null) {
this._parent.removeListener(this.notifyListeners);
this._parent.removeStatusListener(this.notifyStatusListeners);
}
}
public override AnimationStatus status {
get { return this._parent != null ? this._parent.status : this._status; }
}
public override double value {
get { return this._parent != null ? this._parent.value : this._value; }
}
public override string ToString() {
if (this.parent == null) {
return string.Format("{0}(null; {1} {2:F3}", this.GetType(), this.toStringDetails(), this.value);
}
return string.Format("{0}\u27A9{1}", this.parent, this.GetType());
}
}
public class ReverseAnimation : AnimationLocalStatusListenersMixinAnimationLazyListenerMixinAnimation<double> {
public ReverseAnimation(Animation<double> parent) {
D.assert(parent != null);
this._parent = parent;
}
public Animation<double> parent {
get { return this._parent; }
}
readonly Animation<double> _parent;
public override void addListener(VoidCallback listener) {
this.didRegisterListener();
this.parent.addListener(listener);
}
public override void removeListener(VoidCallback listener) {
this.parent.removeListener(listener);
this.didUnregisterListener();
}
protected override void didStartListening() {
this.parent.addStatusListener(this._statusChangeHandler);
}
protected override void didStopListening() {
this.parent.removeStatusListener(this._statusChangeHandler);
}
void _statusChangeHandler(AnimationStatus status) {
this.notifyStatusListeners(this._reverseStatus(status));
}
public override AnimationStatus status {
get { return this._reverseStatus(this.parent.status); }
}
public override double value {
get { return 1.0 - this.parent.value; }
}
AnimationStatus _reverseStatus(AnimationStatus status) {
switch (status) {
case AnimationStatus.forward: return AnimationStatus.reverse;
case AnimationStatus.reverse: return AnimationStatus.forward;
case AnimationStatus.completed: return AnimationStatus.dismissed;
case AnimationStatus.dismissed: return AnimationStatus.completed;
}
D.assert(false);
return default(AnimationStatus);
}
public override string ToString() {
return this.parent + "\u27AA" + this.GetType();
}
}
public class CurvedAnimation : AnimationWithParentMixin<double, double> {
public CurvedAnimation(
Animation<double> parent = null,
Curve curve = null,
Curve reverseCurve = null
) {
D.assert(parent != null);
D.assert(curve != null);
this._parent = parent;
this.curve = curve;
this.reverseCurve = reverseCurve;
this._updateCurveDirection(parent.status);
parent.addStatusListener(this._updateCurveDirection);
}
public override Animation<double> parent {
get { return this._parent; }
}
readonly Animation<double> _parent;
public Curve curve;
public Curve reverseCurve;
AnimationStatus? _curveDirection;
void _updateCurveDirection(AnimationStatus status) {
switch (status) {
case AnimationStatus.dismissed:
case AnimationStatus.completed:
this._curveDirection = null;
break;
case AnimationStatus.forward:
this._curveDirection = this._curveDirection ?? AnimationStatus.forward;
break;
case AnimationStatus.reverse:
this._curveDirection = this._curveDirection ?? AnimationStatus.reverse;
break;
}
}
bool _useForwardCurve {
get {
return this.reverseCurve == null ||
(this._curveDirection ?? this.parent.status) != AnimationStatus.reverse;
}
}
public override double value {
get {
Curve activeCurve = this._useForwardCurve ? this.curve : this.reverseCurve;
double t = this.parent.value;
if (activeCurve == null) {
return t;
}
if (t == 0.0 || t == 1.0) {
D.assert(() => {
double transformedValue = activeCurve.transform(t);
double roundedTransformedValue = transformedValue.round();
if (roundedTransformedValue != t) {
throw new UIWidgetsError(
string.Format(
"Invalid curve endpoint at {0}.\n" +
"Curves must map 0.0 to near zero and 1.0 to near one but " +
"{1} mapped {0} to {2}, which " +
"is near {3}.",
t, activeCurve.GetType(), transformedValue, roundedTransformedValue)
);
}
return true;
});
return t;
}
return activeCurve.transform(t);
}
}
public override string ToString() {
if (this.reverseCurve == null) {
return this.parent + "\u27A9" + this.curve;
}
if (this._useForwardCurve) {
return this.parent + "\u27A9" + this.curve + "\u2092\u2099/" + this.reverseCurve;
}
return this.parent + "\u27A9" + this.curve + "/" + this.reverseCurve + "\u2092\u2099";
}
}
enum _TrainHoppingMode {
minimize,
maximize
}
public class TrainHoppingAnimation :
AnimationLocalStatusListenersMixinAnimationLocalListenersMixinAnimationEagerListenerMixinAnimation<double> {
public TrainHoppingAnimation(
Animation<double> _currentTrain = null,
Animation<double> _nextTrain = null,
VoidCallback onSwitchedTrain = null) {
D.assert(_currentTrain != null);
this._currentTrain = _currentTrain;
this._nextTrain = _nextTrain;
this.onSwitchedTrain = onSwitchedTrain;
if (this._nextTrain != null) {
if (this._currentTrain.value > this._nextTrain.value) {
this._mode = _TrainHoppingMode.maximize;
} else {
this._mode = _TrainHoppingMode.minimize;
if (this._currentTrain.value == this._nextTrain.value) {
this._currentTrain = this._nextTrain;
this._nextTrain = null;
}
}
}
this._currentTrain.addStatusListener(this._statusChangeHandler);
this._currentTrain.addListener(this._valueChangeHandler);
if (this._nextTrain != null) {
this._nextTrain.addListener(this._valueChangeHandler);
}
}
public Animation<double> currentTrain {
get { return this._currentTrain; }
}
Animation<double> _currentTrain;
Animation<double> _nextTrain;
_TrainHoppingMode _mode;
public VoidCallback onSwitchedTrain;
AnimationStatus? _lastStatus;
void _statusChangeHandler(AnimationStatus status) {
D.assert(this._currentTrain != null);
if (status != this._lastStatus) {
this.notifyListeners();
this._lastStatus = status;
}
D.assert(this._lastStatus != null);
}
public override AnimationStatus status {
get { return this._currentTrain.status; }
}
double? _lastValue;
void _valueChangeHandler() {
D.assert(this._currentTrain != null);
bool hop = false;
if (this._nextTrain != null) {
switch (this._mode) {
case _TrainHoppingMode.minimize:
hop = this._nextTrain.value <= this._currentTrain.value;
break;
case _TrainHoppingMode.maximize:
hop = this._nextTrain.value >= this._currentTrain.value;
break;
}
if (hop) {
this._currentTrain.removeStatusListener(this._statusChangeHandler);
this._currentTrain.removeListener(this._valueChangeHandler);
this._currentTrain = this._nextTrain;
this._nextTrain = null;
this._currentTrain.addStatusListener(this._statusChangeHandler);
this._statusChangeHandler(this._currentTrain.status);
}
}
double newValue = this.value;
if (newValue != this._lastValue) {
this.notifyListeners();
this._lastValue = newValue;
}
D.assert(this._lastValue != null);
if (hop && this.onSwitchedTrain != null) {
this.onSwitchedTrain();
}
}
public override double value {
get { return this._currentTrain.value; }
}
public override void dispose() {
D.assert(this._currentTrain != null);
this._currentTrain.removeStatusListener(this._statusChangeHandler);
this._currentTrain.removeListener(this._valueChangeHandler);
this._currentTrain = null;
if (this._nextTrain != null) {
this._nextTrain.removeListener(this._valueChangeHandler);
this._nextTrain = null;
}
base.dispose();
}
public override string ToString() {
if (this._nextTrain != null) {
return string.Format("{0}\u27A9{1}(next: {2})", this.currentTrain, this.GetType(), this._nextTrain);
}
return string.Format("{0}\u27A9{1}(no next)", this.currentTrain, this.GetType());
}
}
public abstract class CompoundAnimation<T> :
AnimationLocalStatusListenersMixinAnimationLocalListenersMixinAnimationLazyListenerMixinAnimation<T> {
public CompoundAnimation(
Animation<T> first = null,
Animation<T> next = null
) {
D.assert(first != null);
D.assert(next != null);
this.first = first;
this.next = next;
}
public readonly Animation<T> first;
public readonly Animation<T> next;
protected override void didStartListening() {
this.first.addListener(this._maybeNotifyListeners);
this.first.addStatusListener(this._maybeNotifyStatusListeners);
this.next.addListener(this._maybeNotifyListeners);
this.next.addStatusListener(this._maybeNotifyStatusListeners);
}
protected override void didStopListening() {
this.first.removeListener(this._maybeNotifyListeners);
this.first.removeStatusListener(this._maybeNotifyStatusListeners);
this.next.removeListener(this._maybeNotifyListeners);
this.next.removeStatusListener(this._maybeNotifyStatusListeners);
}
public override AnimationStatus status {
get {
if (this.next.status == AnimationStatus.forward || this.next.status == AnimationStatus.reverse)
return this.next.status;
return this.first.status;
}
}
public override string ToString() {
return string.Format("{0}({1}, {2})", this.GetType(), this.first, this.next);
}
AnimationStatus _lastStatus;
void _maybeNotifyStatusListeners(AnimationStatus _) {
if (this.status != this._lastStatus) {
this._lastStatus = this.status;
this.notifyStatusListeners(this.status);
}
}
T _lastValue;
void _maybeNotifyListeners() {
if (object.Equals(this.value, this._lastValue)) {
this._lastValue = this.value;
this.notifyListeners();
}
}
}
public class AnimationMean : CompoundAnimation<double> {
public AnimationMean(
Animation<double> left = null,
Animation<double> right = null
) : base(first: left, next: right) {
}
public override double value {
get { return (this.first.value + this.next.value) / 2.0; }
}
}
public class AnimationMax : CompoundAnimation<double> {
public AnimationMax(
Animation<double> left = null,
Animation<double> right = null
) : base(first: left, next: right) {
}
public override double value {
get { return Math.Max(this.first.value, this.next.value); }
}
}
public class AnimationMin : CompoundAnimation<double> {
public AnimationMin(
Animation<double> left = null,
Animation<double> right = null
) : base(first: left, next: right) {
}
public override double value {
get { return Math.Min(this.first.value, this.next.value); }
}
}
public static class Animations {
public static readonly Animation<double> kAlwaysCompleteAnimation = new _AlwaysCompleteAnimation();
public static readonly Animation<double> kAlwaysDismissedAnimation = new _AlwaysDismissedAnimation();
}
}

245
Assets/UIWidgets/animation/listener_helpers.mixin.gen.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.animation {
public abstract class AnimationLazyListenerMixinAnimation<T> : Animation<T> {
int _listenerCounter = 0;
protected void didRegisterListener() {
D.assert(this._listenerCounter >= 0);
if (this._listenerCounter == 0) {
this.didStartListening();
}
this._listenerCounter += 1;
}
protected void didUnregisterListener() {
D.assert(this._listenerCounter >= 1);
this._listenerCounter -= 1;
if (this._listenerCounter == 0) {
this.didStopListening();
}
}
protected abstract void didStartListening();
protected abstract void didStopListening();
public bool isListening {
get { return this._listenerCounter > 0; }
}
}
public abstract class AnimationEagerListenerMixinAnimation<T> : Animation<T> {
protected void didRegisterListener() {
}
protected void didUnregisterListener() {
}
public virtual void dispose() {
}
}
public abstract class AnimationLocalListenersMixinAnimationLazyListenerMixinAnimation<T> : AnimationLazyListenerMixinAnimation<T> {
readonly ObserverList<VoidCallback> _listeners = new ObserverList<VoidCallback>();
public override void addListener(VoidCallback listener) {
this.didRegisterListener();
this._listeners.Add(listener);
}
public override void removeListener(VoidCallback listener) {
this._listeners.Remove(listener);
this.didUnregisterListener();
}
public void notifyListeners() {
var localListeners = new List<VoidCallback>(this._listeners);
foreach (VoidCallback listener in localListeners) {
try {
if (this._listeners.Contains(listener)) {
listener();
}
}
catch (Exception exception) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: exception,
library: "animation library",
context: "while notifying listeners for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " notifying listeners was:");
information.Append(" " + this);
}
));
}
}
}
}
public abstract class AnimationLocalListenersMixinAnimationEagerListenerMixinAnimation<T> : AnimationEagerListenerMixinAnimation<T> {
readonly ObserverList<VoidCallback> _listeners = new ObserverList<VoidCallback>();
public override void addListener(VoidCallback listener) {
this.didRegisterListener();
this._listeners.Add(listener);
}
public override void removeListener(VoidCallback listener) {
this._listeners.Remove(listener);
this.didUnregisterListener();
}
public void notifyListeners() {
var localListeners = new List<VoidCallback>(this._listeners);
foreach (VoidCallback listener in localListeners) {
try {
if (this._listeners.Contains(listener)) {
listener();
}
}
catch (Exception exception) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: exception,
library: "animation library",
context: "while notifying listeners for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " notifying listeners was:");
information.Append(" " + this);
}
));
}
}
}
}
public abstract class AnimationLocalStatusListenersMixinAnimationLocalListenersMixinAnimationLazyListenerMixinAnimation<T> : AnimationLocalListenersMixinAnimationLazyListenerMixinAnimation<T> {
readonly ObserverList<AnimationStatusListener> _statusListeners = new ObserverList<AnimationStatusListener>();
public override void addStatusListener(AnimationStatusListener listener) {
this.didRegisterListener();
this._statusListeners.Add(listener);
}
public override void removeStatusListener(AnimationStatusListener listener) {
this._statusListeners.Remove(listener);
this.didUnregisterListener();
}
public void notifyStatusListeners(AnimationStatus status) {
var localListeners = new List<AnimationStatusListener>(this._statusListeners);
foreach (AnimationStatusListener listener in localListeners) {
try {
if (this._statusListeners.Contains(listener)) {
listener(status);
}
}
catch (Exception exception) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: exception,
library: "animation library",
context: "while notifying status listeners for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " notifying status listeners was:");
information.Append(" " + this);
}
));
}
}
}
}
public abstract class AnimationLocalStatusListenersMixinAnimationLazyListenerMixinAnimation<T> : AnimationLazyListenerMixinAnimation<T> {
readonly ObserverList<AnimationStatusListener> _statusListeners = new ObserverList<AnimationStatusListener>();
public override void addStatusListener(AnimationStatusListener listener) {
this.didRegisterListener();
this._statusListeners.Add(listener);
}
public override void removeStatusListener(AnimationStatusListener listener) {
this._statusListeners.Remove(listener);
this.didUnregisterListener();
}
public void notifyStatusListeners(AnimationStatus status) {
var localListeners = new List<AnimationStatusListener>(this._statusListeners);
foreach (AnimationStatusListener listener in localListeners) {
try {
if (this._statusListeners.Contains(listener)) {
listener(status);
}
}
catch (Exception exception) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: exception,
library: "animation library",
context: "while notifying status listeners for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " notifying status listeners was:");
information.Append(" " + this);
}
));
}
}
}
}
public abstract class AnimationLocalStatusListenersMixinAnimationLocalListenersMixinAnimationEagerListenerMixinAnimation<T> : AnimationLocalListenersMixinAnimationEagerListenerMixinAnimation<T> {
readonly ObserverList<AnimationStatusListener> _statusListeners = new ObserverList<AnimationStatusListener>();
public override void addStatusListener(AnimationStatusListener listener) {
this.didRegisterListener();
this._statusListeners.Add(listener);
}
public override void removeStatusListener(AnimationStatusListener listener) {
this._statusListeners.Remove(listener);
this.didUnregisterListener();
}
public void notifyStatusListeners(AnimationStatus status) {
var localListeners = new List<AnimationStatusListener>(this._statusListeners);
foreach (AnimationStatusListener listener in localListeners) {
try {
if (this._statusListeners.Contains(listener)) {
listener(status);
}
}
catch (Exception exception) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: exception,
library: "animation library",
context: "while notifying status listeners for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " notifying status listeners was:");
information.Append(" " + this);
}
));
}
}
}
}
}

141
Assets/UIWidgets/animation/listener_helpers.mixin.njk


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.animation {
{% macro AnimationLazyListenerMixin(with) %}
public abstract class AnimationLazyListenerMixin{{with | safe}} : {{with | safe}} {
int _listenerCounter = 0;
protected void didRegisterListener() {
D.assert(this._listenerCounter >= 0);
if (this._listenerCounter == 0) {
this.didStartListening();
}
this._listenerCounter += 1;
}
protected void didUnregisterListener() {
D.assert(this._listenerCounter >= 1);
this._listenerCounter -= 1;
if (this._listenerCounter == 0) {
this.didStopListening();
}
}
protected abstract void didStartListening();
protected abstract void didStopListening();
public bool isListening {
get { return this._listenerCounter > 0; }
}
}
{% endmacro %}
{{ AnimationLazyListenerMixin('Animation<T>') }}
{% macro AnimationEagerListenerMixin(with) %}
public abstract class AnimationEagerListenerMixin{{with | safe}} : {{with | safe}} {
protected void didRegisterListener() {
}
protected void didUnregisterListener() {
}
public virtual void dispose() {
}
}
{% endmacro %}
{{ AnimationEagerListenerMixin('Animation<T>') }}
{% macro AnimationLocalListenersMixin(with) %}
public abstract class AnimationLocalListenersMixin{{with | safe}} : {{with | safe}} {
readonly ObserverList<VoidCallback> _listeners = new ObserverList<VoidCallback>();
public override void addListener(VoidCallback listener) {
this.didRegisterListener();
this._listeners.Add(listener);
}
public override void removeListener(VoidCallback listener) {
this._listeners.Remove(listener);
this.didUnregisterListener();
}
public void notifyListeners() {
var localListeners = new List<VoidCallback>(this._listeners);
foreach (VoidCallback listener in localListeners) {
try {
if (this._listeners.Contains(listener)) {
listener();
}
}
catch (Exception exception) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: exception,
library: "animation library",
context: "while notifying listeners for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " notifying listeners was:");
information.Append(" " + this);
}
));
}
}
}
}
{% endmacro %}
{{ AnimationLocalListenersMixin('AnimationLazyListenerMixinAnimation<T>') }}
{{ AnimationLocalListenersMixin('AnimationEagerListenerMixinAnimation<T>') }}
{% macro AnimationLocalStatusListenersMixin(with) %}
public abstract class AnimationLocalStatusListenersMixin{{with | safe}} : {{with | safe}} {
readonly ObserverList<AnimationStatusListener> _statusListeners = new ObserverList<AnimationStatusListener>();
public override void addStatusListener(AnimationStatusListener listener) {
this.didRegisterListener();
this._statusListeners.Add(listener);
}
public override void removeStatusListener(AnimationStatusListener listener) {
this._statusListeners.Remove(listener);
this.didUnregisterListener();
}
public void notifyStatusListeners(AnimationStatus status) {
var localListeners = new List<AnimationStatusListener>(this._statusListeners);
foreach (AnimationStatusListener listener in localListeners) {
try {
if (this._statusListeners.Contains(listener)) {
listener(status);
}
}
catch (Exception exception) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: exception,
library: "animation library",
context: "while notifying status listeners for " + this.GetType(),
informationCollector: information => {
information.AppendLine("The " + this.GetType() + " notifying status listeners was:");
information.Append(" " + this);
}
));
}
}
}
}
{% endmacro %}
{{ AnimationLocalStatusListenersMixin('AnimationLocalListenersMixinAnimationLazyListenerMixinAnimation<T>') }}
{{ AnimationLocalStatusListenersMixin('AnimationLazyListenerMixinAnimation<T>') }}
{{ AnimationLocalStatusListenersMixin('AnimationLocalListenersMixinAnimationEagerListenerMixinAnimation<T>') }}
}

216
Assets/UIWidgets/animation/tween.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.animation {
public abstract class Animatable<T> {
public abstract T evaluate(Animation<double> animation);
public Animation<T> animate(Animation<double> parent) {
return new _AnimatedEvaluation<T>(parent, this);
}
public Animatable<T> chain(Animatable<double> parent) {
return new _ChainedEvaluation<T>(parent, this);
}
}
class _AnimatedEvaluation<T> : AnimationWithParentMixin<double, T> {
internal _AnimatedEvaluation(Animation<double> _parent, Animatable<T> _evaluatable) {
this._parent = parent;
this._evaluatable = _evaluatable;
}
public override Animation<double> parent {
get { return this._parent; }
}
readonly Animation<double> _parent;
readonly Animatable<T> _evaluatable;
public override T value {
get { return this._evaluatable.evaluate(this.parent); }
}
public override string ToString() {
return string.Format("{0}\u27A9{1}\u27A9{2}", this.parent, this._evaluatable, this.value);
}
public override string toStringDetails() {
return base.toStringDetails() + " " + this._evaluatable;
}
}
class _ChainedEvaluation<T> : Animatable<T> {
internal _ChainedEvaluation(Animatable<double> _parent, Animatable<T> _evaluatable) {
this._parent = _parent;
this._evaluatable = _evaluatable;
}
readonly Animatable<double> _parent;
readonly Animatable<T> _evaluatable;
public override T evaluate(Animation<double> animation) {
double value = this._parent.evaluate(animation);
return this._evaluatable.evaluate(new AlwaysStoppedAnimation<double>(value));
}
public override string ToString() {
return string.Format("{0}\u27A9{1}", this._parent, this._evaluatable);
}
}
public abstract class Tween<T> : Animatable<T>, IEquatable<Tween<T>> {
protected Tween(T begin, T end) {
D.assert(begin != null);
D.assert(end != null);
this.begin = begin;
this.end = end;
}
public readonly T begin;
public readonly T end;
public abstract T lerp(double t);
public override T evaluate(Animation<double> animation) {
double t = animation.value;
if (t == 0.0) {
return this.begin;
}
if (t == 1.0) {
return this.end;
}
return this.lerp(t);
}
public override string ToString() {
return string.Format("{0}({1} \u2192 {2})", this.GetType(), this.begin, this.end);
}
public bool Equals(Tween<T> other) {
if (object.ReferenceEquals(null, other)) return false;
if (object.ReferenceEquals(this, other)) return true;
return EqualityComparer<T>.Default.Equals(this.begin, other.begin) &&
EqualityComparer<T>.Default.Equals(this.end, other.end);
}
public override bool Equals(object obj) {
if (object.ReferenceEquals(null, obj)) return false;
if (object.ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return this.Equals((Tween<T>) obj);
}
public override int GetHashCode() {
unchecked {
return (EqualityComparer<T>.Default.GetHashCode(this.begin) * 397) ^
EqualityComparer<T>.Default.GetHashCode(this.end);
}
}
public static bool operator ==(Tween<T> left, Tween<T> right) {
return object.Equals(left, right);
}
public static bool operator !=(Tween<T> left, Tween<T> right) {
return !object.Equals(left, right);
}
}
public class ReverseTween<T> : Tween<T> {
public ReverseTween(Tween<T> parent) : base(begin: parent.end, end: parent.begin) {
}
public readonly Tween<T> parent;
public override T lerp(double t) {
return this.parent.lerp(1.0 - t);
}
}
public class ColorTween : Tween<Color> {
public ColorTween(Color begin = null, Color end = null) : base(begin: begin, end: end) {
}
public override Color lerp(double t) {
return Color.lerp(this.begin, this.end, t);
}
}
public class SizeTween : Tween<Size> {
public SizeTween(Size begin = null, Size end = null) : base(begin: begin, end: end) {
}
public override Size lerp(double t) {
return Size.lerp(this.begin, this.end, t);
}
}
public class RectTween : Tween<Rect> {
public RectTween(Rect begin = null, Rect end = null) : base(begin: begin, end: end) {
}
public override Rect lerp(double t) {
return Rect.lerp(this.begin, this.end, t);
}
}
public class IntTween : Tween<int> {
public IntTween(int begin, int end) : base(begin: begin, end: end) {
}
public override int lerp(double t) {
return (this.begin + (this.end - this.begin) * t).round();
}
}
public class DoubleTween : Tween<double> {
public DoubleTween(int begin, int end) : base(begin: begin, end: end) {
}
public override double lerp(double t) {
return this.begin + (this.end - this.begin) * t;
}
}
public class StepTween : Tween<int> {
public StepTween(int begin, int end) : base(begin: begin, end: end) {
}
public override int lerp(double t) {
return (this.begin + (this.end - this.begin) * t).floor();
}
}
public class CurveTween : Animatable<double> {
public CurveTween(Curve curve = null) {
D.assert(curve != null);
this.curve = curve;
}
public readonly Curve curve;
public override double evaluate(Animation<double> animation) {
double t = animation.value;
if (t == 0.0 || t == 1.0) {
D.assert(this.curve.transform(t).round() == t);
return t;
}
return this.curve.transform(t);
}
public override string ToString() {
return string.Format("{0}(curve: {1})", this.GetType(), this.curve);
}
}
}

44
Assets/UIWidgets/physics/clamped_simulation.cs


using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.physics {
public class ClampedSimulation : Simulation {
public ClampedSimulation(Simulation simulation,
double xMin = double.NegativeInfinity,
double xMax = double.PositiveInfinity,
double dxMin = double.NegativeInfinity,
double dxMax = double.PositiveInfinity
) {
D.assert(simulation != null);
D.assert(xMax >= xMin);
D.assert(dxMax >= dxMin);
this.simulation = simulation;
this.xMin = xMin;
this.dxMin = dxMin;
this.dxMax = dxMax;
}
public readonly Simulation simulation;
public readonly double xMin;
public readonly double xMax;
public readonly double dxMin;
public readonly double dxMax;
public override double x(double time) {
return this.simulation.x(time).clamp(this.xMin, this.xMax);
}
public override double dx(double time) {
return this.simulation.dx(time).clamp(this.dxMin, this.dxMax);
}
public override bool isDone(double time) {
return this.simulation.isDone(time);
}
}
}

3
Assets/UIWidgets/physics/clamped_simulation.cs.meta


fileFormatVersion: 2
guid: e1b026c0820446e69cc5ec78354b9418
timeCreated: 1536564505

96
Assets/UIWidgets/physics/friction_simulation.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.physics {
public class FrictionSimulation : Simulation {
public FrictionSimulation(
double drag, double position, double velocity,
Tolerance tolerance = null
) : base(tolerance: tolerance) {
this._drag = drag;
this._dragLog = Math.Log(drag);
this._x = position;
this._v = velocity;
}
public static FrictionSimulation through(double startPosition, double endPosition, double startVelocity,
double endVelocity) {
D.assert(startVelocity == 0.0 || endVelocity == 0.0 || startVelocity.sign() == endVelocity.sign());
D.assert(startVelocity.abs() >= endVelocity.abs());
D.assert((endPosition - startPosition).sign() == startVelocity.sign());
return new FrictionSimulation(
FrictionSimulation._dragFor(startPosition, endPosition, startVelocity, endVelocity),
startPosition,
startVelocity,
tolerance: new Tolerance(velocity: endVelocity.abs())
);
}
readonly double _drag;
readonly double _dragLog;
readonly double _x;
readonly double _v;
static double _dragFor(double startPosition, double endPosition, double startVelocity, double endVelocity) {
return Math.Pow(Math.E, (startVelocity - endVelocity) / (startPosition - endPosition));
}
public override double x(double time) {
return this._x + this._v * Math.Pow(this._drag, time) / this._dragLog - this._v / this._dragLog;
}
public override double dx(double time) {
return this._v * Math.Pow(this._drag, time);
}
public double finalX {
get { return this._x - this._v / this._dragLog; }
}
public double timeAtX(double x) {
if (x == this._x) {
return 0.0;
}
if (this._v == 0.0 || (this._v > 0 ? (x < this._x || x > this.finalX) : (x > this._x || x < this.finalX))) {
return double.PositiveInfinity;
}
return Math.Log(this._dragLog * (x - this._x) / this._v + 1.0) / this._dragLog;
}
public override bool isDone(double time) {
return this.dx(time).abs() < this.tolerance.velocity;
}
}
public class BoundedFrictionSimulation : FrictionSimulation {
BoundedFrictionSimulation(
double drag,
double position,
double velocity,
double _minX,
double _maxX
) : base(drag, position, velocity) {
D.assert(position.clamp(_minX, _maxX) == position);
this._minX = _minX;
this._maxX = _maxX;
}
readonly double _minX;
readonly double _maxX;
public override double x(double time) {
return base.x(time).clamp(this._minX, this._maxX);
}
public override bool isDone(double time) {
return base.isDone(time) ||
(this.x(time) - this._minX).abs() < this.tolerance.distance ||
(this.x(time) - this._maxX).abs() < this.tolerance.distance;
}
}
}

3
Assets/UIWidgets/physics/friction_simulation.cs.meta


fileFormatVersion: 2
guid: 1d5938e637654fddb90f71c0d24bb3c2
timeCreated: 1536564777

36
Assets/UIWidgets/physics/gravity_simulation.cs


using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.physics {
public class GravitySimulation : Simulation {
public GravitySimulation(
double acceleration,
double distance,
double endDistance,
double velocity
) {
D.assert(endDistance >= 0);
this._a = acceleration;
this._x = distance;
this._v = velocity;
this._end = endDistance;
}
readonly double _x;
readonly double _v;
readonly double _a;
readonly double _end;
public override double x(double time) {
return this._x + this._v * time + 0.5 * this._a * time * time;
}
public override double dx(double time) {
return this._v + time * this._a;
}
public override bool isDone(double time) {
return this.x(time).abs() >= this._end;
}
}
}

3
Assets/UIWidgets/physics/gravity_simulation.cs.meta


fileFormatVersion: 2
guid: f56308b79b45489b9cac8421a70c6795
timeCreated: 1536566201

15
Assets/UIWidgets/physics/simulation.cs


namespace UIWidgets.physics {
public abstract class Simulation {
protected Simulation(Tolerance tolerance = null) {
this.tolerance = tolerance ?? Tolerance.defaultTolerance;
}
public abstract double x(double time);
public abstract double dx(double time);
public abstract bool isDone(double time);
public Tolerance tolerance;
}
}

11
Assets/UIWidgets/physics/simulation.cs.meta


fileFormatVersion: 2
guid: 2856e502c3bc04fd6b143e53f228f788
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

238
Assets/UIWidgets/physics/spring_simulation.cs


using System;
using UIWidgets.foundation;
namespace UIWidgets.physics {
public class SpringDescription {
public SpringDescription(
double mass,
double stiffness,
double damping
) {
this.mass = mass;
this.stiffness = stiffness;
this.damping = damping;
}
public static SpringDescription withDampingRatio(
double mass,
double stiffness,
double ratio = 1.0
) {
var damping = ratio * 2.0 * Math.Sqrt(mass * stiffness);
return new SpringDescription(mass, stiffness, damping);
}
public readonly double mass;
public readonly double stiffness;
public readonly double damping;
public override string ToString() {
return string.Format("{0}(mass {1:F1}, stiffness: {2:F1}, damping: {3:F1})",
this.GetType(), this.mass, this.stiffness, this.damping);
}
}
public enum SpringType {
criticallyDamped,
underDamped,
overDamped,
}
public class SpringSimulation : Simulation {
public SpringSimulation(
SpringDescription spring,
double start,
double end,
double velocity,
Tolerance tolerance = null
) : base(tolerance: tolerance) {
this._endPosition = end;
this._solution = _SpringSolution.create(spring, start - end, velocity);
}
protected readonly double _endPosition;
readonly _SpringSolution _solution;
public SpringType type {
get { return this._solution.type; }
}
public override double x(double time) {
return this._endPosition + this._solution.x(time);
}
public override double dx(double time) {
return this._solution.dx(time);
}
public override bool isDone(double time) {
return PhysicsUtils.nearZero(this._solution.x(time), this.tolerance.distance) &&
PhysicsUtils.nearZero(this._solution.dx(time), this.tolerance.velocity);
}
public override string ToString() {
return string.Format("{0}(end: {1}, {2}", this.GetType(), this._endPosition, this.type);
}
}
public class ScrollSpringSimulation : SpringSimulation {
public ScrollSpringSimulation(
SpringDescription spring,
double start,
double end,
double velocity,
Tolerance tolerance = null
) : base(spring, start, end, velocity, tolerance: tolerance) {
}
public double x(double time) {
return this.isDone(time) ? this._endPosition : base.x(time);
}
}
abstract class _SpringSolution {
public static _SpringSolution create(
SpringDescription spring,
double initialPosition,
double initialVelocity
) {
D.assert(spring != null);
double cmk = spring.damping * spring.damping - 4 * spring.mass * spring.stiffness;
if (cmk == 0.0) {
return _CriticalSolution.create(spring, initialPosition, initialVelocity);
}
if (cmk > 0.0) {
return _OverdampedSolution.create(spring, initialPosition, initialVelocity);
}
return _UnderdampedSolution.create(spring, initialPosition, initialVelocity);
}
public abstract double x(double time);
public abstract double dx(double time);
public abstract SpringType type { get; }
}
class _CriticalSolution : _SpringSolution {
internal static _CriticalSolution create(
SpringDescription spring,
double distance,
double velocity
) {
double r = -spring.damping / (2.0 * spring.mass);
double c1 = distance;
double c2 = velocity / (r * distance);
return new _CriticalSolution(r, c1, c2);
}
private _CriticalSolution(
double r, double c1, double c2
) {
this._r = r;
this._c1 = c1;
this._c2 = c2;
}
readonly double _r, _c1, _c2;
public override double x(double time) {
return (this._c1 + this._c2 * time) * Math.Pow(Math.E, this._r * time);
}
public override double dx(double time) {
double power = Math.Pow(Math.E, this._r * time);
return this._r * (this._c1 + this._c2 * time) * power + this._c2 * power;
}
public override SpringType type {
get { return SpringType.criticallyDamped; }
}
}
class _OverdampedSolution : _SpringSolution {
internal static _OverdampedSolution create(
SpringDescription spring,
double distance,
double velocity
) {
double cmk = spring.damping * spring.damping - 4 * spring.mass * spring.stiffness;
double r1 = (-spring.damping - Math.Sqrt(cmk)) / (2.0 * spring.mass);
double r2 = (-spring.damping + Math.Sqrt(cmk)) / (2.0 * spring.mass);
double c2 = (velocity - r1 * distance) / (r2 - r1);
double c1 = distance - c2;
return new _OverdampedSolution(r1, r2, c1, c2);
}
private _OverdampedSolution(
double r1, double r2, double c1, double c2
) {
this._r1 = r1;
this._r2 = r2;
this._c1 = c1;
this._c2 = c2;
}
readonly double _r1, _r2, _c1, _c2;
public override double x(double time) {
return this._c1 * Math.Pow(Math.E, this._r1 * time) +
this._c2 * Math.Pow(Math.E, this._r2 * time);
}
public override double dx(double time) {
return this._c1 * this._r1 * Math.Pow(Math.E, this._r1 * time) +
this._c2 * this._r2 * Math.Pow(Math.E, this._r2 * time);
}
public override SpringType type {
get { return SpringType.overDamped; }
}
}
class _UnderdampedSolution : _SpringSolution {
internal static _UnderdampedSolution create(
SpringDescription spring,
double distance,
double velocity
) {
double w = Math.Sqrt(4.0 * spring.mass * spring.stiffness -
spring.damping * spring.damping) / (2.0 * spring.mass);
double r = -(spring.damping / 2.0 * spring.mass);
double c1 = distance;
double c2 = (velocity - r * distance) / w;
return new _UnderdampedSolution(w, r, c1, c2);
}
private _UnderdampedSolution(
double w, double r, double c1, double c2
) {
this._w = w;
this._r = r;
this._c1 = c1;
this._c2 = c2;
}
readonly double _w, _r, _c1, _c2;
public override double x(double time) {
return Math.Pow(Math.E, this._r * time) *
(this._c1 * Math.Cos(this._w * time) + this._c2 * Math.Sin(this._w * time));
}
public override double dx(double time) {
double power = Math.Pow(Math.E, this._r * time);
double cosine = Math.Cos(this._w * time);
double sine = Math.Sin(this._w * time);
return power * (this._c2 * this._w * cosine - this._c1 * this._w * sine) +
this._r * power * (this._c2 * sine + this._c1 * cosine);
}
public override SpringType type {
get { return SpringType.underDamped; }
}
}
}

3
Assets/UIWidgets/physics/spring_simulation.cs.meta


fileFormatVersion: 2
guid: 8ed83c6d32a548d08ba79900e173dd53
timeCreated: 1536566442

28
Assets/UIWidgets/physics/tolerance.cs


namespace UIWidgets.physics {
public class Tolerance {
public Tolerance(
double distance = _epsilonDefault,
double time = _epsilonDefault,
double velocity = _epsilonDefault
) {
this.distance = distance;
this.time = time;
this.velocity = velocity;
}
const double _epsilonDefault = 1e-3;
public static readonly Tolerance defaultTolerance = new Tolerance();
public readonly double distance;
public readonly double time;
public readonly double velocity;
public override string ToString() {
return string.Format("Tolerance(distance: ±{0}, time: ±{1}, velocity: ±{2})",
this.distance, this.time, this.velocity);
}
}
}

3
Assets/UIWidgets/physics/tolerance.cs.meta


fileFormatVersion: 2
guid: 24153b761064430a8482c0388fd41746
timeCreated: 1536564124

14
Assets/UIWidgets/physics/utils.cs


using UIWidgets.foundation;
namespace UIWidgets.physics {
public class PhysicsUtils {
public static bool nearEqual(double a, double b, double epsilon) {
D.assert(epsilon >= 0.0);
return (a > (b - epsilon)) && (a < (b + epsilon)) || a == b;
}
public static bool nearZero(double a, double epsilon) {
return nearEqual(a, 0.0, epsilon);
}
}
}

3
Assets/UIWidgets/physics/utils.cs.meta


fileFormatVersion: 2
guid: e65d36fdcaac4e92a77c930023bfd62f
timeCreated: 1536570487
正在加载...
取消
保存