浏览代码

Merge branch 'material' into material_yczhang

/main
Yuncong Zhang 6 年前
当前提交
c05d7130
共有 56 个文件被更改,包括 5115 次插入92 次删除
  1. 3
      Runtime/animation/tween.cs
  2. 6
      Runtime/material/arc.cs
  3. 2
      Runtime/material/debug.cs
  4. 22
      Runtime/material/divider.cs
  5. 175
      Runtime/material/expansion_tile.cs
  6. 94
      Runtime/material/icon_button.cs
  7. 6
      Runtime/material/ink_well.cs
  8. 31
      Runtime/material/material.cs
  9. 5
      Runtime/material/shadows.cs
  10. 30
      Runtime/material/utils.cs
  11. 125
      Runtime/rendering/proxy_box.cs
  12. 2
      Runtime/service/system_chrome.cs
  13. 120
      Runtime/widgets/basic.cs
  14. 191
      Runtime/widgets/implicit_animations.cs
  15. 33
      Runtime/widgets/transitions.cs
  16. 11
      Samples/UIWidgetSample/MaterialCanvas.cs
  17. 11
      Runtime/material/divider.cs.meta
  18. 304
      Runtime/material/drawer.cs
  19. 11
      Runtime/material/drawer.cs.meta
  20. 71
      Runtime/material/drawer_header.cs
  21. 11
      Runtime/material/drawer_header.cs.meta
  22. 93
      Runtime/material/expand_icon.cs
  23. 11
      Runtime/material/expand_icon.cs.meta
  24. 318
      Runtime/material/expansion_panel.cs
  25. 11
      Runtime/material/expansion_panel.cs.meta
  26. 53
      Runtime/material/grid_tile.cs
  27. 11
      Runtime/material/grid_tile.cs.meta
  28. 11
      Runtime/material/icon_button.cs.meta
  29. 7
      Runtime/material/icons.cs
  30. 11
      Runtime/material/icons.cs.meta
  31. 841
      Runtime/material/list_tile.cs
  32. 11
      Runtime/material/list_tile.cs.meta
  33. 714
      Runtime/material/mergeable_material.cs
  34. 11
      Runtime/material/mergeable_material.cs.meta
  35. 269
      Runtime/material/tooltip.cs
  36. 11
      Runtime/material/tooltip.cs.meta
  37. 51
      Runtime/painting/geometry.cs
  38. 11
      Runtime/painting/geometry.cs.meta
  39. 204
      Runtime/rendering/animated_size.cs
  40. 11
      Runtime/rendering/animated_size.cs.meta
  41. 276
      Runtime/rendering/list_body.cs
  42. 11
      Runtime/rendering/list_body.cs.meta
  43. 16
      Runtime/rendering/tweens.cs
  44. 11
      Runtime/rendering/tweens.cs.meta
  45. 20
      Runtime/utils/axis_direction.cs
  46. 11
      Runtime/utils/axis_direction.cs.meta
  47. 228
      Runtime/widgets/animated_cross_fade.cs
  48. 11
      Runtime/widgets/animated_cross_fade.cs.meta
  49. 49
      Runtime/widgets/animated_size.cs
  50. 11
      Runtime/widgets/animated_size.cs.meta
  51. 63
      Runtime/widgets/safe_area.cs
  52. 11
      Runtime/widgets/safe_area.cs.meta
  53. 451
      Runtime/widgets/single_child_scroll_view.cs
  54. 11
      Runtime/widgets/single_child_scroll_view.cs.meta
  55. 92
      Samples/UIWidgetSample/ExpansionPanelCanvas.cs
  56. 11
      Samples/UIWidgetSample/ExpansionPanelCanvas.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;
}

6
Runtime/material/arc.cs


return this._center + new Offset(x, y);
}
public string toString() {
public override string ToString() {
return this.GetType() + "(" + this.begin + "->" + this.end + "); center=" + this.center +
", radius=" + this.radius + ", beginAngle=" + this.beginAngle + ", endAngle=" + this.endAngle;
}

return Rect.fromPoints(this._beginArc.lerp(t), this._endArc.lerp(t));
}
public string toString() {
public override string ToString() {
return this.GetType() + "(" + this.begin + "->" + this.end + ")";
}
}

