浏览代码

Merge branch 'material' into 'master'

Material Phase 2 (fundamental layouts & widgets)

See merge request upm-packages/ui-widgets/com.unity.uiwidgets!48
/main
Shenhua Gu 6 年前
当前提交
62021509
共有 78 个文件被更改,包括 6982 次插入105 次删除
  1. 3
      Runtime/animation/tween.cs
  2. 7
      Runtime/material/button.cs
  3. 76
      Runtime/material/button_theme.cs
  4. 2
      Runtime/material/debug.cs
  5. 2
      Runtime/material/ink_splash.cs
  6. 6
      Runtime/material/ink_well.cs
  7. 33
      Runtime/material/material.cs
  8. 7
      Runtime/material/material_button.cs
  9. 90
      Runtime/material/utils.cs
  10. 130
      Runtime/rendering/proxy_box.cs
  11. 2
      Runtime/service/system_chrome.cs
  12. 122
      Runtime/widgets/basic.cs
  13. 188
      Runtime/widgets/implicit_animations.cs
  14. 34
      Runtime/widgets/transitions.cs
  15. 98
      Samples/UIWidgetSample/MaterialCanvas.cs
  16. 73
      Samples/UIWidgetSample/UIWidgetSample.unity
  17. 395
      Runtime/material/arc.cs
  18. 11
      Runtime/material/arc.cs.meta
  19. 68
      Runtime/material/button_bar.cs
  20. 11
      Runtime/material/button_bar.cs.meta
  21. 51
      Runtime/material/card.cs
  22. 11
      Runtime/material/card.cs.meta
  23. 47
      Runtime/material/divider.cs
  24. 11
      Runtime/material/divider.cs.meta
  25. 308
      Runtime/material/drawer.cs
  26. 11
      Runtime/material/drawer.cs.meta
  27. 71
      Runtime/material/drawer_header.cs
  28. 11
      Runtime/material/drawer_header.cs.meta
  29. 93
      Runtime/material/expand_icon.cs
  30. 11
      Runtime/material/expand_icon.cs.meta
  31. 319
      Runtime/material/expansion_panel.cs
  32. 11
      Runtime/material/expansion_panel.cs.meta
  33. 174
      Runtime/material/expansion_tile.cs
  34. 11
      Runtime/material/expansion_tile.cs.meta
  35. 178
      Runtime/material/flat_button.cs
  36. 11
      Runtime/material/flat_button.cs.meta
  37. 53
      Runtime/material/grid_tile.cs
  38. 11
      Runtime/material/grid_tile.cs.meta
  39. 115
      Runtime/material/icon_button.cs
  40. 11
      Runtime/material/icon_button.cs.meta
  41. 7
      Runtime/material/icons.cs
  42. 11
      Runtime/material/icons.cs.meta
  43. 205
      Runtime/material/ink_ripple.cs
  44. 11
      Runtime/material/ink_ripple.cs.meta
  45. 864
      Runtime/material/list_tile.cs
  46. 11
      Runtime/material/list_tile.cs.meta
  47. 721
      Runtime/material/mergeable_material.cs
  48. 11
      Runtime/material/mergeable_material.cs.meta
  49. 215
      Runtime/material/raised_button.cs
  50. 11
      Runtime/material/raised_button.cs.meta
  51. 106
      Runtime/material/shadows.cs
  52. 11
      Runtime/material/shadows.cs.meta
  53. 271
      Runtime/material/tooltip.cs
  54. 11
      Runtime/material/tooltip.cs.meta
  55. 51
      Runtime/painting/geometry.cs
  56. 11
      Runtime/painting/geometry.cs.meta
  57. 204
      Runtime/rendering/animated_size.cs
  58. 11
      Runtime/rendering/animated_size.cs.meta
  59. 280
      Runtime/rendering/list_body.cs
  60. 11
      Runtime/rendering/list_body.cs.meta
  61. 16
      Runtime/rendering/tweens.cs
  62. 11
      Runtime/rendering/tweens.cs.meta
  63. 20
      Runtime/utils/axis_direction.cs
  64. 11
      Runtime/utils/axis_direction.cs.meta
  65. 228
      Runtime/widgets/animated_cross_fade.cs
  66. 11
      Runtime/widgets/animated_cross_fade.cs.meta
  67. 49
      Runtime/widgets/animated_size.cs
  68. 11
      Runtime/widgets/animated_size.cs.meta
  69. 64
      Runtime/widgets/safe_area.cs
  70. 11
      Runtime/widgets/safe_area.cs.meta
  71. 452
      Runtime/widgets/single_child_scroll_view.cs
  72. 11
      Runtime/widgets/single_child_scroll_view.cs.meta
  73. 8
      Samples/MaterialSample.meta
  74. 156
      Samples/UIWidgetSample/ExpansionPanelCanvas.cs
  75. 11
      Samples/UIWidgetSample/ExpansionPanelCanvas.cs.meta
  76. 95
      Samples/MaterialSample/DividerButtonCanvas.cs
  77. 11
      Samples/MaterialSample/DividerButtonCanvas.cs.meta

3
Runtime/animation/tween.cs


public abstract class Tween<T> : Animatable<T>, IEquatable<Tween<T>> {
protected Tween(T begin, T end) {
D.assert(begin != null);
D.assert(end != null);
this.begin = begin;
this.end = end;
}

7
Runtime/material/button.cs


Clip clipBehavior = Clip.none,
MaterialTapTargetSize? materialTapTargetSize = null,
Widget child = null) : base(key: key) {
D.assert(onPressed != null);
MaterialTapTargetSize _materialTapTargetSize = materialTapTargetSize ?? MaterialTapTargetSize.padded;
shape = shape ?? new RoundedRectangleBorder();
padding = padding ?? EdgeInsets.zero;

onHighlightChanged: this._handleHighlightChanged,
splashColor: this.widget.splashColor,
highlightColor: this.widget.highlightColor,
onTap: () => this.widget.onPressed(),
onTap: () => {
if (this.widget.onPressed != null) {
this.widget.onPressed();
}
},
customBorder: this.widget.shape,
child: IconTheme.merge(
data: new IconThemeData(color: this.widget.textStyle?.color),

76
Runtime/material/button_theme.cs


}
Color getFillColor(MaterialButton button) {
public Color getFillColor(MaterialButton button) {
// todo xingwei.zhu: uncomment these when FlatButton & OutlineButton & RaisedButton are ready
// if (button is FlatButton || button is OutlineButton)
// return null;
//
//
// if (button.enabled && button is RaisedButton && this._buttonColor != null)
// return this._buttonColor;
//todo:xingwei.zhu: uncomment these when OutlineButton are ready
if (button is FlatButton /* || button is OutlineButton*/) {
return null;
}
if (button.enabled && button is RaisedButton && this._buttonColor != null) {
return this._buttonColor;
}
switch (this.getTextTheme(button)) {
case ButtonTextTheme.normal:

return Colors.white;
}
// todo xingwei.zhu: uncomment these when FlatButton & OutlineButton are ready
// if (button is FlatButton || button is OutlineButton)
// return this.colorScheme.primary;
//todo:xingwei.zhu: uncomment these when OutlineButton are ready
if (button is FlatButton /* || button is OutlineButton*/) {
return this.colorScheme.primary;
}
return Colors.black;
}
}

return button.splashColor;
}
// todo xingwei.zhu: uncomment these when FlatButton & OutlineButton & RaisedButton are ready
// if (this._splashColor != null && (button is RaisedButton || button is OutlineButton)) {
// return this._splashColor;
// }
//
// if (this._splashColor != null && button is FlatButton) {
// switch (this.getTextTheme(button)) {
// case ButtonTextTheme.normal:
// case ButtonTextTheme.accent:
// return this._splashColor;
// case ButtonTextTheme.primary:
// break;
// }
// }
//todo:xingwei.zhu: uncomment these when OutlineButton is ready
if (this._splashColor != null && (button is RaisedButton /* || button is OutlineButton*/)) {
return this._splashColor;
}
if (this._splashColor != null && button is FlatButton) {
switch (this.getTextTheme(button)) {
case ButtonTextTheme.normal:
case ButtonTextTheme.accent:
return this._splashColor;
case ButtonTextTheme.primary:
break;
}
}
return this.getTextColor(button).withOpacity(0.12);
}

return button.elevation ?? 0.0;
}
// todo xingwei.zhu: uncomment these when FlatButton are ready
// if (button is FlatButton)
// return 0.0;
if (button is FlatButton) {
return 0.0;
}
return 2.0;
}

return button.highlightElevation ?? 0.0;
}
// todo xingwei.zhu: uncomment these when FlatButton & OutlineButton are ready
// if (button is FlatButton)
// return 0.0;
if (button is FlatButton) {
return 0.0;
}
//todo:xingwei.zhu: uncomment these when OutlineButton are ready
// if (button is OutlineButton)
// return 2.0;
return 8.0;

return button.padding;
}
// todo xingwei.zhu: uncomment these when MaterialButtonWithIconMixin are ready
// if (button is MaterialButtonWithIconMixin)
// return const EdgeInsetsDirectional.only(start: 12.0, end: 16.0);
if (button is MaterialButtonWithIconMixin) {
return EdgeInsets.fromLTRB(12.0, 0.0, 16.0, 0.0);
}
if (this._padding != null) {
return this._padding;

2
Runtime/material/debug.cs


message += "The specific widget that could not find a Material ancestor was:";
message += context.widget.toString();
message += context.widget.ToString();
List<Widget> ancestors = new List<Widget>();
context.visitAncestorElements((Element element) => {

2
Runtime/material/ink_splash.cs


}
}
//todo xingwei.zhu: remove this condition when drawCircle bug fixed (when radius.value == 0)
//todo:xingwei.zhu: remove this condition when drawCircle bug fixed (when radius.value == 0)
if (this._radius.value != 0) {
canvas.drawCircle(center, this._radius.value, paint);
}

6
Runtime/material/ink_well.cs


onDoubleTap: onDoubleTap,
onLongPress: onLongPress,
onTapDown: onTapDown,
onTapCancel: () => onTapCancel(),
onTapCancel: () => {
if (onTapCancel != null) {
onTapCancel();
}
},
onHighlightChanged: onHighlightChanged,
containedInkWell: true,
highlightColor: highlightColor,

33
Runtime/material/material.cs


ShapeBorder shape = this._getShape();
//todo xingwei.zhu: add support for transparentInterior Material
D.assert(false, "material widget is not completely implemented yet.");
return null;
// return this._transparentInterior(
// shape: shape,
// clipBehavior: this.widget.clipBehavior,
// contents: contents);
return _transparentInterior(
shape: shape,
clipBehavior: this.widget.clipBehavior,
contents: contents);
}
return new _MaterialInterior(

color: backgroundColor,
shadowColor: this.widget.shadowColor,
child: contents
);
}
static Widget _transparentInterior(
ShapeBorder shape = null,
Clip? clipBehavior = null,
Widget contents = null) {
_ShapeBorderPaint child = new _ShapeBorderPaint(
child: contents,
shape: shape);
if (clipBehavior == Clip.none) {
return child;
}
return new ClipPath(
child: child,
clipper: new ShapeBorderClipper(shape: shape),
clipBehavior: clipBehavior ?? Clip.none
);
}

protected abstract void paintFeature(Canvas canvas, Matrix3 transform);
public string toString() {
public override string ToString() {
return this.GetType() + "";
}
}

7
Runtime/material/material_button.cs


double? disabledElevation = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
Clip clipBehavior = Clip.none,
Clip? clipBehavior = Clip.none,
MaterialTapTargetSize? materialTapTargetSize = null,
TimeSpan? animationDuration = null,
double? minWidth = null,

D.assert(onPressed != null);
this.onPressed = onPressed;
this.onHighlightChanged = onHighlightChanged;
this.textTheme = textTheme;

base.debugFillProperties(properties);
properties.add(new FlagProperty("enabled", value: this.enabled, ifFalse: "disabled"));
}
}
public interface MaterialButtonWithIconMixin {
}
}

90
Runtime/material/utils.cs


}
}
public static class InkRippleUtils {
public static readonly TimeSpan _kUnconfirmedRippleDuration = new TimeSpan(0, 0, 1);
public static readonly TimeSpan _kFadeInDuration = new TimeSpan(0, 0, 0, 0, 75);
public static readonly TimeSpan _kRadiusDuration = new TimeSpan(0, 0, 0, 0, 225);
public static readonly TimeSpan _kFadeOutDuration = new TimeSpan(0, 0, 0, 0, 375);
public static readonly TimeSpan _kCancelDuration = new TimeSpan(0, 0, 0, 0, 75);
public const double _kFadeOutIntervalStart = 225.0 / 375.0;
public static RectCallback _getClipCallback(RenderBox referenceBox, bool containedInkWell,
RectCallback rectCallback) {
if (rectCallback != null) {
D.assert(containedInkWell);
return rectCallback;
}
if (containedInkWell) {
return () => Offset.zero & referenceBox.size;
}
return null;
}
public static double _getTargetRadius(RenderBox referenceBox, bool containedInkWell, RectCallback rectCallback,
Offset position) {
Size size = rectCallback != null ? rectCallback().size : referenceBox.size;
double d1 = size.bottomRight(Offset.zero).distance;
double d2 = (size.topRight(Offset.zero) - size.bottomLeft(Offset.zero)).distance;
return Math.Max(d1, d2) / 2.0;
}
}
public static class ScrollbarUtils {
public static readonly TimeSpan _kScrollbarFadeDuration = TimeSpan.FromMilliseconds(300);

}
public static class ArcUtils {
public const double _kOnAxisDelta = 2.0;
public static readonly List<_Diagonal> _allDiagonals = new List<_Diagonal> {
new _Diagonal(_CornerId.topLeft, _CornerId.bottomRight),
new _Diagonal(_CornerId.bottomRight, _CornerId.topLeft),
new _Diagonal(_CornerId.topRight, _CornerId.bottomLeft),
new _Diagonal(_CornerId.bottomLeft, _CornerId.topRight)
};
public delegate double _KeyFunc<T>(T input);
public static T _maxBy<T>(List<T> input, _KeyFunc<T> keyFunc) {
T maxValue = default(T);
double? maxKey = null;
foreach (T value in input) {
double key = keyFunc(value);
if (maxKey == null || key > maxKey) {
maxValue = value;
maxKey = key;
}
}
return maxValue;
}
}
public static class ExpansionTileUtils {
public static readonly TimeSpan _kExpand = new TimeSpan(0, 0, 0, 0, 200);
}
public static class ExpansionPanelUtils {
public const double _kPanelHeaderCollapsedHeight = 48.0;
public const double _kPanelHeaderExpandedHeight = 64.0;
}
public static class IconButtonUtils {
public const double _kMinButtonSize = 48.0;
}
public static class DrawerHeaderUtils {
public const double _kDrawerHeaderHeight = 160.0 + 1.0;
}
public static class DrawerUtils {
public const double _kWidth = 304.0;
public const double _kEdgeDragWidth = 20.0;
public const double _kMinFlingVelocity = 365.0;
public static readonly TimeSpan _kBaseSettleDuration = new TimeSpan(0, 0, 0, 0, 246);
}
public static class TooltipUtils {
public static readonly TimeSpan _kFadeDuration = new TimeSpan(0, 0, 0, 0, 200);
public static readonly TimeSpan _kShowDuration = new TimeSpan(0, 0, 0, 0, 1500);
}
}

130
Runtime/rendering/proxy_box.cs


public abstract bool shouldReclip(CustomClipper<T> oldClipper);
public string toString() {
public override string ToString() {
return this.GetType() + "";
}
}

return this._clipper?.getApproximateClipRect(this.size) ?? Offset.zero & this.size;
}
Paint _debugPaint;
TextPainter _debugText;
protected Paint _debugPaint;
protected TextPainter _debugText;
protected override void debugPaintSize(PaintingContext context, Offset offset) {
D.assert(() => {

}
}
public class RenderClipRect : _RenderCustomClip<Rect> {
public RenderClipRect(
RenderBox child = null,
CustomClipper<Rect> clipper = null,
Clip clipBehavior = Clip.antiAlias
) : base(
child: child,
clipper: clipper,
clipBehavior: clipBehavior) {
}
protected override Rect _defaultClip {
get { return Offset.zero & this.size; }
}
public override bool hitTest(HitTestResult result, Offset position = null) {
if (this._clipper != null) {
this._updateClip();
D.assert(this._clip != null);
if (!this._clip.contains(position)) {
return false;
}
}
return base.hitTest(result, position: position);
}
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
this._updateClip();
context.pushClipRect(this.needsCompositing, offset, this._clip,
base.paint, clipBehavior: this.clipBehavior);
}
}
protected override void debugPaintSize(PaintingContext context, Offset offset) {
D.assert(() => {
if (this.child != null) {
base.debugPaintSize(context, offset);
context.canvas.drawRect(this._clip.shift(offset), this._debugPaint);
this._debugText.paint(context.canvas,
offset + new Offset(this._clip.width / 8.0,
-(this._debugText.text.style.fontSize ?? 0.0) * 1.1));
}
return true;
});
}
}
public class RenderClipPath : _RenderCustomClip<Path> {
public RenderClipPath(
RenderBox child = null,
CustomClipper<Path> clipper = null,
Clip clipBehavior = Clip.antiAlias
) : base(child: child, clipper: clipper, clipBehavior: clipBehavior) {
D.assert(clipBehavior != Clip.none);
}
protected override Path _defaultClip {
get {
var path = new Path();
path.addRect(Offset.zero & this.size);
return path;
}
}
public override bool hitTest(HitTestResult result, Offset position = null) {
if (this._clipper != null) {
this._updateClip();
D.assert(this._clip != null);
if (!this._clip.contains(position)) {
return false;
}
}
return base.hitTest(result, position: position);
}
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
this._updateClip();
//todo:xingwei.zhu pushClipPath()
// context.pushClipPath(this.needsCompositing, offset, Offset.zero & this.size,
// this._clip, base.paint, clipBehavior: this.clipBehavior);
base.paint(context, offset);
}
}
protected override void debugPaintSize(PaintingContext context, Offset offset) {
D.assert(() => {
if (this.child != null) {
base.debugPaintSize(context, offset);
Path offsetPath = new Path();
offsetPath.addPath(this._clip, offset);
context.canvas.drawPath(offsetPath, this._debugPaint);
this._debugText.paint(context.canvas, offset);
}
return true;
});
}
}
public abstract class _RenderPhysicalModelBase<T> : _RenderCustomClip<T> where T : class {
public _RenderPhysicalModelBase(
RenderBox child = null,

return base.hitTest(result, position: position);
}
//todo:xingwei.zhu: implementation shadow + compositeLayer
//todo:xingwei.zhu: implementation shadow + compositeLayer (issue: no color when composite)
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
this._updateClip();

this.elevation,
this.color.alpha != 0xFF
);*/
}
if (this.needsCompositing) {
ContainerLayer container = new ContainerLayer();
context.pushLayer(container, base.paint, offset, childPaintBounds: offsetBounds);
return;
}
Paint paint = new Paint {color = this.color};

return base.hitTest(result, position: position);
}
//todo:xingwei.zhu: implementation shadow + compositeLayer
//todo:xingwei.zhu: implementation shadow + compositeLayer (issue: no color when composite)
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
this._updateClip();

