浏览代码

Merge pull request #289 from UnityTech/hook1.5.4

Hook1.5.4
/main
GitHub 5 年前
当前提交
b3e5905c
共有 198 个文件被更改,包括 3445 次插入2214 次删除
  1. 67
      Runtime/animation/curves.cs
  2. 13
      Runtime/foundation/basic_types.cs
  3. 8
      Runtime/foundation/diagnostics.cs
  4. 10
      Runtime/gestures/binding.cs
  5. 2
      Runtime/gestures/constants.cs
  6. 48
      Runtime/gestures/converter.cs
  7. 730
      Runtime/gestures/events.cs
  8. 160
      Runtime/gestures/long_press.cs
  9. 3
      Runtime/gestures/monodrag.cs
  10. 8
      Runtime/gestures/mouse_tracking.cs
  11. 240
      Runtime/gestures/multitap.cs
  12. 6
      Runtime/gestures/scale.cs
  13. 23
      Runtime/gestures/tap.cs
  14. 9
      Runtime/material/app.cs
  15. 39
      Runtime/material/app_bar.cs
  16. 10
      Runtime/material/app_bar_theme.cs
  17. 407
      Runtime/material/bottom_navigation_bar.cs
  18. 2
      Runtime/material/button_theme.cs
  19. 108
      Runtime/material/chip.cs
  20. 22
      Runtime/material/chip_theme.cs
  21. 2
      Runtime/material/dialog.cs
  22. 3
      Runtime/material/drawer.cs
  23. 131
      Runtime/material/dropdown.cs
  24. 32
      Runtime/material/expansion_panel.cs
  25. 4
      Runtime/material/ink_well.cs
  26. 4
      Runtime/material/input_border.cs
  27. 287
      Runtime/material/input_decorator.cs
  28. 18
      Runtime/material/list_tile.cs
  29. 6
      Runtime/material/material.cs
  30. 4
      Runtime/material/material_button.cs
  31. 1
      Runtime/material/popup_menu.cs
  32. 16
      Runtime/material/progress_indicator.cs
  33. 3
      Runtime/material/radio.cs
  34. 113
      Runtime/material/scaffold.cs
  35. 12
      Runtime/material/slider.cs
  36. 4
      Runtime/material/switch.cs
  37. 9
      Runtime/material/tab_bar_theme.cs
  38. 41
      Runtime/material/tabs.cs
  39. 143
      Runtime/material/text_field.cs
  40. 14
      Runtime/material/text_form_field.cs
  41. 2
      Runtime/material/text_selection.cs
  42. 16
      Runtime/material/theme_data.cs
  43. 7
      Runtime/material/user_accounts_drawer_header.cs
  44. 2
      Runtime/material/floating_action_button_location.cs.meta
  45. 2
      Runtime/material/floating_action_button.cs.meta
  46. 7
      Runtime/painting/box_border.cs
  47. 26
      Runtime/painting/decoration_image.cs
  48. 98
      Runtime/painting/gradient.cs
  49. 26
      Runtime/painting/image_stream.cs
  50. 20
      Runtime/painting/notched_shapes.cs
  51. 90
      Runtime/painting/text_painter.cs
  52. 192
      Runtime/painting/text_style.cs
  53. 1
      Runtime/rendering/binding.cs
  54. 6
      Runtime/rendering/box.cs
  55. 2
      Runtime/rendering/custom_layout.cs
  56. 131
      Runtime/rendering/editable.cs
  57. 2
      Runtime/rendering/error.cs
  58. 7
      Runtime/rendering/flex.cs
  59. 2
      Runtime/rendering/image.cs
  60. 164
      Runtime/rendering/layer.cs
  61. 2
      Runtime/rendering/list_body.cs
  62. 9
      Runtime/rendering/object.cs
  63. 47
      Runtime/rendering/paragraph.cs
  64. 2
      Runtime/rendering/performance_overlay.cs
  65. 112
      Runtime/rendering/proxy_box.cs
  66. 2
      Runtime/rendering/proxy_box.mixin.gen.cs
  67. 2
      Runtime/rendering/rotated_box.cs
  68. 10
      Runtime/rendering/shifted_box.cs
  69. 3
      Runtime/rendering/sliver.cs
  70. 3
      Runtime/rendering/sliver_grid.cs
  71. 2
      Runtime/rendering/sliver_list.cs
  72. 2
      Runtime/rendering/stack.cs
  73. 2
      Runtime/rendering/table.cs
  74. 2
      Runtime/rendering/viewport.cs
  75. 2
      Runtime/rendering/wrap.cs
  76. 97
      Runtime/ui/painting/path.cs
  77. 23
      Runtime/ui/painting/txt/font_manager.cs
  78. 87
      Runtime/ui/pointer.cs
  79. 6
      Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs
  80. 43
      Runtime/ui/text.cs
  81. 1001
      Runtime/ui/txt/paragraph.cs
  82. 7
      Runtime/ui/window.cs
  83. 47
      Runtime/widgets/app.cs
  84. 16
      Runtime/widgets/basic.cs
  85. 2
      Runtime/widgets/dismissible.cs
  86. 221
      Runtime/widgets/editable_text.cs
  87. 10
      Runtime/widgets/fade_in_image.cs
  88. 4
      Runtime/widgets/form.cs
  89. 53
      Runtime/widgets/gesture_detector.cs
  90. 81
      Runtime/widgets/heroes.cs
  91. 2
      Runtime/widgets/icon.cs
  92. 2
      Runtime/widgets/layout_builder.cs
  93. 4
      Runtime/widgets/nested_scroll_view.cs
  94. 83
      Runtime/widgets/overlay.cs
  95. 7
      Runtime/widgets/page_view.cs
  96. 8
      Runtime/widgets/routes.cs
  97. 26
      Runtime/widgets/scroll_view.cs
  98. 45
      Runtime/widgets/scrollable.cs
  99. 4
      Runtime/widgets/single_child_scroll_view.cs
  100. 13
      Runtime/widgets/text.cs

67
Runtime/animation/curves.cs


using System;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
using UnityEngine;

public abstract float transform(float t);
public float transform(float t) {
D.assert(t >= 0.0f && t <= 1.0f);
if (t == 0.0f || t == 1.0f) {
return t;
}
return this.transformInternal(t);
}
protected virtual float transformInternal(float t) {
throw new NotImplementedException();
}
public Curve flipped {
get { return new FlippedCurve(this); }

}
class _Linear : Curve {
public override float transform(float t) {
protected override float transformInternal(float t) {
return t;
}
}

public readonly int count;
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
if (t == 1.0f) {
return 1.0f;
}
protected override float transformInternal(float t) {
t *= this.count;
return t - (int) t;
}

public readonly Curve curve;
public override float transform(float t) {
protected override float transformInternal(float t) {
D.assert(t >= 0.0 && t <= 1.0);
D.assert(this.begin >= 0.0);
D.assert(this.begin <= 1.0);

if (t == 0.0 || t == 1.0) {
return t;
}
t = ((t - this.begin) / (this.end - this.begin)).clamp(0.0f, 1.0f);
if (t == 0.0 || t == 1.0) {
return t;

public readonly float threshold;
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
protected override float transformInternal(float t) {
if (t == 0.0 || t == 1.0) {
return t;
}
return t < this.threshold ? 0.0f : 1.0f;
}
}

m * m * m;
}
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
protected override float transformInternal(float t) {
float start = 0.0f;
float end = 1.0f;
while (true) {

public readonly Curve curve;
public override float transform(float t) {
protected override float transformInternal(float t) {
return 1.0f - this.curve.transform(1.0f - t);
}

internal _DecelerateCurve() {
}
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
protected override float transformInternal(float t) {
t = 1.0f - t;
return 1.0f - t * t;
}

internal _BounceInCurve() {
}
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
protected override float transformInternal(float t) {
return 1.0f - Curves._bounce(1.0f - t);
}
}

}
public override float transform(float t) {
D.assert(t >= 0.0f && t <= 1.0f);
protected override float transformInternal(float t) {
return Curves._bounce(t);
}
}

}
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0f);
protected override float transformInternal(float t) {
if (t < 0.5f) {
return (1.0f - Curves._bounce(1.0f - t)) * 0.5f;
}

public readonly float period;
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
protected override float transformInternal(float t) {
float s = this.period / 4.0f;
t = t - 1.0f;
return -Mathf.Pow(2.0f, 10.0f * t) * Mathf.Sin((t - s) * (Mathf.PI * 2.0f) / this.period);

public readonly float period;
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
protected override float transformInternal(float t) {
float s = this.period / 4.0f;
return Mathf.Pow(2.0f, -10.0f * t) * Mathf.Sin((t - s) * (Mathf.PI * 2.0f) / this.period) + 1.0f;
}

public readonly float period;
public override float transform(float t) {
D.assert(t >= 0.0 && t <= 1.0);
protected override float transformInternal(float t) {
float s = this.period / 4.0f;
t = 2.0f * t - 1.0f;
if (t < 0.0) {

public static readonly Cubic easeInOutBack = new Cubic(0.68f, -0.55f, 0.265f, 1.55f);
public static readonly Curve fastOutSlowIn = new Cubic(0.4f, 0.0f, 0.2f, 1.0f);
public static readonly Cubic fastOutSlowIn = new Cubic(0.4f, 0.0f, 0.2f, 1.0f);
public static readonly Cubic slowMiddle = new Cubic(0.15f, 0.85f, 0.85f, 0.15f);
public static readonly Curve bounceIn = new _BounceInCurve();

13
Runtime/foundation/basic_types.cs


namespace Unity.UIWidgets.foundation {
public delegate void ValueChanged<T>(T value);
public delegate void ValueSetter<T>(T value);
public delegate T ValueGetter<T>();
public delegate IEnumerable<T> EnumerableFilter<T>(IEnumerable<T> input);
public static class ObjectUtils {

public static TValue getOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> it, TKey key) {
TValue v;
it.TryGetValue(key, out v);
return v;
}
public static TValue getOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> it, TKey key, TValue defaultVal) {
TValue v = defaultVal;
if (key == null) {
return v;
}
it.TryGetValue(key, out v);
return v;
}

8
Runtime/foundation/diagnostics.cs


}
public virtual string toString(DiagnosticLevel minLevel = DiagnosticLevel.debug) {
return this.toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine).toString(minLevel: minLevel);
string fullString = null;
D.assert(() => {
fullString = this.toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine)
.toString(minLevel: minLevel);
return true;
});
return fullString ?? this.toStringShort();
}
public virtual DiagnosticsNode toDiagnosticsNode(

10
Runtime/gestures/binding.cs


public readonly GestureArenaManager gestureArena;
public readonly PointerSignalResolver pointerSignalResolver = new PointerSignalResolver();
public readonly Dictionary<int, HitTestResult> _hitTests = new Dictionary<int, HitTestResult>();
public readonly HashSet<HitTestTarget> lastMoveTargets = new HashSet<HitTestTarget>();

}
HitTestResult hitTestResult = null;
if (evt is PointerDownEvent) {
if (evt is PointerDownEvent || evt is PointerSignalEvent) {
if (evt is PointerDownEvent) {
this._hitTests[evt.pointer] = hitTestResult;
}
this._hitTests[evt.pointer] = hitTestResult;
D.assert(() => {

}
else if (evt is PointerUpEvent) {
this.gestureArena.sweep(evt.pointer);
}
else if (evt is PointerSignalEvent) {
this.pointerSignalResolver.resolve((PointerSignalEvent) evt);
}
}
}

2
Runtime/gestures/constants.cs


public static readonly TimeSpan kDoubleTapTimeout = new TimeSpan(0, 0, 0, 0, 300);
public static readonly TimeSpan kDoubleTapMinTime = new TimeSpan(0, 0, 0, 0, 40);
public static readonly TimeSpan kLongPressTimeout = new TimeSpan(0, 0, 0, 0, 500);
public const float kMinFlingVelocity = 50.0f;

48
Runtime/gestures/converter.cs


public Offset lastPosition;
public Offset deltaTo(Offset to) {
return to - this.lastPosition;
}
internal static int _synthesiseDownButtons(int buttons, PointerDeviceKind kind) {
switch (kind) {
case PointerDeviceKind.touch:
return buttons;
default:
return buttons;
}
}
public static class PointerEventConverter {
static readonly Dictionary<int, _PointerState> _pointers = new Dictionary<int, _PointerState>();

public static IEnumerable<PointerEvent> expand(IEnumerable<PointerData> data, float devicePixelRatio) {
foreach (PointerData datum in data) {
var position = new Offset(datum.physicalX, datum.physicalY) / devicePixelRatio;
var radiusMinor = _toLogicalPixels(datum.radiusMinor, devicePixelRatio);
var radiusMajor = _toLogicalPixels(datum.radiusMajor, devicePixelRatio);
var radiusMin = _toLogicalPixels(datum.radiusMin, devicePixelRatio);
var radiusMax = _toLogicalPixels(datum.radiusMax, devicePixelRatio);
case PointerChange.add: {
D.assert(!_pointers.ContainsKey(datum.device));
_PointerState state = _ensureStateForPointer(datum, position);
D.assert(state.lastPosition == position);
yield return new PointerAddedEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
distanceMax: datum.distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt
);
break;
}
case PointerChange.down: {
_PointerState state = _ensureStateForPointer(datum, position);
if (state.down) {

state.lastPosition = position;
}
Offset scrollDelta = new Offset(_scrollData.scrollX, _scrollData.scrollY) / devicePixelRatio;
pointer: state.pointer,
delta: new Offset(_scrollData.scrollX, _scrollData.scrollY) / devicePixelRatio
scrollDelta: scrollDelta
);
break;
}

#endif
}
}
}
static float _toLogicalPixels(float physicalPixels, float devicePixelRatio) {
return physicalPixels / devicePixelRatio;
}
}
}

730
Runtime/gestures/events.cs


using System;
using Unity.UIWidgets.foundation;
public abstract class PointerEvent {
public abstract class PointerEvent : Diagnosticable {
PointerDeviceKind kind = PointerDeviceKind.mouse,
PointerDeviceKind kind = PointerDeviceKind.touch,
int buttons = 0,
bool obscured = false,
float pressure = 1.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f,
int platformData = 0,
bool synthesized = false
) {
this.timeStamp = timeStamp;

this.position = position ?? Offset.zero;
this.delta = delta ?? Offset.zero;
this.buttons = buttons;
this.obscured = obscured;
this.pressure = pressure;
this.pressureMin = pressureMin;
this.pressureMax = pressureMax;
this.distance = distance;
this.distanceMax = distanceMax;
this.size = size;
this.radiusMajor = radiusMajor;
this.radiusMinor = radiusMinor;
this.radiusMin = radiusMin;
this.radiusMax = radiusMax;
this.orientation = orientation;
this.tilt = tilt;
this.platformData = platformData;
this.synthesized = synthesized;
}

public readonly Offset delta;
public readonly int buttons;
public readonly bool obscured;
public readonly float pressure;
public readonly float pressureMin;
public readonly float pressureMax;
public readonly float distance;
public float distanceMin {
get { return 0.0f; }
}
public readonly float distanceMax;
public readonly float size;
public readonly float radiusMajor;
public readonly float radiusMinor;
public readonly float radiusMin;
public readonly float radiusMax;
public readonly float orientation;
public readonly float tilt;
public readonly int platformData;
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Offset>("position", this.position));
properties.add(new DiagnosticsProperty<Offset>("delta", this.delta, defaultValue: Offset.zero,
level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<TimeSpan>("timeStamp", this.timeStamp, defaultValue: TimeSpan.Zero,
level: DiagnosticLevel.debug));
properties.add(new IntProperty("pointer", this.pointer, level: DiagnosticLevel.debug));
properties.add(new EnumProperty<PointerDeviceKind>("kind", this.kind, level: DiagnosticLevel.debug));
properties.add(new IntProperty("device", this.device, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(new IntProperty("buttons", this.buttons, defaultValue: 0, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<bool>("down", this.down, level: DiagnosticLevel.debug));
properties.add(
new FloatProperty("pressure", this.pressure, defaultValue: 1.0, level: DiagnosticLevel.debug));
properties.add(new FloatProperty("pressureMin", this.pressureMin, defaultValue: 1.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("pressureMax", this.pressureMax, defaultValue: 1.0,
level: DiagnosticLevel.debug));
properties.add(
new FloatProperty("distance", this.distance, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(new FloatProperty("distanceMin", this.distanceMin, defaultValue: 0.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("distanceMax", this.distanceMax, defaultValue: 0.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("size", this.size, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(new FloatProperty("radiusMajor", this.radiusMajor, defaultValue: 0.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("radiusMinor", this.radiusMinor, defaultValue: 0.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("radiusMin", this.radiusMin, defaultValue: 0.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("radiusMax", this.radiusMax, defaultValue: 0.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("orientation", this.orientation, defaultValue: 0.0,
level: DiagnosticLevel.debug));
properties.add(new FloatProperty("tilt", this.tilt, defaultValue: 0.0, level: DiagnosticLevel.debug));
properties.add(new IntProperty("platformData", this.platformData, defaultValue: 0,
level: DiagnosticLevel.debug));
properties.add(new FlagProperty("obscured", value: this.obscured, ifTrue: "obscured",
level: DiagnosticLevel.debug));
properties.add(new FlagProperty("synthesized", value: this.synthesized, ifTrue: "synthesized",
level: DiagnosticLevel.debug));
}
}
public class PointerAddedEvent : PointerEvent {

int device = 0,
Offset position = null
Offset position = null,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f
position: position
position: position,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt
) {
}
}

TimeSpan timeStamp,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0
int device = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distanceMax = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f
device: device
device: device,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax
public class PointerScrollEvent : PointerEvent {
public PointerScrollEvent(
public class PointerHoverEvent : PointerEvent {
public PointerHoverEvent(
TimeSpan timeStamp,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null,
Offset delta = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f,
bool synthesized = false) : base(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized) {
}
}
public class PointerEnterEvent : PointerEvent {
public PointerEnterEvent(
TimeSpan timeStamp,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null,
Offset delta = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f,
bool synthesized = false,
bool down = false) : base(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: down,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized) {
}
public static PointerEnterEvent fromHoverEvent(PointerHoverEvent e) {
return fromMouseEvent(e);
}
public static PointerEnterEvent fromMouseEvent(PointerEvent hover) {
return new PointerEnterEvent(
timeStamp: hover?.timeStamp ?? TimeSpan.Zero,
kind: hover?.kind ?? PointerDeviceKind.touch,
device: hover?.device ?? 0,
position: hover?.position,
delta: hover?.delta,
buttons: hover?.buttons ?? 0,
down: hover?.down ?? false,
obscured: hover?.obscured ?? false,
pressure: hover?.pressure ?? 0.0f,
pressureMin: hover?.pressureMin ?? 1.0f,
pressureMax: hover?.pressureMax ?? 1.0f,
distance: hover?.distance ?? 0.0f,
distanceMax: hover?.distanceMax ?? 0.0f,
size: hover?.size ?? 0.0f,
radiusMajor: hover?.radiusMajor ?? 0.0f,
radiusMinor: hover?.radiusMinor ?? 0.0f,
radiusMin: hover?.radiusMin ?? 0.0f,
radiusMax: hover?.radiusMax ?? 0.0f,
orientation: hover?.orientation ?? 0.0f,
tilt: hover?.tilt ?? 0.0f,
synthesized: hover?.synthesized ?? false
);
}
}
public class PointerExitEvent : PointerEvent {
public PointerExitEvent(
TimeSpan timeStamp,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null,
Offset delta = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f,
bool synthesized = false,
bool down = false) : base(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: down,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized) {
}
public static PointerExitEvent fromHoverEvent(PointerHoverEvent e) {
return fromMouseEvent(e);
}
public static PointerExitEvent fromMouseEvent(PointerEvent hover) {
return new PointerExitEvent(
timeStamp: hover?.timeStamp ?? TimeSpan.Zero,
kind: hover?.kind ?? PointerDeviceKind.touch,
device: hover?.device ?? 0,
position: hover?.position,
delta: hover?.delta,
buttons: hover?.buttons ?? 0,
down: hover?.down ?? false,
obscured: hover?.obscured ?? false,
pressure: hover?.pressure ?? 0.0f,
pressureMin: hover?.pressureMin ?? 1.0f,
pressureMax: hover?.pressureMax ?? 1.0f,
distance: hover?.distance ?? 0.0f,
distanceMax: hover?.distanceMax ?? 0.0f,
size: hover?.size ?? 0.0f,
radiusMajor: hover?.radiusMajor ?? 0.0f,
radiusMinor: hover?.radiusMinor ?? 0.0f,
radiusMin: hover?.radiusMin ?? 0.0f,
radiusMax: hover?.radiusMax ?? 0.0f,
orientation: hover?.orientation ?? 0.0f,
tilt: hover?.tilt ?? 0.0f,
synthesized: hover?.synthesized ?? false
);
}
}
public class PointerDownEvent : PointerEvent {
public PointerDownEvent(
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f
) : base(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: true,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt) {
}
}
public class PointerMoveEvent : PointerEvent {
public PointerMoveEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null,
Offset delta = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f,
int platformdData = 0,
bool synthesized = false
) : base(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: true,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
platformData: platformdData,
synthesized: synthesized) {
}
}
public class PointerUpEvent : PointerEvent {
public PointerUpEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f
) : base(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt) {
}
}
public class PointerSignalEvent : PointerEvent {
public PointerSignalEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null
) : base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position
) {
}
}
public class PointerScrollEvent : PointerSignalEvent {
public PointerScrollEvent(
TimeSpan timeStamp,
Offset delta = null)
Offset scrollDelta = null)
pointer: pointer,
position: position,
down: true,
delta: delta) {
position: position) {
D.assert(position != null);
D.assert(scrollDelta != null);
this.scrollDelta = scrollDelta;
}
public readonly Offset scrollDelta;
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Offset>("scrollDelta", this.scrollDelta));
}
}
public class PointerCancelEvent : PointerEvent {
public PointerCancelEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f
) : base(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt) {
}
}

position: evt.position,
objectReferences: objectReferences
);
}
}
public class PointerHoverEvent : PointerEvent {
public PointerHoverEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: false) {
}
public static PointerHoverEvent fromHoverEvent(PointerEvent hover) {
return new PointerHoverEvent(
timeStamp: hover.timeStamp,
pointer: hover.pointer,
kind: hover.kind,
device: hover.device,
position: hover.position
);
}
}
public class PointerEnterEvent : PointerEvent {
public PointerEnterEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: false) {
}
public static PointerEnterEvent fromHoverEvent(PointerEvent hover) {
return new PointerEnterEvent(
timeStamp: hover.timeStamp,
pointer: hover.pointer,
kind: hover.kind,
device: hover.device,
position: hover.position
);
}
}
public class PointerExitEvent : PointerEvent {
public PointerExitEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: false) {
}
public static PointerExitEvent fromHoverEvent(PointerEvent hover) {
return new PointerExitEvent(
timeStamp: hover.timeStamp,
pointer: hover.pointer,
kind: hover.kind,
device: hover.device,
position: hover.position
);
}
}
public class PointerDownEvent : PointerEvent {
public PointerDownEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: true) {
}
}
public class PointerMoveEvent : PointerEvent {
public PointerMoveEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null,
Offset delta = null,
bool synthesized = false)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
delta: delta,
down: true,
synthesized: synthesized) {
}
}
public class PointerUpEvent : PointerEvent {
public PointerUpEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: false) {
}
}
public class PointerCancelEvent : PointerEvent {
public PointerCancelEvent(
TimeSpan timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: false) {
}
}
}

160
Runtime/gestures/long_press.cs