height);
}
public string toString() {
public override string ToString() {
return this.GetType() + "(" + this.begin + "->" + this.end + "); centerArc=" + this.centerArc;
}
}

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) => {

22
Runtime/material/divider.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
using Color = Unity.UIWidgets.ui.Color;
namespace Unity.UIWidgets.material {
public class Divider : StatelessWidget {

double indent = 0.0,
Color color = null
) : base(key) {
Color color = null) : base(key: key) {
D.assert(height >= 0.0);
this.height = height;
this.indent = indent;

public readonly double height;
color: Theme.of(context).dividerColor,
width: width
);
color: color ?? Theme.of(context).dividerColor,
width: width);
height: height,
height: this.height,
margin: EdgeInsets.only(left: indent),
margin: EdgeInsets.only(this.indent),
bottom: createBorderSide(context, color)
)
bottom: createBorderSide(context, color: this.color))
)
)
)

175
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;
public class expansion_tile {
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,
//todo xingwei.zhu: add Icons.expand_more
child: null)
)
),
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));
}
}
}

94
Runtime/material/icon_button.cs


using System;
using System.Collections;
using System.Collections.Generic;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.service;
using System;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;

Color color = null,
Color highlightColor = null,
Color splashColor = null,
Color disabledColor = null,
Color disableColor = null,
string tooltip = null
) : base(key : key) {
string tooltip = null) : base(key: key) {
this.padding = padding ?? EdgeInsets.all(8.0);
this.padding = padding ?? EdgeInsets.all(8.0);
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 string tooltip;
public override Widget build(BuildContext context) {
MaterialDebug.debugCheckHasMaterial(context);
Color currentColor;
if (onPressed != null)
currentColor = color;
else
currentColor = disabledColor ?? Theme.of(context).disabledColor;
D.assert(MaterialDebug.debugCheckHasMaterial(context));
Color currentColor = null;
if (this.onPressed != null) {
currentColor = this.color;
}
else {
currentColor = this.disabledColor ?? Theme.of(context).disabledColor;
}
constraints: new BoxConstraints(minWidth: _kMinButtonSize, minHeight: _kMinButtonSize),
constraints: new BoxConstraints(minWidth: IconButtonUtils._kMinButtonSize,
minHeight: IconButtonUtils._kMinButtonSize),
padding: padding,
child: new SizedBox(
height: iconSize,
width: iconSize,
child: new Align(
alignment: alignment,
child: IconTheme.merge(
data: new IconThemeData(
size: iconSize,
color: currentColor
),
child: icon
)
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);
}
onTap: (GestureTapCallback)(() => onPressed()),
child: result,
highlightColor: highlightColor ?? Theme.of(context).highlightColor,
splashColor: splashColor ?? Theme.of(context).splashColor,
radius: Math.Max(
Material.defaultSplashRadius,
(iconSize + Math.Min(padding.horizontal, padding.vertical)) * 0.7
// x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
)
onTap: () => 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)
properties.add(new DiagnosticsProperty<Widget>("icon", icon, showName: false));
properties.add(new ObjectFlagProperty<VoidCallback>("onPressed", onPressed, ifNull: "disabled"));
properties.add(new StringProperty("tooltip", tooltip, defaultValue: null, quoted: false));
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));
}
}
}

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,

31
Runtime/material/material.cs