// this.color.alpha != 0xFF,
// );
// }
if (this.needsCompositing) {
ContainerLayer container = new ContainerLayer();
context.pushLayer(container, base.paint, offset, childPaintBounds: offsetBounds);
return;
}
Paint paint = new Paint {color = this.color, style = PaintingStyle.fill};
canvas.drawPath(offsetPath, paint);
context.clipPathAndPaint(offsetPath, this.clipBehavior,

2
Runtime/service/system_chrome.cs


};
}
public string toString() {
public override string ToString() {
return this._toMap().ToString();
}

122
Runtime/widgets/basic.cs


using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.utils;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;

}
}
public class ClipRect : SingleChildRenderObjectWidget {
public ClipRect(
Key key = null,
CustomClipper<Rect> clipper = null,
Clip clipBehavior = Clip.hardEdge,
Widget child = null
) : base(key: key, child: child) {
this.clipper = clipper;
this.clipBehavior = clipBehavior;
}
public readonly CustomClipper<Rect> clipper;
public readonly Clip clipBehavior;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderClipRect(
clipper: this.clipper,
clipBehavior: this.clipBehavior);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
RenderClipRect _renderObject = (RenderClipRect) renderObject;
_renderObject.clipper = this.clipper;
}
public override void didUnmountRenderObject(RenderObject renderObject) {
RenderClipRect _renderObject = (RenderClipRect) renderObject;
_renderObject.clipper = null;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<CustomClipper<Rect>>("clipper", this.clipper, defaultValue: null));
}
}
public class ClipPath : SingleChildRenderObjectWidget {
public ClipPath(
Key key = null,
CustomClipper<Path> clipper = null,
Clip clipBehavior = Clip.antiAlias,
Widget child = null
) : base(key: key, child: child) {
this.clipper = clipper;
this.clipBehavior = clipBehavior;
}
public readonly CustomClipper<Path> clipper;
public readonly Clip clipBehavior;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderClipPath(clipper: this.clipper, clipBehavior: this.clipBehavior);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
RenderClipPath _renderObject = (RenderClipPath) renderObject;
_renderObject.clipper = this.clipper;
}
public override void didUnmountRenderObject(RenderObject renderObject) {
RenderClipPath _renderObject = (RenderClipPath) renderObject;
_renderObject.clipper = null;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<CustomClipper<Path>>("clipper", this.clipper, defaultValue: null));
}
}
public class LimitedBox : SingleChildRenderObjectWidget {
public LimitedBox(
Key key = null,

}
}
public class ListBody : MultiChildRenderObjectWidget {
public ListBody(
Key key = null,
Axis mainAxis = Axis.vertical,
bool reverse = false,
List<Widget> children = null
) : base(key: key, children: children ?? new List<Widget>()) {
this.mainAxis = mainAxis;
this.reverse = reverse;
}
public readonly Axis mainAxis;
public readonly bool reverse;
AxisDirection _getDirection(BuildContext context) {
return AxisDirectionUtils.getAxisDirectionFromAxisReverseAndDirectionality(context, this.mainAxis,
this.reverse) ?? AxisDirection.right;
}
public override RenderObject createRenderObject(BuildContext context) {
return new RenderListBody(
axisDirection: this._getDirection(context));
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
RenderListBody _renderObject = (RenderListBody) renderObject;
_renderObject.axisDirection = this._getDirection(context);
}
}
public class Stack : MultiChildRenderObjectWidget {
public Stack(
Key key = null,

properties.add(new IntProperty("flex", this.flex));
}
}
public class Expanded : Flexible {
public Expanded(
Key key = null,
int flex = 1,
Widget child = null
) : base(key: key, flex: flex, fit: FlexFit.tight, child: child) {
D.assert(child != null);
}
}
public class PhysicalModel : SingleChildRenderObjectWidget {
public PhysicalModel(

188
Runtime/widgets/implicit_animations.cs


}
}
public class DecorationTween : Tween<Decoration> {
public DecorationTween(
Decoration begin = null,
Decoration end = null) : base(begin: begin, end: end) {
}
public override Decoration lerp(double t) {
return Decoration.lerp(this.begin, this.end, t);
}
}
public class EdgeInsetsTween : Tween<EdgeInsets> {
public EdgeInsetsTween(
EdgeInsets begin = null,
EdgeInsets end = null) : base(begin: begin, end: end) {
}
public override EdgeInsets lerp(double t) {
return EdgeInsets.lerp(this.begin, this.end, t);
}
}
public class BorderRadiusTween : Tween<BorderRadius> {
public BorderRadiusTween(
BorderRadius begin = null,

public override BorderRadius lerp(double t) {
return BorderRadius.lerp(this.begin, this.end, t);
}
}
public class BorderTween : Tween<Border> {
public BorderTween(
Border begin = null,
Border end = null) : base(begin: begin, end: end) {
}
public override Border lerp(double t) {
return Border.lerp(this.begin, this.end, t);
}
}
public class Matrix3Tween : Tween<Matrix3> {
public Matrix3Tween(
Matrix3 begin = null,
Matrix3 end = null) : base(begin: begin, end: end) {
}
//todo:xingwei.zhu implement full matrix3 lerp
public override Matrix3 lerp(double t) {
D.assert(this.begin != null);
D.assert(this.end != null);
return t < 0.5 ? this.begin : this.end;
}
}

void _handleAnimationChanged() {
this.setState(() => { });
}
}
public class AnimatedContainer : ImplicitlyAnimatedWidget {
public AnimatedContainer(
Key key = null,
Alignment alignment = null,
EdgeInsets padding = null,
Color color = null,
Decoration decoration = null,
Decoration foregroundDecoration = null,
double? width = null,
double? height = null,
BoxConstraints constraints = null,
EdgeInsets margin = null,
Matrix3 transform = null,
Widget child = null,
Curve curve = null,
TimeSpan? duration = null
) : base(key: key, curve: curve ?? Curves.linear, duration: duration) {
D.assert(duration != null);
D.assert(margin == null || margin.isNonNegative);
D.assert(padding == null || padding.isNonNegative);
D.assert(decoration == null || decoration.debugAssertIsValid());
D.assert(constraints == null || constraints.debugAssertIsValid());
D.assert(color == null || decoration == null,
"Cannot provide both a color and a decoration\n" +
"The color argument is just a shorthand for \"decoration: new BoxDecoration(backgroundColor: color)\".");
this.alignment = alignment;
this.padding = padding;
this.foregroundDecoration = foregroundDecoration;
this.margin = margin;
this.transform = transform;
this.child = child;
this.decoration = decoration ?? (color != null ? new BoxDecoration(color: color) : null);
this.constraints =
(width != null || height != null)
? constraints?.tighten(width: width, height: height)
?? BoxConstraints.tightFor(width: width, height: height)
: constraints;
}
public readonly Widget child;
public readonly Alignment alignment;
public readonly EdgeInsets padding;
public readonly Decoration decoration;
public readonly Decoration foregroundDecoration;
public readonly BoxConstraints constraints;
public readonly EdgeInsets margin;
public readonly Matrix3 transform;
public override State createState() {
return new _AnimatedContainerState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment, showName: false,
defaultValue: null));
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", this.padding, defaultValue: null));
properties.add(new DiagnosticsProperty<Decoration>("bg", this.decoration, defaultValue: null));
properties.add(
new DiagnosticsProperty<Decoration>("fg", this.foregroundDecoration, defaultValue: null));
properties.add(new DiagnosticsProperty<BoxConstraints>("constraints", this.constraints,
defaultValue: null,
showName: false));
properties.add(new DiagnosticsProperty<EdgeInsets>("margin", this.margin, defaultValue: null));
properties.add(ObjectFlagProperty<Matrix3>.has("transform", this.transform));
}
}
public class _AnimatedContainerState : AnimatedWidgetBaseState<AnimatedContainer> {
AlignmentTween _alignment;
EdgeInsetsTween _padding;
DecorationTween _decoration;
DecorationTween _foregroundDecoration;
BoxConstraintsTween _constraints;
EdgeInsetsTween _margin;
Matrix3Tween _transform;
protected override void forEachTween(ITweenVisitor visitor) {
this._alignment = (AlignmentTween) visitor.visit(this, this._alignment, this.widget.alignment,
(Alignment value) => new AlignmentTween(begin: value));
this._padding = (EdgeInsetsTween) visitor.visit(this, this._padding, this.widget.padding,
(EdgeInsets value) => new EdgeInsetsTween(begin: value));
this._decoration = (DecorationTween) visitor.visit(this, this._decoration, this.widget.decoration,
(Decoration value) => new DecorationTween(begin: value));
this._foregroundDecoration = (DecorationTween) visitor.visit(this, this._foregroundDecoration,
this.widget.foregroundDecoration, (Decoration value) => new DecorationTween(begin: value));
this._constraints = (BoxConstraintsTween) visitor.visit(this, this._constraints, this.widget.constraints,
(BoxConstraints value) => new BoxConstraintsTween(begin: value));
this._margin = (EdgeInsetsTween) visitor.visit(this, this._margin, this.widget.margin,
(EdgeInsets value) => new EdgeInsetsTween(begin: value));
this._transform = (Matrix3Tween) visitor.visit(this, this._transform, this.widget.transform,
(Matrix3 value) => new Matrix3Tween(begin: value));
}
public override Widget build(BuildContext context) {
return new Container(
child: this.widget.child,
alignment: this._alignment?.evaluate(this.animation),
padding: this._padding?.evaluate(this.animation),
decoration: this._decoration?.evaluate(this.animation),
forgroundDecoration: this._foregroundDecoration?.evaluate(this.animation),
constraints: this._constraints?.evaluate(this.animation),
margin: this._margin?.evaluate(this.animation),
transfrom: this._transform?.evaluate(this.animation)
);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder description) {
base.debugFillProperties(description);
description.add(new DiagnosticsProperty<AlignmentTween>("alignment", this._alignment, showName: false,
defaultValue: null));
description.add(new DiagnosticsProperty<EdgeInsetsTween>("padding", this._padding, defaultValue: null));
description.add(new DiagnosticsProperty<DecorationTween>("bg", this._decoration, defaultValue: null));
description.add(
new DiagnosticsProperty<DecorationTween>("fg", this._foregroundDecoration, defaultValue: null));
description.add(new DiagnosticsProperty<BoxConstraintsTween>("constraints", this._constraints,
showName: false, defaultValue: null));
description.add(new DiagnosticsProperty<EdgeInsetsTween>("margin", this._margin, defaultValue: null));
description.add(ObjectFlagProperty<Matrix3Tween>.has("transform", this._transform));
}
}

34
Runtime/widgets/transitions.cs


using Unity.UIWidgets.animation;
using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;

transformHitTests: this.transformHitTests,
child: this.child
);
}
}
public class RotationTransition : AnimatedWidget {
public RotationTransition(
Key key = null,
Animation<double> turns = null,
Alignment alignment = null,
Widget child = null) : base(key: key, listenable: turns) {
D.assert(turns != null);
this.alignment = alignment ?? Alignment.center;
this.child = child;
}
public Animation<double> turns {
get { return (Animation<double>) this.listenable; }
}
public readonly Alignment alignment;
public readonly Widget child;
protected internal override Widget build(BuildContext context) {
double turnsValue = this.turns.value;
Matrix3 transform = Matrix3.makeRotate((float) (turnsValue * Math.PI * 2.0));
return new Transform(
transform: transform,
alignment: this.alignment,
child: this.child);
}
}

98
Samples/UIWidgetSample/MaterialCanvas.cs


using System.Collections.Generic;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;

public class MaterialCanvas : WidgetCanvas {
int testCaseId = 0;
List<Widget> testCases = new List<Widget> {
new MaterialButtonWidget(),
new MaterialInkWellWidget()
};
return new MaterialApp();
return this.testCases[this.testCaseId];
}
class MaterialApp : StatefulWidget {
public MaterialApp(Key key = null) : base(key) {
}
public override State createState() {
return new MaterialWidgetState();
}
class MaterialInkWellWidget : StatefulWidget {
public MaterialInkWellWidget(Key key = null) : base(key) {
class MaterialWidget : StatefulWidget {
public MaterialWidget(Key key = null) : base(key) {
}
public override State createState() {
return new MaterialWidgetState();
}
public override State createState() {
return new MaterialInkWidgetState();
}
// test-case: material button
class MaterialWidgetState : State<MaterialWidget> {
public override Widget build(BuildContext context) {
return new Material(
child: new Center(
child: new MaterialButton(
color: Colors.blue,
splashColor: new Color(0xFFFF0011),
highlightColor: new Color(0x88FF0011),
onPressed: () => { Debug.Log("pressed here"); }
class MaterialInkWidgetState : State<MaterialInkWellWidget> {
public override Widget build(BuildContext context) {
return new Material(
child: new Center(
child: new Container(
width: 30,
height: 30,
child: new InkWell(
borderRadius: BorderRadius.circular(2.0),
highlightColor: new Color(0xAAFF0000),
splashColor: new Color(0xAA0000FF),
onTap: () => { Debug.Log("on tap"); }
);
}
)
);
}
}
class MaterialButtonWidget : StatefulWidget {
public MaterialButtonWidget(Key key = null) : base(key) {
}
public override State createState() {
return new MaterialButtonWidgetState();
}
// // test-case: ink well
// class MaterialWidgetState : State<MaterialWidget> {
// public override Widget build(BuildContext context) {
// return new Material(
// child: new Center(
// child: new Container(
// width: 30,
// height: 30,
// child : new InkWell(
// borderRadius: BorderRadius.circular(2.0),
// highlightColor: new Color(0xAAFF0000),
// splashColor: new Color(0xAA0000FF),
// //radius : 20,
// onTap: () => { }
// ))
// )
// );
// }
// }
class MaterialButtonWidgetState : State<MaterialButtonWidget> {
public override Widget build(BuildContext context) {
return new Material(
child: new Center(
child: new MaterialButton(
splashColor: new Color(0xFFFF0011),
highlightColor: new Color(0x88FF0011),
onPressed: () => { Debug.Log("pressed here"); }
)
)
);
}
}
}

73
Samples/UIWidgetSample/UIWidgetSample.unity


- {fileID: 1399904531}
- {fileID: 432951246}
- {fileID: 552752111}
- {fileID: 1199742532}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1148735784}
m_CullTransparentMesh: 0
--- !u!1 &1199742531
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1199742532}
- component: {fileID: 1199742534}
- component: {fileID: 1199742533}
m_Layer: 5
m_Name: ExpansionPanel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &1199742532
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1199742531}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 304189374}
m_RootOrder: 6
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 300, y: 500}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1199742533
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1199742531}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7b7c8f92f79054eb6ae6e6749ebec2a1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Texture: {fileID: 0}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!222 &1199742534
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1199742531}
m_CullTransparentMesh: 0
--- !u!1 &1333497001
GameObject:

395
Runtime/material/arc.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.material {
public class MaterialPointArcTween : Tween<Offset> {
public MaterialPointArcTween(
Offset begin = null,
Offset end = null) : base(begin: begin, end: end) {
}
bool _dirty = true;
void _initialze() {
D.assert(this.begin != null);
D.assert(this.end != null);
Offset delta = this.end - this.begin;
double deltaX = delta.dx.abs();
double deltaY = delta.dy.abs();
double distanceFromAtoB = delta.distance;
Offset c = new Offset(this.end.dx, this.begin.dy);
double sweepAngle() {
return 2.0 * Math.Asin(distanceFromAtoB / (2.0 * this._radius));
}
if (deltaX > ArcUtils._kOnAxisDelta && deltaY > ArcUtils._kOnAxisDelta) {
if (deltaX < deltaY) {
this._radius = distanceFromAtoB * distanceFromAtoB / (c - this.begin).distance / 2.0;
this._center = new Offset(this.end.dx + this._radius * (this.begin.dx - this.end.dx).sign(),
this.end.dy);
if (this.begin.dx < this.end.dx) {
this._beginAngle = sweepAngle() * (this.begin.dy - this.end.dy).sign();
this._endAngle = 0.0;
}
else {
this._beginAngle = Math.PI + sweepAngle() * (this.end.dy - this.begin.dy).sign();
this._endAngle = Math.PI;
}
}
else {
this._radius = distanceFromAtoB * distanceFromAtoB / (c - this.end).distance / 2.0;
this._center = new Offset(this.begin.dx,
this.begin.dy + (this.end.dy - this.begin.dy).sign() * this._radius);
if (this.begin.dy < this.end.dy) {
this._beginAngle = -Math.PI / 2.0;
this._endAngle = this._beginAngle + sweepAngle() * (this.end.dx - this.begin.dx).sign();
}
else {
this._beginAngle = Math.PI / 2.0;
this._endAngle = this._beginAngle + sweepAngle() * (this.begin.dx - this.end.dx).sign();
}
}
D.assert(this._beginAngle != null);
D.assert(this._endAngle != null);
}
else {
this._beginAngle = null;
this._endAngle = null;
}
this._dirty = false;
}
public Offset center {
get {
if (this.begin == null || this.end == null) {
return null;
}
if (this._dirty) {
this._initialze();
}
return this._center;
}
}
Offset _center;
public double? radius {
get {
if (this.begin == null || this.end == null) {
return null;
}
if (this._dirty) {
this._initialze();
}
return this._radius;
}
}
double _radius;
public double? beginAngle {
get {
if (this.begin == null || this.end == null) {
return null;
}
if (this._dirty) {
this._initialze();
}
return this._beginAngle;
}
}
double? _beginAngle;
public double? endAngle {
get {
if (this.begin == null || this.end == null) {
return null;
}
if (this._dirty) {
this._initialze();
}
return this._endAngle;
}
}
double? _endAngle;
public new Offset begin {
get { return base.begin; }
set {
if (value != base.begin) {
base.begin = value;
this._dirty = true;
}
}
}
public new Offset end {
get { return base.end; }
set {
if (value != base.end) {
base.end = value;
this._dirty = true;
}
}
}
public override Offset lerp(double t) {
if (this._dirty) {
this._initialze();
}
if (t == 0.0) {
return this.begin;
}
if (t == 1.0) {
return this.end;
}
if (this._beginAngle == null || this._endAngle == null) {
return Offset.lerp(this.begin, this.end, t);
}
double angle = MathUtils.lerpNullableDouble(this._beginAngle, this._endAngle, t) ?? 0.0;
double x = Math.Cos(angle) * this._radius;
double y = Math.Sin(angle) * this._radius;
return this._center + new Offset(x, y);
}
public override string ToString() {
return this.GetType() + "(" + this.begin + "->" + this.end + "); center=" + this.center +
", radius=" + this.radius + ", beginAngle=" + this.beginAngle + ", endAngle=" + this.endAngle;
}
}
public enum _CornerId {
topLeft,
topRight,
bottomLeft,
bottomRight
}
public class _Diagonal {
public _Diagonal(
_CornerId beginId,
_CornerId endId) {
this.beginId = beginId;
this.endId = endId;
}
public readonly _CornerId beginId;
public readonly _CornerId endId;
}
public class MaterialRectArcTween : RectTween {
public MaterialRectArcTween(
Rect begin = null,
Rect end = null) : base(begin: begin, end: end) {
}
bool _dirty = true;
void _initialize() {
D.assert(this.begin != null);
D.assert(this.end != null);
Offset centersVector = this.end.center - this.begin.center;
_Diagonal diagonal = ArcUtils._maxBy(ArcUtils._allDiagonals,
(_Diagonal d) => this._diagonalSupport(centersVector, d));
this._beginArc = new MaterialPointArcTween(
begin: this._cornerFor(this.begin, diagonal.beginId),
end: this._cornerFor(this.end, diagonal.beginId));
this._endArc = new MaterialPointArcTween(
begin: this._cornerFor(this.begin, diagonal.endId),
end: this._cornerFor(this.end, diagonal.endId));
this._dirty = false;
}
double _diagonalSupport(Offset centersVector, _Diagonal diagonal) {
Offset delta = this._cornerFor(this.begin, diagonal.endId) - this._cornerFor(this.begin, diagonal.beginId);
double length = delta.distance;
return centersVector.dx * delta.dx / length + centersVector.dy * delta.dy / length;
}
Offset _cornerFor(Rect rect, _CornerId id) {
switch (id) {
case _CornerId.topLeft: return rect.topLeft;
case _CornerId.topRight: return rect.topRight;
case _CornerId.bottomLeft: return rect.bottomLeft;
case _CornerId.bottomRight: return rect.bottomRight;
}
return Offset.zero;
}
public MaterialPointArcTween beginArc {
get {
if (this.begin == null) {
return null;
}
if (this._dirty) {
this._initialize();
}
return this._beginArc;
}
}
MaterialPointArcTween _beginArc;
public MaterialPointArcTween endArc {
get {
if (this.end == null) {
return null;
}
if (this._dirty) {
this._initialize();
}
return this._endArc;
}
}
MaterialPointArcTween _endArc;
public new Rect begin {
get { return base.begin; }
set {
if (value != base.begin) {
base.begin = value;
this._dirty = true;
}
}
}
public new Rect end {
get { return base.end; }
set {
if (value != base.end) {
base.end = value;
this._dirty = true;
}
}
}
public override Rect lerp(double t) {
if (this._dirty) {
this._initialize();
}
if (t == 0.0) {
return this.begin;
}
if (t == 1.0) {
return this.end;
}
return Rect.fromPoints(this._beginArc.lerp(t), this._endArc.lerp(t));
}
public override string ToString() {
return this.GetType() + "(" + this.begin + "->" + this.end + ")";
}
}
public class MaterialRectCenterArcTween : RectTween {
public MaterialRectCenterArcTween(
Rect begin = null,
Rect end = null) : base(begin: begin, end: end) {
}
bool _dirty = true;
void _initialize() {
D.assert(this.begin != null);
D.assert(this.end != null);
this._centerArc = new MaterialPointArcTween(
begin: this.begin.center,
end: this.end.center);
this._dirty = false;
}
public MaterialPointArcTween centerArc {
get {
if (this.begin == null || this.end == null) {
return null;
}
if (this._dirty) {
this._initialize();
}
return this._centerArc;
}
}
MaterialPointArcTween _centerArc;
public new Rect begin {
get { return base.begin; }
set {
if (value != base.begin) {
base.begin = value;
this._dirty = true;
}
}
}
public new Rect end {
get { return base.end; }
set {
if (value != base.end) {
base.end = value;
this._dirty = true;
}
}
}
public override Rect lerp(double t) {
if (this._dirty) {
this._initialize();
}
if (t == 0.0) {
return this.begin;
}
if (t == 1.0) {
return this.end;
}
Offset center = this._centerArc.lerp(t);
double width = MathUtils.lerpDouble(this.begin.width, this.end.width, t);
double height = MathUtils.lerpDouble(this.begin.height, this.end.height, t);
return Rect.fromLTWH(
center.dx - width / 2.0,
center.dy - height / 2.0,
width,
height);
}
public override string ToString() {
return this.GetType() + "(" + this.begin + "->" + this.end + "); centerArc=" + this.centerArc;
}
}
}

11
Runtime/material/arc.cs.meta


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

68
Runtime/material/button_bar.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class ButtonBar : StatelessWidget {
public ButtonBar(
Key key = null,
MainAxisAlignment alignment = MainAxisAlignment.end,
MainAxisSize mainAxisSize = MainAxisSize.max,
List<Widget> children = null
) : base(key: key) {
this.alignment = alignment;
this.mainAxisSize = mainAxisSize;
this.children = children ?? new List<Widget>();
}
public readonly MainAxisAlignment alignment;
public readonly MainAxisSize mainAxisSize;
public readonly List<Widget> children;
public override Widget build(BuildContext context) {
ButtonThemeData buttonTheme = ButtonTheme.of(context);
double paddingUnit = buttonTheme.padding.horizontal / 4.0;
List<Widget> _children = new List<Widget>();
foreach (Widget _child in this.children) {
_children.Add(
new Padding(
padding: EdgeInsets.symmetric(horizontal: paddingUnit),
child: _child
)
);
}
Widget child = new Row(
mainAxisAlignment: this.alignment,
mainAxisSize: this.mainAxisSize,
children: _children
);
switch (buttonTheme.layoutBehavior) {
case ButtonBarLayoutBehavior.padded:
return new Padding(
padding: EdgeInsets.symmetric(
vertical: 2.0 * paddingUnit,
horizontal: paddingUnit
),
child: child
);
case ButtonBarLayoutBehavior.constrained:
return new Container(
padding: EdgeInsets.symmetric(horizontal: paddingUnit),
constraints: new BoxConstraints(minHeight: 52.0),
alignment: Alignment.center,
child: child
);
}
D.assert(false);
return null;
}
}
}

11
Runtime/material/button_bar.cs.meta


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

51
Runtime/material/card.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class Card : StatelessWidget {
public Card(
Key key = null,
Color color = null,
double? elevation = null,
ShapeBorder shape = null,
EdgeInsets margin = null,
Clip clipBehavior = Clip.none,
Widget child = null) : base(key: key) {
this.color = color;
this.elevation = elevation;
this.shape = shape;
this.margin = margin ?? EdgeInsets.all(4.0);
this.clipBehavior = clipBehavior;
this.child = child;
}
public readonly Color color;
public readonly double? elevation;
public readonly ShapeBorder shape;
public readonly Clip clipBehavior;
public readonly EdgeInsets margin;
public readonly Widget child;
public override Widget build(BuildContext context) {
return new Container(
margin: this.margin ?? EdgeInsets.all(4.0),
child: new Material(
type: MaterialType.card,
color: this.color ?? Theme.of(context).cardColor,
elevation: this.elevation ?? 1.0,
shape: this.shape ?? new RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0))
),
clipBehavior: this.clipBehavior,
child: this.child)
);
}
}
}

11
Runtime/material/card.cs.meta


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

