浏览代码

Merge branch 'yczhang_material' into gallery

/main
Yuncong Zhang 6 年前
当前提交
34c69532
共有 54 个文件被更改,包括 5328 次插入185 次删除
  1. 27
      Runtime/foundation/debug.cs
  2. 1
      Runtime/material/app_bar.cs
  3. 1
      Runtime/material/flexible_space_bar.cs
  4. 1
      Runtime/material/ink_well.cs
  5. 6
      Runtime/material/material_localizations.cs
  6. 30
      Runtime/material/theme_data.cs
  7. 3
      Runtime/rendering/box.cs
  8. 26
      Runtime/rendering/layer.cs
  9. 13
      Runtime/rendering/object.cs
  10. 87
      Runtime/rendering/proxy_box.cs
  11. 65
      Runtime/rendering/stack.cs
  12. 8
      Runtime/ui/compositing.cs
  13. 205
      Runtime/ui/painting/canvas_impl.cs
  14. 52
      Runtime/ui/painting/canvas_shader.cs
  15. 33
      Runtime/ui/painting/painting.cs
  16. 12
      Runtime/ui/painting/path.cs
  17. 6
      Runtime/widgets/app.cs
  18. 54
      Runtime/widgets/basic.cs
  19. 49
      Runtime/widgets/implicit_animations.cs
  20. 2
      Runtime/widgets/localizations.cs
  21. 4
      Runtime/widgets/scroll_configuration.cs
  22. 125
      Runtime/widgets/transitions.cs
  23. 12
      Runtime/widgets/preferred_size.cs
  24. 84
      Samples/UIWidgetSample/MaterialSample.cs
  25. 2
      Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture
  26. 2
      Samples/UIWidgetSample/ToDoAppSample.cs
  27. 2
      Samples/UIWidgetsGallery/gallery/options.cs
  28. 56
      Tests/Editor/CanvasAndLayers.cs
  29. 24
      Tests/Editor/Widgets.cs
  30. 25
      Runtime/flow/backdrop_filter_layer.cs
  31. 11
      Runtime/flow/backdrop_filter_layer.cs.meta
  32. 772
      Runtime/material/dropdown.cs
  33. 3
      Runtime/material/dropdown.cs.meta
  34. 381
      Runtime/material/input_border.cs
  35. 3
      Runtime/material/input_border.cs.meta
  36. 1001
      Runtime/material/input_decorator.cs
  37. 3
      Runtime/material/input_decorator.cs.meta
  38. 551
      Runtime/material/progress_indicator.cs
  39. 3
      Runtime/material/progress_indicator.cs.meta
  40. 107
      Runtime/material/tab_bar_theme.cs
  41. 11
      Runtime/material/tab_bar_theme.cs.meta
  42. 187
      Runtime/material/tab_controller.cs
  43. 11
      Runtime/material/tab_controller.cs.meta
  44. 90
      Runtime/material/tab_indicator.cs
  45. 11
      Runtime/material/tab_indicator.cs.meta
  46. 1001
      Runtime/material/tabs.cs
  47. 11
      Runtime/material/tabs.cs.meta
  48. 242
      Runtime/widgets/form.cs
  49. 3
      Runtime/widgets/form.cs.meta
  50. 11
      Runtime/widgets/preferred_size.cs.meta
  51. 69
      Runtime/widgets/will_pop_scope.cs
  52. 3
      Runtime/widgets/will_pop_scope.cs.meta
  53. 11
      Runtime/widgets/perferred_size.cs.meta
  54. 0
      /Runtime/widgets/preferred_size.cs

27
Runtime/foundation/debug.cs


public static class D {
public static void logError(string message, Exception ex = null) {
Debug.LogException(new ReportError(message, ex));
Debug.LogException(new AssertionError(message, ex));
}
[Conditional("UIWidgets_DEBUG")]
public static void assert(Func<bool> result, string message = null) {

[Serializable]
public class AssertionError : Exception {
readonly Exception innerException;
public override string StackTrace {
get {
var stackTrace = base.StackTrace;
var lines = stackTrace.Split('\n');
var strippedLines = lines.Skip(1);
return string.Join("\n", strippedLines);
}
}
}
public class ReportError : Exception {
Exception ex;
public ReportError(string message, Exception ex = null) : base(message) {
this.ex = ex;
public AssertionError(string message, Exception innerException = null) : base(message) {
this.innerException = innerException;
if (this.ex != null) {
return this.ex.StackTrace;
if (this.innerException != null) {
return this.innerException.StackTrace;
}
var stackTrace = base.StackTrace;

return string.Join("\n", strippedLines);
}
}
}
}

1
Runtime/material/app_bar.cs


return this.centerTitle;
}
D.assert(themeData.platform != null);
switch (themeData.platform) {
case RuntimePlatform.IPhonePlayer:
return this.actions == null || this.actions.Count < 2;

1
Runtime/material/flexible_space_bar.cs


return this.widget.centerTitle;
}
D.assert(themeData.platform != null);
switch (themeData.platform) {
case RuntimePlatform.IPhonePlayer:
return true;

1
Runtime/material/ink_well.cs


},
onHighlightChanged: onHighlightChanged,
containedInkWell: true,
highlightShape: BoxShape.rectangle,
highlightColor: highlightColor,
splashColor: splashColor,
splashFactory: splashFactory,

6
Runtime/material/material_localizations.cs


public abstract List<string> narrowWeekdays { get; }
public abstract int firstDayOfWeekIndex { get; }
public abstract string modalBarrierDismissLabel { get; }
public static MaterialLocalizations of(BuildContext context) {
return Localizations.of<MaterialLocalizations>(context, typeof(MaterialLocalizations));

public override string postMeridiemAbbreviation {
get { return "PM"; }
}
public override string modalBarrierDismissLabel {
get { return "Dismiss"; }
}
public override ScriptCategory scriptCategory {

30
Runtime/material/theme_data.cs


TextTheme textTheme = null,
TextTheme primaryTextTheme = null,
TextTheme accentTextTheme = null,
InputDecorationTheme inputDecorationTheme = null,
TabBarTheme tabBarTheme = null,
RuntimePlatform? platform = null,
MaterialTapTargetSize? materialTapTargetSize = null,
PageTransitionsTheme pageTransitionsTheme = null,

indicatorColor = indicatorColor ?? (accentColor == primaryColor ? Colors.white : accentColor);
hintColor = hintColor ?? (isDark ? new Color(0x80FFFFFF) : new Color(0x8A000000));
errorColor = errorColor ?? Colors.red[700];
inputDecorationTheme = inputDecorationTheme ?? new InputDecorationTheme();
pageTransitionsTheme = pageTransitionsTheme ?? new PageTransitionsTheme();
primaryIconTheme = primaryIconTheme ??
(primaryIsDark

? ThemeDataUtils._kDarkThemeSplashColor
: ThemeDataUtils._kLightThemeSplashColor);
tabBarTheme = tabBarTheme ?? new TabBarTheme();
dialogTheme = dialogTheme ?? new DialogTheme();
D.assert(brightness != null);

D.assert(colorScheme != null);
D.assert(typography != null);
D.assert(buttonColor != null);
D.assert(tabBarTheme != null);
D.assert(dialogTheme != null);
this.brightness = brightness ?? Brightness.light;

this.textTheme = textTheme;
this.primaryTextTheme = primaryTextTheme;
this.accentTextTheme = accentTextTheme;
this.inputDecorationTheme = inputDecorationTheme;
this.tabBarTheme = tabBarTheme;
this.platform = platform.Value;
this.materialTapTargetSize = materialTapTargetSize ?? MaterialTapTargetSize.padded;
this.pageTransitionsTheme = pageTransitionsTheme;

TextTheme textTheme = null,
TextTheme primaryTextTheme = null,
TextTheme accentTextTheme = null,
InputDecorationTheme inputDecorationTheme = null,
TabBarTheme tabBarTheme = null,
RuntimePlatform? platform = null,
MaterialTapTargetSize? materialTapTargetSize = null,
PageTransitionsTheme pageTransitionsTheme = null,

D.assert(textTheme != null);
D.assert(primaryTextTheme != null);
D.assert(accentTextTheme != null);
D.assert(inputDecorationTheme != null);
D.assert(iconTheme != null);
D.assert(primaryIconTheme != null);
D.assert(accentIconTheme != null);

D.assert(colorScheme != null);
D.assert(typography != null);
D.assert(buttonColor != null);
D.assert(tabBarTheme != null);
D.assert(dialogTheme != null);
return new ThemeData(

textTheme: textTheme,
primaryTextTheme: primaryTextTheme,
accentTextTheme: accentTextTheme,
inputDecorationTheme: inputDecorationTheme,
tabBarTheme: tabBarTheme,
platform: platform,
materialTapTargetSize: materialTapTargetSize,
pageTransitionsTheme: pageTransitionsTheme,

public readonly TextTheme accentTextTheme;
public readonly InputDecorationTheme inputDecorationTheme;
public readonly TabBarTheme tabBarTheme;
public readonly RuntimePlatform platform;

TextTheme textTheme = null,
TextTheme primaryTextTheme = null,
TextTheme accentTextTheme = null,
InputDecorationTheme inputDecorationTheme = null,
TabBarTheme tabBarTheme = null,
RuntimePlatform? platform = null,
MaterialTapTargetSize? materialTapTargetSize = null,
PageTransitionsTheme pageTransitionsTheme = null,

textTheme: textTheme ?? this.textTheme,
primaryTextTheme: primaryTextTheme ?? this.primaryTextTheme,
accentTextTheme: accentTextTheme ?? this.accentTextTheme,
inputDecorationTheme: this.inputDecorationTheme ?? this.inputDecorationTheme,
tabBarTheme: tabBarTheme ?? this.tabBarTheme,
platform: platform ?? this.platform,
materialTapTargetSize: materialTapTargetSize ?? this.materialTapTargetSize,
pageTransitionsTheme: pageTransitionsTheme ?? this.pageTransitionsTheme,

textTheme: TextTheme.lerp(a.textTheme, b.textTheme, t),
primaryTextTheme: TextTheme.lerp(a.primaryTextTheme, b.primaryTextTheme, t),
accentTextTheme: TextTheme.lerp(a.accentTextTheme, b.accentTextTheme, t),
inputDecorationTheme: t < 0.5f ? a.inputDecorationTheme : b.inputDecorationTheme,
tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t),
platform: t < 0.5 ? a.platform : b.platform,
materialTapTargetSize: t < 0.5 ? a.materialTapTargetSize : b.materialTapTargetSize,
pageTransitionsTheme: t < 0.5 ? a.pageTransitionsTheme : b.pageTransitionsTheme,

other.textTheme == this.textTheme &&
other.primaryTextTheme == this.primaryTextTheme &&
other.accentTextTheme == this.accentTextTheme &&
other.inputDecorationTheme == this.inputDecorationTheme &&
other.tabBarTheme == this.tabBarTheme &&
other.platform == this.platform &&
other.materialTapTargetSize == this.materialTapTargetSize &&
other.pageTransitionsTheme == this.pageTransitionsTheme &&

hashCode = (hashCode * 397) ^ this.textTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.primaryTextTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.accentTextTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.inputDecorationTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.tabBarTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.platform.GetHashCode();
hashCode = (hashCode * 397) ^ this.materialTapTargetSize.GetHashCode();
hashCode = (hashCode * 397) ^ this.pageTransitionsTheme.GetHashCode();

properties.add(new DiagnosticsProperty<TextTheme>("textTheme", this.textTheme));
properties.add(new DiagnosticsProperty<TextTheme>("primaryTextTheme", this.primaryTextTheme));
properties.add(new DiagnosticsProperty<TextTheme>("accentTextTheme", this.accentTextTheme));
properties.add(new DiagnosticsProperty<InputDecorationTheme>("inputDecorationTheme", this.inputDecorationTheme));
properties.add(new DiagnosticsProperty<TabBarTheme>("tabBarTheme", this.tabBarTheme));
properties.add(
new DiagnosticsProperty<MaterialTapTargetSize>("materialTapTargetSize", this.materialTapTargetSize));
properties.add(

3
Runtime/rendering/box.cs


});
}
public virtual bool hitTest(HitTestResult result, Offset position) {
public virtual bool hitTest(HitTestResult result, Offset position = null) {
D.assert(position != null);
D.assert(() => {
if (!this.hasSize) {
if (this.debugNeedsLayout) {

26
Runtime/rendering/layer.cs


properties.add(new DiagnosticsProperty<Offset>("offset", this.offset));
}
}
public class BackdropFilterLayer : ContainerLayer {
public BackdropFilterLayer(ImageFilter filter = null) {
D.assert(filter != null);
this._filter = filter;
}
ImageFilter _filter;
public ImageFilter filter {
get { return this._filter; }
set {
if (value != this._filter) {
this._filter = value;
this.markNeedsAddToScene();
}
}
}
internal override flow.Layer addToScene(SceneBuilder builder, Offset layerOffset = null) {
builder.pushBackdropFilter(this.filter);
this.addChildrenToScene(builder, layerOffset);
builder.pop();
return null;
}
}
public class LayerLink {
public LeaderLayer leader {

13
Runtime/rendering/object.cs


}
}
public void pushClipPath(bool needsCompositing, Offset offset, Rect bounds, Path clipPath,
PaintingContextCallback painter, Clip clipBehavior = Clip.antiAlias) {
Rect offsetBounds = bounds.shift(offset);
Path offsetClipPath = clipPath.shift(offset);
if (needsCompositing) {
this.pushLayer(new ClipPathLayer(clipPath: offsetClipPath, clipBehavior: clipBehavior), painter, offset,
childPaintBounds: offsetBounds);
}
else {
this.clipPathAndPaint(offsetClipPath, clipBehavior, offsetBounds, () => painter(this, offset));
}
}
public void pushTransform(bool needsCompositing, Offset offset, Matrix3 transform,
PaintingContextCallback painter) {
var effectiveTransform = Matrix3.makeTrans(offset.dx, offset.dy);

87
Runtime/rendering/proxy_box.cs


using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Gradient = Unity.UIWidgets.ui.Gradient;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.rendering {
public class RenderProxyBox : RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox<RenderBox> {

}
}
public class RenderBackdropFilter : RenderProxyBox {
public RenderBackdropFilter(
RenderBox child = null,
ImageFilter filter = null
) : base(child) {
D.assert(filter != null);
this._filter = filter;
}
ImageFilter _filter;
public ImageFilter filter {
get { return this._filter; }
set {
D.assert(value != null);
if (this._filter == value) {
return;
}
this.markNeedsPaint();
}
}
protected override bool alwaysNeedsCompositing {
get { return this.child != null; }
}
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
D.assert(this.needsCompositing);
context.pushLayer(new BackdropFilterLayer(this.filter), base.paint, offset);
}
}
}
public abstract class CustomClipper<T> {
public CustomClipper(Listenable reclip = null) {

protected override void debugPaintSize(PaintingContext context, Offset offset) {
D.assert(() => {
// if (this._debugPaint == null) {
// this._debugPaint = new Paint();
// this._debugPaint.shader = Gradient.linear(
// new Offset(0.0, 0.0),
// new Offset(10.0, 10.0),
// new Color(0x00000000),
// new Color(0xFFFF00FF),
// TileMode.repeated);
// this._debugPaint.strokeWidth = 2.0;
// this._debugPaint.style = PaintingStyle.stroke;
// }
// if (this._debugText == null) {
// this._debugText = new TextPainter(
// text: new TextSpan(
// text: "x",
// style: new TextStyle(
// color: new Color(0xFFFF00FF),
// fontSize: 14.0)
// ));
// this._debugText.layout();
// }
if (this._debugPaint == null) {
this._debugPaint = new Paint();
this._debugPaint.shader = Gradient.linear(
new Offset(0.0f, 0.0f),
new Offset(10.0f, 10.0f),
new List<Color> {
new Color(0x00000000),
new Color(0xFFFF00FF),
}, null, TileMode.repeated);
this._debugPaint.strokeWidth = 2.0f;
this._debugPaint.style = PaintingStyle.stroke;
}
if (this._debugText == null) {
this._debugText = new TextPainter(
text: new TextSpan(
text: "x",
style: new TextStyle(
color: new Color(0xFFFF00FF),
fontSize: 14.0f)
));
this._debugText.layout();
}
public class RenderClipRect : _RenderCustomClip<Rect> {
public RenderClipRect(

}
public override bool hitTest(HitTestResult result, Offset position = null) {
D.assert(position != null);
if (this._clipper != null) {
this._updateClip();
D.assert(this._clip != null);

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);
context.pushClipPath(this.needsCompositing, offset, Offset.zero & this.size,
this._clip, base.paint, clipBehavior: this.clipBehavior);
base.paint(context, offset);
}
}

65
Runtime/rendering/stack.cs


return this.defaultHitTestChildren(result, position: position);
}
public void paintStack(PaintingContext context, Offset offset) {
public virtual void paintStack(PaintingContext context, Offset offset) {
this.defaultPaint(context, offset);
}

properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
properties.add(new EnumProperty<StackFit>("fit", this.fit));
properties.add(new EnumProperty<Overflow>("overflow", this.overflow));
}
}
class RenderIndexedStack : RenderStack {
public RenderIndexedStack(
List<RenderBox> children = null,
Alignment alignment = null,
int? index = 0
) : base(fit: null, overflow: null, children: children, alignment: alignment ?? Alignment.topLeft) {
this._index = index;
}
public int? index {
get { return this._index; }
set {
if (this._index != value) {
this._index = value;
this.markNeedsLayout();
}
}
}
int? _index;
RenderBox _childAtIndex() {
D.assert(this.index != null);
RenderBox child = this.firstChild;
int i = 0;
while (child != null && i < this.index) {
StackParentData childParentData = (StackParentData) child.parentData;
child = childParentData.nextSibling;
i += 1;
}
D.assert(i == this.index);
D.assert(child != null);
return child;
}
protected override bool hitTestChildren(HitTestResult result, Offset position) {
if (this.firstChild == null || this.index == null) {
return false;
}
D.assert(position != null);
RenderBox child = this._childAtIndex();
StackParentData childParentData = (StackParentData) child.parentData;
return child.hitTest(result, position: position - childParentData.offset);
}
public override void paintStack(PaintingContext context, Offset offset) {
if (this.firstChild == null || this.index == null) {
return;
}
RenderBox child = this._childAtIndex();
StackParentData childParentData = (StackParentData) child.parentData;
context.paintChild(child, childParentData.offset + offset);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new IntProperty("index", this.index));
}
}
}

8
Runtime/ui/compositing.cs


return layer;
}
public Layer pushBackdropFilter(ImageFilter filter) {
var layer = new BackdropFilterLayer();
layer.filter = filter;
this._pushLayer(layer);
return layer;
}
public void addRetained(Layer layer) {
if (this._currentLayer == null) {
return;

205
Runtime/ui/painting/canvas_impl.cs


layerPaint = paint,
};
parentLayer.layers.Add(layer);
parentLayer.addLayer(layer);
if (paint.backdrop != null) {
if (paint.backdrop is _BlurImageFilter) {
var filter = (_BlurImageFilter) paint.backdrop;
if (!(filter.sigmaX == 0 && filter.sigmaY == 0)) {
var points = new[] {bounds.topLeft, bounds.bottomLeft, bounds.bottomRight, bounds.topRight};
state.matrix.mapPoints(points);
var parentBounds = parentLayer.layerBounds;
for (int i = 0; i < 4; i++) {
points[i] = new Offset(
(points[i].dx - parentBounds.left) / parentBounds.width,
(points[i].dy - parentBounds.top) / parentBounds.height
);
}
var mesh = ImageMeshGenerator.imageMesh(
null,
points[0], points[1], points[2], points[3],
bounds);
var renderDraw = CanvasShader.texRT(layer, layer.layerPaint, mesh, parentLayer);
layer.draws.Add(renderDraw);
var blurLayer = this._createBlurLayer(layer, filter.sigmaX, filter.sigmaY, layer);
var blurMesh = ImageMeshGenerator.imageMesh(null, Rect.one, bounds);
layer.draws.Add(CanvasShader.texRT(layer, paint, blurMesh, blurLayer));
}
} else if (paint.backdrop is _MatrixImageFilter) {
var filter = (_MatrixImageFilter) paint.backdrop;
if (!filter.transform.isIdentity()) {
layer.filterMode = filter.filterMode;
var points = new[] {bounds.topLeft, bounds.bottomLeft, bounds.bottomRight, bounds.topRight};
state.matrix.mapPoints(points);
var parentBounds = parentLayer.layerBounds;
for (int i = 0; i < 4; i++) {
points[i] = new Offset(
(points[i].dx - parentBounds.left) / parentBounds.width,
(points[i].dy - parentBounds.top) / parentBounds.height
);
}
var matrix = Matrix3.makeTrans(-bounds.left, -bounds.top);
matrix.postConcat(filter.transform);
matrix.postTranslate(bounds.left, bounds.top);
var mesh = ImageMeshGenerator.imageMesh(
matrix,
points[0], points[1], points[2], points[3],
bounds);
var renderDraw = CanvasShader.texRT(layer, layer.layerPaint, mesh, parentLayer);
layer.draws.Add(renderDraw);
}
}
}
}
void _restore() {

return;
}
layer.draws.Add(new RenderScissor {
layer.draws.Add(new CmdScissor {
deviceScissor = scissor,
});
layer.lastScissor = scissor;

} else {
layer.ignoreClip = false;
var boundsMesh = new MeshMesh(reducedClip.scissor);
// need to inflate a bit to make sure all area is cleared.
var inflatedScissor = reducedClip.scissor.inflate(this._fringeWidth);
var boundsMesh = new MeshMesh(inflatedScissor);
layer.draws.Add(CanvasShader.stencilClear(layer, boundsMesh));
foreach (var maskElement in reducedClip.maskElements) {

filterMode = FilterMode.Bilinear,
};
parentLayer.layers.Add(maskLayer);
parentLayer.addLayer(maskLayer);
this._layers.Add(maskLayer);
this._currentLayer = maskLayer;

return maskLayer;
}
RenderLayer _createBlurLayer(RenderLayer maskLayer, float sigma, RenderLayer parentLayer) {
sigma = BlurUtils.adjustSigma(sigma, out var scaleFactor, out var radius);
RenderLayer _createBlurLayer(RenderLayer maskLayer, float sigmaX, float sigmaY, RenderLayer parentLayer) {
sigmaX = BlurUtils.adjustSigma(sigmaX, out var scaleFactorX, out var radiusX);
sigmaY = BlurUtils.adjustSigma(sigmaY, out var scaleFactorY, out var radiusY);
var textureWidth = Mathf.CeilToInt((float) maskLayer.width / scaleFactor);
var textureWidth = Mathf.CeilToInt((float) maskLayer.width / scaleFactorX);
var textureHeight = Mathf.CeilToInt((float) maskLayer.height / scaleFactor);
var textureHeight = Mathf.CeilToInt((float) maskLayer.height / scaleFactorY);
if (textureHeight < 1) {
textureHeight = 1;
}

filterMode = FilterMode.Bilinear,
};
parentLayer.layers.Add(blurXLayer);
parentLayer.addLayer(blurXLayer);
var blurYLayer = new RenderLayer {
rtID = Shader.PropertyToID("_rtID_" + this._layers.Count + "_" + parentLayer.layers.Count),

filterMode = FilterMode.Bilinear,
};
parentLayer.layers.Add(blurYLayer);
parentLayer.addLayer(blurYLayer);
var kernel = BlurUtils.get1DGaussianKernel(sigma, radius);
var kernelX = BlurUtils.get1DGaussianKernel(sigmaX, radiusX);
var kernelY = BlurUtils.get1DGaussianKernel(sigmaY, radiusY);
radius, new Vector2(1f / textureWidth, 0), kernel));
radiusX, new Vector2(1f / textureWidth, 0), kernelX));
radius, new Vector2(0, -1f / textureHeight), kernel));
radiusY, new Vector2(0, -1f / textureHeight), kernelY));
return blurYLayer;
}