using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;

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(

}
static Widget _transparentInterior(ShapeBorder shape, Clip clipBehavior, Widget contents) {
_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
);
}
ShapeBorder _getShape() {
if (this.widget.shape != null) {
return this.widget.shape;

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

5
Runtime/material/shadows.cs


namespace Unity.UIWidgets.material {
public class ShadowConstants {
public static Dictionary<int, List<BoxShadow>>
kElevationToShadow = _elevationToShadow; // to hide the literal from the docs
static Dictionary<int, List<BoxShadow>> _elevationToShadow = new Dictionary<int, List<BoxShadow>> {
public static 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,

30
Runtime/material/utils.cs


maxKey = key;
}
}
}
public static class ExpansionTileUtils {
public static 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 TimeSpan _kBaseSettleDuration = new TimeSpan(0, 0, 0, 0, 246);
}
public static class TooltipUtils {
public static TimeSpan _kFadeDuration = new TimeSpan(0, 0, 0, 0, 200);
public static TimeSpan _kShowDuration = new TimeSpan(0, 0, 0, 0, 1500);
}
}

125
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) {
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,

);*/
}
if (this.needsCompositing) {
ContainerLayer container = new ContainerLayer();
context.pushLayer(container, base.paint, offset, childPaintBounds: offsetBounds);
return;
}
Paint paint = new Paint {color = this.color};
canvas.drawRRect(offsetRRect, paint);
context.clipRRectAndPaint(offsetRRect, this.clipBehavior, offsetBounds,

// 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();
}

120
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 override void didUnmountRenderObject(RenderObject renderObject) {
((RenderCustomPaint) renderObject).painter = null;
((RenderCustomPaint) renderObject).foregroundPainter = null;
}
}
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 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,

public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
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 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));
}
}