47
Runtime/material/divider.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class Divider : StatelessWidget {
public Divider(
Key key = null,
double height = 16.0,
double indent = 0.0,
Color color = null) : base(key: key) {
D.assert(height >= 0.0);
this.height = height;
this.indent = indent;
this.color = color;
}
public readonly double height;
public readonly double indent;
public readonly Color color;
public static BorderSide createBorderSide(BuildContext context, Color color = null, double width = 0.0) {
return new BorderSide(
color: color ?? Theme.of(context).dividerColor,
width: width);
}
public override Widget build(BuildContext context) {
return new SizedBox(
height: this.height,
child: new Center(
child: new Container(
height: 0.0,
margin: EdgeInsets.only(this.indent),
decoration: new BoxDecoration(
border: new Border(
bottom: createBorderSide(context, color: this.color))
)
)
)
);
}
}
}

11
Runtime/material/divider.cs.meta


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

308
Runtime/material/drawer.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public enum DrawerAlignment {
start,
end
}
public class Drawer : StatelessWidget {
public Drawer(
Key key = null,
double elevation = 16.0,
Widget child = null) : base(key: key) {
this.elevation = elevation;
this.child = child;
}
public readonly double elevation;
public readonly Widget child;
public override Widget build(BuildContext context) {
return new ConstrainedBox(
constraints: BoxConstraints.expand(width: DrawerUtils._kWidth),
child: new Material(
elevation: this.elevation,
child: this.child
)
);
}
}
public delegate void DrawerCallback(bool isOpened);
public class DrawerController : StatefulWidget {
public DrawerController(
GlobalKey key = null,
Widget child = null,
DrawerAlignment? alignment = null,
DrawerCallback drawerCallback = null) : base(key: key) {
D.assert(child != null);
D.assert(alignment != null);
this.child = child;
this.alignment = alignment ?? DrawerAlignment.start;
this.drawerCallback = drawerCallback;
}
public readonly Widget child;
public readonly DrawerAlignment alignment;
public readonly DrawerCallback drawerCallback;
public override State createState() {
return new DrawerControllerState();
}
}
public class DrawerControllerState : SingleTickerProviderStateMixin<DrawerController> {
public override void initState() {
base.initState();
this._controller = new AnimationController(duration: DrawerUtils._kBaseSettleDuration, vsync: this);
this._controller.addListener(this._animationChanged);
this._controller.addStatusListener(this._animationStatusChanged);
}
public override void dispose() {
this._historyEntry?.remove();
this._controller.dispose();
base.dispose();
}
void _animationChanged() {
this.setState(() => { });
}
LocalHistoryEntry _historyEntry;
readonly FocusScopeNode _focusScopeNode = new FocusScopeNode();
void _ensureHistoryEntry() {
if (this._historyEntry == null) {
ModalRoute route = ModalRoute.of(this.context);
if (route != null) {
this._historyEntry = new LocalHistoryEntry(onRemove: this._handleHistoryEntryRemoved);
route.addLocalHistoryEntry(this._historyEntry);
FocusScope.of(this.context).setFirstFocus(this._focusScopeNode);
}
}
}
void _animationStatusChanged(AnimationStatus status) {
switch (status) {
case AnimationStatus.forward:
this._ensureHistoryEntry();
break;
case AnimationStatus.reverse:
this._historyEntry?.remove();
this._historyEntry = null;
break;
case AnimationStatus.dismissed:
break;
case AnimationStatus.completed:
break;
}
}
void _handleHistoryEntryRemoved() {
this._historyEntry = null;
this.close();
}
AnimationController _controller;
void _handleDragDown(DragDownDetails details) {
this._controller.stop();
this._ensureHistoryEntry();
}
void _handleDragCancel() {
if (this._controller.isDismissed || this._controller.isAnimating) {
return;
}
if (this._controller.value < 0.5) {
this.close();
}
else {
this.open();
}
}
public readonly GlobalKey _drawerKey = GlobalKey.key();
double _width {
get {
RenderBox box = (RenderBox) this._drawerKey.currentContext?.findRenderObject();
if (box != null) {
return box.size.width;
}
return DrawerUtils._kWidth;
}
}
bool _previouslyOpened = false;
void _move(DragUpdateDetails details) {
double delta = (details.primaryDelta ?? 0) / this._width;
switch (this.widget.alignment) {
case DrawerAlignment.start:
break;
case DrawerAlignment.end:
delta = -delta;
break;
}
this._controller.setValue(this._controller.value + delta);
bool opened = this._controller.value > 0.5;
if (opened != this._previouslyOpened && this.widget.drawerCallback != null) {
this.widget.drawerCallback(opened);
}
this._previouslyOpened = opened;
}
void _settle(DragEndDetails details) {
if (this._controller.isDismissed) {
return;
}
if (details.velocity.pixelsPerSecond.dx.abs() >= DrawerUtils._kMinFlingVelocity) {
double visualVelocity = details.velocity.pixelsPerSecond.dx / DrawerUtils._kWidth;
switch (this.widget.alignment) {
case DrawerAlignment.start:
break;
case DrawerAlignment.end:
visualVelocity = -visualVelocity;
break;
}
this._controller.fling(velocity: visualVelocity);
}
else if (this._controller.value < 0.5) {
this.close();
}
else {
this.open();
}
}
public void open() {
this._controller.fling(velocity: 1.0);
if (this.widget.drawerCallback != null) {
this.widget.drawerCallback(true);
}
}
public void close() {
this._controller.fling(velocity: -1.0);
if (this.widget.drawerCallback != null) {
this.widget.drawerCallback(false);
}
}
ColorTween _color = new ColorTween(begin: Colors.transparent, end: Colors.black54);
GlobalKey _gestureDetectorKey = GlobalKey.key();
Alignment _drawerOuterAlignment {
get {
switch (this.widget.alignment) {
case DrawerAlignment.start:
return Alignment.centerLeft;
case DrawerAlignment.end:
return Alignment.centerRight;
}
return null;
}
}
Alignment _drawerInnerAlignment {
get {
switch (this.widget.alignment) {
case DrawerAlignment.start:
return Alignment.centerRight;
case DrawerAlignment.end:
return Alignment.centerLeft;
}
return null;
}
}
Widget _buildDrawer(BuildContext context) {
bool drawerIsStart = this.widget.alignment == DrawerAlignment.start;
EdgeInsets padding = MediaQuery.of(context).padding;
double dragAreaWidth = drawerIsStart ? padding.left : padding.right;
dragAreaWidth = Math.Max(dragAreaWidth, DrawerUtils._kEdgeDragWidth);
if (this._controller.status == AnimationStatus.dismissed) {
return new Align(
alignment: this._drawerOuterAlignment,
child: new GestureDetector(
key: this._gestureDetectorKey,
onHorizontalDragUpdate: this._move,
onHorizontalDragEnd: this._settle,
behavior: HitTestBehavior.translucent,
child: new Container(width: dragAreaWidth)
)
);
}
else {
return new GestureDetector(
key: this._gestureDetectorKey,
onHorizontalDragDown: this._handleDragDown,
onHorizontalDragUpdate: this._move,
onHorizontalDragEnd: this._settle,
onHorizontalDragCancel: this._handleDragCancel,
child: new RepaintBoundary(
child: new Stack(
children: new List<Widget> {
new GestureDetector(
onTap: this.close,
child: new Container(
color: this._color.evaluate(this._controller)
)
),
new Align(
alignment: this._drawerOuterAlignment,
child: new Align(
alignment: this._drawerInnerAlignment,
widthFactor: this._controller.value,
child: new RepaintBoundary(
child: new FocusScope(
key: this._drawerKey,
node: this._focusScopeNode,
child: this.widget.child)
)
)
)
}
)
)
);
}
}
public override Widget build(BuildContext context) {
return new ListTileTheme(
style: ListTileStyle.drawer,
child: this._buildDrawer(context));
}
}
}

11
Runtime/material/drawer.cs.meta


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

71
Runtime/material/drawer_header.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class DrawerHeader : StatelessWidget {
public DrawerHeader(
Key key = null,
Decoration decoration = null,
EdgeInsets margin = null,
EdgeInsets padding = null,
TimeSpan? duration = null,
Curve curve = null,
Widget child = null
) : base(key: key) {
D.assert(child != null);
this.decoration = decoration;
this.margin = margin ?? EdgeInsets.only(bottom: 8.0);
this.padding = padding ?? EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0);
this.duration = duration ?? new TimeSpan(0, 0, 0, 0, 250);
this.curve = curve ?? Curves.fastOutSlowIn;
this.child = child;
}
public readonly Decoration decoration;
public readonly EdgeInsets padding;
public readonly EdgeInsets margin;
public readonly TimeSpan duration;
public readonly Curve curve;
public readonly Widget child;
public override Widget build(BuildContext context) {
D.assert(MaterialDebug.debugCheckHasMaterial(context));
ThemeData theme = Theme.of(context);
double statusBarHeight = MediaQuery.of(context).padding.top;
return new Container(
height: statusBarHeight + DrawerHeaderUtils._kDrawerHeaderHeight,
margin: this.margin,
decoration: new BoxDecoration(
border: new Border(
bottom: Divider.createBorderSide(context)
)
),
child: new AnimatedContainer(
padding: this.padding.add(EdgeInsets.only(top: statusBarHeight)),
decoration: this.decoration,
duration: this.duration,
curve: this.curve,
child: this.child == null
? null
: new DefaultTextStyle(
style: theme.textTheme.body2,
child: MediaQuery.removePadding(
context: context,
removeTop: true,
child: this.child)
)
)
);
}
}
}

11
Runtime/material/drawer_header.cs.meta


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

93
Runtime/material/expand_icon.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class ExpandIcon : StatefulWidget {
public ExpandIcon(
Key key = null,
bool isExpanded = false,
double size = 24.0,
ValueChanged<bool> onPressed = null,
EdgeInsets padding = null) : base(key: key) {
this.isExpanded = isExpanded;
this.size = size;
this.onPressed = onPressed;
this.padding = padding ?? EdgeInsets.all(8.0);
}
public readonly bool isExpanded;
public readonly double size;
public readonly ValueChanged<bool> onPressed;
public readonly EdgeInsets padding;
public override State createState() {
return new _ExpandIconState();
}
}
public class _ExpandIconState : SingleTickerProviderStateMixin<ExpandIcon> {
AnimationController _controller;
Animation<double> _iconTurns;
static readonly Animatable<double> _iconTurnTween =
new DoubleTween(begin: 0.0, end: 0.5).chain(new CurveTween(curve: Curves.fastOutSlowIn));
public override void initState() {
base.initState();
this._controller = new AnimationController(duration: ThemeUtils.kThemeAnimationDuration, vsync: this);
this._iconTurns = this._controller.drive(_iconTurnTween);
if (this.widget.isExpanded) {
this._controller.setValue(Math.PI);
}
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
ExpandIcon _oldWidget = (ExpandIcon) oldWidget;
if (this.widget.isExpanded != _oldWidget.isExpanded) {
if (this.widget.isExpanded) {
this._controller.forward();
}
else {
this._controller.reverse();
}
}
}
void _handlePressed() {
if (this.widget.onPressed != null) {
this.widget.onPressed(this.widget.isExpanded);
}
}
public override Widget build(BuildContext context) {
D.assert(MaterialDebug.debugCheckHasMaterial(context));
ThemeData theme = Theme.of(context);
return new IconButton(
padding: this.widget.padding,
color: theme.brightness == Brightness.dark ? Colors.white54 : Colors.black54,
onPressed: this.widget.onPressed == null ? (VoidCallback) null : this._handlePressed,
icon: new RotationTransition(
turns: this._iconTurns,
child: new Icon(Icons.expand_more))
);
}
}
}

11
Runtime/material/expand_icon.cs.meta


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

319
Runtime/material/expansion_panel.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
class _SaltedKey<S, V> : LocalKey {
public _SaltedKey(
S salt,
V value) {
this.salt = salt;
this.value = value;
}
public readonly S salt;
public readonly V value;
public bool Equals(_SaltedKey<S, V> other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return other.salt.Equals(this.salt)
&& other.value.Equals(this.value);
}
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((_SaltedKey<S, V>) obj);
}
public static bool operator ==(_SaltedKey<S, V> left, _SaltedKey<S, V> right) {
return Equals(left, right);
}
public static bool operator !=(_SaltedKey<S, V> left, _SaltedKey<S, V> right) {
return !Equals(left, right);
}
public override int GetHashCode() {
unchecked {
var hashCode = this.salt.GetHashCode();
hashCode = (hashCode * 397) ^ this.value.GetHashCode();
return hashCode;
}
}
public override string ToString() {
string saltString = this.salt is string ? "<\'" + this.salt + "\'>" : "<" + this.salt + ">";
string valueString = this.value is string ? "<\'" + this.value + "\'>" : "<" + this.value + ">";
return "[" + saltString + " " + valueString + "]";
}
}
public delegate void ExpansionPanelCallback(int panelIndex, bool isExpanded);
public delegate Widget ExpansionPanelHeaderBuilder(BuildContext context, bool isExpanded);
public class ExpansionPanel {
public ExpansionPanel(
ExpansionPanelHeaderBuilder headerBuilder = null,
Widget body = null,
bool isExpanded = false) {
D.assert(headerBuilder != null);
D.assert(body != null);
this.headerBuilder = headerBuilder;
this.body = body;
this.isExpanded = isExpanded;
}
public readonly ExpansionPanelHeaderBuilder headerBuilder;
public readonly Widget body;
public readonly bool isExpanded;
}
public class ExpansionPanelRadio : ExpansionPanel {
public ExpansionPanelRadio(
object value = null,
ExpansionPanelHeaderBuilder headerBuilder = null,
Widget body = null) : base(body: body, headerBuilder: headerBuilder) {
D.assert(headerBuilder != null);
D.assert(body != null);
D.assert(value != null);
this.value = value;
}
public readonly object value;
}
public class ExpansionPanelList : StatefulWidget {
public ExpansionPanelList(
Key key = null,
List<ExpansionPanel> children = null,
ExpansionPanelCallback expansionCallback = null,
TimeSpan? animationDuration = null) : base(key: key) {
this.children = children ?? new List<ExpansionPanel>();
this.expansionCallback = expansionCallback;
this.animationDuration = animationDuration ?? Constants.kThemeChangeDuration;
this._allowOnlyOnePanelOpen = false;
this.initialOpenPanelValue = null;
}
ExpansionPanelList(
Key key = null,
List<ExpansionPanel> children = null,
ExpansionPanelCallback expansionCallback = null,
TimeSpan? animationDuration = null,
object initialOpenPanelValue = null) : base(key: key) {
this.children = children ?? new List<ExpansionPanel>();
this.expansionCallback = expansionCallback;
this.animationDuration = animationDuration ?? Constants.kThemeChangeDuration;
this._allowOnlyOnePanelOpen = true;
this.initialOpenPanelValue = initialOpenPanelValue;
}
public static ExpansionPanelList radio(
Key key = null,
List<ExpansionPanelRadio> children = null,
ExpansionPanelCallback expansionCallback = null,
TimeSpan? animationDuration = null,
object initialOpenPanelValue = null) {
children = children ?? new List<ExpansionPanelRadio>();
var radio = new ExpansionPanelList(
key: key,
children: children.Cast<ExpansionPanel>().ToList(),
expansionCallback: expansionCallback,
animationDuration: animationDuration,
initialOpenPanelValue: initialOpenPanelValue
);
return radio;
}
public readonly List<ExpansionPanel> children;
public readonly ExpansionPanelCallback expansionCallback;
public readonly TimeSpan animationDuration;
public readonly bool _allowOnlyOnePanelOpen;
public readonly object initialOpenPanelValue;
public override State createState() {
return new _ExpansionPanelListState();
}
}
public class _ExpansionPanelListState : State<ExpansionPanelList> {
ExpansionPanelRadio _currentOpenPanel;
public override void initState() {
base.initState();
if (this.widget._allowOnlyOnePanelOpen) {
D.assert(this._allIdentifierUnique(), "All object identifiers are not unique!");
foreach (ExpansionPanelRadio child in this.widget.children) {
if (this.widget.initialOpenPanelValue != null &&
child.value == this.widget.initialOpenPanelValue) {
this._currentOpenPanel = child;
}
}
}
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
ExpansionPanelList _oldWidget = (ExpansionPanelList) oldWidget;
if (this.widget._allowOnlyOnePanelOpen) {
D.assert(this._allIdentifierUnique(), "All object identifiers are not unique!");
foreach (ExpansionPanelRadio newChild in this.widget.children) {
if (this.widget.initialOpenPanelValue != null &&
newChild.value == this.widget.initialOpenPanelValue) {
this._currentOpenPanel = newChild;
}
}
}
else if (_oldWidget._allowOnlyOnePanelOpen) {
this._currentOpenPanel = null;
}
}
bool _allIdentifierUnique() {
Dictionary<object, bool> identifierMap = new Dictionary<object, bool>();
foreach (ExpansionPanelRadio child in this.widget.children) {
identifierMap[child.value] = true;
}
return identifierMap.Count == this.widget.children.Count;
}
bool _isChildExpanded(int index) {
if (this.widget._allowOnlyOnePanelOpen) {
ExpansionPanelRadio radioWidget = (ExpansionPanelRadio) this.widget.children[index];
return this._currentOpenPanel?.value == radioWidget.value;
}
return this.widget.children[index].isExpanded;
}
void _handlePressed(bool isExpanded, int index) {
if (this.widget.expansionCallback != null) {
this.widget.expansionCallback(index, isExpanded);
}
if (this.widget._allowOnlyOnePanelOpen) {
ExpansionPanelRadio pressedChild = (ExpansionPanelRadio) this.widget.children[index];
for (int childIndex = 0; childIndex < this.widget.children.Count; childIndex++) {
ExpansionPanelRadio child = (ExpansionPanelRadio) this.widget.children[childIndex];
if (this.widget.expansionCallback != null && childIndex != index &&
child.value == this._currentOpenPanel?.value) {
this.widget.expansionCallback(childIndex, false);
}
}
this._currentOpenPanel = isExpanded ? null : pressedChild;
}
this.setState(() => { });
}
public override Widget build(BuildContext context) {
List<MergeableMaterialItem> items = new List<MergeableMaterialItem>();
EdgeInsets kExpandedEdgeInsets = EdgeInsets.symmetric(
vertical: ExpansionPanelUtils._kPanelHeaderExpandedHeight -
ExpansionPanelUtils._kPanelHeaderCollapsedHeight);
for (int index = 0; index < this.widget.children.Count; index++) {
int expandIndex = index;
if (this._isChildExpanded(index) && index != 0 && !this._isChildExpanded(index - 1)) {
items.Add(new MaterialGap(
key: new _SaltedKey<BuildContext, int>(context, index * 2 - 1)));
}
ExpansionPanel child = this.widget.children[index];
Row header = new Row(
children: new List<Widget> {
new Expanded(
child: new AnimatedContainer(
duration: this.widget.animationDuration,
curve: Curves.fastOutSlowIn,
margin: this._isChildExpanded(index) ? kExpandedEdgeInsets : EdgeInsets.zero,
child: new ConstrainedBox(
constraints: new BoxConstraints(
minHeight: ExpansionPanelUtils._kPanelHeaderCollapsedHeight),
child: child.headerBuilder(
context,
this._isChildExpanded(index))
)
)
),
new Container(
margin: EdgeInsets.fromLTRB(0, 0, 8, 0),
child: new ExpandIcon(
isExpanded: this._isChildExpanded(index),
padding: EdgeInsets.all(16.0),
onPressed: (bool isExpanded) => this._handlePressed(isExpanded, expandIndex)
)
)
}
);
items.Add(new MaterialSlice(
key: new _SaltedKey<BuildContext, int>(context, index * 2),
child: new Column(
children: new List<Widget> {
header,
new AnimatedCrossFade(
firstChild: new Container(height: 0.0),
secondChild: child.body,
firstCurve: new Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve: new Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: this._isChildExpanded(index)
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: this.widget.animationDuration
)
}
)
)
);
if (this._isChildExpanded(index) && index != this.widget.children.Count - 1) {
items.Add(new MaterialGap(
key: new _SaltedKey<BuildContext, int>(context, index * 2 + 1)));
}
}
return new MergeableMaterial(
hasDividers: true,
children: items);
}
}
}

11
Runtime/material/expansion_panel.cs.meta


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

174
Runtime/material/expansion_tile.cs


using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class ExpansionTile : StatefulWidget {
public ExpansionTile(
Key key = null,
Widget leading = null,
Widget title = null,
Color backgroundColor = null,
ValueChanged<bool> onExpansionChanged = null,
List<Widget> children = null,
Widget trailing = null,
bool initiallyExpanded = false
) : base(key: key) {
D.assert(title != null);
this.leading = leading;
this.title = title;
this.backgroundColor = backgroundColor;
this.onExpansionChanged = onExpansionChanged;
this.children = children ?? new List<Widget>();
this.trailing = trailing;
this.initiallyExpanded = initiallyExpanded;
}
public readonly Widget leading;
public readonly Widget title;
public readonly ValueChanged<bool> onExpansionChanged;
public readonly List<Widget> children;
public readonly Color backgroundColor;
public readonly Widget trailing;
public readonly bool initiallyExpanded;
public override State createState() {
return new _ExpansionTileState();
}
}
public class _ExpansionTileState : SingleTickerProviderStateMixin<ExpansionTile> {
static readonly Animatable<double> _easeOutTween = new CurveTween(curve: Curves.easeOut);
static readonly Animatable<double> _easeInTween = new CurveTween(curve: Curves.easeIn);
static readonly Animatable<double> _halfTween = new DoubleTween(begin: 0.0, end: 0.5);
readonly ColorTween _borderColorTween = new ColorTween();
readonly ColorTween _headerColorTween = new ColorTween();
readonly ColorTween _iconColorTween = new ColorTween();
readonly ColorTween _backgroundColorTween = new ColorTween();
AnimationController _controller;
Animation<double> _iconTurns;
Animation<double> _heightFactor;
Animation<Color> _borderColor;
Animation<Color> _headerColor;
Animation<Color> _iconColor;
Animation<Color> _backgroundColor;
bool _isExpanded = false;
public override void initState() {
base.initState();
this._controller = new AnimationController(duration: ExpansionTileUtils._kExpand, vsync: this);
this._heightFactor = this._controller.drive(_easeInTween);
this._iconTurns = this._controller.drive(_halfTween.chain(_easeInTween));
this._borderColor = this._controller.drive(this._borderColorTween.chain(_easeOutTween));
this._headerColor = this._controller.drive(this._headerColorTween.chain(_easeInTween));
this._iconColor = this._controller.drive(this._iconColorTween.chain(_easeInTween));
this._backgroundColor = this._controller.drive(this._backgroundColorTween.chain(_easeOutTween));
this._isExpanded = PageStorage.of(this.context)?.readState(this.context) == null
? this.widget.initiallyExpanded
: (bool) PageStorage.of(this.context)?.readState(this.context);
if (this._isExpanded) {
this._controller.setValue(1.0);
}
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
void _handleTap() {
this.setState(() => {
this._isExpanded = !this._isExpanded;
if (this._isExpanded) {
this._controller.forward();
}
else {
this._controller.reverse().Then(() => {
if (!this.mounted) {
return;
}
this.setState(() => { });
});
}
PageStorage.of(this.context)?.writeState(this.context, this._isExpanded);
});
if (this.widget.onExpansionChanged != null) {
this.widget.onExpansionChanged(this._isExpanded);
}
}
Widget _buildChildren(BuildContext context, Widget child) {
Color borderSideColor = this._borderColor.value ?? Colors.transparent;
Color titleColor = this._headerColor.value;
return new Container(
decoration: new BoxDecoration(
color: this._backgroundColor.value ?? Colors.transparent,
border: new Border(
top: new BorderSide(color: borderSideColor),
bottom: new BorderSide(color: borderSideColor))),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
IconTheme.merge(
data: new IconThemeData(color: this._iconColor.value),
child: new ListTile(
onTap: this._handleTap,
leading: this.widget.leading,
title: new DefaultTextStyle(
style: Theme.of(this.context).textTheme.subhead.copyWith(color: titleColor),
child: this.widget.title
),
trailing: this.widget.trailing ?? new RotationTransition(
turns: this._iconTurns,
child: new Icon(Icons.expand_more)
)
)
),
new ClipRect(
child: new Align(
heightFactor: this._heightFactor.value,
child: child)
)
}
)
);
}
public override void didChangeDependencies() {
ThemeData theme = Theme.of(this.context);
this._borderColorTween.end = theme.dividerColor;
this._headerColorTween.begin = theme.textTheme.subhead.color;
this._headerColorTween.end = theme.accentColor;
this._iconColorTween.begin = theme.unselectedWidgetColor;
this._iconColorTween.end = theme.accentColor;
this._backgroundColorTween.end = this.widget.backgroundColor;
base.didChangeDependencies();
}
public override Widget build(BuildContext context) {
bool closed = !this._isExpanded && this._controller.isDismissed;
return new AnimatedBuilder(
animation: this._controller.view,
builder: this._buildChildren,
child: closed ? null : new Column(children: this.widget.children));
}
}
}

