浏览代码

merge

/main
gewentao 6 年前
当前提交
4fd35765
共有 70 个文件被更改,包括 4224 次插入453 次删除
  1. 14
      Assets/UIWidgets/Tests/Gestures.cs
  2. 8
      Assets/UIWidgets/Tests/Paragraph.cs
  3. 12
      Assets/UIWidgets/Tests/RenderBoxes.cs
  4. 20
      Assets/UIWidgets/Tests/RenderEditable.cs
  5. 8
      Assets/UIWidgets/Tests/Widgets.cs
  6. 85
      Assets/UIWidgets/editor/editor_window.cs
  7. 4
      Assets/UIWidgets/foundation/assertions.cs
  8. 2
      Assets/UIWidgets/foundation/change_notifier.cs
  9. 10
      Assets/UIWidgets/foundation/debug.cs
  10. 139
      Assets/UIWidgets/foundation/diagnostics.cs
  11. 7
      Assets/UIWidgets/gestures/arena.cs
  12. 15
      Assets/UIWidgets/gestures/binding.cs
  13. 2
      Assets/UIWidgets/gestures/constants.cs
  14. 9
      Assets/UIWidgets/gestures/converter.cs
  15. 16
      Assets/UIWidgets/gestures/monodrag.cs
  16. 21
      Assets/UIWidgets/gestures/multitap.cs
  17. 21
      Assets/UIWidgets/gestures/recognizer.cs
  18. 4
      Assets/UIWidgets/gestures/tap.cs
  19. 23
      Assets/UIWidgets/painting/basic_types.cs
  20. 8
      Assets/UIWidgets/physics/utils.cs
  21. 9
      Assets/UIWidgets/promise/Promise.cs
  22. 9
      Assets/UIWidgets/promise/Promise_NonGeneric.cs
  23. 28
      Assets/UIWidgets/rendering/binding.cs
  24. 5
      Assets/UIWidgets/rendering/editable.cs
  25. 46
      Assets/UIWidgets/rendering/object.cs
  26. 6
      Assets/UIWidgets/rendering/object.mixin.gen.cs
  27. 2
      Assets/UIWidgets/rendering/object.mixin.njk
  28. 45
      Assets/UIWidgets/rendering/proxy_box.cs
  29. 33
      Assets/UIWidgets/rendering/sliver_fixed_extent_list.cs
  30. 4
      Assets/UIWidgets/rendering/sliver_list.cs
  31. 6
      Assets/UIWidgets/rendering/sliver_multi_box_adaptor.cs
  32. 6
      Assets/UIWidgets/rendering/sliver_padding.cs
  33. 2
      Assets/UIWidgets/rendering/view.cs
  34. 6
      Assets/UIWidgets/rendering/viewpoint.cs
  35. 6
      Assets/UIWidgets/rendering/viewport_offset.cs
  36. 32
      Assets/UIWidgets/scheduler/binding.cs
  37. 21
      Assets/UIWidgets/scheduler/ticker.cs
  38. 20
      Assets/UIWidgets/ui/window.cs
  39. 155
      Assets/UIWidgets/widgets/basic.cs
  40. 221
      Assets/UIWidgets/widgets/binding.cs
  41. 25
      Assets/UIWidgets/widgets/debug.cs
  42. 42
      Assets/UIWidgets/widgets/framework.cs
  43. 2
      Assets/UIWidgets/widgets/scroll_activity.cs
  44. 16
      Assets/UIWidgets/widgets/scroll_metrics.cs
  45. 497
      Assets/UIWidgets/widgets/scroll_position.cs
  46. 172
      Assets/UIWidgets/widgets/ticker_provider.cs
  47. 31
      Assets/UIWidgets/gestures/long_press.cs
  48. 3
      Assets/UIWidgets/gestures/long_press.cs.meta
  49. 206
      Assets/UIWidgets/rendering/automatic_keep_alive.cs
  50. 3
      Assets/UIWidgets/rendering/automatic_keep_alive.cs.meta
  51. 380
      Assets/UIWidgets/widgets/gesture_detector.cs
  52. 3
      Assets/UIWidgets/widgets/gesture_detector.cs.meta
  53. 144
      Assets/UIWidgets/widgets/page_storage.cs
  54. 3
      Assets/UIWidgets/widgets/page_storage.cs.meta
  55. 45
      Assets/UIWidgets/widgets/primary_scroll_controller.cs
  56. 3
      Assets/UIWidgets/widgets/primary_scroll_controller.cs.meta
  57. 58
      Assets/UIWidgets/widgets/scroll_configuration.cs
  58. 3
      Assets/UIWidgets/widgets/scroll_configuration.cs.meta
  59. 192
      Assets/UIWidgets/widgets/scroll_controller.cs
  60. 3
      Assets/UIWidgets/widgets/scroll_controller.cs.meta
  61. 205
      Assets/UIWidgets/widgets/scroll_position_with_single_context.cs
  62. 3
      Assets/UIWidgets/widgets/scroll_position_with_single_context.cs.meta
  63. 437
      Assets/UIWidgets/widgets/scroll_view.cs
  64. 3
      Assets/UIWidgets/widgets/scroll_view.cs.meta
  65. 391
      Assets/UIWidgets/widgets/scrollable.cs
  66. 3
      Assets/UIWidgets/widgets/scrollable.cs.meta
  67. 519
      Assets/UIWidgets/widgets/sliver.cs
  68. 3
      Assets/UIWidgets/widgets/sliver.cs.meta
  69. 189
      Assets/UIWidgets/widgets/viewport.cs
  70. 3
      Assets/UIWidgets/widgets/viewport.cs.meta

14
Assets/UIWidgets/Tests/Gestures.cs


private WindowAdapter windowAdapter;
private RendererBindings rendererBindings;
[NonSerialized] private bool hasInvoked = false;
void OnGUI() {

this.hasInvoked = true;
var renderBox = this._options[this._selected]();
this.rendererBindings.setRoot(renderBox);
if (this.windowAdapter != null) {
this.windowAdapter.attachRootRenderBox(renderBox);
}
}
if (this.windowAdapter != null) {

private void OnEnable() {
this.windowAdapter = new WindowAdapter(this);
this.rendererBindings = new RendererBindings(this.windowAdapter);
this._tapRecognizer = new TapGestureRecognizer(this.rendererBindings.rendererBinding);
this._tapRecognizer = new TapGestureRecognizer();
this._panRecognizer = new PanGestureRecognizer(this.rendererBindings.rendererBinding);
this._panRecognizer = new PanGestureRecognizer();
this._doubleTapGesture = new DoubleTapGestureRecognizer(this.rendererBindings.rendererBinding);
this._doubleTapGesture = new DoubleTapGestureRecognizer();
this.rendererBindings = null;
}
TapGestureRecognizer _tapRecognizer;

8
Assets/UIWidgets/Tests/Paragraph.cs


private WindowAdapter windowAdapter;
private RendererBindings rendererBindings;
[NonSerialized] private bool hasInvoked = false;
void OnGUI() {

this.hasInvoked = true;
var renderBox = this._options[this._selected]();
this.rendererBindings.setRoot(renderBox);
if (this.windowAdapter != null) {
this.windowAdapter.attachRootRenderBox(renderBox);
}
}
if (this.windowAdapter != null) {

private void OnEnable() {
this.windowAdapter = new WindowAdapter(this);
this.rendererBindings = new RendererBindings(this.windowAdapter);
this.rendererBindings = null;
}
RenderBox none() {

12
Assets/UIWidgets/Tests/RenderBoxes.cs


private WindowAdapter windowAdapter;
private RendererBindings rendererBindings;
[NonSerialized] private bool hasInvoked = false;
void OnGUI() {

this.hasInvoked = true;
var renderBox = this._options[this._selected]();
this.rendererBindings.setRoot(renderBox);
if (this.windowAdapter != null) {
this.windowAdapter.attachRootRenderBox(renderBox);
}
}
void Update() {

private void OnEnable() {
this.windowAdapter = new WindowAdapter(this);
this.rendererBindings = new RendererBindings(this.windowAdapter);
this.rendererBindings = null;
}
RenderBox none() {

color: new Color(0xFF00FFFF)
)
)));
flexbox.add(new RenderConstrainedBox(
additionalConstraints: new BoxConstraints(minWidth: 50, minHeight: 100),
child: new RenderDecoratedBox(

)));
return flexbox;
}

20
Assets/UIWidgets/Tests/RenderEditable.cs


using UIWidgets.rendering;
using UIWidgets.service;
using UIWidgets.ui;
using UnityEditor;
using FontStyle = UIWidgets.ui.FontStyle;
namespace UIWidgets.Tests
{

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

private WindowAdapter windowAdapter;
private RendererBindings rendererBindings;
[NonSerialized] private bool hasInvoked = false;
void OnGUI() {

this.hasInvoked = true;
var renderBox = this._options[this._selected]();
this.rendererBindings.setRoot(renderBox);
if (this.windowAdapter != null) {
this.windowAdapter.attachRootRenderBox(renderBox);
}
}
if (this.windowAdapter != null) {

private void OnEnable() {
this.windowAdapter = new WindowAdapter(this);
this.rendererBindings = new RendererBindings(this.windowAdapter);
this.rendererBindings = null;
}
private RenderBox box(RenderBox p, int width = 400, int height = 400)

flexbox.add(flexItemBox(
new rendering.RenderEditable(span, TextDirection.ltr,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true), this.rendererBindings.rendererBinding,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true),
onSelectionChanged: selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0),
maxLines: 100,
selectionColor: Color.fromARGB(255, 255, 0, 0))

}, style:new painting.TextStyle(height:1.0));
flexbox.add(flexItemBox(
new rendering.RenderEditable(span, TextDirection.ltr,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true), this.rendererBindings.rendererBinding,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true),
onSelectionChanged: selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0),
maxLines: 100,
selectionColor: Color.fromARGB(255, 255, 0, 0))

}, style:new painting.TextStyle(height:1.0));
flexbox.add(flexItemBox(
new rendering.RenderEditable(span, TextDirection.ltr,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true), this.rendererBindings.rendererBinding,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true),
onSelectionChanged: selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0),
selectionColor: Color.fromARGB(255, 255, 0, 0))
, width:300));

8
Assets/UIWidgets/Tests/Widgets.cs