191
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;
}
}

}
}
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(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));
}
}
public class AnimatedDefaultTextStyle : ImplicitlyAnimatedWidget {
public AnimatedDefaultTextStyle(
Key key = null,

ColorTween _shadowColor;
protected override void forEachTween(ITweenVisitor visitor) {
this._borderRadius = (BorderRadiusTween) visitor.visit(this, this._borderRadius, this.widget.borderRadius,
this._borderRadius = (BorderRadiusTween) visitor.visit(this, this._borderRadius,
this.widget.borderRadius,
(BorderRadius value) => new BorderRadiusTween(begin: value));
this._elevation = (DoubleTween) visitor.visit(this, this._elevation, this.widget.elevation,
(double value) => new DoubleTween(begin: value, end: value));

33
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) {
this.alignment = alignment;
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);
}
}

11
Samples/UIWidgetSample/MaterialCanvas.cs


namespace UIWidgetsSample {
public class MaterialCanvas : WidgetCanvas {
protected override Widget getWidget() {
return new MaterialApp();
}
class MaterialApp : StatefulWidget {
public MaterialApp(Key key = null) : base(key) {
}
public override State createState() {
return new MaterialWidgetState();
}
return new MaterialWidget();
}
class MaterialWidget : StatefulWidget {

11
Runtime/material/divider.cs.meta


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

304
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 ? true : false;
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();
}
}
void open() {
this._controller.fling(velocity: 1.0);
if (this.widget.drawerCallback != null) {
this.widget.drawerCallback(true);
}
}
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 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:

318
Runtime/material/expansion_panel.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.widgets;
using UnityEngine.Networking;
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) {
var radio = new ExpansionPanelList(
key: key,
children: new List<ExpansionPanel>(children),
expansionCallback: expansionCallback,
animationDuration: animationDuration,
initialOpenPanelValue: initialOpenPanelValue
);
return radio;
}
public readonly List<ExpansionPanel> children;
public readonly ExpansionPanelCallback expansionCallback;
public readonly TimeSpan animationDuration;
//todo xingwei.zhu: make them readonly
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) {
ExpansionPanelList _oldWidget = (ExpansionPanelList) oldWidget;
base.didUpdateWidget(_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:

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:

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 IconData expand_more = new IconData(0xe5cf, 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:

841
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 = _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(
);
}
}
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>();
new public _ListTile widget {
get { return (_ListTile) base.widget; }
}
new public _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, this.renderObject.childToSlot[(RenderBox) child]);
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);
}
const double _minLeadingWidth = 40.0;
const double _horizonalTitleGrap = 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) + _horizonalTitleGrap
: 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.getMinIntrinsicWidth(height), _minLeadingWidth) + _horizonalTitleGrap
: 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) + _horizonalTitleGrap : 0.0;
BoxConstraints textConstraints = looseConstraints.tighten(
width: tileWidth - titleStart - (hasTrailing ? trailingSize.width + _horizonalTitleGrap : 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 {
titleY = titleBaseline - _boxBaseline(this.title, this.titleBaseLineType);
subtitleY = subtitleBaseline - _boxBaseline(this.subtitle, this.subtitleBaselineType);
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:

714
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 += 1) {
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 (var 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) {
MergeableMaterial _oldWidget = (MergeableMaterial) oldWidget;
base.didUpdateWidget(_oldWidget);
HashSet<LocalKey> oldKeys = new HashSet<LocalKey>();
foreach (var child in _oldWidget.children) {
oldKeys.Add(child.key);
}
HashSet<LocalKey> newKeys = new HashSet<LocalKey>();
foreach (var 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 = 0;
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:

269
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 = 0.0;
if (tooltipBelow) {
y = Math.Min(target.dy + verticalOffset, size.height - margin);
}
else {
y = Math.Max(target.dy - verticalOffset - childSize.height, margin);
}
double x = 0.0;
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;
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:

276
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 = null;
double position = 0.0;
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));
}
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));
}
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));
}
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));
}
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 class AxisDirectionUtils {
public static AxisDirection? getAxisDirectionFromAxisReverseAndDirectionality(
BuildContext context,
Axis axis,
bool reverse) {
switch (axis) {
case Axis.horizontal:
return reverse ? AxisDirection.right : AxisDirection.left;
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:

63
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:

451
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);
}
public override Widget build(BuildContext context) {
AxisDirection axisDirection = this._getDirection(context) ?? AxisDirection.down;
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;
}
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);
}
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) {
D.assert(this.axisDirection != null);
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;
D.assert(this.axisDirection != null);
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,
Rect rect,
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:

92
Samples/UIWidgetSample/ExpansionPanelCanvas.cs


using Unity.UIWidgets.engine;
using Unity.UIWidgets.widgets;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using System.Collections.Generic;
using UnityEngine;
using Material = Unity.UIWidgets.material.Material;
namespace UIWidgetsSample {
public class ExpansionPanelCanvas : WidgetCanvas {
protected override Widget getWidget() {
return new ExpansionPanelWidget();
}
class ExpansionPanelWidget : StatefulWidget {
public ExpansionPanelWidget(Key key = null) : base(key) {
}
public override State createState() {
return new ExpansionPanelWidgetState();
}
}
class ExpansionPanelWidgetState : State<ExpansionPanelWidget> {
List<bool> isExpand = new List<bool>{false, false};
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, 300)),
color: AsScreenCanvas.CLColors.red,
child: new Center(child: new Text("XXXXXXXX"))
)
)
);*/
return new Material(
child: new SingleChildScrollView(
child: new ExpansionPanelList(
expansionCallback: (int _index, bool _isExpanded) => {
Debug.Log("???????????" + _index + " <> " + _isExpanded);
this.isExpand[_index] = !_isExpanded;
this.setState(() => {});
},
children: new List<ExpansionPanel> {
new ExpansionPanel(
headerBuilder: (BuildContext subContext, bool isExpanded) => {
return new Container(
width: 10.0,
height: 10.0,
constraints: BoxConstraints.tight(new Size(10, 10)),
color: AsScreenCanvas.CLColors.blue
);
},
body: new Container(
width: 40.0,
height: 10.0,
constraints: BoxConstraints.tight(new Size(40, 10)),
color: AsScreenCanvas.CLColors.red
),
isExpanded : this.isExpand[0]
),
new ExpansionPanel(
headerBuilder: (BuildContext subContext, bool isExpanded) => {
return new Container(
width: 10.0,
height: 10.0,
constraints: BoxConstraints.tight(new Size(10, 10)),
color: AsScreenCanvas.CLColors.blue
);
},
body: new Container(
width: 40.0,
height: 10.0,
constraints: BoxConstraints.tight(new Size(40, 10)),
color: AsScreenCanvas.CLColors.red
),
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:
正在加载...
取消
保存