11
Runtime/material/expansion_tile.cs.meta


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

178
Runtime/material/flat_button.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class FlatButton : MaterialButton {
public FlatButton(
Key key = null,
VoidCallback onPressed = null,
ValueChanged<bool> onHighlightChanged = null,
ButtonTextTheme? textTheme = null,
Color textColor = null,
Color disabledTextColor = null,
Color color = null,
Color disabledColor = null,
Color highlightColor = null,
Color splashColor = null,
Brightness? colorBrightness = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
Clip? clipBehavior = Clip.none,
MaterialTapTargetSize? materialTapTargetSize = null,
Widget child = null) : base(
key: key,
onPressed: onPressed,
onHighlightChanged: onHighlightChanged,
textTheme: textTheme,
textColor: textColor,
disabledTextColor: disabledTextColor,
color: color,
disabledColor: disabledColor,
highlightColor: highlightColor,
splashColor: splashColor,
colorBrightness: colorBrightness,
padding: padding,
shape: shape,
clipBehavior: clipBehavior,
materialTapTargetSize: materialTapTargetSize,
child: child) {
}
public static FlatButton icon(
Key key = null,
VoidCallback onPressed = null,
ValueChanged<bool> onHighlightChanged = null,
ButtonTextTheme? textTheme = null,
Color textColor = null,
Color disabledTextColor = null,
Color color = null,
Color disabledColor = null,
Color highlightColor = null,
Color splashColor = null,
Brightness? colorBrightness = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
Clip? clipBehavior = null,
MaterialTapTargetSize? materialTapTargetSize = null,
Widget icon = null,
Widget label = null) {
D.assert(icon != null);
D.assert(label != null);
return new _FlatButtonWithIcon(
key: key,
onPressed: onPressed,
onHighlightChanged: onHighlightChanged,
textTheme: textTheme,
textColor: textColor,
disabledTextColor: disabledTextColor,
color: color,
disabledColor: disabledColor,
highlightColor: highlightColor,
splashColor: splashColor,
colorBrightness: colorBrightness,
padding: padding,
shape: shape,
clipBehavior: clipBehavior,
materialTapTargetSize: materialTapTargetSize,
icon: icon,
label: label
);
}
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
ButtonThemeData buttonTheme = ButtonTheme.of(context);
return new RawMaterialButton(
onPressed: this.onPressed,
onHighlightChanged: this.onHighlightChanged,
clipBehavior: this.clipBehavior ?? Clip.none,
fillColor: buttonTheme.getFillColor(this),
textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)),
highlightColor: buttonTheme.getHighlightColor(this),
splashColor: buttonTheme.getSplashColor(this),
elevation: buttonTheme.getElevation(this),
highlightElevation: buttonTheme.getHighlightElevation(this),
disabledElevation: buttonTheme.getDisabledElevation(this),
padding: buttonTheme.getPadding(this),
constraints: buttonTheme.getConstraints(this),
shape: buttonTheme.getShape(this),
animationDuration: buttonTheme.getAnimationDuration(this),
materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this),
child: this.child
);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new ObjectFlagProperty<VoidCallback>("onPressed", this.onPressed, ifNull: "disabled"));
properties.add(new DiagnosticsProperty<ButtonTextTheme?>("textTheme", this.textTheme, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("textColor", this.textColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("disabledTextColor", this.disabledTextColor,
defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("color", this.color, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("disabledColor", this.disabledColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("highlightColor", this.highlightColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("splashColor", this.splashColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Brightness?>("colorBrightness", this.colorBrightness,
defaultValue: null));
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", this.padding, defaultValue: null));
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", this.shape, defaultValue: null));
properties.add(new DiagnosticsProperty<MaterialTapTargetSize?>("materialTapTargetSize",
this.materialTapTargetSize, defaultValue: null));
}
}
class _FlatButtonWithIcon : FlatButton, MaterialButtonWithIconMixin {
public _FlatButtonWithIcon(
Key key = null,
VoidCallback onPressed = null,
ValueChanged<bool> onHighlightChanged = null,
ButtonTextTheme? textTheme = null,
Color textColor = null,
Color disabledTextColor = null,
Color color = null,
Color disabledColor = null,
Color highlightColor = null,
Color splashColor = null,
Brightness? colorBrightness = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
Clip? clipBehavior = null,
MaterialTapTargetSize? materialTapTargetSize = null,
Widget icon = null,
Widget label = null) : base(
key: key,
onPressed: onPressed,
onHighlightChanged: onHighlightChanged,
textTheme: textTheme,
textColor: textColor,
disabledTextColor: disabledTextColor,
color: color,
disabledColor: disabledColor,
highlightColor: highlightColor,
splashColor: splashColor,
colorBrightness: colorBrightness,
padding: padding,
shape: shape,
clipBehavior: clipBehavior,
materialTapTargetSize: materialTapTargetSize,
child: new Row(
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
icon,
new SizedBox(width: 8.0),
label
}
)) {
D.assert(icon != null);
D.assert(label != null);
}
}
}

11
Runtime/material/flat_button.cs.meta


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

53
Runtime/material/grid_tile.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class GridTile : StatelessWidget {
public GridTile(
Key key = null,
Widget header = null,
Widget footer = null,
Widget child = null) : base(key: key) {
D.assert(child != null);
this.header = header;
this.footer = footer;
this.child = child;
}
public readonly Widget header;
public readonly Widget footer;
public readonly Widget child;
public override Widget build(BuildContext context) {
if (this.header == null && this.footer == null) {
return this.child;
}
List<Widget> children = new List<Widget> {
Positioned.fill(
child: this.child)
};
if (this.header != null) {
children.Add(new Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
child: this.header));
}
if (this.footer != null) {
children.Add(new Positioned(
left: 0.0,
bottom: 0.0,
right: 0.0,
child: this.footer));
}
return new Stack(
children: children);
}
}
}

11
Runtime/material/grid_tile.cs.meta


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

115
Runtime/material/icon_button.cs


using System;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class IconButton : StatelessWidget {
public IconButton(
Key key = null,
double iconSize = 24.0,
EdgeInsets padding = null,
Alignment alignment = null,
Widget icon = null,
Color color = null,
Color highlightColor = null,
Color splashColor = null,
Color disableColor = null,
VoidCallback onPressed = null,
string tooltip = null) : base(key: key) {
D.assert(icon != null);
this.iconSize = iconSize;
this.padding = padding ?? EdgeInsets.all(8.0);
this.alignment = alignment ?? Alignment.center;
this.icon = icon;
this.color = color;
this.highlightColor = highlightColor;
this.splashColor = splashColor;
this.disabledColor = disableColor;
this.onPressed = onPressed;
this.tooltip = tooltip;
}
public readonly double iconSize;
public readonly EdgeInsets padding;
public readonly Alignment alignment;
public readonly Widget icon;
public readonly Color color;
public readonly Color splashColor;
public readonly Color highlightColor;
public readonly Color disabledColor;
public readonly VoidCallback onPressed;
public readonly string tooltip;
public override Widget build(BuildContext context) {
D.assert(MaterialDebug.debugCheckHasMaterial(context));
Color currentColor;
if (this.onPressed != null) {
currentColor = this.color;
}
else {
currentColor = this.disabledColor ?? Theme.of(context).disabledColor;
}
Widget result = new ConstrainedBox(
constraints: new BoxConstraints(minWidth: IconButtonUtils._kMinButtonSize,
minHeight: IconButtonUtils._kMinButtonSize),
child: new Padding(
padding: this.padding,
child: new SizedBox(
height: this.iconSize,
width: this.iconSize,
child: new Align(
alignment: this.alignment,
child: IconTheme.merge(
data: new IconThemeData(
size: this.iconSize,
color: currentColor),
child: this.icon)
)
)
)
);
if (this.tooltip != null) {
result = new Tooltip(
message: this.tooltip,
child: result);
}
return new InkResponse(
onTap: () => {
if (this.onPressed != null) {
this.onPressed();
}
},
child: result,
highlightColor: this.highlightColor ?? Theme.of(context).highlightColor,
splashColor: this.splashColor ?? Theme.of(context).splashColor,
radius: Math.Max(
Material.defaultSplashRadius,
(this.iconSize + Math.Min(this.padding.horizontal, this.padding.vertical)) * 0.7)
);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Widget>("icon", this.icon, showName: false));
properties.add(new ObjectFlagProperty<VoidCallback>("onPressed", this.onPressed, ifNull: "disabled"));
properties.add(new StringProperty("tooltip", this.tooltip, defaultValue: null, quoted: false));
}
}
}

11
Runtime/material/icon_button.cs.meta


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

7
Runtime/material/icons.cs


using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public static class Icons {
public static readonly IconData expand_more = new IconData(0xe313, fontFamily: "Material Icons");
}
}

11
Runtime/material/icons.cs.meta


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

205
Runtime/material/ink_ripple.cs


using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.material {
public class _InkRippleFactory : InteractiveInkFeatureFactory {
public _InkRippleFactory() {
}
public override InteractiveInkFeature create(
MaterialInkController controller = null,
RenderBox referenceBox = null,
Offset position = null,
Color color = null,
bool containedInkWell = false,
RectCallback rectCallback = null,
BorderRadius borderRadius = null,
ShapeBorder customBorder = null,
double? radius = null,
VoidCallback onRemoved = null
) {
D.assert(controller != null);
D.assert(referenceBox != null);
D.assert(position != null);
D.assert(color != null);
return new InkRipple(
controller: controller,
referenceBox: referenceBox,
position: position,
color: color,
containedInkWell: containedInkWell,
rectCallback: rectCallback,
borderRadius: borderRadius,
customBorder: customBorder,
radius: radius,
onRemoved: onRemoved);
}
}
public class InkRipple : InteractiveInkFeature {
public InkRipple(
MaterialInkController controller = null,
RenderBox referenceBox = null,
Offset position = null,
Color color = null,
bool containedInkWell = false,
RectCallback rectCallback = null,
BorderRadius borderRadius = null,
ShapeBorder customBorder = null,
double? radius = null,
VoidCallback onRemoved = null
) : base(
controller: controller,
referenceBox: referenceBox,
color: color,
onRemoved: onRemoved) {
D.assert(controller != null);
D.assert(referenceBox != null);
D.assert(color != null);
D.assert(position != null);
this._position = position;
this._borderRadius = borderRadius ?? BorderRadius.zero;
this._customBorder = customBorder;
this._targetRadius =
radius ?? InkRippleUtils._getTargetRadius(referenceBox, containedInkWell, rectCallback, position);
this._clipCallback = InkRippleUtils._getClipCallback(referenceBox, containedInkWell, rectCallback);
D.assert(this._borderRadius != null);
this._fadeInController =
new AnimationController(duration: InkRippleUtils._kFadeInDuration, vsync: controller.vsync);
this._fadeInController.addListener(controller.markNeedsPaint);
this._fadeInController.forward();
this._fadeIn = this._fadeInController.drive(new IntTween(
begin: 0,
end: color.alpha
));
this._radiusController = new AnimationController(
duration: InkRippleUtils._kUnconfirmedRippleDuration,
vsync: controller.vsync);
this._radiusController.addListener(controller.markNeedsPaint);
this._radiusController.forward();
this._radius = this._radiusController.drive(new DoubleTween(
begin: this._targetRadius * 0.30,
end: this._targetRadius + 5.0
).chain(_easeCurveTween)
);
this._fadeOutController = new AnimationController(
duration: InkRippleUtils._kFadeOutDuration,
vsync: controller.vsync);
this._fadeOutController.addListener(controller.markNeedsPaint);
this._fadeOutController.addStatusListener(this._handleAlphaStatusChanged);
this._fadeOut = this._fadeOutController.drive(new IntTween(
begin: color.alpha,
end: 0
).chain(_fadeOutIntervalTween)
);
controller.addInkFeature(this);
}
readonly Offset _position;
readonly BorderRadius _borderRadius;
readonly ShapeBorder _customBorder;
readonly double _targetRadius;
readonly RectCallback _clipCallback;
Animation<double> _radius;
AnimationController _radiusController;
Animation<int> _fadeIn;
AnimationController _fadeInController;
Animation<int> _fadeOut;
AnimationController _fadeOutController;
public static InteractiveInkFeatureFactory splashFactory = new _InkRippleFactory();
static readonly Animatable<double> _easeCurveTween = new CurveTween(curve: Curves.ease);
static readonly Animatable<double> _fadeOutIntervalTween =
new CurveTween(curve: new Interval(InkRippleUtils._kFadeOutIntervalStart, 1.0));
public override void confirm() {
this._radiusController.duration = InkRippleUtils._kRadiusDuration;
this._radiusController.forward();
this._fadeInController.forward();
this._fadeOutController.animateTo(1.0, duration: InkRippleUtils._kFadeOutDuration);
}
public override void cancel() {
this._fadeInController.stop();
double fadeOutValue = 1.0 - this._fadeInController.value;
this._fadeOutController.setValue(fadeOutValue);
if (fadeOutValue < 1.0) {
this._fadeOutController.animateTo(1.0, duration: InkRippleUtils._kCancelDuration);
}
}
void _handleAlphaStatusChanged(AnimationStatus status) {
if (status == AnimationStatus.completed) {
this.dispose();
}
}
public override void dispose() {
this._radiusController.dispose();
this._fadeInController.dispose();
this._fadeOutController.dispose();
base.dispose();
}
protected override void paintFeature(Canvas canvas, Matrix3 transform) {
int alpha = this._fadeInController.isAnimating ? this._fadeIn.value : this._fadeOut.value;
Paint paint = new Paint {color = this.color.withAlpha(alpha)};
Offset center = Offset.lerp(
this._position,
this.referenceBox.size.center(Offset.zero),
Curves.ease.transform(this._radiusController.value)
);
Offset originOffset = transform.getAsTranslation();
canvas.save();
if (originOffset == null) {
canvas.concat(transform);
}
else {
canvas.translate(originOffset.dx, originOffset.dy);
}
if (this._clipCallback != null) {
Rect rect = this._clipCallback();
if (this._customBorder != null) {
canvas.clipPath(this._customBorder.getOuterPath(rect));
}
else if (this._borderRadius != BorderRadius.zero) {
canvas.clipRRect(RRect.fromRectAndCorners(
rect,
topLeft: this._borderRadius.topLeft,
topRight: this._borderRadius.topRight,
bottomLeft: this._borderRadius.bottomLeft,
bottomRight: this._borderRadius.bottomRight));
}
else {
canvas.clipRect(rect);
}
}
//todo:xingwei.zhu: remove this condition when drawCircle bug fixed (when radius.value == 0)
if (this._radius.value != 0) {
canvas.drawCircle(center, this._radius.value, paint);
}
canvas.restore();
}
}
}

11
Runtime/material/ink_ripple.cs.meta


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