var maskLayer = this._createMaskLayer(layer, maskBounds, drawAction, paint);
var blurLayer = this._createBlurLayer(maskLayer, sigma, layer);
var blurLayer = this._createBlurLayer(maskLayer, sigma, sigma, layer);
var blurMesh = ImageMeshGenerator.imageMesh(null, Rect.one, maskBounds);
if (!this._applyClip(blurMesh.bounds)) {

}
void _drawLayer(RenderLayer layer, CommandBuffer cmdBuf) {
foreach (var subLayer in layer.layers) {
var desc = new RenderTextureDescriptor(
subLayer.width, subLayer.height,
RenderTextureFormat.Default, 24) {
useMipMap = false,
autoGenerateMips = false,
};
if (layer.rtID == 0) {
cmdBuf.SetRenderTarget(this._renderTexture,
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
cmdBuf.ClearRenderTarget(true, true, UnityEngine.Color.clear);
}
else {
cmdBuf.SetRenderTarget(layer.rtID,
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
cmdBuf.ClearRenderTarget(true, true, UnityEngine.Color.clear);
}
foreach (var cmdObj in layer.draws) {
switch (cmdObj) {
case CmdLayer cmd:
var subLayer = cmd.layer;
var desc = new RenderTextureDescriptor(
subLayer.width, subLayer.height,
RenderTextureFormat.Default, 24) {
useMipMap = false,
autoGenerateMips = false,
};
if (QualitySettings.antiAliasing != 0) {
desc.msaaSamples = QualitySettings.antiAliasing;
}
if (QualitySettings.antiAliasing != 0) {
desc.msaaSamples = QualitySettings.antiAliasing;
}
cmdBuf.GetTemporaryRT(subLayer.rtID, desc, subLayer.filterMode);
this._drawLayer(subLayer, cmdBuf);
}
if (layer.rtID == 0) {
cmdBuf.SetRenderTarget(this._renderTexture,
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
cmdBuf.ClearRenderTarget(true, true, UnityEngine.Color.clear);
}
else {
cmdBuf.SetRenderTarget(layer.rtID,
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
cmdBuf.ClearRenderTarget(true, true, UnityEngine.Color.clear);
}
cmdBuf.GetTemporaryRT(subLayer.rtID, desc, subLayer.filterMode);
this._drawLayer(subLayer, cmdBuf);
if (layer.rtID == 0) {
cmdBuf.SetRenderTarget(this._renderTexture,
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
}
else {
cmdBuf.SetRenderTarget(layer.rtID,
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
}
foreach (var cmdObj in layer.draws) {
switch (cmdObj) {
case RenderDraw cmd:
break;
case CmdDraw cmd:
cmdBuf.SetGlobalTexture(RenderDraw.texId, cmd.layer.rtID);
if (cmd.layer.rtID == 0) {
cmdBuf.SetGlobalTexture(CmdDraw.texId, this._renderTexture);
} else {
cmdBuf.SetGlobalTexture(CmdDraw.texId, cmd.layer.rtID);
}
}
D.assert(cmd.meshObj == null);

if (mesh == null) {
continue;
}
D.assert(mesh.vertices.Count > 0);
cmd.meshObj.SetVertices(mesh.vertices);

if (mesh.matrix == null) {
cmd.properties.SetFloatArray(RenderDraw.matId, RenderDraw.idMat3.fMat);
cmd.properties.SetFloatArray(CmdDraw.matId, CmdDraw.idMat3.fMat);
cmd.properties.SetFloatArray(RenderDraw.matId, mesh.matrix.fMat);
cmd.properties.SetFloatArray(CmdDraw.matId, mesh.matrix.fMat);
cmdBuf.DrawMesh(cmd.meshObj, RenderDraw.idMat, cmd.material, 0, cmd.pass, cmd.properties);
cmdBuf.DrawMesh(cmd.meshObj, CmdDraw.idMat, cmd.material, 0, cmd.pass, cmd.properties);
cmdBuf.SetGlobalTexture(RenderDraw.texId, BuiltinRenderTextureType.None);
cmdBuf.SetGlobalTexture(CmdDraw.texId, BuiltinRenderTextureType.None);
case RenderScissor cmd:
case CmdScissor cmd:
if (cmd.deviceScissor == null) {
cmdBuf.DisableScissorRect();
} else {

void _clearLayer(RenderLayer layer) {
foreach (var cmdObj in layer.draws) {
switch (cmdObj) {
case RenderDraw cmd:
case CmdDraw cmd:
if (cmd.meshObjCreated) {
this._meshPool.returnMesh(cmd.meshObj);
cmd.meshObj = null;

public uint lastClipGenId;
public Rect lastClipBounds;
public Rect lastScissor;
public bool ignoreClip;
public bool ignoreClip = true;
Vector4? _viewport;

this.currentState = new State();
this.states.Add(this.currentState);
}
public void addLayer(RenderLayer layer) {
this.layers.Add(layer);
this.draws.Add(new CmdLayer {layer = layer});
}
}
internal class State {

}
}
internal class RenderDraw {
internal class CmdLayer {
public RenderLayer layer;
}
internal class CmdDraw {
public MeshMesh mesh;
public TextBlobMesh textMesh;
public int pass;

public static readonly int matId = Shader.PropertyToID("_mat");
}
internal class RenderScissor {
internal class CmdScissor {
public Rect deviceScissor;
}
}

10, 11, 14, 11, 15, 14,
};
public static MeshMesh imageMesh(Matrix3 matrix,
Offset srcTL, Offset srcBL, Offset srcBR, Offset srcTR,
Rect dst) {
var vertices = new List<Vector3>(4);
var uv = new List<Vector2>(4);
vertices.Add(new Vector2(dst.left, dst.top));
uv.Add(new Vector2(srcTL.dx, 1.0f - srcTL.dy));
vertices.Add(new Vector2(dst.left, dst.bottom));
uv.Add(new Vector2(srcBL.dx, 1.0f - srcBL.dy));
vertices.Add(new Vector2(dst.right, dst.bottom));
uv.Add(new Vector2(srcBR.dx, 1.0f - srcBR.dy));
vertices.Add(new Vector2(dst.right, dst.top));
uv.Add(new Vector2(srcTR.dx, 1.0f - srcTR.dy));
return new MeshMesh(matrix, vertices, _imageTriangles, uv);
}
public static MeshMesh imageMesh(Matrix3 matrix, Rect src, Rect dst) {
var vertices = new List<Vector3>(4);
var uv = new List<Vector2>(4);

52
Runtime/ui/painting/canvas_shader.cs


}
}
public static PictureFlusher.RenderDraw convexFill(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw convexFill(PictureFlusher.RenderLayer layer, Paint paint,
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw fill0(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
public static PictureFlusher.CmdDraw fill0(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
Vector4 viewport = layer.viewport;
var mat = _fill0Mat.getMaterial(layer.ignoreClip);

return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw fill1(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw fill1(PictureFlusher.RenderLayer layer, Paint paint,
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh.boundsMesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw stroke0(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw stroke0(PictureFlusher.RenderLayer layer, Paint paint,
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw stroke1(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
public static PictureFlusher.CmdDraw stroke1(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
Vector4 viewport = layer.viewport;
var mat = _stroke1Mat;

return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw stencilClear(
public static PictureFlusher.CmdDraw stencilClear(
PictureFlusher.RenderLayer layer, MeshMesh mesh) {
Vector4 viewport = layer.viewport;
var mat = _stencilMat;

props.SetVector("_viewport", viewport);
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw stencil0(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
public static PictureFlusher.CmdDraw stencil0(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
Vector4 viewport = layer.viewport;
var mat = _stencilMat;

return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw stencil1(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
public static PictureFlusher.CmdDraw stencil1(PictureFlusher.RenderLayer layer, MeshMesh mesh) {
Vector4 viewport = layer.viewport;
var mat = _stencilMat;

return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

public static PictureFlusher.RenderDraw tex(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw tex(PictureFlusher.RenderLayer layer, Paint paint,
MeshMesh mesh, Image image) {
var mat = _texMat.getMaterial(paint.blendMode, layer.ignoreClip);
_getShaderPassAndProps(layer, paint, mesh, 1.0f, out var pass, out var props);

props.SetInt("_texMode", image.texture is RenderTexture ? 1 : 0); // pre alpha if RT else post alpha
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

}
public static PictureFlusher.RenderDraw texRT(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw texRT(PictureFlusher.RenderLayer layer, Paint paint,
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

}
public static PictureFlusher.RenderDraw texAlpha(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw texAlpha(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.RenderDraw texAlpha(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw texAlpha(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.RenderDraw texAlpha(PictureFlusher.RenderLayer layer, Paint paint,
public static PictureFlusher.CmdDraw texAlpha(PictureFlusher.RenderLayer layer, Paint paint,
MeshMesh mesh, TextBlobMesh textMesh, Texture tex) {
var mat = _texMat.getMaterial(paint.blendMode, layer.ignoreClip);

props.SetInt("_texMode", 2); // alpha only
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
textMesh = textMesh,
pass = pass,

}
public static PictureFlusher.RenderDraw maskFilter(PictureFlusher.RenderLayer layer, MeshMesh mesh,
public static PictureFlusher.CmdDraw maskFilter(PictureFlusher.RenderLayer layer, MeshMesh mesh,
PictureFlusher.RenderLayer renderLayer, float radius, Vector2 imgInc, float[] kernel) {
Vector4 viewport = layer.viewport;
var mat = _filterMat;

props.SetVector("_mf_imgInc", imgInc);
props.SetFloatArray("_mf_kernel", kernel);
return new PictureFlusher.RenderDraw {
return new PictureFlusher.CmdDraw {
mesh = mesh,
pass = pass,
material = mat,

33
Runtime/ui/painting/painting.cs


}
}
public abstract class ImageFilter {
public static ImageFilter blur(float sigmaX = 0.0f, float sigmaY = 0.0f) {
return new _BlurImageFilter(sigmaX, sigmaY);
}
public static ImageFilter matrix(Matrix3 transform, FilterMode filterMode = FilterMode.Point) {
return new _MatrixImageFilter(transform, filterMode);
}
}
class _BlurImageFilter : ImageFilter {
public _BlurImageFilter(float sigmaX, float sigmaY) {
this.sigmaX = sigmaX;
this.sigmaY = sigmaY;
}
public readonly float sigmaX;
public readonly float sigmaY;
}
class _MatrixImageFilter : ImageFilter {
public _MatrixImageFilter(Matrix3 transform, FilterMode filterMode) {
D.assert(transform != null);
this.transform = transform;
this.filterMode = filterMode;
}
public readonly Matrix3 transform;
public readonly FilterMode filterMode;
}
public class Paint {
static readonly Color _kColorDefault = new Color(0xFFFFFFFF);

public MaskFilter maskFilter = null;
public ImageFilter backdrop = null;
public PaintShader shader = null;
public bool invertColors = false;

this.filterMode = paint.filterMode;
this.colorFilter = paint.colorFilter;
this.maskFilter = paint.maskFilter;
this.backdrop = paint.backdrop;
this.shader = paint.shader;
this.invertColors = paint.invertColors;
}

12
Runtime/ui/painting/path.cs


this._cache = null;
}
public void relativeMoveTo(float x, float y) {
var x0 = this._commandx;
var y0 = this._commandy;
this._appendCommands(new[] {
(float) PathCommand.moveTo,
x + x0, y + y0,
});
}
}
}
public void lineTo(float x, float y) {
this._appendCommands(new[] {

6
Runtime/widgets/app.cs


public readonly Dictionary<string, WidgetBuilder> routes;
public readonly TextStyle textStyle;
public readonly Window window;
public readonly bool showPerformanceoverlay;
public readonly bool showPerformanceOverlay;
public readonly Locale locale;
public readonly List<LocalizationsDelegate> localizationsDelegates;
public readonly LocaleListResolutionCallback localeListResolutionCallback;

this.localeListResolutionCallback = localeListResolutionCallback;
this.localeResolutionCallback = localeResolutionCallback;
this.supportedLocales = supportedLocales;
this.showPerformanceoverlay = showPerformanceOverlay;
this.showPerformanceOverlay = showPerformanceOverlay;
D.assert(
home == null ||

}
PerformanceOverlay performanceOverlay = null;
if (this.widget.showPerformanceoverlay) {
if (this.widget.showPerformanceOverlay) {
performanceOverlay = PerformanceOverlay.allEnabled();
}

54
Runtime/widgets/basic.cs


}
}
public class BackdropFilter : SingleChildRenderObjectWidget {
public BackdropFilter(
Key key = null,
ImageFilter filter = null,
Widget child = null)
: base(key, child) {
D.assert(filter != null);
this.filter = filter;
}
public readonly ImageFilter filter;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderBackdropFilter(filter: this.filter);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
((RenderBackdropFilter) renderObject).filter = this.filter;
}
}
public class Opacity : SingleChildRenderObjectWidget {
public Opacity(float opacity, Key key = null, Widget child = null) : base(key, child) {
this.opacity = opacity;

}
}
class IndexedStack : Stack {
public IndexedStack(
Key key = null,
Alignment alignment = null,
StackFit sizing = StackFit.loose,
int index = 0,
List<Widget> children = null
) : base(key: key, alignment: alignment ?? Alignment.topLeft, fit: sizing, children: children) {
this.index = index;
}
public readonly int index;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderIndexedStack(
index: this.index,
alignment: this.alignment
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
RenderIndexedStack renderIndexedStack = renderObject as RenderIndexedStack;
renderIndexedStack.index = this.index;
renderIndexedStack.alignment = this.alignment;
}
}
public class Positioned : ParentDataWidget<Stack> {
public Positioned(Widget child, Key key = null, float? left = null, float? top = null,
float? right = null, float? bottom = null, float? width = null, float? height = null) :

top: rect.top, width: rect.width, height: rect.height);
}
public static Positioned fromRelativeRect(Rect rect, Widget child, Key key = null) {
public static Positioned fromRelativeRect(RelativeRect rect, Widget child, Key key = null) {
return new Positioned(child, key: key, left: rect.left,
top: rect.top, right: rect.right, bottom: rect.bottom);
}

public static List<Widget> ensureUniqueKeysForList(IEnumerable<Widget> items, int baseIndex = 0) {
if (items == null) {
return null;
itemsWithUniqueKeys.Add(KeyedSubtree.wrap(item, itemIndex));
itemsWithUniqueKeys.Add(wrap(item, itemIndex));
itemIndex += 1;
}

49
Runtime/widgets/implicit_animations.cs


}
}
public class AnimatedOpacity : ImplicitlyAnimatedWidget {
public AnimatedOpacity(
Key key = null,
Widget child = null,
float? opacity = null,
Curve curve = null,
TimeSpan? duration = null
) :
base(key: key, curve: curve ?? Curves.linear, duration: duration) {
D.assert(opacity != null && opacity >= 0.0 && opacity <= 1.0);
this.child = child;
this.opacity = opacity ?? 1.0f;
}
public readonly Widget child;
public readonly float opacity;
public override State createState() {
return new _AnimatedOpacityState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FloatProperty("opacity", this.opacity));
}
}
class _AnimatedOpacityState : ImplicitlyAnimatedWidgetState<AnimatedOpacity> {
FloatTween _opacity;
Animation<float> _opacityAnimation;
protected override void forEachTween(TweenVisitor visitor) {
this._opacity = (FloatTween) visitor.visit(this, this._opacity, this.widget.opacity,
(float value) => new FloatTween(begin: value, end: 1.0f));
}
protected override void didUpdateTweens() {
this._opacityAnimation = this.animation.drive(this._opacity);
}
public override Widget build(BuildContext context) {
return new FadeTransition(
opacity: this._opacityAnimation,
child: this.widget.child
);
}
}
public class AnimatedDefaultTextStyle : ImplicitlyAnimatedWidget {
public AnimatedDefaultTextStyle(
Key key = null,

2
Runtime/widgets/localizations.cs


public T resourcesFor<T>(Type type) {
D.assert(type != null);
T resources = (T) this._typeToResources[type];
T resources = (T) this._typeToResources.getOrDefault(type);
return resources;
}

4
Runtime/widgets/scroll_configuration.cs


namespace Unity.UIWidgets.widgets {
public class ScrollBehavior {
public Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
public virtual Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
public ScrollPhysics getScrollPhysics(BuildContext context) {
public virtual ScrollPhysics getScrollPhysics(BuildContext context) {
return new BouncingScrollPhysics();
}

125
Runtime/widgets/transitions.cs


using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using UnityEngine;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.widgets {
public abstract class AnimatedWidget : StatefulWidget {

public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Animation<float>>("opacity", this.opacity));
}
}
public class PositionedTransition : AnimatedWidget {
public PositionedTransition(
Key key = null,
Animation<RelativeRect> rect = null,
Widget child = null
) : base(key: key, listenable: rect) {
D.assert(rect != null);
D.assert(child != null);
this.child = child;
}
Animation<RelativeRect> rect {
get { return (Animation<RelativeRect>) this.listenable; }
}
public readonly Widget child;
protected internal override Widget build(BuildContext context) {
return Positioned.fromRelativeRect(
rect: this.rect.value,
child: this.child
);
}
}
public class RelativePositionedTransition : AnimatedWidget {
public RelativePositionedTransition(
Key key = null,
Animation<Rect> rect = null,
Size size = null,
Widget child = null
) : base(key: key, listenable: rect) {
D.assert(rect != null);
D.assert(size != null);
D.assert(child != null);
}
Animation<Rect> rect {
get { return (Animation<Rect>) this.listenable; }
}
public readonly Size size;
public readonly Widget child;
protected internal override Widget build(BuildContext context) {
RelativeRect offsets = RelativeRect.fromSize(this.rect.value, this.size);
return new Positioned(
top: offsets.top,
right: offsets.right,
bottom: offsets.bottom,
left: offsets.left,
child: this.child
);
}
}
public class DecoratedBoxTransition : AnimatedWidget {
public DecoratedBoxTransition(
Key key = null,
Animation<Decoration> decoration = null,
DecorationPosition position = DecorationPosition.background,
Widget child = null
) : base(key: key, listenable: decoration) {
D.assert(decoration != null);
D.assert(child != null);
this.decoration = decoration;
this.position = position;
this.child = child;
}
public readonly Animation<Decoration> decoration;
public readonly DecorationPosition position;
public readonly Widget child;
protected internal override Widget build(BuildContext context) {
return new DecoratedBox(
decoration: this.decoration.value,
position: this.position,
child: this.child
);
}
}
public class AlignTransition : AnimatedWidget {
public AlignTransition(
Key key = null,
Animation<Alignment> alignment = null,
Widget child = null,
float? widthFactor = null,
float? heightFactor = null
) : base(key: key, listenable: alignment) {
this.child = child;
this.widthFactor = widthFactor;
this.heightFactor = heightFactor;
}
Animation<Alignment> alignment {
get { return (Animation<Alignment>) this.listenable; }
}
public readonly float? widthFactor;
public readonly float? heightFactor;
public readonly Widget child;
protected internal override Widget build(BuildContext context) {
return new Align(
alignment: this.alignment.value,
widthFactor: this.widthFactor,
heightFactor: this.heightFactor,
child: this.child
);
}
}

12
Runtime/widgets/preferred_size.cs


}
public class PreferredSize : StatelessWidget, SizePreferred {
public class PreferredSize : PreferredSizeWidget {
public PreferredSize(
Key key = null,
Widget child = null,

public readonly Widget child;
public Size preferredSize { get; }
public override Size preferredSize { get; }
public override State createState() {
return new _PreferredSizeState();
}
}
class _PreferredSizeState : State<PreferredSize> {
return this.child;
return this.widget.child;
}
}
}

84
Samples/UIWidgetSample/MaterialSample.cs


using System.Collections.Generic;
using RSG;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;

namespace UIWidgetsSample {
public class MaterialSample : UIWidgetsSamplePanel {
int testCaseId = 2;
int testCaseId = 3;
new MaterialAppBarWidget()
new MaterialAppBarWidget(),
new MaterialTabBarWidget()
showPerformanceOverlay: true,
showPerformanceOverlay: false,
home: this.testCases[this.testCaseId]);
}

}
}
class MaterialTabBarWidget : StatefulWidget {
public MaterialTabBarWidget(Key key = null) : base(key) {
}
public override State createState() {
return new MaterialTabBarWidgetState();
}
}
class MaterialTabBarWidgetState : SingleTickerProviderStateMixin<MaterialTabBarWidget> {
TabController _tabController;
public override void initState() {
base.initState();
this._tabController = new TabController(vsync: this, length: Choice.choices.Count);
}
public override void dispose() {
this._tabController.dispose();
base.dispose();
}
void _nextPage(int delta) {
int newIndex = this._tabController.index + delta;
if (newIndex < 0 || newIndex >= this._tabController.length) {
return;
}
this._tabController.animateTo(newIndex);
}
public override Widget build(BuildContext context) {
List<Widget> tapChildren = new List<Widget>();
foreach (Choice choice in Choice.choices) {
tapChildren.Add(
new Padding(
padding: EdgeInsets.all(16.0f),
child: new ChoiceCard(choice: choice)));
}
return new Scaffold(
appBar: new AppBar(
title: new Center(
child: new Text("AppBar Bottom Widget")
),
leading: new IconButton(
tooltip: "Previous choice",
icon: new Icon(Unity.UIWidgets.material.Icons.arrow_back),
onPressed: () => { this._nextPage(-1); }
),
actions: new List<Widget> {
new IconButton(
icon: new Icon(Unity.UIWidgets.material.Icons.arrow_forward),
tooltip: "Next choice",
onPressed: () => { this._nextPage(1); })
},
bottom: new PreferredSize(
preferredSize: Size.fromHeight(48.0f),
child: new Theme(
data: Theme.of(context).copyWith(accentColor: Colors.white),
child: new Container(
height: 48.0f,
alignment: Alignment.center,
child: new TabPageSelector(
controller: this._tabController))))
),
body: new TabBarView(
controller: this._tabController,
children: tapChildren
));
}
}
class MaterialAppBarWidget : StatefulWidget {
public MaterialAppBarWidget(Key key = null) : base(key) {
}

this.setState(() => { this._showBottomSheetCallback = this._showBottomSheet; });
}
return null;
return new Promise();
});
}

2
Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture


m_ForcedFallbackFormat: 4
m_DownscaleFallback: 0
m_Width: 480
m_Height: 480
m_Height: 270
m_AntiAliasing: 1
m_DepthFormat: 2
m_ColorFormat: 0

2
Samples/UIWidgetSample/ToDoAppSample.cs


var texture = Resources.Load<RenderTexture>("VideoSampleRT");
return new Center(
child: new Container(
width: 480, height: 270,
width: 240, height: 135,
child: new Texture(texture: texture)
)
);

2
Samples/UIWidgetsGallery/gallery/options.cs


class _TextScaleFactorItem : StatelessWidget {
public _TextScaleFactorItem(GalleryOptions options, ValueChanged<GalleryOptions> onOptionsChanged) {
this.options = options;
this.onOptionsChanged = this.onOptionsChanged;
this.onOptionsChanged = onOptionsChanged;
}
public readonly GalleryOptions options;

56
Tests/Editor/CanvasAndLayers.cs


void saveLayer() {
var pictureRecorder = new PictureRecorder();
var canvas = new RecorderCanvas(pictureRecorder);
var paint1 = new Paint {
color = new Color(0xFFFFFFFF),
};
var path1 = new Path();
path1.moveTo(0, 0);
path1.lineTo(0, 90);
path1.lineTo(90, 90);
path1.lineTo(90, 0);
path1.close();
canvas.drawPath(path1, paint1);
path.moveTo(10, 10);
path.lineTo(10, 110);
path.lineTo(90, 110);
path.lineTo(110, 10);
path.moveTo(20, 20);
path.lineTo(20, 70);
path.lineTo(70, 70);
path.lineTo(70, 20);
paint = new Paint {
var paint2 = new Paint {
var rect = Unity.UIWidgets.ui.Rect.fromLTWH(10, 150, 100, 100);
var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16);
var rect1 = Unity.UIWidgets.ui.Rect.fromLTWH(18, 152, 88, 92);
var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16);
canvas.drawDRRect(rrect, rrect1, paint);
canvas.rotate(-45 * Mathf.PI / 180.0f, new Offset(150, 150));
var path2 = new Path();
path2.moveTo(30, 30);
path2.lineTo(30, 60);
path2.lineTo(60, 60);
path2.lineTo(60, 30);
path2.close();
// paint = new Paint {
// color = new Color(0xFF00FFFF),
// blurSigma = 3,
// };
// canvas.drawRectShadow(
// Rect.fromLTWH(150, 150, 110, 120),
// paint);
canvas.drawPath(path2, paint2);
Debug.Log("picture.paintBounds: " + picture.paintBounds);
editorCanvas.saveLayer(picture.paintBounds, new Paint {color = new Color(0x7FFFFFFF)});
editorCanvas.saveLayer(
picture.paintBounds, new Paint {
color = new Color(0xFFFFFFFF),
});
editorCanvas.translate(150, 0);
editorCanvas.saveLayer(picture.paintBounds, new Paint {color = new Color(0xFFFFFFFF)});
editorCanvas.drawPicture(picture);
editorCanvas.saveLayer(Unity.UIWidgets.ui.Rect.fromLTWH(45, 45, 90, 90), new Paint {
color = new Color(0xFFFFFFFF),
backdrop = ImageFilter.blur(3f, 3f)
});
editorCanvas.restore();
editorCanvas.flush();

24
Tests/Editor/Widgets.cs


child: new Container(
color: CLColors.background3,
child: new Transform(
transform: Matrix3.makeRotate(Mathf.PI/180 * 5, px, py),
transform: Matrix3.makeRotate(Mathf.PI / 180 * 5, px, py),
child:
new Column(
children: new List<Widget> {

)
)
);
return container;
var stack = new Stack(
children: new List<Widget> {
container,
new Positioned(
top: 50,
right: 50,
child: new BackdropFilter(
filter: ImageFilter.blur(10, 10),
child: new Container(
width: 300, height: 300,
decoration: new BoxDecoration(
color: Colors.transparent
)
)
)
)
}
);
return stack;
}
}

25
Runtime/flow/backdrop_filter_layer.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.flow {
public class BackdropFilterLayer : ContainerLayer {
ImageFilter _filter;
public ImageFilter filter {
set { this._filter = value; }
}
public override void paint(PaintContext context) {
D.assert(this.needsPainting);
var canvas = context.canvas;
canvas.saveLayer(this.paintBounds, new Paint {backdrop = this._filter});
try {
this.paintChildren(context);
} finally {
canvas.restore();
}
}
}
}

11
Runtime/flow/backdrop_filter_layer.cs.meta


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

772
Runtime/material/dropdown.cs


using System;
using System.Collections.Generic;
using System.Linq;
using RSG;
using Unity.UIWidgets.animation;
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 UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.material {
class DropdownConstants {
public static readonly TimeSpan _kDropdownMenuDuration = new TimeSpan(0, 0, 0, 0, 300);
public const float _kMenuItemHeight = 48.0f;
public const float _kDenseButtonHeight = 24.0f;
public static EdgeInsets _kMenuItemPadding = EdgeInsets.symmetric(horizontal: 16.0f);
public static EdgeInsets _kAlignedButtonPadding = EdgeInsets.only(left: 16.0f, right: 4.0f);
public static EdgeInsets _kUnalignedButtonPadding = EdgeInsets.zero;
public static EdgeInsets _kAlignedMenuMargin = EdgeInsets.zero;
public static EdgeInsets _kUnalignedMenuMargin = EdgeInsets.only(left: 16.0f, right: 24.0f);
}
class _DropdownMenuPainter : AbstractCustomPainter {
public _DropdownMenuPainter(
Color color = null,
int? elevation = null,
int? selectedIndex = null,
Animation<float> resize = null
) : base(repaint: resize) {
D.assert(elevation != null);
this._painter = new BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(2.0f),
boxShadow: ShadowConstants.kElevationToShadow[elevation ?? 0]
).createBoxPainter();
this.color = color;
this.elevation = elevation;
this.selectedIndex = selectedIndex;
this.resize = resize;
}
public readonly Color color;
public readonly int? elevation;
public readonly int? selectedIndex;
public readonly Animation<float> resize;
public readonly BoxPainter _painter;
public override void paint(Canvas canvas, Size size) {
float selectedItemOffset = this.selectedIndex ?? 0 * DropdownConstants._kMenuItemHeight +
Constants.kMaterialListPadding.top;
FloatTween top = new FloatTween(
begin: selectedItemOffset.clamp(0.0f, size.height - DropdownConstants._kMenuItemHeight),
end: 0.0f
);
FloatTween bottom = new FloatTween(
begin: (top.begin + DropdownConstants._kMenuItemHeight).clamp(DropdownConstants._kMenuItemHeight,
size.height),
end: size.height
);
Rect rect = Rect.fromLTRB(0.0f, top.evaluate(this.resize), size.width, bottom.evaluate(this.resize));
this._painter.paint(canvas, rect.topLeft, new ImageConfiguration(size: rect.size));
}
public override bool shouldRepaint(CustomPainter painter) {
_DropdownMenuPainter oldPainter = painter as _DropdownMenuPainter;
return oldPainter.color != this.color
|| oldPainter.elevation != this.elevation
|| oldPainter.selectedIndex != this.selectedIndex
|| oldPainter.resize != this.resize;
}
}
class _DropdownScrollBehavior : ScrollBehavior {
public _DropdownScrollBehavior() {
}
public override Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
return child;
}
public override ScrollPhysics getScrollPhysics(BuildContext context) {
return new ClampingScrollPhysics();
}
}
class _DropdownMenu<T> : StatefulWidget where T : class {
public _DropdownMenu(
Key key = null,
EdgeInsets padding = null,
_DropdownRoute<T> route = null
) : base(key: key) {
this.route = route;
this.padding = padding;
}
public readonly _DropdownRoute<T> route;
public readonly EdgeInsets padding;
public override State createState() {
return new _DropdownMenuState<T>();
}
}
class _DropdownMenuState<T> : State<_DropdownMenu<T>> where T : class {
CurvedAnimation _fadeOpacity;
CurvedAnimation _resize;
public _DropdownMenuState() {
}
public override void initState() {
base.initState();
// We need to hold these animations as state because of their curve
// direction. When the route's animation reverses, if we were to recreate
// the CurvedAnimation objects in build, we'd lose
// CurvedAnimation._curveDirection.
this._fadeOpacity = new CurvedAnimation(
parent: this.widget.route.animation,
curve: new Interval(0.0f, 0.25f),
reverseCurve: new Interval(0.75f, 1.0f)
);
this._resize = new CurvedAnimation(
parent: this.widget.route.animation,
curve: new Interval(0.25f, 0.5f),
reverseCurve: new Threshold(0.0f)
);
}
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
MaterialLocalizations localizations = MaterialLocalizations.of(context);
_DropdownRoute<T> route = this.widget.route;
float unit = 0.5f / (route.items.Count + 1.5f);
List<Widget> children = new List<Widget>();
for (int itemIndex = 0; itemIndex < route.items.Count; ++itemIndex) {
CurvedAnimation opacity;
if (itemIndex == route.selectedIndex) {
opacity = new CurvedAnimation(parent: route.animation, curve: new Threshold(0.0f));
}
else {
float start = (0.5f + (itemIndex + 1) * unit).clamp(0.0f, 1.0f);
float end = (start + 1.5f * unit).clamp(0.0f, 1.0f);
opacity = new CurvedAnimation(parent: route.animation, curve: new Interval(start, end));
}
var index = itemIndex;
children.Add(new FadeTransition(
opacity: opacity,
child: new InkWell(
child: new Container(
padding: this.widget.padding,
child: route.items[itemIndex]
),
onTap: () => Navigator.pop(
context,
new _DropdownRouteResult<T>(route.items[index].value)
)
)
));
}
return new FadeTransition(
opacity: this._fadeOpacity,
child: new CustomPaint(
painter: new _DropdownMenuPainter(
color: Theme.of(context).canvasColor,
elevation: route.elevation,
selectedIndex: route.selectedIndex,
resize: this._resize
),
child: new Material(
type: MaterialType.transparency,
textStyle: route.style,
child: new ScrollConfiguration(
behavior: new _DropdownScrollBehavior(),
child: new Scrollbar(
child: new ListView(
controller: this.widget.route.scrollController,
padding: Constants.kMaterialListPadding,
itemExtent: DropdownConstants._kMenuItemHeight,
shrinkWrap: true,
children: children
)
)
)
)
)
);
}
}
class _DropdownMenuRouteLayout<T> : SingleChildLayoutDelegate {
public _DropdownMenuRouteLayout(
Rect buttonRect,
float menuTop,
float menuHeight,
TextDirection textDirection
) {
this.buttonRect = buttonRect;
this.menuTop = menuTop;
this.menuHeight = menuHeight;
this.textDirection = textDirection;
}
public readonly Rect buttonRect;
public readonly float menuTop;
public readonly float menuHeight;
public readonly TextDirection textDirection;
public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
float maxHeight = Mathf.Max(0.0f, constraints.maxHeight - 2 * DropdownConstants._kMenuItemHeight);
float width = Mathf.Min(constraints.maxWidth, this.buttonRect.width);
return new BoxConstraints(
minWidth: width,
maxWidth: width,
minHeight: 0.0f,
maxHeight: maxHeight
);
}
public override Offset getPositionForChild(Size size, Size childSize) {
D.assert(() => {
Rect container = Offset.zero & size;
if (container.intersect(this.buttonRect) == this.buttonRect) {
// If the button was entirely on-screen, then verify
// that the menu is also on-screen.
// If the button was a bit off-screen, then, oh well.
D.assert(this.menuTop >= 0.0f);
D.assert(this.menuTop + this.menuHeight <= size.height);
}
return true;
});
float left;
switch (this.textDirection) {
case TextDirection.rtl:
left = this.buttonRect.right.clamp(0.0f, size.width) - childSize.width;
break;
case TextDirection.ltr:
left = this.buttonRect.left.clamp(0.0f, size.width - childSize.width);
break;
default:
throw new Exception("Unknown text direction: " + this.textDirection);
}
return new Offset(left, this.menuTop);
}
public override bool shouldRelayout(SingleChildLayoutDelegate _oldDelegate) {
_DropdownMenuRouteLayout<T> oldDelegate = _oldDelegate as _DropdownMenuRouteLayout<T>;
return this.buttonRect != oldDelegate.buttonRect
|| this.menuTop != oldDelegate.menuTop
|| this.menuHeight != oldDelegate.menuHeight
|| this.textDirection != oldDelegate.textDirection;
}
}
class _DropdownRouteResult<T> where T: class {
public _DropdownRouteResult(T result) {
this.result = result;
}
public readonly T result;
public static bool operator ==(_DropdownRouteResult<T> left, _DropdownRouteResult<T> right) {
return left.result == right.result;
}
public static bool operator !=(_DropdownRouteResult<T> left, _DropdownRouteResult<T> right) {
return left.result != right.result;
}
public override int GetHashCode() {
return this.result.GetHashCode();
}
}
class _DropdownRoute<T> : PopupRoute where T : class {
public _DropdownRoute(
List<DropdownMenuItem<T>> items = null,
EdgeInsets padding = null,
Rect buttonRect = null,
int? selectedIndex = null,
int elevation = 8,
ThemeData theme = null,
TextStyle style = null,
string barrierLabel = null
) {
D.assert(style != null);
this.items = items;
this.padding = padding;
this.buttonRect = buttonRect;
this.selectedIndex = selectedIndex;
this.elevation = elevation;
this.theme = theme;
this.style = style;
this.barrierLabel = barrierLabel;
}
public readonly List<DropdownMenuItem<T>> items;
public readonly EdgeInsets padding;
public readonly Rect buttonRect;
public readonly int? selectedIndex;
public readonly int elevation;
public readonly ThemeData theme;
public readonly TextStyle style;
public ScrollController scrollController;
public override TimeSpan transitionDuration {
get { return DropdownConstants._kDropdownMenuDuration; }
}
public override bool barrierDismissible {
get { return true; }
}
public override Color barrierColor {
get { return null; }
}
public string barrierLabel;
public override Widget buildPage(BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation) {
D.assert(WidgetsD.debugCheckHasDirectionality(context));
float screenHeight = MediaQuery.of(context).size.height;
float maxMenuHeight = screenHeight - 2.0f * DropdownConstants._kMenuItemHeight;
float buttonTop = this.buttonRect.top;
float buttonBottom = this.buttonRect.bottom;
float topLimit = Mathf.Min(DropdownConstants._kMenuItemHeight, buttonTop);
float bottomLimit = Mathf.Max(screenHeight - DropdownConstants._kMenuItemHeight, buttonBottom);
float? selectedItemOffset = this.selectedIndex * DropdownConstants._kMenuItemHeight +
Constants.kMaterialListPadding.top;
float? menuTop = (buttonTop - selectedItemOffset) -
(DropdownConstants._kMenuItemHeight - this.buttonRect.height) / 2.0f;
float preferredMenuHeight = (this.items.Count * DropdownConstants._kMenuItemHeight) +
Constants.kMaterialListPadding.vertical;
float menuHeight = Mathf.Min(maxMenuHeight, preferredMenuHeight);
float? menuBottom = menuTop + menuHeight;
if (menuTop < topLimit) {
menuTop = Mathf.Min(buttonTop, topLimit);
}
if (menuBottom > bottomLimit) {
menuBottom = Mathf.Max(buttonBottom, bottomLimit);
menuTop = menuBottom - menuHeight;
}
if (this.scrollController == null) {
float scrollOffset = preferredMenuHeight > maxMenuHeight
? Mathf.Max(0.0f, selectedItemOffset ?? 0.0f - (buttonTop - (menuTop ?? 0.0f)))
: 0.0f;
this.scrollController = new ScrollController(initialScrollOffset: scrollOffset);
}
TextDirection textDirection = Directionality.of(context);
Widget menu = new _DropdownMenu<T>(
route: this,
padding: this.padding
);
if (this.theme != null) {
menu = new Theme(data: this.theme, child: menu);
}
return MediaQuery.removePadding(
context: context,
removeTop: true,
removeBottom: true,
removeLeft: true,
removeRight: true,
child: new Builder(
builder: (BuildContext _context) => {
return new CustomSingleChildLayout(
layoutDelegate: new _DropdownMenuRouteLayout<T>(
buttonRect: this.buttonRect,
menuTop: menuTop ?? 0.0f,
menuHeight: menuHeight,
textDirection: textDirection
),
child: menu
);
}
)
);
}
public void _dismiss() {
this.navigator?.removeRoute(this);
}
}
public class DropdownMenuItem<T> : StatelessWidget where T : class {
public DropdownMenuItem(
Key key = null,
T value = null,
Widget child = null
) : base(key: key) {
D.assert(child != null);
this.value = value;
this.child = child;
}
public readonly Widget child;
public readonly T value;
public override Widget build(BuildContext context) {
return new Container(
height: DropdownConstants._kMenuItemHeight,
alignment: Alignment.centerLeft,
child: this.child
);
}
}
public class DropdownButtonHideUnderline : InheritedWidget {
public DropdownButtonHideUnderline(
Key key = null,
Widget child = null
) : base(key: key, child: child) {
D.assert(child != null);
}
public static bool at(BuildContext context) {
return context.inheritFromWidgetOfExactType(typeof(DropdownButtonHideUnderline)) != null;
}
public override bool updateShouldNotify(InheritedWidget oldWidget) {
return false;
}
}
public class DropdownButton<T> : StatefulWidget where T : class {
public DropdownButton(
Key key = null,
List<DropdownMenuItem<T>> items = null,
T value = null,
Widget hint = null,
Widget disabledHint = null,
ValueChanged<T> onChanged = null,
int elevation = 8,
TextStyle style = null,
float iconSize = 24.0f,
bool isDense = false,
bool isExpanded = false
) :
base(key: key) {
D.assert(items == null || value == null ||
items.Where<DropdownMenuItem<T>>((DropdownMenuItem<T> item) => item.value.Equals(value)).ToList()
.Count == 1);
this.items = items;
this.value = value;
this.hint = hint;
this.disabledHint = disabledHint;
this.onChanged = onChanged;
this.elevation = elevation;
this.style = style;
this.iconSize = iconSize;
this.isDense = isDense;
this.isExpanded = isExpanded;
}
public readonly List<DropdownMenuItem<T>> items;
public readonly T value;
public readonly Widget hint;
public readonly Widget disabledHint;
public readonly ValueChanged<T> onChanged;
public readonly int elevation;
public readonly TextStyle style;
public readonly float iconSize;
public readonly bool isDense;
public readonly bool isExpanded;
public override State createState() {
return new _DropdownButtonState<T>();
}
}
class _DropdownButtonState<T> : State<DropdownButton<T>>, WidgetsBindingObserver where T : class {
int? _selectedIndex;
_DropdownRoute<T> _dropdownRoute;
public void didChangeTextScaleFactor() {
}
public void didChangeLocales(List<Locale> locale) {
}
public IPromise<bool> didPopRoute() {
return Promise<bool>.Resolved(false);
}
public IPromise<bool> didPushRoute(string route) {
return Promise<bool>.Resolved(false);
}
public override void initState() {
base.initState();
this._updateSelectedIndex();
WidgetsBinding.instance.addObserver(this);
}
public override void dispose() {
WidgetsBinding.instance.removeObserver(this);
this._removeDropdownRoute();
base.dispose();
}
public void didChangeMetrics() {
this._removeDropdownRoute();
}
void _removeDropdownRoute() {
this._dropdownRoute?._dismiss();
this._dropdownRoute = null;
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
this._updateSelectedIndex();
}
void _updateSelectedIndex() {
if (!this._enabled) {
return;
}
D.assert(this.widget.value == null ||
this.widget.items.Where((DropdownMenuItem<T> item) => item.value.Equals(this.widget.value))
.ToList().Count == 1);
this._selectedIndex = null;
for (int itemIndex = 0; itemIndex < this.widget.items.Count; itemIndex++) {
if (this.widget.items[itemIndex].value.Equals(this.widget.value)) {
this._selectedIndex = itemIndex;
return;
}
}
}
TextStyle _textStyle {
get { return this.widget.style ?? Theme.of(this.context).textTheme.subhead; }
}
void _handleTap() {
RenderBox itemBox = (RenderBox) this.context.findRenderObject();
Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size;
TextDirection textDirection = Directionality.of(this.context);
EdgeInsets menuMargin = ButtonTheme.of(this.context).alignedDropdown
? DropdownConstants._kAlignedMenuMargin
: DropdownConstants._kUnalignedMenuMargin;
D.assert(this._dropdownRoute == null);
this._dropdownRoute = new _DropdownRoute<T>(
items: this.widget.items,
buttonRect: menuMargin.inflateRect(itemRect),
padding: DropdownConstants._kMenuItemPadding,
selectedIndex: this._selectedIndex ?? 0,
elevation: this.widget.elevation,
theme: Theme.of(this.context, shadowThemeOnly: true),
style: this._textStyle,
barrierLabel: MaterialLocalizations.of(this.context).modalBarrierDismissLabel
);
Navigator.push(this.context, this._dropdownRoute).Then(newValue => {
_DropdownRouteResult<T> value = newValue as _DropdownRouteResult<T>;
this._dropdownRoute = null;
if (!this.mounted || newValue == null) {
return;
}
if (this.widget.onChanged != null) {
this.widget.onChanged(value.result);
}
});
}
float? _denseButtonHeight {
get {
return Mathf.Max(this._textStyle.fontSize ?? 0.0f,
Mathf.Max(this.widget.iconSize, DropdownConstants._kDenseButtonHeight));
}
}
Color _downArrowColor {
get {
if (this._enabled) {
if (Theme.of(this.context).brightness == Brightness.light) {
return Colors.grey.shade700;
}
else {
return Colors.white70;
}
}
else {
if (Theme.of(this.context).brightness == Brightness.light) {
return Colors.grey.shade400;
}
else {
return Colors.white10;
}
}
}
}
bool _enabled {
get { return this.widget.items != null && this.widget.items.isNotEmpty() && this.widget.onChanged != null; }
}
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterial(context));
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
List<Widget> items = this._enabled ? new List<Widget>(this.widget.items) : new List<Widget>();
int hintIndex = 0;
if (this.widget.hint != null || (!this._enabled && this.widget.disabledHint != null)) {
Widget emplacedHint =
this._enabled
? this.widget.hint
: new DropdownMenuItem<Widget>(child: this.widget.disabledHint ?? this.widget.hint);
hintIndex = items.Count;
items.Add(new DefaultTextStyle(
style: this._textStyle.copyWith(color: Theme.of(context).hintColor),
child: new IgnorePointer(
child: emplacedHint
)
));
}
EdgeInsets padding = ButtonTheme.of(context).alignedDropdown
? DropdownConstants._kAlignedButtonPadding
: DropdownConstants._kUnalignedButtonPadding;
IndexedStack innerItemsWidget = new IndexedStack(
index: this._enabled ? (this._selectedIndex ?? hintIndex) : hintIndex,
alignment: Alignment.centerLeft,
children: items
);
Widget result = new DefaultTextStyle(
style: this._textStyle,
child: new Container(
padding: padding,
height: this.widget.isDense ? this._denseButtonHeight : null,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
this.widget.isExpanded ? new Expanded(child: innerItemsWidget) : (Widget) innerItemsWidget,
new Icon(Icons.arrow_drop_down,
size: this.widget.iconSize,
color: this._downArrowColor
)
}
)
)
);
if (!DropdownButtonHideUnderline.at(context)) {
float bottom = this.widget.isDense ? 0.0f : 8.0f;
result = new Stack(
children: new List<Widget> {
result,
new Positioned(
left: 0.0f,
right: 0.0f,
bottom: bottom,
child: new Container(
height: 1.0f,
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(color: new Color(0xFFBDBDBD), width: 0.0f))
)
)
)
}
);
}
return new GestureDetector(
onTap: this._enabled ? (GestureTapCallback) this._handleTap : null,
behavior: HitTestBehavior.opaque,
child: result
);
}
}
public class DropdownButtonFormField<T> : FormField<T> where T : class {
public DropdownButtonFormField(
Key key = null,
T value = null,
List<DropdownMenuItem<T>> items = null,
ValueChanged<T> onChanged = null,
InputDecoration decoration = null,
FormFieldSetter<T> onSaved = null,
FormFieldValidator<T> validator = null,
Widget hint = null
) : base(
key: key,
onSaved: onSaved,
initialValue: value,
validator: validator,
builder: (FormFieldState<T> field) => {
InputDecoration effectiveDecoration = (decoration ?? new InputDecoration())
.applyDefaults(Theme.of(field.context).inputDecorationTheme);
return new InputDecorator(
decoration: effectiveDecoration.copyWith(errorText: field.errorText),
isEmpty: value == null,
child: new DropdownButtonHideUnderline(
child: new DropdownButton<T>(
isDense: true,
value: value,
items: items,
hint: hint,
onChanged: field.didChange
)
)
);
}
) {
this.onChanged = onChanged;
}
public readonly ValueChanged<T> onChanged;
public override State createState() {
return new _DropdownButtonFormFieldState<T>();
}
}
class _DropdownButtonFormFieldState<T> : FormFieldState<T> where T : class {
public DropdownButtonFormField<T> widget {
get { return base.widget as DropdownButtonFormField<T>; }
}
public override void didChange(T value) {
base.didChange(value);
if (this.widget.onChanged != null) {
this.widget.onChanged(value);
}
}
}
}

3
Runtime/material/dropdown.cs.meta


fileFormatVersion: 2
guid: 54d382ec712d4e87b802716ca97c1f3d
timeCreated: 1552537966

381
Runtime/material/input_border.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.material {
public abstract class InputBorder : ShapeBorder {
public InputBorder(
BorderSide borderSide = null
) {
this.borderSide = this.borderSide ?? BorderSide.none;
}
public static readonly InputBorder none = new _NoInputBorder();
public readonly BorderSide borderSide;
public abstract InputBorder copyWith(BorderSide borderSide = null);
public virtual bool isOutline { get; }
public abstract void paint(Canvas canvas, Rect rect,
float gapStart,
float gapExtent = 0.0f,
float gapPercentage = 0.0f,
TextDirection? textDirection = null
);
public override void paint(Canvas canvas, Rect rect) {
this.paint(canvas, rect, 0.0f);
}
}
class _NoInputBorder : InputBorder {
public _NoInputBorder() : base(borderSide: BorderSide.none) {
}
public override InputBorder copyWith(BorderSide borderSide) {
return new _NoInputBorder();
}
public override bool isOutline {
get { return false; }
}
public override EdgeInsets dimensions {
get { return EdgeInsets.zero; }
}
public override ShapeBorder scale(float t) {
return new _NoInputBorder();
}
public override Path getInnerPath(Rect rect) {
Path path = new Path();
path.addRect(rect);
return path;
}
public override Path getOuterPath(Rect rect) {
Path path = new Path();
path.addRect(rect);
return path;
}
public override void paint(Canvas canvas, Rect rect,
float gapStart,
float gapExtent = 0.0f,
float gapPercentage = 0.0f,
TextDirection? textDirection = null
) {
}
}
class UnderlineInputBorder : InputBorder {
public UnderlineInputBorder(
BorderSide borderSide = null,
BorderRadius borderRadius = null
) : base(borderSide: borderSide ?? new BorderSide()) {
this.borderRadius = borderRadius ?? BorderRadius.only(
topLeft: Radius.circular(4.0f),
topRight: Radius.circular(4.0f)
);
}
public readonly BorderRadius borderRadius;
public override bool isOutline {
get { return false; }
}
public UnderlineInputBorder copyWith(BorderSide borderSide = null, BorderRadius borderRadius = null) {
return new UnderlineInputBorder(
borderSide: borderSide ?? this.borderSide,
borderRadius: borderRadius ?? this.borderRadius
);
}
public override InputBorder copyWith(BorderSide borderSide = null) {
return new UnderlineInputBorder(
borderSide: borderSide ?? this.borderSide
);
}
public override EdgeInsets dimensions {
get { return EdgeInsets.only(bottom: this.borderSide.width); }
}
public override ShapeBorder scale(float t) {
return new UnderlineInputBorder(borderSide: this.borderSide.scale(t));
}
public override Path getInnerPath(Rect rect) {
Path path = new Path();
path.addRect(Rect.fromLTWH(rect.left, rect.top, rect.width,
Mathf.Max(0.0f, rect.height - this.borderSide.width)));
return path;
}
public override Path getOuterPath(Rect rect) {
Path path = new Path();
path.addRRect(this.borderRadius.toRRect(rect));
return path;
}
public override ShapeBorder lerpFrom(ShapeBorder a, float t) {
if (a is UnderlineInputBorder) {
return new UnderlineInputBorder(
borderSide: BorderSide.lerp((a as UnderlineInputBorder).borderSide, this.borderSide, t),
borderRadius: BorderRadius.lerp((a as UnderlineInputBorder).borderRadius, this.borderRadius, t)
);
}
return base.lerpFrom(a, t);
}
public override ShapeBorder lerpTo(ShapeBorder b, float t) {
if (b is UnderlineInputBorder) {
return new UnderlineInputBorder(
borderSide: BorderSide.lerp(this.borderSide, (b as UnderlineInputBorder).borderSide, t),
borderRadius: BorderRadius.lerp(this.borderRadius, (b as UnderlineInputBorder).borderRadius, t)
);
}
return base.lerpTo(b, t);
}
public override void paint(Canvas canvas, Rect rect,
float gapStart,
float gapExtent = 0.0f,
float gapPercentage = 0.0f,
TextDirection? textDirection = null
) {
if (this.borderRadius.bottomLeft != Radius.zero || this.borderRadius.bottomRight != Radius.zero) {
canvas.clipPath(this.getOuterPath(rect));
}
canvas.drawLine(rect.bottomLeft, rect.bottomRight, this.borderSide.toPaint());
}
public static bool operator ==(UnderlineInputBorder left, UnderlineInputBorder other) {
return left.borderSide == other.borderSide;
}
public static bool operator !=(UnderlineInputBorder left, UnderlineInputBorder other) {
return left.borderSide != other.borderSide;
}
public override int GetHashCode() {
return this.borderSide.GetHashCode();
}
}
public class OutlineInputBorder : InputBorder {
public OutlineInputBorder(
BorderSide borderSide = null,
BorderRadius borderRadius = null,
float gapPadding = 4.0f
) : base(borderSide: borderSide ?? new BorderSide()) {
D.assert(gapPadding >= 0.0f);
this.borderRadius = borderRadius ?? BorderRadius.all(Radius.circular(4.0f));
}
static bool _cornersAreCircular(BorderRadius borderRadius) {
return borderRadius.topLeft.x == borderRadius.topLeft.y
&& borderRadius.bottomLeft.x == borderRadius.bottomLeft.y
&& borderRadius.topRight.x == borderRadius.topRight.y
&& borderRadius.bottomRight.x == borderRadius.bottomRight.y;
}
public readonly float gapPadding;
public readonly BorderRadius borderRadius;
public override bool isOutline {
get { return true; }
}
public OutlineInputBorder copyWith(
BorderSide borderSide,
BorderRadius borderRadius,
float? gapPadding
) {
return new OutlineInputBorder(
borderSide: borderSide ?? this.borderSide,
borderRadius: borderRadius ?? this.borderRadius,
gapPadding: gapPadding ?? this.gapPadding
);
}
public override InputBorder copyWith(BorderSide borderSide) {
return new OutlineInputBorder(
borderSide: borderSide ?? this.borderSide,
borderRadius: this.borderRadius,
gapPadding: this.gapPadding
);
}
public override EdgeInsets dimensions {
get { return EdgeInsets.all(this.borderSide.width); }
}
public override ShapeBorder scale(float t) {
return new OutlineInputBorder(
borderSide: this.borderSide.scale(t),
borderRadius: this.borderRadius * t,
gapPadding: this.gapPadding * t
);
}
public override ShapeBorder lerpFrom(ShapeBorder a, float t) {
if (a is OutlineInputBorder) {
OutlineInputBorder outline = a as OutlineInputBorder;
return new OutlineInputBorder(
borderRadius: BorderRadius.lerp(outline.borderRadius, this.borderRadius, t),
borderSide: BorderSide.lerp(outline.borderSide, this.borderSide, t),
gapPadding: outline.gapPadding
);
}
return base.lerpFrom(a, t);
}
public override ShapeBorder lerpTo(ShapeBorder b, float t) {
if (b is OutlineInputBorder) {
OutlineInputBorder outline = b as OutlineInputBorder;
return new OutlineInputBorder(
borderRadius: BorderRadius.lerp(this.borderRadius, outline.borderRadius, t),
borderSide: BorderSide.lerp(this.borderSide, outline.borderSide, t),
gapPadding: outline.gapPadding
);
}
return base.lerpTo(b, t);
}
public override Path getInnerPath(Rect rect) {
Path path = new Path();
path.addRRect(this.borderRadius.toRRect(rect).deflate(this.borderSide.width));
return path;
}
public override Path getOuterPath(Rect rect) {
Path path = new Path();
path.addRRect(this.borderRadius.toRRect(rect));
return path;
}
Path _gapBorderPath(Canvas canvas, RRect center, float start, float extent) {
Rect tlCorner = Rect.fromLTWH(
center.left,
center.top,
center.tlRadiusX * 2.0f,
center.tlRadiusY * 2.0f
);
Rect trCorner = Rect.fromLTWH(
center.right - center.trRadiusX * 2.0f,
center.top,
center.trRadiusX * 2.0f,
center.trRadiusY * 2.0f
);
Rect brCorner = Rect.fromLTWH(
center.right - center.brRadiusX * 2.0f,
center.bottom - center.brRadiusY * 2.0f,
center.brRadiusX * 2.0f,
center.brRadiusY * 2.0f
);
Rect blCorner = Rect.fromLTWH(
center.left,
center.bottom - center.brRadiusY * 2.0f,
center.blRadiusX * 2.0f,
center.blRadiusY * 2.0f
);
const float cornerArcSweep = Mathf.PI / 2.0f;
float tlCornerArcSweep = start < center.tlRadiusX
? Mathf.Asin(start / center.tlRadiusX)
: Mathf.PI / 2.0f;
Path path = new Path();
path.addArc(tlCorner, Mathf.PI, tlCornerArcSweep);
path.moveTo(center.left + center.tlRadiusX, center.top);
if (start > center.tlRadiusX) {
path.lineTo(center.left + start, center.top);
}
const float trCornerArcStart = (3 * Mathf.PI) / 2.0f;
const float trCornerArcSweep = cornerArcSweep;
if (start + extent < center.width - center.trRadiusX) {
path.relativeMoveTo(extent, 0.0f);
path.lineTo(center.right - center.trRadiusX, center.top);
path.addArc(trCorner, trCornerArcStart, trCornerArcSweep);
}
else if (start + extent < center.width) {
float dx = center.width - (start + extent);
float sweep = Mathf.Acos(dx / center.trRadiusX);
path.addArc(trCorner, trCornerArcStart + sweep, trCornerArcSweep - sweep);
}
path.moveTo(center.right, center.top + center.trRadiusY);
path.lineTo(center.right, center.bottom - center.brRadiusY);
path.addArc(brCorner, 0.0f, cornerArcSweep);
path.lineTo(center.left + center.blRadiusX, center.bottom);
path.addArc(blCorner, Mathf.PI / 2.0f, cornerArcSweep);
path.lineTo(center.left, center.top + center.trRadiusY);
return path;
}
public override void paint(Canvas canvas, Rect rect,
float gapStart,
float gapExtent = 0.0f,
float gapPercentage = 0.0f,
TextDirection? textDirection = null
) {
D.assert(gapPercentage >= 0.0f && gapPercentage <= 1.0f);
D.assert(_cornersAreCircular(this.borderRadius));
Paint paint = this.borderSide.toPaint();
RRect outer = this.borderRadius.toRRect(rect);
RRect center = outer.deflate(this.borderSide.width / 2.0f);
if (gapExtent <= 0.0f || gapPercentage == 0.0f) {
canvas.drawRRect(center, paint);
}
else {
float extent = MathUtils.lerpFloat(0.0f, gapExtent + this.gapPadding * 2.0f, gapPercentage);
switch (textDirection) {
case TextDirection.rtl: {
Path path = this._gapBorderPath(canvas, center, gapStart + this.gapPadding - extent, extent);
canvas.drawPath(path, paint);
break;
}
case TextDirection.ltr: {
Path path = this._gapBorderPath(canvas, center, gapStart - this.gapPadding, extent);
canvas.drawPath(path, paint);
break;
}
}
}
}
public static bool operator ==(OutlineInputBorder left, OutlineInputBorder other) {
return other.borderSide == left.borderSide
&& other.borderRadius == left.borderRadius
&& other.gapPadding == left.gapPadding;
}
public static bool operator !=(OutlineInputBorder left, OutlineInputBorder other) {
return !(left == other);
}
public override int GetHashCode() {
var hashCode = this.borderSide.GetHashCode();
hashCode = (hashCode * 397) ^ this.borderRadius.GetHashCode();
hashCode = (hashCode * 397) ^ this.gapPadding.GetHashCode();
return hashCode;
}
}
}

3
Runtime/material/input_border.cs.meta


fileFormatVersion: 2
guid: 6431f8efd0b444ea9982ff6d0a0e74f4
timeCreated: 1552619063

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

3
Runtime/material/input_decorator.cs.meta


fileFormatVersion: 2
guid: 2106361ab28b4560a12fdbae0f1b1c8f
timeCreated: 1552548801

551
Runtime/material/progress_indicator.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
namespace Unity.UIWidgets.material {
class _ProgressIndicatorContants {
public const float _kLinearProgressIndicatorHeight = 6.0f;
public const float _kMinCircularProgressIndicatorSize = 36.0f;
public const int _kIndeterminateLinearDuration = 1800;
public static readonly Animatable<float> _kStrokeHeadTween = new CurveTween(
curve: new Interval(0.0f, 0.5f, curve: Curves.fastOutSlowIn)
).chain(new CurveTween(
curve: new SawTooth(5)
));
public static readonly Animatable<float> _kStrokeTailTween = new CurveTween(
curve: new Interval(0.5f, 1.0f, curve: Curves.fastOutSlowIn)
).chain(new CurveTween(
curve: new SawTooth(5)
));
public static readonly Animatable<int> _kStepTween = new StepTween(begin: 0, end: 5);
public static readonly Animatable<float> _kRotationTween = new CurveTween(curve: new SawTooth(5));
}
public abstract class ProgressIndicator : StatefulWidget {
public ProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null
) : base(key: key) {
this.value = value;
this.backgroundColor = backgroundColor;
this.valueColor = valueColor;
}
public readonly float? value;
public readonly Color backgroundColor;
public readonly Animation<Color> valueColor;
public Color _getBackgroundColor(BuildContext context) {
return this.backgroundColor ?? Theme.of(context).backgroundColor;
}
public Color _getValueColor(BuildContext context) {
return this.valueColor?.value ?? Theme.of(context).accentColor;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new PercentProperty("value", this.value ?? 0.0f, showName: false,
ifNull: "<indeterminate>"));
}
}
class _LinearProgressIndicatorPainter : AbstractCustomPainter {
public _LinearProgressIndicatorPainter(
Color backgroundColor = null,
Color valueColor = null,
float? value = null,
float? animationValue = null,
TextDirection? textDirection = null
) {
D.assert(textDirection != null);
this.backgroundColor = backgroundColor;
this.valueColor = valueColor;
this.value = value;
this.animationValue = animationValue;
this.textDirection = textDirection;
}
public readonly Color backgroundColor;
public readonly Color valueColor;
public readonly float? value;
public readonly float? animationValue;
public readonly TextDirection? textDirection;
static readonly Curve line1Head = new Interval(
0.0f,
750.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.2f, 0.0f, 0.8f, 1.0f)
);
static readonly Curve line1Tail = new Interval(
333.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
(333.0f + 750.0f) / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.4f, 0.0f, 1.0f, 1.0f)
);
static readonly Curve line2Head = new Interval(
1000.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
(1000.0f + 567.0f) / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.0f, 0.0f, 0.65f, 1.0f)
);
static readonly Curve line2Tail = new Interval(
1267.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
(1267.0f + 533.0f) / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.10f, 0.0f, 0.45f, 1.0f)
);
public override void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = this.backgroundColor;
paint.style = PaintingStyle.fill;
canvas.drawRect(Offset.zero & size, paint);
paint.color = this.valueColor;
void drawBar(float x, float width) {
if (width <= 0.0f) {
return;
}
float left;
switch (this.textDirection) {
case TextDirection.rtl:
left = size.width - width - x;
break;
case TextDirection.ltr:
left = x;
break;
default:
throw new Exception("Unknown text direction: " + this.textDirection);
}
canvas.drawRect(new Offset(left, 0.0f) & new Size(width, size.height), paint);
}
if (this.value != null) {
drawBar(0.0f, this.value.Value.clamp(0.0f, 1.0f) * size.width);
}
else {
float x1 = size.width * line1Tail.transform(this.animationValue ?? 0.0f);
float width1 = size.width * line1Head.transform(this.animationValue ?? 0.0f) - x1;
float x2 = size.width * line2Tail.transform(this.animationValue ?? 0.0f);
float width2 = size.width * line2Head.transform(this.animationValue ?? 0.0f) - x2;
drawBar(x1, width1);
drawBar(x2, width2);
}
}
public override bool shouldRepaint(CustomPainter oldPainter) {
D.assert(oldPainter is _LinearProgressIndicatorPainter);
_LinearProgressIndicatorPainter painter = oldPainter as _LinearProgressIndicatorPainter;
return painter.backgroundColor != this.backgroundColor
|| painter.valueColor != this.valueColor
|| painter.value != this.value
|| painter.animationValue != this.animationValue
|| painter.textDirection != this.textDirection;
}
}
public class LinearProgressIndicator : ProgressIndicator {
public LinearProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null
) : base(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor
) {
}
public override State createState() {
return new _LinearProgressIndicatorState();
}
}
class _LinearProgressIndicatorState : SingleTickerProviderStateMixin<LinearProgressIndicator> {
AnimationController _controller;
public _LinearProgressIndicatorState() {
}
public override void initState() {
base.initState();
this._controller = new AnimationController(
duration: new TimeSpan(0, 0, 0, 0, _ProgressIndicatorContants._kIndeterminateLinearDuration),
vsync: this
);
if (this.widget.value == null) {
this._controller.repeat();
}
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
if (this.widget.value == null && !this._controller.isAnimating) {
this._controller.repeat();
}
else if (this.widget.value != null && this._controller.isAnimating) {
this._controller.stop();
}
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
Widget _buildIndicator(BuildContext context, float animationValue, TextDirection textDirection) {
return new Container(
constraints: new BoxConstraints(
minWidth: float.PositiveInfinity,
minHeight: _ProgressIndicatorContants._kLinearProgressIndicatorHeight
),
child: new CustomPaint(
painter: new _LinearProgressIndicatorPainter(
backgroundColor: this.widget._getBackgroundColor(context),
valueColor: this.widget._getValueColor(context),
value: this.widget.value, // may be null
animationValue: animationValue, // ignored if widget.value is not null
textDirection: textDirection
)
)
);
}
public override Widget build(BuildContext context) {
TextDirection textDirection = Directionality.of(context);
if (this.widget.value != null) {
return this._buildIndicator(context, this._controller.value, textDirection);
}
return new AnimatedBuilder(
animation: this._controller.view,
builder: (BuildContext _context, Widget child) => {
return this._buildIndicator(_context, this._controller.value, textDirection);
}
);
}
}
class _CircularProgressIndicatorPainter : AbstractCustomPainter {
public _CircularProgressIndicatorPainter(
Color valueColor = null,
float? value = null,
float? headValue = null,
float? tailValue = null,
int? stepValue = null,
float? rotationValue = null,
float? strokeWidth = null
) {
this.valueColor = valueColor;
this.value = value;
this.headValue = headValue;
this.tailValue = tailValue;
this.stepValue = stepValue;
this.rotationValue = rotationValue;
this.strokeWidth = strokeWidth;
this.arcStart = value != null
? _startAngle
: _startAngle + tailValue * 3 / 2 * Mathf.PI + rotationValue * Mathf.PI * 1.7f -
stepValue * 0.8f * Mathf.PI;
this.arcSweep = value != null
? value.Value.clamp(0.0f, 1.0f) * _sweep
: Mathf.Max(headValue * 3 / 2 * Mathf.PI - tailValue * 3 / 2 * Mathf.PI ?? 0.0f, _epsilon);
}
public readonly Color valueColor;
public readonly float? value;
public readonly float? headValue;
public readonly float? tailValue;
public readonly int? stepValue;
public readonly float? rotationValue;
public readonly float? strokeWidth;
public readonly float? arcStart;
public readonly float? arcSweep;
const float _twoPi = Mathf.PI * 2.0f;
const float _epsilon = .001f;
const float _sweep = _twoPi - _epsilon;
const float _startAngle = -Mathf.PI / 2.0f;
public override void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = this.valueColor;
paint.strokeWidth = this.strokeWidth ?? 0.0f;
paint.style = PaintingStyle.stroke;
if (this.value == null) // Indeterminate
{
paint.strokeCap = StrokeCap.square;
}
canvas.drawArc(Offset.zero & size, this.arcStart ?? 0.0f, this.arcSweep ?? 0.0f, false, paint);
}
public override bool shouldRepaint(CustomPainter oldPainter) {
D.assert(oldPainter is _CircularProgressIndicatorPainter);
_CircularProgressIndicatorPainter painter = oldPainter as _CircularProgressIndicatorPainter;
return painter.valueColor != this.valueColor
|| painter.value != this.value
|| painter.headValue != this.headValue
|| painter.tailValue != this.tailValue
|| painter.stepValue != this.stepValue
|| painter.rotationValue != this.rotationValue
|| painter.strokeWidth != this.strokeWidth;
}
}
public class CircularProgressIndicator : ProgressIndicator {
public CircularProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null,
float strokeWidth = 4.0f
) : base(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor
) {
this.strokeWidth = strokeWidth;
}
public readonly float? strokeWidth;
public override State createState() {
return new _CircularProgressIndicatorState();
}
}
class _CircularProgressIndicatorState : SingleTickerProviderStateMixin<CircularProgressIndicator> {
protected AnimationController _controller;
public _CircularProgressIndicatorState() {
}
public override void initState() {
base.initState();
this._controller = new AnimationController(
duration: new TimeSpan(0, 0, 0, 5),
vsync: this
);
if (this.widget.value == null) {
this._controller.repeat();
}
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
if (this.widget.value == null && !this._controller.isAnimating) {
this._controller.repeat();
}
else if (this.widget.value != null && this._controller.isAnimating) {
this._controller.stop();
}
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
Widget _buildIndicator(BuildContext context, float headValue, float tailValue, int stepValue,
float rotationValue) {
return new Container(
constraints: new BoxConstraints(
minWidth: _ProgressIndicatorContants._kMinCircularProgressIndicatorSize,
minHeight: _ProgressIndicatorContants._kMinCircularProgressIndicatorSize
),
child: new CustomPaint(
painter: new _CircularProgressIndicatorPainter(
valueColor: this.widget._getValueColor(context),
value: this.widget.value,
headValue: headValue,
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: this.widget.strokeWidth
)
)
);
}
protected Widget _buildAnimation() {
return new AnimatedBuilder(
animation: this._controller,
builder: (BuildContext context, Widget child) => {
return this._buildIndicator(
context,
_ProgressIndicatorContants._kStrokeHeadTween.evaluate(this._controller),
_ProgressIndicatorContants._kStrokeTailTween.evaluate(this._controller),
_ProgressIndicatorContants._kStepTween.evaluate(this._controller),
_ProgressIndicatorContants._kRotationTween.evaluate(this._controller)
);
}
);
}
public override Widget build(BuildContext context) {
if (this.widget.value != null) {
return this._buildIndicator(context, 0.0f, 0.0f, 0, 0.0f);
}
return this._buildAnimation();
}
}
class _RefreshProgressIndicatorPainter : _CircularProgressIndicatorPainter {
public _RefreshProgressIndicatorPainter(
Color valueColor = null,
float? value = null,
float? headValue = null,
float? tailValue = null,
int? stepValue = null,
float? rotationValue = null,
float? strokeWidth = null,
float? arrowheadScale = null
) : base(
valueColor: valueColor,
value: value,
headValue: headValue,
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: strokeWidth
) {
this.arrowheadScale = arrowheadScale;
}
public readonly float? arrowheadScale;
void paintArrowhead(Canvas canvas, Size size) {
// ux, uy: a unit vector whose direction parallels the base of the arrowhead.
// (So ux, -uy points in the direction the arrowhead points.)
float arcEnd = this.arcStart + this.arcSweep ?? 0.0f;
float ux = Mathf.Cos(arcEnd);
float uy = Mathf.Sin(arcEnd);
D.assert(size.width == size.height);
float radius = size.width / 2.0f;
float? arrowheadPointX = radius + ux * radius + -uy * this.strokeWidth * 2.0f * this.arrowheadScale;
float? arrowheadPointY = radius + uy * radius + ux * this.strokeWidth * 2.0f * this.arrowheadScale;
float? arrowheadRadius = this.strokeWidth * 1.5f * this.arrowheadScale;
float? innerRadius = radius - arrowheadRadius;
float? outerRadius = radius + arrowheadRadius;
Path path = new Path();
path.moveTo(radius + ux * innerRadius ?? 0.0f, radius + uy * innerRadius ?? 0.0f);
path.lineTo(radius + ux * outerRadius ?? 0.0f, radius + uy * outerRadius ?? 0.0f);
path.lineTo(arrowheadPointX ?? 0.0f, arrowheadPointY ?? 0.0f);
path.close();
Paint paint = new Paint();
paint.color = this.valueColor;
paint.strokeWidth = this.strokeWidth ?? 0.0f;
paint.style = PaintingStyle.fill;
canvas.drawPath(path, paint);
}
public override void paint(Canvas canvas, Size size) {
base.paint(canvas, size);
if (this.arrowheadScale > 0.0) {
this.paintArrowhead(canvas, size);
}
}
}
public class RefreshProgressIndicator : CircularProgressIndicator {
public RefreshProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null,
float strokeWidth = 2.0f
) : base(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor,
strokeWidth: strokeWidth
) {
}
public override State createState() {
return new _RefreshProgressIndicatorState();
}
}
class _RefreshProgressIndicatorState : _CircularProgressIndicatorState {
const float _indicatorSize = 40.0f;
public _RefreshProgressIndicatorState() {
}
public override Widget build(BuildContext context) {
if (this.widget.value != null) {
this._controller.setValue(this.widget.value / 10.0f ?? 0.0f);
}
else if (!this._controller.isAnimating) {
this._controller.repeat();
}
return this._buildAnimation();
}
Widget _buildIndicator(BuildContext context, float headValue, float tailValue, int stepValue,
float rotationValue) {
float arrowheadScale =
this.widget.value == null ? 0.0f : (this.widget.value * 2.0f).Value.clamp(0.0f, 1.0f);
return new Container(
width: _indicatorSize,
height: _indicatorSize,
margin: EdgeInsets.all(4.0f),
child: new Material(
type: MaterialType.circle,
color: this.widget.backgroundColor ?? Theme.of(context).canvasColor,
elevation: 2.0f,
child: new Padding(
padding: EdgeInsets.all(12.0f),
child: new CustomPaint(
painter: new _RefreshProgressIndicatorPainter(
valueColor: this.widget._getValueColor(context),
value: null, // Draw the indeterminate progress indicator.
headValue: headValue,
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: this.widget.strokeWidth,
arrowheadScale: arrowheadScale
)
)
)
)
);
}
}
}

3
Runtime/material/progress_indicator.cs.meta


fileFormatVersion: 2
guid: 42b0b0b180624c38b2dec573a232bd8a
timeCreated: 1552530632

107
Runtime/material/tab_bar_theme.cs


using System;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class TabBarTheme : Diagnosticable, IEquatable<TabBarTheme> {
public TabBarTheme(
Decoration indicator = null,
TabBarIndicatorSize? indicatorSize = null,
Color labelColor = null,
Color unselectedLabelColor = null) {
this.indicator = indicator;
this.indicatorSize = indicatorSize;
this.labelColor = labelColor;
this.unselectedLabelColor = unselectedLabelColor;
}
public readonly Decoration indicator;
public readonly TabBarIndicatorSize? indicatorSize;
public readonly Color labelColor;
public readonly Color unselectedLabelColor;
public TabBarTheme copyWith(
Decoration indicator = null,
TabBarIndicatorSize? indicatorSize = null,
Color labelColor = null,
Color unselectedLabelColor = null
) {
return new TabBarTheme(
indicator: indicator ?? this.indicator,
indicatorSize: indicatorSize ?? this.indicatorSize,
labelColor: labelColor ?? this.labelColor,
unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor);
}
public static TabBarTheme of(BuildContext context) {
return Theme.of(context).tabBarTheme;
}
public static TabBarTheme lerp(TabBarTheme a, TabBarTheme b, float t) {
D.assert(a != null);
D.assert(b != null);
return new TabBarTheme(
indicator: Decoration.lerp(a.indicator, b.indicator, t),
indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize,
labelColor: Color.lerp(a.labelColor, b.labelColor, t),
unselectedLabelColor: Color.lerp(a.unselectedLabelColor, b.unselectedLabelColor, t)
);
}
public override int GetHashCode() {
unchecked {
var hashCode = this.indicator != null ? this.indicator.GetHashCode() : 0;
hashCode = (hashCode * 397) ^ (this.indicatorSize != null ? this.indicatorSize.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.labelColor != null ? this.labelColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^
(this.unselectedLabelColor != null ? this.unselectedLabelColor.GetHashCode() : 0);
return hashCode;
}
}
public bool Equals(TabBarTheme other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return other.indicator == this.indicator &&
other.indicatorSize == this.indicatorSize &&
other.labelColor == this.labelColor &&
other.unselectedLabelColor == this.unselectedLabelColor;
}
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((TabBarTheme) obj);
}
public static bool operator ==(TabBarTheme left, TabBarTheme right) {
return Equals(left, right);
}
public static bool operator !=(TabBarTheme left, TabBarTheme right) {
return !Equals(left, right);
}
}
}

11
Runtime/material/tab_bar_theme.cs.meta


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

187
Runtime/material/tab_controller.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class TabController : ChangeNotifier {
public TabController(
int initialIndex = 0,
int? length = null,
TickerProvider vsync = null) {
D.assert(length != null && length >= 0);
D.assert(initialIndex >= 0 && (length == 0 || initialIndex < length));
D.assert(vsync != null);
this.length = length.Value;
this._index = initialIndex;
this._previousIndex = initialIndex;
this._animationController = length < 2
? null
: new AnimationController(
value: initialIndex,
upperBound: length.Value - 1,
vsync: vsync);
}
public Animation<float> animation {
get { return this._animationController?.view ?? Animations.kAlwaysCompleteAnimation; }
}
readonly AnimationController _animationController;
public readonly int length;
void _changeIndex(int value, TimeSpan? duration = null, Curve curve = null) {
D.assert(value >= 0 && (value < this.length || this.length == 0));
D.assert(duration == null ? curve == null : true);
D.assert(this._indexIsChangingCount >= 0);
if (value == this._index || this.length < 2) {
return;
}
this._previousIndex = this.index;
this._index = value;
if (duration != null) {
this._indexIsChangingCount++;
this.notifyListeners();
this._animationController.animateTo(
this._index, duration: duration, curve: curve).whenCompleteOrCancel(() => {
this._indexIsChangingCount--;
this.notifyListeners();
});
}
else {
this._indexIsChangingCount++;
this._animationController.setValue(this._index);
this._indexIsChangingCount--;
this.notifyListeners();
}
}
public int index {
get { return this._index; }
set { this._changeIndex(value); }
}
int _index;
public int previousIndex {
get { return this._previousIndex; }
}
int _previousIndex;
public bool indexIsChanging {
get { return this._indexIsChangingCount != 0; }
}
int _indexIsChangingCount = 0;
public void animateTo(int value, TimeSpan? duration = null, Curve curve = null) {
duration = duration ?? Constants.kTabScrollDuration;
curve = curve ?? Curves.ease;
this._changeIndex(value, duration: duration, curve: curve);
}
public float offset {
get { return this.length > 1 ? this._animationController.value - this._index : 0.0f; }
set {
D.assert(this.length > 1);
D.assert(value >= -1.0f && value <= 1.0f);
D.assert(!this.indexIsChanging);
if (value == this.offset) {
return;
}
this._animationController.setValue(value + this._index);
}
}
public override void dispose() {
this._animationController?.dispose();
base.dispose();
}
}
class _TabControllerScope : InheritedWidget {
public _TabControllerScope(
Key key = null,
TabController controller = null,
bool? enabled = null,
Widget child = null
) : base(key: key, child: child) {
this.controller = controller;
this.enabled = enabled;
}
public readonly TabController controller;
public readonly bool? enabled;
public override bool updateShouldNotify(InheritedWidget old) {
_TabControllerScope _old = (_TabControllerScope) old;
return this.enabled != _old.enabled
|| this.controller != _old.controller;
}
}
class DefaultTabController : StatefulWidget {
public DefaultTabController(
Key key = null,
int? length = null,
int initialIndex = 0,
Widget child = null
) : base(key: key) {
D.assert(length != null);
D.assert(child != null);
this.length = length;
this.initialIndex = initialIndex;
this.child = child;
}
public readonly int? length;
public readonly int initialIndex;
public readonly Widget child;
public static TabController of(BuildContext context) {
_TabControllerScope scope =
(_TabControllerScope) context.inheritFromWidgetOfExactType(typeof(_TabControllerScope));
return scope?.controller;
}
public override State createState() {
return new _DefaultTabControllerState();
}
}
class _DefaultTabControllerState : SingleTickerProviderStateMixin<DefaultTabController> {
TabController _controller;
public override void initState() {
base.initState();
this._controller = new TabController(
vsync: this,
length: this.widget.length,
initialIndex: this.widget.initialIndex
);
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
public override Widget build(BuildContext context) {
return new _TabControllerScope(
controller: this._controller,
enabled: TickerMode.of(context),
child: this.widget.child
);
}
}
}

11
Runtime/material/tab_controller.cs.meta


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

90
Runtime/material/tab_indicator.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.material {
public class UnderlineTabIndicator : Decoration {
public UnderlineTabIndicator(
BorderSide borderSide = null,
EdgeInsets insets = null) {
borderSide = borderSide ?? new BorderSide(width: 2.0f, color: Colors.white);
insets = insets ?? EdgeInsets.zero;
this.borderSide = borderSide;
this.insets = insets;
}
public readonly BorderSide borderSide;
public readonly EdgeInsets insets;
public override Decoration lerpFrom(Decoration a, float t) {
if (a is UnderlineTabIndicator) {
UnderlineTabIndicator _a = (UnderlineTabIndicator) a;
return new UnderlineTabIndicator(
borderSide: BorderSide.lerp(_a.borderSide, this.borderSide, t),
insets: EdgeInsets.lerp(_a.insets, this.insets, t)
);
}
return base.lerpFrom(a, t);
}
public override Decoration lerpTo(Decoration b, float t) {
if (b is UnderlineTabIndicator) {
UnderlineTabIndicator _b = (UnderlineTabIndicator) b;
return new UnderlineTabIndicator(
borderSide: BorderSide.lerp(this.borderSide, _b.borderSide, t),
insets: EdgeInsets.lerp(this.insets, _b.insets, t)
);
}
return base.lerpTo(b, t);
}
public override BoxPainter createBoxPainter(VoidCallback onChanged) {
return new _UnderlinePainter(this, onChanged);
}
}
class _UnderlinePainter : BoxPainter {
public _UnderlinePainter(
UnderlineTabIndicator decoration = null,
VoidCallback onChanged = null
) : base(onChanged: onChanged) {
D.assert(decoration != null);
this.decoration = decoration;
}
public readonly UnderlineTabIndicator decoration;
public BorderSide borderSide {
get { return this.decoration.borderSide; }
}
public EdgeInsets insets {
get { return this.decoration.insets; }
}
Rect _indicatorRectFor(Rect rect) {
D.assert(rect != null);
Rect indicator = this.insets.deflateRect(rect);
return Rect.fromLTWH(
indicator.left,
indicator.bottom - this.borderSide.width,
indicator.width,
this.borderSide.width);
}
public override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
D.assert(configuration != null);
D.assert(configuration.size != null);
Rect rect = offset & configuration.size;
Rect indicator = this._indicatorRectFor(rect).deflate(this.borderSide.width / 2.0f);
Paint paint = this.borderSide.toPaint();
paint.strokeCap = StrokeCap.square;
canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
}
}
}

11
Runtime/material/tab_indicator.cs.meta


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

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

11
Runtime/material/tabs.cs.meta


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

242
Runtime/widgets/form.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.widgets {
class Form : StatefulWidget {
public Form(
Key key = null,
Widget child = null,
bool autovalidate = false,
WillPopCallback onWillPop = null,
VoidCallback onChanged = null
) : base(key: key) {
D.assert(child != null);
this.child = child;
this.autovalidate = autovalidate;
this.onWillPop = onWillPop;
this.onChanged = onChanged;
}
public static FormState of(BuildContext context) {
_FormScope scope = (_FormScope) context.inheritFromWidgetOfExactType(typeof(_FormScope));
return scope?._formState;
}
public readonly Widget child;
public readonly bool autovalidate;
public readonly WillPopCallback onWillPop;
public readonly VoidCallback onChanged;
public override State createState() {
return new FormState();
}
}
class FormState : State<Form> {
int _generation = 0;
public readonly HashSet<FormFieldState<dynamic>> _fields = new HashSet<FormFieldState<dynamic>>();
public FormState() {
}
public void _fieldDidChange() {
if (this.widget.onChanged != null) {
this.widget.onChanged();
}
this._forceRebuild();
}
void _forceRebuild() {
this.setState(() => { ++this._generation; });
}
public void _register(FormFieldState<dynamic> field) {
this._fields.Add(field);
}
public void _unregister(FormFieldState<dynamic> field) {
this._fields.Remove(field);
}
public override Widget build(BuildContext context) {
if (this.widget.autovalidate) {
this._validate();
}
return new WillPopScope(
onWillPop: this.widget.onWillPop,
child: new _FormScope(
formState: this,
generation: this._generation,
child: this.widget.child
)
);
}
void save() {
foreach (FormFieldState<dynamic> field in this._fields) {
field.save();
}
}
void reset() {
foreach (FormFieldState<dynamic> field in this._fields) {
field.reset();
}
this._fieldDidChange();
}
bool validate() {
this._forceRebuild();
return this._validate();
}
bool _validate() {
bool hasError = false;
foreach (FormFieldState<dynamic> field in this._fields) {
hasError = !field.validate() || hasError;
}
return !hasError;
}
}
class _FormScope : InheritedWidget {
public _FormScope(
Key key = null,
Widget child = null,
FormState formState = null,
int? generation = null
) :
base(key: key, child: child) {
this._formState = formState;
this._generation = generation;
}
public readonly FormState _formState;
public readonly int? _generation;
public Form form {
get { return this._formState.widget; }
}
public override bool updateShouldNotify(InheritedWidget _old) {
_FormScope old = _old as _FormScope;
return this._generation != old._generation;
}
}
public delegate string FormFieldValidator<T>(T value);
public delegate void FormFieldSetter<T>(T newValue);
public delegate Widget FormFieldBuilder<T>(FormFieldState<T> field) where T : class;
public class FormField<T> : StatefulWidget where T : class {
public FormField(
Key key = null,
FormFieldBuilder<T> builder = null,
FormFieldSetter<T> onSaved = null,
FormFieldValidator<T> validator = null,
T initialValue = null,
bool autovalidate = false,
bool enabled = true
) : base(key: key) {
D.assert(builder != null);
}
public readonly FormFieldSetter<T> onSaved;
public readonly FormFieldValidator<T> validator;
public readonly FormFieldBuilder<T> builder;
public readonly T initialValue;
public readonly bool autovalidate;
public readonly bool enabled;
public override State createState() {
return new FormFieldState<T>();
}
}
public class FormFieldState<T> : State<FormField<T>> where T : class {
T _value;
string _errorText;
public T value {
get { return this._value; }
}
public string errorText {
get { return this._errorText; }
}
public bool hasError {
get { return this._errorText != null; }
}
public void save() {
if (this.widget.onSaved != null) {
this.widget.onSaved(this.value);
}
}
public void reset() {
this.setState(() => {
this._value = this.widget.initialValue;
this._errorText = null;
});
}
public bool validate() {
this.setState(() => { this._validate(); });
return !this.hasError;
}
bool _validate() {
if (this.widget.validator != null) {
this._errorText = this.widget.validator(this._value);
}
return !this.hasError;
}
public virtual void didChange(T value) {
this.setState(() => { this._value = value; });
Form.of(this.context)?._fieldDidChange();
}
protected void setValue(T value) {
this._value = value;
}
public override void initState() {
base.initState();
this._value = this.widget.initialValue;
}
public override void deactivate() {
Form.of(this.context)?._unregister(this as FormFieldState<dynamic>);
base.deactivate();
}
public override Widget build(BuildContext context) {
if (this.widget.autovalidate && this.widget.enabled) {
this._validate();
}
Form.of(context)?._register(this as FormFieldState<dynamic>);
return this.widget.builder(this);
}
}
}

3
Runtime/widgets/form.cs.meta


fileFormatVersion: 2
guid: 3ce8dad5676b40ec862b142dd03b9f64
timeCreated: 1552545243

11
Runtime/widgets/preferred_size.cs.meta


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

69
Runtime/widgets/will_pop_scope.cs


using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.widgets {
class WillPopScope : StatefulWidget {
public WillPopScope(
Key key = null,
Widget child = null,
WillPopCallback onWillPop = null
) : base(key: key) {
D.assert(child != null);
this.onWillPop = onWillPop;
this.child = child;
}
public readonly Widget child;
public readonly WillPopCallback onWillPop;
public override State createState() {
return new _WillPopScopeState();
}
}
class _WillPopScopeState : State<WillPopScope> {
ModalRoute _route;
public _WillPopScopeState() {
}
public override void didChangeDependencies() {
base.didChangeDependencies();
if (this.widget.onWillPop != null) {
this._route?.removeScopedWillPopCallback(this.widget.onWillPop);
}
this._route = ModalRoute.of(this.context);
if (this.widget.onWillPop != null) {
this._route?.addScopedWillPopCallback(this.widget.onWillPop);
}
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
base.didUpdateWidget(_oldWidget);
D.assert(this._route == ModalRoute.of(this.context));
WillPopScope oldWidget = _oldWidget as WillPopScope;
if (this.widget.onWillPop != oldWidget.onWillPop && this._route != null) {
if (oldWidget.onWillPop != null) {
this._route.removeScopedWillPopCallback(oldWidget.onWillPop);
}
if (this.widget.onWillPop != null) {
this._route.addScopedWillPopCallback(this.widget.onWillPop);
}
}
}
public override void dispose() {
if (this.widget.onWillPop != null) {
this._route?.removeScopedWillPopCallback(this.widget.onWillPop);
}
base.dispose();
}
public override Widget build(BuildContext context) {
return this.widget.child;
}
}
}

3
Runtime/widgets/will_pop_scope.cs.meta


fileFormatVersion: 2
guid: 624e6292cdfc4b43ac439df81ae8efee
timeCreated: 1552547854

11
Runtime/widgets/perferred_size.cs.meta


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

/Runtime/widgets/perferred_size.cs → /Runtime/widgets/preferred_size.cs

正在加载...
取消
保存