public class Widgets : EditorWindow {
private WindowAdapter windowAdapter;
private WidgetsBindings widgetsBindings;
private PaintingBinding paintingBinding;
private readonly Func<Widget>[] _options;

var rootWidget = this._options[this._selected]();
if (widgetsBindings != null) {
widgetsBindings.attachRootWidget(rootWidget);
}
this.windowAdapter.attachRootWidget(rootWidget);
}
if (this.windowAdapter != null) {

this.paintingBinding = new PaintingBinding(null);
paintingBinding.initInstances();
this.windowAdapter = new WindowAdapter(this);
this.widgetsBindings = new WidgetsBindings(windowAdapter);
this.widgetsBindings = null;
}
Widget flexRow() {

85
Assets/UIWidgets/editor/editor_window.cs


using System.Diagnostics;
using UIWidgets.async;
using UIWidgets.flow;
using UIWidgets.rendering;
using UIWidgets.widgets;
using UnityEditor;
using UnityEngine;
using Rect = UnityEngine.Rect;

public WindowAdapter(EditorWindow editorWindow) {
this.editorWindow = editorWindow;
this.editorWindow.wantsMouseMove = false;
this.editorWindow.wantsMouseEnterLeaveWindow = false;
this._editorWindow = editorWindow;
this._editorWindow.wantsMouseMove = false;
this._editorWindow.wantsMouseEnterLeaveWindow = false;
this._lastPosition.width * EditorGUIUtility.pixelsPerPoint,
this._lastPosition.width * EditorGUIUtility.pixelsPerPoint,
Window.instance = this;
try {
this._binding = new WidgetsBinding();
}
finally {
Window.instance = null;
}
public readonly EditorWindow editorWindow;
readonly EditorWindow _editorWindow;
readonly WidgetsBinding _binding;
Rect _lastPosition;
readonly DateTime _epoch = new DateTime(Stopwatch.GetTimestamp());
readonly MicrotaskQueue _microtaskQueue = new MicrotaskQueue();

Window.instance = this;
WidgetsBinding.instance = this._binding;
try {
this.doOnGUI();
}
finally {
Window.instance = null;
WidgetsBinding.instance = null;
}
}
private void doOnGUI() {
var evt = Event.current;
if (evt.type == EventType.Repaint) {

}
public void Update() {
Window.instance = this;
WidgetsBinding.instance = this._binding;
try {
this.doUpdate();
}
finally {
Window.instance = null;
WidgetsBinding.instance = null;
}
}
private void doUpdate() {
this.flushMicrotasks();
this._timerProvider.update();

dirty = true;
}
if (this._lastPosition != this.editorWindow.position) {
if (this._lastPosition != this._editorWindow.position) {
this._lastPosition = this.editorWindow.position;
this._lastPosition = this._editorWindow.position;
this._physicalSize = new Size(
this._lastPosition.width * EditorGUIUtility.pixelsPerPoint,
this._lastPosition.height * EditorGUIUtility.pixelsPerPoint);

}
public override void scheduleFrame() {
if (this.editorWindow != null) {
this.editorWindow.Repaint();
if (this._editorWindow != null) {
this._editorWindow.Repaint();
}
}

public override Timer run(TimeSpan duration, Action callback) {
return this._timerProvider.run(duration, callback);
}
public void attachRootRenderBox(RenderBox root) {
Window.instance = this;
WidgetsBinding.instance = this._binding;
try {
this._binding.renderView.child = root;
}
finally {
Window.instance = null;
WidgetsBinding.instance = null;
}
}
public void attachRootWidget(Widget root) {
Window.instance = this;
WidgetsBinding.instance = this._binding;
try {
this._binding.attachRootWidget(root);
}
finally {
Window.instance = null;
WidgetsBinding.instance = null;
}
}
}
}

4
Assets/UIWidgets/foundation/assertions.cs


}
if (_errorCount == 0 || forceReport) {
Debug.Log(details.ToString());
Debug.LogError(details.ToString());
Debug.Log("Another exception was thrown: " + details.exceptionAsString());
Debug.LogWarning("Another exception was thrown: " + details.exceptionAsString());
}
_errorCount += 1;

2
Assets/UIWidgets/foundation/change_notifier.cs


this._listeners = null;
}
protected void notifyListeners() {
protected virtual void notifyListeners() {
D.assert(this._debugAssertNotDisposed());
if (this._listeners != null) {
var localListeners = new List<VoidCallback>(this._listeners);

10
Assets/UIWidgets/foundation/debug.cs


public static bool debugPrintGestureArenaDiagnostics = true;
public static bool debugPrintHitTestResults = true;
public static bool debugPrintHitTestResults = false;
public static bool debugPrintRecognizerCallbacksTrace = true;
public static bool debugPrintRecognizerCallbacksTrace = false;
public static bool debugPrintBeginFrameBanner = true;
public static bool debugPrintBeginFrameBanner = false;
public static bool debugPrintEndFrameBanner = true;
public static bool debugPrintEndFrameBanner = false;
public static bool debugPrintScheduleFrameStacks = true;
public static bool debugPrintScheduleFrameStacks = false;
}
[Serializable]

139
Assets/UIWidgets/foundation/diagnostics.cs


}
}
public abstract class _NumProperty<T> : DiagnosticsProperty<T> {
internal _NumProperty(string name,
T value,
string ifNull = null,
string unit = null,
bool showName = true,
Object defaultValue = null,
string tooltip = null,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
value,
ifNull: ifNull,
showName: showName,
defaultValue: defaultValue,
tooltip: tooltip,
level: level
) {
this.unit = unit;
}
internal _NumProperty(string name,
ComputePropertyValueCallback<T> computeValue,
string ifNull = null,
string unit = null,
bool showName = true,
object defaultValue = null,
string tooltip = null,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
computeValue,
ifNull: ifNull,
showName: showName,
defaultValue: defaultValue,
tooltip: tooltip,
level: level
) {
this.unit = unit;
}
public override Dictionary<string, object> toJsonMap() {
var json = base.toJsonMap();
if (this.unit != null) {
json["unit"] = this.unit;
}
json["numberToString"] = this.numberToString();
return json;
}
public readonly string unit;
protected abstract string numberToString();
protected override string valueToString(TextTreeConfiguration parentConfiguration = null) {
if (this.value == null) {
return "null";
}
return this.unit != null ? this.numberToString() + this.unit : this.numberToString();
}
}
public class DoubleProperty : _NumProperty<double?> {
public DoubleProperty(string name, double? value,
string ifNull = null,
string unit = null,
string tooltip = null,
object defaultValue = null,
bool showName = true,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
value,
ifNull: ifNull,
unit: unit,
tooltip: tooltip,
defaultValue: defaultValue,
showName: showName,
level: level
) {
}
private DoubleProperty(
string name,
ComputePropertyValueCallback<double?> computeValue,
string ifNull = null,
bool showName = true,
string unit = null,
string tooltip = null,
object defaultValue = null,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
computeValue,
showName: showName,
ifNull: ifNull,
unit: unit,
tooltip: tooltip,
defaultValue: defaultValue,
level: level
) {
}
public static DoubleProperty lazy(
string name,
ComputePropertyValueCallback<double?> computeValue,
string ifNull = null,
bool showName = true,
string unit = null,
string tooltip = null,
object defaultValue = null,
DiagnosticLevel level = DiagnosticLevel.info
) {
return new DoubleProperty(
name,
computeValue,
showName: showName,
ifNull: ifNull,
unit: unit,
tooltip: tooltip,
defaultValue: defaultValue,
level: level
);
}
protected override string numberToString() {
if (this.value != null) {
return this.value.Value.ToString("F1");
}
return "null";
}
}
public class FlagProperty : DiagnosticsProperty<bool> {
public FlagProperty(String name,
bool value,

this.missingIfNull = missingIfNull;
}
private DiagnosticsProperty(
internal DiagnosticsProperty(
string name,
ComputePropertyValueCallback<T> computeValue,
string description = null,

7
Assets/UIWidgets/gestures/arena.cs


public class GestureArenaManager {
readonly Dictionary<int, _GestureArena> _arenas = new Dictionary<int, _GestureArena>();
readonly Window _window;
public GestureArenaManager(Window window) {
this._window = window;
}
public GestureArenaEntry add(int pointer, GestureArenaMember member) {
_GestureArena state = this._arenas.putIfAbsent(pointer, () => {

D.assert(!state.isOpen);
if (state.members.Count == 1) {
this._window.scheduleMicrotask(() => this._resolveByDefault(pointer, state));
Window.instance.scheduleMicrotask(() => this._resolveByDefault(pointer, state));
} else if (state.members.isEmpty()) {
this._arenas.Remove(pointer);
D.assert(this._debugLogDiagnostic(pointer, "Arena empty."));

15
Assets/UIWidgets/gestures/binding.cs


namespace UIWidgets.gestures {
public class GestureBinding : SchedulerBinding, HitTestable, HitTestDispatcher, HitTestTarget {
public GestureBinding(Window window) : base(window) {
this.window.onPointerEvent += this._handlePointerDataPacket;
public static new GestureBinding instance {
get { return (GestureBinding) SchedulerBinding.instance; }
set { SchedulerBinding.instance = value; }
}
public GestureBinding() {
Window.instance.onPointerEvent += this._handlePointerDataPacket;
this.gestureArena = new GestureArenaManager(window);
this.gestureArena = new GestureArenaManager();
foreach (var pointerEvent in PointerEventConverter.expand(packet.data, this.window.devicePixelRatio)) {
foreach (var pointerEvent in PointerEventConverter.expand(packet.data, Window.instance.devicePixelRatio)) {
this._pendingPointerEvents.Enqueue(pointerEvent);
}

public void cancelPointer(int pointer) {
if (this._pendingPointerEvents.isEmpty()) {
this.window.scheduleMicrotask(this._flushPointerEventQueue);
Window.instance.scheduleMicrotask(this._flushPointerEventQueue);
}
this._pendingPointerEvents.Enqueue(

2
Assets/UIWidgets/gestures/constants.cs


public static readonly TimeSpan kPressTimeout = new TimeSpan(0, 0, 0, 0, 100);
public static readonly TimeSpan kDoubleTapTimeout = new TimeSpan(0, 0, 0, 0, 300);
public static readonly TimeSpan kLongPressTimeout = new TimeSpan(0, 0, 0, 0, 500);
public const double kMinFlingVelocity = 50.0;

9
Assets/UIWidgets/gestures/converter.cs


}
break;
case PointerChange.move: {
bool alreadyAdded = _pointers.ContainsKey(datum.device);
if (!alreadyAdded) {
break;
}
if (!state.down) {
break;
}
Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield return new PointerMoveEvent(

16
Assets/UIWidgets/gestures/monodrag.cs


public delegate void GestureDragCancelCallback();
public abstract class DragGestureRecognizer : OneSequenceGestureRecognizer {
public DragGestureRecognizer(GestureBinding binding, object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
public DragGestureRecognizer(object debugOwner = null)
: base(debugOwner: debugOwner) {
}
public GestureDragDownCallback onDown;

}
public class VerticalDragGestureRecognizer : DragGestureRecognizer {
public VerticalDragGestureRecognizer(GestureBinding binding, Object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
public VerticalDragGestureRecognizer(Object debugOwner = null)
: base(debugOwner: debugOwner) {
}
protected override bool _isFlingGesture(VelocityEstimate estimate) {

}
public class HorizontalDragGestureRecognizer : DragGestureRecognizer {
public HorizontalDragGestureRecognizer(GestureBinding binding, Object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
public HorizontalDragGestureRecognizer(Object debugOwner = null)
: base(debugOwner: debugOwner) {
}
protected override bool _isFlingGesture(VelocityEstimate estimate) {

}
public class PanGestureRecognizer : DragGestureRecognizer {
public PanGestureRecognizer(GestureBinding binding, Object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
public PanGestureRecognizer(Object debugOwner = null)
: base(debugOwner: debugOwner) {
}
protected override bool _isFlingGesture(VelocityEstimate estimate) {

21
Assets/UIWidgets/gestures/multitap.cs


class _TapTracker {
internal _TapTracker(
GestureBinding binding = null,
this._binding = binding;
this.pointer = evt.pointer;
this._initialPosition = evt.position;
this.entry = entry;

public readonly GestureArenaEntry entry;
readonly Offset _initialPosition;
readonly GestureBinding _binding;
bool _isTrackingPointer = false;

this._binding.pointerRouter.addRoute(this.pointer, route);
GestureBinding.instance.pointerRouter.addRoute(this.pointer, route);
}
}

this._binding.pointerRouter.removeRoute(this.pointer, route);
GestureBinding.instance.pointerRouter.removeRoute(this.pointer, route);
}
}

}
public class DoubleTapGestureRecognizer : GestureRecognizer {
public DoubleTapGestureRecognizer(
GestureBinding binding = null, object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
public DoubleTapGestureRecognizer(object debugOwner = null)
: base(debugOwner: debugOwner) {
}
public GestureDoubleTapCallback onDoubleTap;

this._stopDoubleTapTimer();
_TapTracker tracker = new _TapTracker(
binding: this._binding,
entry: this._binding.gestureArena.add(evt.pointer, this)
entry: GestureBinding.instance.gestureArena.add(evt.pointer, this)
);
this._trackers[evt.pointer] = tracker;
tracker.startTrackingPointer(this._handleEvent);

_TapTracker tracker = this._firstTap;
this._firstTap = null;
this._reject(tracker);
this._binding.gestureArena.release(tracker.pointer);
GestureBinding.instance.gestureArena.release(tracker.pointer);
}
this._clearTrackers();

this._startDoubleTapTimer();
this._binding.gestureArena.hold(tracker.pointer);
GestureBinding.instance.gestureArena.hold(tracker.pointer);
this._freezeTracker(tracker);
this._trackers.Remove(tracker.pointer);
this._clearTrackers();

void _startDoubleTapTimer() {
this._doubleTapTimer =
this._doubleTapTimer
?? this._binding.window.run(Constants.kDoubleTapTimeout, this._reset);
?? Window.instance.run(Constants.kDoubleTapTimeout, this._reset);
}
void _stopDoubleTapTimer() {

21
Assets/UIWidgets/gestures/recognizer.cs


public delegate T RecognizerCallback<T>();
public abstract class GestureRecognizer : DiagnosticableTree, GestureArenaMember {
protected GestureRecognizer(GestureBinding binding = null, object debugOwner = null) {
this._binding = binding;
protected GestureRecognizer(object debugOwner = null) {
protected readonly GestureBinding _binding;
public readonly object debugOwner;

}
public abstract class OneSequenceGestureRecognizer : GestureRecognizer {
protected OneSequenceGestureRecognizer(
GestureBinding binding = null, object debugOwner = null) : base(binding, debugOwner) {
protected OneSequenceGestureRecognizer(object debugOwner = null) : base(debugOwner) {
}
readonly Dictionary<int, GestureArenaEntry> _entries = new Dictionary<int, GestureArenaEntry>();

public override void dispose() {
this.resolve(GestureDisposition.rejected);
foreach (int pointer in this._trackedPointers) {
this._binding.pointerRouter.removeRoute(pointer, this.handleEvent);
GestureBinding.instance.pointerRouter.removeRoute(pointer, this.handleEvent);
}
this._trackedPointers.Clear();

return this._team.add(pointer, this);
}
return this._binding.gestureArena.add(pointer, this);
return GestureBinding.instance.gestureArena.add(pointer, this);
this._binding.pointerRouter.addRoute(pointer, this.handleEvent);
GestureBinding.instance.pointerRouter.addRoute(pointer, this.handleEvent);
this._trackedPointers.Add(pointer);
D.assert(!this._entries.ContainsKey(pointer));
this._entries[pointer] = this._addPointerToArena(pointer);

if (this._trackedPointers.Contains(pointer)) {
this._binding.pointerRouter.removeRoute(pointer, this.handleEvent);
GestureBinding.instance.pointerRouter.removeRoute(pointer, this.handleEvent);
this._trackedPointers.Remove(pointer);
if (this._trackedPointers.isEmpty()) {
this.didStopTrackingLastPointer(pointer);

public abstract class PrimaryPointerGestureRecognizer : OneSequenceGestureRecognizer {
protected PrimaryPointerGestureRecognizer(
TimeSpan? deadline = null,
GestureBinding binding = null,
) : base(binding: binding, debugOwner: debugOwner) {
) : base(debugOwner: debugOwner) {
this.deadline = deadline;
}

this.primaryPointer = evt.pointer;
this.initialPosition = evt.position;
if (this.deadline != null) {
this._timer = this._binding.window.run(this.deadline.Value, this.didExceedDeadline);
this._timer = Window.instance.run(this.deadline.Value, this.didExceedDeadline);
}
}
}

4
Assets/UIWidgets/gestures/tap.cs


public delegate void GestureTapCancelCallback();
public class TapGestureRecognizer : PrimaryPointerGestureRecognizer {
public TapGestureRecognizer(GestureBinding binding, object debugOwner = null)
: base(deadline: Constants.kPressTimeout, binding: binding, debugOwner: debugOwner) {
public TapGestureRecognizer(object debugOwner = null)
: base(deadline: Constants.kPressTimeout, debugOwner: debugOwner) {
}
public GestureTapDownCallback onTapDown;

23
Assets/UIWidgets/painting/basic_types.cs


using System;
using System.ComponentModel;
using UIWidgets.foundation;
using UIWidgets.widgets;
namespace UIWidgets.painting {
public enum AxisDirection {

throw new Exception("unknown axisDirection");
}
public static AxisDirection getAxisDirectionFromAxisReverseAndDirectionality(
BuildContext context,
Axis axis,
bool reverse
) {
switch (axis) {
case Axis.horizontal:
D.assert(WidgetsD.debugCheckHasDirectionality(context));
TextDirection textDirection = Directionality.of(context);
AxisDirection axisDirection = textDirectionToAxisDirection(textDirection);
return reverse ? flipAxisDirection(axisDirection) : axisDirection;
case Axis.vertical:
return reverse ? AxisDirection.up : AxisDirection.down;
}
throw new Exception("unknown axisDirection");
}
public enum RenderComparison
{
public enum RenderComparison {
identical,
metadata,
paint,

8
Assets/UIWidgets/physics/utils.cs


namespace UIWidgets.physics {
public class PhysicsUtils {
public static bool nearEqual(double a, double b, double epsilon) {
public static bool nearEqual(double? a, double? b, double epsilon) {
if (a == null || b == null) {
return a == b;
}
public static bool nearZero(double a, double epsilon) {
public static bool nearZero(double? a, double epsilon) {
return nearEqual(a, 0.0, epsilon);
}
}

9
Assets/UIWidgets/promise/Promise.cs


using System.Collections.Generic;
using System.Linq;
using RSG.Exceptions;
using UIWidgets.ui;
namespace RSG
{

{
if (CurState == PromiseState.Resolved)
{
InvokeHandler(resolveHandler, resultPromise, resolveValue);
Window.instance.scheduleMicrotask(() => {
InvokeHandler(resolveHandler, resultPromise, resolveValue);
});
InvokeHandler(rejectHandler, resultPromise, rejectionException);
Window.instance.scheduleMicrotask(() => {
InvokeHandler(rejectHandler, resultPromise, rejectionException);
});
}
else
{

9
Assets/UIWidgets/promise/Promise_NonGeneric.cs


using System.Collections.Generic;
using System.Linq;
using RSG.Exceptions;
using UIWidgets.ui;
namespace RSG
{

PendingPromises.Remove(this);
}
InvokeRejectHandlers(ex);
Window.instance.scheduleMicrotask(() => {
InvokeRejectHandlers(ex);
});
}

PendingPromises.Remove(this);
}
InvokeResolveHandlers();
Window.instance.scheduleMicrotask(() => {
InvokeResolveHandlers();
});
}

28
Assets/UIWidgets/rendering/binding.cs


namespace UIWidgets.rendering {
public class RendererBinding : GestureBinding {
public RendererBinding(Window window) : base(window) {
public static new RendererBinding instance {
get { return (RendererBinding) GestureBinding.instance; }
set { GestureBinding.instance = value; }
}
public RendererBinding() {
binding: this,
window.onMetricsChanged += this.handleMetricsChanged;
Window.instance.onMetricsChanged += this.handleMetricsChanged;
this.initRenderView();
D.assert(this.renderView != null);
this.addPersistentFrameCallback(this._handlePersistentFrameCallback);

}
protected virtual ViewConfiguration createViewConfiguration() {
var devicePixelRatio = this.window.devicePixelRatio;
var devicePixelRatio = Window.instance.devicePixelRatio;
size: this.window.physicalSize / devicePixelRatio,
size: Window.instance.physicalSize / devicePixelRatio,
devicePixelRatio: devicePixelRatio
);
}

D.assert(this.renderView != null);
this.renderView.hitTest(result, position: position);
base.hitTest(result, position);
}
}
public class RendererBindings {
public RendererBindings(Window window) {
this.window = window;
this.rendererBinding = new RendererBinding(window);
}
public readonly Window window;
public readonly RendererBinding rendererBinding;
public void setRoot(RenderBox root) {
this.rendererBinding.renderView.child = root;
}
}
}

5
Assets/UIWidgets/rendering/editable.cs


public RenderEditable(TextSpan text, TextDirection textDirection, ViewportOffset offset,
ValueNotifier<bool> showCursor,
GestureBinding binding,
TextAlign textAlign = TextAlign.left, double textScaleFactor = 1.0, Color cursorColor = null,
bool? hasFocus = null, int maxLines = 1, Color selectionColor = null,
TextSelection selection = null, bool obscureText = false, SelectionChangedHandler onSelectionChanged = null,

D.assert(_showCursor != null);
D.assert(!_showCursor.value || cursorColor != null);
_tap = new TapGestureRecognizer(binding, this);
_doubleTap = new DoubleTapGestureRecognizer(binding, this);
_tap = new TapGestureRecognizer(this);
_doubleTap = new DoubleTapGestureRecognizer(this);
_tap.onTapDown = this._handleTapDown;
_tap.onTap = this._handleTap;
_doubleTap.onDoubleTap = this._handleDoubleTap;

46
Assets/UIWidgets/rendering/object.cs


public class PipelineOwner {
public PipelineOwner(
RendererBinding binding = null,
this.binding = binding;
public readonly RendererBinding binding;
public readonly VoidCallback onNeedVisualUpdate;

public List<RenderObject> _nodesNeedingLayout = new List<RenderObject>();
public bool debugDoingLayout {
get { return this._debugDoingLayout; }
}
bool _debugDoingLayout = false;
while (this._nodesNeedingLayout.Count > 0) {
var dirtyNodes = this._nodesNeedingLayout;
this._nodesNeedingLayout = new List<RenderObject>();
dirtyNodes.Sort((a, b) => a.depth - b.depth);
foreach (var node in dirtyNodes) {
if (node._needsLayout && node.owner == this) {
node._layoutWithoutResize();
D.assert(() => {
this._debugDoingLayout = true;
return true;
});
try {
while (this._nodesNeedingLayout.Count > 0) {
var dirtyNodes = this._nodesNeedingLayout;
this._nodesNeedingLayout = new List<RenderObject>();
dirtyNodes.Sort((a, b) => a.depth - b.depth);
foreach (var node in dirtyNodes) {
if (node._needsLayout && node.owner == this) {
node._layoutWithoutResize();
}
}
finally {
D.assert(() => {
this._debugDoingLayout = false;
return true;
});
}
}

}
public interface RenderObjectWithChildMixin {
bool debugValidateChild(RenderObject child);
bool debugValidateChild(RenderObject child);
public interface RenderObjectWithChildMixin<ChildType> : RenderObjectWithChildMixin
where ChildType : RenderObject {
new ChildType child { get; set; }
}
public interface ContainerParentDataMixin<ChildType> where ChildType : RenderObject {
ChildType previousSibling { get; set; }
ChildType nextSibling { get; set; }

6
Assets/UIWidgets/rendering/object.mixin.gen.cs


namespace UIWidgets.rendering {
public abstract class RenderObjectWithChildMixinRenderObject<ChildType> : RenderObject, RenderObjectWithChildMixin where ChildType : RenderObject {
public abstract class RenderObjectWithChildMixinRenderObject<ChildType> : RenderObject, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {

}
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox, RenderObjectWithChildMixin where ChildType : RenderObject {
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {

}
public abstract class RenderObjectWithChildMixinRenderSliver<ChildType> : RenderSliver, RenderObjectWithChildMixin where ChildType : RenderObject {
public abstract class RenderObjectWithChildMixinRenderSliver<ChildType> : RenderSliver, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {

2
Assets/UIWidgets/rendering/object.mixin.njk


namespace UIWidgets.rendering {
{% macro RenderObjectWithChildMixin(with) %}
public abstract class RenderObjectWithChildMixin{{with}}<ChildType> : {{with}}, RenderObjectWithChildMixin where ChildType : RenderObject {
public abstract class RenderObjectWithChildMixin{{with}}<ChildType> : {{with}}, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {

45
Assets/UIWidgets/rendering/proxy_box.cs


if (didNeedCompositing != alwaysNeedsCompositing) {
markNeedsCompositingBitsUpdate();
}
markNeedsPaint();
}
}

context.paintChild(child, offset);
return;
}
}
public class RenderRepaintBoundary : RenderProxyBox {
public RenderRepaintBoundary(
RenderBox child = null
) : base(child) {
}
public override bool isRepaintBoundary {
get { return true; }
}
}
public class RenderIgnorePointer : RenderProxyBox {
public RenderIgnorePointer(
RenderBox child = null,
bool ignoring = true
) : base(child) {
this._ignoring = ignoring;
}
public bool ignoring {
get { return this._ignoring; }
set {
if (value == this._ignoring) {
return;
}
this._ignoring = value;
}
}
bool _ignoring;
public override bool hitTest(HitTestResult result, Offset position = null) {
return this.ignoring ? false : base.hitTest(result, position: position);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<bool>("ignoring", this.ignoring));
}
}
}

33
Assets/UIWidgets/rendering/sliver_fixed_extent_list.cs


namespace UIWidgets.rendering {
public abstract class RenderSliverFixedExtentBoxAdaptor : RenderSliverMultiBoxAdaptor {
RenderSliverFixedExtentBoxAdaptor(
protected RenderSliverFixedExtentBoxAdaptor(
public abstract double itemExtent { get; }
public abstract double itemExtent { get; set; }
public double indexToLayoutOffset(double itemExtent, int index) {
return itemExtent * index;

return itemExtent > 0.0 ? Math.Max(0, (int) Math.Ceiling(scrollOffset / itemExtent) - 1) : 0;
}
public double estimateMaxScrollOffset(SliverConstraints constraints,
public double? estimateMaxScrollOffset(SliverConstraints constraints,
int firstIndex = 0,
int lastIndex = 0,
double leadingScrollOffset = 0.0,

}
public double computeMaxScrollOffset(SliverConstraints constraints, double itemExtent) {
return this.childManager.childCount * itemExtent;
return this.childManager.childCount.Value * itemExtent;
}

lastIndex: lastIndex,
leadingScrollOffset: leadingScrollOffset,
trailingScrollOffset: trailingScrollOffset
);
).Value;
double paintExtent = this.calculatePaintOffset(
this.constraints,

this.childManager.didFinishLayout();
}
}
public class RenderSliverFixedExtentList : RenderSliverFixedExtentBoxAdaptor {
public RenderSliverFixedExtentList(
RenderSliverBoxChildManager childManager = null,
double itemExtent = 0.0
) : base(childManager: childManager) {
this._itemExtent = itemExtent;
}
public override double itemExtent {
get { return this._itemExtent; }
set {
if (this._itemExtent == value) {
return;
}
this._itemExtent = value;
this.markNeedsLayout();
}
}
double _itemExtent;
}
}

4
Assets/UIWidgets/rendering/sliver_list.cs


namespace UIWidgets.rendering {
public class RenderSliverList : RenderSliverMultiBoxAdaptor {
RenderSliverList(
public RenderSliverList(
RenderSliverBoxChildManager childManager = null
) : base(childManager: childManager) {
}

lastIndex: this.indexOf(this.lastChild),
leadingScrollOffset: this.childScrollOffset(this.firstChild),
trailingScrollOffset: endScrollOffset
);
).Value;
}
double paintExtent = this.calculatePaintOffset(

6
Assets/UIWidgets/rendering/sliver_multi_box_adaptor.cs


void removeChild(RenderBox child);
double estimateMaxScrollOffset(
double? estimateMaxScrollOffset(
SliverConstraints constraints,
int firstIndex = 0,
int lastIndex = 0,

int childCount { get; }
int? childCount { get; }
void didAdoptChild(RenderBox child);

void didFinishLayout();
bool debugAssertChildListLocked();
}
public class SliverMultiBoxAdaptorParentData : ContainerParentDataMixinSliverLogicalParentData<RenderBox> {

6
Assets/UIWidgets/rendering/sliver_padding.cs


namespace UIWidgets.rendering {
public class RenderSliverPadding : RenderObjectWithChildMixinRenderSliver<RenderSliver> {
RenderSliverPadding(
EdgeInsets padding,
RenderSliver child
public RenderSliverPadding(
EdgeInsets padding = null,
RenderSliver child = null
) {
this._padding = padding;
this.child = child;

2
Assets/UIWidgets/rendering/view.cs


var builder = new SceneBuilder();
this.layer.addToScene(builder, Offset.zero);
var scene = builder.build();
this.owner.binding.window.render(scene);
Window.instance.render(scene);
}
public override Rect paintBounds {

6
Assets/UIWidgets/rendering/viewpoint.cs


AxisDirection axisDirection = AxisDirection.down,
AxisDirection crossAxisDirection = AxisDirection.right,
ViewportOffset offset = null,
double cacheExtent = RenderAbstractViewportUtils.defaultCacheExtent
double? cacheExtent = null
this._cacheExtent = cacheExtent;
this._cacheExtent = cacheExtent ?? RenderAbstractViewportUtils.defaultCacheExtent;
}
public AxisDirection axisDirection {

double anchor = 0.0,
List<RenderSliver> children = null,
RenderSliver center = null,
double cacheExtent = RenderAbstractViewportUtils.defaultCacheExtent
double? cacheExtent = null
) : base(axisDirection, crossAxisDirection, offset, cacheExtent) {
this.addAll(children);
if (center == null && this.firstChild != null) {

6
Assets/UIWidgets/rendering/viewport_offset.cs


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 IPromise animateTo(double to, TimeSpan duration, Curve curve);
public abstract ScrollDirection userScrollDirection { get; }

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

32
Assets/UIWidgets/scheduler/binding.cs


}
public class SchedulerBinding {
public SchedulerBinding(Window window) {
D.assert(window != null);
this.window = window;
window.onBeginFrame += this._handleBeginFrame;
window.onDrawFrame += this._handleDrawFrame;
public static SchedulerBinding instance {
get {
D.assert(_instance != null, "Binding.instance is null");
return _instance;
}
set {
if (value == null) {
D.assert(_instance != null, "Binding.instance is already cleared.");
_instance = null;
} else {
D.assert(_instance == null, "Binding.instance is already assigned.");
_instance = value;
}
}
public readonly Window window;
static SchedulerBinding _instance;
public SchedulerBinding() {
Window.instance.onBeginFrame += this._handleBeginFrame;
Window.instance.onDrawFrame += this._handleDrawFrame;
}
public double timeDilation {
get { return this._timeDilation; }

return true;
});
this.window.scheduleFrame();
Window.instance.scheduleFrame();
this._hasScheduledFrame = true;
}

return true;
});
this.window.scheduleFrame();
Window.instance.scheduleFrame();
this._hasScheduledFrame = true;
}

21
Assets/UIWidgets/scheduler/ticker.cs


public interface TickerProvider {
Ticker createTicker(TickerCallback onTick);
SchedulerBinding schedulerBinding { get; }
public Ticker(SchedulerBinding binding, TickerCallback onTick, string debugLabel = null) {
public Ticker(TickerCallback onTick, string debugLabel = null) {
this._binding = binding;
readonly SchedulerBinding _binding;
TickerFutureImpl _future;

return false;
}
if (this._binding.framesEnabled) {
if (SchedulerBinding.instance.framesEnabled) {
if (this._binding.schedulerPhase != SchedulerPhase.idle) {
if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle) {
return true;
}

this.scheduleTick();
}
if (this._binding.schedulerPhase > SchedulerPhase.idle &&
this._binding.schedulerPhase < SchedulerPhase.postFrameCallbacks) {
this._startTime = this._binding.currentFrameTimeStamp;
if (SchedulerBinding.instance.schedulerPhase > SchedulerPhase.idle &&
SchedulerBinding.instance.schedulerPhase < SchedulerPhase.postFrameCallbacks) {
this._startTime = SchedulerBinding.instance.currentFrameTimeStamp;
}
return this._future;

protected void scheduleTick(bool rescheduling = false) {
D.assert(!this.scheduled);
D.assert(this.shouldScheduleTick);
this._animationId = this._binding.scheduleFrameCallback(this._tick, rescheduling: rescheduling);
this._animationId = SchedulerBinding.instance.scheduleFrameCallback(this._tick, rescheduling: rescheduling);
this._binding.cancelFrameCallbackWithId(this._animationId.Value);
SchedulerBinding.instance.cancelFrameCallbackWithId(this._animationId.Value);
this._animationId = null;
}

20
Assets/UIWidgets/ui/window.cs


using System;
using UIWidgets.async;
using UIWidgets.foundation;
namespace UIWidgets.ui {
public delegate void VoidCallback();

public delegate void PointerDataPacketCallback(PointerDataPacket packet);
public abstract class Window {
public static Window instance {
get {
D.assert(_instance != null, "Window.instance is null");
return _instance;
}
set {
if (value == null) {
D.assert(_instance != null, "Window.instance is already cleared.");
_instance = null;
} else {
D.assert(_instance == null, "Window.instance is already assigned.");
_instance = value;
}
}
}
static Window _instance;
public double devicePixelRatio {
get { return this._devicePixelRatio; }
}

155
Assets/UIWidgets/widgets/basic.cs


public Offset origin;
public Alignment alignment;
public bool transformHitTests;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderTransform(
transform: transform,

}
}
public class SliverPadding : SingleChildRenderObjectWidget {
public SliverPadding(
Key key = null,
EdgeInsets padding = null,
Widget sliver = null
) : base(key: key, child: sliver) {
D.assert(padding != null);
this.padding = padding;
}
public readonly EdgeInsets padding;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderSliverPadding(
padding: this.padding
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObjectRaw) {
var renderObject = (RenderSliverPadding) renderObjectRaw;
renderObject.padding = this.padding;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", this.padding));
}
}
public class RawImage : LeafRenderObjectWidget {
public RawImage(Key key, ui.Image image, double width, double height, double scale, Color color,
BlendMode colorBlendMode, BoxFit fit, Rect centerSlice, Alignment alignment = null,

public Alignment alignment;
public ImageRepeat repeat;
public Rect centerSlice;
}
public class Listener : SingleChildRenderObjectWidget {
public Listener(
Key key = null,
PointerDownEventListener onPointerDown = null,
PointerMoveEventListener onPointerMove = null,
PointerUpEventListener onPointerUp = null,
PointerCancelEventListener onPointerCancel = null,
HitTestBehavior behavior = HitTestBehavior.deferToChild,
Widget child = null
) : base(key: key, child: child) {
this.onPointerDown = onPointerDown;
this.onPointerMove = onPointerMove;
this.onPointerUp = onPointerUp;
this.onPointerCancel = onPointerCancel;
this.behavior = behavior;
}
public readonly PointerDownEventListener onPointerDown;
public readonly PointerMoveEventListener onPointerMove;
public readonly PointerUpEventListener onPointerUp;
public readonly PointerCancelEventListener onPointerCancel;
public readonly HitTestBehavior behavior;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderPointerListener(
onPointerDown: this.onPointerDown,
onPointerMove: this.onPointerMove,
onPointerUp: this.onPointerUp,
onPointerCancel: this.onPointerCancel,
behavior: this.behavior
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObjectRaw) {
var renderObject = (RenderPointerListener) renderObjectRaw;
renderObject.onPointerDown = this.onPointerDown;
renderObject.onPointerMove = this.onPointerMove;
renderObject.onPointerUp = this.onPointerUp;
renderObject.onPointerCancel = this.onPointerCancel;
renderObject.behavior = this.behavior;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
List<string> listeners = new List<string>();
if (this.onPointerDown != null) {
listeners.Add("down");
}
if (this.onPointerMove != null) {
listeners.Add("move");
}
if (this.onPointerUp != null) {
listeners.Add("up");
}
if (this.onPointerCancel != null) {
listeners.Add("cancel");
}
properties.add(new EnumerableProperty<string>("listeners", listeners, ifEmpty: "<none>"));
properties.add(new EnumProperty<HitTestBehavior>("behavior", this.behavior));
}
}
public class RepaintBoundary : SingleChildRenderObjectWidget {
public RepaintBoundary(Key key = null, Widget child = null) : base(key: key, child: child) {
}
public static RepaintBoundary wrap(Widget child, int childIndex) {
D.assert(child != null);
Key key = child.key != null ? (Key) new ValueKey<Key>(child.key) : new ValueKey<int>(childIndex);
return new RepaintBoundary(key: key, child: child);
}
public static List<RepaintBoundary> wrapAll(List<Widget> widgets) {
List<RepaintBoundary> result = new List<RepaintBoundary>(widgets.Count);
for (int i = 0; i < result.Count; ++i) {
result[i] = RepaintBoundary.wrap(widgets[i], i);
}
return result;
}
public override RenderObject createRenderObject(BuildContext context) {
return new RenderRepaintBoundary();
}
}
public class IgnorePointer : SingleChildRenderObjectWidget {
public IgnorePointer(
Key key = null,
bool ignoring = true,
Widget child = null
) : base(key: key, child: child) {
this.ignoring = ignoring;
}
public readonly bool ignoring;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderIgnorePointer(
ignoring: this.ignoring
);
}
public override
void updateRenderObject(BuildContext context, RenderObject renderObjectRaw) {
var renderObject = (RenderIgnorePointer) renderObjectRaw;
renderObject.ignoring = this.ignoring;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<bool>("ignoring", this.ignoring));
}
}
}

221
Assets/UIWidgets/widgets/binding.cs


}
public class WidgetsBinding : RendererBinding {
public WidgetsBinding(Window window) : base(window) {
public static new WidgetsBinding instance {
get { return (WidgetsBinding) RendererBinding.instance; }
set { RendererBinding.instance = value; }
}
public WidgetsBinding() {
window.onLocaleChanged += this.handleLocaleChanged;
Window.instance.onLocaleChanged += this.handleLocaleChanged;
}
public BuildOwner buildOwner {

readonly BuildOwner _buildOwner = new BuildOwner();
public Element renderViewElement {
get { return this._renderViewElement; }
public FocusManager focusManager {
get { return this._buildOwner.focusManager; }
Element _renderViewElement;
readonly List<WidgetsBindingObserver> _observers = new List<WidgetsBindingObserver>();
public List<WidgetsBindingObserver> _observers = new List<WidgetsBindingObserver>();
public void addObserver(WidgetsBindingObserver observer) {
this._observers.Add(observer);
}
void addObserver(WidgetsBindingObserver observer) {
_observers.Add(observer);
public bool removeObserver(WidgetsBindingObserver observer) {
return this._observers.Remove(observer);
foreach (WidgetsBindingObserver observer in _observers) {
foreach (WidgetsBindingObserver observer in this._observers) {
bool removeObserver(WidgetsBindingObserver observer) {
return _observers.Remove(observer);
void handleLocaleChanged() {
// todo
// dispatchLocaleChanged(window.locale);
ensureVisualUpdate();
D.assert(() => {
if (this.debugBuildingDirtyElements) {
throw new UIWidgetsError(
"Build scheduled during frame.\n" +
"While the widget tree was being built, laid out, and painted, " +
"a new frame was scheduled to rebuild the widget tree. " +
"This might be because setState() was called from a layout or " +
"paint callback. " +
"If a change is needed to the widget tree, it should be applied " +
"as the tree is being built. Scheduling a change for the subsequent " +
"frame instead results in an interface that lags behind by one frame. " +
"If this was done to make your build dependent on a size measured at " +
"layout time, consider using a LayoutBuilder, CustomSingleChildLayout, " +
"or CustomMultiChildLayout. If, on the other hand, the one frame delay " +
"is the desired effect, for example because this is an " +
"animation, consider scheduling the frame in a post-frame callback " +
"using SchedulerBinding.addPostFrameCallback or " +
"using an AnimationController to trigger the animation."
);
}
return true;
});
this.ensureVisualUpdate();
void handleLocaleChanged() {
// todo
// dispatchLocaleChanged(window.locale);
}
protected bool debugBuildingDirtyElements = false;
if (renderViewElement != null) {
buildOwner.buildScope(renderViewElement);
D.assert(!this.debugBuildingDirtyElements);
D.assert(() => {
this.debugBuildingDirtyElements = true;
return true;
});
try {
if (this.renderViewElement != null) {
this.buildOwner.buildScope(this.renderViewElement);
}
base.drawFrame();
this.buildOwner.finalizeTree();
finally {
D.assert(() => {
this.debugBuildingDirtyElements = false;
return true;
});
}
}
base.drawFrame();
buildOwner.finalizeTree();
public RenderObjectToWidgetElement<RenderBox> renderViewElement {
get { return this._renderViewElement; }
RenderObjectToWidgetElement<RenderBox> _renderViewElement;
var _adapter = new RenderObjectToWidgetAdapter<RenderBox>(
container: renderView,
this._renderViewElement = new RenderObjectToWidgetAdapter<RenderBox>(
container: this.renderView,
debugShortDescription: "[root]",
);
_renderViewElement = _adapter.attachToRenderTree(buildOwner,
_renderViewElement as RenderObjectToWidgetElement<RenderBox>);
).attachToRenderTree(this.buildOwner, this._renderViewElement);
public RenderObjectToWidgetAdapter(Widget child, RenderObjectWithChildMixinRenderObject<T> container) : base(
new GlobalObjectKey<State<StatefulWidget>>(container)) {
public RenderObjectToWidgetAdapter(
Widget child = null,
RenderObjectWithChildMixin<T> container = null,
string debugShortDescription = null
) : base(
new GlobalObjectKey<State>(container)) {
this.debugShortDescription = debugShortDescription;
public Widget child;
public readonly Widget child;
public RenderObjectWithChildMixinRenderObject<T> container;
public readonly RenderObjectWithChildMixin<T> container;
public string debugShortDescription;
public readonly string debugShortDescription;
public override Element createElement() {
return new RenderObjectToWidgetElement<T>(this);

return container;
return (RenderObject) this.container;
public void updateRenderObject(BuildContext context, RenderObject renderObject) {
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
element = (RenderObjectToWidgetElement<T>) createElement();
element.assignOwner(owner);
owner.lockState(() => {
element = (RenderObjectToWidgetElement<T>) this.createElement();
D.assert(element != null);
element.assignOwner(owner);
});
}
else {
} else {
element._newWidget = this;
element.markNeedsBuild();
}

public override string toStringShort() {
return this.debugShortDescription ?? base.toStringShort();
}
public RenderObjectToWidgetElement(RenderObjectWidget widget) : base(widget) {
public RenderObjectToWidgetElement(RenderObjectToWidgetAdapter<T> widget) : base(widget) {
public RenderObjectToWidgetAdapter<T> widget {
public new RenderObjectToWidgetAdapter<T> widget {
get { return (RenderObjectToWidgetAdapter<T>) base.widget; }
}

public Widget _newWidget;
public new RenderObjectWithChildMixin renderObject {
get { return base.renderObject as RenderObjectWithChildMixin; }
}
if (_child != null)
visitor(_child);
if (this._child != null) {
visitor(this._child);
}
D.assert(child == _child);
_child = null;
D.assert(child == this._child);
this._child = null;
_rebuild();
this._rebuild();
D.assert(widget == newWidget);
_rebuild();
D.assert(this.widget == newWidget);
this._rebuild();
internal Widget _newWidget;
if (_newWidget != null) {
Widget newWidget = _newWidget;
_newWidget = null;
update(newWidget);
if (this._newWidget != null) {
Widget newWidget = this._newWidget;
this._newWidget = null;
this.update(newWidget);
D.assert(_newWidget == null);
D.assert(this._newWidget == null);
}
void _rebuild() {
try {
this._child = this.updateChild(this._child, this.widget.child, _rootChildSlot);
// allow
}
catch (Exception ex) {
var details = new UIWidgetsErrorDetails(
exception: ex,
library: "widgets library",
context: "attaching to the render tree"
);
UIWidgetsError.reportError(details);
Widget error = ErrorWidget.builder(details);
this._child = this.updateChild(null, error, _rootChildSlot);
}
}
public new RenderObjectWithChildMixin<T> renderObject {
get { return (RenderObjectWithChildMixin<T>) base.renderObject; }
renderObject.child = child;
D.assert(this.renderObject.debugValidateChild(child));
this.renderObject.child = (T) child;
}
protected override void moveChildRenderObject(RenderObject child, object slot) {

protected override void removeChildRenderObject(RenderObject child) {
D.assert(renderObject.child == child);
renderObject.child = null;
}
void _rebuild() {
try {
_child = updateChild(_child, widget.child, _rootChildSlot);
D.assert(_child != null);
}
catch (Exception e) {
Widget error = ErrorWidget.builder(new UIWidgetsErrorDetails(e));
_child = updateChild(null, error, _rootChildSlot);
}
}
}
public class WidgetsBindings {
public WidgetsBindings(Window window) {
this.window = window;
this.widgetsBinding = new WidgetsBinding(window);
}
public readonly Window window;
public readonly WidgetsBinding widgetsBinding;
public void attachRootWidget(Widget root) {
this.widgetsBinding.attachRootWidget(root);
D.assert(this.renderObject.child == child);
this.renderObject.child = null;
}
}
}

25
Assets/UIWidgets/widgets/debug.cs


});
}
public static bool debugCheckHasDirectionality(BuildContext context) {
D.assert(() => {
if (!(context.widget is Directionality) &&
context.ancestorWidgetOfExactType(typeof(Directionality)) == null) {
Element element = (Element) context;
throw new UIWidgetsError(
"No Directionality widget found.\n" +
context.widget.GetType() + " widgets require a Directionality widget ancestor.\n" +
"The specific widget that could not find a Directionality ancestor was:\n" +
" " + context.widget + "\n" +
"The ownership chain for the affected widget is:\n" +
" " + element.debugGetCreatorChain(10) + "\n" +
"Typically, the Directionality widget is introduced by the MaterialApp " +
"or WidgetsApp widget at the top of your application widget tree. It " +
"determines the ambient reading direction and is used, for example, to " +
"determine how to lay out text, how to interpret \"start\" and \"end\" " +
"values, and to resolve EdgeInsetsDirectional, " +
"AlignmentDirectional, and other *Directional objects.");
}
return true;
});
return true;
}
internal static UIWidgetsErrorDetails _debugReportException(
string context,
Exception exception,

42
Assets/UIWidgets/widgets/framework.cs


}
internal Element _currentElement {
get { return _registry[this]; }
get {
Element result;
_registry.TryGetValue(this, out result);
return result;
}
}
public BuildContext currentContext {

get { return this._currentElement == null ? null : this._currentElement.widget; }
}
public State<StatefulWidget> currentState {
public State currentState {
if (state is State<StatefulWidget>) {
return (State<StatefulWidget>) state;
if (state is State) {
return (State) state;
}
}

}
public abstract class GlobalKey<T> : GlobalKey where T : State<StatefulWidget> {
public new static GlobalKey key(string debugLabel = null) {
public abstract class GlobalKey<T> : GlobalKey where T : State {
public new static GlobalKey<T> key(string debugLabel = null) {
return new LabeledGlobalKey<T>(debugLabel);
}

}
}
public class LabeledGlobalKey<T> : GlobalKey<T> where T : State<StatefulWidget> {
public class LabeledGlobalKey<T> : GlobalKey<T> where T : State {
public LabeledGlobalKey(string _debugLabel = null) {
this._debugLabel = _debugLabel;
}

}
}
public class GlobalObjectKey<T> : GlobalKey<T>, IEquatable<GlobalObjectKey<T>> where T : State<StatefulWidget> {
public class GlobalObjectKey<T> : GlobalKey<T>, IEquatable<GlobalObjectKey<T>> where T : State {
public GlobalObjectKey(object value) {
this.value = value;
}

public override string ToString() {
String selfType = this.GetType().ToString();
string suffix = "<State<StatefulWidget>>";
string suffix = "`1[UIWidgets.widgets.State]";
if (selfType.EndsWith(suffix)) {
selfType = selfType.Substring(0, selfType.Length - suffix.Length);
}

public virtual void visitChildren(ElementVisitor visitor) {
}
public void debugVisitOnstageChildren(ElementVisitor visitor) {
public virtual void debugVisitOnstageChildren(ElementVisitor visitor) {
this.visitChildren(visitor);
}

this.visitChildren(visitor);
}
protected Element updateChild(Element child, Widget newWidget, object newSlot) {
protected virtual Element updateChild(Element child, Widget newWidget, object newSlot) {
D.assert(() => {
if (newWidget != null && newWidget.key is GlobalKey) {
GlobalKey key = (GlobalKey) newWidget.key;

public virtual InheritedWidget inheritFromWidgetOfExactType(Type targetType, object aspect = null) {
D.assert(this._debugCheckStateIsActiveForAncestorLookup());
InheritedElement ancestor = this._inheritedWidgets == null ? null : this._inheritedWidgets[targetType];
InheritedElement ancestor = null;
if (this._inheritedWidgets != null) {
this._inheritedWidgets.TryGetValue(targetType, out ancestor);
}
if (ancestor != null) {
return this.inheritFromElement(ancestor, aspect: aspect);
}

public virtual InheritedElement ancestorInheritedElementForWidgetOfExactType(Type targetType) {
D.assert(this._debugCheckStateIsActiveForAncestorLookup());
InheritedElement ancestor = this._inheritedWidgets == null ? null : this._inheritedWidgets[targetType];
InheritedElement ancestor = null;
if (this._inheritedWidgets != null) {
this._inheritedWidgets.TryGetValue(targetType, out ancestor);
}
return ancestor;
}

internal readonly Dictionary<Element, object> _dependents = new Dictionary<Element, object>();
internal override void _updateInheritance() {
Dictionary<Type, InheritedElement> incomingWidgets = this._parent == null ? null : this._inheritedWidgets;
Dictionary<Type, InheritedElement> incomingWidgets =
this._parent == null ? null : this._parent._inheritedWidgets;
if (incomingWidgets != null) {
this._inheritedWidgets = new Dictionary<Type, InheritedElement>(incomingWidgets);
} else {

}
ParentDataElement<RenderObjectWidget> _findAncestorParentDataElement() {
Element ancestor = _parent;
Element ancestor = this._parent;
while (ancestor != null && !(ancestor is RenderObjectElement)) {
var element = ancestor as ParentDataElement<RenderObjectWidget>;
if (element != null) {

2
Assets/UIWidgets/widgets/scroll_activity.cs


new ScrollEndNotification(
metrics: metrics,
context: context,
dragDetails: lastDetails is DragEndDetails ? (DragEndDetails) lastDetails : null
dragDetails: lastDetails as DragEndDetails
).dispatch(context);
}

16
Assets/UIWidgets/widgets/scroll_metrics.cs


}
public static class ScrollMetricsUtils {
public static ScrollMetrics copyWith(ScrollMetrics it,
double? minScrollExtent = null,
double? maxScrollExtent = null,
double? pixels = null,
double? viewportDimension = null,
AxisDirection? axisDirection = null
) {
return new FixedScrollMetrics(
minScrollExtent: minScrollExtent ?? it.minScrollExtent,
maxScrollExtent: maxScrollExtent ?? it.maxScrollExtent,
pixels: pixels ?? it.pixels,
viewportDimension: viewportDimension ?? it.viewportDimension,
axisDirection: axisDirection ?? it.axisDirection
);
}
public static Axis axis(this ScrollMetrics it) {
return AxisUtils.axisDirectionToAxis(it.axisDirection);
}

497
Assets/UIWidgets/widgets/scroll_position.cs


using System;
using System.Collections.Generic;
using RSG;
using UIWidgets.animation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.physics;
// public abstract class ScrollPosition : ViewportOffset, ScrollMetrics {
// ScrollPosition(
// ScrollPhysics physics = null,
// ScrollContext context = null,
// bool keepScrollOffset = true,
// ScrollPosition oldPosition = null,
// string debugLabel = null
// ) {
// D.assert(physics != null);
// D.assert(context != null);
// D.assert(context.vsync != null);
//
// this.physics = physics;
// this.context = context;
// this.keepScrollOffset = keepScrollOffset;
// this.debugLabel = debugLabel;
//
// if (oldPosition != null) {
// this.absorb(oldPosition);
// }
//
// if (keepScrollOffset) {
// this.restoreScrollOffset();
// }
// }
//
// public readonly ScrollPhysics physics;
// public readonly ScrollContext context;
// public readonly bool keepScrollOffset;
// public readonly string debugLabel;
//
// public double minScrollExtent {
// get { return this._minScrollExtent; }
// }
//
// double _minScrollExtent;
//
// public double maxScrollExtent {
// get { return this._maxScrollExtent; }
// }
//
// double _maxScrollExtent;
//
// public override double? pixels {
// get { return this._pixels; }
// }
//
// double? _pixels;
//
// public double viewportDimension {
// get { return this._viewportDimension; }
// }
//
// double _viewportDimension;
//
// public bool haveDimensions {
// get { return this._haveDimensions; }
// }
//
// bool _haveDimensions = false;
//
// protected virtual void absorb(ScrollPosition other) {
// D.assert(other != null);
// D.assert(other.context == context);
// D.assert(_pixels == null);
// _minScrollExtent = other.minScrollExtent;
// _maxScrollExtent = other.maxScrollExtent;
// _pixels = other._pixels;
// _viewportDimension = other.viewportDimension;
//
// D.assert(activity == null);
// D.assert(other.activity != null);
// _activity = other.activity;
// other._activity = null;
// if (other.runtimeType != runtimeType)
// activity.resetActivity();
// context.setIgnorePointer(activity.shouldIgnorePointer);
// isScrollingNotifier.value = activity.isScrolling;
// }
//
// public double setPixels(double newPixels) {
// D.assert(this._pixels != null);
// D.assert(this.context.vsync.schedulerBinding.schedulerPhase <= SchedulerPhase.transientCallbacks);
// if (newPixels != this.pixels) {
// double overscroll = this.applyBoundaryConditions(newPixels);
// D.assert(() => {
// double delta = newPixels - this.pixels;
// if (overscroll.abs() > delta.abs()) {
// throw new UIWidgetsError(
// string.Format(
// "{0}.applyBoundaryConditions returned invalid overscroll value.\n" +
// "setPixels() was called to change the scroll offset from {1} to {2}.\n" +
// "That is a delta of {3} units.\n" +
// "{0}.applyBoundaryConditions reported an overscroll of {4} units."
// , this.GetType(), this.pixels, newPixels, delta, overscroll));
// }
//
// return true;
// });
//
// double oldPixels = this.pixels;
// this._pixels = newPixels - overscroll;
// if (this._pixels != oldPixels) {
// this.notifyListeners();
// this.didUpdateScrollPositionBy(this._pixels - oldPixels);
// }
//
// if (overscroll != 0.0) {
// this.didOverscrollBy(overscroll);
// return overscroll;
// }
// }
//
// return 0.0;
// }
//
// public void correctPixels(double value) {
// this._pixels = value;
// }
//
// public override void correctBy(double correction) {
// D.assert(
// this._pixels != null,
// "An initial pixels value must exist by caling correctPixels on the ScrollPosition"
// );
//
// this._pixels += correction;
// this._didChangeViewportDimensionOrReceiveCorrection = true;
// }
//
// protected void forcePixels(double value) {
// D.assert(this.pixels != null);
// _pixels = value;
// notifyListeners();
// }
//
// protected void saveScrollOffset() {
// PageStorage.of(context.storageContext)?.writeState(context.storageContext, pixels);
// }
//
// protected void restoreScrollOffset() {
// if (pixels == null) {
// final double value = PageStorage.of(context.storageContext)?.readState(context.storageContext);
// if (value != null)
// correctPixels(value);
// }
// }
// }
public abstract class ScrollPosition : ViewportOffset, ScrollMetrics {
protected ScrollPosition(
ScrollPhysics physics = null,
ScrollContext context = null,
bool keepScrollOffset = true,
ScrollPosition oldPosition = null,
string debugLabel = null
) {
D.assert(physics != null);
D.assert(context != null);
D.assert(context.vsync != null);
this.physics = physics;
this.context = context;
this.keepScrollOffset = keepScrollOffset;
this.debugLabel = debugLabel;
if (oldPosition != null) {
this.absorb(oldPosition);
}
if (keepScrollOffset) {
this.restoreScrollOffset();
}
}
public readonly ScrollPhysics physics;
public readonly ScrollContext context;
public readonly bool keepScrollOffset;
public readonly string debugLabel;
public double minScrollExtent {
get { return this._minScrollExtent.Value; }
}
double? _minScrollExtent;
public double maxScrollExtent {
get { return this._maxScrollExtent.Value; }
}
double? _maxScrollExtent;
public override double pixels {
get {
D.assert(this._pixels != null);
return this._pixels ?? 0.0;
}
}
internal double? _pixels;
public double viewportDimension {
get { return this._viewportDimension.Value; }
}
double? _viewportDimension;
public bool haveDimensions {
get { return this._haveDimensions; }
}
bool _haveDimensions = false;
public abstract AxisDirection axisDirection { get; }
protected virtual void absorb(ScrollPosition other) {
D.assert(other != null);
D.assert(other.context == this.context);
D.assert(this._pixels == null);
this._minScrollExtent = other.minScrollExtent;
this._maxScrollExtent = other.maxScrollExtent;
this._pixels = other._pixels;
this._viewportDimension = other.viewportDimension;
D.assert(this.activity == null);
D.assert(other.activity != null);
this._activity = other.activity;
other._activity = null;
if (other.GetType() != this.GetType()) {
this.activity.resetActivity();
}
this.context.setIgnorePointer(this.activity.shouldIgnorePointer);
this.isScrollingNotifier.value = this.activity.isScrolling;
}
public virtual double setPixels(double newPixels) {
D.assert(this._pixels != null);
D.assert(SchedulerBinding.instance.schedulerPhase <= SchedulerPhase.transientCallbacks);
if (newPixels != this.pixels) {
double overscroll = this.applyBoundaryConditions(newPixels);
D.assert(() => {
double delta = newPixels - this.pixels;
if (overscroll.abs() > delta.abs()) {
throw new UIWidgetsError(
string.Format(
"{0}.applyBoundaryConditions returned invalid overscroll value.\n" +
"setPixels() was called to change the scroll offset from {1} to {2}.\n" +
"That is a delta of {3} units.\n" +
"{0}.applyBoundaryConditions reported an overscroll of {4} units."
, this.GetType(), this.pixels, newPixels, delta, overscroll));
}
return true;
});
double oldPixels = this.pixels;
this._pixels = newPixels - overscroll;
if (this.pixels != oldPixels) {
this.notifyListeners();
this.didUpdateScrollPositionBy(this.pixels - oldPixels);
}
if (overscroll != 0.0) {
this.didOverscrollBy(overscroll);
return overscroll;
}
}
return 0.0;
}
public void correctPixels(double value) {
this._pixels = value;
}
public override void correctBy(double correction) {
D.assert(
this._pixels != null,
"An initial pixels value must exist by caling correctPixels on the ScrollPosition"
);
this._pixels += correction;
this._didChangeViewportDimensionOrReceiveCorrection = true;
}
protected void forcePixels(double value) {
D.assert(this._pixels != null);
this._pixels = value;
this.notifyListeners();
}
protected void saveScrollOffset() {
var pageStorage = PageStorage.of(this.context.storageContext);
if (pageStorage != null) {
pageStorage.writeState(this.context.storageContext, this.pixels);
}
}
protected void restoreScrollOffset() {
if (this._pixels == null) {
var pageStorage = PageStorage.of(this.context.storageContext);
if (pageStorage != null) {
object valueRaw = pageStorage.readState(this.context.storageContext);
if (valueRaw != null) {
this.correctPixels((double) valueRaw);
}
}
}
}
protected double applyBoundaryConditions(double value) {
double result = this.physics.applyBoundaryConditions(this, value);
D.assert(() => {
double delta = value - this.pixels;
if (result.abs() > delta.abs()) {
throw new UIWidgetsError(
string.Format(
"{0}.applyBoundaryConditions returned invalid overscroll value.\n" +
"The method was called to consider a change from {1} to {2}, which is a " +
"delta of {3:F1} units. However, it returned an overscroll of " +
"${4:F1} units, which has a greater magnitude than the delta. " +
"The applyBoundaryConditions method is only supposed to reduce the possible range " +
"of movement, not increase it.\n" +
"The scroll extents are {5} .. {6}, and the " +
"viewport dimension is {7}.",
this.physics.GetType(), this.pixels, value, delta, result,
this.minScrollExtent, this.maxScrollExtent, this.viewportDimension));
}
return true;
});
return result;
}
bool _didChangeViewportDimensionOrReceiveCorrection = true;
public override bool applyViewportDimension(double viewportDimension) {
if (this._viewportDimension != viewportDimension) {
this._viewportDimension = viewportDimension;
this._didChangeViewportDimensionOrReceiveCorrection = true;
}
return true;
}
public override bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
if (!PhysicsUtils.nearEqual(this._minScrollExtent, minScrollExtent, Tolerance.defaultTolerance.distance) ||
!PhysicsUtils.nearEqual(this._maxScrollExtent, maxScrollExtent, Tolerance.defaultTolerance.distance) ||
this._didChangeViewportDimensionOrReceiveCorrection) {
this._minScrollExtent = minScrollExtent;
this._maxScrollExtent = maxScrollExtent;
this._haveDimensions = true;
this.applyNewDimensions();
this._didChangeViewportDimensionOrReceiveCorrection = false;
}
return true;
}
protected virtual void applyNewDimensions() {
D.assert(this._pixels != null);
this.activity.applyNewDimensions();
}
public IPromise ensureVisible(RenderObject renderObject,
double alignment = 0.0,
TimeSpan? duration = null,
Curve curve = null
) {
D.assert(renderObject.attached);
RenderAbstractViewport viewport = RenderAbstractViewportUtils.of(renderObject);
D.assert(viewport != null);
double target = viewport.getOffsetToReveal(renderObject, alignment).offset.clamp(
this.minScrollExtent, this.maxScrollExtent);
if (target == this.pixels) {
return Promise.Resolved();
}
duration = duration ?? TimeSpan.Zero;
if (duration == TimeSpan.Zero) {
this.jumpTo(target);
return Promise.Resolved();
}
curve = curve ?? Curves.ease;
return this.animateTo(target, duration: duration.Value, curve: curve);
}
public readonly ValueNotifier<bool> isScrollingNotifier = new ValueNotifier<bool>(false);
public override bool allowImplicitScrolling {
get { return this.physics.allowImplicitScrolling; }
}
public abstract ScrollHoldController hold(VoidCallback holdCancelCallback);
public abstract Drag drag(DragStartDetails details, VoidCallback dragCancelCallback);
protected ScrollActivity activity {
get { return this._activity; }
}
ScrollActivity _activity;
public virtual void beginActivity(ScrollActivity newActivity) {
if (newActivity == null) {
return;
}
bool wasScrolling, oldIgnorePointer;
if (this._activity != null) {
oldIgnorePointer = this._activity.shouldIgnorePointer;
wasScrolling = this._activity.isScrolling;
if (wasScrolling && !newActivity.isScrolling) {
this.didEndScroll();
}
this._activity.dispose();
} else {
oldIgnorePointer = false;
wasScrolling = false;
}
this._activity = newActivity;
if (oldIgnorePointer != this.activity.shouldIgnorePointer) {
this.context.setIgnorePointer(this.activity.shouldIgnorePointer);
}
this.isScrollingNotifier.value = this.activity.isScrolling;
if (!wasScrolling && this._activity.isScrolling) {
this.didStartScroll();
}
}
public void didStartScroll() {
this.activity.dispatchScrollStartNotification(
ScrollMetricsUtils.copyWith(this), this.context.notificationContext);
}
public void didUpdateScrollPositionBy(double delta) {
this.activity.dispatchScrollUpdateNotification(
ScrollMetricsUtils.copyWith(this), this.context.notificationContext, delta);
}
public void didEndScroll() {
this.activity.dispatchScrollEndNotification(
ScrollMetricsUtils.copyWith(this), this.context.notificationContext);
if (this.keepScrollOffset) {
this.saveScrollOffset();
}
}
public void didOverscrollBy(double value) {
D.assert(this.activity.isScrolling);
this.activity.dispatchOverscrollNotification(
ScrollMetricsUtils.copyWith(this), this.context.notificationContext, value);
}
public void didUpdateScrollDirection(ScrollDirection direction) {
new UserScrollNotification(metrics:
ScrollMetricsUtils.copyWith(this), context: this.context.notificationContext, direction: direction
).dispatch(this.context.notificationContext);
}
public override void dispose() {
D.assert(this._pixels != null);
if (this.activity != null) {
this.activity.dispose();
this._activity = null;
}
base.dispose();
}
protected override void debugFillDescription(List<String> description) {
if (this.debugLabel != null) {
description.Add(this.debugLabel);
}
base.debugFillDescription(description);
description.Add(string.Format("range: {0:F1}..{1:F1}", this._minScrollExtent, this._maxScrollExtent));
description.Add(string.Format("viewport: {0:F1}", this._viewportDimension));
}
}
}

172
Assets/UIWidgets/widgets/ticker_provider.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.rendering;
using UIWidgets.ui;
using UnityEngine.Assertions;
using UIWidgets.scheduler;
public TickerMode(Key key, bool enabled, Widget child) : base(key, child) {
public TickerMode(
Key key = null,
bool enabled = true,
Widget child = null)
: base(key, child) {
this.enabled = enabled;
}

var widget = context.inheritFromWidgetOfExactType(typeof(TickerMode));
return widget is TickerMode ? (widget as TickerMode).enabled : true;
var widget = (TickerMode) context.inheritFromWidgetOfExactType(typeof(TickerMode));
return widget != null ? widget.enabled : true;
return this.enabled != ((TickerMode)oldWidget).enabled;
return this.enabled != ((TickerMode) oldWidget).enabled;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FlagProperty("mode", value: this.enabled, ifTrue: "enabled", ifFalse: "disabled",
showName: true));
public override Element createElement() {
throw new NotImplementedException();
}
public abstract class SingleTickerProviderStateMixin<T> : State<T>, TickerProvider where T : StatefulWidget {
Ticker _ticker;
public Ticker createTicker(TickerCallback onTick) {
D.assert(() => {
if (this._ticker == null) {
return true;
}
throw new UIWidgetsError(
this.GetType() + " is a SingleTickerProviderStateMixin but multiple tickers were created.\n" +
"A SingleTickerProviderStateMixin can only be used as a TickerProvider once. If a " +
"State is used for multiple AnimationController objects, or if it is passed to other " +
"objects and those objects might use it more than one time in total, then instead of " +
"mixing in a SingleTickerProviderStateMixin, use a regular TickerProviderStateMixin."
);
});
this._ticker = new Ticker(onTick, debugLabel: "created by " + this);
return this._ticker;
}
public override void dispose() {
D.assert(() => {
if (this._ticker == null || !this._ticker.isActive) {
return true;
}
throw new UIWidgetsError(
this + " was disposed with an active Ticker.\n" +
this.GetType() + " created a Ticker via its SingleTickerProviderStateMixin, but at the time " +
"dispose() was called on the mixin, that Ticker was still active. The Ticker must " +
"be disposed before calling super.dispose(). Tickers used by AnimationControllers " +
"should be disposed by calling dispose() on the AnimationController itself. " +
"Otherwise, the ticker will leak.\n" +
"The offending ticker was: " + this._ticker.toString(debugIncludeStack: true)
);
});
base.dispose();
}
public override void didChangeDependencies() {
if (this._ticker != null) {
this._ticker.muted = !TickerMode.of(this.context);
}
base.didChangeDependencies();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
String tickerDescription = null;
if (this._ticker != null) {
if (this._ticker.isActive && this._ticker.muted) {
tickerDescription = "active but muted";
} else if (this._ticker.isActive) {
tickerDescription = "active";
} else if (this._ticker.muted) {
tickerDescription = "inactive and muted";
} else {
tickerDescription = "inactive";
}
}
properties.add(new DiagnosticsProperty<Ticker>("ticker", this._ticker, description: tickerDescription,
showSeparator: false, defaultValue: Diagnostics.kNullDefaultValue));
}
}
public abstract class TickerProviderStateMixin<T> : State<T>, TickerProvider where T : StatefulWidget {
HashSet<Ticker> _tickers;
public Ticker createTicker(TickerCallback onTick) {
this._tickers = this._tickers ?? new HashSet<Ticker>();
var result = new _WidgetTicker<T>(onTick, this, debugLabel: "created by " + this);
this._tickers.Add(result);
return result;
}
internal void _removeTicker(_WidgetTicker<T> ticker) {
D.assert(this._tickers != null);
D.assert(this._tickers.Contains(ticker));
this._tickers.Remove(ticker);
}
public override void dispose() {
D.assert(() => {
if (this._tickers != null) {
foreach (Ticker ticker in this._tickers) {
if (ticker.isActive) {
throw new UIWidgetsError(
this + " was disposed with an active Ticker.\n" +
this.GetType() +
" created a Ticker via its TickerProviderStateMixin, but at the time " +
"dispose() was called on the mixin, that Ticker was still active. All Tickers must " +
"be disposed before calling super.dispose(). Tickers used by AnimationControllers " +
"should be disposed by calling dispose() on the AnimationController itself. " +
"Otherwise, the ticker will leak.\n" +
"The offending ticker was: " + ticker.toString(debugIncludeStack: true)
);
}
}
}
return true;
});
base.dispose();
}
public override void didChangeDependencies() {
bool muted = !TickerMode.of(this.context);
if (this._tickers != null) {
foreach (Ticker ticker in this._tickers) {
ticker.muted = muted;
}
}
base.didChangeDependencies();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<HashSet<Ticker>>(
"tickers",
this._tickers,
description: this._tickers != null ? "tracking " + this._tickers.Count + " tickers" : null,
defaultValue: Diagnostics.kNullDefaultValue
));
}
}
class _WidgetTicker<T> : Ticker where T : StatefulWidget {
internal _WidgetTicker(
TickerCallback onTick,
TickerProviderStateMixin<T> creator,
string debugLabel = null) :
base(onTick: onTick, debugLabel: debugLabel) {
this._creator = creator;
}
readonly TickerProviderStateMixin<T> _creator;
public override void dispose() {
this._creator._removeTicker(this);
base.dispose();
}
}
}

31
Assets/UIWidgets/gestures/long_press.cs


namespace UIWidgets.gestures {
public delegate void GestureLongPressCallback();
public class LongPressGestureRecognizer : PrimaryPointerGestureRecognizer {
public LongPressGestureRecognizer(object debugOwner = null) :
base(deadline: Constants.kLongPressTimeout, debugOwner: debugOwner) {
}
public GestureLongPressCallback onLongPress;
protected override void didExceedDeadline() {
this.resolve(GestureDisposition.accepted);
if (this.onLongPress != null) {
this.invokeCallback<object>("onLongPress", () => {
this.onLongPress();
return null;
});
}
}
protected override void handlePrimaryPointer(PointerEvent evt) {
if (evt is PointerUpEvent) {
this.resolve(GestureDisposition.rejected);
}
}
public override string debugDescription {
get { return "long press"; }
}
}
}

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


fileFormatVersion: 2
guid: 3315b2f4cd844e3c81aa0f074b4914a3
timeCreated: 1537166837

206
Assets/UIWidgets/rendering/automatic_keep_alive.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.scheduler;
using UIWidgets.ui;
using UIWidgets.widgets;
namespace UIWidgets.rendering {
public class AutomaticKeepAlive : StatefulWidget {
public AutomaticKeepAlive(
Key key = null,
Widget child = null
) : base(key: key) {
}
public readonly Widget child;
public override State createState() {
return new _AutomaticKeepAliveState();
}
}
class _AutomaticKeepAliveState : State<AutomaticKeepAlive> {
Dictionary<Listenable, VoidCallback> _handles;
Widget _child;
bool _keepingAlive = false;
public override void initState() {
base.initState();
this._updateChild();
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
this._updateChild();
}
void _updateChild() {
this._child = new NotificationListener<KeepAliveNotification>(
onNotification: this._addClient,
child: this.widget.child
);
}
public override void dispose() {
if (this._handles != null) {
foreach (Listenable handle in this._handles.Keys)
handle.removeListener(this._handles[handle]);
}
base.dispose();
}
bool _addClient(KeepAliveNotification notification) {
Listenable handle = notification.handle;
this._handles = this._handles ?? new Dictionary<Listenable, VoidCallback>();
D.assert(!this._handles.ContainsKey(handle));
this._handles[handle] = this._createCallback(handle);
handle.addListener(this._handles[handle]);
if (!this._keepingAlive) {
this._keepingAlive = true;
ParentDataElement<SliverMultiBoxAdaptorWidget> childElement = this._getChildElement();
if (childElement != null) {
this._updateParentDataOfChild(childElement);
} else {
SchedulerBinding.instance.addPostFrameCallback(timeStamp => {
ParentDataElement<SliverMultiBoxAdaptorWidget> childElement1 = this._getChildElement();
D.assert(childElement1 != null);
this._updateParentDataOfChild(childElement1);
});
}
}
return false;
}
ParentDataElement<SliverMultiBoxAdaptorWidget> _getChildElement() {
Element element = (Element) this.context;
Element childElement = null;
element.visitChildren((Element child) => { childElement = child; });
D.assert(childElement == null || childElement is ParentDataElement<SliverMultiBoxAdaptorWidget>);
return (ParentDataElement<SliverMultiBoxAdaptorWidget>) childElement;
}
void _updateParentDataOfChild(ParentDataElement<SliverMultiBoxAdaptorWidget> childElement) {
childElement.applyWidgetOutOfTurn((ParentDataWidget<SliverMultiBoxAdaptorWidget>) this.build(this.context));
}
VoidCallback _createCallback(Listenable handle) {
return () => {
D.assert(() => {
if (!this.mounted) {
throw new UIWidgetsError(
"AutomaticKeepAlive handle triggered after AutomaticKeepAlive was disposed." +
"Widgets should always trigger their KeepAliveNotification handle when they are " +
"deactivated, so that they (or their handle) do not send spurious events later " +
"when they are no longer in the tree."
);
}
return true;
});
this._handles.Remove(handle);
if (this._handles.isEmpty()) {
if (SchedulerBinding.instance.schedulerPhase < SchedulerPhase.persistentCallbacks) {
this.setState(() => { this._keepingAlive = false; });
} else {
this._keepingAlive = false;
Window.instance.scheduleMicrotask(() => {
if (this.mounted && this._handles.isEmpty()) {
this.setState(() => { D.assert(!this._keepingAlive); });
}
});
}
}
};
}
public override Widget build(BuildContext context) {
D.assert(this._child != null);
return new KeepAlive(
keepAlive: this._keepingAlive,
child: this._child
);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder description) {
base.debugFillProperties(description);
description.add(new FlagProperty("_keepingAlive", value: this._keepingAlive,
ifTrue: "keeping subtree alive"));
description.add(new DiagnosticsProperty<Dictionary<Listenable, VoidCallback>>(
"handles",
this._handles,
description: this._handles != null ? this._handles.Count + " active clients" : null,
ifNull: "no notifications ever received"
));
}
}
public class KeepAliveNotification : Notification {
public KeepAliveNotification(Listenable handle) {
D.assert(handle != null);
this.handle = handle;
}
public readonly Listenable handle;
}
public class KeepAliveHandle : ChangeNotifier {
public void release() {
this.notifyListeners();
}
}
public abstract class AutomaticKeepAliveClientMixin<T> : State<T> where T : StatefulWidget {
KeepAliveHandle _keepAliveHandle;
void _ensureKeepAlive() {
D.assert(this._keepAliveHandle == null);
this._keepAliveHandle = new KeepAliveHandle();
new KeepAliveNotification(this._keepAliveHandle).dispatch(this.context);
}
void _releaseKeepAlive() {
this._keepAliveHandle.release();
this._keepAliveHandle = null;
}
protected abstract bool wantKeepAlive { get; }
protected void updateKeepAlive() {
if (this.wantKeepAlive) {
if (this._keepAliveHandle == null)
this._ensureKeepAlive();
} else {
if (this._keepAliveHandle != null)
this._releaseKeepAlive();
}
}
public override void initState() {
base.initState();
if (this.wantKeepAlive) {
this._ensureKeepAlive();
}
}
public override void deactivate() {
if (this._keepAliveHandle != null) {
this._releaseKeepAlive();
}
base.deactivate();
}
public override Widget build(BuildContext context) {
if (this.wantKeepAlive && this._keepAliveHandle == null) {
this._ensureKeepAlive();
}
return null;
}
}
}

3
Assets/UIWidgets/rendering/automatic_keep_alive.cs.meta


fileFormatVersion: 2
guid: a3c3b140ce174c61bfd25672b4ad6f21
timeCreated: 1537325090

380
Assets/UIWidgets/widgets/gesture_detector.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.rendering;
namespace UIWidgets.widgets {
public abstract class GestureRecognizerFactory {
public abstract GestureRecognizer constructorRaw();
public abstract void initializerRaw(GestureRecognizer instance);
internal abstract bool _debugAssertTypeMatches(Type type);
}
public abstract class GestureRecognizerFactory<T> : GestureRecognizerFactory where T : GestureRecognizer {
public override GestureRecognizer constructorRaw() {
return this.constructor();
}
public override void initializerRaw(GestureRecognizer instance) {
this.initializer((T) instance);
}
public abstract T constructor();
public abstract void initializer(T instance);
internal override bool _debugAssertTypeMatches(Type type) {
D.assert(type == typeof(T),
"GestureRecognizerFactory of type " + typeof(T) + " was used where type $type was specified.");
return true;
}
}
public delegate T GestureRecognizerFactoryConstructor<T>() where T : GestureRecognizer;
public delegate void GestureRecognizerFactoryInitializer<T>(T instance) where T : GestureRecognizer;
public class GestureRecognizerFactoryWithHandlers<T> : GestureRecognizerFactory<T> where T : GestureRecognizer {
public GestureRecognizerFactoryWithHandlers(GestureRecognizerFactoryConstructor<T> constructor,
GestureRecognizerFactoryInitializer<T> initializer) {
D.assert(constructor != null);
D.assert(initializer != null);
this._constructor = constructor;
this._initializer = initializer;
}
readonly GestureRecognizerFactoryConstructor<T> _constructor;
readonly GestureRecognizerFactoryInitializer<T> _initializer;
public override T constructor() {
return this._constructor();
}
public override void initializer(T instance) {
this._initializer(instance);
}
}
public class GestureDetector : StatelessWidget {
public GestureDetector(
Key key = null,
Widget child = null,
GestureTapDownCallback onTapDown = null,
GestureTapUpCallback onTapUp = null,
GestureTapCallback onTap = null,
GestureTapCancelCallback onTapCancel = null,
GestureDoubleTapCallback onDoubleTap = null,
GestureLongPressCallback onLongPress = null,
GestureDragDownCallback onVerticalDragDown = null,
GestureDragStartCallback onVerticalDragStart = null,
GestureDragUpdateCallback onVerticalDragUpdate = null,
GestureDragEndCallback onVerticalDragEnd = null,
GestureDragCancelCallback onVerticalDragCancel = null,
GestureDragDownCallback onHorizontalDragDown = null,
GestureDragStartCallback onHorizontalDragStart = null,
GestureDragUpdateCallback onHorizontalDragUpdate = null,
GestureDragEndCallback onHorizontalDragEnd = null,
GestureDragCancelCallback onHorizontalDragCancel = null,
GestureDragDownCallback onPanDown = null,
GestureDragStartCallback onPanStart = null,
GestureDragUpdateCallback onPanUpdate = null,
GestureDragEndCallback onPanEnd = null,
GestureDragCancelCallback onPanCancel = null,
HitTestBehavior behavior = HitTestBehavior.deferToChild) : base(key) {
D.assert(() => {
bool haveVerticalDrag =
onVerticalDragStart != null || onVerticalDragUpdate != null ||
onVerticalDragEnd != null;
bool haveHorizontalDrag =
onHorizontalDragStart != null || onHorizontalDragUpdate != null ||
onHorizontalDragEnd != null;
bool havePan = onPanStart != null || onPanUpdate != null || onPanEnd != null;
if (havePan) {
if (haveVerticalDrag && haveHorizontalDrag) {
throw new UIWidgetsError(
"Incorrect GestureDetector arguments.\n" +
"Simultaneously having a vertical drag gesture recognizer, a horizontal drag gesture recognizer, and a pan gesture recognizer " +
"will result in the pan gesture recognizer being ignored, since the other two will catch all drags."
);
}
}
return true;
});
this.child = child;
this.onTapDown = onTapDown;
this.onTapUp = onTapUp;
this.onTap = onTap;
this.onTapCancel = onTapCancel;
this.onDoubleTap = onDoubleTap;
this.onLongPress = onLongPress;
this.onVerticalDragDown = onVerticalDragDown;
this.onVerticalDragStart = onVerticalDragStart;
this.onVerticalDragUpdate = onVerticalDragUpdate;
this.onVerticalDragEnd = onVerticalDragEnd;
this.onVerticalDragCancel = onVerticalDragCancel;
this.onHorizontalDragDown = onHorizontalDragDown;
this.onHorizontalDragStart = onHorizontalDragStart;
this.onHorizontalDragUpdate = onHorizontalDragUpdate;
this.onHorizontalDragEnd = onHorizontalDragEnd;
this.onHorizontalDragCancel = onHorizontalDragCancel;
this.onPanDown = onPanDown;
this.onPanStart = onPanStart;
this.onPanUpdate = onPanUpdate;
this.onPanEnd = onPanEnd;
this.onPanCancel = onPanCancel;
this.behavior = behavior;
}
public readonly Widget child;
public readonly GestureTapDownCallback onTapDown;
public readonly GestureTapUpCallback onTapUp;
public readonly GestureTapCallback onTap;
public readonly GestureTapCancelCallback onTapCancel;
public readonly GestureDoubleTapCallback onDoubleTap;
public readonly GestureLongPressCallback onLongPress;
public readonly GestureDragDownCallback onVerticalDragDown;
public readonly GestureDragStartCallback onVerticalDragStart;
public readonly GestureDragUpdateCallback onVerticalDragUpdate;
public readonly GestureDragEndCallback onVerticalDragEnd;
public readonly GestureDragCancelCallback onVerticalDragCancel;
public readonly GestureDragDownCallback onHorizontalDragDown;
public readonly GestureDragStartCallback onHorizontalDragStart;
public readonly GestureDragUpdateCallback onHorizontalDragUpdate;
public readonly GestureDragEndCallback onHorizontalDragEnd;
public readonly GestureDragCancelCallback onHorizontalDragCancel;
public readonly GestureDragDownCallback onPanDown;
public readonly GestureDragStartCallback onPanStart;
public readonly GestureDragUpdateCallback onPanUpdate;
public readonly GestureDragEndCallback onPanEnd;
public readonly GestureDragCancelCallback onPanCancel;
public readonly HitTestBehavior behavior;
public override Widget build(BuildContext context) {
var gestures = new Dictionary<Type, GestureRecognizerFactory>();
if (this.onTapDown != null ||
this.onTapUp != null ||
this.onTap != null ||
this.onTapCancel != null) {
gestures[typeof(TapGestureRecognizer)] =
new GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
() => new TapGestureRecognizer(debugOwner: this),
instance => {
instance.onTapDown = this.onTapDown;
instance.onTapUp = this.onTapUp;
instance.onTap = this.onTap;
instance.onTapCancel = this.onTapCancel;
}
);
}
if (this.onDoubleTap != null) {
gestures[typeof(DoubleTapGestureRecognizer)] =
new GestureRecognizerFactoryWithHandlers<DoubleTapGestureRecognizer>(
() => new DoubleTapGestureRecognizer(debugOwner: this),
instance => { instance.onDoubleTap = this.onDoubleTap; }
);
}
if (this.onLongPress != null) {
gestures[typeof(LongPressGestureRecognizer)] =
new GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
() => new LongPressGestureRecognizer(debugOwner: this),
instance => { instance.onLongPress = this.onLongPress; }
);
}
if (this.onVerticalDragDown != null ||
this.onVerticalDragStart != null ||
this.onVerticalDragUpdate != null ||
this.onVerticalDragEnd != null ||
this.onVerticalDragCancel != null) {
gestures[typeof(VerticalDragGestureRecognizer)] =
new GestureRecognizerFactoryWithHandlers<VerticalDragGestureRecognizer>(
() => new VerticalDragGestureRecognizer(debugOwner: this),
instance => {
instance.onDown = this.onVerticalDragDown;
instance.onStart = this.onVerticalDragStart;
instance.onUpdate = this.onVerticalDragUpdate;
instance.onEnd = this.onVerticalDragEnd;
instance.onCancel = this.onVerticalDragCancel;
}
);
}
if (this.onHorizontalDragDown != null ||
this.onHorizontalDragStart != null ||
this.onHorizontalDragUpdate != null ||
this.onHorizontalDragEnd != null ||
this.onHorizontalDragCancel != null) {
gestures[typeof(HorizontalDragGestureRecognizer)] =
new GestureRecognizerFactoryWithHandlers<HorizontalDragGestureRecognizer>(
() => new HorizontalDragGestureRecognizer(debugOwner: this),
instance => {
instance.onDown = this.onHorizontalDragDown;
instance.onStart = this.onHorizontalDragStart;
instance.onUpdate = this.onHorizontalDragUpdate;
instance.onEnd = this.onHorizontalDragEnd;
instance.onCancel = this.onHorizontalDragCancel;
}
);
}
if (this.onPanDown != null ||
this.onPanStart != null ||
this.onPanUpdate != null ||
this.onPanEnd != null ||
this.onPanCancel != null) {
gestures[typeof(PanGestureRecognizer)] =
new GestureRecognizerFactoryWithHandlers<PanGestureRecognizer>(
() => new PanGestureRecognizer(debugOwner: this),
instance => {
instance.onDown = this.onPanDown;
instance.onStart = this.onPanStart;
instance.onUpdate = this.onPanUpdate;
instance.onEnd = this.onPanEnd;
instance.onCancel = this.onPanCancel;
}
);
}
return new RawGestureDetector(
gestures: gestures,
behavior: this.behavior,
child: this.child
);
}
}
public class RawGestureDetector : StatefulWidget {
public RawGestureDetector(
Key key = null,
Widget child = null,
Dictionary<Type, GestureRecognizerFactory> gestures = null,
HitTestBehavior? behavior = null
) : base(key: key) {
D.assert(gestures != null);
this.child = child;
this.gestures = gestures ?? new Dictionary<Type, GestureRecognizerFactory>();
this.behavior = behavior;
}
public readonly Widget child;
public readonly Dictionary<Type, GestureRecognizerFactory> gestures;
public readonly HitTestBehavior? behavior;
public override State createState() {
return new RawGestureDetectorState();
}
}
public class RawGestureDetectorState : State<RawGestureDetector> {
Dictionary<Type, GestureRecognizer> _recognizers = new Dictionary<Type, GestureRecognizer>();
public override void initState() {
base.initState();
this._syncAll(this.widget.gestures);
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
this._syncAll(this.widget.gestures);
}
public void replaceGestureRecognizers(Dictionary<Type, GestureRecognizerFactory> gestures) {
D.assert(() => {
if (!this.context.findRenderObject().owner.debugDoingLayout) {
throw new UIWidgetsError(
"Unexpected call to replaceGestureRecognizers() method of RawGestureDetectorState.\n" +
"The replaceGestureRecognizers() method can only be called during the layout phase. " +
"To set the gesture recognizers at other times, trigger a new build using setState() " +
"and provide the new gesture recognizers as constructor arguments to the corresponding " +
"RawGestureDetector or GestureDetector object.");
}
return true;
});
this._syncAll(gestures);
}
public override void dispose() {
foreach (GestureRecognizer recognizer in this._recognizers.Values) {
recognizer.dispose();
}
this._recognizers = null;
base.dispose();
}
void _syncAll(Dictionary<Type, GestureRecognizerFactory> gestures) {
D.assert(this._recognizers != null);
var oldRecognizers = this._recognizers;
this._recognizers = new Dictionary<Type, GestureRecognizer>();
foreach (Type type in gestures.Keys) {
D.assert(gestures[type] != null);
D.assert(gestures[type]._debugAssertTypeMatches(type));
D.assert(!this._recognizers.ContainsKey(type));
this._recognizers[type] = oldRecognizers.ContainsKey(type) ? oldRecognizers[type] : gestures[type].constructorRaw();
D.assert(this._recognizers[type].GetType() == type,
"GestureRecognizerFactory of type " + type + " created a GestureRecognizer of type " +
this._recognizers[type].GetType() +
". The GestureRecognizerFactory must be specialized with the type of the class that it returns from its constructor method.");
gestures[type].initializerRaw(this._recognizers[type]);
}
foreach (Type type in oldRecognizers.Keys) {
if (!this._recognizers.ContainsKey(type)) {
oldRecognizers[type].dispose();
}
}
}
void _handlePointerDown(PointerDownEvent evt) {
D.assert(this._recognizers != null);
foreach (GestureRecognizer recognizer in this._recognizers.Values) {
recognizer.addPointer(evt);
}
}
HitTestBehavior _defaultBehavior {
get { return this.widget.child == null ? HitTestBehavior.translucent : HitTestBehavior.deferToChild; }
}
public override Widget build(BuildContext context) {
Widget result = new Listener(
onPointerDown: this._handlePointerDown,
behavior: this.widget.behavior ?? this._defaultBehavior,
child: this.widget.child
);
return result;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
if (this._recognizers == null) {
properties.add(DiagnosticsNode.message("DISPOSED"));
} else {
List<String> gestures = this._recognizers.Values.Select(recognizer => recognizer.debugDescription)
.ToList();
properties.add(new EnumerableProperty<string>("gestures", gestures, ifEmpty: "<none>"));
properties.add(new EnumerableProperty<GestureRecognizer>("recognizers", this._recognizers.Values,
level: DiagnosticLevel.fine));
}
properties.add(new EnumProperty<HitTestBehavior?>("behavior", this.widget.behavior,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
}

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


fileFormatVersion: 2
guid: c9c16577359d413ab2306df2227987dd
timeCreated: 1537165902

144
Assets/UIWidgets/widgets/page_storage.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
namespace UIWidgets.widgets {
public interface PageStorageKey {
}
public class PageStorageKey<T> : ValueKey<T>, PageStorageKey {
public PageStorageKey(T value) : base(value) {
}
}
class _StorageEntryIdentifier : IEquatable<_StorageEntryIdentifier> {
internal _StorageEntryIdentifier(List<PageStorageKey> keys) {
D.assert(keys != null);
this.keys = keys;
}
public readonly List<PageStorageKey> keys;
public bool isNotEmpty {
get { return this.keys.isNotEmpty(); }
}
public override string ToString() {
return string.Format("StorageEntryIdentifier({0})",
string.Join(":", this.keys.Select(x => x.ToString()).ToArray()));
}
public bool Equals(_StorageEntryIdentifier other) {
if (object.ReferenceEquals(null, other)) return false;
if (object.ReferenceEquals(this, other)) return true;
return this.keys.SequenceEqual(other.keys);
}
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((_StorageEntryIdentifier) obj);
}
public override int GetHashCode() {
if (this.keys == null || this.keys.isEmpty()) {
return 0;
}
var hashCode = this.keys[0].GetHashCode();
for (var i = 1; i < this.keys.Count; i++) {
hashCode = (hashCode * 397) ^ this.keys[i].GetHashCode();
}
return hashCode;
}
public static bool operator ==(_StorageEntryIdentifier left, _StorageEntryIdentifier right) {
return object.Equals(left, right);
}
public static bool operator !=(_StorageEntryIdentifier left, _StorageEntryIdentifier right) {
return !object.Equals(left, right);
}
}
public class PageStorageBucket {
static bool _maybeAddKey(BuildContext context, List<PageStorageKey> keys) {
Widget widget = context.widget;
Key key = widget.key;
if (key is PageStorageKey) {
keys.Add((PageStorageKey) key);
}
return !(widget is PageStorage);
}
List<PageStorageKey> _allKeys(BuildContext context) {
List<PageStorageKey> keys = new List<PageStorageKey>();
if (_maybeAddKey(context, keys)) {
context.visitAncestorElements(element => _maybeAddKey(element, keys));
}
return keys;
}
_StorageEntryIdentifier _computeIdentifier(BuildContext context) {
return new _StorageEntryIdentifier(this._allKeys(context));
}
Dictionary<object, object> _storage;
public void writeState(BuildContext context, object data, object identifier = null) {
this._storage = this._storage ?? new Dictionary<object, object>();
if (identifier != null) {
this._storage[identifier] = data;
} else {
_StorageEntryIdentifier contextIdentifier = this._computeIdentifier(context);
if (contextIdentifier.isNotEmpty) {
this._storage[contextIdentifier] = data;
}
}
}
public object readState(BuildContext context, object identifier = null) {
if (this._storage == null) {
return null;
}
if (identifier != null) {
return this._storage[identifier];
}
_StorageEntryIdentifier contextIdentifier = this._computeIdentifier(context);
return contextIdentifier.isNotEmpty ? this._storage[contextIdentifier] : null;
}
}
public class PageStorage : StatelessWidget {
public PageStorage(
Key key,
PageStorageBucket bucket,
Widget child
) : base(key: key) {
D.assert(bucket != null);
this.bucket = bucket;
this.child = child;
}
public readonly Widget child;
public readonly PageStorageBucket bucket;
public static PageStorageBucket of(BuildContext context) {
PageStorage widget = (PageStorage) context.ancestorWidgetOfExactType(typeof(PageStorage));
return widget == null ? null : widget.bucket;
}
public override Widget build(BuildContext context) {
return this.child;
}
}
}

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


fileFormatVersion: 2
guid: 45b0579fc707492f9c779c21360b8881
timeCreated: 1537153497

45
Assets/UIWidgets/widgets/primary_scroll_controller.cs


using UIWidgets.foundation;
namespace UIWidgets.widgets {
public class PrimaryScrollController : InheritedWidget {
public PrimaryScrollController(
Key key = null,
ScrollController controller = null,
Widget child = null
) : base(key: key, child: child) {
D.assert(controller != null);
this.controller = controller;
}
private PrimaryScrollController(
Key key = null,
Widget child = null
) : base(key: key, child: child) {
}
public static PrimaryScrollController none(
Key key = null,
Widget child = null
) {
return new PrimaryScrollController(key, child);
}
public readonly ScrollController controller;
public static ScrollController of(BuildContext context) {
PrimaryScrollController result =
(PrimaryScrollController) context.inheritFromWidgetOfExactType(typeof(PrimaryScrollController));
return result == null ? null : result.controller;
}
public override bool updateShouldNotify(InheritedWidget oldWidget) {
return this.controller != ((PrimaryScrollController) oldWidget).controller;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<ScrollController>("controller", this.controller,
ifNull: "no controller", showName: false));
}
}
}

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


fileFormatVersion: 2
guid: aaa3c6886fef4a7b80059bd64b818145
timeCreated: 1537172309

58
Assets/UIWidgets/widgets/scroll_configuration.cs


using UIWidgets.foundation;
using UIWidgets.painting;
namespace UIWidgets.widgets {
public class ScrollBehavior {
public Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
return child;
}
public ScrollPhysics getScrollPhysics(BuildContext context) {
return new BouncingScrollPhysics();
}
public virtual bool shouldNotify(ScrollBehavior oldDelegate) {
return false;
}
public override string ToString() {
return this.GetType().ToString();
}
}
public class ScrollConfiguration : InheritedWidget {
public ScrollConfiguration(
Key key = null,
ScrollBehavior behavior = null,
Widget child = null
) : base(key: key, child: child) {
D.assert(behavior != null);
this.behavior = behavior;
}
public readonly ScrollBehavior behavior;
public static ScrollBehavior of(BuildContext context) {
ScrollConfiguration configuration =
(ScrollConfiguration) context.inheritFromWidgetOfExactType(typeof(ScrollConfiguration));
if (configuration != null) {
return configuration.behavior;
}
return new ScrollBehavior();
}
public override bool updateShouldNotify(InheritedWidget oldWidgetRaw) {
var oldWidget = (ScrollConfiguration) oldWidgetRaw;
D.assert(this.behavior != null);
return this.behavior.GetType() != oldWidget.behavior.GetType()
|| this.behavior != oldWidget.behavior && this.behavior.shouldNotify(oldWidget.behavior);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<ScrollBehavior>("behavior", this.behavior));
}
}
}

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


fileFormatVersion: 2
guid: 64f86fe6ce0a475fa47b21a73a250752
timeCreated: 1537163722

192
Assets/UIWidgets/widgets/scroll_controller.cs


using System;
using System.Collections.Generic;
using System.Linq;
using RSG;
using UIWidgets.animation;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.widgets {
public class ScrollController : ChangeNotifier {
public ScrollController(
double initialScrollOffset = 0.0,
bool keepScrollOffset = true,
string debugLabel = null
) {
this._initialScrollOffset = initialScrollOffset;
this.keepScrollOffset = keepScrollOffset;
this.debugLabel = debugLabel;
}
public virtual double initialScrollOffset {
get { return this._initialScrollOffset; }
}
readonly double _initialScrollOffset;
public readonly bool keepScrollOffset;
public readonly string debugLabel;
public IEnumerable<ScrollPosition> positions {
get { return this._positions; }
}
readonly List<ScrollPosition> _positions = new List<ScrollPosition>();
public bool hasClients {
get { return this._positions.isNotEmpty(); }
}
public ScrollPosition position {
get {
D.assert(this._positions.isNotEmpty(), "ScrollController not attached to any scroll views.");
D.assert(this._positions.Count == 1, "ScrollController attached to multiple scroll views.");
return this._positions.Single();
}
}
public double offset {
get { return this.position.pixels; }
}
public IPromise animateTo(double to,
TimeSpan duration,
Curve curve
) {
D.assert(this._positions.isNotEmpty(), "ScrollController not attached to any scroll views.");
List<IPromise> animations = new List<IPromise>(this._positions.Count);
for (int i = 0; i < this._positions.Count; i += 1) {
animations[i] = this._positions[i].animateTo(to, duration: duration, curve: curve);
}
return Promise.All(animations);
}
public void jumpTo(double value) {
D.assert(this._positions.isNotEmpty(), "ScrollController not attached to any scroll views.");
foreach (ScrollPosition position in new List<ScrollPosition>(this._positions)) {
position.jumpTo(value);
}
}
public virtual void attach(ScrollPosition position) {
D.assert(!this._positions.Contains(position));
this._positions.Add(position);
position.addListener(this.notifyListeners);
}
public virtual void detach(ScrollPosition position) {
D.assert(this._positions.Contains(position));
position.removeListener(this.notifyListeners);
this._positions.Remove(position);
}
public override void dispose() {
foreach (ScrollPosition position in this._positions) {
position.removeListener(this.notifyListeners);
}
base.dispose();
}
public ScrollPosition createScrollPosition(
ScrollPhysics physics,
ScrollContext context,
ScrollPosition oldPosition
) {
return new ScrollPositionWithSingleContext(
physics: physics,
context: context,
initialPixels: this.initialScrollOffset,
keepScrollOffset: this.keepScrollOffset,
oldPosition: oldPosition,
debugLabel: this.debugLabel
);
}
public override string ToString() {
List<string> description = new List<string>();
this.debugFillDescription(description);
return string.Format("{0}({1})", Diagnostics.describeIdentity(this),
string.Join(", ", description.ToArray()));
}
protected virtual void debugFillDescription(List<string> description) {
if (this.debugLabel != null) {
description.Add(this.debugLabel);
}
if (this.initialScrollOffset != 0.0) {
description.Add(string.Format("initialScrollOffset: {0:F1}, ", this.initialScrollOffset));
}
if (this._positions.isEmpty()) {
description.Add("no clients");
} else if (this._positions.Count == 1) {
description.Add(string.Format("one client, offset {0:F1}", this.offset));
} else {
description.Add(this._positions.Count + " clients");
}
}
}
public class TrackingScrollController : ScrollController {
public TrackingScrollController(
double initialScrollOffset = 0.0,
bool keepScrollOffset = true,
String debugLabel = null
) : base(initialScrollOffset: initialScrollOffset,
keepScrollOffset: keepScrollOffset,
debugLabel: debugLabel) {
}
readonly Dictionary<ScrollPosition, VoidCallback> _positionToListener =
new Dictionary<ScrollPosition, VoidCallback>();
ScrollPosition _lastUpdated;
double? _lastUpdatedOffset;
public ScrollPosition mostRecentlyUpdatedPosition {
get { return this._lastUpdated; }
}
public override double initialScrollOffset {
get { return this._lastUpdatedOffset ?? base.initialScrollOffset; }
}
public override void attach(ScrollPosition position) {
base.attach(position);
D.assert(!this._positionToListener.ContainsKey(position));
this._positionToListener[position] = () => {
this._lastUpdated = position;
this._lastUpdatedOffset = position.pixels;
};
position.addListener(this._positionToListener[position]);
}
public override void detach(ScrollPosition position) {
base.detach(position);
D.assert(this._positionToListener.ContainsKey(position));
position.removeListener(this._positionToListener[position]);
this._positionToListener.Remove(position);
if (this._lastUpdated == position) {
this._lastUpdated = null;
}
if (this._positionToListener.isEmpty()) {
this._lastUpdatedOffset = null;
}
}
public override void dispose() {
foreach (ScrollPosition position in this.positions) {
D.assert(this._positionToListener.ContainsKey(position));
position.removeListener(this._positionToListener[position]);
}
base.dispose();
}
}
}

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


fileFormatVersion: 2
guid: 1ae725e691fc4453b2fe1a0e5d40c642
timeCreated: 1537160307

205
Assets/UIWidgets/widgets/scroll_position_with_single_context.cs


using System;
using System.Collections.Generic;
using RSG;
using UIWidgets.animation;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.physics;
using UIWidgets.rendering;
using UIWidgets.ui;
namespace UIWidgets.widgets {
public class ScrollPositionWithSingleContext : ScrollPosition, ScrollActivityDelegate {
public ScrollPositionWithSingleContext(
ScrollPhysics physics = null,
ScrollContext context = null,
double? initialPixels = 0.0,
bool keepScrollOffset = true,
ScrollPosition oldPosition = null,
string debugLabel = null
) : base(
physics: physics,
context: context,
keepScrollOffset: keepScrollOffset,
oldPosition: oldPosition,
debugLabel: debugLabel
) {
if (this._pixels == null && initialPixels != null) {
this.correctPixels(initialPixels.Value);
}
if (this.activity == null) {
this.goIdle();
}
D.assert(this.activity != null);
}
double _heldPreviousVelocity = 0.0;
public override AxisDirection axisDirection {
get { return this.context.axisDirection; }
}
public override double setPixels(double newPixels) {
D.assert(this.activity.isScrolling);
return base.setPixels(newPixels);
}
protected override void absorb(ScrollPosition other) {
base.absorb(other);
if (!(other is ScrollPositionWithSingleContext)) {
this.goIdle();
return;
}
this.activity.updateDelegate(this);
ScrollPositionWithSingleContext typedOther = (ScrollPositionWithSingleContext) other;
this._userScrollDirection = typedOther._userScrollDirection;
D.assert(this._currentDrag == null);
if (typedOther._currentDrag != null) {
this._currentDrag = typedOther._currentDrag;
this._currentDrag.updateDelegate(this);
typedOther._currentDrag = null;
}
}
protected override void applyNewDimensions() {
base.applyNewDimensions();
this.context.setCanDrag(this.physics.shouldAcceptUserOffset(this));
}
public override void beginActivity(ScrollActivity newActivity) {
this._heldPreviousVelocity = 0.0;
if (newActivity == null) {
return;
}
D.assert(newActivity.del == this);
base.beginActivity(newActivity);
if (this._currentDrag != null) {
this._currentDrag.dispose();
this._currentDrag = null;
}
if (!this.activity.isScrolling) {
this.updateUserScrollDirection(ScrollDirection.idle);
}
}
public virtual void applyUserOffset(double delta) {
this.updateUserScrollDirection(delta > 0.0 ? ScrollDirection.forward : ScrollDirection.reverse);
this.setPixels(this.pixels - this.physics.applyPhysicsToUserOffset(this, delta));
}
public void goIdle() {
this.beginActivity(new IdleScrollActivity(this));
}
public void goBallistic(double velocity) {
D.assert(this._pixels != null);
Simulation simulation = this.physics.createBallisticSimulation(this, velocity);
if (simulation != null) {
this.beginActivity(new BallisticScrollActivity(this, simulation, this.context.vsync));
} else {
this.goIdle();
}
}
public override ScrollDirection userScrollDirection {
get { return this._userScrollDirection; }
}
ScrollDirection _userScrollDirection = ScrollDirection.idle;
protected void updateUserScrollDirection(ScrollDirection value) {
if (this.userScrollDirection == value) {
return;
}
this._userScrollDirection = value;
this.didUpdateScrollDirection(value);
}
public override IPromise animateTo(double to,
TimeSpan duration,
Curve curve
) {
if (PhysicsUtils.nearEqual(to, this.pixels, this.physics.tolerance.distance)) {
this.jumpTo(to);
return Promise.Resolved();
}
DrivenScrollActivity activity = new DrivenScrollActivity(
this,
from: this.pixels,
to: to,
duration: duration,
curve: curve,
vsync: this.context.vsync
);
this.beginActivity(activity);
return activity.done;
}
public override void jumpTo(double value) {
this.goIdle();
if (this.pixels != value) {
double oldPixels = this.pixels;
this.forcePixels(value);
// this.notifyListeners(); already in forcePixels, no need here.
this.didStartScroll();
this.didUpdateScrollPositionBy(this.pixels - oldPixels);
this.didEndScroll();
}
this.goBallistic(0.0);
}
public override ScrollHoldController hold(VoidCallback holdCancelCallback) {
double previousVelocity = this.activity.velocity;
HoldScrollActivity holdActivity = new HoldScrollActivity(
del: this,
onHoldCanceled: holdCancelCallback
);
this.beginActivity(holdActivity);
this._heldPreviousVelocity = previousVelocity;
return holdActivity;
}
ScrollDragController _currentDrag;
public override Drag drag(DragStartDetails details, VoidCallback dragCancelCallback) {
ScrollDragController drag = new ScrollDragController(
del: this,
details: details,
onDragCanceled: dragCancelCallback,
carriedVelocity: this.physics.carriedMomentum(this._heldPreviousVelocity),
motionStartDistanceThreshold: this.physics.dragStartDistanceMotionThreshold
);
this.beginActivity(new DragScrollActivity(this, drag));
D.assert(this._currentDrag == null);
this._currentDrag = drag;
return drag;
}
public override void dispose() {
if (this._currentDrag != null) {
this._currentDrag.dispose();
this._currentDrag = null;
}
base.dispose();
}
protected override void debugFillDescription(List<String> description) {
base.debugFillDescription(description);
description.Add(this.context.GetType().ToString());
description.Add(this.physics.ToString());
description.Add(this.activity.ToString());
description.Add(this.userScrollDirection.ToString());
}
}
}

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


fileFormatVersion: 2
guid: 9379d18fbd274c9b834f6d440e39959d
timeCreated: 1537159068

437
Assets/UIWidgets/widgets/scroll_view.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.rendering;
namespace UIWidgets.widgets {
public abstract class ScrollView : StatelessWidget {
protected ScrollView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
double? cacheExtent = null
) : base(key: key) {
D.assert(!(controller != null && primary == true),
"Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. " +
"You cannot both set primary to true and pass an explicit controller.");
primary = primary ?? controller == null && scrollDirection == Axis.vertical;
physics = physics ?? (primary.Value ? new AlwaysScrollableScrollPhysics() : null);
this.scrollDirection = scrollDirection;
this.reverse = reverse;
this.controller = controller;
this.primary = primary.Value;
this.physics = physics;
this.shrinkWrap = shrinkWrap;
this.cacheExtent = cacheExtent;
}
public readonly Axis scrollDirection;
public readonly bool reverse;
public readonly ScrollController controller;
public readonly bool primary;
public readonly ScrollPhysics physics;
public readonly bool shrinkWrap;
public readonly double? cacheExtent;
protected AxisDirection getDirection(BuildContext context) {
return AxisUtils.getAxisDirectionFromAxisReverseAndDirectionality(
context, this.scrollDirection, this.reverse);
}
protected abstract List<Widget> buildSlivers(BuildContext context);
protected Widget buildViewport(
BuildContext context,
ViewportOffset offset,
AxisDirection axisDirection,
List<Widget> slivers
) {
if (this.shrinkWrap) {
return new ShrinkWrappingViewport(
axisDirection: axisDirection,
offset: offset,
slivers: slivers
);
}
return new Viewport(
axisDirection: axisDirection,
offset: offset,
slivers: slivers,
cacheExtent: this.cacheExtent
);
}
public override Widget build(BuildContext context) {
List<Widget> slivers = this.buildSlivers(context);
AxisDirection axisDirection = this.getDirection(context);
ScrollController scrollController = this.primary ? PrimaryScrollController.of(context) : this.controller;
Scrollable scrollable = new Scrollable(
axisDirection: axisDirection,
controller: scrollController,
physics: this.physics,
viewportBuilder: (viewportContext, offset) =>
this.buildViewport(viewportContext, offset, axisDirection, slivers)
);
return this.primary && scrollController != null
? (Widget) PrimaryScrollController.none(child: scrollable)
: scrollable;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<Axis>("scrollDirection", this.scrollDirection));
properties.add(new FlagProperty("reverse", value: this.reverse, ifTrue: "reversed", showName: true));
properties.add(new DiagnosticsProperty<ScrollController>("controller", this.controller, showName: false,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new FlagProperty("primary", value: this.primary, ifTrue: "using primary controller",
showName: true));
properties.add(new DiagnosticsProperty<ScrollPhysics>("physics", this.physics, showName: false,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new FlagProperty("shrinkWrap", value: this.shrinkWrap, ifTrue: "shrink-wrapping",
showName: true));
}
}
public class CustomScrollView : ScrollView {
public CustomScrollView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
double? cacheExtent = null,
List<Widget> slivers = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
cacheExtent: cacheExtent
) {
this.slivers = slivers ?? new List<Widget>();
}
public readonly List<Widget> slivers;
protected override List<Widget> buildSlivers(BuildContext context) {
return this.slivers;
}
}
public abstract class BoxScrollView : ScrollView {
public BoxScrollView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
double? cacheExtent = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
cacheExtent: cacheExtent
) {
this.padding = padding;
}
public readonly EdgeInsets padding;
protected override List<Widget> buildSlivers(BuildContext context) {
Widget sliver = this.buildChildLayout(context);
EdgeInsets effectivePadding = this.padding; // no need to check MediaQuery for now.
if (effectivePadding != null) {
sliver = new SliverPadding(padding: effectivePadding, sliver: sliver);
}
return new List<Widget> {sliver};
}
protected abstract Widget buildChildLayout(BuildContext context);
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", this.padding,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
public class ListView : BoxScrollView {
public ListView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
double? itemExtent = null,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double? cacheExtent = null,
List<Widget> children = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
this.itemExtent = itemExtent;
this.childrenDelegate = new SliverChildListDelegate(
children,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries
);
}
private ListView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
double? itemExtent = null,
IndexedWidgetBuilder itemBuilder = null,
int? itemCount = null,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double? cacheExtent = null
) : base(key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
this.itemExtent = itemExtent;
this.childrenDelegate = new SliverChildBuilderDelegate(
itemBuilder,
childCount: itemCount,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries
);
}
public static ListView builder(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
double? itemExtent = null,
IndexedWidgetBuilder itemBuilder = null,
int? itemCount = null,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double? cacheExtent = null
) {
return new ListView(
key,
scrollDirection,
reverse,
controller,
primary,
physics,
shrinkWrap,
padding,
itemExtent,
itemBuilder,
itemCount,
addAutomaticKeepAlives,
addRepaintBoundaries
);
}
private ListView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
IndexedWidgetBuilder itemBuilder = null,
IndexedWidgetBuilder separatorBuilder = null,
int itemCount = 0,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double? cacheExtent = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
D.assert(itemBuilder != null);
D.assert(separatorBuilder != null);
D.assert(itemCount >= 0);
this.itemExtent = null;
this.childrenDelegate = new SliverChildBuilderDelegate(
(context, index) => {
int itemIndex = index / 2;
return index % 2 == 0
? itemBuilder(context, itemIndex)
: separatorBuilder(context, itemIndex);
},
childCount: Math.Max(0, itemCount * 2 - 1),
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries
);
}
public static ListView seperated(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
IndexedWidgetBuilder itemBuilder = null,
IndexedWidgetBuilder separatorBuilder = null,
int itemCount = 0,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double? cacheExtent = null
) {
return new ListView(
key,
scrollDirection,
reverse,
controller,
primary,
physics,
shrinkWrap,
padding,
itemBuilder,
separatorBuilder,
itemCount,
addAutomaticKeepAlives,
addRepaintBoundaries,
cacheExtent
);
}
private ListView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
double? itemExtent = null,
SliverChildDelegate childrenDelegate = null,
double? cacheExtent = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
D.assert(childrenDelegate != null);
this.itemExtent = itemExtent;
this.childrenDelegate = childrenDelegate;
}
public static ListView custom(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
double? itemExtent = null,
SliverChildDelegate childrenDelegate = null,
double? cacheExtent = null
) {
return new ListView(
key,
scrollDirection,
reverse,
controller,
primary,
physics,
shrinkWrap,
padding,
itemExtent,
childrenDelegate,
cacheExtent);
}
public readonly double? itemExtent;
public readonly SliverChildDelegate childrenDelegate;
protected override Widget buildChildLayout(BuildContext context) {
if (this.itemExtent != null) {
return new SliverFixedExtentList(
del: this.childrenDelegate,
itemExtent: this.itemExtent.Value
);
}
return new SliverList(del: this.childrenDelegate);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DoubleProperty("itemExtent", this.itemExtent,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
}

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


fileFormatVersion: 2
guid: 167b885cf5254b048c2bac3acf71aafa
timeCreated: 1537171143

391
Assets/UIWidgets/widgets/scrollable.cs


using System;
using System.Collections.Generic;
using System.Linq;
using RSG;
using UIWidgets.animation;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.rendering;
using UIWidgets.scheduler;
using UIWidgets.ui;
namespace UIWidgets.widgets {
public delegate Widget ViewportBuilder(BuildContext context, ViewportOffset position);
public class Scrollable : StatefulWidget {
public Scrollable(
Key key = null,
AxisDirection axisDirection = AxisDirection.down,
ScrollController controller = null,
ScrollPhysics physics = null,
ViewportBuilder viewportBuilder = null
) : base(key: key) {
D.assert(viewportBuilder != null);
this.axisDirection = axisDirection;
this.controller = controller;
this.physics = physics;
this.viewportBuilder = viewportBuilder;
}
public readonly AxisDirection axisDirection;
public readonly ScrollController controller;
public readonly ScrollPhysics physics;
public readonly ViewportBuilder viewportBuilder;
public Axis axis {
get { return AxisUtils.axisDirectionToAxis(this.axisDirection); }
}
public override State createState() {
return new ScrollableState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<AxisDirection>("axisDirection", this.axisDirection));
properties.add(new DiagnosticsProperty<ScrollPhysics>("physics", this.physics));
}
public static ScrollableState of(BuildContext context) {
_ScrollableScope widget = (_ScrollableScope) context.inheritFromWidgetOfExactType(typeof(_ScrollableScope));
return widget == null ? null : widget.scrollable;
}
public static IPromise ensureVisible(BuildContext context,
double alignment = 0.0,
TimeSpan? duration = null,
Curve curve = null
) {
duration = duration ?? TimeSpan.Zero;
curve = curve ?? Curves.ease;
List<IPromise> futures = new List<IPromise>();
ScrollableState scrollable = Scrollable.of(context);
while (scrollable != null) {
futures.Add(scrollable.position.ensureVisible(
context.findRenderObject(),
alignment: alignment,
duration: duration,
curve: curve
));
context = scrollable.context;
scrollable = Scrollable.of(context);
}
if (futures.isEmpty() || duration == TimeSpan.Zero) {
return Promise.Resolved();
}
if (futures.Count == 1) {
return futures.Single();
}
return Promise.All(futures);
}
}
class _ScrollableScope : InheritedWidget {
internal _ScrollableScope(
Key key = null,
ScrollableState scrollable = null,
ScrollPosition position = null,
Widget child = null
) : base(key: key, child: child) {
D.assert(scrollable != null);
D.assert(child != null);
this.scrollable = scrollable;
this.position = position;
}
public readonly ScrollableState scrollable;
public readonly ScrollPosition position;
public override bool updateShouldNotify(InheritedWidget old) {
return this.position != ((_ScrollableScope) old).position;
}
}
public class ScrollableState : TickerProviderStateMixin<Scrollable>, ScrollContext {
public ScrollPosition position {
get { return this._position; }
}
ScrollPosition _position;
public AxisDirection axisDirection {
get { return this.widget.axisDirection; }
}
ScrollBehavior _configuration;
ScrollPhysics _physics;
void _updatePosition() {
this._configuration = ScrollConfiguration.of(this.context);
this._physics = this._configuration.getScrollPhysics(this.context);
if (this.widget.physics != null) {
this._physics = this.widget.physics.applyTo(this._physics);
}
ScrollController controller = this.widget.controller;
ScrollPosition oldPosition = this.position;
if (oldPosition != null) {
if (controller != null) {
controller.detach(oldPosition);
}
Window.instance.scheduleMicrotask(oldPosition.dispose);
}
this._position = controller == null
? null
: controller.createScrollPosition(this._physics, this, oldPosition);
this._position = this._position
?? new ScrollPositionWithSingleContext(physics: this._physics, context: this,
oldPosition: oldPosition);
D.assert(this.position != null);
if (controller != null) {
controller.attach(this.position);
}
}
public override void didChangeDependencies() {
base.didChangeDependencies();
this._updatePosition();
}
bool _shouldUpdatePosition(Scrollable oldWidget) {
ScrollPhysics newPhysics = this.widget.physics;
ScrollPhysics oldPhysics = oldWidget.physics;
do {
Type newPhysicsType = newPhysics != null ? newPhysics.GetType() : null;
Type oldPhysicsType = oldPhysics != null ? oldPhysics.GetType() : null;
if (newPhysicsType != oldPhysicsType) {
return true;
}
if (newPhysics != null) {
newPhysics = newPhysics.parent;
}
if (oldPhysics != null) {
oldPhysics = oldPhysics.parent;
}
} while (newPhysics != null || oldPhysics != null);
Type controllerType = this.widget.controller == null ? null : this.widget.controller.GetType();
Type oldControllerType = oldWidget.controller == null ? null : oldWidget.controller.GetType();
return controllerType != oldControllerType;
}
public override void didUpdateWidget(StatefulWidget oldWidgetRaw) {
Scrollable oldWidget = (Scrollable) oldWidgetRaw;
base.didUpdateWidget(oldWidget);
if (this.widget.controller != oldWidget.controller) {
if (oldWidget.controller != null) {
oldWidget.controller.detach(this.position);
}
if (this.widget.controller != null) {
this.widget.controller.attach(this.position);
}
}
if (this._shouldUpdatePosition(oldWidget)) {
this._updatePosition();
}
}
public override void dispose() {
if (this.widget.controller != null) {
this.widget.controller.detach(this.position);
}
this.position.dispose();
base.dispose();
}
readonly GlobalKey<RawGestureDetectorState> _gestureDetectorKey = GlobalKey<RawGestureDetectorState>.key();
readonly GlobalKey _ignorePointerKey = GlobalKey.key();
Dictionary<Type, GestureRecognizerFactory> _gestureRecognizers =
new Dictionary<Type, GestureRecognizerFactory>();
bool _shouldIgnorePointer = false;
bool _lastCanDrag;
Axis _lastAxisDirection;
public void setCanDrag(bool canDrag) {
if (canDrag == this._lastCanDrag && (!canDrag || this.widget.axis == this._lastAxisDirection)) {
return;
}
if (!canDrag) {
this._gestureRecognizers = new Dictionary<Type, GestureRecognizerFactory>();
} else {
switch (this.widget.axis) {
case Axis.vertical:
this._gestureRecognizers = new Dictionary<Type, GestureRecognizerFactory>();
this._gestureRecognizers.Add(typeof(VerticalDragGestureRecognizer),
new GestureRecognizerFactoryWithHandlers<VerticalDragGestureRecognizer>(
() => new VerticalDragGestureRecognizer(),
instance => {
instance.onDown = this._handleDragDown;
instance.onStart = this._handleDragStart;
instance.onUpdate = this._handleDragUpdate;
instance.onEnd = this._handleDragEnd;
instance.onCancel = this._handleDragCancel;
instance.minFlingDistance =
this._physics == null ? (double?) null : this._physics.minFlingDistance;
instance.minFlingVelocity =
this._physics == null ? (double?) null : this._physics.minFlingVelocity;
instance.maxFlingVelocity =
this._physics == null ? (double?) null : this._physics.maxFlingVelocity;
}
));
break;
case Axis.horizontal:
this._gestureRecognizers = new Dictionary<Type, GestureRecognizerFactory>();
this._gestureRecognizers.Add(typeof(HorizontalDragGestureRecognizer),
new GestureRecognizerFactoryWithHandlers<HorizontalDragGestureRecognizer>(
() => new HorizontalDragGestureRecognizer(),
instance => {
instance.onDown = this._handleDragDown;
instance.onStart = this._handleDragStart;
instance.onUpdate = this._handleDragUpdate;
instance.onEnd = this._handleDragEnd;
instance.onCancel = this._handleDragCancel;
instance.minFlingDistance =
this._physics == null ? (double?) null : this._physics.minFlingDistance;
instance.minFlingVelocity =
this._physics == null ? (double?) null : this._physics.minFlingVelocity;
instance.maxFlingVelocity =
this._physics == null ? (double?) null : this._physics.maxFlingVelocity;
}
));
break;
}
}
this._lastCanDrag = canDrag;
this._lastAxisDirection = this.widget.axis;
if (this._gestureDetectorKey.currentState != null) {
this._gestureDetectorKey.currentState.replaceGestureRecognizers(this._gestureRecognizers);
}
}
public TickerProvider vsync {
get { return this; }
}
public void setIgnorePointer(bool value) {
if (this._shouldIgnorePointer == value) {
return;
}
this._shouldIgnorePointer = value;
if (this._ignorePointerKey.currentContext != null) {
var renderBox = (RenderIgnorePointer) this._ignorePointerKey.currentContext.findRenderObject();
renderBox.ignoring = this._shouldIgnorePointer;
}
}
public BuildContext notificationContext {
get { return this._gestureDetectorKey.currentContext; }
}
public BuildContext storageContext {
get { return this.context; }
}
Drag _drag;
ScrollHoldController _hold;
void _handleDragDown(DragDownDetails details) {
D.assert(this._drag == null);
D.assert(this._hold == null);
this._hold = this.position.hold(this._disposeHold);
}
void _handleDragStart(DragStartDetails details) {
D.assert(this._drag == null);
this._drag = this.position.drag(details, this._disposeDrag);
D.assert(this._drag != null);
D.assert(this._hold == null);
}
void _handleDragUpdate(DragUpdateDetails details) {
D.assert(this._hold == null || this._drag == null);
if (this._drag != null) {
this._drag.update(details);
}
}
void _handleDragEnd(DragEndDetails details) {
D.assert(this._hold == null || this._drag == null);
if (this._drag != null) {
this._drag.end(details);
}
D.assert(this._drag == null);
}
void _handleDragCancel() {
D.assert(this._hold == null || this._drag == null);
if (this._hold != null) {
this._hold.cancel();
}
if (this._drag != null) {
this._drag.cancel();
}
D.assert(this._hold == null);
D.assert(this._drag == null);
}
void _disposeHold() {
this._hold = null;
}
void _disposeDrag() {
this._drag = null;
}
public override Widget build(BuildContext context) {
D.assert(this.position != null);
Widget result = new RawGestureDetector(
key: this._gestureDetectorKey,
gestures: this._gestureRecognizers,
behavior: HitTestBehavior.opaque,
child: new IgnorePointer(
key: this._ignorePointerKey,
ignoring: this._shouldIgnorePointer,
child: new _ScrollableScope(
scrollable: this,
position: this.position,
child: this.widget.viewportBuilder(context, this.position)
)
)
);
return this._configuration.buildViewportChrome(context, result, this.widget.axisDirection);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<ScrollPosition>("position", this.position));
}
}
}

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


fileFormatVersion: 2
guid: c3917312a54a4263a839cd628ae99010
timeCreated: 1537160124

519
Assets/UIWidgets/widgets/sliver.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.rendering;
namespace UIWidgets.widgets {
public abstract class SliverChildDelegate {
protected SliverChildDelegate() {
}
public abstract Widget build(BuildContext context, int index);
public virtual int? estimatedChildCount {
get { return null; }
}
public virtual double? estimateMaxScrollOffset(
int firstIndex,
int lastIndex,
double leadingScrollOffset,
double trailingScrollOffset
) {
return null;
}
public virtual void didFinishLayout(int firstIndex, int lastIndex) {
}
public abstract bool shouldRebuild(SliverChildDelegate oldDelegate);
public override string ToString() {
var description = new List<string>();
this.debugFillDescription(description);
return string.Format("{0}({1})", Diagnostics.describeIdentity(this),
string.Join(", ", description.ToArray()));
}
protected virtual void debugFillDescription(List<String> description) {
try {
var children = this.estimatedChildCount;
if (children != null) {
description.Add("estimated child count: " + children);
}
}
catch (Exception ex) {
description.Add("estimated child count: EXCEPTION (" + ex.GetType() + ")");
}
}
}
public class SliverChildBuilderDelegate : SliverChildDelegate {
public SliverChildBuilderDelegate(
IndexedWidgetBuilder builder,
int? childCount = null,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true
) {
D.assert(builder != null);
this.builder = build;
this.childCount = childCount;
this.addAutomaticKeepAlives = addAutomaticKeepAlives;
this.addRepaintBoundaries = addRepaintBoundaries;
}
public readonly IndexedWidgetBuilder builder;
public readonly int? childCount;
public readonly bool addAutomaticKeepAlives;
public readonly bool addRepaintBoundaries;
public override Widget build(BuildContext context, int index) {
D.assert(this.builder != null);
if (index < 0 || (this.childCount != null && index >= this.childCount)) {
return null;
}
Widget child = this.builder(context, index);
if (child == null) {
return null;
}
if (this.addRepaintBoundaries) {
child = RepaintBoundary.wrap(child, index);
}
if (this.addAutomaticKeepAlives) {
child = new AutomaticKeepAlive(child: child);
}
return child;
}
public override int? estimatedChildCount {
get { return this.childCount; }
}
public override bool shouldRebuild(SliverChildDelegate oldDelegate) {
return true;
}
}
public class SliverChildListDelegate : SliverChildDelegate {
public SliverChildListDelegate(
List<Widget> children,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true
) {
D.assert(children != null);
this.children = children;
this.addAutomaticKeepAlives = addAutomaticKeepAlives;
this.addRepaintBoundaries = addRepaintBoundaries;
}
public readonly bool addAutomaticKeepAlives;
public readonly bool addRepaintBoundaries;
public readonly List<Widget> children;
public override Widget build(BuildContext context, int index) {
D.assert(this.children != null);
if (index < 0 || index >= this.children.Count) {
return null;
}
Widget child = this.children[index];
D.assert(child != null);
if (this.addRepaintBoundaries) {
child = RepaintBoundary.wrap(child, index);
}
if (this.addAutomaticKeepAlives) {
child = new AutomaticKeepAlive(child: child);
}
return child;
}
public override int? estimatedChildCount {
get { return this.children.Count; }
}
public override bool shouldRebuild(SliverChildDelegate oldDelegate) {
return this.children != ((SliverChildListDelegate) oldDelegate).children;
}
}
public abstract class SliverMultiBoxAdaptorWidget : RenderObjectWidget {
protected SliverMultiBoxAdaptorWidget(
Key key = null,
SliverChildDelegate del = null
) : base(key: key) {
D.assert(del != null);
this.del = del;
}
public readonly SliverChildDelegate del;
public override Element createElement() {
return new SliverMultiBoxAdaptorElement(this);
}
public double? estimateMaxScrollOffset(
SliverConstraints constraints,
int firstIndex,
int lastIndex,
double leadingScrollOffset,
double trailingScrollOffset
) {
D.assert(lastIndex >= firstIndex);
return this.del.estimateMaxScrollOffset(
firstIndex,
lastIndex,
leadingScrollOffset,
trailingScrollOffset
);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<SliverChildDelegate>("del", this.del));
}
}
public class SliverList : SliverMultiBoxAdaptorWidget {
public SliverList(
Key key = null,
SliverChildDelegate del = null
) : base(key: key, del: del) {
}
public override RenderObject createRenderObject(BuildContext context) {
SliverMultiBoxAdaptorElement element = (SliverMultiBoxAdaptorElement) context;
return new RenderSliverList(childManager: element);
}
}
public class SliverFixedExtentList : SliverMultiBoxAdaptorWidget {
public SliverFixedExtentList(
Key key = null,
SliverChildDelegate del = null,
double itemExtent = 0
) : base(key: key, del: del) {
this.itemExtent = itemExtent;
}
public readonly double itemExtent;
public override RenderObject createRenderObject(BuildContext context) {
SliverMultiBoxAdaptorElement element = (SliverMultiBoxAdaptorElement) context;
return new RenderSliverFixedExtentList(childManager: element, itemExtent: this.itemExtent);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObjectRaw) {
var renderObject = (RenderSliverFixedExtentList) renderObjectRaw;
renderObject.itemExtent = this.itemExtent;
}
}
public class SliverMultiBoxAdaptorElement : RenderObjectElement, RenderSliverBoxChildManager {
public SliverMultiBoxAdaptorElement(SliverMultiBoxAdaptorWidget widget) : base(widget) {
}
public new SliverMultiBoxAdaptorWidget widget {
get { return (SliverMultiBoxAdaptorWidget) base.widget; }
}
public new RenderSliverMultiBoxAdaptor renderObject {
get { return (RenderSliverMultiBoxAdaptor) base.renderObject; }
}
public override void update(Widget newWidgetRaw) {
var newWidget = (SliverMultiBoxAdaptorWidget) newWidgetRaw;
SliverMultiBoxAdaptorWidget oldWidget = this.widget;
base.update(newWidget);
SliverChildDelegate newDelegate = newWidget.del;
SliverChildDelegate oldDelegate = oldWidget.del;
if (newDelegate != oldDelegate &&
(newDelegate.GetType() != oldDelegate.GetType() || newDelegate.shouldRebuild(oldDelegate))) {
this.performRebuild();
}
}
Dictionary<int, Widget> _childWidgets = new Dictionary<int, Widget>();
SortedDictionary<int, Element> _childElements = new SortedDictionary<int, Element>();
RenderBox _currentBeforeChild;
protected override void performRebuild() {
this._childWidgets.Clear();
base.performRebuild();
this._currentBeforeChild = null;
D.assert(this._currentlyUpdatingChildIndex == null);
try {
int firstIndex = 0;
int lastIndex = 0;
if (!this._childElements.isEmpty()) {
firstIndex = this._childElements.Keys.First();
lastIndex = this._childElements.Keys.Last();
if (this._didUnderflow) {
lastIndex += 1;
}
}
for (int index = firstIndex; index <= lastIndex; ++index) {
this._currentlyUpdatingChildIndex = index;
Element newChild = this.updateChild(this._childElements[index], this._build(index), index);
if (newChild != null) {
this._childElements[index] = newChild;
this._currentBeforeChild = (RenderBox) newChild.renderObject;
} else {
this._childElements.Remove(index);
}
}
}
finally {
this._currentlyUpdatingChildIndex = null;
}
}
Widget _build(int index) {
return this._childWidgets.putIfAbsent(index, () => this.widget.del.build(this, index));
}
public void createChild(int index, RenderBox after = null) {
D.assert(this._currentlyUpdatingChildIndex == null);
this.owner.buildScope(this, () => {
bool insertFirst = after == null;
D.assert(insertFirst || this._childElements[index - 1] != null);
this._currentBeforeChild = insertFirst ? null : (RenderBox) this._childElements[index - 1].renderObject;
Element newChild;
try {
this._currentlyUpdatingChildIndex = index;
newChild = this.updateChild(this._childElements[index], this._build(index), index);
}
finally {
this._currentlyUpdatingChildIndex = null;
}
if (newChild != null) {
this._childElements[index] = newChild;
} else {
this._childElements.Remove(index);
}
});
}
protected override Element updateChild(Element child, Widget newWidget, object newSlot) {
SliverMultiBoxAdaptorParentData oldParentData = null;
if (child != null && child.renderObject != null) {
oldParentData = (SliverMultiBoxAdaptorParentData) child.renderObject.parentData;
}
Element newChild = base.updateChild(child, newWidget, newSlot);
SliverMultiBoxAdaptorParentData newParentData = null;
if (child != null && child.renderObject != null) {
newParentData = (SliverMultiBoxAdaptorParentData) newChild.renderObject.parentData;
}
if (oldParentData != newParentData && oldParentData != null && newParentData != null) {
newParentData.layoutOffset = oldParentData.layoutOffset;
}
return newChild;
}
protected override void forgetChild(Element child) {
D.assert(child != null);
D.assert(child.slot != null);
D.assert(this._childElements.ContainsKey((int) child.slot));
this._childElements.Remove((int) child.slot);
}
public void removeChild(RenderBox child) {
int index = this.renderObject.indexOf(child);
D.assert(this._currentlyUpdatingChildIndex == null);
D.assert(index >= 0);
this.owner.buildScope(this, () => {
D.assert(this._childElements.ContainsKey(index));
try {
this._currentlyUpdatingChildIndex = index;
Element result = this.updateChild(this._childElements[index], null, index);
D.assert(result == null);
}
finally {
this._currentlyUpdatingChildIndex = null;
}
this._childElements.Remove(index);
D.assert(!this._childElements.ContainsKey(index));
});
}
static double _extrapolateMaxScrollOffset(
int firstIndex,
int lastIndex,
double leadingScrollOffset,
double trailingScrollOffset,
int childCount
) {
if (lastIndex == childCount - 1)
return trailingScrollOffset;
int reifiedCount = lastIndex - firstIndex + 1;
double averageExtent = (trailingScrollOffset - leadingScrollOffset) / reifiedCount;
int remainingCount = childCount - lastIndex - 1;
return trailingScrollOffset + averageExtent * remainingCount;
}
public double? estimateMaxScrollOffset(SliverConstraints constraints,
int firstIndex = 0,
int lastIndex = 0,
double leadingScrollOffset = 0,
double trailingScrollOffset = 0
) {
int? childCount = this.childCount;
if (childCount == null) {
return double.PositiveInfinity;
}
return this.widget.estimateMaxScrollOffset(
constraints,
firstIndex,
lastIndex,
leadingScrollOffset,
trailingScrollOffset
) ?? _extrapolateMaxScrollOffset(
firstIndex,
lastIndex,
leadingScrollOffset,
trailingScrollOffset,
childCount.Value
);
}
public int? childCount {
get { return this.widget.del.estimatedChildCount; }
}
public void didStartLayout() {
D.assert(this.debugAssertChildListLocked());
}
public void didFinishLayout() {
D.assert(this.debugAssertChildListLocked());
int firstIndex = this._childElements.Keys.FirstOrDefault();
int lastIndex = this._childElements.Keys.LastOrDefault();
this.widget.del.didFinishLayout(firstIndex, lastIndex);
}
int? _currentlyUpdatingChildIndex;
public bool debugAssertChildListLocked() {
D.assert(this._currentlyUpdatingChildIndex == null);
return true;
}
public void didAdoptChild(RenderBox child) {
D.assert(this._currentlyUpdatingChildIndex != null);
SliverMultiBoxAdaptorParentData childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
childParentData.index = this._currentlyUpdatingChildIndex.Value;
}
bool _didUnderflow = false;
public void setDidUnderflow(bool value) {
this._didUnderflow = value;
}
protected override void insertChildRenderObject(RenderObject child, object slotRaw) {
D.assert(slotRaw != null);
int slot = (int) slotRaw;
D.assert(this._currentlyUpdatingChildIndex == slot);
D.assert(this.renderObject.debugValidateChild(child));
this.renderObject.insert((RenderBox) child, after: this._currentBeforeChild);
D.assert(() => {
SliverMultiBoxAdaptorParentData childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
D.assert(slot == childParentData.index);
return true;
});
}
protected override void moveChildRenderObject(RenderObject child, object slotRaw) {
D.assert(false);
}
protected override void removeChildRenderObject(RenderObject child) {
D.assert(this._currentlyUpdatingChildIndex != null);
this.renderObject.remove((RenderBox) child);
}
public override void visitChildren(ElementVisitor visitor) {
D.assert(!this._childElements.Values.Any(child => child == null));
this._childElements.Values.ToList().ForEach(e => visitor(e));
}
public override void debugVisitOnstageChildren(ElementVisitor visitor) {
this._childElements.Values.Where(child => {
SliverMultiBoxAdaptorParentData parentData =
(SliverMultiBoxAdaptorParentData) child.renderObject.parentData;
double itemExtent = 0;
switch (this.renderObject.constraints.axis) {
case Axis.horizontal:
itemExtent = child.renderObject.paintBounds.width;
break;
case Axis.vertical:
itemExtent = child.renderObject.paintBounds.height;
break;
}
return parentData.layoutOffset < this.renderObject.constraints.scrollOffset +
this.renderObject.constraints.remainingPaintExtent &&
parentData.layoutOffset + itemExtent > this.renderObject.constraints.scrollOffset;
}).ToList().ForEach(e => visitor(e));
}
}
public class KeepAlive : ParentDataWidget<SliverMultiBoxAdaptorWidget> {
public KeepAlive(
Key key = null,
bool keepAlive = true,
Widget child = null
) : base(key: key, child: child) {
D.assert(child != null);
this.keepAlive = keepAlive;
}
public readonly bool keepAlive;
public override void applyParentData(RenderObject renderObject) {
D.assert(renderObject.parentData is SliverMultiBoxAdaptorParentData);
SliverMultiBoxAdaptorParentData parentData = (SliverMultiBoxAdaptorParentData) renderObject.parentData;
if (parentData.keepAlive != this.keepAlive) {
parentData.keepAlive = this.keepAlive;
var targetParent = renderObject.parent;
if (targetParent is RenderObject && !this.keepAlive) {
((RenderObject) targetParent).markNeedsLayout();
}
}
}
public override bool debugCanApplyOutOfTurn() {
return this.keepAlive;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<bool>("keepAlive", this.keepAlive));
}
}
}

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


fileFormatVersion: 2
guid: 657ce5eaa41b4a498591bbb1682d04f4
timeCreated: 1537323273

189
Assets/UIWidgets/widgets/viewport.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.rendering;
namespace UIWidgets.widgets {
public class Viewport : MultiChildRenderObjectWidget {
public Viewport(
Key key = null,
AxisDirection axisDirection = AxisDirection.down,
AxisDirection? crossAxisDirection = null,
double anchor = 0.0,
ViewportOffset offset = null,
Key center = null,
double? cacheExtent = null,
List<Widget> slivers = null
) : base(key: key, children: slivers) {
D.assert(offset != null);
D.assert(center == null || this.children.Count(child => child.key == center) == 1);
this.axisDirection = axisDirection;
this.crossAxisDirection = crossAxisDirection;
this.anchor = anchor;
this.offset = offset;
this.center = center;
this.cacheExtent = cacheExtent;
}
public readonly AxisDirection axisDirection;
public readonly AxisDirection? crossAxisDirection;
public readonly double anchor;
public readonly ViewportOffset offset;
public readonly Key center;
public readonly double? cacheExtent;
public static AxisDirection getDefaultCrossAxisDirection(BuildContext context, AxisDirection axisDirection) {
switch (axisDirection) {
case AxisDirection.up:
return AxisUtils.textDirectionToAxisDirection(Directionality.of(context));
case AxisDirection.right:
return AxisDirection.down;
case AxisDirection.down:
return AxisUtils.textDirectionToAxisDirection(Directionality.of(context));
case AxisDirection.left:
return AxisDirection.down;
}
throw new Exception("unknown axisDirection");
}
public override RenderObject createRenderObject(BuildContext context) {
return new RenderViewport(
axisDirection: this.axisDirection,
crossAxisDirection: this.crossAxisDirection ??
Viewport.getDefaultCrossAxisDirection(context, this.axisDirection),
anchor: this.anchor,
offset: this.offset,
cacheExtent: this.cacheExtent
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObjectRaw) {
var renderObject = (RenderViewport) renderObjectRaw;
renderObject.axisDirection = this.axisDirection;
renderObject.crossAxisDirection = this.crossAxisDirection ??
Viewport.getDefaultCrossAxisDirection(context, this.axisDirection);
renderObject.anchor = this.anchor;
renderObject.offset = this.offset;
renderObject.cacheExtent = this.cacheExtent ?? RenderAbstractViewportUtils.defaultCacheExtent;
}
public override Element createElement() {
return new _ViewportElement(this);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<AxisDirection>("axisDirection", this.axisDirection));
properties.add(new EnumProperty<AxisDirection?>("crossAxisDirection", this.crossAxisDirection,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DoubleProperty("anchor", this.anchor));
properties.add(new DiagnosticsProperty<ViewportOffset>("offset", this.offset));
if (this.center != null) {
properties.add(new DiagnosticsProperty<Key>("center", this.center));
} else if (this.children.isNotEmpty() && this.children.First().key != null) {
properties.add(new DiagnosticsProperty<Key>("center", this.children.First().key, tooltip: "implicit"));
}
}
}
class _ViewportElement : MultiChildRenderObjectElement {
internal _ViewportElement(Viewport widget) : base(widget) {
}
public new Viewport widget {
get { return (Viewport) base.widget; }
}
public new RenderViewport renderObject {
get { return (RenderViewport) base.renderObject; }
}
public override void mount(Element parent, object newSlot) {
base.mount(parent, newSlot);
this._updateCenter();
}
public override void update(Widget newWidget) {
base.update(newWidget);
this._updateCenter();
}
void _updateCenter() {
if (this.widget.center != null) {
this.renderObject.center = (RenderSliver) this.children.Single(
element => element.widget.key == this.widget.center).renderObject;
} else if (this.children.Any()) {
this.renderObject.center = (RenderSliver) this.children.First().renderObject;
} else {
this.renderObject.center = null;
}
}
public override void debugVisitOnstageChildren(ElementVisitor visitor) {
this.children.Where(e => {
RenderSliver renderSliver = (RenderSliver) e.renderObject;
return renderSliver.geometry.visible;
}).ToList().ForEach(e => visitor(e));
}
}
public class ShrinkWrappingViewport : MultiChildRenderObjectWidget {
public ShrinkWrappingViewport(
Key key = null,
AxisDirection axisDirection = AxisDirection.down,
AxisDirection? crossAxisDirection = null,
ViewportOffset offset = null,
List<Widget> slivers = null
) : base(key: key, children: slivers) {
D.assert(offset != null);
this.axisDirection = axisDirection;
this.crossAxisDirection = crossAxisDirection;
this.offset = offset;
}
public readonly AxisDirection axisDirection;
public readonly AxisDirection? crossAxisDirection;
public readonly ViewportOffset offset;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderShrinkWrappingViewport(
axisDirection: this.axisDirection,
crossAxisDirection: this.crossAxisDirection
?? Viewport.getDefaultCrossAxisDirection(context, this.axisDirection),
offset: this.offset
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObjectRaw) {
var renderObject = (RenderShrinkWrappingViewport) renderObjectRaw;
renderObject.axisDirection = this.axisDirection;
renderObject.crossAxisDirection = this.crossAxisDirection
?? Viewport.getDefaultCrossAxisDirection(context, this.axisDirection);
renderObject.offset = this.offset;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<AxisDirection>("axisDirection", this.axisDirection));
properties.add(new EnumProperty<AxisDirection?>("crossAxisDirection", this.crossAxisDirection,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DiagnosticsProperty<ViewportOffset>("offset", this.offset));
}
}
}

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


fileFormatVersion: 2
guid: cbc0da359825401197d0c5772ebdaac1
timeCreated: 1537172721
正在加载...
取消
保存