864
Runtime/material/list_tile.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.material {
public enum ListTileStyle {
list,
drawer
}
public class ListTileTheme : InheritedWidget {
public ListTileTheme(
Key key = null,
bool dense = false,
ListTileStyle style = ListTileStyle.list,
Color selectedColor = null,
Color iconColor = null,
Color textColor = null,
EdgeInsets contentPadding = null,
Widget child = null) : base(key: key, child: child) {
this.dense = dense;
this.style = style;
this.selectedColor = selectedColor;
this.iconColor = iconColor;
this.textColor = textColor;
this.contentPadding = contentPadding;
}
public static Widget merge(
Key key = null,
bool? dense = null,
ListTileStyle? style = null,
Color selectedColor = null,
Color iconColor = null,
Color textColor = null,
EdgeInsets contentPadding = null,
Widget child = null) {
D.assert(child != null);
return new Builder(
builder: (BuildContext context) => {
ListTileTheme parent = of(context);
return new ListTileTheme(
key: key,
dense: dense ?? parent.dense,
style: style ?? parent.style,
selectedColor: selectedColor ?? parent.selectedColor,
iconColor: iconColor ?? parent.iconColor,
textColor: textColor ?? parent.textColor,
contentPadding: contentPadding ?? parent.contentPadding,
child: child);
}
);
}
public readonly bool dense;
public readonly ListTileStyle style;
public readonly Color selectedColor;
public readonly Color iconColor;
public readonly Color textColor;
public readonly EdgeInsets contentPadding;
public static ListTileTheme of(BuildContext context) {
ListTileTheme result = (ListTileTheme) context.inheritFromWidgetOfExactType(typeof(ListTileTheme));
return result ?? new ListTileTheme();
}
public override bool updateShouldNotify(InheritedWidget oldWidget) {
ListTileTheme _oldWidget = (ListTileTheme) oldWidget;
return this.dense != _oldWidget.dense ||
this.style != _oldWidget.style ||
this.selectedColor != _oldWidget.selectedColor ||
this.iconColor != _oldWidget.iconColor ||
this.textColor != _oldWidget.textColor ||
this.contentPadding != _oldWidget.contentPadding;
}
}
public enum ListTileControlAffinity {
leading,
trailing,
platform
}
public class ListTile : StatelessWidget {
public ListTile(
Key key = null,
Widget leading = null,
Widget title = null,
Widget subtitle = null,
Widget trailing = null,
bool isThreeLine = false,
bool? dense = null,
EdgeInsets contentPadding = null,
bool enabled = true,
GestureTapCallback onTap = null,
GestureLongPressCallback onLongPress = null,
bool selected = false
) : base(key: key) {
D.assert(!isThreeLine || subtitle != null);
this.leading = leading;
this.title = title;
this.subtitle = subtitle;
this.trailing = trailing;
this.isThreeLine = isThreeLine;
this.dense = dense;
this.contentPadding = contentPadding;
this.enabled = enabled;
this.onTap = onTap;
this.onLongPress = onLongPress;
this.selected = selected;
}
public readonly Widget leading;
public readonly Widget title;
public readonly Widget subtitle;
public readonly Widget trailing;
public readonly bool isThreeLine;
public readonly bool? dense;
public readonly EdgeInsets contentPadding;
public readonly bool enabled;
public readonly GestureTapCallback onTap;
public readonly GestureLongPressCallback onLongPress;
public readonly bool selected;
Color _iconColor(ThemeData theme, ListTileTheme tileTheme) {
if (!this.enabled) {
return theme.disabledColor;
}
if (this.selected && tileTheme?.selectedColor != null) {
return tileTheme.selectedColor;
}
if (!this.selected && tileTheme?.iconColor != null) {
return tileTheme.iconColor;
}
switch (theme.brightness) {
case Brightness.light:
return this.selected ? theme.primaryColor : Colors.black45;
case Brightness.dark:
return this.selected ? theme.accentColor : null;
}
return null;
}
Color _textColor(ThemeData theme, ListTileTheme tileTheme, Color defaultColor) {
if (!this.enabled) {
return theme.disabledColor;
}
if (this.selected && tileTheme?.selectedColor != null) {
return tileTheme.selectedColor;
}
if (!this.selected && tileTheme?.textColor != null) {
return tileTheme.textColor;
}
if (this.selected) {
switch (theme.brightness) {
case Brightness.light:
return theme.primaryColor;
case Brightness.dark:
return theme.accentColor;
}
}
return defaultColor;
}
bool _isDenseLayout(ListTileTheme tileTheme) {
return this.dense != null ? this.dense ?? false : (tileTheme?.dense ?? false);
}
TextStyle _titleTextStyle(ThemeData theme, ListTileTheme tileTheme) {
TextStyle style = null;
if (tileTheme != null) {
switch (tileTheme.style) {
case ListTileStyle.drawer:
style = theme.textTheme.body2;
break;
case ListTileStyle.list:
style = theme.textTheme.subhead;
break;
}
}
else {
style = theme.textTheme.subhead;
}
Color color = this._textColor(theme, tileTheme, style.color);
return this._isDenseLayout(tileTheme)
? style.copyWith(fontSize: 13.0, color: color)
: style.copyWith(color: color);
}
TextStyle _subtitleTextStyle(ThemeData theme, ListTileTheme tileTheme) {
TextStyle style = theme.textTheme.body1;
Color color = this._textColor(theme, tileTheme, theme.textTheme.caption.color);
return this._isDenseLayout(tileTheme)
? style.copyWith(color: color, fontSize: 12.0)
: style.copyWith(color: color);
}
public override Widget build(BuildContext context) {
D.assert(MaterialDebug.debugCheckHasMaterial(context));
ThemeData theme = Theme.of(context);
ListTileTheme tileTheme = ListTileTheme.of(context);
IconThemeData iconThemeData = null;
if (this.leading != null || this.trailing != null) {
iconThemeData = new IconThemeData(color: this._iconColor(theme, tileTheme));
}
Widget leadingIcon = null;
if (this.leading != null) {
leadingIcon = IconTheme.merge(
data: iconThemeData,
child: this.leading);
}
TextStyle titleStyle = this._titleTextStyle(theme, tileTheme);
Widget titleText = new AnimatedDefaultTextStyle(
style: titleStyle,
duration: Constants.kThemeChangeDuration,
child: this.title ?? new SizedBox()
);
Widget subtitleText = null;
TextStyle subtitleStyle = null;
if (this.subtitle != null) {
subtitleStyle = this._subtitleTextStyle(theme, tileTheme);
subtitleText = new AnimatedDefaultTextStyle(
style: subtitleStyle,
duration: Constants.kThemeChangeDuration,
child: this.subtitle);
}
Widget trailingIcon = null;
if (this.trailing != null) {
trailingIcon = IconTheme.merge(
data: iconThemeData,
child: this.trailing);
}
EdgeInsets _defaultContentPadding = EdgeInsets.symmetric(horizontal: 16.0);
EdgeInsets resolvedContentPadding =
this.contentPadding ?? tileTheme?.contentPadding ?? _defaultContentPadding;
return new InkWell(
onTap: this.enabled ? this.onTap : null,
onLongPress: this.enabled ? this.onLongPress : null,
child: new SafeArea(
top: false,
bottom: false,
mininum: resolvedContentPadding,
child: new _ListTile(
leading: leadingIcon,
title: titleText,
subtitle: subtitleText,
trailing: trailingIcon,
isDense: this._isDenseLayout(tileTheme),
isThreeLine: this.isThreeLine,
titleBaselineType: titleStyle.textBaseline,
subtitleBaselineType: subtitleStyle?.textBaseline
)
)
);
}
}
public enum _ListTileSlot {
leading,
title,
subtitle,
trailing
}
public class _ListTile : RenderObjectWidget {
public _ListTile(
Key key = null,
Widget leading = null,
Widget title = null,
Widget subtitle = null,
Widget trailing = null,
bool? isThreeLine = null,
bool? isDense = null,
TextBaseline? titleBaselineType = null,
TextBaseline? subtitleBaselineType = null) : base(key: key) {
D.assert(isThreeLine != null);
D.assert(isDense != null);
D.assert(titleBaselineType != null);
this.leading = leading;
this.title = title;
this.subtitle = subtitle;
this.trailing = trailing;
this.isThreeLine = isThreeLine ?? false;
this.isDense = isDense ?? false;
this.titleBaselineType = titleBaselineType ?? TextBaseline.alphabetic;
this.subtitleBaselineType = subtitleBaselineType;
}
public readonly Widget leading;
public readonly Widget title;
public readonly Widget subtitle;
public readonly Widget trailing;
public readonly bool isThreeLine;
public readonly bool isDense;
public readonly TextBaseline titleBaselineType;
public readonly TextBaseline? subtitleBaselineType;
public override Element createElement() {
return new _ListTileElement(this);
}
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderListTile(
isThreeLine: this.isThreeLine,
isDense: this.isDense,
titleBaselineType: this.titleBaselineType,
subtitleBaselineType: this.subtitleBaselineType
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
_RenderListTile _renderObject = (_RenderListTile) renderObject;
_renderObject.isThreeLine = this.isThreeLine;
_renderObject.isDense = this.isDense;
_renderObject.titleBaselineType = this.titleBaselineType;
_renderObject.subtitleBaselineType = this.subtitleBaselineType;
}
}
public class _ListTileElement : RenderObjectElement {
public _ListTileElement(RenderObjectWidget widget) : base(widget) {
}
readonly Dictionary<_ListTileSlot, Element> slotToChild = new Dictionary<_ListTileSlot, Element>();
readonly Dictionary<Element, _ListTileSlot> childToSlot = new Dictionary<Element, _ListTileSlot>();
public new _ListTile widget {
get { return (_ListTile) base.widget; }
}
public new _RenderListTile renderObject {
get { return (_RenderListTile) base.renderObject; }
}
public override void visitChildren(ElementVisitor visitor) {
foreach (var element in this.slotToChild.Values) {
visitor(element);
}
}
protected override void forgetChild(Element child) {
D.assert(this.slotToChild.Values.Contains(child));
D.assert(this.childToSlot.Keys.Contains(child));
_ListTileSlot slot = this.childToSlot[child];
this.childToSlot.Remove(child);
this.slotToChild.Remove(slot);
}
void _mountChild(Widget widget, _ListTileSlot slot) {
Element oldChild = this.slotToChild[slot];
Element newChild = this.updateChild(oldChild, widget, slot);
if (oldChild != null) {
this.slotToChild.Remove(slot);
this.childToSlot.Remove(oldChild);
}
if (newChild != null) {
this.slotToChild[slot] = newChild;
this.childToSlot[newChild] = slot;
}
}
public override void mount(Element parent, object newSlot) {
base.mount(parent, newSlot);
this._mountChild(this.widget.leading, _ListTileSlot.leading);
this._mountChild(this.widget.title, _ListTileSlot.title);
this._mountChild(this.widget.subtitle, _ListTileSlot.subtitle);
this._mountChild(this.widget.trailing, _ListTileSlot.trailing);
}
void _updateChild(Widget widget, _ListTileSlot slot) {
Element oldChild = this.slotToChild[slot];
Element newChild = this.updateChild(oldChild, widget, slot);
if (oldChild != null) {
this.childToSlot.Remove(oldChild);
this.slotToChild.Remove(slot);
}
if (newChild != null) {
this.slotToChild[slot] = newChild;
this.childToSlot[newChild] = slot;
}
}
public override void update(Widget newWidget) {
base.update(newWidget);
D.assert(this.widget == newWidget);
this._updateChild(this.widget.leading, _ListTileSlot.leading);
this._updateChild(this.widget.title, _ListTileSlot.title);
this._updateChild(this.widget.subtitle, _ListTileSlot.subtitle);
this._updateChild(this.widget.trailing, _ListTileSlot.trailing);
}
void _updateRenderObject(RenderObject child, _ListTileSlot slot) {
switch (slot) {
case _ListTileSlot.leading:
this.renderObject.leading = (RenderBox) child;
break;
case _ListTileSlot.title:
this.renderObject.title = (RenderBox) child;
break;
case _ListTileSlot.subtitle:
this.renderObject.subtitle = (RenderBox) child;
break;
case _ListTileSlot.trailing:
this.renderObject.trailing = (RenderBox) child;
break;
}
}
protected override void insertChildRenderObject(RenderObject child, object slotValue) {
D.assert(child is RenderBox);
D.assert(slotValue is _ListTileSlot);
_ListTileSlot slot = (_ListTileSlot) slotValue;
this._updateRenderObject(child, slot);
D.assert(this.renderObject.childToSlot.Keys.Contains(child));
D.assert(this.renderObject.slotToChild.Keys.Contains(slot));
}
protected override void removeChildRenderObject(RenderObject child) {
D.assert(child is RenderBox);
D.assert(this.renderObject.childToSlot.Keys.Contains(child));
_ListTileSlot slot = this.renderObject.childToSlot[(RenderBox) child];
this._updateRenderObject(null, slot);
D.assert(!this.renderObject.childToSlot.Keys.Contains(child));
D.assert(!this.renderObject.slotToChild.Keys.Contains(slot));
}
protected override void moveChildRenderObject(RenderObject child, object slotValue) {
D.assert(false, "not reachable");
}
}
public class _RenderListTile : RenderBox {
public _RenderListTile(
bool? isDense = null,
bool? isThreeLine = null,
TextBaseline? titleBaselineType = null,
TextBaseline? subtitleBaselineType = null) {
D.assert(isDense != null);
D.assert(isThreeLine != null);
D.assert(titleBaselineType != null);
this._isDense = isDense ?? false;
this._isThreeLine = isThreeLine ?? false;
this._titleBaselineType = titleBaselineType ?? TextBaseline.alphabetic;
this._subtitleBaselineType = subtitleBaselineType;
}
const double _minLeadingWidth = 40.0;
const double _horizontalTitleGap = 16.0;
const double _minVerticalPadding = 4.0;
public readonly Dictionary<_ListTileSlot, RenderBox> slotToChild = new Dictionary<_ListTileSlot, RenderBox>();
public readonly Dictionary<RenderBox, _ListTileSlot> childToSlot = new Dictionary<RenderBox, _ListTileSlot>();
RenderBox _updateChild(RenderBox oldChild, RenderBox newChild, _ListTileSlot slot) {
if (oldChild != null) {
this.dropChild(oldChild);
this.childToSlot.Remove(oldChild);
this.slotToChild.Remove(slot);
}
if (newChild != null) {
this.childToSlot[newChild] = slot;
this.slotToChild[slot] = newChild;
this.adoptChild(newChild);
}
return newChild;
}
RenderBox _leading;
public RenderBox leading {
get { return this._leading; }
set { this._leading = this._updateChild(this._leading, value, _ListTileSlot.leading); }
}
RenderBox _title;
public RenderBox title {
get { return this._title; }
set { this._title = this._updateChild(this._title, value, _ListTileSlot.title); }
}
RenderBox _subtitle;
public RenderBox subtitle {
get { return this._subtitle; }
set { this._subtitle = this._updateChild(this._subtitle, value, _ListTileSlot.subtitle); }
}
RenderBox _trailing;
public RenderBox trailing {
get { return this._trailing; }
set { this._trailing = this._updateChild(this._trailing, value, _ListTileSlot.trailing); }
}
List<RenderObject> _children {
get {
List<RenderObject> ret = new List<RenderObject>();
if (this.leading != null) {
ret.Add(this.leading);
}
if (this.title != null) {
ret.Add(this.title);
}
if (this.subtitle != null) {
ret.Add(this.subtitle);
}
if (this.trailing != null) {
ret.Add(this.trailing);
}
return ret;
}
}
public bool isDense {
get { return this._isDense; }
set {
if (this._isDense == value) {
return;
}
this._isDense = value;
this.markNeedsLayout();
}
}
bool _isDense;
public bool isThreeLine {
get { return this._isThreeLine; }
set {
if (this._isThreeLine == value) {
return;
}
this._isThreeLine = value;
this.markNeedsLayout();
}
}
bool _isThreeLine;
public TextBaseline titleBaselineType {
get { return this._titleBaselineType; }
set {
if (this._titleBaselineType == value) {
return;
}
this._titleBaselineType = value;
this.markNeedsLayout();
}
}
TextBaseline _titleBaselineType;
public TextBaseline? subtitleBaselineType {
get { return this._subtitleBaselineType; }
set {
if (this._subtitleBaselineType == value) {
return;
}
this._subtitleBaselineType = value;
this.markNeedsLayout();
}
}
TextBaseline? _subtitleBaselineType;
public override void attach(object owner) {
base.attach(owner);
foreach (RenderBox child in this._children) {
child.attach(owner);
}
}
public override void detach() {
base.detach();
foreach (RenderBox child in this._children) {
child.detach();
}
}
public override void redepthChildren() {
foreach (var child in this._children) {
this.redepthChild(child);
}
}
public override void visitChildren(RenderObjectVisitor visitor) {
foreach (var child in this._children) {
visitor(child);
}
}
public override List<DiagnosticsNode> debugDescribeChildren() {
List<DiagnosticsNode> value = new List<DiagnosticsNode>();
void add(RenderBox child, string name) {
if (child != null) {
value.Add(child.toDiagnosticsNode(name: name));
}
}
add(this.leading, "leading");
add(this.title, "title");
add(this.subtitle, "subtitle");
add(this.trailing, "trailing");
return value;
}
public new bool sizedByParent {
get { return false; }
}
static double _minWidth(RenderBox box, double height) {
return box == null ? 0.0 : box.getMinIntrinsicWidth(height);
}
static double _maxWidth(RenderBox box, double height) {
return box == null ? 0.0 : box.getMaxIntrinsicWidth(height);
}
protected override double computeMinIntrinsicWidth(double height) {
double leadingWidth = this.leading != null
? Math.Max(this.leading.getMinIntrinsicWidth(height), _minLeadingWidth) + _horizontalTitleGap
: 0.0;
return leadingWidth + Math.Max(_minWidth(this.title, height), _minWidth(this.subtitle, height)) +
_maxWidth(this.trailing, height);
}
protected override double computeMaxIntrinsicWidth(double height) {
double leadingWidth = this.leading != null
? Math.Max(this.leading.getMaxIntrinsicWidth(height), _minLeadingWidth) + _horizontalTitleGap
: 0.0;
return leadingWidth + Math.Max(_maxWidth(this.title, height), _maxWidth(this.subtitle, height)) +
_maxWidth(this.trailing, height);
}
double _defaultTileHeight {
get {
bool hasSubtitle = this.subtitle != null;
bool isTwoLine = !this.isThreeLine && hasSubtitle;
bool isOneLine = !this.isThreeLine && !hasSubtitle;
if (isOneLine) {
return this.isDense ? 48.0 : 56.0;
}
if (isTwoLine) {
return this.isDense ? 64.0 : 72.0;
}
return this.isDense ? 76.0 : 88.0;
}
}
protected override double computeMinIntrinsicHeight(double width) {
return Math.Max(
this._defaultTileHeight,
this.title.getMinIntrinsicHeight(width) + this.subtitle?.getMinIntrinsicHeight(width) ?? 0.0);
}
protected override double computeMaxIntrinsicHeight(double width) {
return this.computeMinIntrinsicHeight(width);
}
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
D.assert(this.title != null);
BoxParentData parentData = (BoxParentData) this.title.parentData;
return parentData.offset.dy + this.title.getDistanceToActualBaseline(baseline);
}
static double _boxBaseline(RenderBox box, TextBaseline baseline) {
return box.getDistanceToBaseline(baseline) ?? 0.0;
}
static Size _layoutBox(RenderBox box, BoxConstraints constraints) {
if (box == null) {
return Size.zero;
}
box.layout(constraints, parentUsesSize: true);
return box.size;
}
static void _positionBox(RenderBox box, Offset offset) {
BoxParentData parentData = (BoxParentData) box.parentData;
parentData.offset = offset;
}
protected override void performLayout() {
bool hasLeading = this.leading != null;
bool hasSubtitle = this.subtitle != null;
bool hasTrailing = this.trailing != null;
bool isTwoLine = !this.isThreeLine && hasSubtitle;
bool isOneLine = !this.isThreeLine && !hasSubtitle;
BoxConstraints looseConstraints = this.constraints.loosen();
double tileWidth = looseConstraints.maxWidth;
Size leadingSize = _layoutBox(this.leading, looseConstraints);
Size trailingSize = _layoutBox(this.trailing, looseConstraints);
double titleStart = hasLeading ? Math.Max(_minLeadingWidth, leadingSize.width) + _horizontalTitleGap : 0.0;
BoxConstraints textConstraints = looseConstraints.tighten(
width: tileWidth - titleStart - (hasTrailing ? trailingSize.width + _horizontalTitleGap : 0.0));
Size titleSize = _layoutBox(this.title, textConstraints);
Size subtitleSize = _layoutBox(this.subtitle, textConstraints);
double titleBaseline = 0.0;
double subtitleBaseline = 0.0;
if (isTwoLine) {
titleBaseline = this.isDense ? 28.0 : 32.0;
subtitleBaseline = this.isDense ? 48.0 : 52.0;
}
else if (this.isThreeLine) {
titleBaseline = this.isDense ? 22.0 : 28.0;
subtitleBaseline = this.isDense ? 42.0 : 48.0;
}
else {
D.assert(isOneLine);
}
double tileHeight = 0.0;
double titleY = 0.0;
double subtitleY = 0.0;
if (!hasSubtitle) {
tileHeight = Math.Max(this._defaultTileHeight, titleSize.height + 2.0 * _minVerticalPadding);
titleY = (tileHeight - titleSize.height) / 2.0;
}
else {
D.assert(this.subtitleBaselineType != null);
titleY = titleBaseline - _boxBaseline(this.title, this.titleBaselineType);
subtitleY = subtitleBaseline -
_boxBaseline(this.subtitle, this.subtitleBaselineType ?? TextBaseline.alphabetic);
tileHeight = this._defaultTileHeight;
double titleOverlap = titleY + titleSize.height - subtitleY;
if (titleOverlap > 0.0) {
titleY -= titleOverlap / 2.0;
subtitleY += titleOverlap / 2.0;
}
if (titleY < _minVerticalPadding ||
(subtitleY + subtitleSize.height + _minVerticalPadding) > tileHeight) {
tileHeight = titleSize.height + subtitleSize.height + 2.0 * _minVerticalPadding;
titleY = _minVerticalPadding;
subtitleY = titleSize.height + _minVerticalPadding;
}
}
double leadingY = (tileHeight - leadingSize.height) / 2.0;
double trailingY = (tileHeight - trailingSize.height) / 2.0;
if (hasLeading) {
_positionBox(this.leading, new Offset(0.0, leadingY));
}
_positionBox(this.title, new Offset(titleStart, titleY));
if (hasSubtitle) {
_positionBox(this.subtitle, new Offset(titleStart, subtitleY));
}
if (hasTrailing) {
_positionBox(this.trailing, new Offset(tileWidth - trailingSize.width, trailingY));
}
this.size = this.constraints.constrain(new Size(tileWidth, tileHeight));
D.assert(this.size.width == this.constraints.constrainWidth(tileWidth));
D.assert(this.size.height == this.constraints.constrainHeight(tileHeight));
}
public override void paint(PaintingContext context, Offset offset) {
void doPaint(RenderBox child) {
if (child != null) {
BoxParentData parentData = (BoxParentData) child.parentData;
context.paintChild(child, parentData.offset + offset);
}
}
doPaint(this.leading);
doPaint(this.title);
doPaint(this.subtitle);
doPaint(this.trailing);
}
protected override bool hitTestSelf(Offset position) {
return true;
}
protected override bool hitTestChildren(HitTestResult result, Offset position) {
D.assert(position != null);
foreach (RenderBox child in this._children) {
BoxParentData parentData = (BoxParentData) child.parentData;
if (child.hitTest(result, position: position - parentData.offset)) {
return true;
}
}
return false;
}
}
}

11
Runtime/material/list_tile.cs.meta


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

721
Runtime/material/mergeable_material.cs