public delegate void GestureLongPressUpCallback();
public delegate void GestureLongPressDragStartCallback(GestureLongPressDragStartDetails details);
public delegate void GestureLongPressStartCallback(LongPressStartDetails details);
public delegate void GestureLongPressDragUpdateCallback(GestureLongPressDragUpdateDetails details);
public delegate void GestureLongPressMoveUpdateCallback(LongPressMoveUpdateDetails details);
public delegate void GestureLongPressDragUpCallback(GestureLongPressDragUpDetails details);
public delegate void GestureLongPressEndCallback(LongPressEndDetails details);
public class GestureLongPressDragStartDetails {
public GestureLongPressDragStartDetails(
TimeSpan? sourceTimeStamp = null,
public class LongPressStartDetails {
public LongPressStartDetails(
this.sourceTimeStamp = sourceTimeStamp;
public readonly TimeSpan? sourceTimeStamp;
public class GestureLongPressDragUpdateDetails {
public GestureLongPressDragUpdateDetails(
TimeSpan? sourceTimeStamp = null,
public class LongPressMoveUpdateDetails {
public LongPressMoveUpdateDetails(
this.sourceTimeStamp = sourceTimeStamp;
public readonly TimeSpan? sourceTimeStamp;
public readonly Offset globalPosition;

public class GestureLongPressDragUpDetails {
public GestureLongPressDragUpDetails(
TimeSpan? sourceTimeStamp = null,
public class LongPressEndDetails {
public LongPressEndDetails(
this.sourceTimeStamp = sourceTimeStamp;
public readonly TimeSpan? sourceTimeStamp;
public LongPressGestureRecognizer(object debugOwner = null, PointerDeviceKind? kind = null) :
base(deadline: Constants.kLongPressTimeout, debugOwner: debugOwner, kind: kind) {
}
public LongPressGestureRecognizer(
float? postAcceptSlopTolerance = null,
object debugOwner = null,
PointerDeviceKind? kind = null) : base(
deadline: Constants.kLongPressTimeout,
postAcceptSlopTolerance: postAcceptSlopTolerance,
kind: kind,
debugOwner: debugOwner) { }
Offset _longPressOrigin;
public GestureLongPressStartCallback onLongPressStart;
public GestureLongPressMoveUpdateCallback onLongPressMoveUpdate;
public GestureLongPressEndCallback onLongPressEnd;
base.acceptGesture(this.primaryPointer);
if (this.onLongPress != null) {
this.invokeCallback<object>("onLongPress", () => {
this.onLongPress();

}
protected override void handlePrimaryPointer(PointerEvent evt) {
if (evt is PointerUpEvent) {
if (this._longPressAccepted && this.onLongPressUp != null) {
this._longPressAccepted = false;
this.invokeCallback<object>("onLongPressUp", () => {
this.onLongPressUp();
if (this.onLongPressStart != null) {
this.invokeCallback<object>("onLongPressStart",
() => {
this.onLongPressStart(new LongPressStartDetails(globalPosition: this._longPressOrigin));
}
else {
this.resolve(GestureDisposition.rejected);
}
}
else if (evt is PointerDownEvent || evt is PointerCancelEvent) {
this._longPressAccepted = false;
public override string debugDescription {
get { return "long press"; }
}
}
public class LongPressDragGestureRecognizer : PrimaryPointerGestureRecognizer {
public LongPressDragGestureRecognizer(object debugOwner = null) : base(
deadline: Constants.kLongPressTimeout,
postAcceptSlopTolerance: null,
debugOwner: debugOwner
) {
}
bool _longPressAccepted = false;
Offset _longPressOrigin;
TimeSpan? _longPressStartTimestamp;
public GestureLongPressDragStartCallback onLongPressStart;
public GestureLongPressDragUpdateCallback onLongPressDragUpdate;
public GestureLongPressDragUpCallback onLongPressUp;
protected override void handlePrimaryPointer(PointerEvent evt) {
if (evt is PointerUpEvent) {
if (this._longPressAccepted) {
if (this.onLongPressUp != null) {
this.invokeCallback<object>("onLongPressUp", () => {
this.onLongPressUp();
return null;
});
}
protected override void didExceedDeadline() {
this.resolve(GestureDisposition.accepted);
this._longPressAccepted = true;
base.acceptGesture(this.primaryPointer);
if (this.onLongPressStart != null) {
this.invokeCallback<object>("onLongPressStart", () => {
this.onLongPressStart(new GestureLongPressDragStartDetails(
sourceTimeStamp: this._longPressStartTimestamp,
globalPosition: this._longPressOrigin
));
return null;
});
}
}
if (this.onLongPressEnd != null) {
this.invokeCallback<object>("onLongPressEnd", () => {
this.onLongPressEnd(new LongPressEndDetails(globalPosition: evt.position));
return null;
});
}
protected override void handlePrimaryPointer(PointerEvent e) {
if (e is PointerUpEvent) {
if (this._longPressAccepted == true && this.onLongPressUp != null) {
this._longPressAccepted = false;
this.invokeCallback<object>("onLongPressUp", () => {
this.onLongPressUp(new GestureLongPressDragUpDetails(
sourceTimeStamp: e.timeStamp,
globalPosition: e.position
));
return null;
});
this._longPressAccepted = true;
else if (e is PointerDownEvent) {
else if (evt is PointerDownEvent || evt is PointerCancelEvent) {
this._longPressStartTimestamp = e.timeStamp;
this._longPressOrigin = e.position;
this._longPressOrigin = evt.position;
else if (e is PointerMoveEvent && this._longPressAccepted && this.onLongPressDragUpdate != null) {
this.invokeCallback<object>("onLongPressDrag", () => {
this.onLongPressDragUpdate(new GestureLongPressDragUpdateDetails(
sourceTimeStamp: e.timeStamp,
globalPosition: e.position,
offsetFromOrigin: e.position - this._longPressOrigin
else if (evt is PointerMoveEvent && this._longPressAccepted && this.onLongPressMoveUpdate != null) {
this.invokeCallback<object>("onLongPressMoveUpdate", () => {
this.onLongPressMoveUpdate(new LongPressMoveUpdateDetails(
globalPosition: evt.position,
offsetFromOrigin: evt.position - this._longPressOrigin
));
return null;
});

public override void acceptGesture(int pointer) {
}
protected override void didStopTrackingLastPointer(int pointer) {
this._longPressAccepted = false;
this._longPressOrigin = null;
this._longPressStartTimestamp = null;
base.didStopTrackingLastPointer(pointer);
}
get { return "long press drag"; }
get { return "long press"; }
}
}
}

3
Runtime/gestures/monodrag.cs


protected override void handleEvent(PointerEvent evt) {
D.assert(this._state != _DragState.ready);
if (evt is PointerScrollEvent) {
Offset delta = evt.delta;
var scrollEvt = (PointerScrollEvent) evt;
Offset delta = scrollEvt.scrollDelta;
if (this.onUpdate != null) {
this.invokeCallback<object>("onUpdate", () => {
this.onUpdate(new DragUpdateDetails(

8
Runtime/gestures/mouse_tracking.cs


if (trackedAnnotation.activeDevices.Contains(deviceId)) {
if (trackedAnnotation.annotation?.onExit != null) {
trackedAnnotation.annotation.onExit(
PointerExitEvent.fromHoverEvent(this._lastMouseEvent[deviceId]));
PointerExitEvent.fromMouseEvent(this._lastMouseEvent[deviceId]));
}
trackedAnnotation.activeDevices.Remove(deviceId);

if (!hitAnnotation.activeDevices.Contains(deviceId)) {
hitAnnotation.activeDevices.Add(deviceId);
if (hitAnnotation.annotation?.onEnter != null) {
hitAnnotation.annotation.onEnter(PointerEnterEvent.fromHoverEvent(lastEvent));
hitAnnotation.annotation.onEnter(PointerEnterEvent.fromMouseEvent(lastEvent));
if (hitAnnotation.annotation?.onHover != null) {
hitAnnotation.annotation.onHover(PointerHoverEvent.fromHoverEvent(lastEvent));
if (hitAnnotation.annotation?.onHover != null && lastEvent is PointerHoverEvent) {
hitAnnotation.annotation.onHover(lastEvent as PointerHoverEvent);
}
//leave

240
Runtime/gestures/multitap.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.async;
using Unity.UIWidgets.foundation;

public delegate void GestureDoubleTapCallback(DoubleTapDetails details);
public delegate void GestureMultiTapDownCallback(int pointer, TapDownDetails details);
public delegate void GestureMultiTapUpCallback(int pointer, TapUpDetails details);
public delegate void GestureMultiTapCallback(int pointer);
public delegate void GestureMultiTapCancelCallback(int pointer);
public class _CountdownZoned {
_CountdownZoned(TimeSpan duration) {
D.assert(duration != null);
this._timer = Window.instance.run(duration, this._onTimeout);
}
public bool _timeout = false;
public Timer _timer;
public bool timeout {
get { return this._timeout; }
}
void _onTimeout() {
this._timeout = true;
}
}
public class DoubleTapDetails {
public DoubleTapDetails(Offset firstGlobalPosition = null) {
this.firstGlobalPosition = firstGlobalPosition ?? Offset.zero;

class _TapTracker {
internal _TapTracker(
PointerDownEvent evt = null,
GestureArenaEntry entry = null) {
PointerDownEvent evt,
TimeSpan doubleTapMinTime,
GestureArenaEntry entry = null
) {
this.pointer = evt.pointer;
this._initialPosition = evt.position;
this.entry = entry;

public readonly GestureArenaEntry entry;
internal readonly Offset _initialPosition;
internal readonly _CountdownZoned _doubleTapMinTimeCountdown;
bool _isTrackingPointer = false;

}
}
public void stopTrackingPointer(PointerRoute route) {
public virtual void stopTrackingPointer(PointerRoute route) {
if (this._isTrackingPointer) {
this._isTrackingPointer = false;
GestureBinding.instance.pointerRouter.removeRoute(this.pointer, route);

Offset offset = evt.position - this._initialPosition;
return offset.distance <= tolerance;
}
public bool hasElapsedMinTime() {
return this._doubleTapMinTimeCountdown.timeout;
}
: base(debugOwner: debugOwner, kind: kind) {
}
: base(debugOwner: debugOwner, kind: kind) { }
public GestureDoubleTapCallback onDoubleTap;

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

}
}
public override void acceptGesture(int pointer) {
}
public override void acceptGesture(int pointer) { }
public override void rejectGesture(int pointer) {
_TapTracker tracker;

foreach (var tracker in this._trackers.Values) {
this._reject(tracker);
}
D.assert(this._trackers.isEmpty());
}

public override string debugDescription {
get { return "double tap"; }
}
}
class _TapGesture : _TapTracker {
public _TapGesture(
MultiTapGestureRecognizer gestureRecognizer,
PointerEvent evt,
TimeSpan longTapDelay
) : base(
evt: (PointerDownEvent) evt,
entry: GestureBinding.instance.gestureArena.add(evt.pointer, gestureRecognizer),
doubleTapMinTime: Constants.kDoubleTapMinTime
) {
this.gestureRecognizer = gestureRecognizer;
this._lastPosition = evt.position;
this.startTrackingPointer(this.handleEvent);
if (longTapDelay > TimeSpan.Zero) {
this._timer = Window.instance.run(longTapDelay, () => {
this._timer = null;
this.gestureRecognizer._dispatchLongTap(evt.pointer, this._lastPosition);
});
}
}
public readonly MultiTapGestureRecognizer gestureRecognizer;
bool _wonArena = false;
Timer _timer;
Offset _lastPosition;
Offset _finalPosition;
void handleEvent(PointerEvent evt) {
D.assert(evt.pointer == this.pointer);
if (evt is PointerMoveEvent) {
if (!this.isWithinTolerance(evt, Constants.kTouchSlop)) {
this.cancel();
}
else {
this._lastPosition = evt.position;
}
}
else if (evt is PointerCancelEvent) {
this.cancel();
}
else if (evt is PointerUpEvent) {
this.stopTrackingPointer(this.handleEvent);
this._finalPosition = evt.position;
this._check();
}
}
public override void stopTrackingPointer(PointerRoute route) {
this._timer?.cancel();
this._timer = null;
base.stopTrackingPointer(route);
}
public void accept() {
this._wonArena = true;
this._check();
}
public void reject() {
this.stopTrackingPointer(this.handleEvent);
this.gestureRecognizer._dispatchCancel(this.pointer);
}
public void cancel() {
if (this._wonArena) {
this.reject();
}
else {
this.entry.resolve(GestureDisposition.rejected);
}
}
void _check() {
if (this._wonArena && this._finalPosition != null) {
this.gestureRecognizer._dispatchTap(this.pointer, this._finalPosition);
}
}
}
public class MultiTapGestureRecognizer : GestureRecognizer {
public MultiTapGestureRecognizer(
TimeSpan? longTapDelay = null,
object debugOwner = null,
PointerDeviceKind? kind = null
) : base(debugOwner: debugOwner, kind: kind) {
this.longTapDelay = longTapDelay ?? TimeSpan.Zero;
}
GestureMultiTapDownCallback onTapDown;
GestureMultiTapUpCallback onTapUp;
GestureMultiTapCallback onTap;
GestureMultiTapCancelCallback onTapCancel;
TimeSpan longTapDelay;
GestureMultiTapDownCallback onLongTapDown;
readonly Dictionary<int, _TapGesture> _gestureMap = new Dictionary<int, _TapGesture>();
public override void addAllowedPointer(PointerDownEvent evt) {
D.assert(!this._gestureMap.ContainsKey(evt.pointer));
this._gestureMap[evt.pointer] = new _TapGesture(
gestureRecognizer: this,
evt: evt,
longTapDelay: this.longTapDelay
);
if (this.onTapDown != null) {
this.invokeCallback<object>("onTapDown", () => {
this.onTapDown(evt.pointer, new TapDownDetails(globalPosition: evt.position));
return null;
});
}
}
public override void acceptGesture(int pointer) {
D.assert(this._gestureMap.ContainsKey(pointer));
this._gestureMap[pointer].accept();
}
public override void rejectGesture(int pointer) {
D.assert(this._gestureMap.ContainsKey(pointer));
this._gestureMap[pointer].reject();
D.assert(!this._gestureMap.ContainsKey(pointer));
}
public void _dispatchCancel(int pointer) {
D.assert(this._gestureMap.ContainsKey(pointer));
this._gestureMap.Remove(pointer);
if (this.onTapCancel != null) {
this.invokeCallback<object>("onTapCancel", () => {
this.onTapCancel(pointer);
return null;
});
}
}
public void _dispatchTap(int pointer, Offset globalPosition) {
D.assert(this._gestureMap.ContainsKey(pointer));
this._gestureMap.Remove(pointer);
if (this.onTapUp != null) {
this.invokeCallback<object>("onTapUp",
() => {
this.onTapUp(pointer, new TapUpDetails(globalPosition: globalPosition));
return null;
});
}
if (this.onTap != null) {
this.invokeCallback<object>("onTap", () => {
this.onTap(pointer);
return null;
});
}
}
public void _dispatchLongTap(int pointer, Offset lastPosition) {
D.assert(this._gestureMap.ContainsKey(pointer));
if (this.onLongTapDown != null) {
this.invokeCallback<object>("onLongTapDown",
() => {
this.onLongTapDown(pointer, new TapDownDetails(globalPosition: lastPosition));
return null;
});
}
}
public override void dispose() {
List<_TapGesture> localGestures = new List<_TapGesture>();
foreach (var item in this._gestureMap) {
localGestures.Add(item.Value);
}
foreach (_TapGesture gesture in localGestures) {
gesture.cancel();
}
D.assert(this._gestureMap.isEmpty);
base.dispose();
}
public override string debugDescription {
get { return "multitap"; }
}
}
}

6
Runtime/gestures/scale.cs


public class ScaleGestureRecognizer : OneSequenceGestureRecognizer {
public ScaleGestureRecognizer(object debugOwner) : base(debugOwner: debugOwner) {
}
public ScaleGestureRecognizer(object debugOwner, PointerDeviceKind? kind = null) : base(debugOwner: debugOwner,
kind: kind) { }
public GestureScaleStartCallback onStart;

get { return "scale"; }
}
}
}
}

23
Runtime/gestures/tap.cs


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

protected override void handlePrimaryPointer(PointerEvent evt) {
if (evt is PointerUpEvent) {
this._finalPosition = evt.position;
this._checkUp();
if (this._wonArenaForPrimaryPointer) {
this.resolve(GestureDisposition.accepted);
this._checkUp();
}
if (this._sentTapDown && this.onTapCancel != null) {
this.invokeCallback<object>("onTapCancel", () => this.onTapCancel);
}
this._reset();
}
}

D.assert(this._sentTapDown);
if (this.onTapCancel != null) {
this.invokeCallback<object>("spontaneous onTapCancel", () => {
this.onTapCancel();

public override void rejectGesture(int pointer) {
base.rejectGesture(pointer);
if (pointer == this.primaryPointer) {
if (this.onTapCancel != null) {
if (this._sentTapDown && this.onTapCancel != null) {
this.invokeCallback<object>("forced onTapCancel", () => {
this.onTapCancel();
return null;

}
void _checkUp() {
if (this._wonArenaForPrimaryPointer && this._finalPosition != null) {
this.resolve(GestureDisposition.accepted);
if (!this._wonArenaForPrimaryPointer || this._finalPosition == null) {
return;
}
if (this._finalPosition != null) {
if (this.onTapUp != null) {
this.invokeCallback<object>("onTapUp", () => {
this.onTapUp(new TapUpDetails(globalPosition: this._finalPosition));

9
Runtime/material/app.cs


class _MaterialAppState : State<MaterialApp> {
HeroController _heroController;
this._heroController = new HeroController(createRectTween: this._createRectTween);
if (this.widget.navigatorKey != (oldWidget as MaterialApp).navigatorKey) {
this._heroController = new HeroController(createRectTween: this._createRectTween);
}
this._updateNavigator();
}

this.widget.onGenerateRoute != null ||
this.widget.onUnknownRoute != null) {
this._navigatorObservers = new List<NavigatorObserver>(this.widget.navigatorObservers);
this._navigatorObservers.Add(this._heroController);
this._navigatorObservers = null;
this._navigatorObservers = new List<NavigatorObserver>();
}
}

39
Runtime/material/app_bar.cs


Widget flexibleSpace = null,
PreferredSizeWidget bottom = null,
float? elevation = null,
ShapeBorder shape = null,
IconThemeData actionsIconTheme = null,
TextTheme textTheme = null,
bool primary = true,
bool? centerTitle = null,

this.flexibleSpace = flexibleSpace;
this.bottom = bottom;
this.elevation = elevation;
this.shape = shape;
this.actionsIconTheme = actionsIconTheme;
this.textTheme = textTheme;
this.primary = primary;
this.centerTitle = centerTitle;

public readonly float? elevation;
public readonly ShapeBorder shape;
public readonly IconThemeData actionsIconTheme;
public readonly TextTheme textTheme;

bool canPop = parentRoute?.canPop ?? false;
bool useCloseButton = parentRoute is PageRoute && ((PageRoute) parentRoute).fullscreenDialog;
IconThemeData appBarIconTheme = this.widget.iconTheme
IconThemeData overallIconTheme = this.widget.iconTheme
IconThemeData actionsIconTheme = this.widget.actionsIconTheme
?? appBarTheme.actionsIconTheme
?? overallIconTheme;
TextStyle centerStyle = this.widget.textTheme?.title
?? appBarTheme.textTheme?.title
?? themeData.primaryTextTheme.title;

sideStyle = sideStyle.copyWith(color: sideStyle.color.withOpacity(opacity));
}
appBarIconTheme = appBarIconTheme.copyWith(
opacity: opacity * (appBarIconTheme.opacity ?? 1.0f)
overallIconTheme = overallIconTheme.copyWith(
opacity: opacity * (overallIconTheme.opacity ?? 1.0f)
);
actionsIconTheme = actionsIconTheme.copyWith(
opacity: opacity * (actionsIconTheme.opacity ?? 1.0f)
);
}

tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip);
}
if (actions != null) {
actions = IconTheme.merge(
data: actionsIconTheme,
child: actions
);
}
Widget toolbar = new NavigationToolbar(
leading: leading,
middle: title,

child: new CustomSingleChildLayout(
layoutDelegate: new _ToolbarContainerLayout(),
child: IconTheme.merge(
data: appBarIconTheme,
data: overallIconTheme,
child: new DefaultTextStyle(
style: sideStyle,
child: toolbar)

elevation: this.widget.elevation
?? appBarTheme.elevation
?? _defaultElevation,
shape: this.widget.shape,
child: appBar
));
}

Color backgroundColor,
Brightness? brightness,
IconThemeData iconTheme,
IconThemeData actionsIconTheme,
TextTheme textTheme,
bool primary,
bool? centerTitle,

this.backgroundColor = backgroundColor;
this.brightness = brightness;
this.iconTheme = iconTheme;
this.actionsIconTheme = actionsIconTheme;
this.textTheme = textTheme;
this.primary = primary;
this.centerTitle = centerTitle;

public readonly Color backgroundColor;
public readonly Brightness? brightness;
public readonly IconThemeData iconTheme;
public readonly IconThemeData actionsIconTheme;
public readonly TextTheme textTheme;
public readonly bool primary;
public readonly bool? centerTitle;

|| this.backgroundColor != oldDelegate.backgroundColor
|| this.brightness != oldDelegate.brightness
|| this.iconTheme != oldDelegate.iconTheme
|| this.actionsIconTheme != oldDelegate.actionsIconTheme
|| this.textTheme != oldDelegate.textTheme
|| this.primary != oldDelegate.primary
|| this.centerTitle != oldDelegate.centerTitle

Color backgroundColor = null,
Brightness? brightness = null,
IconThemeData iconTheme = null,
IconThemeData actionsIconTheme = null,
TextTheme textTheme = null,
bool primary = true,
bool? centerTitle = null,

this.backgroundColor = backgroundColor;
this.brightness = brightness;
this.iconTheme = iconTheme;
this.actionsIconTheme = actionsIconTheme;
this.textTheme = textTheme;
this.primary = primary;
this.centerTitle = centerTitle;

public readonly Brightness? brightness;
public readonly IconThemeData iconTheme;
public readonly IconThemeData actionsIconTheme;
public readonly TextTheme textTheme;

backgroundColor: this.widget.backgroundColor,
brightness: this.widget.brightness,
iconTheme: this.widget.iconTheme,
actionsIconTheme: this.widget.actionsIconTheme,
textTheme: this.widget.textTheme,
primary: this.widget.primary,
centerTitle: this.widget.centerTitle,

10
Runtime/material/app_bar_theme.cs


Color color = null,
float? elevation = null,
IconThemeData iconTheme = null,
IconThemeData actionsIconTheme = null,
TextTheme textTheme = null
) {
this.brightness = brightness;

this.actionsIconTheme = actionsIconTheme;
this.textTheme = textTheme;
}

public readonly IconThemeData iconTheme;
public readonly IconThemeData actionsIconTheme;
public readonly TextTheme textTheme;
AppBarTheme copyWith(

IconThemeData iconTheme = null,
IconThemeData actionsIconTheme = null,
TextTheme textTheme = null
) {
return new AppBarTheme(

iconTheme: iconTheme ?? this.iconTheme,
actionsIconTheme: actionsIconTheme ?? this.actionsIconTheme,
textTheme: textTheme ?? this.textTheme
);
}

color: Color.lerp(a?.color, b?.color, t),
elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t),
iconTheme: IconThemeData.lerp(a?.iconTheme, b?.iconTheme, t),
actionsIconTheme: IconThemeData.lerp(a?.actionsIconTheme, b?.actionsIconTheme, t),
textTheme: TextTheme.lerp(a?.textTheme, b?.textTheme, t)
);
}

hashCode = (hashCode * 397) ^ this.color?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.elevation?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.iconTheme?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.actionsIconTheme?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.textTheme?.GetHashCode() ?? 0;
return hashCode;
}

&& other.color == this.color
&& other.elevation == this.elevation
&& other.iconTheme == this.iconTheme
&& other.actionsIconTheme == this.actionsIconTheme
&& other.textTheme == this.textTheme;
}

properties.add(new DiagnosticsProperty<Color>("color", this.color, defaultValue: null));
properties.add(new DiagnosticsProperty<float?>("elevation", this.elevation, defaultValue: null));
properties.add(new DiagnosticsProperty<IconThemeData>("iconTheme", this.iconTheme, defaultValue: null));
properties.add(new DiagnosticsProperty<IconThemeData>("actionsIconTheme", this.actionsIconTheme, defaultValue: null));
properties.add(new DiagnosticsProperty<TextTheme>("textTheme", this.textTheme, defaultValue: null));
}
}

407
Runtime/material/bottom_navigation_bar.cs


using Transform = Unity.UIWidgets.widgets.Transform;
namespace Unity.UIWidgets.material {
class BottomNavigationBarUtils {
public const float _kActiveFontSize = 14.0f;
public const float _kInactiveFontSize = 12.0f;
public const float _kTopMargin = 6.0f;
public const float _kBottomMargin = 8.0f;
}
public enum BottomNavigationBarType {
fix,
shifting

List<BottomNavigationBarItem> items = null,
ValueChanged<int> onTap = null,
int currentIndex = 0,
float elevation = 8.0f,
float iconSize = 24.0f
Color backgroundColor = null,
float iconSize = 24.0f,
Color selectedItemColor = null,
Color unselectedItemColor = null,
float selectedFontSize = 14.0f,
float unselectedFontSize = 12.0f,
bool showSelectedLabels = true,
bool? showUnselectedLabels = null
) : base(key: key) {
D.assert(items != null);
D.assert(items.Count >= 2);

D.assert(0 <= currentIndex && currentIndex < items.Count);
D.assert(elevation >= 0.0f);
D.assert(iconSize >= 0.0f);
D.assert(selectedItemColor == null || fixedColor == null,
() => "Either selectedItemColor or fixedColor can be specified, but not both!");
D.assert(selectedFontSize >= 0.0f);
D.assert(unselectedFontSize >= 0.0f);
type = _type(type, items);
this.elevation = elevation;
this.fixedColor = fixedColor;
this.backgroundColor = backgroundColor;
this.selectedItemColor = selectedItemColor ?? fixedColor;
this.unselectedItemColor = unselectedItemColor;
this.selectedFontSize = selectedFontSize;
this.unselectedFontSize = unselectedFontSize;
this.showSelectedLabels = showSelectedLabels;
this.showUnselectedLabels = showUnselectedLabels ?? _defaultShowUnselected(_type(type, items));
}
public readonly List<BottomNavigationBarItem> items;

public readonly int currentIndex;
public readonly float elevation;
public readonly Color fixedColor;
public Color fixedColor {
get { return this.selectedItemColor; }
}
public readonly Color backgroundColor;
public readonly Color selectedItemColor;
public readonly Color unselectedItemColor;
public readonly float selectedFontSize;
public readonly float unselectedFontSize;
public readonly bool showUnselectedLabels;
public readonly bool showSelectedLabels;
static BottomNavigationBarType _type(
BottomNavigationBarType? type,
List<BottomNavigationBarItem> items
) {
if (type != null) {
return type.Value;
}
return items.Count <= 3 ? BottomNavigationBarType.fix : BottomNavigationBarType.shifting;
}
static bool _defaultShowUnselected(BottomNavigationBarType type) {
switch (type) {
case BottomNavigationBarType.shifting:
return false;
case BottomNavigationBarType.fix:
return true;
}
D.assert(false);
return false;
}
public override State createState() {
return new _BottomNavigationBarState();
}

ColorTween colorTween = null,
float? flex = null,
bool selected = false,
float? selectedFontSize = null,
float? unselectedFontSize = null,
bool? showSelectedLabels = null,
bool? showUnselectedLabels = null,
D.assert(type != null);
D.assert(item != null);
D.assert(animation != null);
D.assert(selectedFontSize != null && selectedFontSize >= 0);
D.assert(unselectedFontSize != null && unselectedFontSize >= 0);
this.type = type;
this.item = item;
this.animation = animation;

this.flex = flex;
this.selected = selected;
this.selectedFontSize = selectedFontSize.Value;
this.unselectedFontSize = unselectedFontSize.Value;
this.showSelectedLabels = showSelectedLabels ?? false;
this.showUnselectedLabels = showUnselectedLabels ?? false;
this.indexLabel = indexLabel;
}

public readonly ColorTween colorTween;
public readonly float? flex;
public readonly bool selected;
public readonly float selectedFontSize;
public readonly float unselectedFontSize;
public readonly bool showSelectedLabels;
public readonly bool showUnselectedLabels;
Widget label;
float bottomPadding = this.selectedFontSize / 2.0f;
float topPadding = this.selectedFontSize / 2.0f;
if (this.showSelectedLabels && !this.showUnselectedLabels) {
bottomPadding = new FloatTween(
begin: 0.0f,
end: this.selectedFontSize / 2.0f
).evaluate(this.animation);
topPadding = new FloatTween(
begin: this.selectedFontSize,
end: this.selectedFontSize / 2.0f
).evaluate(this.animation);
}
if (!this.showSelectedLabels && !this.showUnselectedLabels) {
bottomPadding = 0.0f;
topPadding = this.selectedFontSize;
}
label = new _FixedLabel(colorTween: this.colorTween, animation: this.animation, item: this.item);
label = new _ShiftingLabel(animation: this.animation, item: this.item);
break;
default:
throw new Exception("Unknown BottomNavigationBarType: " + this.type);

children: new List<Widget> {
new InkResponse(
onTap: this.onTap == null ? (GestureTapCallback) null : () => { this.onTap(); },
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
new _TileIcon(
type: this.type,
colorTween: this.colorTween,
animation: this.animation,
iconSize: this.iconSize,
selected: this.selected,
item: this.item
),
label
}
child: new Padding(
padding: EdgeInsets.only(top: topPadding, bottom: bottomPadding),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
new _TileIcon(
colorTween: this.colorTween,
animation: this.animation,
iconSize: this.iconSize,
selected: this.selected,
item: this.item
),
new _Label(
colorTween: this.colorTween,
animation: this.animation,
item: this.item,
selectedFontSize: this.selectedFontSize,
unselectedFontSize: this.unselectedFontSize,
showSelectedLabels: this.showSelectedLabels,
showUnselectedLabels: this.showUnselectedLabels
)
}
)
)
)
}

class _TileIcon : StatelessWidget {
public _TileIcon(
Key key = null,
BottomNavigationBarType? type = null,
ColorTween colorTween = null,
Animation<float> animation = null,
float? iconSize = null,

this.type = type;
D.assert(selected != null);
D.assert(item != null);
this.colorTween = colorTween;
this.animation = animation;
this.iconSize = iconSize;

BottomNavigationBarType? type;
ColorTween colorTween;
Animation<float> animation;
float? iconSize;

public override Widget build(BuildContext context) {
float tweenStart;
Color iconColor;
switch (this.type) {
case BottomNavigationBarType.fix:
tweenStart = 8.0f;
iconColor = this.colorTween.evaluate(this.animation);
break;
case BottomNavigationBarType.shifting:
tweenStart = 16.0f;
iconColor = Colors.white;
break;
default:
throw new Exception("Unknown BottomNavigationBarType: " + this.type);
}
Color iconColor = this.colorTween.evaluate(this.animation);
margin: EdgeInsets.only(
top: new FloatTween(
begin: tweenStart,
end: BottomNavigationBarUtils._kTopMargin
).evaluate(this.animation)
),
child: new IconTheme(
data: new IconThemeData(
color: iconColor,

}
}
class _FixedLabel : StatelessWidget {
public _FixedLabel(
class _Label : StatelessWidget {
public _Label(
BottomNavigationBarItem item = null
BottomNavigationBarItem item = null,
float? selectedFontSize = null,
float? unselectedFontSize = null,
bool? showSelectedLabels = null,
bool? showUnselectedLabels = null
D.assert(colorTween != null);
D.assert(animation != null);
D.assert(item != null);
D.assert(selectedFontSize != null);
D.assert(unselectedFontSize != null);
D.assert(showSelectedLabels != null);
D.assert(showUnselectedLabels != null);
this.selectedFontSize = selectedFontSize.Value;
this.unselectedFontSize = unselectedFontSize.Value;
this.showSelectedLabels = showSelectedLabels.Value;
this.showUnselectedLabels = showUnselectedLabels.Value;
ColorTween colorTween;
Animation<float> animation;
BottomNavigationBarItem item;
public readonly ColorTween colorTween;
public readonly Animation<float> animation;
public readonly BottomNavigationBarItem item;
public readonly float selectedFontSize;
public readonly float unselectedFontSize;
public readonly bool showSelectedLabels;
public readonly bool showUnselectedLabels;
float t = new FloatTween(
begin: BottomNavigationBarUtils._kInactiveFontSize / BottomNavigationBarUtils._kActiveFontSize,
end: 1.0f
).evaluate(this.animation);
return new Align(
alignment: Alignment.bottomCenter,
heightFactor: 1.0f,
child: new Container(
margin: EdgeInsets.only(bottom: BottomNavigationBarUtils._kBottomMargin),
child: DefaultTextStyle.merge(
style: new TextStyle(
fontSize: BottomNavigationBarUtils._kActiveFontSize,
color: this.colorTween.evaluate(this.animation)
),
child: new Transform(
transform: Matrix3.makeScale(t),
alignment: Alignment.bottomCenter,
child: this.item.title
)
)
float t = new FloatTween(begin: this.unselectedFontSize / this.selectedFontSize, end: 1.0f)
.evaluate(this.animation);
Widget text = DefaultTextStyle.merge(
style: new TextStyle(
fontSize: this.selectedFontSize,
color: this.colorTween.evaluate(this.animation)
),
child: new Transform(
transform: Matrix3.makeAll(t, 0, 0,
0, t, 0,
0, 0, 1),
alignment: Alignment.bottomCenter,
child: this.item.title
}
}
class _ShiftingLabel : StatelessWidget {
public _ShiftingLabel(
Key key = null,
Animation<float> animation = null,
BottomNavigationBarItem item = null
) : base(key: key) {
this.animation = animation;
this.item = item;
}
Animation<float> animation;
BottomNavigationBarItem item;
public override Widget build(BuildContext context) {
if (!this.showUnselectedLabels && !this.showSelectedLabels) {
text = new Opacity(
opacity: 0.0f,
child: text
);
}
else if (this.showUnselectedLabels) {
text = new FadeTransition(
opacity: this.animation,
child: text
);
}
else if (!this.showSelectedLabels) {
text = new FadeTransition(
opacity: new FloatTween(begin: 1.0f, end: 0.0f).animate(this.animation),
child: text
);
}
child: new Container(
margin: EdgeInsets.only(
bottom: new FloatTween(
begin: 2.0f,
end: BottomNavigationBarUtils._kBottomMargin
).evaluate(this.animation)
),
child: new FadeTransition(
opacity: this.animation,
child: DefaultTextStyle.merge(
style: new TextStyle(
fontSize: BottomNavigationBarUtils._kActiveFontSize,
color: Colors.white
),
child: this.item.title
)
)
)
child: new Container(child: text)
class _BottomNavigationBarState : TickerProviderStateMixin<BottomNavigationBar> {
public List<AnimationController> _controllers = new List<AnimationController> { };

List<Widget> _createTiles() {
MaterialLocalizations localizations = MaterialLocalizations.of(this.context);
D.assert(localizations != null);
List<Widget> children = new List<Widget> { };
ThemeData themeData = Theme.of(this.context);
Color themeColor;
switch (themeData.brightness) {
case Brightness.light:
themeColor = themeData.primaryColor;
break;
case Brightness.dark:
themeColor = themeData.accentColor;
break;
default:
throw new Exception("Unknown brightness: " + themeData.brightness);
}
ColorTween colorTween;
ThemeData themeData = Theme.of(this.context);
TextTheme textTheme = themeData.textTheme;
Color themeColor;
switch (themeData.brightness) {
case Brightness.light:
themeColor = themeData.primaryColor;
break;
case Brightness.dark:
themeColor = themeData.accentColor;
break;
default:
throw new Exception("Unknown brightness: " + themeData.brightness);
}
ColorTween colorTween = new ColorTween(
begin: textTheme.caption.color,
end: this.widget.fixedColor ?? themeColor
colorTween = new ColorTween(
begin: this.widget.unselectedItemColor ?? themeData.textTheme.caption.color,
end: this.widget.selectedItemColor ?? this.widget.fixedColor ?? themeColor
for (int i = 0; i < this.widget.items.Count; i += 1) {
int index = i;
children.Add(
new _BottomNavigationTile(this.widget.type, this.widget.items[i], this._animations[i],
this.widget.iconSize,
onTap: () => {
if (this.widget.onTap != null) {
this.widget.onTap(index);
}
},
colorTween: colorTween,
selected: i == this.widget.currentIndex,
indexLabel: localizations.tabLabel(tabIndex: i + 1,
tabCount: this.widget.items.Count)
)
);
}
for (int i = 0; i < this.widget.items.Count; i += 1) {
int index = i;
children.Add(
new _BottomNavigationTile(this.widget.type, this.widget.items[i], this._animations[i],
this.widget.iconSize,
onTap: () => {
if (this.widget.onTap != null) {
this.widget.onTap(index);
}
},
flex:
this._evaluateFlex(this._animations[i]),
selected: i == this.widget.currentIndex,
indexLabel: localizations.tabLabel(tabIndex: i + 1,
tabCount: this.widget.items.Count)
)
);
}
colorTween = new ColorTween(
begin: this.widget.unselectedItemColor ?? Colors.white,
end: this.widget.selectedItemColor ?? Colors.white
);
break;
default:
throw new UIWidgetsError($"Unknown bottom navigation bar type: {this.widget.type}");
}
break;
List<Widget> tiles = new List<Widget>();
for (int i = 0; i < this.widget.items.Count; i++) {
int index = i;
tiles.Add(new _BottomNavigationTile(
this.widget.type,
this.widget.items[i],
this._animations[i],
this.widget.iconSize,
selectedFontSize: this.widget.selectedFontSize,
unselectedFontSize: this.widget.unselectedFontSize,
onTap: () => {
if (this.widget.onTap != null) {
this.widget.onTap(index);
}
},
colorTween: colorTween,
flex: this._evaluateFlex(this._animations[i]),
selected: i == this.widget.currentIndex,
showSelectedLabels: this.widget.showSelectedLabels,
showUnselectedLabels: this.widget.showUnselectedLabels,
indexLabel: localizations.tabLabel(tabIndex: i+1, tabCount: this.widget.items.Count)
));
return children;
return tiles;
}
Widget _createContainer(List<Widget> tiles) {

D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
float additionalBottomPadding =
Mathf.Max(MediaQuery.of(context).padding.bottom - BottomNavigationBarUtils._kBottomMargin, 0.0f);
Mathf.Max(MediaQuery.of(context).padding.bottom - this.widget.selectedFontSize / 2.0f, 0.0f);
Color backgroundColor = null;
switch (this.widget.type) {
case BottomNavigationBarType.fix:

return new Material(
elevation: 8.0f,
elevation: this.widget.elevation,
color: backgroundColor,
child: new ConstrainedBox(
constraints: new BoxConstraints(

2
Runtime/material/button_theme.cs


return fillColor;
}
if (button is FlatButton || button is OutlineButton) {
if (button is FlatButton || button is OutlineButton || button.GetType() == typeof(MaterialButton)) {
return null;
}

108
Runtime/material/chip.cs


MaterialTapTargetSize? materialTapTargetSize { get; }
float? elevation { get; }
Color shadowColor { get; }
}
public interface DeletableChipAttributes {

string tooltip { get; }
ShapeBorder avatarBorder { get; }
Color selectedShadowColor { get; }
}
public interface DisabledChipAttributes {

Color backgroundColor = null,
EdgeInsets padding = null,
MaterialTapTargetSize? materialTapTargetSize = null,
float? elevation = null
float? elevation = null,
Color shadowColor = null
) : base(key: key) {
D.assert(label != null);
D.assert(elevation == null || elevation >= 0.0f);

this._padding = padding;
this._materialTapTargetSize = materialTapTargetSize;
this._elevation = elevation;
this._shadowColor = shadowColor;
}
public Widget avatar {

}
float? _elevation;
public Color shadowColor {
get { return this._shadowColor; }
}
Color _shadowColor;
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterial(context));

padding: this.padding,
materialTapTargetSize: this.materialTapTargetSize,
elevation: this.elevation,
shadowColor: this.shadowColor,
isEnabled: true
);
}

EdgeInsets padding = null,
MaterialTapTargetSize? materialTapTargetSize = null,
float? elevation = null,
Color shadowColor = null,
Color selectedShadowColor = null,
ShapeBorder avatarBorder = null
) : base(key: key) {

this._padding = padding;
this._materialTapTargetSize = materialTapTargetSize;
this._elevation = elevation;
this._shadowColor = shadowColor;
this._selectedShadowColor = selectedShadowColor;
}
public Widget avatar {

float? _elevation;
public Color shadowColor {
get { return this._shadowColor; }
}
Color _shadowColor;
public Color selectedShadowColor {
get { return this._selectedShadowColor; }
}
Color _selectedShadowColor;
public ShapeBorder avatarBorder {
get { return this._avatarBorder; }
}

padding: this.padding,
materialTapTargetSize: this.materialTapTargetSize,
elevation: this.elevation,
shadowColor: this.shadowColor,
selectedShadowColor: this.selectedShadowColor,
isEnabled: this.isEnabled == true &&
(this.onSelected != null || this.onDeleted != null || this.onPressed != null),
avatarBorder: this.avatarBorder

EdgeInsets padding = null,
MaterialTapTargetSize? materialTapTargetSize = null,
float? elevation = null,
Color shadowColor = null,
Color selectedShadowColor = null,
ShapeBorder avatarBorder = null
) : base(key: key) {
D.assert(selected != null);

this._padding = padding;
this._materialTapTargetSize = materialTapTargetSize;
this._elevation = elevation;
this._shadowColor = shadowColor;
this._selectedShadowColor = selectedShadowColor;
}
public Widget avatar {

float? _elevation;
public Color shadowColor {
get { return this._shadowColor; }
}
Color _shadowColor;
public Color selectedShadowColor {
get { return this._selectedShadowColor; }
}
Color _selectedShadowColor;
public ShapeBorder avatarBorder {
get { return this._avatarBorder; }
}

isEnabled: this.isEnabled,
materialTapTargetSize: this.materialTapTargetSize,
elevation: this.elevation,
shadowColor: this.shadowColor,
selectedShadowColor: this.selectedShadowColor,
avatarBorder: this.avatarBorder
);
}

EdgeInsets padding = null,
MaterialTapTargetSize? materialTapTargetSize = null,
float? elevation = null,
Color shadowColor = null,
Color selectedShadowColor = null,
ShapeBorder avatarBorder = null
) : base(key: key) {
D.assert(label != null);

this._padding = padding;
this._materialTapTargetSize = materialTapTargetSize;
this._elevation = elevation;
this._shadowColor = shadowColor;
this._selectedShadowColor = selectedShadowColor;
}
public Widget avatar {

float? _elevation;
public Color shadowColor {
get { return this._shadowColor; }
}
Color _shadowColor;
public Color selectedShadowColor {
get { return this._selectedShadowColor; }
}
Color _selectedShadowColor;
public ShapeBorder avatarBorder {
get { return this._avatarBorder; }
}

isEnabled: this.isEnabled,
materialTapTargetSize: this.materialTapTargetSize,
elevation: this.elevation,
shadowColor: this.shadowColor,
selectedShadowColor: this.selectedShadowColor,
avatarBorder: this.avatarBorder
);
}

Color backgroundColor = null,
EdgeInsets padding = null,
MaterialTapTargetSize? materialTapTargetSize = null,
float? elevation = null
float? elevation = null,
Color shadowColor = null
) : base(key: key) {
D.assert(label != null);
D.assert(

this._padding = padding;
this._materialTapTargetSize = materialTapTargetSize;
this._elevation = elevation;
this._shadowColor = shadowColor;
}

float? _elevation;
public Color shadowColor {
get { return this._shadowColor; }
}
Color _shadowColor;
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterial(context));
return new RawChip(

labelPadding: this.labelPadding,
isEnabled: true,
materialTapTargetSize: this.materialTapTargetSize,
elevation: this.elevation
elevation: this.elevation,
shadowColor: this._shadowColor
);
}
}

Color backgroundColor = null,
MaterialTapTargetSize? materialTapTargetSize = null,
float? elevation = null,
Color shadowColor = null,
Color selectedShadowColor = null,
ShapeBorder avatarBorder = null
) : base(key: key) {
D.assert(label != null);

this._backgroundColor = backgroundColor;
this._materialTapTargetSize = materialTapTargetSize;
this._elevation = elevation;
this._shadowColor = shadowColor;
this._selectedShadowColor = selectedShadowColor;
}

float? _elevation;
public Color shadowColor {
get { return this._shadowColor; }
}
Color _shadowColor;
public Color selectedShadowColor {
get { return this._selectedShadowColor; }
}
Color _selectedShadowColor;
public ShapeBorder avatarBorder {
get { return this._avatarBorder; }
}

ShapeBorder shape = this.widget.shape ?? chipTheme.shape;
float elevation = this.widget.elevation ?? (chipTheme.elevation ?? _defaultElevation);
float pressElevation = this.widget.pressElevation ?? (chipTheme.pressElevation ?? _defaultPressElevation);
Color shadowColor = this.widget.shadowColor ?? chipTheme.shadowColor ?? _defaultShadowColor;
Color selectedShadowColor = this.widget.selectedShadowColor ?? chipTheme.selectedShadowColor ?? _defaultShadowColor;
bool selected = this.widget.selected ?? false;
shadowColor: selected ? selectedShadowColor : shadowColor,
child: new InkResponse(
child: new InkWell(
onTapCancel: this.canTap ? this._handleTapCancel : (GestureTapCallback) null,
onTapCancel: this.canTap ? this._handleTapCancel : (GestureTapCancelCallback) null,
customBorder: shape,
child: new AnimatedBuilder(
animation: ListenableUtils.merge(new List<Listenable>
{this.selectController, this.enableController}),

);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this.computeMinIntrinsicHeight(width);
}

22
Runtime/material/chip_theme.cs


Color disabledColor = null,
Color selectedColor = null,
Color secondarySelectedColor = null,
Color shadowColor = null,
Color selectedShadowColor = null,
EdgeInsets labelPadding = null,
EdgeInsets padding = null,
ShapeBorder shape = null,

this.disabledColor = disabledColor;
this.selectedColor = selectedColor;
this.secondarySelectedColor = secondarySelectedColor;
this.shadowColor = shadowColor;
this.selectedShadowColor = selectedShadowColor;
this.labelPadding = labelPadding;
this.padding = padding;
this.shape = shape;

public readonly Color secondarySelectedColor;
public readonly Color shadowColor;
public readonly Color selectedShadowColor;
public readonly EdgeInsets labelPadding;
public readonly EdgeInsets padding;

Color disabledColor = null,
Color selectedColor = null,
Color secondarySelectedColor = null,
Color shadowColor = null,
Color selectedShadowColor = null,
EdgeInsets labelPadding = null,
EdgeInsets padding = null,
ShapeBorder shape = null,

disabledColor: disabledColor ?? this.disabledColor,
selectedColor: selectedColor ?? this.selectedColor,
secondarySelectedColor: secondarySelectedColor ?? this.secondarySelectedColor,
shadowColor: shadowColor ?? this.shadowColor,
selectedShadowColor: selectedShadowColor ?? this.selectedShadowColor,
labelPadding: labelPadding ?? this.labelPadding,
padding: padding ?? this.padding,
shape: shape ?? this.shape,

disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
secondarySelectedColor: Color.lerp(a?.secondarySelectedColor, b?.secondarySelectedColor, t),
shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t),
selectedShadowColor: Color.lerp(a?.selectedShadowColor, b?.selectedShadowColor, t),
labelPadding: EdgeInsets.lerp(a?.labelPadding, b?.labelPadding, t),
padding: EdgeInsets.lerp(a?.padding, b?.padding, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),

hashCode = (hashCode * 397) ^ this.disabledColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.selectedColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.secondarySelectedColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.shadowColor?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.selectedShadowColor?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.labelPadding.GetHashCode();
hashCode = (hashCode * 397) ^ this.padding.GetHashCode();
hashCode = (hashCode * 397) ^ this.shape.GetHashCode();

&& other.disabledColor == this.disabledColor
&& other.selectedColor == this.selectedColor
&& other.secondarySelectedColor == this.secondarySelectedColor
&& other.shadowColor == this.shadowColor
&& other.selectedShadowColor == this.selectedShadowColor
&& other.labelPadding == this.labelPadding
&& other.padding == this.padding
&& other.shape == this.shape

defaultValue: defaultData.selectedColor));
properties.add(new DiagnosticsProperty<Color>("secondarySelectedColor", this.secondarySelectedColor,
defaultValue: defaultData.secondarySelectedColor));
properties.add(new DiagnosticsProperty<Color>("shadowColor", this.shadowColor,
defaultValue: defaultData.shadowColor));
properties.add(new DiagnosticsProperty<Color>("selectedShadowColor", this.selectedShadowColor,
defaultValue: defaultData.selectedShadowColor));
properties.add(new DiagnosticsProperty<EdgeInsets>("labelPadding", this.labelPadding,
defaultValue: defaultData.labelPadding));
properties.add(

2
Runtime/material/dialog.cs


) {
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
ThemeData theme = Theme.of(context, shadowThemeOnly: true);
ThemeData theme = Theme.of(context, shadowThemeOnly: true);
Widget pageChild = new Builder(builder: builder);
return new SafeArea(
child: new Builder(

3
Runtime/material/drawer.cs


Widget child = null,
DrawerAlignment? alignment = null,
DrawerCallback drawerCallback = null,
DragStartBehavior? dragStartBehavior = null
DragStartBehavior dragStartBehavior = DragStartBehavior.start
D.assert(dragStartBehavior != null);
this.child = child;
this.alignment = alignment ?? DrawerAlignment.start;
this.drawerCallback = drawerCallback;

131
Runtime/material/dropdown.cs


public override Widget buildPage(BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation) {
return new LayoutBuilder(
builder: (ctx, constraints) => {
return new _DropdownRoutePage<T>(
route: this,
constraints: constraints,
items: this.items,
padding: this.padding,
buttonRect: this.buttonRect,
selectedIndex: this.selectedIndex,
elevation: this.elevation,
theme: this.theme,
style: this.style
);
}
);
}
internal void _dismiss() {
this.navigator?.removeRoute(this);
}
}
class _DropdownRoutePage<T> : StatelessWidget where T : class {
public _DropdownRoutePage(
Key key = null,
_DropdownRoute<T> route = null,
BoxConstraints constraints = null,
List<DropdownMenuItem<T>> items = null,
EdgeInsets padding = null,
Rect buttonRect = null,
int? selectedIndex = null,
int elevation = 0,
ThemeData theme = null,
TextStyle style = null
) : base(key: key) {
this.route = route;
this.constraints = constraints;
this.items = items;
this.padding = padding;
this.buttonRect = buttonRect;
this.selectedIndex = selectedIndex;
this.elevation = elevation;
this.theme = theme;
this.style = style;
}
public readonly _DropdownRoute<T> route;
public readonly BoxConstraints constraints;
public readonly List<DropdownMenuItem<T>> items;
public readonly EdgeInsets padding;
public readonly Rect buttonRect;
public readonly int? selectedIndex;
public readonly int elevation;
public readonly ThemeData theme;
public readonly TextStyle style;
public override Widget build(BuildContext context) {
float screenHeight = MediaQuery.of(context).size.height;
float maxMenuHeight = screenHeight - 2.0f * DropdownConstants._kMenuItemHeight;
float availableHeight = this.constraints.maxHeight;
float maxMenuHeight = availableHeight - 2.0f * DropdownConstants._kMenuItemHeight;
float buttonBottom = this.buttonRect.bottom;
float buttonBottom = Mathf.Min(this.buttonRect.bottom, availableHeight);
float bottomLimit = Mathf.Max(screenHeight - DropdownConstants._kMenuItemHeight, buttonBottom);
float bottomLimit = Mathf.Max(availableHeight - DropdownConstants._kMenuItemHeight, buttonBottom);
float? selectedItemOffset = this.selectedIndex * DropdownConstants._kMenuItemHeight +
Constants.kMaterialListPadding.top;

menuTop = menuBottom - menuHeight;
}
if (this.scrollController == null) {
if (this.route.scrollController == null) {
this.scrollController = new ScrollController(initialScrollOffset: scrollOffset);
this.route.scrollController = new ScrollController(initialScrollOffset: scrollOffset);
route: this,
route: this.route,
padding: this.padding
);

}
)
);
}
public void _dismiss() {
this.navigator?.removeRoute(this);
}
}

ValueChanged<T> onChanged = null,
int elevation = 8,
TextStyle style = null,
Widget underline = null,
Widget icon = null,
Color iconDisabledColor = null,
Color iconEnabledColor = null,
float iconSize = 24.0f,
bool isDense = false,
bool isExpanded = false

this.onChanged = onChanged;
this.elevation = elevation;
this.style = style;
this.underline = underline;
this.icon = icon;
this.iconDisabledColor = iconDisabledColor;
this.iconEnabledColor = iconEnabledColor;
this.iconSize = iconSize;
this.isDense = isDense;
this.isExpanded = isExpanded;

public readonly TextStyle style;
public readonly Widget underline;
public readonly Widget icon;
public readonly Color iconDisabledColor;
public readonly Color iconEnabledColor;
public readonly float iconSize;
public readonly bool isDense;

}
}
Color _downArrowColor {
Color _iconColor {
if (Theme.of(this.context).brightness == Brightness.light) {
return Colors.grey.shade700;
if (this.widget.iconEnabledColor != null) {
return this.widget.iconEnabledColor;
else {
return Colors.white70;
switch (Theme.of(this.context).brightness) {
case Brightness.light:
return Colors.grey.shade700;
case Brightness.dark:
return Colors.white70;
if (Theme.of(this.context).brightness == Brightness.light) {
return Colors.grey.shade400;
if (this.widget.iconDisabledColor != null) {
return this.widget.iconDisabledColor;
else {
return Colors.white10;
switch (Theme.of(this.context).brightness) {
case Brightness.light:
return Colors.grey.shade400;
case Brightness.dark:
return Colors.white10;
D.assert(false);
return null;
}
}

children: items
);
Icon defaultIcon = new Icon(Icons.arrow_drop_down);
Widget result = new DefaultTextStyle(
style: this._textStyle,
child: new Container(

mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
this.widget.isExpanded ? new Expanded(child: innerItemsWidget) : (Widget) innerItemsWidget,
new Icon(Icons.arrow_drop_down,
size: this.widget.iconSize,
color: this._downArrowColor
new IconTheme(
data: new IconThemeData(
color: this._iconColor,
size: this.widget.iconSize
),
child: this.widget.icon ?? defaultIcon
)
}
)

left: 0.0f,
right: 0.0f,
bottom: bottom,
child: new Container(
child: this.widget.underline ?? new Container(
height: 1.0f,
decoration: new BoxDecoration(
border: new Border(

32
Runtime/material/expansion_panel.cs


public ExpansionPanel(
ExpansionPanelHeaderBuilder headerBuilder = null,
Widget body = null,
bool isExpanded = false) {
bool isExpanded = false,
bool canTapOnHeader = false) {
this.canTapOnHeader = false;
}
public readonly ExpansionPanelHeaderBuilder headerBuilder;

public readonly bool isExpanded;
public readonly bool canTapOnHeader;
}

ExpansionPanelHeaderBuilder headerBuilder = null,
Widget body = null) : base(body: body, headerBuilder: headerBuilder) {
Widget body = null,
bool canTapOnHeader = false)
: base(body: body, headerBuilder: headerBuilder, canTapOnHeader: canTapOnHeader) {
D.assert(headerBuilder != null);
D.assert(body != null);
D.assert(value != null);

}
ExpansionPanel child = this.widget.children[index];
Widget headerWidget = child.headerBuilder(
context,
this._isChildExpanded(index)
);
Row header = new Row(
children: new List<Widget> {
new Expanded(

child: new ConstrainedBox(
constraints: new BoxConstraints(
minHeight: ExpansionPanelUtils._kPanelHeaderCollapsedHeight),
child: child.headerBuilder(
context,
this._isChildExpanded(index))
child: headerWidget
)
)
),

isExpanded: this._isChildExpanded(index),
padding: EdgeInsets.all(16.0f),
onPressed: (bool isExpanded) => this._handlePressed(isExpanded, expandIndex)
onPressed: !child.canTapOnHeader
? (ValueChanged<bool>) ((bool isExpanded) => {
this._handlePressed(isExpanded, expandIndex);
})
: null
)
)
}

key: new _SaltedKey<BuildContext, int>(context, index * 2),
child: new Column(
children: new List<Widget> {
header,
child.canTapOnHeader
? (Widget) new InkWell(
onTap: () =>
this._handlePressed(this._isChildExpanded(expandIndex), expandIndex),
child: header
)
: header,
new AnimatedCrossFade(
firstChild: new Container(height: 0.0f),
secondChild: child.body,

4
Runtime/material/ink_well.cs


Widget child = null,
GestureTapCallback onTap = null,
GestureTapDownCallback onTapDown = null,
GestureTapCallback onTapCancel = null,
GestureTapCancelCallback onTapCancel = null,
GestureTapCallback onDoubleTap = null,
GestureLongPressCallback onLongPress = null,
ValueChanged<bool> onHighlightChanged = null,

public readonly GestureTapDownCallback onTapDown;
public readonly GestureTapCallback onTapCancel;
public readonly GestureTapCancelCallback onTapCancel;
public readonly GestureTapCallback onDoubleTap;

4
Runtime/material/input_border.cs


const float cornerArcSweep = Mathf.PI / 2.0f;
float tlCornerArcSweep = start < center.tlRadiusX
? Mathf.Asin(start / center.tlRadiusX)
? Mathf.Asin((start / center.tlRadiusX).clamp(-1.0f, 1.0f))
: Mathf.PI / 2.0f;
Path path = new Path();

}
else {
float extent = MathUtils.lerpFloat(0.0f, gapExtent + this.gapPadding * 2.0f, gapPercentage);
Path path = this._gapBorderPath(canvas, center, gapStart - this.gapPadding, extent);
Path path = this._gapBorderPath(canvas, center, Mathf.Max(0.0f,gapStart - this.gapPadding), extent);
canvas.drawPath(path, paint);
}
}

287
Runtime/material/input_decorator.cs


public _RenderDecoration(
_Decoration decoration,
TextBaseline? textBaseline,
bool isFocused
bool isFocused,
bool expands
) {
D.assert(decoration != null);
D.assert(textBaseline != null);

this._expands = expands;
public const float subtextGap = 8.0f;
public readonly Dictionary<_DecorationSlot, RenderBox> slotToChild =
new Dictionary<_DecorationSlot, RenderBox>();

bool _isFocused;
public bool expands {
get { return this._expands; }
set {
if (this._expands == value) {
return;
}
this._expands = value;
this.markNeedsLayout();
}
}
bool _expands = false;
public override void attach(object owner) {
base.attach(owner);
foreach (RenderBox child in this._children) {

get { return this.decoration.contentPadding; }
}
float _layoutLineBox(RenderBox box, BoxConstraints constraints) {
if (box == null) {
return 0.0f;
}
box.layout(constraints, parentUsesSize: true);
float baseline = box.getDistanceToBaseline(this.textBaseline.Value).Value;
D.assert(baseline >= 0.0f);
return baseline;
}
float aboveBaseline = 0.0f;
float belowBaseline = 0.0f;
void layoutLineBox(RenderBox box) {
if (box == null) {
return;
}
box.layout(boxConstraints, parentUsesSize: true);
float baseline = box.getDistanceToBaseline(this.textBaseline ?? 0.0f) ?? 0.0f;
D.assert(baseline >= 0.0f);
boxToBaseline[box] = baseline;
aboveBaseline = Mathf.Max(baseline, aboveBaseline);
belowBaseline = Mathf.Max(box.size.height - baseline, belowBaseline);
if (this.prefix != null) {
boxToBaseline[this.prefix] = this._layoutLineBox(this.prefix, boxConstraints);
}
if (this.suffix != null) {
boxToBaseline[this.suffix] = this._layoutLineBox(this.suffix, boxConstraints);
layoutLineBox(this.prefix);
layoutLineBox(this.suffix);
this.icon.layout(boxConstraints, parentUsesSize: true);
boxToBaseline[this.icon] = this._layoutLineBox(this.icon, boxConstraints);
this.prefixIcon.layout(boxConstraints, parentUsesSize: true);
boxToBaseline[this.prefixIcon] = this._layoutLineBox(this.prefixIcon, boxConstraints);
this.suffixIcon.layout(boxConstraints, parentUsesSize: true);
boxToBaseline[this.suffixIcon] = this._layoutLineBox(this.suffixIcon, boxConstraints);
float inputWidth = Mathf.Max(0.0f, this.constraints.maxWidth - (
_boxSize(this.icon).width
+ this.contentPadding.left
+ _boxSize(this.prefixIcon).width
+ _boxSize(this.prefix).width
+ _boxSize(this.suffix).width
+ _boxSize(this.suffixIcon).width
+ this.contentPadding.right));
boxConstraints = boxConstraints.copyWith(maxWidth: inputWidth);
float inputWidth = Math.Max(0.0f, this.constraints.maxWidth - (
_boxSize(this.icon).width
+ this.contentPadding.left
+ _boxSize(this.prefixIcon).width
+ _boxSize(this.prefix).width
+ _boxSize(this.suffix).width
+ _boxSize(this.suffixIcon).width
+ this.contentPadding.right));
if (this.decoration.alignLabelWithHint == true) {
layoutLineBox(this.label);
}
else {
this.label.layout(boxConstraints, parentUsesSize: true);
}
boxToBaseline[this.label] = this._layoutLineBox(this.label,
boxConstraints.copyWith(maxWidth: inputWidth)
);
boxConstraints = boxConstraints.copyWith(minWidth: inputWidth);
layoutLineBox(this.hint);
layoutLineBox(this.input);
if (this.hint != null) {
boxToBaseline[this.hint] = this._layoutLineBox(this.hint,
boxConstraints.copyWith(minWidth: inputWidth, maxWidth: inputWidth)
);
}
float inputBaseline = this.contentPadding.top + aboveBaseline;
float containerHeight = this.contentPadding.top
+ aboveBaseline
+ belowBaseline
+ this.contentPadding.bottom;
if (this.counter != null) {
boxToBaseline[this.counter] = this._layoutLineBox(this.counter, boxConstraints);
}
if (this.label != null) {
containerHeight += this.decoration.floatingLabelHeight;
inputBaseline += this.decoration.floatingLabelHeight;
if (this.helperError != null) {
boxToBaseline[this.helperError] = this._layoutLineBox(this.helperError,
boxConstraints.copyWith(
maxWidth: Math.Max(0.0f, boxConstraints.maxWidth
- _boxSize(this.icon).width
- _boxSize(this.counter).width
- this.contentPadding.horizontal
)
)
);
}
float labelHeight = this.label == null
? 0
: this.decoration.floatingLabelHeight;
float topHeight = this.decoration.border.isOutline
? Math.Max(labelHeight - boxToBaseline[this.label], 0)
: labelHeight;
float counterHeight = this.counter == null
? 0
: boxToBaseline[this.counter] + subtextGap;
bool helperErrorExists = this.helperError?.size != null
&& this.helperError.size.height > 0;
float helperErrorHeight = !helperErrorExists
? 0
: this.helperError.size.height + subtextGap;
float bottomHeight = Math.Max(
counterHeight,
helperErrorHeight
);
if (this.input != null) {
boxToBaseline[this.input] = this._layoutLineBox(this.input,
boxConstraints.deflate(EdgeInsets.only(
top: this.contentPadding.top + topHeight,
bottom: this.contentPadding.bottom + bottomHeight
)).copyWith(
minWidth: inputWidth,
maxWidth: inputWidth
)
);
containerHeight = Mathf.Max(
containerHeight,
Mathf.Max(
_boxSize(this.suffixIcon).height,
_boxSize(this.prefixIcon).height));
// The field can be occupied by a hint or by the input itself
float hintHeight = this.hint == null ? 0 : this.hint.size.height;
float inputDirectHeight = this.input == null ? 0 : this.input.size.height;
float inputHeight = Math.Max(hintHeight, inputDirectHeight);
float inputInternalBaseline = Math.Max(
boxToBaseline.getOrDefault(this.input, 0.0f),
boxToBaseline.getOrDefault(this.hint, 0.0f)
);
float outlineBaseline = aboveBaseline +
(containerHeight - (2.0f + aboveBaseline + belowBaseline)) / 2.0f;
// Calculate the amount that prefix/suffix affects height above and below
// the input.
float prefixHeight = this.prefix == null ? 0 : this.prefix.size.height;
float suffixHeight = this.suffix == null ? 0 : this.suffix.size.height;
float fixHeight = Math.Max(
boxToBaseline.getOrDefault(this.prefix, 0.0f),
boxToBaseline.getOrDefault(this.suffix, 0.0f)
);
float fixAboveInput = Math.Max(0, fixHeight - inputInternalBaseline);
float fixBelowBaseline = Math.Max(
prefixHeight - boxToBaseline.getOrDefault(this.prefix, 0.0f),
suffixHeight - boxToBaseline.getOrDefault(this.suffix, 0.0f)
);
float fixBelowInput = Math.Max(
0,
fixBelowBaseline - (inputHeight - inputInternalBaseline)
);
float subtextBaseline = 0.0f;
float subtextHeight = 0.0f;
if (this.helperError != null || this.counter != null) {
boxConstraints = layoutConstraints.loosen();
aboveBaseline = 0.0f;
belowBaseline = 0.0f;
layoutLineBox(this.counter);
// Calculate the height of the input text container.
float prefixIconHeight = this.prefixIcon == null ? 0 : this.prefixIcon.size.height;
float suffixIconHeight = this.suffixIcon == null ? 0 : this.suffixIcon.size.height;
float fixIconHeight = Math.Max(prefixIconHeight, suffixIconHeight);
float contentHeight = Math.Max(
fixIconHeight,
topHeight
+ this.contentPadding.top
+ fixAboveInput
+ inputHeight
+ fixBelowInput
+ this.contentPadding.bottom
);
float maxContainerHeight = boxConstraints.maxHeight - bottomHeight;
float containerHeight = this.expands
? maxContainerHeight
: Math.Min(contentHeight, maxContainerHeight);
// Always position the prefix/suffix in the same place (baseline).
float overflow = Math.Max(0, contentHeight - maxContainerHeight);
float baselineAdjustment = fixAboveInput - overflow;
// The baselines that will be used to draw the actual input text content.
float inputBaseline = this.contentPadding.top
+ topHeight
+ inputInternalBaseline
+ baselineAdjustment;
// The text in the input when an outline border is present is centered
// within the container less 2.0 dps at the top to account for the vertical
// space occupied by the floating label.
float outlineBaseline = inputInternalBaseline
+ baselineAdjustment / 2
+ (containerHeight - (2.0f + inputHeight)) / 2.0f;
boxConstraints = boxConstraints.copyWith(
maxWidth: Mathf.Max(0.0f, boxConstraints.maxWidth
- _boxSize(this.icon).width
- _boxSize(this.counter).width
- this.contentPadding.horizontal
)
);
layoutLineBox(this.helperError);
// Find the positions of the text below the input when it exists.
float subtextCounterBaseline = 0;
float subtextHelperBaseline = 0;
float subtextCounterHeight = 0;
float subtextHelperHeight = 0;
if (this.counter != null) {
subtextCounterBaseline =
containerHeight + subtextGap + boxToBaseline.getOrDefault(this.counter, 0.0f);
subtextCounterHeight = this.counter.size.height + subtextGap;
}
if (aboveBaseline + belowBaseline > 0.0f) {
const float subtextGap = 8.0f;
subtextBaseline = containerHeight + subtextGap + aboveBaseline;
subtextHeight = subtextGap + aboveBaseline + belowBaseline;
}
if (helperErrorExists) {
subtextHelperBaseline =
containerHeight + subtextGap + boxToBaseline.getOrDefault(this.helperError, 0.0f);
subtextHelperHeight = helperErrorHeight;
float subtextBaseline = Math.Max(
subtextCounterBaseline,
subtextHelperBaseline
);
float subtextHeight = Math.Max(
subtextCounterHeight,
subtextHelperHeight
);
return new _RenderDecorationLayout(
boxToBaseline: boxToBaseline,
containerHeight: containerHeight,

protected override float computeMinIntrinsicHeight(float width) {
float subtextHeight = this._lineHeight(width, new List<RenderBox> {this.helperError, this.counter});
if (subtextHeight > 0.0f) {
subtextHeight += 8.0f;
subtextHeight += subtextGap;
}
return this.contentPadding.top

+ this.contentPadding.bottom;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
D.assert(false, () => "not implemented");
return 0.0f;
return _boxParentData(this.input).offset.dy + this.input.getDistanceToActualBaseline(baseline);
}
Matrix3 _labelTransform;

Key key = null,
_Decoration decoration = null,
TextBaseline? textBaseline = null,
bool isFocused = false
bool isFocused = false,
bool? expands = null
D.assert(expands != null);
this.expands = expands.Value;
public readonly bool expands;
public override Element createElement() {
return new _RenderDecorationElement(this);

return new _RenderDecoration(
decoration: this.decoration,
textBaseline: this.textBaseline,
isFocused: this.isFocused
isFocused: this.isFocused,
expands: this.expands
);
}

renderObject.textBaseline = this.textBaseline;
renderObject.isFocused = this.isFocused;
renderObject.expands = this.expands;
}
}

TextStyle baseStyle = null,
TextAlign? textAlign = null,
bool isFocused = false,
bool expands = false,
bool isEmpty = false,
Widget child = null
) : base(key: key) {

this.isFocused = isFocused;
this.expands = expands;
this.isEmpty = isEmpty;
this.child = child;
}

public readonly TextAlign? textAlign;
public readonly bool isFocused;
public readonly bool expands;
public readonly bool isEmpty;

properties.add(new DiagnosticsProperty<InputDecoration>("decoration", this.decoration));
properties.add(new DiagnosticsProperty<TextStyle>("baseStyle", this.baseStyle, defaultValue: null));
properties.add(new DiagnosticsProperty<bool>("isFocused", this.isFocused));
properties.add(new DiagnosticsProperty<bool>("expands", this.expands));
properties.add(new DiagnosticsProperty<bool>("isEmpty", this.isEmpty));
}
}

container: container
),
textBaseline: textBaseline,
isFocused: this.isFocused
isFocused: this.isFocused,
expands: this.widget.expands
);
}
}

bool? alignLabelWithHint = null
) {
D.assert(enabled != null);
D.assert(!(prefix != null && prefixText != null), () => "Declaring both prefix and prefixText is not supported");
D.assert(!(suffix != null && suffixText != null), () => "Declaring both suffix and suffixText is not supported");
D.assert(!(prefix != null && prefixText != null),
() => "Declaring both prefix and prefixText is not supported");
D.assert(!(suffix != null && suffixText != null),
() => "Declaring both suffix and suffixText is not supported");
this.isCollapsed = false;
this.icon = icon;
this.labelText = labelText;

18
Runtime/material/list_tile.cs


this.title.getMinIntrinsicHeight(width) + this.subtitle?.getMinIntrinsicHeight(width) ?? 0.0f);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this.computeMinIntrinsicHeight(width);
}

bool hasTrailing = this.trailing != null;
bool isTwoLine = !this.isThreeLine && hasSubtitle;
bool isOneLine = !this.isThreeLine && !hasSubtitle;
BoxConstraints maxIconHeightConstrains = new BoxConstraints(
maxHeight: this.isDense ? 48.0f: 56.0f
);
BoxConstraints iconConstraints = looseConstraints.enforce(maxIconHeightConstrains);
Size leadingSize = _layoutBox(this.leading, looseConstraints);
Size trailingSize = _layoutBox(this.trailing, looseConstraints);
Size leadingSize = _layoutBox(this.leading, iconConstraints);
Size trailingSize = _layoutBox(this.trailing, iconConstraints);
D.assert(
tileWidth != leadingSize.width,
() => "Leading widget consumes entire width. Please use a sized widget."
);
D.assert(
tileWidth != trailingSize.width,
() => "Trailing widget consumes entire width. Please use a sized widget."
);
float titleStart = hasLeading
? Mathf.Max(_minLeadingWidth, leadingSize.width) + _horizontalTitleGap

6
Runtime/material/material.cs


public override Widget build(BuildContext context) {
Color backgroundColor = this._getBackgroundColor(context);
D.assert(backgroundColor != null || this.widget.type == MaterialType.transparency);
D.assert(backgroundColor != null || this.widget.type == MaterialType.transparency,
() => "If Material type is not MaterialType.transparency, a color must" +
"either be passed in through the 'color' property, or be defined " +
"in the theme (ex. canvasColor != null if type is set to " +
"MaterialType.canvas");
Widget contents = this.widget.child;
if (contents != null) {
contents = new AnimatedDefaultTextStyle(

4
Runtime/material/material_button.cs


return new RawMaterialButton(
onPressed: this.onPressed,
onHighlightChanged: this.onHighlightChanged,
fillColor: this.color,
fillColor: buttonTheme.getFillColor(this),
textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)),
highlightColor: this.highlightColor ?? theme.highlightColor,
splashColor: this.splashColor ?? theme.splashColor,

constraints: buttonTheme.getConstraints(this).copyWith(
minWidth: this.minWidth,
minHeight: this.height),
shape: buttonTheme.shape,
shape: buttonTheme.getShape(this),
clipBehavior: this.clipBehavior ?? Clip.none,
animationDuration: buttonTheme.getAnimationDuration(this),
child: this.child,

1
Runtime/material/popup_menu.cs


float elevation = 8.0f
) {
D.assert(context != null);
D.assert(position != null);
D.assert(items != null && items.isNotEmpty());
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));

16
Runtime/material/progress_indicator.cs


class _CircularProgressIndicatorPainter : AbstractCustomPainter {
public _CircularProgressIndicatorPainter(
Color backgroundColor = null,
Color valueColor = null,
float? value = null,
float? headValue = null,

float? strokeWidth = null
) {
this.backgroundColor = backgroundColor;
this.valueColor = valueColor;
this.value = value;
this.headValue = headValue;

: Mathf.Max(headValue * 3 / 2 * Mathf.PI - tailValue * 3 / 2 * Mathf.PI ?? 0.0f, _epsilon);
}
public readonly Color backgroundColor;
public readonly Color valueColor;
public readonly float? value;
public readonly float? headValue;

paint.strokeWidth = this.strokeWidth ?? 0.0f;
paint.style = PaintingStyle.stroke;
if (this.backgroundColor != null) {
Paint backgroundPaint = new Paint() {
color = this.backgroundColor,
strokeWidth = this.strokeWidth ?? 0.0f,
style = PaintingStyle.stroke
};
canvas.drawArc(Offset.zero & size, 0, _sweep, false, backgroundPaint);
}
if (this.value == null)
{
paint.strokeCap = StrokeCap.square;

public override bool shouldRepaint(CustomPainter oldPainter) {
D.assert(oldPainter is _CircularProgressIndicatorPainter);
_CircularProgressIndicatorPainter painter = oldPainter as _CircularProgressIndicatorPainter;
return painter.valueColor != this.valueColor
return painter.backgroundColor != this.backgroundColor
|| painter.valueColor != this.valueColor
|| painter.value != this.value
|| painter.headValue != this.headValue
|| painter.tailValue != this.tailValue

),
child: new CustomPaint(
painter: new _CircularProgressIndicatorPainter(
backgroundColor: this.widget.backgroundColor,
valueColor: this.widget._getValueColor(context),
value: this.widget.value,
headValue: headValue,

3
Runtime/material/radio.cs


public override void paint(PaintingContext context, Offset offset) {
Canvas canvas = context.canvas;
this.paintRadialReaction(canvas, offset,
new Offset(Constants.kRadialReactionRadius, Constants.kRadialReactionRadius));
this.paintRadialReaction(canvas, offset, this.size.center(Offset.zero));
Offset center = (offset & this.size).center;
Color radioColor = this.onChanged != null ? this.activeColor : this.inactiveColor;

113
Runtime/material/scaffold.cs


}
}
class _BodyBoxConstraints : BoxConstraints {
public _BodyBoxConstraints(
float minWidth = 0.0f,
float maxWidth = float.PositiveInfinity,
float minHeight = 0.0f,
float maxHeight = float.PositiveInfinity,
float? bottomWidgetsHeight = null
) : base(minWidth: minWidth, maxWidth: maxWidth, minHeight: minHeight, maxHeight: maxHeight) {
D.assert(bottomWidgetsHeight != null);
D.assert(bottomWidgetsHeight >= 0);
this.bottomWidgetsHeight = bottomWidgetsHeight.Value;
}
public readonly float bottomWidgetsHeight;
public bool Equals(_BodyBoxConstraints other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return this.bottomWidgetsHeight.Equals(other.bottomWidgetsHeight)
&& base.Equals(other);
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
if (obj.GetType() != this.GetType()) {
return false;
}
return this.Equals((_BodyBoxConstraints) obj);
}
public override int GetHashCode() {
unchecked {
var hashCode = base.GetHashCode();
hashCode = (hashCode * 397) ^ this.bottomWidgetsHeight.GetHashCode();
return hashCode;
}
}
public static bool operator ==(_BodyBoxConstraints left, _BodyBoxConstraints right) {
return Equals(left, right);
}
public static bool operator !=(_BodyBoxConstraints left, _BodyBoxConstraints right) {
return !Equals(left, right);
}
}
class _BodyBuilder : StatelessWidget {
public _BodyBuilder(Key key = null, Widget body = null) : base(key: key) {
this.body = body;
}
public readonly Widget body;
public override Widget build(BuildContext context) {
return new LayoutBuilder(
builder: (ctx, constraints) => {
_BodyBoxConstraints bodyConstraints = (_BodyBoxConstraints) constraints;
MediaQueryData metrics = MediaQuery.of(context);
return new MediaQuery(
data: metrics.copyWith(
padding: metrics.padding.copyWith(
bottom: Mathf.Max(metrics.padding.bottom, bodyConstraints.bottomWidgetsHeight)
)
)
);
}
);
}
}
class _ScaffoldLayout : MultiChildLayoutDelegate {
public _ScaffoldLayout(
EdgeInsets minInsets,

float floatingActionButtonMoveAnimationProgress,
FloatingActionButtonAnimator floatingActionButtonMotionAnimator
FloatingActionButtonAnimator floatingActionButtonMotionAnimator,
bool extendBody
) {
D.assert(minInsets != null);
D.assert(geometryNotifier != null);

this.currentFloatingActionButtonLocation = currentFloatingActionButtonLocation;
this.floatingActionButtonMoveAnimationProgress = floatingActionButtonMoveAnimationProgress;
this.floatingActionButtonMotionAnimator = floatingActionButtonMotionAnimator;
this.extendBody = extendBody;
public readonly bool extendBody;
public readonly EdgeInsets minInsets;
public readonly _ScaffoldGeometryNotifier geometryNotifier;

float contentBottom = Mathf.Max(0.0f, bottom - Mathf.Max(this.minInsets.bottom, bottomWidgetsHeight));
if (this.hasChild(_ScaffoldSlot.body)) {
BoxConstraints bodyConstraints = new BoxConstraints(
float bodyMaxHeight = Mathf.Max(0.0f, contentBottom - contentTop);
if (this.extendBody) {
bodyMaxHeight += bottomWidgetsHeight;
D.assert(bodyMaxHeight <= Mathf.Max(0.0f, looseConstraints.maxHeight - contentTop));
}
BoxConstraints bodyConstraints = new _BodyBoxConstraints(
maxHeight: Mathf.Max(0.0f, contentBottom - contentTop)
maxHeight: bodyMaxHeight,
bottomWidgetsHeight: this.extendBody ? bottomWidgetsHeight : 0.0f
);
this.layoutChild(_ScaffoldSlot.body, bodyConstraints);
this.positionChild(_ScaffoldSlot.body, new Offset(0.0f, contentTop));

bool? resizeToAvoidBottomPadding = null,
bool? resizeToAvoidBottomInset = null,
bool primary = true,
DragStartBehavior drawerDragStartBehavior = DragStartBehavior.down
DragStartBehavior drawerDragStartBehavior = DragStartBehavior.start,
bool extendBody = false
) : base(key: key) {
this.appBar = appBar;
this.body = body;

this.resizeToAvoidBottomInset = resizeToAvoidBottomInset;
this.primary = primary;
this.drawerDragStartBehavior = drawerDragStartBehavior;
this.extendBody = extendBody;
public readonly bool extendBody;
public readonly PreferredSizeWidget appBar;

this._addIfNonNull(
children: children,
child: this.widget.body,
child: this.widget.body != null && this.widget.extendBody
? new _BodyBuilder(body: this.widget.body) : this.widget.body,
childId: _ScaffoldSlot.body,
removeLeftPadding: false,
removeTopPadding: this.widget.appBar != null,

bottom: this._resizeToAvoidBottomInset ? mediaQuery.viewInsets.bottom : 0.0f
);
bool _extendBody = !(minInsets.bottom > 0) && this.widget.extendBody;
return new _ScaffoldScope(
hasDrawer: this.hasDrawer,
geometryNotifier: this._geometryNotifier,

return new CustomMultiChildLayout(
children: new List<Widget>(children),
layoutDelegate: new _ScaffoldLayout(
extendBody: _extendBody,
minInsets: minInsets,
currentFloatingActionButtonLocation: this._floatingActionButtonLocation,
floatingActionButtonMoveAnimationProgress: this

12
Runtime/material/slider.cs


return Mathf.Max(this._minPreferredTrackHeight, this._maxSliderPartHeight);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return Mathf.Max(this._minPreferredTrackHeight, this._maxSliderPartHeight);
}

sliderTheme: this._sliderTheme
).width;
if ((trackRect.width - tickMarkWidth) / this.divisions.Value >= 3.0f * tickMarkWidth) {
float adjustedTrackWidth = trackRect.width - tickMarkWidth;
if (adjustedTrackWidth / this.divisions.Value >= 3.0f * tickMarkWidth) {
float dy = trackRect.center.dy;
float tickX = trackRect.left +
tickValue * (trackRect.width - tickMarkWidth) + tickMarkWidth / 2;
float tickY = trackRect.center.dy;
Offset tickMarkOffset = new Offset(tickX, tickY);
float dx = trackRect.left + tickValue * adjustedTrackWidth + tickMarkWidth / 2;
Offset tickMarkOffset = new Offset(dx, dy);
this._sliderTheme.tickMarkShape.paint(
context,
tickMarkOffset,

4
Runtime/material/switch.cs


ImageProvider activeThumbImage = null,
ImageProvider inactiveThumbImage = null,
MaterialTapTargetSize? materialTapTargetSize = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : this(
key: key,
value: value,

ImageProvider inactiveThumbImage = null,
MaterialTapTargetSize? materialTapTargetSize = null,
_SwitchType switchType = _SwitchType.material,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key) {
D.assert(value != null);
this.value = value.Value;

9
Runtime/material/tab_bar_theme.cs


Decoration indicator = null,
TabBarIndicatorSize? indicatorSize = null,
Color labelColor = null,
EdgeInsets labelPadding = null,
TextStyle labelStyle = null,
Color unselectedLabelColor = null,
TextStyle unselectedLabelStyle = null) {

this.labelPadding = labelPadding;
this.labelStyle = labelStyle;
this.unselectedLabelColor = unselectedLabelColor;
this.unselectedLabelStyle = unselectedLabelStyle;

public readonly Color labelColor;
public readonly EdgeInsets labelPadding;
public readonly TextStyle labelStyle;
public readonly Color unselectedLabelColor;

Decoration indicator = null,
TabBarIndicatorSize? indicatorSize = null,
Color labelColor = null,
EdgeInsets labelPadding = null,
TextStyle labelStyle = null,
Color unselectedLabelColor = null,
TextStyle unselectedLabelStyle = null

indicatorSize: indicatorSize ?? this.indicatorSize,
labelColor: labelColor ?? this.labelColor,
labelPadding: labelPadding ?? this.labelPadding,
labelStyle: labelStyle ?? this.labelStyle,
unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor,
unselectedLabelStyle: unselectedLabelStyle ?? this.unselectedLabelStyle);

indicator: Decoration.lerp(a.indicator, b.indicator, t),
indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize,
labelColor: Color.lerp(a.labelColor, b.labelColor, t),
labelPadding: EdgeInsets.lerp(a.labelPadding, b.labelPadding, t),
labelStyle: TextStyle.lerp(a.labelStyle, b.labelStyle, t),
unselectedLabelColor: Color.lerp(a.unselectedLabelColor, b.unselectedLabelColor, t),
unselectedLabelStyle: TextStyle.lerp(a.unselectedLabelStyle, b.unselectedLabelStyle, t)

var hashCode = this.indicator != null ? this.indicator.GetHashCode() : 0;
hashCode = (hashCode * 397) ^ (this.indicatorSize != null ? this.indicatorSize.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.labelColor != null ? this.labelColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.labelPadding != null ? this.labelPadding.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.labelStyle != null ? this.labelStyle.GetHashCode() : 0);
hashCode = (hashCode * 397) ^
(this.unselectedLabelColor != null ? this.unselectedLabelColor.GetHashCode() : 0);

return other.indicator == this.indicator &&
other.indicatorSize == this.indicatorSize &&
other.labelColor == this.labelColor &&
other.labelPadding == this.labelPadding &&
other.unselectedLabelColor == this.unselectedLabelColor;
}

41
Runtime/material/tabs.cs


protected internal override Widget build(BuildContext context) {
ThemeData themeData = Theme.of(context);
TabBarTheme tabBarTheme = TabBarTheme.of(context);
TextStyle defaultStyle = this.labelStyle ?? tabBarTheme.labelStyle ?? themeData.primaryTextTheme.body2;
TextStyle defaultUnselectedStyle = this.unselectedLabelStyle
Animation<float> animation = (Animation<float>) this.listenable;
TextStyle defaultStyle = (this.labelStyle
?? tabBarTheme.labelStyle
?? themeData.primaryTextTheme.body2).copyWith(inherit: true);
TextStyle defaultUnselectedStyle = (this.unselectedLabelStyle
?? this.labelStyle ?? themeData.primaryTextTheme.body2;
Animation<float> animation = (Animation<float>) this.listenable;
?? this.labelStyle
?? themeData.primaryTextTheme.body2).copyWith(inherit: true);
TextStyle textStyle = this.selected
? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value)
: TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value);

EdgeInsets labelPadding = null,
Color unselectedLabelColor = null,
TextStyle unselectedLabelStyle = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ValueChanged<int> onTap = null
) : base(key: key) {
indicatorPadding = indicatorPadding ?? EdgeInsets.zero;

return true;
});
D.assert(() => {
if (newController.length != this.widget.tabs.Count) {
throw new UIWidgetsError(
$"Controller's length property {newController.length} does not match the\n" +
$"number of tab elements {this.widget.tabs.Count} present in TabBar's tabs property."
);
}
return true;
});
if (newController == this._controller) {
return;
}

);
}
TabBarTheme tabBarTheme = TabBarTheme.of(context);
padding: this.widget.labelPadding ?? Constants.kTabLabelPadding,
padding: this.widget.labelPadding ?? tabBarTheme.labelPadding ?? Constants.kTabLabelPadding,
child: new KeyedSubtree(
key: this._tabKeys[i],
child: this.widget.tabs[i]

List<Widget> children = null,
TabController controller = null,
ScrollPhysics physics = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key) {
D.assert(children != null);
this.children = children;

"TabController using the \"controller\" property, or you must ensure that there " +
"is a DefaultTabController above the " + this.widget.GetType() + ".\n" +
"In this case, there was neither an explicit controller nor a default controller."
);
}
return true;
});
D.assert(() => {
if (newController.length != this.widget.children.Count) {
throw new UIWidgetsError(
$"Controller's length property {newController.length} does not match the\n" +
$"number of elements {this.widget.children.Count} present in TabBarView's children property."
);
}

143
Runtime/material/text_field.cs


using System.Collections.Generic;
using System.Text;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;

bool? isFocused);
public class TextField : StatefulWidget {
public TextField(Key key = null, TextEditingController controller = null, FocusNode focusNode = null,
InputDecoration decoration = null, bool noDecoration = false, TextInputType keyboardType = null,
public TextField(Key key = null,
TextEditingController controller = null,
FocusNode focusNode = null,
InputDecoration decoration = null,
bool noDecoration = false,
TextInputType keyboardType = null,
TextCapitalization textCapitalization = TextCapitalization.none, TextStyle style = null,
TextAlign textAlign = TextAlign.left, TextDirection textDirection = TextDirection.ltr,
bool autofocus = false, bool obscureText = false, bool autocorrect = false, int? maxLines = 1,
int? maxLength = null, bool maxLengthEnforced = true, ValueChanged<string> onChanged = null,
TextCapitalization textCapitalization = TextCapitalization.none,
TextStyle style = null,
StrutStyle strutStyle = null,
TextAlign textAlign = TextAlign.left,
TextDirection textDirection = TextDirection.ltr,
bool autofocus = false,
bool obscureText = false,
bool autocorrect = false,
int? maxLines = 1,
int? minLines = null,
bool expands = false,
int? maxLength = null,
bool maxLengthEnforced = true,
ValueChanged<string> onChanged = null,
ValueChanged<string> onSubmitted = null, List<TextInputFormatter> inputFormatters = null,
bool? enabled = null, float? cursorWidth = 2.0f, Radius cursorRadius = null, Color cursorColor = null,
Brightness? keyboardAppearance = null, EdgeInsets scrollPadding = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down,
ValueChanged<string> onSubmitted = null,
List<TextInputFormatter> inputFormatters = null,
bool? enabled = null,
float? cursorWidth = 2.0f,
Radius cursorRadius = null,
Color cursorColor = null,
Brightness? keyboardAppearance = null,
EdgeInsets scrollPadding = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
InputCounterWidgetBuilder buildCounter = null
InputCounterWidgetBuilder buildCounter = null,
ScrollPhysics scrollPhysics = null
D.assert(minLines == null || minLines > 0);
D.assert((maxLines == null) || (minLines == null) || (maxLines >= minLines),
() => "minLines can't be greater than maxLines");
D.assert(!expands || (maxLines == null && minLines == null),
() => "minLines and maxLines must be null when expands is true.");
D.assert(maxLength == null || maxLength == TextField.noMaxLength || maxLength > 0);
this.controller = controller;

this.textCapitalization = textCapitalization;
this.style = style;
this.strutStyle = strutStyle;
this.textAlign = textAlign;
this.textDirection = textDirection;
this.autofocus = autofocus;

this.minLines = minLines;
this.expands = expands;
this.maxLength = maxLength;
this.maxLengthEnforced = maxLengthEnforced;
this.onChanged = onChanged;

this.scrollPadding = scrollPadding ?? EdgeInsets.all(20.0f);
this.dragStartBehavior = dragStartBehavior;
this.buildCounter = buildCounter;
this.scrollPhysics = scrollPhysics;
}
public readonly TextEditingController controller;

public readonly TextCapitalization textCapitalization;
public readonly TextStyle style;
public readonly StrutStyle strutStyle;
public readonly TextAlign textAlign;

public readonly bool autocorrect;
public readonly int? maxLines;
public readonly int? minLines;
public readonly bool expands;
public const long noMaxLength = -1;

public readonly bool? enableInteractiveSelection;
public readonly DragStartBehavior dragStartBehavior;
public readonly ScrollPhysics scrollPhysics;
public bool selectionEnabled {
get {

properties.add(new DiagnosticsProperty<bool>("obscureText", this.obscureText, defaultValue: false));
properties.add(new DiagnosticsProperty<bool>("autocorrect", this.autocorrect, defaultValue: true));
properties.add(new IntProperty("maxLines", this.maxLines, defaultValue: 1));
properties.add(new IntProperty("minLines", this.minLines, defaultValue: null));
properties.add(new DiagnosticsProperty<bool>("expands", this.expands, defaultValue: false));
properties.add(new IntProperty("maxLength", this.maxLength, defaultValue: null));
properties.add(new FlagProperty("maxLengthEnforced", value: this.maxLengthEnforced, defaultValue: true,
ifFalse: "maxLength not enforced"));

properties.add(new DiagnosticsProperty<Brightness?>("keyboardAppearance", this.keyboardAppearance, defaultValue: null));
properties.add(new DiagnosticsProperty<EdgeInsets>("scrollPadding", this.scrollPadding, defaultValue: EdgeInsets.all(20.0f)));
properties.add(new FlagProperty("selectionEnabled", value: this.selectionEnabled, defaultValue: true, ifFalse: "selection disabled"));
properties.add(new DiagnosticsProperty<ScrollPhysics>("scrollPhysics", this.scrollPhysics, defaultValue: null));
}
}

}
void _handleSelectionChanged(TextSelection selection, SelectionChangedCause cause) {
if (Theme.of(this.context).platform == RuntimePlatform.IPhonePlayer
&& cause == SelectionChangedCause.longPress) {
this._editableTextKey.currentState?.bringIntoView(selection.basePos);
switch (Theme.of(this.context).platform) {
case RuntimePlatform.IPhonePlayer:
if (cause == SelectionChangedCause.longPress) {
this._editableTextKey.currentState?.bringIntoView(selection.basePos);
}
return;
case RuntimePlatform.Android:
break;
}
}

this._cancelCurrentSplash();
}
void _handleLongPress() {
if (this.widget.enableInteractiveSelection == true) {
this._renderEditable.handleLongPress();
void _handleSingleLongTapStart(LongPressStartDetails details) {
if (this.widget.selectionEnabled) {
switch (Theme.of(this.context).platform) {
case RuntimePlatform.IPhonePlayer:
this._renderEditable.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress
);
break;
case RuntimePlatform.Android:
this._renderEditable.selectWord(cause: SelectionChangedCause.longPress);
Feedback.forLongPress(this.context);
break;
}
}
this._confirmCurrentSplash();
}
void _handleSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) {
if (this.widget.selectionEnabled) {
switch (Theme.of(this.context).platform) {
case RuntimePlatform.IPhonePlayer:
this._renderEditable.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress
);
break;
case RuntimePlatform.Android:
this._renderEditable.selectWordsInRange(
from: details.globalPosition - details.offsetFromOrigin,
to: details.globalPosition,
cause: SelectionChangedCause.longPress);
Feedback.forLongPress(this.context);
break;
}
}
this._confirmCurrentSplash();
void _handleSingleLongTapEnd(LongPressEndDetails details) {
this._editableTextKey.currentState.showToolbar();
void _handleDragSelectionStart(DragStartDetails details) {
void _handleDoubleTapDown(TapDownDetails details) {
if (this.widget.selectionEnabled) {
this._renderEditable.selectWord(cause: SelectionChangedCause.doubleTap);
this._editableTextKey.currentState.showToolbar();
}
}
void _handleMouseDragSelectionStart(DragStartDetails details) {
this._renderEditable.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.drag);

void _handleDragSelectionUpdate(DragStartDetails startDetails,
void _handleMouseDragSelectionUpdate(DragStartDetails startDetails,
DragUpdateDetails updateDetails) {
this._renderEditable.selectPositionAt(
from: startDetails.globalPosition,

textInputAction: this.widget.textInputAction,
textCapitalization: this.widget.textCapitalization,
style: style,
strutStyle: this.widget.strutStyle,
textAlign: this.widget.textAlign,
textDirection: this.widget.textDirection,
autofocus: this.widget.autofocus,

minLines: this.widget.minLines,
expands: this.widget.expands,
selectionColor: themeData.textSelectionColor,
selectionControls: this.widget.selectionEnabled ? textSelectionControls : null,
onChanged: this.widget.onChanged,

scrollPadding: this.widget.scrollPadding,
keyboardAppearance: keyboardAppearance,
enableInteractiveSelection: this.widget.enableInteractiveSelection == true,
dragStartBehavior: this.widget.dragStartBehavior
dragStartBehavior: this.widget.dragStartBehavior,
scrollPhysics: this.widget.scrollPhysics
)
);

textAlign: this.widget.textAlign,
isFocused: focusNode.hasFocus,
isEmpty: controller.value.text.isEmpty(),
expands: this.widget.expands,
child: _child
);
},

// onForcePressStart: forcePressEnabled ? this._handleForcePressStarted : null, // TODO: Remove this when force press is added
onSingleTapUp: this._handleSingleTapUp,
onSingleTapCancel: this._handleSingleTapCancel,
onSingleLongTapStart: this._handleLongPress,
onDragSelectionStart: this._handleDragSelectionStart,
onDragSelectionUpdate: this._handleDragSelectionUpdate,
onSingleLongTapStart: this._handleSingleLongTapStart,
onSingleLongTapMoveUpdate: this._handleSingleLongTapMoveUpdate,
onSingleLongTapEnd: this._handleSingleLongTapEnd,
onDoubleTapDown: this._handleDoubleTapDown,
onDragSelectionStart: this._handleMouseDragSelectionStart,
onDragSelectionUpdate: this._handleMouseDragSelectionUpdate,
behavior: HitTestBehavior.translucent,
child: child
)

14
Runtime/material/text_form_field.cs


TextCapitalization textCapitalization = TextCapitalization.none,
TextInputAction? textInputAction = null,
TextStyle style = null,
StrutStyle strutStyle = null,
TextDirection? textDirection = null,
TextAlign textAlign = TextAlign.left,
bool autofocus = false,

bool maxLengthEnforced = true,
int maxLines = 1,
int? maxLines = 1,
int? minLines = null,
bool expands = false,
int? maxLength = null,
VoidCallback onEditingComplete = null,
ValueChanged<string> onFieldSubmitted = null,

keyboardType: keyboardType,
textInputAction: textInputAction,
style: style,
strutStyle: strutStyle,
textAlign: textAlign,
textDirection: textDirection ?? TextDirection.ltr,
textCapitalization: textCapitalization,

maxLengthEnforced: maxLengthEnforced,
maxLines: maxLines,
minLines: minLines,
expands: expands,
maxLength: maxLength,
onChanged: field.didChange,
onEditingComplete: onEditingComplete,

) {
D.assert(initialValue == null || controller == null);
D.assert(maxLines > 0);
D.assert(maxLines == null || maxLines > 0);
D.assert(minLines == null || minLines > 0);
D.assert((maxLines == null) || (minLines == null) || (maxLines >= minLines),
() => "minLines can't be greater than maxLines");
D.assert(!expands || (maxLines == null && minLines == null),
() => "minLines and maxLines must be null when expands is true.");
D.assert(maxLength == null || maxLength > 0);
this.controller = controller;
}

2
Runtime/material/text_selection.cs


namespace Unity.UIWidgets.material {
public static class MaterialUtils {
public readonly static TextSelectionControls materialTextSelectionControls =
public static readonly TextSelectionControls materialTextSelectionControls =
new _MaterialTextSelectionControls();
internal const float _kHandleSize = 22.0f;

16
Runtime/material/theme_data.cs


BottomAppBarTheme bottomAppBarTheme = null,
ColorScheme colorScheme = null,
DialogTheme dialogTheme = null,
FloatingActionButtonThemeData floatingActionButtonTheme = null,
Typography typography = null
) {
brightness = brightness ?? Brightness.light;

labelStyle: textTheme.body2
);
dialogTheme = dialogTheme ?? new DialogTheme();
floatingActionButtonTheme = floatingActionButtonTheme ?? new FloatingActionButtonThemeData();
D.assert(brightness != null);
D.assert(primaryColor != null);

D.assert(cardTheme != null);
D.assert(chipTheme != null);
D.assert(dialogTheme != null);
D.assert(floatingActionButtonTheme != null);
this.brightness = brightness ?? Brightness.light;
this.primaryColor = primaryColor;

this.bottomAppBarTheme = bottomAppBarTheme;
this.colorScheme = colorScheme;
this.dialogTheme = dialogTheme;
this.floatingActionButtonTheme = floatingActionButtonTheme;
this.typography = typography;
}

BottomAppBarTheme bottomAppBarTheme = null,
ColorScheme colorScheme = null,
DialogTheme dialogTheme = null,
FloatingActionButtonThemeData floatingActionButtonTheme = null,
Typography typography = null
) {
D.assert(brightness != null);

D.assert(cardTheme != null);
D.assert(chipTheme != null);
D.assert(dialogTheme != null);
D.assert(floatingActionButtonTheme != null);
return new ThemeData(
brightness: brightness,

bottomAppBarTheme: bottomAppBarTheme,
colorScheme: colorScheme,
dialogTheme: dialogTheme,
floatingActionButtonTheme: floatingActionButtonTheme,
typography: typography);
}

public readonly ColorScheme colorScheme;
public readonly DialogTheme dialogTheme;
public readonly FloatingActionButtonThemeData floatingActionButtonTheme;
public readonly Typography typography;

BottomAppBarTheme bottomAppBarTheme = null,
ColorScheme colorScheme = null,
DialogTheme dialogTheme = null,
FloatingActionButtonThemeData floatingActionButtonTheme = null,
Typography typography = null
) {
return raw(

bottomAppBarTheme: bottomAppBarTheme ?? this.bottomAppBarTheme,
colorScheme: colorScheme ?? this.colorScheme,
dialogTheme: dialogTheme ?? this.dialogTheme,
floatingActionButtonTheme: floatingActionButtonTheme ?? this.floatingActionButtonTheme,
typography: typography ?? this.typography
);
}

bottomAppBarTheme: BottomAppBarTheme.lerp(a.bottomAppBarTheme, b.bottomAppBarTheme, t),
colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t),
dialogTheme: DialogTheme.lerp(a.dialogTheme, b.dialogTheme, t),
floatingActionButtonTheme: FloatingActionButtonThemeData.lerp(a.floatingActionButtonTheme, b.floatingActionButtonTheme, t),
typography: Typography.lerp(a.typography, b.typography, t)
);
}

other.bottomAppBarTheme == this.bottomAppBarTheme &&
other.colorScheme == this.colorScheme &&
other.dialogTheme == this.dialogTheme &&
other.floatingActionButtonTheme == this.floatingActionButtonTheme &&
other.typography == this.typography;
}

hashCode = (hashCode * 397) ^ this.bottomAppBarTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.colorScheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.dialogTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.floatingActionButtonTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.typography.GetHashCode();
this._cachedHashCode = hashCode;

defaultValue: defaultData.colorScheme));
properties.add(new DiagnosticsProperty<DialogTheme>("dialogTheme", this.dialogTheme,
defaultValue: defaultData.dialogTheme));
properties.add(new DiagnosticsProperty<FloatingActionButtonThemeData>("floatingActionButtonTheme",
this.floatingActionButtonTheme, defaultValue: defaultData.floatingActionButtonTheme));
properties.add(new DiagnosticsProperty<Typography>("typography", this.typography,
defaultValue: defaultData.typography));
}

7
Runtime/material/user_accounts_drawer_header.cs


public override void didUpdateWidget(StatefulWidget _oldWidget) {
base.didUpdateWidget(_oldWidget);
_AccountDetails oldWidget = _oldWidget as _AccountDetails;
if (this._animation.status == AnimationStatus.dismissed ||
this._animation.status == AnimationStatus.reverse) {
if (oldWidget.isOpen == this.widget.isOpen) {
return;
}
if(this.widget.isOpen ?? false) {
this._controller.forward();
}
else {

2
Runtime/material/floating_action_button_location.cs.meta


fileFormatVersion: 2
guid: cfa1c894caa2a46b19d419f6f53ae91f
guid: 6c8b71fe76d6bdb4ca66ecad56f25d3f
MonoImporter:
externalObjects: {}
serializedVersion: 2

2
Runtime/material/floating_action_button.cs.meta


fileFormatVersion: 2
guid: 274f3c1005cd046a28b169d8048c0292
guid: 44d53f5996891c54780cbc0073567bfd
MonoImporter:
externalObjects: {}
serializedVersion: 2

7
Runtime/painting/box_border.cs


this.left = left ?? BorderSide.none;
}
public static Border fromBorderSide(BorderSide side) {
D.assert(side != null);
return new Border(top: side, right: side, bottom: side, left: side);
}
public static Border all(
Color color = null,
float width = 1.0f,

return new Border(top: side, right: side, bottom: side, left: side);
return Border.fromBorderSide(side);
}
public static Border merge(Border a, Border b) {

26
Runtime/painting/decoration_image.cs


outputSize += sliceBorder;
destinationSize += sliceBorder;
D.assert(sourceSize == inputSize,
() => $"centerSlice was used with a BoxFit {fit} that does not guarantee that the image is fully visible.");
() =>
$"centerSlice was used with a BoxFit {fit} that does not guarantee that the image is fully visible.");
}
if (repeat != ImageRepeat.noRepeat && destinationSize == outputSize) {

Rect sourceRect = alignment.inscribe(
sourceSize, Offset.zero & inputSize
);
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) {
canvas.drawImageRect(image, sourceRect, tileRect, paint);
if (repeat == ImageRepeat.noRepeat) {
canvas.drawImageRect(image, sourceRect, destinationRect, paint);
}
else {
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) {
canvas.drawImageRect(image, sourceRect, tileRect, paint);
}
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) {
canvas.drawImageNine(image, centerSlice, tileRect, paint);
if (repeat == ImageRepeat.noRepeat) {
canvas.drawImageNine(image, centerSlice, destinationRect, paint);
}
else {
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) {
canvas.drawImageNine(image, centerSlice, tileRect, paint);
}
}
}

static IEnumerable<Rect> _generateImageTileRects(Rect outputRect, Rect fundamentalRect,
ImageRepeat repeat) {
if (repeat == ImageRepeat.noRepeat) {
yield return fundamentalRect;
yield break;
}
int startX = 0;
int startY = 0;
int stopX = 0;

98
Runtime/painting/gradient.cs


public readonly List<Color> colors;
public readonly List<float> stops;
public static _ColorsAndStops _interpolateColorsAndStops(
List<Color> aColors, List<float> aStops, List<Color> bColors, List<float> bStops, float t) {
D.assert(aColors.Count == bColors.Count,
() => "Cannot interpolate between two gradients with a different number of colors.");
D.assert((aStops == null && aColors.Count == 2) || (aStops != null && aStops.Count == aColors.Count));
D.assert((bStops == null && bColors.Count == 2) || (bStops != null && bStops.Count == bColors.Count));
List<Color> interpolatedColors = new List<Color>();
static Color _sample(List<Color> colors, List<float> stops, float t) {
D.assert(colors != null);
D.assert(colors.isNotEmpty);
D.assert(stops != null);
D.assert(stops.isNotEmpty);
if (t < stops.first()) {
return colors.first();
}
for (int i = 0; i < aColors.Count; i += 1) {
interpolatedColors.Add(Color.lerp(aColors[i], bColors[i], t));
if (t > stops.last()) {
return colors.last();
List<float> interpolatedStops = null;
if (aStops != null || bStops != null) {
aStops = aStops ?? new List<float> {0.0f, 1.0f};
bStops = bStops ?? new List<float> {0.0f, 1.0f};
int index = stops.FindLastIndex((float s) => { return s <= t; });
D.assert(index != -1);
return Color.lerp(colors[index], colors[index + 1],
(t - stops[index]) / (stops[index + 1] - stops[index]));
}
D.assert(aStops.Count == bStops.Count);
interpolatedStops = new List<float>();
for (int i = 0; i < aStops.Count; i += 1) {
interpolatedStops.Add(MathUtils.lerpFloat(aStops[i], bStops[i], t).clamp(0.0f, 1.0f));
}
}
internal static _ColorsAndStops _interpolateColorsAndStops(
List<Color> aColors,
List<float> aStops,
List<Color> bColors,
List<float> bStops,
float t) {
D.assert(aColors.Count >= 2);
D.assert(bColors.Count >= 2);
D.assert(aStops.Count == aColors.Count);
D.assert(bStops.Count == bColors.Count);
SplayTree<float, bool> stops = new SplayTree<float, bool>();
stops.AddAll(aStops);
stops.AddAll(bStops);
List<float> interpolatedStops = stops.Keys.ToList();
List<Color> interpolatedColors = interpolatedStops.Select<float, Color>((float stop) => {
return Color.lerp(_sample(aColors, aStops, stop), _sample(bColors, bStops, stop), t);
}).ToList();
return new _ColorsAndStops(interpolatedColors, interpolatedStops);
}

protected List<float> _impliedStops() {
if (this.stops != null) {
return this.stops;
}
if (this.colors.Count == 2) {
return null;
}
D.assert(this.colors.Count >= 2, () => "colors list must have at least two colors");

}
protected override Gradient lerpFrom(Gradient a, float t) {
if (a == null || (a is LinearGradient && a.colors.Count == this.colors.Count)) {
return LinearGradient.lerp((LinearGradient) a, this, t);
if (a == null || (a is LinearGradient)) {
return lerp((LinearGradient) a, this, t);
}
return base.lerpFrom(a, t);

if (b == null || (b is LinearGradient && b.colors.Count == this.colors.Count)) {
return LinearGradient.lerp(this, (LinearGradient) b, t);
if (b == null || (b is LinearGradient)) {
return lerp(this, (LinearGradient) b, t);
}
return base.lerpTo(b, t);

return (LinearGradient) a.scale(1.0f - t);
}
_ColorsAndStops interpolated =
_ColorsAndStops._interpolateColorsAndStops(a.colors, a.stops, b.colors, b.stops, t);
_ColorsAndStops interpolated = _ColorsAndStops._interpolateColorsAndStops(
a.colors,
a._impliedStops(),
b.colors,
b._impliedStops(),
t);
return new LinearGradient(
begin: Alignment.lerp(a.begin, b.begin, t),
end: Alignment.lerp(a.end, b.end, t),

return !Equals(left, right);
}
public override String ToString() {
public override string ToString() {
return $"{this.GetType()}({this.begin}, {this.end}," +
$"{this.colors.toStringList()}, {this.stops.toStringList()}, {this.tileMode})";
}

}
protected override Gradient lerpFrom(Gradient a, float t) {
if (a == null || (a is RadialGradient && a.colors.Count == this.colors.Count)) {
return RadialGradient.lerp((RadialGradient) a, this, t);
if (a == null || (a is RadialGradient)) {
return lerp((RadialGradient) a, this, t);
}
return base.lerpFrom(a, t);

if (b == null || (b is RadialGradient && b.colors.Count == this.colors.Count)) {
return RadialGradient.lerp(this, (RadialGradient) b, t);
if (b == null || (b is RadialGradient)) {
return lerp(this, (RadialGradient) b, t);
}
return base.lerpTo(b, t);

return (RadialGradient) a.scale(1.0f - t);
}
_ColorsAndStops interpolated =
_ColorsAndStops._interpolateColorsAndStops(a.colors, a.stops, b.colors, b.stops, t);
_ColorsAndStops interpolated = _ColorsAndStops._interpolateColorsAndStops(
a.colors,
a._impliedStops(),
b.colors,
b._impliedStops(),
t);
return new RadialGradient(
center: Alignment.lerp(a.center, b.center, t),
radius: Mathf.Max(0.0f, MathUtils.lerpFloat(a.radius, b.radius, t)),

return !Equals(left, right);
}
public override String ToString() {
public override string ToString() {
return $"{this.GetType()}({this.center}, {this.radius}," +
$"{this.colors.toStringList()}, {this.stops.toStringList()}, {this.tileMode})";
}

protected override Gradient lerpFrom(Gradient a, float t) {
if (a == null || (a is SweepGradient && a.colors.Count == this.colors.Count)) {
return SweepGradient.lerp((SweepGradient) a, this, t);
return lerp((SweepGradient) a, this, t);
}
return base.lerpFrom(a, t);

return !Equals(left, right);
}
public override String ToString() {
public override string ToString() {
return $"{this.GetType()}({this.center}, {this.startAngle}, {this.endAngle}, " +
$"{this.colors.toStringList()}, {this.stops.toStringList()}, {this.tileMode})";
}

26
Runtime/painting/image_stream.cs


new UIWidgetsErrorDetails(
exception: ex,
library: "image resource service",
context: "by a synchronously-called image error listener"
context: "when reporting an error to an image listener"
)
);
}

this._scale = scale;
this._informationCollector = informationCollector;
this._framesEmitted = 0;
this._timer = null;
codec.Then((Action<Codec>) this._handleCodecReady, ex => {
this.reportError(
context: "resolving an image codec",

FrameInfo _nextFrame;
TimeSpan? _shownTimestamp;
TimeSpan? _frameDuration;
int _framesEmitted;
int _framesEmitted = 0;
bool _frameCallbackScheduled = false;
this._decodeNextFrameAndSchedule();
if (this.hasListeners) {
this._decodeNextFrameAndSchedule();
}
this._frameCallbackScheduled = false;
if (!this.hasListeners) {
return;
}

TimeSpan delay = this._frameDuration.Value - (timestamp - this._shownTimestamp.Value);
delay = new TimeSpan((long) (delay.Ticks * SchedulerBinding.instance.timeDilation));
this._timer = Window.instance.run(delay,
() => { SchedulerBinding.instance.scheduleFrameCallback(this._handleAppFrame); });
this._timer = Window.instance.run(delay, this._scheduleAppFrame);
}
bool _isFirstFrame() {

return;
}
this._scheduleAppFrame();
}
void _scheduleAppFrame() {
if (this._frameCallbackScheduled) {
return;
}
this._frameCallbackScheduled = true;
SchedulerBinding.instance.scheduleFrameCallback(this._handleAppFrame);
}

20
Runtime/painting/notched_shapes.cs


return ret;
}
}
class AutomaticNotchedShape : NotchedShape {
public AutomaticNotchedShape(ShapeBorder host, ShapeBorder guest = null) {
this.host = host;
this.guest = guest;
}
public readonly ShapeBorder host;
public readonly ShapeBorder guest;
public override Path getOuterPath(Rect hostRect, Rect guestRect) {
Path hostPath = this.host.getOuterPath(hostRect);
if (this.guest != null && guestRect != null) {
Path guestPath = this.guest.getOuterPath(guestRect);
return Path.combine(PathOperation.difference, hostPath, guestPath);
}
return hostPath;
}
}
}

90
Runtime/painting/text_painter.cs


using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.painting {
class _CaretMetrics {
public _CaretMetrics(Offset offset, float? fullHeight) {
this.offset = offset;
this.fullHeight = fullHeight;
}
public Offset offset;
public float? fullHeight;
}
public class TextPainter {
TextSpan _text;
TextAlign _textAlign;

TextDirection textDirection = TextDirection.ltr,
float textScaleFactor = 1.0f,
int? maxLines = null,
string ellipsis = "") {
string ellipsis = "",
StrutStyle strutStyle = null) {
this._text = text;
this._textAlign = textAlign;
this._textDirection = textDirection;

this._strutStyle = strutStyle;
}
public float textScaleFactor {

}
}
public StrutStyle strutStyle {
get { return this._strutStyle; }
set {
if (this._strutStyle == value) {
return;
}
this._strutStyle = value;
this._paragraph = null;
this._needsLayout = true;
}
}
StrutStyle _strutStyle;
public float minIntrinsicWidth {
get {
Debug.Assert(!this._needsLayout);

}
public Offset getOffsetForCaret(TextPosition position, Rect caretPrototype) {
this._computeCaretMetrics(position, caretPrototype);
return this._caretMetrics.offset;
}
public float? getFullHeightForCaret(TextPosition position, Rect caretPrototype) {
this._computeCaretMetrics(position, caretPrototype);
return this._caretMetrics.fullHeight;
}
_CaretMetrics _caretMetrics;
TextPosition _previousCaretPosition;
Rect _previousCaretPrototype;
void _computeCaretMetrics(TextPosition position, Rect caretPrototype) {
var offset = position.offset;
if (offset > 0) {
var prevCodeUnit = this._text.codeUnitAt(offset);
if (prevCodeUnit == null) // out of upper bounds
{
var rectNextLineTop = this._paragraph.getNextLineStartRectTop();
if (rectNextLineTop != null) {
return new Offset(0, rectNextLineTop.Value);
}
}
if (position == this._previousCaretPosition && caretPrototype == this._previousCaretPrototype) {
return;
var offset = position.offset;
Rect rect;
return this._getOffsetFromUpstream(offset, caretPrototype) ??
this._getOffsetFromDownstream(offset, caretPrototype) ?? this._emptyOffset;
rect = this._getRectFromUpstream(offset, caretPrototype) ??
this._getRectFromDownStream(offset, caretPrototype);
break;
return this._getOffsetFromDownstream(offset, caretPrototype) ??
this._getOffsetFromUpstream(offset, caretPrototype) ?? this._emptyOffset;
rect = this._getRectFromDownStream(offset, caretPrototype) ??
this._getRectFromUpstream(offset, caretPrototype);
break;
default:
throw new UIWidgetsError("Unknown Position Affinity");
return null;
this._caretMetrics = new _CaretMetrics(
offset: rect != null ? new Offset(rect.left, rect.top) : this._emptyOffset,
fullHeight: rect != null ? (float?) (rect.bottom - rect.top) : null);
}
public Paragraph.LineRange getLineRange(int lineNumber) {

textAlign: this.textAlign,
textDirection: this.textDirection ?? defaultTextDirection,
maxLines: this.maxLines,
ellipsis: this.ellipsis
ellipsis: this.ellipsis,
strutStyle: this._strutStyle
);
}

const int _zwjUtf16 = 0x200d;
Offset _getOffsetFromUpstream(int offset, Rect caretPrototype) {
Rect _getRectFromUpstream(int offset, Rect caretPrototype) {
string flattenedText = this._text.toPlainText();
var prevCodeUnit = this._text.codeUnitAt(Mathf.Max(0, offset - 1));
if (prevCodeUnit == null) {

TextBox box = boxes[0];
const int NEWLINE_CODE_UNIT = 10;
if (prevCodeUnit == NEWLINE_CODE_UNIT) {
return new Offset(this._emptyOffset.dx, box.bottom);
return Rect.fromLTRB(this._emptyOffset.dx, box.bottom,
this._emptyOffset.dx, box.bottom + box.bottom - box.top);
return new Offset(dx, box.top);
return Rect.fromLTRB(Mathf.Min(dx, this.width), box.top,
Mathf.Min(dx, this.width), box.bottom);
Offset _getOffsetFromDownstream(int offset, Rect caretPrototype) {
Rect _getRectFromDownStream(int offset, Rect caretPrototype) {
string flattenedText = this._text.toPlainText();
var nextCodeUnit =
this._text.codeUnitAt(Mathf.Min(offset, flattenedText == null ? 0 : flattenedText.Length - 1));

TextBox box = boxes[boxes.Count - 1];
float caretStart = box.start;
float dx = box.direction == TextDirection.rtl ? caretStart - caretPrototype.width : caretStart;
return new Offset(dx, box.top);
return Rect.fromLTRB(Mathf.Min(dx, this.width), box.top,
Mathf.Min(dx, this.width), box.bottom);
}
return null;

192
Runtime/painting/text_style.cs


public static readonly float _defaultFontSize = 14.0f;
public readonly bool inherit;
public readonly Color color;
public readonly Color backgroundColor;
public readonly float? fontSize;
public readonly FontWeight fontWeight;
public readonly FontStyle? fontStyle;

public readonly TextDecoration decoration;
public readonly Color decorationColor;
public readonly TextDecorationStyle? decorationStyle;
public readonly float? decorationThickness;
public readonly Paint foreground;
public List<string> fontFamilyFallback {
get { return this._fontFamilyFallback; }
}
readonly List<string> _fontFamilyFallback;
const string _kColorForegroundWarning = "Cannot provide both a color and a foreground\n" +
"The color argument is just a shorthand for 'foreground: new Paint()..color = color'.";
public TextStyle(bool inherit = true, Color color = null, float? fontSize = null,
const string _kColorBackgroundWarning = "Cannot provide both a backgroundColor and a background\n" +
"The backgroundColor argument is just a shorthand for 'background: new Paint()..color = color'.";
public TextStyle(bool inherit = true,
Color color = null,
Color backgroundColor = null,
float? fontSize = null,
FontStyle? fontStyle = null, float? letterSpacing = null, float? wordSpacing = null,
TextBaseline? textBaseline = null, float? height = null, Paint background = null,
FontStyle? fontStyle = null,
float? letterSpacing = null,
float? wordSpacing = null,
TextBaseline? textBaseline = null,
float? height = null,
Paint foreground = null,
Paint background = null,
Color decorationColor = null, TextDecorationStyle? decorationStyle = null,
string fontFamily = null, string debugLabel = null) {
Color decorationColor = null,
TextDecorationStyle? decorationStyle = null,
float? decorationThickness = null,
string fontFamily = null,
List<string> fontFamilyFallback = null,
string debugLabel = null) {
D.assert(color == null || foreground == null, () => _kColorForegroundWarning);
D.assert(backgroundColor == null || background == null, () => _kColorBackgroundWarning);
this.backgroundColor = backgroundColor;
this.fontSize = fontSize;
this.fontWeight = fontWeight;
this.fontStyle = fontStyle;

this.decoration = decoration;
this.decorationColor = decorationColor;
this.decorationStyle = decorationStyle;
this.decorationThickness = decorationThickness;
this._fontFamilyFallback = fontFamilyFallback;
this.debugLabel = debugLabel;
this.background = background;
}

public TextStyle apply(
Color color = null,
Color backgroundColor = null,
float decorationThicknessFactor = 1.0f,
float decorationThicknessDelta = 0.0f,
List<string> fontFamilyFallback = null,
float fontSizeFactor = 1.0f,
float fontSizeDelta = 0.0f,
int fontWeightDelta = 0,

float heightFactor = 1.0f,
float heightDelta = 0.0f
) {
D.assert(this.fontSize != null || (fontSizeFactor == 1.0 && fontSizeDelta == 0.0));
D.assert(this.fontWeight != null || fontWeightDelta == 0.0);
D.assert(this.letterSpacing != null || (letterSpacingFactor == 1.0 && letterSpacingDelta == 0.0));
D.assert(this.wordSpacing != null || (wordSpacingFactor == 1.0 && wordSpacingDelta == 0.0));
D.assert(this.height != null || (heightFactor == 1.0 && heightDelta == 0.0));
D.assert(this.fontSize != null || (fontSizeFactor == 1.0f && fontSizeDelta == 0.0f));
D.assert(this.fontWeight != null || fontWeightDelta == 0.0f);
D.assert(this.letterSpacing != null || (letterSpacingFactor == 1.0f && letterSpacingDelta == 0.0f));
D.assert(this.wordSpacing != null || (wordSpacingFactor == 1.0f && wordSpacingDelta == 0.0f));
D.assert(this.height != null || (heightFactor == 1.0f && heightDelta == 0.0f));
D.assert(this.decorationThickness != null ||
(decorationThicknessFactor == 1.0f && decorationThicknessDelta == 0.0f));
string modifiedDebugLabel = "";
D.assert(() => {

return new TextStyle(
inherit: this.inherit,
color: color ?? this.color,
color: this.foreground == null ? color ?? this.color : null,
backgroundColor: this.background == null ? backgroundColor ?? this.backgroundColor : null,
fontFamilyFallback: fontFamilyFallback ?? this.fontFamilyFallback,
fontSize: this.fontSize == null ? null : this.fontSize * fontSizeFactor + fontSizeDelta,
fontWeight: this.fontWeight == null ? null : this.fontWeight,
fontStyle: this.fontStyle,

wordSpacing: this.wordSpacing == null ? null : this.wordSpacing * wordSpacingFactor + wordSpacingDelta,
textBaseline: this.textBaseline,
height: this.height == null ? null : this.height * heightFactor + heightDelta,
foreground: this.foreground,
decorationThickness: this.decorationThickness == null
? null
: this.decorationThickness * decorationThicknessFactor + decorationThicknessDelta,
debugLabel: modifiedDebugLabel
);
}

return this.copyWith(
color: other.color,
backgroundColor: other.backgroundColor,
fontFamilyFallback: other.fontFamilyFallback,
fontSize: other.fontSize,
fontWeight: other.fontWeight,
fontStyle: other.fontStyle,

height: other.height,
foreground: other.foreground,
background: other.background,
background: other.background,
decorationThickness: other.decorationThickness,
public TextStyle copyWith(Color color = null,
public TextStyle copyWith(
bool? inherit = null,
Color color = null,
Color backgroundColor = null,
List<string> fontFamilyFallback = null,
float? fontSize = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,

float? height = null,
Paint foreground = null,
float? decorationThickness = null,
D.assert(color == null || foreground == null, () => _kColorForegroundWarning);
D.assert(backgroundColor == null || background == null, () => _kColorBackgroundWarning);
string newDebugLabel = null;
D.assert(() => {
if (this.debugLabel != null) {

});
return new TextStyle(
inherit: this.inherit,
color: color ?? this.color,
inherit: inherit ?? this.inherit,
color: this.foreground == null && foreground == null ? color ?? this.color : null,
backgroundColor: this.background == null && background == null ? color ?? this.color : null,
fontFamilyFallback: fontFamilyFallback ?? this.fontFamilyFallback,
fontSize: fontSize ?? this.fontSize,
fontWeight: fontWeight ?? this.fontWeight,
fontStyle: fontStyle ?? this.fontStyle,

decoration: decoration ?? this.decoration,
decorationColor: decorationColor ?? this.decorationColor,
decorationStyle: decorationStyle ?? this.decorationStyle,
decorationThickness: decorationThickness ?? this.decorationThickness,
background: background ?? this.background,
debugLabel: newDebugLabel
);

return new TextStyle(
inherit: b.inherit,
color: Color.lerp(null, b.color, t),
fontFamily: t < 0.5 ? null : b.fontFamily,
fontSize: t < 0.5 ? null : b.fontSize,
fontWeight: t < 0.5 ? null : b.fontWeight,
fontStyle: t < 0.5 ? null : b.fontStyle,
letterSpacing: t < 0.5 ? null : b.letterSpacing,
wordSpacing: t < 0.5 ? null : b.wordSpacing,
textBaseline: t < 0.5 ? null : b.textBaseline,
height: t < 0.5 ? null : b.height,
background: t < 0.5 ? null : b.background,
decoration: t < 0.5 ? null : b.decoration,
backgroundColor: Color.lerp(null, b.backgroundColor, t),
fontFamily: t < 0.5f ? null : b.fontFamily,
fontFamilyFallback: t < 0.5f ? null : b.fontFamilyFallback,
fontSize: t < 0.5f ? null : b.fontSize,
fontWeight: t < 0.5f ? null : b.fontWeight,
fontStyle: t < 0.5f ? null : b.fontStyle,
letterSpacing: t < 0.5f ? null : b.letterSpacing,
wordSpacing: t < 0.5f ? null : b.wordSpacing,
textBaseline: t < 0.5f ? null : b.textBaseline,
height: t < 0.5f ? null : b.height,
foreground: t < 0.5f ? null : b.foreground,
background: t < 0.5f ? null : b.background,
decoration: t < 0.5f ? null : b.decoration,
decorationStyle: t < 0.5 ? null : b.decorationStyle,
decorationStyle: t < 0.5f ? null : b.decorationStyle,
decorationThickness: t < 0.5f ? null : b.decorationThickness,
debugLabel: lerpDebugLabel
);
}

inherit: a.inherit,
color: Color.lerp(a.color, null, t),
fontFamily: t < 0.5 ? a.fontFamily : null,
fontSize: t < 0.5 ? a.fontSize : null,
fontWeight: t < 0.5 ? a.fontWeight : null,
fontStyle: t < 0.5 ? a.fontStyle : null,
letterSpacing: t < 0.5 ? a.letterSpacing : null,
wordSpacing: t < 0.5 ? a.wordSpacing : null,
textBaseline: t < 0.5 ? a.textBaseline : null,
height: t < 0.5 ? a.height : null,
background: t < 0.5 ? a.background : null,
decoration: t < 0.5 ? a.decoration : null,
backgroundColor: Color.lerp(a.backgroundColor, null, t),
fontFamily: t < 0.5f ? a.fontFamily : null,
fontFamilyFallback: t < 0.5f ? a.fontFamilyFallback : null,
fontSize: t < 0.5f ? a.fontSize : null,
fontWeight: t < 0.5f ? a.fontWeight : null,
fontStyle: t < 0.5f ? a.fontStyle : null,
letterSpacing: t < 0.5f ? a.letterSpacing : null,
wordSpacing: t < 0.5f ? a.wordSpacing : null,
textBaseline: t < 0.5f ? a.textBaseline : null,
height: t < 0.5f ? a.height : null,
foreground: t < 0.5f ? a.foreground : null,
background: t < 0.5f ? a.background : null,
decoration: t < 0.5f ? a.decoration : null,
decorationStyle: t < 0.5 ? a.decorationStyle : null,
decorationStyle: t < 0.5f ? a.decorationStyle : null,
decorationThickness: t < 0.5f ? a.decorationThickness : null,
debugLabel: lerpDebugLabel
);
}

color: Color.lerp(a.color, b.color, t),
color: a.foreground == null && b.foreground == null ? Color.lerp(a.color, b.color, t) : null,
backgroundColor: a.background == null && b.background == null
? Color.lerp(a.backgroundColor, b.backgroundColor, t)
: null,
fontFamilyFallback: t < 0.5 ? a.fontFamilyFallback : b.fontFamilyFallback,
fontSize: MathUtils.lerpNullableFloat(a.fontSize ?? b.fontSize, b.fontSize ?? a.fontSize, t),
fontWeight: t < 0.5 ? a.fontWeight : b.fontWeight,
fontStyle: t < 0.5 ? a.fontStyle : b.fontStyle,

b.wordSpacing ?? a.wordSpacing, t),
textBaseline: t < 0.5 ? a.textBaseline : b.textBaseline,
height: MathUtils.lerpNullableFloat(a.height ?? b.height, b.height ?? a.height, t),
background: t < 0.5 ? a.background : b.background,
foreground: (a.foreground != null || b.foreground != null)
? t < 0.5
? a.foreground ?? new Paint() {color = a.color}
: b.foreground ?? new Paint() {color = b.color}
: null,
background: (a.background != null || b.background != null)
? t < 0.5
? a.background ?? new Paint() {color = a.backgroundColor}
: b.background ?? new Paint() {color = b.backgroundColor}
: null,
decorationThickness: MathUtils.lerpFloat(
a.decorationThickness ?? b.decorationThickness ?? 0.0f,
b.decorationThickness ?? a.decorationThickness ?? 0.0f, t),
debugLabel: lerpDebugLabel
);
}

List<DiagnosticsNode> styles = new List<DiagnosticsNode>();
styles.Add(new DiagnosticsProperty<Color>("color", this.color,
defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new DiagnosticsProperty<Color>("backgroundColor", this.backgroundColor,
styles.Add(new EnumerableProperty<string>("familyFallback", this.fontFamilyFallback,
defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new DiagnosticsProperty<float?>("size", this.fontSize,
defaultValue: Diagnostics.kNullDefaultValue));
string weightDescription = "";

defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new DiagnosticsProperty<float?>("height", this.height,
defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new StringProperty("foreground", this.foreground == null ? null : this.foreground.ToString(),
defaultValue: Diagnostics.kNullDefaultValue, quoted: false));
styles.Add(new StringProperty("background", this.background == null ? null : this.background.ToString(),
defaultValue: Diagnostics.kNullDefaultValue, quoted: false));
if (this.decoration != null) {

D.assert(decorationDescription.isNotEmpty);
styles.Add(new MessageProperty("decoration", string.Join(" ", decorationDescription.ToArray())));
styles.Add(new FloatProperty("decorationThickness", this.decorationThickness, unit: "x",
defaultValue: Diagnostics.kNoDefaultValue));
}
bool styleSpecified = styles.Any((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info));

return true;
}
return this.inherit == other.inherit && Equals(this.color, other.color) &&
this.fontSize.Equals(other.fontSize) && this.fontWeight == other.fontWeight &&
this.fontStyle == other.fontStyle && this.letterSpacing.Equals(other.letterSpacing) &&
this.wordSpacing.Equals(other.wordSpacing) && this.textBaseline == other.textBaseline &&
return this.inherit == other.inherit &&
Equals(this.color, other.color) &&
Equals(this.backgroundColor, other.backgroundColor) &&
this.fontSize.Equals(other.fontSize) &&
this.fontWeight == other.fontWeight &&
this.fontStyle == other.fontStyle &&
this.letterSpacing.Equals(other.letterSpacing) &&
this.wordSpacing.Equals(other.wordSpacing) &&
this.textBaseline == other.textBaseline &&
this.decorationStyle == other.decorationStyle && Equals(this.background, other.background) &&
this.decorationStyle == other.decorationStyle &&
this.decorationThickness == other.decorationThickness &&
Equals(this.foreground, other.foreground) &&
Equals(this.background, other.background) &&
CollectionUtils.equalsList(this.fontFamilyFallback, other.fontFamilyFallback) &&
string.Equals(this.fontFamily, other.fontFamily);
}

unchecked {
var hashCode = this.inherit.GetHashCode();
hashCode = (hashCode * 397) ^ (this.color != null ? this.color.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.backgroundColor != null ? this.backgroundColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.fontSize.GetHashCode();
hashCode = (hashCode * 397) ^ (this.fontWeight != null ? this.fontWeight.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.fontStyle.GetHashCode();

hashCode = (hashCode * 397) ^ (this.decoration != null ? this.decoration.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.decorationColor != null ? this.decorationColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.decorationStyle.GetHashCode();
hashCode = (hashCode * 397) ^ this.decorationThickness.GetHashCode();
hashCode = (hashCode * 397) ^ (this.foreground != null ? this.foreground.GetHashCode() : 0);
hashCode = (hashCode * 397) ^
(this.fontFamilyFallback != null ? this.fontFamilyFallback.GetHashCode() : 0);
return hashCode;
}
}

1
Runtime/rendering/binding.cs


Window.instance.onMetricsChanged += this.handleMetricsChanged;
Window.instance.onTextScaleFactorChanged += this.handleTextScaleFactorChanged;
Window.instance.onPlatformBrightnessChanged += this.handlePlatformBrightnessChanged;
this.initRenderView();
D.assert(this.renderView != null);
this.addPersistentFrameCallback(this._handlePersistentFrameCallback);

6
Runtime/rendering/box.cs


this.computeMaxIntrinsicHeight);
}
protected virtual float computeMaxIntrinsicHeight(float width) {
protected internal virtual float computeMaxIntrinsicHeight(float width) {
return 0.0f;
}

if (this.constraints.hasBoundedWidth) {
testIntrinsicsForValues(this.getMinIntrinsicWidth, this.getMaxIntrinsicWidth, "Width",
this.constraints.maxWidth);
this.constraints.maxHeight);
this.constraints.maxHeight);
this.constraints.maxWidth);
}
debugCheckingIntrinsics = false;

2
Runtime/rendering/custom_layout.cs


return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
float height = this._getSize(BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite()) {
return height;

131
Runtime/rendering/editable.cs


using System.Collections.Generic;
using System.Xml.Schema;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;

TextPainter _textPainter;
Color _cursorColor;
int? _maxLines;
int? _minLines;
bool _expands;
Color _selectionColor;
ViewportOffset _offset;
ValueNotifier<bool> _showCursor;

Color backgroundCursorColor = null,
bool? hasFocus = null,
int? maxLines = 1,
int? minLines = null,
bool expands = false,
StrutStyle strutStyle = null,
Color selectionColor = null,
TextSelection selection = null,
bool obscureText = false,

float cursorWidth = 1.0f,
Radius cursorRadius = null,
bool? enableInteractiveSelection = null,
bool? enableInteractiveSelection = null,
D.assert(minLines == null || minLines > 0);
D.assert((minLines == null) || maxLines >= minLines, () => "minLines can't be greater than maxLines");
textScaleFactor: textScaleFactor);
textScaleFactor: textScaleFactor, strutStyle: strutStyle);
this._minLines = minLines;
this._expands = expands;
this._selectionColor = selectionColor;
this._selection = selection;
this._obscureText = obscureText;

public TextSelectionDelegate textSelectionDelegate;
public ValueListenable<bool> selectionStartInViewport {
get { return this._selectionStartInViewport; }
}
readonly ValueNotifier<bool> _selectionStartInViewport = new ValueNotifier<bool>(true);
public ValueListenable<bool> selectionEndInViewport {
get { return this._selectionEndInViewport; }
}
readonly ValueNotifier<bool> _selectionEndInViewport = new ValueNotifier<bool>(true);
void _updateSelectionExtentsVisibility(Offset effectiveOffset) {
Rect visibleRegion = Offset.zero & this.size;
Offset startOffset = this._textPainter.getOffsetForCaret(
new TextPosition(offset: this._selection.start, affinity: this._selection.affinity),
Rect.zero
);
float visibleRegionSlop = 0.5f;
this._selectionStartInViewport.value = visibleRegion
.inflate(visibleRegionSlop)
.contains(startOffset + effectiveOffset);
Offset endOffset = this._textPainter.getOffsetForCaret(
new TextPosition(offset: this._selection.end, affinity: this._selection.affinity),
Rect.zero
);
this._selectionEndInViewport.value = visibleRegion
.inflate(visibleRegionSlop)
.contains(endOffset + effectiveOffset);
}
int _extentOffset = -1;
int _baseOffset = -1;

}
}
public StrutStyle strutStyle {
get { return this._textPainter.strutStyle; }
set {
if (this._textPainter.strutStyle == value) {
return;
}
this._textPainter.strutStyle = value;
this.markNeedsTextLayout();
}
}
public Color cursorColor {
get { return this._cursorColor; }
set {

}
}
bool _hasFocus;
bool _hasFocus = false;
bool _listenerAttached = false;
public bool hasFocus {

}
}
public int? minLines {
get { return this._minLines; }
set {
D.assert(value == null || value > 0);
if (this._minLines == value) {
return;
}
this._minLines = value;
this.markNeedsTextLayout();
}
}
public bool expands {
get { return this._expands; }
set {
if (this.expands == value) {
return;
}
this._expands = value;
this.markNeedsTextLayout();
}
}
public Color selectionColor {
get { return this._selectionColor; }
set {

return this._preferredHeight(width);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this._preferredHeight(width);
}

}
public void handleTapDown(TapDownDetails details) {
this._lastTapDownPosition = details.globalPosition - this._paintOffset;
this._lastTapDownPosition = details.globalPosition;
if (!Application.isMobilePlatform) {
this.selectPosition(SelectionChangedCause.tap);
}

this.selectWordsInRange(from: this._lastTapDownPosition, cause: cause);
}
void selectWordsInRange(Offset from = null, Offset to = null, SelectionChangedCause? cause = null) {
public void selectWordsInRange(Offset from = null, Offset to = null, SelectionChangedCause? cause = null) {
D.assert(cause != null);
D.assert(from != null);
this._layoutText(this.constraints.maxWidth);

D.assert(this._lastTapDownPosition != null);
if (this.onSelectionChanged != null) {
TextPosition position =
this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition));
this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition - this._paintOffset));
TextRange word = this._textPainter.getWordBoundary(position);
if (position.offset - word.start <= 1) {
this.onSelectionChanged(

void _paintCaret(Canvas canvas, Offset effectiveOffset, TextPosition textPosition) {
D.assert(this._textLayoutLastWidth == this.constraints.maxWidth);
var caretOffset = this._textPainter.getOffsetForCaret(textPosition, this._caretPrototype);
Rect caretRect = this._caretPrototype.shift(caretOffset + effectiveOffset);
var caretOffset = this._textPainter.getOffsetForCaret(textPosition, this._caretPrototype) + effectiveOffset;
Rect caretRect = this._caretPrototype.shift(caretOffset);
#if !UNITY_IOS
if (this._textPainter.getFullHeightForCaret(textPosition, this._caretPrototype) != null) {
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top - _kCaretHeightOffset,
caretRect.width,
this._textPainter.getFullHeightForCaret(textPosition, this._caretPrototype).Value
);
}
#endif
caretRect = caretRect.shift(this._getPixelPerfectCursorOffset(caretRect));
if (this.cursorRadius == null) {
canvas.drawRect(caretRect, paint);

}
float _preferredHeight(float width) {
if (this.maxLines != null) {
bool lockedMax = this.maxLines != null && this.minLines == null;
bool lockedBoth = this.maxLines != null && this.minLines == this.maxLines;
bool singleLine = this.maxLines == 1;
if (singleLine || lockedMax || lockedBoth) {
}
bool minLimited = this.minLines != null && this.minLines > 1;
bool maxLimited = this.maxLines != null;
if (minLimited || maxLimited) {
this._layoutText(width);
if (minLimited && this._textPainter.height < this.preferredLineHeight * this.minLines.Value) {
return this.preferredLineHeight * this.minLines.Value;
}
if (maxLimited && this._textPainter.height > this.preferredLineHeight * this.maxLines.Value) {
return this.preferredLineHeight * this.maxLines.Value;
}
}
if (!width.isFinite()) {

properties.add(new DiagnosticsProperty<Color>("cursorColor", this.cursorColor));
properties.add(new DiagnosticsProperty<ValueNotifier<bool>>("showCursor", this.showCursor));
properties.add(new DiagnosticsProperty<int?>("maxLines", this.maxLines));
properties.add(new DiagnosticsProperty<int?>("minLines", this.minLines));
properties.add(new DiagnosticsProperty<bool>("expands", this.expands));
properties.add(new DiagnosticsProperty<Color>("selectionColor", this.selectionColor));
properties.add(new DiagnosticsProperty<float>("textScaleFactor", this.textScaleFactor));
properties.add(new DiagnosticsProperty<TextSelection>("selection", this.selection));

2
Runtime/rendering/error.cs


);
static ParagraphStyle paragraphStyle = new ParagraphStyle(
lineHeight: 1.0f
height: 1.0f
);
}
}

7
Runtime/rendering/flex.cs


);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this._getIntrinsicSize(
sizingDirection: Axis.vertical,
extent: width,

if (totalFlex > 0 || this.crossAxisAlignment == CrossAxisAlignment.baseline) {
float spacePerFlex = canFlex && totalFlex > 0 ? (freeSpace / totalFlex) : float.NaN;
child = this.firstChild;
float maxSizeAboveBaseline = 0;
float maxSizeBelowBaseline = 0;
while (child != null) {
int flex = this._getFlex(child);
if (flex > 0) {

float? distance = child.getDistanceToBaseline(this.textBaseline, onlyReal: true);
if (distance != null) {
maxBaselineDistance = Mathf.Max(maxBaselineDistance, distance.Value);
maxSizeAboveBaseline = Mathf.Max(distance.Value, maxSizeAboveBaseline);
maxSizeBelowBaseline = Mathf.Max(child.size.height - distance.Value, maxSizeBelowBaseline);
crossSize = maxSizeAboveBaseline + maxSizeBelowBaseline;
}
}

2
Runtime/rendering/image.cs


return this._sizeForConstraints(BoxConstraints.tightForFinite(width: width)).height;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
D.assert(width >= 0.0);
return this._sizeForConstraints(BoxConstraints.tightForFinite(width: width)).height;
}

164
Runtime/rendering/layer.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.external.simplejson;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;

public Layer lastChild {
get { return this._lastChild; }
}
internal override S find<S>(Offset regionOffset) {
Layer current = this.lastChild;
while (current != null) {

return child == equals;
}
PictureLayer _highlightConflictingLayer(PhysicalModelLayer child) {
PictureRecorder recorder = new PictureRecorder();
var canvas = new RecorderCanvas(recorder);
canvas.drawPath(child.clipPath, new Paint() {
color = new Color(0xFFAA0000),
style = PaintingStyle.stroke,
strokeWidth = child.elevation + 10.0f,
});
PictureLayer pictureLayer = new PictureLayer(child.clipPath.getBounds());
pictureLayer.picture = recorder.endRecording();
pictureLayer.debugCreator = child;
child.append(pictureLayer);
return pictureLayer;
}
List<PictureLayer> _processConflictingPhysicalLayers(PhysicalModelLayer predecessor, PhysicalModelLayer child) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: new UIWidgetsError("Painting order is out of order with respect to elevation.\n" +
"See https://api.flutter.dev/flutter/rendering/debugCheckElevations.html " +
"for more details."),
context: "during compositing",
informationCollector: (StringBuilder builder) => {
builder.AppendLine("Attempted to composite layer");
builder.AppendLine(child.ToString());
builder.AppendLine("after layer");
builder.AppendLine(predecessor.ToString());
builder.AppendLine("which occupies the same area at a higher elevation.");
}
));
return new List<PictureLayer> {
this._highlightConflictingLayer(predecessor),
this._highlightConflictingLayer(child)
};
}
protected List<PictureLayer> _debugCheckElevations() {
List<PhysicalModelLayer> physicalModelLayers =
this.depthFirstIterateChildren().OfType<PhysicalModelLayer>().ToList();
List<PictureLayer> addedLayers = new List<PictureLayer>();
for (int i = 0; i < physicalModelLayers.Count; i++) {
PhysicalModelLayer physicalModelLayer = physicalModelLayers[i];
D.assert(physicalModelLayer.lastChild?.debugCreator != physicalModelLayer,
() => "debugCheckElevations has either already visited this layer or failed to remove the" +
" added picture from it.");
float accumulatedElevation = physicalModelLayer.elevation;
Layer ancestor = physicalModelLayer.parent;
while (ancestor != null) {
if (ancestor is PhysicalModelLayer modelLayer) {
accumulatedElevation += modelLayer.elevation;
}
ancestor = ancestor.parent;
}
for (int j = 0; j <= i; j++) {
PhysicalModelLayer predecessor = physicalModelLayers[j];
float predecessorAccumulatedElevation = predecessor.elevation;
ancestor = predecessor.parent;
while (ancestor != null) {
if (ancestor == predecessor) {
continue;
}
if (ancestor is PhysicalModelLayer modelLayer) {
predecessorAccumulatedElevation += modelLayer.elevation;
}
ancestor = ancestor.parent;
}
if (predecessorAccumulatedElevation <= accumulatedElevation) {
continue;
}
Path intersection = Path.combine(
PathOperation.intersect,
predecessor._debugTransformedClipPath,
physicalModelLayer._debugTransformedClipPath);
if (intersection != null && intersection.computeMetrics().Any((metric) => metric.length > 0)) {
addedLayers.AddRange(this._processConflictingPhysicalLayers(predecessor, physicalModelLayer));
}
}
}
return addedLayers;
}
internal override void updateSubtreeNeedsAddToScene() {
base.updateSubtreeNeedsAddToScene();
Layer child = this.firstChild;

D.assert(transform != null);
}
public List<Layer> depthFirstIterateChildren() {
if (this.firstChild == null) {
return new List<Layer>();
}
List<Layer> children = new List<Layer>();
Layer child = this.firstChild;
while (child != null) {
children.Add(child);
if (child is ContainerLayer containerLayer) {
children.AddRange(containerLayer.depthFirstIterateChildren());
}
child = child.nextSibling;
}
return children;
}
public override List<DiagnosticsNode> debugDescribeChildren() {
var children = new List<DiagnosticsNode>();
if (this.firstChild == null) {

}
public Scene buildScene(SceneBuilder builder) {
List<PictureLayer> temporaryLayers = null;
D.assert(() => {
if (RenderingDebugUtils.debugCheckElevationsEnabled) {
temporaryLayers = this._debugCheckElevations();
}
return true;
});
return builder.build();
Scene scene = builder.build();
D.assert(() => {
if (temporaryLayers != null) {
foreach (PictureLayer temporaryLayer in temporaryLayers) {
temporaryLayer.remove();
}
}
return true;
});
return scene;
}
internal override flow.Layer addToScene(SceneBuilder builder, Offset layerOffset = null) {

if (this._invertedTransform == null) {
return null;
}
Offset transform = this._invertedTransform.mapXY(regionOffset.dx, regionOffset.dy);
return base.find<S>(transform);
}

public override void applyTransform(Layer child, Matrix3 transform) {
D.assert(child != null);
D.assert(transform != null);
transform.preConcat(this._lastEffectiveTransform);
D.assert(this._lastEffectiveTransform != null || this.transform != null);
if (this._lastEffectiveTransform == null) {
transform.preConcat(this.transform);
}
else {
transform.preConcat(this._lastEffectiveTransform);
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {

properties.add(new DiagnosticsProperty<Offset>("offset", this.offset));
}
}
public class BackdropFilterLayer : ContainerLayer {
public BackdropFilterLayer(ImageFilter filter = null) {
D.assert(filter != null);

protected override bool alwaysNeedsAddToScene {
get { return true; }
}
internal override flow.Layer addToScene(SceneBuilder builder, Offset layerOffset = null) {
layerOffset = layerOffset ?? Offset.zero;

}
}
}
internal Path _debugTransformedClipPath {
get {
ContainerLayer ancestor = this.parent;
Matrix3 matrix = Matrix3.I();
while (ancestor != null && ancestor.parent != null) {
ancestor.applyTransform(this, matrix);
ancestor = ancestor.parent;
}
return this.clipPath.transform(matrix);
}
}
Clip _clipBehavior;

2
Runtime/rendering/list_body.cs


}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
switch (this.mainAxis) {
case Axis.horizontal:
return this._getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));

9
Runtime/rendering/object.cs


using Unity.UIWidgets.ui;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.rendering {

Paint paint = new Paint {
style = PaintingStyle.stroke,
strokeWidth = 1.0f,
color = new ui.Color(0xFFFF9800),
color = new Color(0xFFFF9800),
};
this.canvas.drawRect(this.estimatedBounds, paint);
}

Matrix3 effectiveTransform;
if (offset == null || offset == Offset.zero) {
effectiveTransform = transform;
} else {
}
else {
effectiveTransform = Matrix3.makeTrans(offset.dx, offset.dy);
effectiveTransform.preConcat(transform);
effectiveTransform.preTranslate(-offset.dx, -offset.dy);

var inverse = Matrix3.I();
var invertible = effectiveTransform.invert(inverse);
// it could just be "scale == 0", ignore the assertion.
// D.assert(invertible);

}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<object>(
"creator", this.debugCreator, defaultValue: Diagnostics.kNullDefaultValue,
level: DiagnosticLevel.debug));

47
Runtime/rendering/paragraph.cs


/// Use an ellipsis to indicate that the text has overflowed.
ellipsis,
/// Render overflowing text outside of its container.
visible,
}

TextOverflow _overflow;
readonly TextPainter _textPainter;
bool _hasVisualOverflow = false;
bool _needsClipping = false;
List<TextBox> _selectionRects;

TextOverflow overflow = TextOverflow.clip,
float textScaleFactor = 1.0f,
int? maxLines = null,
StrutStyle strutStyle = null,
Action onSelectionChanged = null,
Color selectionColor = null
) {

textDirection,
textScaleFactor,
maxLines,
overflow == TextOverflow.ellipsis ? _kEllipsis : ""
overflow == TextOverflow.ellipsis ? _kEllipsis : "",
strutStyle: strutStyle
);
this._selection = null;

return this._computeIntrinsicHeight(width);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this._computeIntrinsicHeight(width);
}

protected override void performLayout() {
this._layoutTextWithConstraints(this.constraints);
var textSize = this._textPainter.size;
var didOverflowHeight = this._textPainter.didExceedMaxLines;
var textDidExceedMaxLines = this._textPainter.didExceedMaxLines;
var didOverflowHeight = this.size.height < textSize.height || textDidExceedMaxLines;
this._hasVisualOverflow = didOverflowWidth || didOverflowHeight;
var hasVisualOverflow = didOverflowWidth || didOverflowHeight;
if (hasVisualOverflow) {
switch (this._overflow) {
case TextOverflow.visible:
this._needsClipping = false;
break;
case TextOverflow.clip:
case TextOverflow.ellipsis:
case TextOverflow.fade:
this._needsClipping = true;
break;
}
}
else {
this._needsClipping = false;
}
this._selectionRects = null;
}

this._layoutTextWithConstraints(this.constraints);
var canvas = context.canvas;
if (this._hasVisualOverflow) {
if (this._needsClipping) {
var bounds = offset & this.size;
canvas.save();
canvas.clipRect(bounds);

}
this._textPainter.paint(canvas, offset);
if (this._hasVisualOverflow) {
if (this._needsClipping) {
canvas.restore();
}
}

}
canvas.drawPath(barPath, paint);
}
public StrutStyle strutStyle {
get { return this._textPainter.strutStyle; }
set {
if (this._textPainter.strutStyle == value) {
return;
}
this._textPainter.strutStyle = value;
this.markNeedsLayout();
}
}
void _layoutText(float minWidth = 0.0f, float maxWidth = float.PositiveInfinity) {

2
Runtime/rendering/performance_overlay.cs


return this._intrinsicHeight;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this._intrinsicHeight;
}

112
Runtime/rendering/proxy_box.cs


return height;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this._additionalConstraints.hasBoundedHeight && this._additionalConstraints.hasTightHeight) {
return this._additionalConstraints.minHeight;
}

return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (width.isFinite()) {
return width / this._aspectRatio;
}

return _applyStep(height, this._stepHeight);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this.child == null) {
return 0.0f;
}

Color _color;
protected static Paint _transparentPaint {
get { return new Paint {color = new Color(0x00000000)}; }
}
get { return this._elevation != 0.0; }
get { return true; }
}
public override void debugFillProperties(DiagnosticPropertiesBuilder description) {

Path offsetRRectAsPath = new Path();
offsetRRectAsPath.addRRect(offsetRRect);
if (this.needsCompositing) {
PhysicalModelLayer physicalModel = new PhysicalModelLayer(
clipPath: offsetRRectAsPath,
clipBehavior: this.clipBehavior,
elevation: this.elevation,
color: this.color,
shadowColor: this.shadowColor);
context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds);
}
else {
Canvas canvas = context.canvas;
if (this.elevation != 0.0) {
canvas.drawRect(
offsetBounds.inflate(20.0f),
_transparentPaint
);
canvas.drawShadow(
offsetRRectAsPath,
this.shadowColor,
this.elevation,
this.color.alpha != 0xFF
);
}
Paint paint = new Paint {color = this.color};
canvas.drawRRect(offsetRRect, paint);
context.clipRRectAndPaint(offsetRRect, this.clipBehavior, offsetBounds,
() => base.paint(context, offset));
D.assert(context.canvas == canvas, () => "canvas changed even though needsCompositing was false");
}
PhysicalModelLayer physicalModel = new PhysicalModelLayer(
clipPath: offsetRRectAsPath,
clipBehavior: this.clipBehavior,
elevation: this.elevation,
color: this.color,
shadowColor: this.shadowColor);
D.assert(() => {
physicalModel.debugCreator = this.debugCreator;
return true;
});
context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds);
}
}

Path offsetPath = new Path();
offsetPath.addPath(this._clip, offset);
if (this.needsCompositing) {
PhysicalModelLayer physicalModel = new PhysicalModelLayer(
clipPath: offsetPath,
clipBehavior: this.clipBehavior,
elevation: this.elevation,
color: this.color,
shadowColor: this.shadowColor);
context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds);
}
else {
Canvas canvas = context.canvas;
if (this.elevation != 0.0) {
canvas.drawRect(
offsetBounds.inflate(20.0f),
_transparentPaint
);
canvas.drawShadow(
offsetPath,
this.shadowColor,
this.elevation,
this.color.alpha != 0xFF
);
}
Paint paint = new Paint {color = this.color, style = PaintingStyle.fill};
canvas.drawPath(offsetPath, paint);
context.clipPathAndPaint(offsetPath, this.clipBehavior,
offsetBounds, () => base.paint(context, offset));
D.assert(context.canvas == canvas, () => "canvas changed even though needsCompositing was false");
}
PhysicalModelLayer physicalModel = new PhysicalModelLayer(
clipPath: offsetPath,
clipBehavior: this.clipBehavior,
elevation: this.elevation,
color: this.color,
shadowColor: this.shadowColor);
context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds);
}
}

public delegate void PointerCancelEventListener(PointerCancelEvent evt);
public delegate void PointerSignalEventListener(PointerSignalEvent evt);
public delegate void PointerScrollEventListener(PointerScrollEvent evt);
public class RenderPointerListener : RenderProxyBoxWithHitTestBehavior {

PointerExitEventListener onPointerExit = null,
PointerUpEventListener onPointerUp = null,
PointerCancelEventListener onPointerCancel = null,
PointerSignalEventListener onPointerSignal = null,
PointerScrollEventListener onPointerScroll = null,
PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter = null,
PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover = null,

this.onPointerMove = onPointerMove;
this.onPointerUp = onPointerUp;
this.onPointerCancel = onPointerCancel;
this.onPointerSignal = onPointerSignal;
this.onPointerScroll = onPointerScroll;
this._onPointerEnter = onPointerEnter;

public PointerUpEventListener onPointerUp;
public PointerCancelEventListener onPointerCancel;
public PointerSignalEventListener onPointerSignal;
public MouseTrackerAnnotation hoverAnnotation {
get { return this._hoverAnnotation; }
}
void _updateAnnotations() {
D.assert(this._onPointerEnter != this._hoverAnnotation.onEnter ||
this._onPointerHover != this._hoverAnnotation.onHover ||

return;
}
if (this.onPointerSignal != null && evt is PointerSignalEvent) {
this.onPointerSignal((PointerSignalEvent) evt);
return;
}
if (this.onPointerScroll != null && evt is PointerScrollEvent) {
this.onPointerScroll((PointerScrollEvent) evt);
}

if (this.onPointerCancel != null) {
listeners.Add("cancel");
}
if (this.onPointerSignal != null) {
listeners.Add("signal");
}
if (listeners.isEmpty()) {

return base.computeMinIntrinsicHeight(width);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this.offstage) {
return 0.0f;
}

2
Runtime/rendering/proxy_box.mixin.gen.cs


return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(width);
}

2
Runtime/rendering/rotated_box.cs


return this._isVertical ? this.child.getMinIntrinsicWidth(width) : this.child.getMinIntrinsicHeight(width);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this.child == null) {
return 0.0f;
}

10
Runtime/rendering/shifted_box.cs


return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(width);
}

return this._padding.vertical;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(Mathf.Max(0.0f, width - this._padding.horizontal)) +
this._padding.vertical;

return this._requestedSize.height;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this._requestedSize.height;
}

return result / (this._heightFactor ?? 1.0f);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
float result;
if (this.child == null) {
result = base.computeMaxIntrinsicHeight(width);

return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
float height = this._getSize(BoxConstraints.tightForFinite(width: width)).height;
if (height.isFinite()) {
return height;

3
Runtime/rendering/sliver.cs


public readonly bool hasVisualOverflow;
public readonly float? scrollOffsetCorrection;
public readonly float cacheExtent;
public const float precisionErrorTolerance = 1e-10f;
internal static string _debugCompareFloats(string labelA, float valueA, string labelB, float valueB) {
if (valueA.ToString("F1") != valueB.ToString("F1")) {

);
}
if (this.maxPaintExtent < this.paintExtent) {
if (this.paintExtent - this.maxPaintExtent > precisionErrorTolerance) {
verify(false,
"The \"maxPaintExtent\" is less than the \"paintExtent\".\n" +
_debugCompareFloats("maxPaintExtent", this.maxPaintExtent, "paintExtent",

3
Runtime/rendering/sliver_grid.cs


float _getOffsetFromStartInCrossAxis(float crossAxisStart) {
if (this.reverseCrossAxis == true) {
return (this.crossAxisCount * this.crossAxisStride - crossAxisStart - this.childCrossAxisExtent) ??
return (this.crossAxisCount * this.crossAxisStride - crossAxisStart - this.childCrossAxisExtent
- (this.crossAxisStride - this.childCrossAxisExtent)) ??
0.0f;
}

2
Runtime/rendering/sliver_list.cs


}
else {
float firstChildScrollOffset = earliestScrollOffset - this.paintExtentOf(this.firstChild);
if (firstChildScrollOffset < 0.0) {
if (firstChildScrollOffset < -SliverGeometry.precisionErrorTolerance) {
float correction = 0.0f;
while (earliestUsefulChild != null) {
D.assert(this.firstChild == earliestUsefulChild);

2
Runtime/rendering/stack.cs


return this._getIntrinsicDimension((RenderBox child) => child.getMinIntrinsicHeight(width));
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this._getIntrinsicDimension((RenderBox child) => child.getMaxIntrinsicHeight(width));
}

2
Runtime/rendering/table.cs


return rowTop;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
return this.computeMinIntrinsicHeight(width);
}

2
Runtime/rendering/viewport.cs


return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
D.assert(this.debugThrowIfNotCheckingIntrinsics());
return 0.0f;
}

2
Runtime/rendering/wrap.cs


throw new Exception("Unknown axis: " + this.direction);
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
switch (this.direction) {
case Axis.horizontal:
return this._computeIntrinsicHeightForWidth(width);

97
Runtime/ui/painting/path.cs


using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Unity.UIWidgets.foundation;

public enum PathOperation {
difference,
intersect,
union,
xor,
reverseDifference,
}
struct VertexUV {
public List<Vector3> fillVertices;
public List<Vector2> fillUV;

}
return Rect.fromLTRB(this._minX, this._minY, this._maxX, this._maxY);
}
public static Path combine(PathOperation operation, Path path1, Path path2) {
D.assert(path1 != null);
D.assert(path2 != null);
Path path = null;
D.assert(() => {
Debug.LogWarning("Path._op() not implemented yet!");
return true;
});
return path;
// if (path._op(path1, path2, (int) operation)) {
// return path;
// }
// throw new UIWidgetsError("Path.combine() failed. This may be due an invalid path; " +
// "in particular, check for NaN values.");
}
public PathMetrics computeMetrics(bool forceClosed = false) {
return PathMetrics._(this, forceClosed);
}
void _appendMoveTo(float x, float y) {

return _return_check_zero(r);
}
}
public class PathMetrics : IEnumerable<PathMetric> {
public PathMetrics(IEnumerator<PathMetric> enumerator) {
this._enumerator = enumerator;
}
public static PathMetrics _(Path path, bool forceClosed) {
return new PathMetrics(PathMetricIterator._(new _PathMeasure())); // TODO: complete the implementation
}
public readonly IEnumerator<PathMetric> _enumerator;
public IEnumerator<PathMetric> GetEnumerator() {
return this._enumerator;
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
}
public class PathMetric {
// TODO
public readonly float length;
}
public class PathMetricIterator : IEnumerator<PathMetric> {
PathMetricIterator(_PathMeasure measure) {
this._pathMeasure = measure;
}
internal static PathMetricIterator _(_PathMeasure _pathMeasure) {
D.assert(_pathMeasure != null);
return new PathMetricIterator(_pathMeasure);
}
PathMetric _pathMetric;
_PathMeasure _pathMeasure;
public void Reset() {
throw new NotImplementedException();
}
public PathMetric Current {
get { return this._pathMetric; }
}
object IEnumerator.Current {
get { return this._pathMetric; }
}
public bool MoveNext() {
// if (_pathMeasure._nextContour()) {
// _pathMetric = PathMetric._(_pathMeasure);
// return true;
// }
// _pathMetric = null;
return false;
}
public void Dispose() {
throw new NotImplementedException();
}
}
class _PathMeasure {
}
public enum PathWinding {

23
Runtime/ui/painting/txt/font_manager.cs


public class FontManager {
readonly Dictionary<string, FontInfo>[] _fonts =
new Dictionary<string, FontInfo>[9 * 2]; // max weight size x max style size
static readonly int defaultFontSize = 14;
public static readonly FontManager instance = new FontManager();

}
public void addFont(Font font, string familyName,
public void addFont(Font font, string familyName,
FontWeight fontWeight = null, FontStyle fontStyle = FontStyle.normal) {
fontWeight = fontWeight ?? FontWeight.normal;

var fonts = this._getFonts(fontWeight.index, fontStyle);
fonts.TryGetValue(familyName, out var current);
D.assert(current == null || current.font == font,
D.assert(current == null || current.font == font,
() => $"font with key {familyName} {fontWeight} {fontStyle} already exists");
var fontInfo = new FontInfo(font);
fonts[familyName] = fontInfo;

return fontInfo;
}
}
var osFont = Font.CreateDynamicFontFromOSFont(familyName, defaultFontSize);
osFont.hideFlags = HideFlags.DontSave;
osFont.material.hideFlags = HideFlags.DontSave;

}
}
public static class FontExtension
{
public static class FontExtension {
internal static bool getGlyphInfo(this Font font, char ch, out CharacterInfo info, int fontSize,
UnityEngine.FontStyle fontStyle) {
if (fontSize <= 0) {

bool success = font.GetCharacterInfo(ch, out info, fontSize, fontStyle);
if (!success) {
if (!char.IsControl(ch)) {
Debug.LogWarning(
$"character info not found from the given font: character '{ch}' (code{(int) ch}) font: ${font.name}");
D.assert(() => {
Debug.LogWarning(
$"character info not found from the given font: character '{ch}' (code{(int) ch}) font: ${font.name}");
return true;
});
}
info = default;

return true;
}
internal static void RequestCharactersInTextureSafe(this Font font, string text, int fontSize,
UnityEngine.FontStyle fontStyle = UnityEngine.FontStyle.Normal) {
internal static void RequestCharactersInTextureSafe(this Font font, string text, int fontSize,
UnityEngine.FontStyle fontStyle = UnityEngine.FontStyle.Normal) {
font.RequestCharactersInTexture(text, fontSize, fontStyle);
}
}

87
Runtime/ui/pointer.cs


mouse,
}
public enum PointerSignalKind {
none,
scroll,
unknown,
}
int device,
float physicalX,
float physicalY) {
PointerSignalKind signalKind = PointerSignalKind.none,
int device = 0,
float physicalX = 0.0f,
float physicalY = 0.0f,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 0.0f,
float pressureMax = 0.0f,
float distance = 0.0f,
float distanceMax = 0.0f,
float size = 0.0f,
float radiusMajor = 0.0f,
float radiusMinor = 0.0f,
float radiusMin = 0.0f,
float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f,
int platformData = 0,
float scrollDeltaX = 0.0f,
float scrollDeltaY = 0.0f) {
this.signalKind = signalKind;
this.buttons = buttons;
this.obscured = obscured;
this.pressure = pressure;
this.pressureMin = pressureMin;
this.pressureMax = pressureMax;
this.distance = distance;
this.distanceMax = distanceMax;
this.size = size;
this.radiusMajor = radiusMajor;
this.radiusMinor = radiusMinor;
this.radiusMin = radiusMin;
this.radiusMax = radiusMax;
this.orientation = orientation;
this.tilt = tilt;
this.platformData = platformData;
this.scrollDeltaX = scrollDeltaX;
this.scrollDeltaY = scrollDeltaY;
public PointerChange change;
public PointerDeviceKind kind;
public int device;
public float physicalX;
public float physicalY;
public readonly PointerChange change;
public readonly PointerDeviceKind kind;
public readonly PointerSignalKind signalKind;
public readonly int device;
public readonly float physicalX;
public readonly float physicalY;
public readonly int buttons;
public readonly bool obscured;
public readonly float pressure;
public readonly float pressureMin;
public readonly float pressureMax;
public readonly float distance;
public readonly float distanceMax;
public readonly float size;
public readonly float radiusMajor;
public readonly float radiusMinor;
public readonly float radiusMin;
public readonly float radiusMax;
public readonly float orientation;
public readonly float tilt;
public readonly int platformData;
public readonly float scrollDeltaX;
public readonly float scrollDeltaY;
}
public class ScrollData : PointerData {

PointerDeviceKind kind,
int device,
float physicalX,
float physicalY,
float scrollX,
float scrollY) : base(timeStamp, change, kind, device, physicalX, physicalY) {
PointerSignalKind signalKind = PointerSignalKind.none,
int device = 0,
float physicalX = 0.0f,
float physicalY = 0.0f,
float scrollX = 0.0f,
float scrollY = 0.0f) : base(timeStamp, change, kind, signalKind, device, physicalX, physicalY) {
this.scrollX = scrollX;
this.scrollY = scrollY;
}

6
Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs


using System;
using Unity.UIWidgets.foundation;
using UnityEngine;
using UnityEngine.Rendering;

mat.SetInt(_dstBlend, (int) UnityEngine.Rendering.BlendMode.Zero);
}
else {
Debug.LogWarning("Not supported BlendMode: " + op + ". Defaults to srcOver");
D.assert(() => {
Debug.LogWarning("Not supported BlendMode: " + op + ". Defaults to srcOver");
return true;
});
mat.SetInt(_srcBlend, (int) UnityEngine.Rendering.BlendMode.One);
mat.SetInt(_dstBlend, (int) UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
}

43
Runtime/ui/text.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.painting;
namespace Unity.UIWidgets.ui {
public enum FontStyle {

int? maxLines = null,
float? fontSize = null,
string fontFamily = null,
float? lineHeight = null, // todo
string ellipsis = null) {
float? height = null, // todo
string ellipsis = null,
StrutStyle strutStyle = null) {
this.textAlign = textAlign;
this.textDirection = textDirection;
this.fontWeight = fontWeight;

this.fontFamily = fontFamily;
this.lineHeight = lineHeight;
this.height = height;
this.strutStyle = strutStyle;
}
public bool Equals(ParagraphStyle other) {

return this.textAlign == other.textAlign && this.textDirection == other.textDirection &&
this.fontWeight == other.fontWeight && this.fontStyle == other.fontStyle &&
this.maxLines == other.maxLines && this.fontSize.Equals(other.fontSize) &&
string.Equals(this.fontFamily, other.fontFamily) && this.lineHeight.Equals(other.lineHeight) &&
string.Equals(this.fontFamily, other.fontFamily) && this.height.Equals(other.height) &&
string.Equals(this.ellipsis, other.ellipsis);
}

hashCode = (hashCode * 397) ^ this.maxLines.GetHashCode();
hashCode = (hashCode * 397) ^ this.fontSize.GetHashCode();
hashCode = (hashCode * 397) ^ (this.fontFamily != null ? this.fontFamily.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.lineHeight.GetHashCode();
hashCode = (hashCode * 397) ^ this.height.GetHashCode();
hashCode = (hashCode * 397) ^ (this.ellipsis != null ? this.ellipsis.GetHashCode() : 0);
return hashCode;
}

fontStyle: this.fontStyle,
fontFamily: this.fontFamily,
fontSize: this.fontSize,
height: this.lineHeight
height: this.height
);
}

public readonly int? maxLines;
public readonly float? fontSize;
public readonly string fontFamily;
public readonly float? lineHeight;
public readonly float? height;
public readonly StrutStyle strutStyle;
public bool ellipsized() {
return !string.IsNullOrEmpty(this.ellipsis);

public readonly int index;
public static readonly FontWeight w100 = new FontWeight(0);
public static readonly FontWeight w200 = new FontWeight(1);
public static readonly FontWeight w300 = new FontWeight(2);
public static readonly FontWeight w400 = new FontWeight(3);
public static readonly FontWeight w500 = new FontWeight(4);
public static readonly FontWeight w600 = new FontWeight(5);
public static readonly FontWeight w700 = new FontWeight(6);
public static readonly FontWeight w800 = new FontWeight(7);
public static readonly FontWeight w900 = new FontWeight(8);
public static readonly FontWeight w100 = new FontWeight(0); // Ultralight
public static readonly FontWeight w200 = new FontWeight(1); // Thin
public static readonly FontWeight w300 = new FontWeight(2); // Light
public static readonly FontWeight w400 = new FontWeight(3); // Regular
public static readonly FontWeight w500 = new FontWeight(4); // Medium
public static readonly FontWeight w600 = new FontWeight(5); // Semibold
public static readonly FontWeight w700 = new FontWeight(6); // Bold
public static readonly FontWeight w800 = new FontWeight(7); // Heavy
public static readonly FontWeight w900 = new FontWeight(8); // Black
public static readonly FontWeight bold = w700;

1001
Runtime/ui/txt/paragraph.cs
文件差异内容过多而无法显示
查看文件

7
Runtime/ui/window.cs


VoidCallback _onTextScaleFactorChanged;
public VoidCallback onPlatformBrightnessChanged {
get { return this._onPlatformBrightnessChanged; }
set { this._onPlatformBrightnessChanged = value; }
}
VoidCallback _onPlatformBrightnessChanged;
public FrameCallback onBeginFrame {
get { return this._onBeginFrame; }
set { this._onBeginFrame = value; }

47
Runtime/widgets/app.cs


public delegate Locale LocaleResolutionCallback(Locale locale, List<Locale> supportedLocales);
public delegate string GenerateAppTitle(BuildContext context);
public delegate PageRoute PageRouteFactory(RouteSettings settings, WidgetBuilder builder);
public class WidgetsApp : StatefulWidget {

public readonly LocaleResolutionCallback localeResolutionCallback;
public readonly List<Locale> supportedLocales;
public readonly string title;
public readonly GenerateAppTitle onGenerateTitle;
public readonly Color color;
public readonly InspectorSelectButtonBuilder inspectorSelectButtonBuilder;
public WidgetsApp(
Key key = null,
GlobalKey<NavigatorState> navigatorKey = null,

LocaleListResolutionCallback localeListResolutionCallback = null,
LocaleResolutionCallback localeResolutionCallback = null,
List<Locale> supportedLocales = null,
bool showPerformanceOverlay = false
bool showPerformanceOverlay = false,
GenerateAppTitle onGenerateTitle = null,
string title = "",
Color color = null,
InspectorSelectButtonBuilder inspectorSelectButtonBuilder = null
) : base(key) {
routes = routes ?? new Dictionary<string, WidgetBuilder>();
supportedLocales = supportedLocales ?? new List<Locale> {new Locale("en", "US")};

this.localeResolutionCallback = localeResolutionCallback;
this.supportedLocales = supportedLocales;
this.showPerformanceOverlay = showPerformanceOverlay;
this.onGenerateTitle = onGenerateTitle;
this.title = title;
this.color = color;
this.inspectorSelectButtonBuilder = inspectorSelectButtonBuilder;
"cannot include an entry for \" / \", since it would be redundant."
"cannot include an entry for \" / \", since it would be redundant."
);
D.assert(

onGenerateRoute != null ||
onUnknownRoute != null,
() => "Either the home property must be specified, " +
"or the routes table must include an entry for \"/\", " +
"or there must be on onGenerateRoute callback specified, " +
"or there must be an onUnknownRoute callback specified, " +
"or the builder property must be specified, " +
"because otherwise there is nothing to fall back on if the " +
"app is started with an intent that specifies an unknown route."
"or the routes table must include an entry for \"/\", " +
"or there must be on onGenerateRoute callback specified, " +
"or there must be an onUnknownRoute callback specified, " +
"or the builder property must be specified, " +
"because otherwise there is nothing to fall back on if the " +
"app is started with an intent that specifies an unknown route."
);
D.assert(

() => "If neither builder nor onGenerateRoute are provided, the " +
"pageRouteBuilder must be specified so that the default handler " +
"will know what kind of PageRoute transition to build."
"pageRouteBuilder must be specified so that the default handler " +
"will know what kind of PageRoute transition to build."
);
}

return provider.window;
}
public static Window of(GameObject gameObject) {
var panel = gameObject.GetComponent<UIWidgetsPanel>();
return panel == null ? null : panel.window;

public void didChangeTextScaleFactor() {
this.setState();
}
this.setState(() => {
});
this.setState(() => { });
}
public void didChangeLocales(List<Locale> locale) {

public override void initState() {
base.initState();
this._updateNavigator();
//todo: xingwei.zhu: change the default locale to ui.Window.locale
this._locale =
this._resolveLocales(new List<Locale> {new Locale("en", "US")}, this.widget.supportedLocales);

if (pageContentBuilder != null) {
D.assert(this.widget.pageRouteBuilder != null,
() => "The default onGenerateRoute handler for WidgetsApp must have a " +
"pageRouteBuilder set if the home or routes properties are set.");
"pageRouteBuilder set if the home or routes properties are set.");
var route = this.widget.pageRouteBuilder(
settings,
pageContentBuilder

16
Runtime/widgets/basic.cs


float textScaleFactor = 1.0f,
int? maxLines = null,
Action onSelectionChanged = null,
Color selectionColor = null
Color selectionColor = null,
StrutStyle strutStyle = null
) : base(key: key) {
D.assert(text != null);
D.assert(maxLines == null || maxLines > 0);

this.maxLines = maxLines;
this.onSelectionChanged = onSelectionChanged;
this.selectionColor = selectionColor;
this.strutStyle = strutStyle;
}
public readonly TextSpan text;

public readonly int? maxLines;
public readonly Action onSelectionChanged;
public readonly Color selectionColor;
public readonly StrutStyle strutStyle;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderParagraph(

renderObject.maxLines = this.maxLines;
renderObject.onSelectionChanged = this.onSelectionChanged;
renderObject.selectionColor = this.selectionColor;
renderObject.strutStyle = this.strutStyle;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {

PointerHoverEventListener onPointerHover = null,
PointerUpEventListener onPointerUp = null,
PointerCancelEventListener onPointerCancel = null,
PointerSignalEventListener onPointerSignal = null,
PointerScrollEventListener onPointerScroll = null,
PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter = null,
PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover = null,

this.onPointerMove = onPointerMove;
this.onPointerUp = onPointerUp;
this.onPointerCancel = onPointerCancel;
this.onPointerSignal = onPointerSignal;
this.onPointerHover = onPointerHover;
this.onPointerExit = onPointerExit;
this.onPointerEnter = onPointerEnter;

public readonly PointerCancelEventListener onPointerCancel;
public readonly PointerSignalEventListener onPointerSignal;
public readonly PointerHoverEventListener onPointerHover;
public readonly PointerEnterEventListener onPointerEnter;

onPointerMove: this.onPointerMove,
onPointerUp: this.onPointerUp,
onPointerCancel: this.onPointerCancel,
onPointerSignal: this.onPointerSignal,
onPointerEnter: this.onPointerEnter,
onPointerExit: this.onPointerExit,
onPointerHover: this.onPointerHover,

renderObject.onPointerMove = this.onPointerMove;
renderObject.onPointerUp = this.onPointerUp;
renderObject.onPointerCancel = this.onPointerCancel;
renderObject.onPointerSignal = this.onPointerSignal;
renderObject.onPointerEnter = this.onPointerEnter;
renderObject.onPointerHover = this.onPointerHover;
renderObject.onPointerExit = this.onPointerExit;

if (this.onPointerCancel != null) {
listeners.Add("cancel");
}
if (this.onPointerSignal != null) {
listeners.Add("signal");
}
if (this.onPointerEnter != null) {

2
Runtime/widgets/dismissible.cs


Dictionary<DismissDirection?, float?> dismissThresholds = null,
TimeSpan? movementDuration = null,
float crossAxisEndOffset = 0.0f,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key) {
D.assert(key != null);
D.assert(secondaryBackground != null ? background != null : true);

221
Runtime/widgets/editable_text.cs


get { return this.value.text; }
set {
this.value = this.value.copyWith(text: value, selection: TextSelection.collapsed(-1),
this.value = this.value.copyWith(
text: value,
selection: TextSelection.collapsed(-1),
composing: TextRange.empty);
}
}

}
public class EditableText : StatefulWidget {
public readonly TextEditingController controller;
public readonly FocusNode focusNode;
public readonly bool obscureText;
public readonly bool autocorrect;
public readonly TextStyle style;
public readonly TextAlign textAlign;
public readonly TextDirection? textDirection;
public readonly TextCapitalization textCapitalization;
public readonly float? textScaleFactor;
public readonly Color cursorColor;
public readonly Color backgroundCursorColor;
public readonly int? maxLines;
public readonly bool autofocus;
public readonly Color selectionColor;
public readonly TextSelectionControls selectionControls;
public readonly TextInputType keyboardType;
public readonly TextInputAction? textInputAction;
public readonly ValueChanged<string> onChanged;
public readonly VoidCallback onEditingComplete;
public readonly ValueChanged<string> onSubmitted;
public readonly SelectionChangedCallback onSelectionChanged;
public readonly List<TextInputFormatter> inputFormatters;
public readonly bool rendererIgnoresPointer;
public readonly bool unityTouchKeyboard;
public EditableText(TextEditingController controller, FocusNode focusNode, TextStyle style,
Color cursorColor, Color backgroundCursorColor = null, bool obscureText = false, bool autocorrect = false,
TextAlign textAlign = TextAlign.left, TextDirection? textDirection = null,
float? textScaleFactor = null, int? maxLines = 1,
bool autofocus = false, Color selectionColor = null, TextSelectionControls selectionControls = null,
TextInputType keyboardType = null, TextInputAction? textInputAction = null,
public EditableText(
TextEditingController controller = null,
FocusNode focusNode = null, TextStyle style = null,
StrutStyle strutStyle = null,
Color cursorColor = null,
Color backgroundCursorColor = null,
bool obscureText = false,
bool autocorrect = false,
TextAlign textAlign = TextAlign.left,
TextDirection? textDirection = null,
float? textScaleFactor = null,
int? maxLines = 1,
int? minLines = null,
bool expands = false,
bool autofocus = false,
Color selectionColor = null,
TextSelectionControls selectionControls = null,
TextInputType keyboardType = null,
TextInputAction? textInputAction = null,
ValueChanged<string> onChanged = null, VoidCallback onEditingComplete = null,
ValueChanged<string> onSubmitted = null, SelectionChangedCallback onSelectionChanged = null,
List<TextInputFormatter> inputFormatters = null, bool rendererIgnoresPointer = false,
EdgeInsets scrollPadding = null, bool unityTouchKeyboard = false,
Key key = null, float? cursorWidth = 2.0f, Radius cursorRadius = null, bool cursorOpacityAnimates = false,
Offset cursorOffset = null, bool paintCursorAboveText = false,
ValueChanged<string> onChanged = null,
VoidCallback onEditingComplete = null,
ValueChanged<string> onSubmitted = null,
SelectionChangedCallback onSelectionChanged = null,
List<TextInputFormatter> inputFormatters = null,
bool rendererIgnoresPointer = false,
EdgeInsets scrollPadding = null,
bool unityTouchKeyboard = false,
Key key = null,
float? cursorWidth = 2.0f,
Radius cursorRadius = null,
bool cursorOpacityAnimates = false,
Offset cursorOffset = null,
bool paintCursorAboveText = false,
bool? enableInteractiveSelection = null
bool? enableInteractiveSelection = null,
ScrollPhysics scrollPhysics = null
) : base(key) {
D.assert(controller != null);
D.assert(focusNode != null);

D.assert(minLines == null || minLines > 0);
D.assert((maxLines == null) || (minLines == null) || (maxLines >= minLines),
() => "minLines can't be greater than maxLines");
D.assert(!expands || (maxLines == null && minLines == null),
() => "minLines and maxLines must be null when expands is true.");
// D.assert(backgroundCursorColor != null); // TODO: remove comment
this.keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline);

this.obscureText = obscureText;
this.autocorrect = autocorrect;
this.style = style;
this._strutStyle = strutStyle;
this.textAlign = textAlign;
this.textDirection = textDirection;
this.textScaleFactor = textScaleFactor;

this.backgroundCursorColor = backgroundCursorColor ?? Colors.grey; // TODO: remove ??
this.maxLines = maxLines;
this.minLines = minLines;
this.expands = expands;
this.autofocus = autofocus;
this.selectionColor = selectionColor;
this.onChanged = onChanged;

this.keyboardAppearance = keyboardAppearance;
this.enableInteractiveSelection = enableInteractiveSelection;
this.dragStartBehavior = dragStartBehavior;
this.scrollPhysics = scrollPhysics;
public readonly TextEditingController controller;
public readonly FocusNode focusNode;
public readonly bool obscureText;
public readonly bool autocorrect;
public readonly TextStyle style;
public StrutStyle strutStyle {
get {
if (this._strutStyle == null) {
return this.style != null
? StrutStyle.fromTextStyle(this.style, forceStrutHeight: true)
: StrutStyle.disabled;
}
return this._strutStyle.inheritFromTextStyle(this.style);
}
}
readonly StrutStyle _strutStyle;
public readonly TextAlign textAlign;
public readonly TextDirection? textDirection;
public readonly TextCapitalization textCapitalization;
public readonly float? textScaleFactor;
public readonly Color cursorColor;
public readonly Color backgroundCursorColor;
public readonly int? maxLines;
public readonly int? minLines;
public readonly bool expands;
public readonly bool autofocus;
public readonly Color selectionColor;
public readonly TextSelectionControls selectionControls;
public readonly TextInputType keyboardType;
public readonly TextInputAction? textInputAction;
public readonly ValueChanged<string> onChanged;
public readonly VoidCallback onEditingComplete;
public readonly ValueChanged<string> onSubmitted;
public readonly SelectionChangedCallback onSelectionChanged;
public readonly List<TextInputFormatter> inputFormatters;
public readonly bool rendererIgnoresPointer;
public readonly bool unityTouchKeyboard;
public readonly float? cursorWidth;
public readonly Radius cursorRadius;
public readonly bool cursorOpacityAnimates;

public readonly EdgeInsets scrollPadding;
public readonly DragStartBehavior dragStartBehavior;
public readonly ScrollPhysics scrollPhysics;
public bool selectionEnabled {
get { return this.enableInteractiveSelection ?? !this.obscureText; }

properties.add(new DiagnosticsProperty<float?>("textScaleFactor", this.textScaleFactor,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DiagnosticsProperty<int?>("maxLines", this.maxLines, defaultValue: 1));
properties.add(new DiagnosticsProperty<int?>("minLines", this.minLines,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DiagnosticsProperty<bool>("expands", this.expands, defaultValue: false));
properties.add(new DiagnosticsProperty<ScrollPhysics>("scrollPhysics", this.scrollPhysics,
defaultValue: Diagnostics.kNullDefaultValue));
}
}

public void performAction(TextInputAction action) {
switch (action) {
case TextInputAction.newline:
if (this.widget.maxLines == 1) {
if (!this._isMultiline) {
this._finalizeEditing(true);
}

public void updateFloatingCursor(RawFloatingCursorPoint point) {
switch (point.state) {
case FloatingCursorDragState.Start:
if (this._floatingCursorResetController.isAnimating) {
this._floatingCursorResetController.stop();
this._onFloatingCursorResetTick();
}
TextPosition currentTextPosition =
new TextPosition(offset: this.renderEditable.selection.baseOffset);
this._startCaretRect = this.renderEditable.getLocalRectForCaret(currentTextPosition);

this._handleSelectionChanged(TextSelection.collapsed(offset: this._lastTextPosition.offset),
this.renderEditable, SelectionChangedCause.forcePress);
}
} else {
}
else {
float lerpValue = this._floatingCursorResetController.value;
float lerpX = MathUtils.lerpFloat(this._lastBoundedOffset.dx, finalPosition.dx, lerpValue);
float lerpY = MathUtils.lerpFloat(this._lastBoundedOffset.dy, finalPosition.dy, lerpValue);

public void requestKeyboard() {
if (this._hasFocus) {
this._openInputConnection();
} else {
}
else {
FocusScope.of(this.context).requestFocus(this.widget.focusNode);
}
}

get {
TextDirection? result = this.widget.textDirection ?? Directionality.of(this.context);
D.assert(result != null,
() => $"{this.GetType().FullName} created without a textDirection and with no ambient Directionality.");
() =>
$"{this.GetType().FullName} created without a textDirection and with no ambient Directionality.");
return result;
}
}

}
public override Widget build(BuildContext context) {
D.assert(WidgetsD.debugCheckHasMediaQuery(context));
FocusScope.of(context).reparentIfNeeded(this.widget.focusNode);
base.build(context); // See AutomaticKeepAliveClientMixin.

physics: new ClampingScrollPhysics(),
physics: this.widget.scrollPhysics,
dragStartBehavior: this.widget.dragStartBehavior,
viewportBuilder: (BuildContext _context, ViewportOffset offset) =>
new CompositedTransformTarget(

: this._cursorVisibilityNotifier,
hasFocus: this._hasFocus,
maxLines: this.widget.maxLines,
minLines: this.widget.minLines,
expands: this.widget.expands,
strutStyle: this.widget.strutStyle,
selectionColor: this.widget.selectionColor,
textScaleFactor: this.widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
textAlign: this.widget.textAlign,

public readonly ValueNotifier<bool> showCursor;
public readonly bool hasFocus;
public readonly int? maxLines;
public readonly int? minLines;
public readonly bool expands;
public readonly StrutStyle strutStyle;
public readonly Color selectionColor;
public readonly float textScaleFactor;
public readonly TextAlign textAlign;

public readonly float? devicePixelRatio;
public _Editable(TextSpan textSpan = null, TextEditingValue value = null,
Color cursorColor = null, Color backgroundCursorColor = null, ValueNotifier<bool> showCursor = null,
public _Editable(TextSpan textSpan = null,
TextEditingValue value = null,
Color cursorColor = null,
Color backgroundCursorColor = null,
ValueNotifier<bool> showCursor = null,
int? maxLines = null, Color selectionColor = null, float textScaleFactor = 1.0f,
TextDirection? textDirection = null, bool obscureText = false, TextAlign textAlign = TextAlign.left,
bool autocorrect = false, ViewportOffset offset = null, SelectionChangedHandler onSelectionChanged = null,
CaretChangedHandler onCaretChanged = null, bool rendererIgnoresPointer = false,
Key key = null, TextSelectionDelegate textSelectionDelegate = null, float? cursorWidth = null,
Radius cursorRadius = null, Offset cursorOffset = null, bool enableInteractiveSelection = true,
bool? paintCursorAboveText = null, float? devicePixelRatio = null) : base(key) {
int? maxLines = null,
int? minLines = null,
bool expands = false,
StrutStyle strutStyle = null,
Color selectionColor = null,
float textScaleFactor = 1.0f,
TextDirection? textDirection = null,
bool obscureText = false,
TextAlign textAlign = TextAlign.left,
bool autocorrect = false,
ViewportOffset offset = null,
SelectionChangedHandler onSelectionChanged = null,
CaretChangedHandler onCaretChanged = null,
bool rendererIgnoresPointer = false,
Key key = null,
TextSelectionDelegate textSelectionDelegate = null,
float? cursorWidth = null,
Radius cursorRadius = null,
Offset cursorOffset = null,
bool enableInteractiveSelection = true,
bool? paintCursorAboveText = null,
float? devicePixelRatio = null) : base(key) {
this.textSpan = textSpan;
this.value = value;
this.cursorColor = cursorColor;

this.maxLines = maxLines;
this.minLines = minLines;
this.strutStyle = strutStyle;
this.selectionColor = selectionColor;
this.textScaleFactor = textScaleFactor;
this.textAlign = textAlign;

backgroundCursorColor: this.backgroundCursorColor,
hasFocus: this.hasFocus,
maxLines: this.maxLines,
minLines: this.minLines,
expands: this.expands,
strutStyle: this.strutStyle,
selectionColor: this.selectionColor,
textScaleFactor: this.textScaleFactor,
textAlign: this.textAlign,

edit.showCursor = this.showCursor;
edit.hasFocus = this.hasFocus;
edit.maxLines = this.maxLines;
edit.strutStyle = this.strutStyle;
edit.selectionColor = this.selectionColor;
edit.textScaleFactor = this.textScaleFactor;
edit.textAlign = this.textAlign;

10
Runtime/widgets/fade_in_image.cs


) {
D.assert(placeholder != null);
D.assert(image != null);
D.assert(fadeOutDuration != null);
D.assert(fadeOutCurve != null);
D.assert(fadeInDuration != null);
D.assert(fadeInCurve != null);
D.assert(alignment != null);
fadeOutDuration = fadeOutDuration ?? new TimeSpan(0, 0, 0, 0, 300);
fadeOutCurve = fadeOutCurve ?? Curves.easeOut;
fadeInDuration = fadeInDuration ?? new TimeSpan(0, 0, 0, 0, 700);
fadeInCurve = Curves.easeIn;
alignment = alignment ?? Alignment.center;
var imageProvider = placeholderScale != null
? new ExactAssetImage(placeholder, bundle: bundle, scale: placeholderScale ?? 1.0f)
: (ImageProvider) new AssetImage(placeholder, bundle: bundle);

4
Runtime/widgets/form.cs


return !this.hasError;
}
bool _validate() {
void _validate() {
return !this.hasError;
}
public virtual void didChange(T value) {

53
Runtime/widgets/gesture_detector.cs


GestureTapCancelCallback onTapCancel = null,
GestureDoubleTapCallback onDoubleTap = null,
GestureLongPressCallback onLongPress = null,
GestureLongPressStartCallback onLongPressStart = null,
GestureLongPressMoveUpdateCallback onLongPressMoveUpdate = null,
GestureLongPressDragStartCallback onLongPressDragStart = null,
GestureLongPressDragUpdateCallback onLongPressDragUpdate = null,
GestureLongPressDragUpCallback onLongPressDragUp = null,
GestureLongPressEndCallback onLongPressEnd = null,
GestureDragDownCallback onVerticalDragDown = null,
GestureDragStartCallback onVerticalDragStart = null,
GestureDragUpdateCallback onVerticalDragUpdate = null,

bool haveHorizontalDrag =
onHorizontalDragStart != null || onHorizontalDragUpdate != null ||
onHorizontalDragEnd != null;
bool haveLongPress = onLongPress != null || onLongPressUp != null;
bool haveLongPressDrag = onLongPressDragStart != null || onLongPressDragUpdate != null ||
onLongPressDragUp != null;
bool havePan = onPanStart != null || onPanUpdate != null || onPanEnd != null;
bool haveScale = onScaleStart != null || onScaleUpdate != null || onScaleEnd != null;
if (havePan || haveScale) {

}
}
if (haveLongPress && haveLongPressDrag) {
throw new UIWidgetsError(
"Incorrect GestureDetector arguments.\n" +
"Having both a long press and a long press drag recognizer is " +
"redundant as the long press drag is a superset of long press. " +
"Except long press drag allows for drags after the long press is " +
"triggered."
);
}
return true;
});

this.onDoubleTap = onDoubleTap;
this.onLongPress = onLongPress;
this.onLongPressUp = onLongPressUp;
this.onLongPressDragStart = onLongPressDragStart;
this.onLongPressDragUpdate = onLongPressDragUpdate;
this.onLongPressDragUp = onLongPressDragUp;
this.onLongPressStart = onLongPressStart;
this.onLongPressMoveUpdate = onLongPressMoveUpdate;
this.onLongPressEnd = onLongPressEnd;
this.onVerticalDragDown = onVerticalDragDown;
this.onVerticalDragStart = onVerticalDragStart;
this.onVerticalDragUpdate = onVerticalDragUpdate;

public readonly GestureDoubleTapCallback onDoubleTap;
public readonly GestureLongPressCallback onLongPress;
public readonly GestureLongPressUpCallback onLongPressUp;
public readonly GestureLongPressDragStartCallback onLongPressDragStart;
public readonly GestureLongPressDragUpdateCallback onLongPressDragUpdate;
public readonly GestureLongPressDragUpCallback onLongPressDragUp;
public readonly GestureLongPressStartCallback onLongPressStart;
public readonly GestureLongPressMoveUpdateCallback onLongPressMoveUpdate;
public readonly GestureLongPressEndCallback onLongPressEnd;
public readonly GestureDragDownCallback onVerticalDragDown;
public readonly GestureDragStartCallback onVerticalDragStart;
public readonly GestureDragUpdateCallback onVerticalDragUpdate;

);
}
if (this.onLongPress != null || this.onLongPressUp != null) {
if (this.onLongPress != null ||
this.onLongPressUp != null ||
this.onLongPressStart != null ||
this.onLongPressMoveUpdate != null ||
this.onLongPressEnd != null) {
instance.onLongPressStart = this.onLongPressStart;
instance.onLongPressMoveUpdate = this.onLongPressMoveUpdate;
instance.onLongPressEnd = this.onLongPressEnd;
}
);
}
if (this.onLongPressDragStart != null || this.onLongPressDragUpdate != null ||
this.onLongPressDragUp != null) {
gestures[typeof(LongPressDragGestureRecognizer)] =
new GestureRecognizerFactoryWithHandlers<LongPressDragGestureRecognizer>(
() => new LongPressDragGestureRecognizer(debugOwner: this),
(LongPressDragGestureRecognizer instance) => {
instance.onLongPressStart = this.onLongPressDragStart;
instance.onLongPressDragUpdate = this.onLongPressDragUpdate;
instance.onLongPressUp = this.onLongPressDragUp;
}
);
}

81
Runtime/widgets/heroes.cs


public readonly bool transitionOnUserGestures;
internal static Dictionary<object, _HeroState>
_allHeroesFor(BuildContext context, bool isUserGestureTransition) {
_allHeroesFor(BuildContext context, bool isUserGestureTransition, NavigatorState navigator) {
D.assert(navigator != null);
void addHero(StatefulElement hero, object tag) {
D.assert(() => {
if (result.ContainsKey(tag)) {
throw new UIWidgetsError(
"There are multiple heroes that share the same tag within a subtree.\n" +
"Within each subtree for which heroes are to be animated (typically a PageRoute subtree), " +
"each Hero must have a unique non-null tag.\n" +
$"In this case, multiple heroes had the following tag: {tag}\n" +
"Here is the subtree for one of the offending heroes:\n" +
$"{hero.toStringDeep(prefixLineOne: "# ")}"
);
}
return true;
});
_HeroState heroState = (_HeroState) hero.state;
result[tag] = heroState;
}
void visitor(Element element) {
if (element.widget is Hero) {
StatefulElement hero = (StatefulElement) element;

D.assert(tag != null);
D.assert(() => {
if (result.ContainsKey(tag)) {
throw new UIWidgetsError(
"There are multiple heroes that share the same tag within a subtree.\n" +
"Within each subtree for which heroes are to be animated (typically a PageRoute subtree), " +
"each Hero must have a unique non-null tag.\n" +
$"In this case, multiple heroes had the following tag: {tag}\n" +
"Here is the subtree for one of the offending heroes:\n" +
$"{element.toStringDeep(prefixLineOne: "# ")}"
);
if (Navigator.of(hero) == navigator) {
addHero(hero, tag);
}
else {
ModalRoute heroRoute = ModalRoute.of(hero);
if (heroRoute != null && heroRoute is PageRoute && heroRoute.isCurrent) {
addHero(hero, tag);
return true;
});
_HeroState heroState = (_HeroState) hero.state;
result[tag] = heroState;
}
}
}

}
public override Widget build(BuildContext context) {
D.assert(context.ancestorWidgetOfExactType(typeof(Hero)) == null,
() => "A Hero widget cannot be the descendant of another Hero widget.");
if (this._placeholderSize != null) {
if (this.widget.placeholderBuilder == null) {
return new SizedBox(

HeroFlightShuttleBuilder shuttleBuilder,
bool isUserGestureTransition
) {
D.assert(this.fromHero.widget.tag == this.toHero.widget.tag);
D.assert(fromHero.widget.tag == toHero.widget.tag);
this.type = type;
this.overlay = overlay;
this.navigatorRect = navigatorRect;

}
public class HeroController : NavigatorObserver {
HeroController(CreateRectTween createRectTween) {
public HeroController(CreateRectTween createRectTween = null) {
this.createRectTween = createRectTween;
}

public override void didPop(Route route, Route previousRoute) {
D.assert(this.navigator != null);
D.assert(route != null);
this._maybeStartHeroTransition(route, previousRoute, HeroFlightDirection.pop, false);
if (!this.navigator.userGestureInProgress) {
this._maybeStartHeroTransition(route, previousRoute, HeroFlightDirection.pop, false);
}
}
public override void didReplace(Route newRoute = null, Route oldRoute = null) {
D.assert(this.navigator != null);
if (newRoute?.isCurrent == true) {
this._maybeStartHeroTransition(oldRoute, newRoute, HeroFlightDirection.push, false);
}
}
public override void didStartUserGesture(Route route, Route previousRoute) {

Rect navigatorRect = HeroUtils._globalBoundingBoxFor(this.navigator.context);
Dictionary<object, _HeroState>
fromHeroes = Hero._allHeroesFor(from.subtreeContext, isUserGestureTransition);
Dictionary<object, _HeroState> toHeroes = Hero._allHeroesFor(to.subtreeContext, isUserGestureTransition);
Dictionary<object, _HeroState> fromHeroes =
Hero._allHeroesFor(from.subtreeContext, isUserGestureTransition, this.navigator);
Dictionary<object, _HeroState> toHeroes =
Hero._allHeroesFor(to.subtreeContext, isUserGestureTransition, this.navigator);
if (toHeroes[tag] != null) {
if (toHeroes.ContainsKey(tag)) {
HeroFlightShuttleBuilder fromShuttleBuilder = fromHeroes[tag].widget.flightShuttleBuilder;
HeroFlightShuttleBuilder toShuttleBuilder = toHeroes[tag].widget.flightShuttleBuilder;

isUserGestureTransition: isUserGestureTransition
);
if (this._flights[tag] != null) {
this._flights[tag].divert(manifest);
if (this._flights.TryGetValue(tag, out var result)) {
result.divert(manifest);
}
else {
this._flights[tag] = new _HeroFlight(this._handleFlightEnded);

else if (this._flights[tag] != null) {
this._flights[tag].abort();
else if (this._flights.TryGetValue(tag, out var result)) {
result.abort();
}
}
}

return toHero.child;
};
}
}
}

2
Runtime/widgets/icon.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using TextStyle = Unity.UIWidgets.painting.TextStyle;

}
Widget iconWidget = new RichText(
overflow: TextOverflow.visible,
text: new TextSpan(
text: new string(new[] {(char) this.icon.codePoint}),
style: new TextStyle(

2
Runtime/widgets/layout_builder.cs


return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
D.assert(this._debugThrowIfNotCheckingIntrinsics());
return 0.0f;
}

4
Runtime/widgets/nested_scroll_view.cs


ScrollPhysics physics = null,
NestedScrollViewHeaderSliversBuilder headerSliverBuilder = null,
Widget body = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key) {
D.assert(headerSliverBuilder != null);
D.assert(body != null);

ScrollController controller,
List<Widget> slivers,
SliverOverlapAbsorberHandle handle,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
scrollDirection: scrollDirection,
reverse: reverse,

83
Runtime/widgets/overlay.cs


this.insertAll(this.widget.initialEntries);
}
public void insert(OverlayEntry entry, OverlayEntry above = null) {
D.assert(entry._overlay == null);
D.assert(above == null || (above._overlay == this && this._entries.Contains(above)));
internal int _insertionIndex(OverlayEntry below, OverlayEntry above) {
D.assert(below == null || above == null);
if (below != null) {
return this._entries.IndexOf(below);
}
if (above != null) {
return this._entries.IndexOf(above) + 1;
}
return this._entries.Count;
}
public void insert(OverlayEntry entry, OverlayEntry below = null, OverlayEntry above = null) {
D.assert(above == null || below == null, () => "Only one of `above` and `below` may be specified.");
D.assert(above == null || (above._overlay == this && this._entries.Contains(above)),
() => "The provided entry for `above` is not present in the Overlay.");
D.assert(below == null || (below._overlay == this && this._entries.Contains(below)),
() => "The provided entry for `below` is not present in the Overlay.");
D.assert(!this._entries.Contains(entry), () => "The specified entry is already present in the Overlay.");
D.assert(entry._overlay == null, () => "The specified entry is already present in another Overlay.");
this.setState(() => {
int index = above == null ? this._entries.Count : this._entries.IndexOf(above) + 1;
this._entries.Insert(index, entry);
});
this.setState(() => { this._entries.Insert(this._insertionIndex(below, above), entry); });
public void insertAll(ICollection<OverlayEntry> entries, OverlayEntry above = null) {
D.assert(above == null || (above._overlay == this && this._entries.Contains(above)));
public void insertAll(ICollection<OverlayEntry> entries, OverlayEntry below = null, OverlayEntry above = null) {
D.assert(above == null || below == null, () => "Only one of `above` and `below` may be specified.");
D.assert(above == null || (above._overlay == this && this._entries.Contains(above)),
() => "The provided entry for `above` is not present in the Overlay.");
D.assert(below == null || (below._overlay == this && this._entries.Contains(below)),
() => "The provided entry for `below` is not present in the Overlay.");
D.assert(entries.All(entry => !this._entries.Contains(entry)),
() => "One or more of the specified entries are already present in the Overlay.");
D.assert(entries.All(entry => entry._overlay == null),
() => "One or more of the specified entries are already present in another Overlay.");
if (entries.isEmpty()) {
return;
}

}
this.setState(() => {
int index = above == null ? this._entries.Count : this._entries.IndexOf(above) + 1;
this._entries.InsertRange(index, entries);
this._entries.InsertRange(this._insertionIndex(below, above), entries);
});
}
public void rearrange(IEnumerable<OverlayEntry> newEntries, OverlayEntry below = null, OverlayEntry above = null) {
List<OverlayEntry> newEntriesList =
newEntries is List<OverlayEntry> ?(newEntries as List<OverlayEntry>) : newEntries.ToList();
D.assert(above == null || below == null, () => "Only one of `above` and `below` may be specified.");
D.assert(above == null || (above._overlay == this && this._entries.Contains(above)),
() => "The provided entry for `above` is not present in the Overlay.");
D.assert(below == null || (below._overlay == this && this._entries.Contains(below)),
() => "The provided entry for `below` is not present in the Overlay.");
D.assert(newEntriesList.All(entry => !this._entries.Contains(entry)),
() => "One or more of the specified entries are already present in the Overlay.");
D.assert(newEntriesList.All(entry => entry._overlay == null),
() => "One or more of the specified entries are already present in another Overlay.");
if (newEntriesList.isEmpty()) {
return;
}
if (this._entries.SequenceEqual(newEntriesList)) {
return;
}
HashSet<OverlayEntry> old = new HashSet<OverlayEntry>(this._entries);
foreach(OverlayEntry entry in newEntriesList) {
entry._overlay = entry._overlay ?? this;
}
this.setState(() => {
this._entries.Clear();
this._entries.AddRange(newEntriesList);
foreach (OverlayEntry entry in newEntriesList) {
old.Remove(entry);
}
this._entries.InsertRange(this._insertionIndex(below, above), old);
this.setState(() => {
this._entries.Remove(entry);
});
this.setState(() => { this._entries.Remove(entry); });
}
}

7
Runtime/widgets/page_view.cs


bool pageSnapping = true,
ValueChanged<int> onPageChanged = null,
List<Widget> children = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
IndexedWidgetBuilder itemBuilder = null,
SliverChildDelegate childDelegate = null,
int itemCount = 0

this.childrenDelegate = new SliverChildListDelegate(children ?? new List<Widget>());
}
}
// TODO: PageView.builder
// TODO: PageView.custom
public readonly Axis scrollDirection;

8
Runtime/widgets/routes.cs


protected internal override void install(OverlayEntry insertionPoint) {
D.assert(this._overlayEntries.isEmpty());
this._overlayEntries.AddRange(this.createOverlayEntries());
this.navigator.overlay?.insertAll(this._overlayEntries, insertionPoint);
this.navigator.overlay?.insertAll(this._overlayEntries, above: insertionPoint);
base.install(insertionPoint);
}

break;
case AnimationStatus.dismissed:
// We might still be the current route if a subclass is controlling the
// We might still be an active route if a subclass is controlling the
if (!this.isCurrent) {
if (!this.isActive) {
this.navigator.finalizeRoute(this);
D.assert(this.overlayEntries.isEmpty());
}

this._willPopCallbacks.Remove(callback);
}
protected bool hasScopedWillPopCallback {
protected internal bool hasScopedWillPopCallback {
get { return this._willPopCallbacks.isNotEmpty(); }
}

26
Runtime/widgets/scroll_view.cs


Key center = null,
float anchor = 0.0f,
float? cacheExtent = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key) {
D.assert(!(controller != null && primary == true),
() => "Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. " +

float anchor = 0.0f,
float? cacheExtent = null,
List<Widget> slivers = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
key: key,
scrollDirection: scrollDirection,

bool shrinkWrap = false,
EdgeInsets padding = null,
float? cacheExtent = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
key: key,
scrollDirection: scrollDirection,

bool addRepaintBoundaries = true,
float? cacheExtent = null,
List<Widget> children = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
key: key,
scrollDirection: scrollDirection,

bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key,
scrollDirection: scrollDirection,
reverse: reverse,

bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) {
return new ListView(
key: key,

bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
key: key,
scrollDirection: scrollDirection,

SliverGridDelegate gridDelegate = null,
SliverChildDelegate childrenDelegate = null,
float? cacheExtent = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
key: key,
scrollDirection: scrollDirection,

SliverGridDelegate gridDelegate = null,
SliverChildDelegate childrenDelegate = null,
float? cacheExtent = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) {
return new GridView(
key: key,

bool addRepaintBoundaries = true,
float? cacheExtent = null,
List<Widget> children = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
key: key,
scrollDirection: scrollDirection,

bool addRepaintBoundaries = true,
float? cacheExtent = null,
List<Widget> children = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) {
return new GridView(
key: key,

bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
List<Widget> children = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(
key: key,
scrollDirection: scrollDirection,

bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
List<Widget> children = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) {
return new GridView(
key: key,

45
Runtime/widgets/scrollable.cs


using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using UnityEngine;
namespace Unity.UIWidgets.widgets {
public delegate Widget ViewportBuilder(BuildContext context, ViewportOffset position);

ScrollController controller = null,
ScrollPhysics physics = null,
ViewportBuilder viewportBuilder = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key) {
D.assert(viewportBuilder != null);

D.assert(this._hold == null);
D.assert(this._drag == null);
}
float _targetScrollOffsetForPointerScroll(PointerScrollEvent e) {
float delta = this.widget.axis == Axis.horizontal ? e.delta.dx : e.delta.dy;
return Mathf.Min(Mathf.Max(this.position.pixels + delta, this.position.minScrollExtent),
this.position.maxScrollExtent);
}
void _receivedPointerSignal(PointerSignalEvent e) {
if (e is PointerScrollEvent && this.position != null) {
float targetScrollOffset = this._targetScrollOffsetForPointerScroll(e as PointerScrollEvent);
if (targetScrollOffset != this.position.pixels) {
GestureBinding.instance.pointerSignalResolver.register(e, this._handlePointerScroll);
}
}
}
void _handlePointerScroll(PointerEvent e) {
D.assert(e is PointerScrollEvent);
float targetScrollOffset = this._targetScrollOffsetForPointerScroll(e as PointerScrollEvent);
if (targetScrollOffset != this.position.pixels) {
this.position.jumpTo(targetScrollOffset);
}
}
void _disposeHold() {
this._hold = null;

Widget result = new _ScrollableScope(
scrollable: this,
position: this.position,
child: new RawGestureDetector(
key: this._gestureDetectorKey,
gestures: this._gestureRecognizers,
behavior: HitTestBehavior.opaque,
child: new IgnorePointer(
key: this._ignorePointerKey,
ignoring: this._shouldIgnorePointer,
child: this.widget.viewportBuilder(context, this.position)
child: new Listener(
onPointerSignal: this._receivedPointerSignal,
child: new RawGestureDetector(
key: this._gestureDetectorKey,
gestures: this._gestureRecognizers,
behavior: HitTestBehavior.opaque,
child: new IgnorePointer(
key: this._ignorePointerKey,
ignoring: this._shouldIgnorePointer,
child: this.widget.viewportBuilder(context, this.position)
)
)
)
);

4
Runtime/widgets/single_child_scroll_view.cs


ScrollPhysics physics = null,
ScrollController controller = null,
Widget child = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.down
DragStartBehavior dragStartBehavior = DragStartBehavior.start
) : base(key: key) {
D.assert(!(controller != null && primary == true),
() => "Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. " +

return 0.0f;
}
protected override float computeMaxIntrinsicHeight(float width) {
protected internal override float computeMaxIntrinsicHeight(float width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(width);
}

13
Runtime/widgets/text.cs


public Text(string data,
Key key = null,
TextStyle style = null,
StrutStyle strutStyle = null,
D.assert(data != null);
D.assert(data != null, () => "A non-null string must be provided to a Text widget.");
this.strutStyle = strutStyle;
this.textAlign = textAlign;
this.softWrap = softWrap;
this.overflow = overflow;

Text(TextSpan textSpan,
Key key = null,
TextStyle style = null,
StrutStyle strutStyle = null,
D.assert(textSpan != null);
D.assert(textSpan != null, () => "A non-null TextSpan must be provided to a Text.rich widget.");
this.strutStyle = strutStyle;
this.textAlign = textAlign;
this.softWrap = softWrap;
this.overflow = overflow;

public static Text rich(TextSpan textSpan,
Key key = null,
TextStyle style = null,
StrutStyle strutStyle = null,
TextAlign? textAlign = null,
bool? softWrap = null,
TextOverflow? overflow = null,

textSpan, key,
style,
strutStyle,
textAlign,
softWrap,
overflow,

public readonly TextStyle style;
public readonly StrutStyle strutStyle;
public readonly TextAlign? textAlign;
public readonly bool? softWrap;

overflow: this.overflow ?? defaultTextStyle.overflow,
textScaleFactor: this.textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
maxLines: this.maxLines ?? defaultTextStyle.maxLines,
strutStyle: this.strutStyle,
text: new TextSpan(
style: effectiveTextStyle,
text: this.data,

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存