using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.utils;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public abstract class MergeableMaterialItem {
public MergeableMaterialItem(
LocalKey key) {
D.assert(key != null);
this.key = key;
}
public readonly LocalKey key;
}
public class MaterialSlice : MergeableMaterialItem {
public MaterialSlice(
LocalKey key = null,
Widget child = null) : base(key: key) {
D.assert(key != null);
D.assert(child != null);
this.child = child;
}
public readonly Widget child;
public override string ToString() {
return "MergeableSlice(key: " + this.key + ", child: " + this.child + ")";
}
}
public class MaterialGap : MergeableMaterialItem {
public MaterialGap(
LocalKey key = null,
double size = 16.0) : base(key: key) {
D.assert(key != null);
this.size = size;
}
public readonly double size;
public override string ToString() {
return "MaterialGap(key: " + this.key + ", child: " + this.size + ")";
}
}
public class MergeableMaterial : StatefulWidget {
public MergeableMaterial(
Key key = null,
Axis mainAxis = Axis.vertical,
int elevation = 2,
bool hasDividers = false,
List<MergeableMaterialItem> children = null) : base(key: key) {
this.mainAxis = mainAxis;
this.elevation = elevation;
this.hasDividers = hasDividers;
this.children = children ?? new List<MergeableMaterialItem>();
}
public readonly List<MergeableMaterialItem> children;
public readonly Axis mainAxis;
public readonly int elevation;
public readonly bool hasDividers;
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<Axis>("mainAxis", this.mainAxis));
properties.add(new DoubleProperty("elevation", this.elevation));
}
public override State createState() {
return new _MergeableMaterialState();
}
}
public class _AnimationTuple {
public _AnimationTuple(
AnimationController controller = null,
CurvedAnimation startAnimation = null,
CurvedAnimation endAnimation = null,
CurvedAnimation gapAnimation = null,
double gapStart = 0.0) {
this.controller = controller;
this.startAnimation = startAnimation;
this.endAnimation = endAnimation;
this.gapAnimation = gapAnimation;
this.gapStart = gapStart;
}
public readonly AnimationController controller;
public readonly CurvedAnimation startAnimation;
public readonly CurvedAnimation endAnimation;
public readonly CurvedAnimation gapAnimation;
public double gapStart;
}
public class _MergeableMaterialState : TickerProviderStateMixin<MergeableMaterial> {
List<MergeableMaterialItem> _children;
public readonly Dictionary<LocalKey, _AnimationTuple> _animationTuples =
new Dictionary<LocalKey, _AnimationTuple>();
public override void initState() {
base.initState();
this._children = new List<MergeableMaterialItem>();
this._children.AddRange(this.widget.children);
for (int i = 0; i < this._children.Count; i++) {
if (this._children[i] is MaterialGap) {
this._initGap((MaterialGap) this._children[i]);
this._animationTuples[this._children[i].key].controller.setValue(1.0);
}
}
D.assert(this._debugGapsAreValid(this._children));
}
void _initGap(MaterialGap gap) {
AnimationController controller = new AnimationController(
duration: ThemeUtils.kThemeAnimationDuration,
vsync: this);
CurvedAnimation startAnimation = new CurvedAnimation(
parent: controller,
curve: Curves.fastOutSlowIn);
CurvedAnimation endAnimation = new CurvedAnimation(
parent: controller,
curve: Curves.fastOutSlowIn);
CurvedAnimation gapAnimation = new CurvedAnimation(
parent: controller,
curve: Curves.fastOutSlowIn);
controller.addListener(this._handleTick);
this._animationTuples[gap.key] = new _AnimationTuple(
controller: controller,
startAnimation: startAnimation,
endAnimation: endAnimation,
gapAnimation: gapAnimation);
}
public override void dispose() {
foreach (MergeableMaterialItem child in this._children) {
if (child is MaterialGap) {
this._animationTuples[child.key].controller.dispose();
}
}
base.dispose();
}
void _handleTick() {
this.setState(() => { });
}
bool _debugHasConsecutiveGaps(List<MergeableMaterialItem> children) {
for (int i = 0; i < this.widget.children.Count - 1; i++) {
if (this.widget.children[i] is MaterialGap &&
this.widget.children[i + 1] is MaterialGap) {
return true;
}
}
return false;
}
bool _debugGapsAreValid(List<MergeableMaterialItem> children) {
if (this._debugHasConsecutiveGaps(children)) {
return false;
}
if (children.isNotEmpty()) {
if (children.first() is MaterialGap || children.last() is MaterialGap) {
return false;
}
}
return true;
}
void _insertChild(int index, MergeableMaterialItem child) {
this._children.Insert(index, child);
if (child is MaterialGap) {
this._initGap((MaterialGap) child);
}
}
void _removeChild(int index) {
MergeableMaterialItem child = this._children[index];
this._children.RemoveAt(index);
if (child is MaterialGap) {
this._animationTuples[child.key] = null;
}
}
bool _isClosingGap(int index) {
if (index < this._children.Count - 1 && this._children[index] is MaterialGap) {
return this._animationTuples[this._children[index].key].controller.status == AnimationStatus.reverse;
}
return false;
}
void _removeEmptyGaps() {
int j = 0;
while (j < this._children.Count) {
if (this._children[j] is MaterialGap &&
this._animationTuples[this._children[j].key].controller.status == AnimationStatus.dismissed) {
this._removeChild(j);
}
else {
j++;
}
}
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
MergeableMaterial _oldWidget = (MergeableMaterial) oldWidget;
HashSet<LocalKey> oldKeys = new HashSet<LocalKey>();
foreach (MergeableMaterialItem child in _oldWidget.children) {
oldKeys.Add(child.key);
}
HashSet<LocalKey> newKeys = new HashSet<LocalKey>();
foreach (MergeableMaterialItem child in this.widget.children) {
newKeys.Add(child.key);
}
HashSet<LocalKey> newOnly = new HashSet<LocalKey>();
foreach (var key in newKeys) {
if (!oldKeys.Contains(key)) {
newOnly.Add(key);
}
}
HashSet<LocalKey> oldOnly = new HashSet<LocalKey>();
foreach (var key in oldKeys) {
if (!newKeys.Contains(key)) {
oldOnly.Add(key);
}
}
List<MergeableMaterialItem> newChildren = this.widget.children;
int i = 0;
int j = 0;
D.assert(this._debugGapsAreValid(newChildren));
this._removeEmptyGaps();
while (i < newChildren.Count && j < this._children.Count) {
if (newOnly.Contains(newChildren[i].key) ||
oldOnly.Contains(this._children[j].key)) {
int startNew = i;
int startOld = j;
while (newOnly.Contains(newChildren[i].key)) {
i++;
}
while (oldOnly.Contains(this._children[j].key) || this._isClosingGap(j)) {
j++;
}
int newLength = i - startNew;
int oldLength = j - startOld;
if (newLength > 0) {
if (oldLength > 1 || oldLength == 1 && this._children[startOld] is MaterialSlice) {
if (newLength == 1 && newChildren[startNew] is MaterialGap) {
double gapSizeSum = 0.0;
while (startOld < j) {
if (this._children[startOld] is MaterialGap) {
MaterialGap gap = (MaterialGap) this._children[startOld];
gapSizeSum += gap.size;
}
this._removeChild(startOld);
j--;
}
this._insertChild(startOld, newChildren[startNew]);
this._animationTuples[newChildren[startNew].key].gapStart = gapSizeSum;
this._animationTuples[newChildren[startNew].key].controller.forward();
j++;
}
else {
for (int k = 0; k < oldLength; k++) {
this._removeChild(startOld);
}
for (int k = 0; k < newLength; k++) {
this._insertChild(startOld + k, newChildren[startNew + k]);
}
j += (newLength - oldLength);
}
}
else if (oldLength == 1) {
if (newLength == 1 && newChildren[startNew] is MaterialGap &&
this._children[startOld].key == newChildren[startNew].key) {
this._animationTuples[newChildren[startNew].key].controller.forward();
}
else {
double gapSize = this._getGapSize(startOld);
this._removeChild(startOld);
for (int k = 0; k < newLength; k++) {
this._insertChild(startOld + k, newChildren[startNew + k]);
}
j += (newLength - 1);
double gapSizeSum = 0.0;
for (int k = startNew; k < i; k++) {
if (newChildren[k] is MaterialGap) {
MaterialGap gap = (MaterialGap) newChildren[k];
gapSizeSum += gap.size;
}
}
for (int k = startNew; k < i; k++) {
if (newChildren[k] is MaterialGap) {
MaterialGap gap = (MaterialGap) newChildren[k];
this._animationTuples[gap.key].gapStart = gapSize * gap.size / gapSizeSum;
this._animationTuples[gap.key].controller.setValue(0.0);
this._animationTuples[gap.key].controller.forward();
}
}
}
}
else {
for (int k = 0; k < newLength; k++) {
this._insertChild(startOld + k, newChildren[startNew + k]);
if (newChildren[startNew + k] is MaterialGap) {
MaterialGap gap = (MaterialGap) newChildren[startNew + k];
this._animationTuples[gap.key].controller.forward();
}
}
j += newLength;
}
}
else {
if (oldLength > 1 || oldLength == 1 && this._children[startOld] is MaterialSlice) {
double gapSizeSum = 0.0;
while (startOld < j) {
if (this._children[startOld] is MaterialGap) {
MaterialGap gap = (MaterialGap) this._children[startOld];
gapSizeSum += gap.size;
}
this._removeChild(startOld);
j--;
}
if (gapSizeSum != 0.0) {
MaterialGap gap = new MaterialGap(key: new UniqueKey(), size: gapSizeSum);
this._insertChild(startOld, gap);
this._animationTuples[gap.key].gapStart = 0.0;
this._animationTuples[gap.key].controller.setValue(1.0);
this._animationTuples[gap.key].controller.reverse();
j++;
}
}
else if (oldLength == 1) {
MaterialGap gap = (MaterialGap) this._children[startOld];
this._animationTuples[gap.key].gapStart = 0.0;
this._animationTuples[gap.key].controller.reverse();
}
}
}
else {
if ((this._children[j] is MaterialGap) == (newChildren[i] is MaterialGap)) {
this._children[j] = newChildren[i];
i++;
j++;
}
else {
D.assert(this._children[j] is MaterialGap);
j++;
}
}
}
while (j < this._children.Count) {
this._removeChild(j);
}
while (i < newChildren.Count) {
this._insertChild(j, newChildren[i]);
i++;
j++;
}
}
BorderRadius _borderRadius(int index, bool start, bool end) {
D.assert(MaterialConstantsUtils.kMaterialEdges[MaterialType.card].topLeft ==
MaterialConstantsUtils.kMaterialEdges[MaterialType.card].topRight);
D.assert(MaterialConstantsUtils.kMaterialEdges[MaterialType.card].topLeft ==
MaterialConstantsUtils.kMaterialEdges[MaterialType.card].bottomLeft);
D.assert(MaterialConstantsUtils.kMaterialEdges[MaterialType.card].topLeft ==
MaterialConstantsUtils.kMaterialEdges[MaterialType.card].bottomRight);
Radius cardRadius = MaterialConstantsUtils.kMaterialEdges[MaterialType.card].topLeft;
Radius startRadius = Radius.zero;
Radius endRadius = Radius.zero;
if (index > 0 && this._children[index - 1] is MaterialGap) {
startRadius = Radius.lerp(
Radius.zero,
cardRadius,
this._animationTuples[this._children[index - 1].key].startAnimation.value);
}
if (index < this._children.Count - 2 && this._children[index + 1] is MaterialGap) {
endRadius = Radius.lerp(
Radius.zero,
cardRadius,
this._animationTuples[this._children[index + 1].key].endAnimation.value);
}
if (this.widget.mainAxis == Axis.vertical) {
return BorderRadius.vertical(
top: start ? cardRadius : startRadius,
bottom: end ? cardRadius : endRadius);
}
else {
return BorderRadius.horizontal(
left: start ? cardRadius : startRadius,
right: end ? cardRadius : endRadius);
}
}
double _getGapSize(int index) {
MaterialGap gap = (MaterialGap) this._children[index];
return MathUtils.lerpDouble(this._animationTuples[gap.key].gapStart,
gap.size,
this._animationTuples[gap.key].gapAnimation.value);
}
bool _willNeedDivider(int index) {
if (index < 0) {
return false;
}
if (index >= this._children.Count) {
return false;
}
return this._children[index] is MaterialSlice || this._isClosingGap(index);
}
public override Widget build(BuildContext context) {
this._removeEmptyGaps();
List<Widget> widgets = new List<Widget>();
List<Widget> slices = new List<Widget>();
int i;
for (i = 0; i < this._children.Count; i++) {
if (this._children[i] is MaterialGap) {
D.assert(slices.isNotEmpty());
widgets.Add(
new Container(
decoration: new BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: this._borderRadius(i - 1, widgets.isEmpty(), false),
shape: BoxShape.rectangle),
child: new ListBody(
mainAxis: this.widget.mainAxis,
children: slices)
)
);
slices = new List<Widget>();
widgets.Add(
new SizedBox(
width: this.widget.mainAxis == Axis.horizontal ? this._getGapSize(i) : (double?) null,
height: this.widget.mainAxis == Axis.vertical ? this._getGapSize(i) : (double?) null)
);
}
else {
MaterialSlice slice = (MaterialSlice) this._children[i];
Widget child = slice.child;
if (this.widget.hasDividers) {
bool hasTopDivider = this._willNeedDivider(i - 1);
bool hasBottomDivider = this._willNeedDivider(i + 1);
Border border;
BorderSide divider = Divider.createBorderSide(
context,
width: 0.5
);
if (i == 0) {
border = new Border(
bottom: hasBottomDivider ? divider : BorderSide.none);
}
else if (i == this._children.Count - 1) {
border = new Border(
top: hasTopDivider ? divider : BorderSide.none);
}
else {
border = new Border(
top: hasTopDivider ? divider : BorderSide.none,
bottom: hasBottomDivider ? divider : BorderSide.none
);
}
D.assert(border != null);
child = new AnimatedContainer(
key: new _MergeableMaterialSliceKey(this._children[i].key),
decoration: new BoxDecoration(border: border),
duration: ThemeUtils.kThemeAnimationDuration,
curve: Curves.fastOutSlowIn,
child: child
);
}
slices.Add(
new Material(
type: MaterialType.transparency,
child: child
)
);
}
}
if (slices.isNotEmpty()) {
widgets.Add(
new Container(
decoration: new BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: this._borderRadius(i - 1, widgets.isEmpty(), true),
shape: BoxShape.rectangle
),
child: new ListBody(
mainAxis: this.widget.mainAxis,
children: slices
)
)
);
slices = new List<Widget>();
}
return new _MergeableMaterialListBody(
mainAxis: this.widget.mainAxis,
boxShadows: ShadowConstants.kElevationToShadow[this.widget.elevation],
items: this._children,
children: widgets
);
}
}
class _MergeableMaterialSliceKey : GlobalKey {
public _MergeableMaterialSliceKey(LocalKey value) : base() {
this.value = value;
}
public readonly LocalKey value;
public bool Equals(_MergeableMaterialSliceKey other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return other.value == this.value;
}
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((_MergeableMaterialSliceKey) obj);
}
public static bool operator ==(_MergeableMaterialSliceKey left, _MergeableMaterialSliceKey right) {
return Equals(left, right);
}
public static bool operator !=(_MergeableMaterialSliceKey left, _MergeableMaterialSliceKey right) {
return !Equals(left, right);
}
public override int GetHashCode() {
unchecked {
var hashCode = this.value.GetHashCode();
return hashCode;
}
}
public override string ToString() {
return "_MergeableMaterialSliceKey(" + this.value + ")";
}
}
class _MergeableMaterialListBody : ListBody {
public _MergeableMaterialListBody(
List<Widget> children = null,
Axis mainAxis = Axis.vertical,
List<MergeableMaterialItem> items = null,
List<BoxShadow> boxShadows = null
) : base(children: children, mainAxis: mainAxis) {
this.items = items;
this.boxShadows = boxShadows;
}
public readonly List<MergeableMaterialItem> items;
public readonly List<BoxShadow> boxShadows;
AxisDirection _getDirection(BuildContext context) {
return AxisDirectionUtils.getAxisDirectionFromAxisReverseAndDirectionality(context, this.mainAxis, false) ??
AxisDirection.right;
}
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderMergeableMaterialListBody(
axisDirection: this._getDirection(context),
boxShadows: this.boxShadows
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
_RenderMergeableMaterialListBody materialRenderListBody = (_RenderMergeableMaterialListBody) renderObject;
materialRenderListBody.axisDirection = this._getDirection(context);
materialRenderListBody.boxShadows = this.boxShadows;
}
}
class _RenderMergeableMaterialListBody : RenderListBody {
public _RenderMergeableMaterialListBody(
List<RenderBox> children = null,
AxisDirection axisDirection = AxisDirection.down,
List<BoxShadow> boxShadows = null
) : base(children: children, axisDirection: axisDirection) {
this.boxShadows = boxShadows;
}
public List<BoxShadow> boxShadows;
void _paintShadows(Canvas canvas, Rect rect) {
foreach (BoxShadow boxShadow in this.boxShadows) {
Paint paint = boxShadow.toPaint();
canvas.drawRRect(
MaterialConstantsUtils.kMaterialEdges[MaterialType.card].toRRect(rect), paint);
}
}
public override void paint(PaintingContext context, Offset offset) {
RenderBox child = this.firstChild;
int i = 0;
while (child != null) {
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
Rect rect = (childParentData.offset + offset) & child.size;
if (i % 2 == 0) {
this._paintShadows(context.canvas, rect);
}
child = childParentData.nextSibling;
i++;
}
this.defaultPaint(context, offset);
}
}
}

11
Runtime/material/mergeable_material.cs.meta


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

215
Runtime/material/raised_button.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class RaisedButton : MaterialButton {
public RaisedButton(
Key key = null,
VoidCallback onPressed = null,
ValueChanged<bool> onHighlightChanged = null,
ButtonTextTheme? textTheme = null,
Color textColor = null,
Color disabledTextColor = null,
Color color = null,
Color disabledColor = null,
Color highlightColor = null,
Color splashColor = null,
Brightness? colorBrightness = null,
double? elevation = null,
double? highlightElevation = null,
double? disabledElevation = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
Clip? clipBehavior = Clip.none,
MaterialTapTargetSize? materialTapTargetSize = null,
TimeSpan? animationDuration = null,
Widget child = null
) : base(
key: key,
onPressed: onPressed,
onHighlightChanged: onHighlightChanged,
textTheme: textTheme,
textColor: textColor,
disabledTextColor: disabledTextColor,
color: color,
disabledColor: disabledColor,
highlightColor: highlightColor,
splashColor: splashColor,
colorBrightness: colorBrightness,
elevation: elevation,
highlightElevation: highlightElevation,
disabledElevation: disabledElevation,
padding: padding,
shape: shape,
clipBehavior: clipBehavior,
materialTapTargetSize: materialTapTargetSize,
animationDuration: animationDuration,
child: child) {
D.assert(elevation == null || elevation >= 0.0);
D.assert(highlightElevation == null || highlightElevation >= 0.0);
D.assert(disabledElevation == null || disabledElevation >= 0.0);
}
public static RaisedButton icon(
Key key = null,
VoidCallback onPressed = null,
ValueChanged<bool> onHighlightChanged = null,
ButtonTextTheme? textTheme = null,
Color textColor = null,
Color disabledTextColor = null,
Color color = null,
Color disabledColor = null,
Color highlightColor = null,
Color splashColor = null,
Brightness? colorBrightness = null,
double? elevation = null,
double? highlightElevation = null,
double? disabledElevation = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
Clip? clipBehavior = null,
MaterialTapTargetSize? materialTapTargetSize = null,
TimeSpan? animationDuration = null,
Widget icon = null,
Widget label = null) {
D.assert(icon != null);
D.assert(label != null);
return new _RaisedButtonWithIcon(
key: key,
onPressed: onPressed,
onHighlightChanged: onHighlightChanged,
textTheme: textTheme,
textColor: textColor,
disabledTextColor: disabledTextColor,
color: color,
disabledColor: disabledColor,
highlightColor: highlightColor,
splashColor: splashColor,
colorBrightness: colorBrightness,
elevation: elevation,
highlightElevation: highlightElevation,
disabledElevation: disabledElevation,
padding: padding,
shape: shape,
clipBehavior: clipBehavior,
materialTapTargetSize: materialTapTargetSize,
animationDuration: animationDuration,
icon: icon,
label: label);
}
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
ButtonThemeData buttonTheme = ButtonTheme.of(context);
return new RawMaterialButton(
onPressed: this.onPressed,
onHighlightChanged: this.onHighlightChanged,
clipBehavior: this.clipBehavior ?? Clip.none,
fillColor: buttonTheme.getFillColor(this),
textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)),
highlightColor: buttonTheme.getHighlightColor(this),
splashColor: buttonTheme.getSplashColor(this),
elevation: buttonTheme.getElevation(this),
highlightElevation: buttonTheme.getHighlightElevation(this),
disabledElevation: buttonTheme.getDisabledElevation(this),
padding: buttonTheme.getPadding(this),
constraints: buttonTheme.getConstraints(this),
shape: buttonTheme.getShape(this),
animationDuration: buttonTheme.getAnimationDuration(this),
materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this),
child: this.child
);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new ObjectFlagProperty<VoidCallback>("onPressed", this.onPressed, ifNull: "disabled"));
properties.add(new DiagnosticsProperty<ButtonTextTheme?>("textTheme", this.textTheme, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("textColor", this.textColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("disabledTextColor", this.disabledTextColor,
defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("color", this.color, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("disabledColor", this.disabledColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("highlightColor", this.highlightColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Color>("splashColor", this.splashColor, defaultValue: null));
properties.add(new DiagnosticsProperty<Brightness?>("colorBrightness", this.colorBrightness,
defaultValue: null));
properties.add(new DiagnosticsProperty<double?>("elevation", this.elevation, defaultValue: null));
properties.add(new DiagnosticsProperty<double?>("highlightElevation", this.highlightElevation,
defaultValue: null));
properties.add(new DiagnosticsProperty<double?>("disabledElevation", this.disabledElevation,
defaultValue: null));
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", this.padding, defaultValue: null));
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", this.shape, defaultValue: null));
properties.add(new DiagnosticsProperty<MaterialTapTargetSize?>("materialTapTargetSize",
this.materialTapTargetSize, defaultValue: null));
}
}
class _RaisedButtonWithIcon : RaisedButton, MaterialButtonWithIconMixin {
public _RaisedButtonWithIcon(
Key key = null,
VoidCallback onPressed = null,
ValueChanged<bool> onHighlightChanged = null,
ButtonTextTheme? textTheme = null,
Color textColor = null,
Color disabledTextColor = null,
Color color = null,
Color disabledColor = null,
Color highlightColor = null,
Color splashColor = null,
Brightness? colorBrightness = null,
double? elevation = null,
double? highlightElevation = null,
double? disabledElevation = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
Clip? clipBehavior = Clip.none,
MaterialTapTargetSize? materialTapTargetSize = null,
TimeSpan? animationDuration = null,
Widget icon = null,
Widget label = null
) : base(
key: key,
onPressed: onPressed,
onHighlightChanged: onHighlightChanged,
textTheme: textTheme,
textColor: textColor,
disabledTextColor: disabledTextColor,
color: color,
disabledColor: disabledColor,
highlightColor: highlightColor,
splashColor: splashColor,
colorBrightness: colorBrightness,
elevation: elevation,
highlightElevation: highlightElevation,
disabledElevation: disabledElevation,
padding: padding,
shape: shape,
clipBehavior: clipBehavior,
materialTapTargetSize: materialTapTargetSize,
animationDuration: animationDuration,
child: new Row(
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
icon,
new SizedBox(width: 8.0),
label
}
)) {
D.assert(elevation == null || elevation >= 0.0);
D.assert(highlightElevation == null || highlightElevation >= 0.0);
D.assert(disabledElevation == null || disabledElevation >= 0.0);
D.assert(icon != null);
D.assert(label != null);
}
}
}

11
Runtime/material/raised_button.cs.meta


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

106
Runtime/material/shadows.cs


using System.Collections.Generic;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.material {
public class ShadowConstants {
static readonly Color _kKeyUmbraOpacity = new Color(0x33000000); // alpha = 0.2
static readonly Color _kKeyPenumbraOpacity = new Color(0x24000000); // alpha = 0.14
static readonly Color _kAmbientShadowOpacity = new Color(0x1F000000); // alpha = 0.12
public static readonly Dictionary<int, List<BoxShadow>> kElevationToShadow =
new Dictionary<int, List<BoxShadow>> {
{
1, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 2.0), blurRadius: 1.0, spreadRadius: -1.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 1.0), blurRadius: 1.0, spreadRadius: 0.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 1.0), blurRadius: 3.0, spreadRadius: 0.0,
color: _kAmbientShadowOpacity)
}
}, {
2, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 3.0), blurRadius: 1.0, spreadRadius: -2.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 2.0), blurRadius: 2.0, spreadRadius: 0.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 1.0), blurRadius: 5.0, spreadRadius: 0.0,
color: _kAmbientShadowOpacity)
}
}, {
3, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 3.0), blurRadius: 3.0, spreadRadius: -2.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 3.0), blurRadius: 4.0, spreadRadius: 0.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 1.0), blurRadius: 8.0, spreadRadius: 0.0,
color: _kAmbientShadowOpacity)
}
}, {
4, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 2.0), blurRadius: 4.0, spreadRadius: -1.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 4.0), blurRadius: 5.0, spreadRadius: 0.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 1.0), blurRadius: 10.0, spreadRadius: 0.0,
color: _kAmbientShadowOpacity)
}
}, {
6, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 3.0), blurRadius: 5.0, spreadRadius: -1.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 6.0), blurRadius: 10.0, spreadRadius: 0.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 1.0), blurRadius: 18.0, spreadRadius: 0.0,
color: _kAmbientShadowOpacity)
}
}, {
8, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 5.0), blurRadius: 5.0, spreadRadius: -3.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 8.0), blurRadius: 10.0, spreadRadius: 1.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 3.0), blurRadius: 14.0, spreadRadius: 2.0,
color: _kAmbientShadowOpacity)
}
}, {
9, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 5.0), blurRadius: 6.0, spreadRadius: -3.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 9.0), blurRadius: 12.0, spreadRadius: 1.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 3.0), blurRadius: 16.0, spreadRadius: 2.0,
color: _kAmbientShadowOpacity)
}
}, {
12, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 7.0), blurRadius: 8.0, spreadRadius: -4.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 12.0), blurRadius: 17.0, spreadRadius: 2.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 5.0), blurRadius: 22.0, spreadRadius: 4.0,
color: _kAmbientShadowOpacity)
}
}, {
16, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 8.0), blurRadius: 10.0, spreadRadius: -5.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 16.0), blurRadius: 24.0, spreadRadius: 2.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 6.0), blurRadius: 30.0, spreadRadius: 5.0,
color: _kAmbientShadowOpacity)
}
}, {
24, new List<BoxShadow> {
new BoxShadow(offset: new Offset(0.0, 11.0), blurRadius: 15.0, spreadRadius: -7.0,
color: _kKeyUmbraOpacity),
new BoxShadow(offset: new Offset(0.0, 24.0), blurRadius: 38.0, spreadRadius: 3.0,
color: _kKeyPenumbraOpacity),
new BoxShadow(offset: new Offset(0.0, 9.0), blurRadius: 46.0, spreadRadius: 8.0,
color: _kAmbientShadowOpacity)
}
}
};
}
}

11
Runtime/material/shadows.cs.meta


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

271
Runtime/material/tooltip.cs


using Unity.UIWidgets.animation;
using Unity.UIWidgets.async;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class Tooltip : StatefulWidget {
public Tooltip(
Key key = null,
string message = null,
double height = 32.0,
EdgeInsets padding = null,
double verticalOffset = 24.0,
bool preferBelow = true,
Widget child = null
) : base(key: key) {
D.assert(message != null);
this.message = message;
this.height = height;
this.padding = padding ?? EdgeInsets.symmetric(horizontal: 16.0);
this.verticalOffset = verticalOffset;
this.preferBelow = preferBelow;
this.child = child;
}
public readonly string message;
public readonly double height;
public readonly EdgeInsets padding;
public readonly double verticalOffset;
public readonly bool preferBelow;
public readonly Widget child;
public override State createState() {
return new _TooltipState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new StringProperty("message", this.message, showName: false));
properties.add(new DoubleProperty("vertical offset", this.verticalOffset));
properties.add(new FlagProperty("position", value: this.preferBelow, ifTrue: "below", ifFalse: "above",
showName: true));
}
}
public class _TooltipState : SingleTickerProviderStateMixin<Tooltip> {
AnimationController _controller;
OverlayEntry _entry;
Timer _timer;
public override void initState() {
base.initState();
this._controller = new AnimationController(duration: TooltipUtils._kFadeDuration, vsync: this);
this._controller.addStatusListener(this._handleStatusChanged);
}
void _handleStatusChanged(AnimationStatus status) {
if (status == AnimationStatus.dismissed) {
this._removeEntry();
}
}
bool ensureTooltopVisible() {
if (this._entry != null) {
this._timer?.cancel();
this._timer = null;
this._controller.forward();
return false;
}
RenderBox box = (RenderBox) this.context.findRenderObject();
Offset target = box.localToGlobal(box.size.center(Offset.zero));
Widget overlay = new _TooltipOverlay(
message: this.widget.message,
height: this.widget.height,
padding: this.widget.padding,
animation: new CurvedAnimation(
parent: this._controller,
curve: Curves.fastOutSlowIn),
target: target,
verticalOffset: this.widget.verticalOffset,
preferBelow: this.widget.preferBelow
);
this._entry = new OverlayEntry(builder: (BuildContext context) => overlay);
Overlay.of(this.context, debugRequiredFor: this.widget).insert(this._entry);
GestureBinding.instance.pointerRouter.addGlobalRoute(this._handlePointerEvent);
this._controller.forward();
return true;
}
void _removeEntry() {
D.assert(this._entry != null);
this._timer?.cancel();
this._timer = null;
this._entry.remove();
this._entry = null;
GestureBinding.instance.pointerRouter.removeGlobalRoute(this._handlePointerEvent);
}
void _handlePointerEvent(PointerEvent pEvent) {
D.assert(this._entry != null);
if (pEvent is PointerUpEvent || pEvent is PointerCancelEvent) {
this._timer = this._timer ?? Window.instance.run(TooltipUtils._kShowDuration,
() => this._controller.reverse());
}
else if (pEvent is PointerDownEvent) {
this._controller.reverse();
}
}
public override void deactivate() {
if (this._entry != null) {
this._controller.reverse();
}
base.deactivate();
}
public override void dispose() {
if (this._entry != null) {
this._removeEntry();
}
this._controller.dispose();
base.dispose();
}
void _handleLongPress() {
}
public override Widget build(BuildContext context) {
D.assert(Overlay.of(context, debugRequiredFor: this.widget) != null);
return new GestureDetector(
behavior: HitTestBehavior.opaque,
onLongPress: this._handleLongPress,
child: this.widget.child
);
}
}
public class _TooltipPositionDelegate : SingleChildLayoutDelegate {
public _TooltipPositionDelegate(
Offset target = null,
double? verticalOffset = null,
bool? preferBelow = null) {
D.assert(target != null);
D.assert(verticalOffset != null);
D.assert(preferBelow != null);
this.target = target;
this.verticalOffset = verticalOffset ?? 0.0;
this.preferBelow = preferBelow ?? true;
}
public readonly Offset target;
public readonly double verticalOffset;
public readonly bool preferBelow;
public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return constraints.loosen();
}
public override Offset getPositionForChild(Size size, Size childSize) {
return Geometry.positionDependentBox(
size: size,
childSize: childSize,
target: this.target,
verticalOffset: this.verticalOffset,
preferBelow: this.preferBelow);
}
public override bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) {
_TooltipPositionDelegate _oldDelegate = (_TooltipPositionDelegate) oldDelegate;
return this.target != _oldDelegate.target ||
this.verticalOffset != _oldDelegate.verticalOffset ||
this.preferBelow != _oldDelegate.preferBelow;
}
}
class _TooltipOverlay : StatelessWidget {
public _TooltipOverlay(
Key key = null,
string message = null,
double? height = null,
EdgeInsets padding = null,
Animation<double> animation = null,
Offset target = null,
double? verticalOffset = null,
bool? preferBelow = null
) : base(key: key) {
this.message = message;
this.height = height;
this.padding = padding;
this.animation = animation;
this.target = target;
this.verticalOffset = verticalOffset;
this.preferBelow = preferBelow;
}
public readonly string message;
public readonly double? height;
public readonly EdgeInsets padding;
public readonly Animation<double> animation;
public readonly Offset target;
public readonly double? verticalOffset;
public readonly bool? preferBelow;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
ThemeData darkTheme = new ThemeData(
brightness: Brightness.dark,
textTheme: theme.brightness == Brightness.dark ? theme.textTheme : theme.primaryTextTheme
);
return Positioned.fill(
child: new IgnorePointer(
child: new CustomSingleChildLayout(
layoutDelegate: new _TooltipPositionDelegate(
target: this.target,
verticalOffset: this.verticalOffset,
preferBelow: this.preferBelow),
child: new FadeTransition(
opacity: this.animation,
child: new Opacity(
opacity: 0.9,
child: new ConstrainedBox(
constraints: new BoxConstraints(minHeight: this.height ?? 0.0),
child: new Container(
decoration: new BoxDecoration(
color: darkTheme.backgroundColor,
borderRadius: BorderRadius.circular(2.0)),
padding: this.padding,
child: new Center(
widthFactor: 1.0,
heightFactor: 1.0,
child: new Text(this.message, style: darkTheme.textTheme.body1)
)
)
)
)
)
)
)
);
}
}
}

11
Runtime/material/tooltip.cs.meta


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

51
Runtime/painting/geometry.cs


using System;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.painting {
public static class Geometry {
public static Offset positionDependentBox(
Size size = null,
Size childSize = null,
Offset target = null,
bool? preferBelow = null,
double verticalOffset = 0.0,
double margin = 10.0) {
D.assert(size != null);
D.assert(childSize != null);
D.assert(target != null);
D.assert(preferBelow != null);
bool fitsBelow = target.dy + verticalOffset + childSize.height <= size.height - margin;
bool fitsAbove = target.dy - verticalOffset - childSize.height >= margin;
bool tooltipBelow = (preferBelow ?? true) ? (fitsBelow || !fitsAbove) : !(fitsAbove || !fitsBelow);
double y;
if (tooltipBelow) {
y = Math.Min(target.dy + verticalOffset, size.height - margin);
}
else {
y = Math.Max(target.dy - verticalOffset - childSize.height, margin);
}
double x;
if (size.width - margin * 2.0 < childSize.width) {
x = (size.width - childSize.width) / 2.0;
}
else {
double normalizedTargetX = target.dx.clamp(margin, size.width - margin);
double edge = margin + childSize.width / 2.0;
if (normalizedTargetX < edge) {
x = margin;
}
else if (normalizedTargetX > size.width - edge) {
x = size.width - margin - childSize.width;
}
else {
x = normalizedTargetX - childSize.width / 2.0;
}
}
return new Offset(x, y);
}
}
}

11
Runtime/painting/geometry.cs.meta


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

204
Runtime/rendering/animated_size.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.rendering {
public enum RenderAnimatedSizeState {
start,
stable,
changed,
unstable
}
public class RenderAnimatedSize : RenderAligningShiftedBox {
public RenderAnimatedSize(
TickerProvider vsync = null,
TimeSpan? duration = null,
Curve curve = null,
Alignment alignment = null,
RenderBox child = null
) : base(child: child, alignment: alignment ?? Alignment.center) {
D.assert(vsync != null);
D.assert(duration != null);
curve = curve ?? Curves.linear;
this._vsync = vsync;
this._controller = new AnimationController(
vsync: this.vsync,
duration: duration);
this._controller.addListener(() => {
if (this._controller.value != this._lastValue) {
this.markNeedsLayout();
}
});
this._animation = new CurvedAnimation(
parent: this._controller,
curve: curve);
}
AnimationController _controller;
CurvedAnimation _animation;
readonly SizeTween _sizeTween = new SizeTween();
bool _hasVisualOverflow;
double _lastValue;
public RenderAnimatedSizeState state {
get { return this._state; }
}
RenderAnimatedSizeState _state = RenderAnimatedSizeState.start;
public TimeSpan? duration {
get { return this._controller.duration; }
set {
D.assert(value != null);
if (value == this._controller.duration) {
return;
}
this._controller.duration = value;
}
}
public Curve curve {
get { return this._animation.curve; }
set {
D.assert(value != null);
if (value == this._animation.curve) {
return;
}
this._animation.curve = value;
}
}
public bool isAnimating {
get { return this._controller.isAnimating; }
}
public TickerProvider vsync {
get { return this._vsync; }
set {
D.assert(value != null);
if (value == this._vsync) {
return;
}
this._vsync = value;
this._controller.resync(this.vsync);
}
}
TickerProvider _vsync;
public override void detach() {
this._controller.stop();
base.detach();
}
Size _animatedSize {
get { return this._sizeTween.evaluate(this._animation); }
}
protected override void performLayout() {
this._lastValue = this._controller.value;
this._hasVisualOverflow = false;
if (this.child == null || this.constraints.isTight) {
this._controller.stop();
this.size = this._sizeTween.begin = this._sizeTween.end = this.constraints.smallest;
this._state = RenderAnimatedSizeState.start;
this.child?.layout(this.constraints);
return;
}
this.child.layout(this.constraints, parentUsesSize: true);
switch (this._state) {
case RenderAnimatedSizeState.start:
this._layoutStart();
break;
case RenderAnimatedSizeState.stable:
this._layoutStable();
break;
case RenderAnimatedSizeState.changed:
this._layoutChanged();
break;
case RenderAnimatedSizeState.unstable:
this._layoutUnstable();
break;
}
this.size = this.constraints.constrain(this._animatedSize);
this.alignChild();
if (this.size.width < this._sizeTween.end.width ||
this.size.height < this._sizeTween.end.height) {
this._hasVisualOverflow = true;
}
}
void _restartAnimation() {
this._lastValue = 0.0;
this._controller.forward(from: 0.0);
}
void _layoutStart() {
this._sizeTween.begin = this._sizeTween.end = this.debugAdoptSize(this.child.size);
this._state = RenderAnimatedSizeState.stable;
}
void _layoutStable() {
if (this._sizeTween.end != this.child.size) {
this._sizeTween.begin = this.size;
this._sizeTween.end = this.debugAdoptSize(this.child.size);
this._restartAnimation();
this._state = RenderAnimatedSizeState.changed;
}
else if (this._controller.value == this._controller.upperBound) {
this._sizeTween.begin = this._sizeTween.end = this.debugAdoptSize(this.child.size);
}
else if (!this._controller.isAnimating) {
this._controller.forward();
}
}
void _layoutChanged() {
if (this._sizeTween.end != this.child.size) {
this._sizeTween.begin = this._sizeTween.end = this.debugAdoptSize(this.child.size);
this._restartAnimation();
this._state = RenderAnimatedSizeState.unstable;
}
else {
this._state = RenderAnimatedSizeState.stable;
if (!this._controller.isAnimating) {
this._controller.forward();
}
}
}
void _layoutUnstable() {
if (this._sizeTween.end != this.child.size) {
this._sizeTween.begin = this._sizeTween.end = this.debugAdoptSize(this.child.size);
this._restartAnimation();
}
else {
this._controller.stop();
this._state = RenderAnimatedSizeState.stable;
}
}
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null && this._hasVisualOverflow) {
Rect rect = Offset.zero & this.size;
context.pushClipRect(this.needsCompositing, offset, rect, base.paint);
}
else {
base.paint(context, offset);
}
}
}
}

11
Runtime/rendering/animated_size.cs.meta


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

280
Runtime/rendering/list_body.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.rendering {
public class ListBodyParentData : ContainerParentDataMixinBoxParentData<RenderBox> {
}
delegate double __ChildSizingFunction(RenderBox child);
public class RenderListBody : RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox<RenderBox,
ListBodyParentData> {
public RenderListBody(
List<RenderBox> children = null,
AxisDirection axisDirection = AxisDirection.down) {
this._axisDirection = axisDirection;
this.addAll(children);
}
public override void setupParentData(RenderObject child) {
if (!(child.parentData is ListBodyParentData)) {
child.parentData = new ListBodyParentData();
}
}
public AxisDirection axisDirection {
get { return this._axisDirection; }
set {
if (this._axisDirection == value) {
return;
}
this._axisDirection = value;
this.markNeedsLayout();
}
}
AxisDirection _axisDirection;
public Axis mainAxis {
get { return AxisUtils.axisDirectionToAxis(this.axisDirection); }
}
protected override void performLayout() {
D.assert(() => {
switch (this.mainAxis) {
case Axis.horizontal:
if (!this.constraints.hasBoundedWidth) {
return true;
}
break;
case Axis.vertical:
if (!this.constraints.hasBoundedHeight) {
return true;
}
break;
}
throw new UIWidgetsError(
"RenderListBody must have unlimited space along its main axis.\n" +
"RenderListBody does not clip or resize its children, so it must be " +
"placed in a parent that does not constrain the main " +
"axis. You probably want to put the RenderListBody inside a " +
"RenderViewport with a matching main axis.");
});
D.assert(() => {
switch (this.mainAxis) {
case Axis.horizontal:
if (this.constraints.hasBoundedHeight) {
return true;
}
break;
case Axis.vertical:
if (this.constraints.hasBoundedWidth) {
return true;
}
break;
}
throw new UIWidgetsError(
"RenderListBody must have a bounded constraint for its cross axis.\n" +
"RenderListBody forces its children to expand to fit the RenderListBody\"s container, " +
"so it must be placed in a parent that constrains the cross " +
"axis to a finite dimension. If you are attempting to nest a RenderListBody with " +
"one direction inside one of another direction, you will want to " +
"wrap the inner one inside a box that fixes the dimension in that direction, " +
"for example, a RenderIntrinsicWidth or RenderIntrinsicHeight object. " +
"This is relatively expensive, however."
);
});
double mainAxisExtent = 0.0;
RenderBox child = this.firstChild;
BoxConstraints innerConstraints;
double position;
switch (this.axisDirection) {
case AxisDirection.right:
innerConstraints = BoxConstraints.tightFor(height: this.constraints.maxHeight);
while (child != null) {
child.layout(innerConstraints, parentUsesSize: true);
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
childParentData.offset = new Offset(mainAxisExtent, 0.0);
mainAxisExtent += child.size.width;
D.assert(child.parentData == childParentData);
child = childParentData.nextSibling;
}
this.size = this.constraints.constrain(new Size(mainAxisExtent, this.constraints.maxHeight));
break;
case AxisDirection.left:
innerConstraints = BoxConstraints.tightFor(height: this.constraints.maxHeight);
while (child != null) {
child.layout(innerConstraints, parentUsesSize: true);
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
mainAxisExtent += child.size.width;
D.assert(child.parentData == childParentData);
child = childParentData.nextSibling;
}
position = 0.0;
child = this.firstChild;
while (child != null) {
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
position += child.size.width;
childParentData.offset = new Offset(mainAxisExtent - position, 0.0);
D.assert(child.parentData == childParentData);
child = childParentData.nextSibling;
}
this.size = this.constraints.constrain(new Size(mainAxisExtent, this.constraints.maxHeight));
break;
case AxisDirection.down:
innerConstraints = BoxConstraints.tightFor(width: this.constraints.maxWidth);
while (child != null) {
child.layout(innerConstraints, parentUsesSize: true);
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
childParentData.offset = new Offset(0.0, mainAxisExtent);
mainAxisExtent += child.size.height;
D.assert(child.parentData == childParentData);
child = childParentData.nextSibling;
}
this.size = this.constraints.constrain(new Size(this.constraints.maxWidth, mainAxisExtent));
break;
case AxisDirection.up:
innerConstraints = BoxConstraints.tightFor(width: this.constraints.maxWidth);
while (child != null) {
child.layout(innerConstraints, parentUsesSize: true);
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
mainAxisExtent += child.size.height;
D.assert(child.parentData == childParentData);
child = childParentData.nextSibling;
}
position = 0.0;
child = this.firstChild;
while (child != null) {
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
position += child.size.height;
childParentData.offset = new Offset(0.0, mainAxisExtent - position);
D.assert(child.parentData == childParentData);
child = childParentData.nextSibling;
}
this.size = this.constraints.constrain(new Size(this.constraints.maxWidth, mainAxisExtent));
break;
}
D.assert(this.size.isFinite);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<AxisDirection>("axisDirection", this.axisDirection));
}
double _getIntrinsicCrossAxis(__ChildSizingFunction childSize) {
double extent = 0.0;
RenderBox child = this.firstChild;
while (child != null) {
extent = Math.Max(extent, childSize(child));
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
child = childParentData.nextSibling;
}
return extent;
}
double _getIntrinsicMainAxis(__ChildSizingFunction childSize) {
double extent = 0.0;
RenderBox child = this.firstChild;
while (child != null) {
extent += childSize(child);
ListBodyParentData childParentData = (ListBodyParentData) child.parentData;
child = childParentData.nextSibling;
}
return extent;
}
protected override double computeMinIntrinsicWidth(double height) {
switch (this.mainAxis) {
case Axis.horizontal:
return this._getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicWidth(height));
case Axis.vertical:
return this._getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicWidth(height));
}
D.assert(false);
return 0.0;
}
protected override double computeMaxIntrinsicWidth(double height) {
switch (this.mainAxis) {
case Axis.horizontal:
return this._getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicWidth(height));
case Axis.vertical:
return this._getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicWidth(height));
}
D.assert(false);
return 0.0;
}
protected override double computeMinIntrinsicHeight(double width) {
switch (this.mainAxis) {
case Axis.horizontal:
return this._getIntrinsicMainAxis((RenderBox child) => child.getMinIntrinsicHeight(width));
case Axis.vertical:
return this._getIntrinsicCrossAxis((RenderBox child) => child.getMinIntrinsicHeight(width));
}
D.assert(false);
return 0.0;
}
protected override double computeMaxIntrinsicHeight(double width) {
switch (this.mainAxis) {
case Axis.horizontal:
return this._getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));
case Axis.vertical:
return this._getIntrinsicCrossAxis((RenderBox child) => child.getMaxIntrinsicHeight(width));
}
D.assert(false);
return 0.0;
}
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
return this.defaultComputeDistanceToFirstActualBaseline(baseline);
}
public override void paint(PaintingContext context, Offset offset) {
this.defaultPaint(context, offset);
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
return this.defaultHitTestChildren(result, position: position);
}
}
}

11
Runtime/rendering/list_body.cs.meta


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

16
Runtime/rendering/tweens.cs


using Unity.UIWidgets.animation;
using Unity.UIWidgets.painting;
namespace Unity.UIWidgets.rendering {
public class AlignmentTween : Tween<Alignment> {
public AlignmentTween(
Alignment begin = null,
Alignment end = null)
: base(begin: begin, end: end) {
}
public override Alignment lerp(double t) {
return Alignment.lerp(this.begin, this.end, t);
}
}
}

11
Runtime/rendering/tweens.cs.meta


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

20
Runtime/utils/axis_direction.cs


using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.utils {
public static class AxisDirectionUtils {
public static AxisDirection? getAxisDirectionFromAxisReverseAndDirectionality(
BuildContext context,
Axis axis,
bool reverse) {
switch (axis) {
case Axis.horizontal:
return reverse ? AxisDirection.left : AxisDirection.right;
case Axis.vertical:
return reverse ? AxisDirection.up : AxisDirection.down;
}
return null;
}
}
}

11
Runtime/utils/axis_direction.cs.meta


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

228
Runtime/widgets/animated_cross_fade.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
namespace Unity.UIWidgets.widgets {
public enum CrossFadeState {
showFirst,
showSecond
}
public delegate Widget AnimatedCrossFadeBuilder(Widget topChild, Key topChildKey, Widget bottomChild,
Key bottomChildKey);
public class AnimatedCrossFade : StatefulWidget {
public AnimatedCrossFade(
Key key = null,
Widget firstChild = null,
Widget secondChild = null,
Curve firstCurve = null,
Curve secondCurve = null,
Curve sizeCurve = null,
Alignment alignment = null,
CrossFadeState? crossFadeState = null,
TimeSpan? duration = null,
AnimatedCrossFadeBuilder layoutBuilder = null
) : base(key: key) {
D.assert(firstChild != null);
D.assert(secondChild != null);
D.assert(crossFadeState != null);
D.assert(duration != null);
this.firstChild = firstChild;
this.secondChild = secondChild;
this.firstCurve = firstCurve ?? Curves.linear;
this.secondCurve = secondCurve ?? Curves.linear;
this.sizeCurve = sizeCurve ?? Curves.linear;
this.alignment = alignment ?? Alignment.topCenter;
this.crossFadeState = crossFadeState ?? CrossFadeState.showFirst;
this.duration = duration ?? TimeSpan.Zero;
this.layoutBuilder = layoutBuilder ?? defaultLayoutBuilder;
}
public readonly Widget firstChild;
public readonly Widget secondChild;
public readonly CrossFadeState crossFadeState;
public readonly TimeSpan duration;
public readonly Curve firstCurve;
public readonly Curve secondCurve;
public readonly Curve sizeCurve;
public readonly Alignment alignment;
public readonly AnimatedCrossFadeBuilder layoutBuilder;
static Widget defaultLayoutBuilder(Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey) {
return new Stack(
overflow: Overflow.visible,
children: new List<Widget> {
new Positioned(
key: bottomChildKey,
left: 0.0,
top: 0.0,
right: 0.0,
child: bottomChild),
new Positioned(
key: topChildKey,
child: topChild)
}
);
}
public override State createState() {
return new _AnimatedCrossFadeState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<CrossFadeState>("crossFadeState", this.crossFadeState));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment,
defaultValue: Alignment.topCenter));
}
}
public class _AnimatedCrossFadeState : TickerProviderStateMixin<AnimatedCrossFade> {
AnimationController _controller;
Animation<double> _firstAnimation;
Animation<double> _secondAnimation;
public override void initState() {
base.initState();
this._controller = new AnimationController(duration: this.widget.duration, vsync: this);
if (this.widget.crossFadeState == CrossFadeState.showSecond) {
this._controller.setValue(1.0);
}
this._firstAnimation = this._initAnimation(this.widget.firstCurve, true);
this._secondAnimation = this._initAnimation(this.widget.secondCurve, false);
this._controller.addStatusListener((AnimationStatus status) => { this.setState(() => { }); });
}
Animation<double> _initAnimation(Curve curve, bool inverted) {
Animation<double> result = this._controller.drive(new CurveTween(curve: curve));
if (inverted) {
result = result.drive(new DoubleTween(begin: 1.0, end: 0.0));
}
return result;
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
AnimatedCrossFade _oldWidget = (AnimatedCrossFade) oldWidget;
if (this.widget.duration != _oldWidget.duration) {
this._controller.duration = this.widget.duration;
}
if (this.widget.firstCurve != _oldWidget.firstCurve) {
this._firstAnimation = this._initAnimation(this.widget.firstCurve, true);
}
if (this.widget.secondCurve != _oldWidget.secondCurve) {
this._secondAnimation = this._initAnimation(this.widget.secondCurve, false);
}
if (this.widget.crossFadeState != _oldWidget.crossFadeState) {
switch (this.widget.crossFadeState) {
case CrossFadeState.showFirst:
this._controller.reverse();
break;
case CrossFadeState.showSecond:
this._controller.forward();
break;
}
}
}
bool _isTransitioning {
get {
return this._controller.status == AnimationStatus.forward ||
this._controller.status == AnimationStatus.reverse;
}
}
public override Widget build(BuildContext context) {
Key kFirstChildKey = new ValueKey<CrossFadeState>(CrossFadeState.showFirst);
Key kSecondChildKey = new ValueKey<CrossFadeState>(CrossFadeState.showSecond);
bool transitioningForwards = this._controller.status == AnimationStatus.completed ||
this._controller.status == AnimationStatus.forward;
Key topKey;
Widget topChild;
Animation<double> topAnimation;
Key bottomKey;
Widget bottomChild;
Animation<double> bottomAnimation;
if (transitioningForwards) {
topKey = kSecondChildKey;
topChild = this.widget.secondChild;
topAnimation = this._secondAnimation;
bottomKey = kFirstChildKey;
bottomChild = this.widget.firstChild;
bottomAnimation = this._firstAnimation;
}
else {
topKey = kFirstChildKey;
topChild = this.widget.firstChild;
topAnimation = this._firstAnimation;
bottomKey = kSecondChildKey;
bottomChild = this.widget.secondChild;
bottomAnimation = this._secondAnimation;
}
bottomChild = new TickerMode(
key: bottomKey,
enabled: this._isTransitioning,
child: new FadeTransition(
opacity: bottomAnimation,
child: bottomChild
)
);
topChild = new TickerMode(
key: topKey,
enabled: true,
child: new FadeTransition(
opacity: topAnimation,
child: topChild
)
);
return new ClipRect(
child: new AnimatedSize(
alignment: this.widget.alignment,
duration: this.widget.duration,
curve: this.widget.sizeCurve,
vsync: this,
child: this.widget.layoutBuilder(topChild, topKey, bottomChild, bottomKey)
)
);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder description) {
base.debugFillProperties(description);
description.add(new EnumProperty<CrossFadeState>("crossFadeState", this.widget.crossFadeState));
description.add(
new DiagnosticsProperty<AnimationController>("controller", this._controller, showName: false));
description.add(new DiagnosticsProperty<Alignment>("alignment", this.widget.alignment,
defaultValue: Alignment.topCenter));
}
}
}

11
Runtime/widgets/animated_cross_fade.cs.meta


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

49
Runtime/widgets/animated_size.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
namespace Unity.UIWidgets.widgets {
public class AnimatedSize : SingleChildRenderObjectWidget {
public AnimatedSize(
Key key = null,
Widget child = null,
Alignment alignment = null,
Curve curve = null,
TimeSpan? duration = null,
TickerProvider vsync = null) : base(key: key, child: child) {
D.assert(duration != null);
D.assert(vsync != null);
this.alignment = alignment ?? Alignment.center;
this.curve = curve ?? Curves.linear;
this.duration = duration ?? TimeSpan.Zero;
this.vsync = vsync;
}
public readonly Alignment alignment;
public readonly Curve curve;
public readonly TimeSpan duration;
public readonly TickerProvider vsync;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderAnimatedSize(
alignment: this.alignment,
duration: this.duration,
curve: this.curve,
vsync: this.vsync);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
RenderAnimatedSize _renderObject = (RenderAnimatedSize) renderObject;
_renderObject.alignment = this.alignment;
_renderObject.duration = this.duration;
_renderObject.curve = this.curve;
_renderObject.vsync = this.vsync;
}
}
}

11
Runtime/widgets/animated_size.cs.meta


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

64
Runtime/widgets/safe_area.cs


using System;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
namespace Unity.UIWidgets.widgets {
public class SafeArea : StatelessWidget {
public SafeArea(
Key key = null,
bool left = true,
bool top = true,
bool right = true,
bool bottom = true,
EdgeInsets mininum = null,
Widget child = null
) : base(key: key) {
D.assert(child != null);
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
this.minimum = mininum ?? EdgeInsets.zero;
this.child = child;
}
public readonly bool left;
public readonly bool top;
public readonly bool right;
public readonly bool bottom;
public readonly EdgeInsets minimum;
public readonly Widget child;
public override Widget build(BuildContext context) {
EdgeInsets padding = MediaQuery.of(context).padding;
return new Padding(
padding: EdgeInsets.only(
left: Math.Max(this.left ? padding.left : 0.0, this.minimum.left),
top: Math.Max(this.top ? padding.top : 0.0, this.minimum.top),
right: Math.Max(this.right ? padding.right : 0.0, this.minimum.right),
bottom: Math.Max(this.bottom ? padding.bottom : 0.0, this.minimum.bottom)
),
child: MediaQuery.removePadding(
context: context,
removeLeft: this.left,
removeTop: this.top,
removeRight: this.right,
removeBottom: this.bottom,
child: this.child));
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FlagProperty("left", value: this.left, ifTrue: "avoid left padding"));
properties.add(new FlagProperty("top", value: this.top, ifTrue: "avoid top padding"));
properties.add(new FlagProperty("right", value: this.right, ifTrue: "avoid right padding"));
properties.add(new FlagProperty("bottom", value: this.bottom, ifTrue: "avoid bottom padding"));
}
}
}

11
Runtime/widgets/safe_area.cs.meta


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

452
Runtime/widgets/single_child_scroll_view.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.utils;
namespace Unity.UIWidgets.widgets {
public class SingleChildScrollView : StatelessWidget {
public SingleChildScrollView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
EdgeInsets padding = null,
bool? primary = null,
ScrollPhysics physics = null,
ScrollController controller = null,
Widget child = null
) : base(key: key) {
D.assert(!(controller != null && primary == true),
"Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. " +
"You cannot both set primary to true and pass an explicit controller.");
this.scrollDirection = scrollDirection;
this.reverse = reverse;
this.padding = padding;
this.primary = primary ?? controller == null && scrollDirection == Axis.vertical;
this.physics = physics;
this.controller = controller;
this.child = child;
}
public readonly Axis scrollDirection;
public readonly bool reverse;
public readonly EdgeInsets padding;
public readonly ScrollController controller;
public readonly bool primary;
public readonly ScrollPhysics physics;
public readonly Widget child;
AxisDirection _getDirection(BuildContext context) {
return AxisDirectionUtils.getAxisDirectionFromAxisReverseAndDirectionality(context, this.scrollDirection,
this.reverse) ?? AxisDirection.down;
}
public override Widget build(BuildContext context) {
AxisDirection axisDirection = this._getDirection(context);
Widget contents = this.child;
if (this.padding != null) {
contents = new Padding(
padding: this.padding,
child: contents);
}
ScrollController scrollController = this.primary
? PrimaryScrollController.of(context)
: this.controller;
Scrollable scrollable = new Scrollable(
axisDirection: axisDirection,
controller: scrollController,
physics: this.physics,
viewportBuilder: (BuildContext subContext, ViewportOffset offset) => {
return new _SingleChildViewport(
axisDirection: axisDirection,
offset: offset,
child: contents);
}
);
if (this.primary && scrollController != null) {
return PrimaryScrollController.none(child: scrollable);
}
return scrollable;
}
}
class _SingleChildViewport : SingleChildRenderObjectWidget {
public _SingleChildViewport(
Key key = null,
AxisDirection axisDirection = AxisDirection.down,
ViewportOffset offset = null,
Widget child = null
) : base(key: key, child: child) {
this.axisDirection = axisDirection;
this.offset = offset;
}
public readonly AxisDirection axisDirection;
public readonly ViewportOffset offset;
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderSingleChildViewport(
axisDirection: this.axisDirection,
offset: this.offset
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
_RenderSingleChildViewport _renderObject = (_RenderSingleChildViewport) renderObject;
_renderObject.axisDirection = this.axisDirection;
_renderObject.offset = this.offset;
}
}
class _RenderSingleChildViewport : RenderObjectWithChildMixinRenderBox<RenderBox>, RenderAbstractViewport {
public _RenderSingleChildViewport(
AxisDirection axisDirection = AxisDirection.down,
ViewportOffset offset = null,
double cacheExtent = RenderViewportUtils.defaultCacheExtent,
RenderBox child = null) {
D.assert(offset != null);
this._axisDirection = axisDirection;
this._offset = offset;
this._cacheExtent = cacheExtent;
this.child = child;
}
public new RenderObject parent {
get { return (RenderObject) base.parent; }
}
public AxisDirection axisDirection {
get { return this._axisDirection; }
set {
if (value == this._axisDirection) {
return;
}
this._axisDirection = value;
this.markNeedsLayout();
}
}
AxisDirection _axisDirection;
public Axis axis {
get { return AxisUtils.axisDirectionToAxis(this.axisDirection); }
}
public ViewportOffset offset {
get { return this._offset; }
set {
D.assert(value != null);
if (value == this._offset) {
return;
}
if (this.attached) {
this.offset.removeListener(this._hasScrolled);
}
this.offset = value;
if (this.attached) {
this._offset.addListener(this._hasScrolled);
}
this.markNeedsLayout();
}
}
ViewportOffset _offset;
public double cacheExtent {
get { return this._cacheExtent; }
set {
if (value == this._cacheExtent) {
return;
}
this._cacheExtent = value;
this.markNeedsLayout();
}
}
double _cacheExtent;
void _hasScrolled() {
this.markNeedsPaint();
}
public override void setupParentData(RenderObject child) {
if (!(child.parentData is ParentData)) {
child.parentData = new ParentData();
}
}
public override void attach(object owner) {
base.attach(owner);
this._offset.addListener(this._hasScrolled);
}
public override void detach() {
this._offset.removeListener(this._hasScrolled);
base.detach();
}
public override bool isRepaintBoundary {
get { return true; }
}
double _viewportExtent {
get {
D.assert(this.hasSize);
switch (this.axis) {
case Axis.horizontal:
return this.size.width;
case Axis.vertical:
return this.size.height;
}
D.assert(false);
return 0.0;
}
}
double _minScrollExtent {
get {
D.assert(this.hasSize);
return 0.0;
}
}
double _maxScrollExtent {
get {
D.assert(this.hasSize);
if (this.child == null) {
return 0.0;
}
switch (this.axis) {
case Axis.horizontal:
return Math.Max(0.0, this.child.size.width - this.size.width);
case Axis.vertical:
return Math.Max(0.0, this.child.size.height - this.size.height);
}
D.assert(false);
return 0.0;
}
}
BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
switch (this.axis) {
case Axis.horizontal:
return constraints.heightConstraints();
case Axis.vertical:
return constraints.widthConstraints();
}
return null;
}
protected override double computeMinIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMinIntrinsicWidth(height);
}
return 0.0;
}
protected override double computeMaxIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMaxIntrinsicWidth(height);
}
return 0.0;
}
protected override double computeMinIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMinIntrinsicHeight(width);
}
return 0.0;
}
protected override double computeMaxIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(width);
}
return 0.0;
}
protected override void performLayout() {
if (this.child == null) {
this.size = this.constraints.smallest;
}
else {
this.child.layout(this._getInnerConstraints(this.constraints), parentUsesSize: true);
this.size = this.constraints.constrain(this.child.size);
}
this.offset.applyViewportDimension(this._viewportExtent);
this.offset.applyContentDimensions(this._minScrollExtent, this._maxScrollExtent);
}
Offset _paintOffset {
get { return this._paintOffsetForPosition(this.offset.pixels); }
}
Offset _paintOffsetForPosition(double position) {
switch (this.axisDirection) {
case AxisDirection.up:
return new Offset(0.0, position - this.child.size.height + this.size.height);
case AxisDirection.down:
return new Offset(0.0, -position);
case AxisDirection.left:
return new Offset(position - this.child.size.width + this.size.width, 0.0);
case AxisDirection.right:
return new Offset(-position, 0.0);
}
return null;
}
bool _shouldClipAtPaintOffset(Offset paintOffset) {
D.assert(this.child != null);
return paintOffset < Offset.zero ||
!(Offset.zero & this.size).contains((paintOffset & this.child.size).bottomRight);
}
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
Offset paintOffset = this._paintOffset;
void paintContents(PaintingContext subContext, Offset SubOffset) {
subContext.paintChild(this.child, SubOffset + paintOffset);
}
if (this._shouldClipAtPaintOffset(paintOffset)) {
context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size, paintContents);
}
else {
paintContents(context, offset);
}
}
}
public override void applyPaintTransform(RenderObject child, Matrix3 transform) {
Offset paintOffset = this._paintOffset;
transform.preTranslate((float) paintOffset.dx, (float) paintOffset.dy);
}
public override Rect describeApproximatePaintClip(RenderObject child) {
if (child != null && this._shouldClipAtPaintOffset(this._paintOffset)) {
return Offset.zero & this.size;
}
return null;
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.child != null) {
Offset transformed = position + (-this._paintOffset);
return this.child.hitTest(result, position: transformed);
}
return false;
}
public RevealedOffset getOffsetToReveal(RenderObject target, double alignment, Rect rect = null) {
rect = rect ?? target.paintBounds;
if (!(target is RenderBox)) {
return new RevealedOffset(offset: this.offset.pixels, rect: rect);
}
RenderBox targetBox = (RenderBox) target;
Matrix3 transform = targetBox.getTransformTo(this);
Rect bounds = transform.mapRect(rect);
Size contentSize = this.child.size;
double leadingScrollOffset = 0.0;
double targetMainAxisExtent = 0.0;
double mainAxisExtent = 0.0;
switch (this.axisDirection) {
case AxisDirection.up:
mainAxisExtent = this.size.height;
leadingScrollOffset = contentSize.height - bounds.bottom;
targetMainAxisExtent = bounds.height;
break;
case AxisDirection.right:
mainAxisExtent = this.size.width;
leadingScrollOffset = bounds.left;
targetMainAxisExtent = bounds.width;
break;
case AxisDirection.down:
mainAxisExtent = this.size.height;
leadingScrollOffset = bounds.top;
targetMainAxisExtent = bounds.height;
break;
case AxisDirection.left:
mainAxisExtent = this.size.width;
leadingScrollOffset = contentSize.width - bounds.right;
targetMainAxisExtent = bounds.width;
break;
}
double targetOffset = leadingScrollOffset - (mainAxisExtent - targetMainAxisExtent) * alignment;
Rect targetRect = bounds.shift(this._paintOffsetForPosition(targetOffset));
return new RevealedOffset(offset: targetOffset, rect: targetRect);
}
public override void showOnScreen(
RenderObject descendant = null,
Rect rect = null,
TimeSpan? duration = null,
Curve curve = null
) {
if (!this.offset.allowImplicitScrolling) {
base.showOnScreen(
descendant: descendant,
rect: rect,
duration: duration,
curve: curve
);
}
Rect newRect = RenderViewport.showInViewport(
descendant: descendant,
viewport: this,
offset: this.offset,
rect: rect,
duration: duration,
curve: curve);
base.showOnScreen(
rect: newRect,
duration: duration,
curve: curve);
}
}
}

11
Runtime/widgets/single_child_scroll_view.cs.meta


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

8
Samples/MaterialSample.meta


fileFormatVersion: 2
guid: 611706478d8aa410983272ad601895d3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

156
Samples/UIWidgetSample/ExpansionPanelCanvas.cs


using System.Collections.Generic;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Material = Unity.UIWidgets.material.Material;
namespace UIWidgetsSample {
public class ExpansionPanelCanvas : WidgetCanvas {
int testCaseId = 1;
readonly List<Widget> testCases = new List<Widget> {
new SingleChildScrollWidget(),
new ExpansionPanelWidget()
};
protected override Widget getWidget() {
return this.testCases[this.testCaseId];
}
}
class SingleChildScrollWidget : StatefulWidget {
public SingleChildScrollWidget(Key key = null) : base(key) {
}
public override State createState() {
return new SingleChildScrollWidgetState();
}
}
class SingleChildScrollWidgetState : State<SingleChildScrollWidget> {
public override Widget build(BuildContext context) {
return new Material(
child: new SingleChildScrollView(
child: new Container(
width: 40.0,
height: 40.0,
constraints: BoxConstraints.tight(new Size(40, 600)),
color: AsScreenCanvas.CLColors.red,
child: new Center(child: new Text("Beijing"))
)
)
);
}
}
class ExpansionPanelWidget : StatefulWidget {
public ExpansionPanelWidget(Key key = null) : base(key) {
}
public override State createState() {
return new ExpansionPanelWidgetState();
}
}
class ExpansionPanelWidgetState : State<ExpansionPanelWidget> {
readonly List<bool> isExpand = new List<bool> {false, false};
public override Widget build(BuildContext context) {
return new Material(
child: new SingleChildScrollView(
child: new ExpansionPanelList(
expansionCallback: (int _index, bool _isExpanded) => {
Debug.Log("<tile " + _index + "> from [" + (_isExpanded ? "Open" : "Close") + "]" +
" to [" + (_isExpanded ? "Close" : "Open") + "]");
this.isExpand[_index] = !_isExpanded;
this.setState(() => { });
},
children: new List<ExpansionPanel> {
new ExpansionPanel(
headerBuilder: (BuildContext subContext, bool isExpanded) => {
return new Container(
color: Colors.black45,
child: new Center(
child: new Text("Beijing")
)
);
},
body: new Container(
child: new Column(
children: new List<Widget> {
new Card(
child: new Container(
color: Colors.black38,
height: 36,
width: 300,
child: new Center(
child: new Text("Beijing")
)
)
)
}
)
),
isExpanded: this.isExpand[0]
),
new ExpansionPanel(
headerBuilder: (BuildContext subContext, bool isExpanded) => {
return new Container(
color: Colors.black45,
child: new Center(
child: new Text("Hebei")
)
);
},
body: new Container(
child: new Column(
children: new List<Widget> {
new Card(
child: new Container(
color: Colors.black38,
height: 36,
width: 300,
child: new Center(
child: new Text("Tianjin")
)
)
),
new Card(
child: new Container(
color: Colors.black38,
height: 36,
width: 300,
child: new Center(
child: new Text("Shijiazhuang")
)
)
),
new Card(
child: new Container(
color: Colors.black38,
height: 36,
width: 300,
child: new Center(
child: new Text("Zhumadian")
)
)
)
}
)
),
isExpanded: this.isExpand[1]
),
}
)
)
);
}
}
}

11
Samples/UIWidgetSample/ExpansionPanelCanvas.cs.meta


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

95
Samples/MaterialSample/DividerButtonCanvas.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.widgets;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.material;
using Unity.UIWidgets.ui;
using Color = Unity.UIWidgets.ui.Color;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsSample {
public class DividerButtonCanvas : WidgetCanvas {
protected override Widget getWidget() {
return new DemoApp();
}
public class DemoApp : StatefulWidget {
public DemoApp(Key key = null) : base(key) {
}
public override State createState() {
return new _DemoAppState();
}
}
public class _DemoAppState : State<DemoApp> {
string title = "Hello";
string subtitle = "World";
TextEditingController controller = new TextEditingController("");
public override Widget build(BuildContext context) {
return new Container(
height: 200,
padding: EdgeInsets.all(10),
decoration: new BoxDecoration(
color: new Color(0xFFEF1F7F),
border: Border.all(color: Color.fromARGB(255, 0xDF, 0x10, 0x70), width: 5),
borderRadius: BorderRadius.all(20)
),
child: new Center(
child: new Column(
children: new List<Widget>() {
new Text(title),
new Divider(),
new Text(subtitle),
new Divider(),
new Container(
width: 500,
decoration: new BoxDecoration(border: Border.all(new Color(0xFF00FF00), 1)),
child: new EditableText(
controller: controller,
focusNode: new FocusNode(),
style: new TextStyle(
fontSize: 18,
height: 1.5f,
color: new Color(0xFFFF89FD)),
cursorColor: Color.fromARGB(255, 0, 0, 0)
)
),
new Divider(),
new ButtonBar(
children: new List<Widget> {
new FlatButton(
onPressed: () => {
setState(() => {
title = controller.text;
});
},
padding: EdgeInsets.all(5.0),
child: new Center(
child: new Text("Set Title")
)
),
new RaisedButton(
onPressed: () => {
setState(() => {
subtitle = controller.text;
});
},
padding: EdgeInsets.all(5.0),
child: new Center(
child: new Text("Set Subtitle")
)
)
}
)
}
)
)
);
}
}
}
}

11
Samples/MaterialSample/DividerButtonCanvas.cs.meta


fileFormatVersion: 2
guid: 7d02ebc8543484a84b26e073e5ec501f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存