浏览代码

Merge remote-tracking branch 'upstream/master' into text_edit

/main
fzhangtj 6 年前
当前提交
d217b35c
共有 106 个文件被更改,包括 22938 次插入225 次删除
  1. 4
      Runtime/Resources/UIWidgets_canvas.cginc
  2. 17
      Runtime/engine/UIWidgetsPanel.cs
  3. 1
      Runtime/flow/clip_path_layer.cs
  4. 1
      Runtime/flow/clip_rect_layer.cs
  5. 1
      Runtime/flow/clip_rrect_layer.cs
  6. 38
      Runtime/flow/physical_shape_layer.cs
  7. 5
      Runtime/flow/raster_cache.cs
  8. 24
      Runtime/gestures/monodrag.cs
  9. 9
      Runtime/gestures/recognizer.cs
  10. 7
      Runtime/material/app_bar.cs
  11. 145
      Runtime/material/bottom_sheet.cs
  12. 23
      Runtime/material/dropdown.cs
  13. 55
      Runtime/material/input_border.cs
  14. 170
      Runtime/material/input_decorator.cs
  15. 25
      Runtime/material/outline_button.cs
  16. 2
      Runtime/material/scaffold.cs
  17. 2
      Runtime/material/theme.cs
  18. 2
      Runtime/rendering/object.mixin.gen.cs
  19. 6
      Runtime/rendering/paragraph.cs
  20. 202
      Runtime/rendering/proxy_box.cs
  21. 8
      Runtime/rendering/sliver_persistent_header.cs
  22. 1
      Runtime/rendering/stack.cs
  23. 86
      Runtime/ui/geometry.cs
  24. 6
      Runtime/ui/matrix.cs
  25. 8
      Runtime/ui/painting/canvas.cs
  26. 6
      Runtime/ui/painting/canvas_impl.cs
  27. 39
      Runtime/ui/painting/path.cs
  28. 35
      Runtime/widgets/basic.cs
  29. 24
      Runtime/widgets/binding.cs
  30. 6
      Runtime/widgets/framework.cs
  31. 2
      Runtime/widgets/media_query.cs
  32. 10
      Runtime/widgets/scroll_physics.cs
  33. 4
      Runtime/widgets/sliver_persistent_header.cs
  34. 24
      Samples/UIWidgetSample/MaterialSample.cs
  35. 2
      Samples/UIWidgetsGallery/demo/colors_demo.cs
  36. 62
      Samples/UIWidgetsGallery/gallery/demo.cs
  37. 74
      Samples/UIWidgetsGallery/gallery/demos.cs
  38. 110
      Runtime/material/bottom_app_bar.cs
  39. 3
      Runtime/material/bottom_app_bar.cs.meta
  40. 592
      Runtime/material/bottom_navigation_bar.cs
  41. 3
      Runtime/material/bottom_navigation_bar.cs.meta
  42. 183
      Runtime/material/radio.cs
  43. 3
      Runtime/material/radio.cs.meta
  44. 71
      Runtime/painting/notched_shapes.cs
  45. 3
      Runtime/painting/notched_shapes.cs.meta
  46. 181
      Runtime/ui/painting/shadow_utils.cs
  47. 27
      Runtime/widgets/bottom_navigation_bar_item.cs
  48. 3
      Runtime/widgets/bottom_navigation_bar_item.cs.meta
  49. 423
      Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs
  50. 3
      Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs.meta
  51. 523
      Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs
  52. 3
      Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs.meta
  53. 228
      Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs
  54. 3
      Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs.meta
  55. 217
      Samples/UIWidgetsGallery/demo/material/cards_demo.cs
  56. 3
      Samples/UIWidgetsGallery/demo/material/cards_demo.cs.meta
  57. 1001
      Tests/Resources/india_chettinad_silk_maker.png
  58. 88
      Tests/Resources/india_chettinad_silk_maker.png.meta
  59. 1001
      Tests/Resources/india_thanjavur_market.png
  60. 88
      Tests/Resources/india_thanjavur_market.png.meta
  61. 8
      Tests/Resources/products.meta
  62. 1001
      Tests/Resources/products/backpack.png
  63. 88
      Tests/Resources/products/backpack.png.meta
  64. 1001
      Tests/Resources/products/belt.png
  65. 88
      Tests/Resources/products/belt.png.meta
  66. 406
      Tests/Resources/products/cup.png
  67. 88
      Tests/Resources/products/cup.png.meta
  68. 1001
      Tests/Resources/products/deskset.png
  69. 88
      Tests/Resources/products/deskset.png.meta
  70. 702
      Tests/Resources/products/dress.png
  71. 88
      Tests/Resources/products/dress.png.meta
  72. 1001
      Tests/Resources/products/earrings.png
  73. 88
      Tests/Resources/products/earrings.png.meta
  74. 408
      Tests/Resources/products/flatwear.png
  75. 88
      Tests/Resources/products/flatwear.png.meta
  76. 852
      Tests/Resources/products/hat.png
  77. 88
      Tests/Resources/products/hat.png.meta
  78. 702
      Tests/Resources/products/jacket.png
  79. 88
      Tests/Resources/products/jacket.png.meta
  80. 676
      Tests/Resources/products/jumper.png
  81. 88
      Tests/Resources/products/jumper.png.meta
  82. 1001
      Tests/Resources/products/kitchen_quattro.png
  83. 88
      Tests/Resources/products/kitchen_quattro.png.meta
  84. 1001
      Tests/Resources/products/napkins.png
  85. 88
      Tests/Resources/products/napkins.png.meta
  86. 984
      Tests/Resources/products/planters.png
  87. 88
      Tests/Resources/products/planters.png.meta
  88. 908
      Tests/Resources/products/platter.png
  89. 88
      Tests/Resources/products/platter.png.meta
  90. 1001
      Tests/Resources/products/scarf.png
  91. 88
      Tests/Resources/products/scarf.png.meta
  92. 808
      Tests/Resources/products/shirt.png
  93. 88
      Tests/Resources/products/shirt.png.meta
  94. 360
      Tests/Resources/products/sunnies.png
  95. 88
      Tests/Resources/products/sunnies.png.meta
  96. 807
      Tests/Resources/products/sweater.png
  97. 88
      Tests/Resources/products/sweater.png.meta
  98. 967
      Tests/Resources/products/sweats.png
  99. 88
      Tests/Resources/products/sweats.png.meta

4
Runtime/Resources/UIWidgets_canvas.cginc


half4 color = half4(0, 0, 0, 0);
float2 coord = i.ftcoord - _mf_radius * _mf_imgInc;
int width = _mf_radius * 2 + 1;
int width = _mf_radius * 2.0 + 1; // use 2.0 to avoid "bitfieldInsert"
[unroll(25)]
for (int i = 0; i < width; i++) {
color += tex2D(_tex, coord) * _mf_kernel[i];
coord += _mf_imgInc;

17
Runtime/engine/UIWidgetsPanel.cs


this._padding = new WindowPadding(
Screen.safeArea.x,
Screen.safeArea.y,
Screen.width - Screen.safeArea.width,
Screen.height - Screen.safeArea.height);
Screen.width - Screen.safeArea.width - Screen.safeArea.x,
Screen.height - Screen.safeArea.height - Screen.safeArea.y);
}
protected override bool hasFocus() {

protected override Vector2 queryWindowSize() {
var rect = this._uiWidgetsPanel.rectTransform.rect;
var size = new Vector2(rect.width,rect.height) *
var size = new Vector2(rect.width, rect.height) *
this._uiWidgetsPanel.canvas.scaleFactor / this._uiWidgetsPanel.devicePixelRatio;
size.x = Mathf.Round(size.x);
size.y = Mathf.Round(size.y);

if (canvas.renderMode != RenderMode.ScreenSpaceCamera) {
camera = canvas.GetComponent<GraphicRaycaster>().eventCamera;
}
var pos = new Vector2(windowPos.dx, windowPos.dy);
pos = pos * this.queryDevicePixelRatio() / this._uiWidgetsPanel.canvas.scaleFactor;
var rectTransform = this._uiWidgetsPanel.rectTransform;

protected override void OnEnable() {
base.OnEnable();
//Disable the default touch -> mouse event conversion on mobile devices
//Disable the default touch -> mouse event conversion on mobile devices
if (_repaintEvent == null) {
_repaintEvent = new Event {type = EventType.Repaint};
}

using (this._windowAdapter.getScope()) {
root = this.createWidget();
}
this._windowAdapter.attachRootWidget(root);
this._windowAdapter.attachRootWidget(root);
this._lastMouseMove = Input.mousePosition;
this._enteredPointers = new HashSet<int>();

PerformanceUtils.instance.updateDeltaTime(Time.unscaledDeltaTime);
this._displayMetrics.Update();
UIWidgetsMessageManager.ensureUIWidgetsMessageManagerIfNeeded();
if (this._mouseEntered) {
if (this._lastMouseMove.x != Input.mousePosition.x || this._lastMouseMove.y != Input.mousePosition.y) {
this.handleMouseMovement();

D.assert(this._windowAdapter != null);
this._windowAdapter.Update();
this._windowAdapter.OnGUI(_repaintEvent);
}
void OnGUI() {

1
Runtime/flow/clip_path_layer.cs


var clipPathBounds = this._clipPath.getBounds();
context.cullRect = context.cullRect.intersect(clipPathBounds);
this.paintBounds = Rect.zero;
if (!context.cullRect.isEmpty) {
var childPaintBounds = Rect.zero;
this.prerollChildren(context, matrix, ref childPaintBounds);

1
Runtime/flow/clip_rect_layer.cs


context.cullRect = context.cullRect.intersect(this._clipRect);
this.paintBounds = Rect.zero;
if (!context.cullRect.isEmpty) {
var childPaintBounds = Rect.zero;
this.prerollChildren(context, matrix, ref childPaintBounds);

1
Runtime/flow/clip_rrect_layer.cs


var clipPathBounds = this._clipRRect.outerRect;
context.cullRect = context.cullRect.intersect(clipPathBounds);
this.paintBounds = Rect.zero;
if (!context.cullRect.isEmpty) {
var childPaintBounds = Rect.zero;
this.prerollChildren(context, matrix, ref childPaintBounds);

38
Runtime/flow/physical_shape_layer.cs


using Unity.UIWidgets.ui;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.flow {
public class PhysicalShapeLayer : ContainerLayer {

}
else {
Rect bounds = this._path.getBounds();
//todo xingwei.zhu: outter set shadow
//bounds.outset(20.0f, 20.0f);
this.paintBounds = bounds;
Rect outset = bounds.outset(20.0f, 20.0f);
this.paintBounds = outset;
this.drawShadow(context.canvas, this._path, this._shadow_color, this._elevation,
drawShadow(context.canvas, this._path, this._shadow_color, this._elevation,
this._color.alpha != 255, this._device_pixel_ratio);
}

}
void drawShadow(Canvas canvas, Path path, Color color, float elevation, bool transparentOccluder, float dpr) {
//todo xingwei.zhu: to be implemented
public static void drawShadow(Canvas canvas, Path path, Color color, float elevation, bool transparentOccluder,
float dpr) {
float kAmbientAlpha = 0.039f;
float kSpotAlpha = 0.25f;
float kLightHeight = 600f;
float kLightRadius = 800f;
Rect bounds = path.getBounds();
float shadow_x = (bounds.left + bounds.right) / 2f;
float shadow_y = bounds.top - 600.0f;
Color inAmbient = color.withAlpha((int) (kAmbientAlpha * color.alpha));
Color inSpot = color.withAlpha((int) (kSpotAlpha * color.alpha));
Color ambientColor = null;
Color spotColor = null;
ShadowUtils.computeTonalColors(inAmbient, inSpot, ref ambientColor, ref spotColor);
ShadowUtils.drawShadow(
canvas,
path,
new Vector3(0, 0, dpr * elevation),
new Vector3(shadow_x, shadow_y, dpr * kLightHeight),
dpr * kLightRadius,
ambientColor,
spotColor,
0
);
}
}
}

5
Runtime/flow/raster_cache.cs


public readonly float devicePixelRatio;
public void draw(Canvas canvas) {
var bounds = canvas.getTotalMatrix().mapRect(this.logicalRect);
var bounds = canvas.getTotalMatrix().mapRect(this.logicalRect).roundOut(this.devicePixelRatio);
D.assert(() => {
var textureWidth = Mathf.CeilToInt(bounds.width * this.devicePixelRatio);

D.assert(this.image.height == textureHeight);
return true;
});
canvas.save();
try {

RasterCacheResult _rasterizePicture(Picture picture, Matrix3 transform, float devicePixelRatio,
MeshPool meshPool) {
var bounds = transform.mapRect(picture.paintBounds);
var bounds = transform.mapRect(picture.paintBounds).roundOut(devicePixelRatio);
var desc = new RenderTextureDescriptor(
Mathf.CeilToInt((bounds.width * devicePixelRatio)),

24
Runtime/gestures/monodrag.cs


});
}
this.invokeCallback<object>("onEnd", () => {
this.onEnd(new DragEndDetails(
velocity: Velocity.zero,
primaryVelocity: 0.0f
));
return null;
}, debugReport: () => { return "Pointer scroll end"; }
);
this._state = _DragState.ready;
this.stopTrackingScrollerPointer(evt.pointer);
return;
}

public override void rejectGesture(int pointer) {
this.stopTrackingPointer(pointer);
}
protected override void didStopTrackingLastScrollerPointer(int pointer) {
this._state = _DragState.ready;
this.invokeCallback<object>("onEnd", () => {
this.onEnd(new DragEndDetails(
velocity: Velocity.zero,
primaryVelocity: 0.0f
));
return null;
}, debugReport: () => { return "Pointer scroll end"; }
);
}
protected override void didStopTrackingLastPointer(int pointer) {

9
Runtime/gestures/recognizer.cs


protected abstract void didStopTrackingLastPointer(int pointer);
protected virtual void didStopTrackingLastScrollerPointer(int pointer) {
}
protected virtual void resolve(GestureDisposition disposition) {
var localEntries = new List<GestureArenaEntry>(this._entries.Values);
this._entries.Clear();

protected void startTrackingScrollerPointer(int pointer) {
GestureBinding.instance.pointerRouter.addRoute(pointer, this.handleEvent);
}
protected void stopTrackingScrollerPointer(int pointer) {
if (this._trackedPointers.isEmpty()) {
this.didStopTrackingLastScrollerPointer(pointer);
}
}
protected void startTrackingPointer(int pointer) {

7
Runtime/material/app_bar.cs


bool pinned = false,
bool snap = false
) : base(key: key) {
D.assert(automaticallyImplyLeading != null);
D.assert(forceElevated != null);
D.assert(primary != null);
D.assert(titleSpacing != null);
D.assert(floating != null);
D.assert(pinned != null);
D.assert(snap != null);
D.assert(floating || !snap, "The 'snap' argument only makes sense for floating app bars.");
this.leading = leading;
this.automaticallyImplyLeading = true;

145
Runtime/material/bottom_sheet.cs


using System;
using RSG;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;

using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
static class BottomSheetUtils {
public static class BottomSheetUtils {
public static IPromise<object> showModalBottomSheet<T>(
BuildContext context,
WidgetBuilder builder
) {
D.assert(context != null);
D.assert(builder != null);
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
return Navigator.push(context, new _ModalBottomSheetRoute<T>(
builder: builder,
theme: Theme.of(context, shadowThemeOnly: true),
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel
));
}
public static PersistentBottomSheetController<object> showBottomSheet(
BuildContext context,
WidgetBuilder builder
) {
D.assert(context != null);
D.assert(builder != null);
return Scaffold.of(context).showBottomSheet(builder);
}
}

onVerticalDragEnd: this._handleDragEnd,
child: bottomSheet
);
}
}
class _ModalBottomSheetLayout : SingleChildLayoutDelegate {
public _ModalBottomSheetLayout(float progress) {
this.progress = progress;
}
public readonly float progress;
public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return new BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: 0.0f,
maxHeight: constraints.maxHeight * 9.0f / 16.0f
);
}
public override Offset getPositionForChild(Size size, Size childSize) {
return new Offset(0.0f, size.height - childSize.height * this.progress);
}
public override bool shouldRelayout(SingleChildLayoutDelegate _oldDelegate) {
_ModalBottomSheetLayout oldDelegate = _oldDelegate as _ModalBottomSheetLayout;
return this.progress != oldDelegate.progress;
}
}
class _ModalBottomSheet<T> : StatefulWidget {
public _ModalBottomSheet(Key key = null, _ModalBottomSheetRoute<T> route = null) : base(key: key) {
this.route = route;
}
public readonly _ModalBottomSheetRoute<T> route;
public override State createState() {
return new _ModalBottomSheetState<T>();
}
}
class _ModalBottomSheetState<T> : State<_ModalBottomSheet<T>> {
public override Widget build(BuildContext context) {
MediaQueryData mediaQuery = MediaQuery.of(context);
MaterialLocalizations localizations = MaterialLocalizations.of(context);
return new GestureDetector(
onTap: () => Navigator.pop(context),
child: new AnimatedBuilder(
animation: this.widget.route.animation,
builder: (BuildContext _context, Widget child) => {
float animationValue =
mediaQuery.accessibleNavigation ? 1.0f : this.widget.route.animation.value;
return new ClipRect(
child: new CustomSingleChildLayout(
layoutDelegate: new _ModalBottomSheetLayout(animationValue),
child: new BottomSheet(
animationController: this.widget.route._animationController,
onClosing: () => Navigator.pop(_context),
builder: this.widget.route.builder
)
)
);
}
)
);
}
}
class _ModalBottomSheetRoute<T> : PopupRoute {
public _ModalBottomSheetRoute(
WidgetBuilder builder = null,
ThemeData theme = null,
string barrierLabel = null,
RouteSettings settings = null
) : base(settings: settings) {
this.builder = builder;
this.theme = theme;
this.barrierLabel = barrierLabel;
}
public readonly WidgetBuilder builder;
public readonly ThemeData theme;
public override TimeSpan transitionDuration {
get { return BottomSheetUtils._kBottomSheetDuration; }
}
public override bool barrierDismissible {
get { return true; }
}
public readonly string barrierLabel;
public override Color barrierColor {
get { return Colors.black54; }
}
public AnimationController _animationController;
public override AnimationController createAnimationController() {
D.assert(this._animationController == null);
this._animationController = BottomSheet.createAnimationController(this.navigator.overlay);
return this._animationController;
}
public override Widget buildPage(BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation) {
Widget bottomSheet = MediaQuery.removePadding(
context: context,
removeTop: true,
child: new _ModalBottomSheet<T>(route: this)
);
if (this.theme != null) {
bottomSheet = new Theme(data: this.theme, child: bottomSheet);
}
return bottomSheet;
}
}
}

23
Runtime/material/dropdown.cs


public readonly T result;
public static bool operator ==(_DropdownRouteResult<T> left, _DropdownRouteResult<T> right) {
return left.result == right.result;
return left.Equals(right);
return left.result != right.result;
return !left.Equals(right);
}
public bool Equals(_DropdownRouteResult<T> other) {
return this.result == other.result;
}
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((_DropdownRouteResult<T>) obj);
}
public override int GetHashCode() {

}
class _DropdownButtonFormFieldState<T> : FormFieldState<T> where T : class {
public DropdownButtonFormField<T> widget {
public new DropdownButtonFormField<T> widget {
get { return base.widget as DropdownButtonFormField<T>; }
}

55
Runtime/material/input_border.cs


using System.Runtime.CompilerServices;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;

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 right) {
return left.Equals(right);
}
public static bool operator !=(UnderlineInputBorder left, UnderlineInputBorder right) {
return !left.Equals(right);
public static bool operator !=(UnderlineInputBorder left, UnderlineInputBorder other) {
return left.borderSide != other.borderSide;
public bool Equals(UnderlineInputBorder other) {
return this.borderSide == other.borderSide;
}
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((UnderlineInputBorder) obj);
}
public override int GetHashCode() {

}
}
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 right) {
return left.Equals(right);
}
public static bool operator !=(OutlineInputBorder left, OutlineInputBorder right) {
return !left.Equals(right);
}
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((OutlineInputBorder) obj);
public static bool operator !=(OutlineInputBorder left, OutlineInputBorder other) {
return !(left == other);
public bool Equals(OutlineInputBorder other) {
return other.borderSide == this.borderSide
&& other.borderRadius == this.borderRadius
&& other.gapPadding == this.gapPadding;
}
public override int GetHashCode() {

170
Runtime/material/input_decorator.cs


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

}
}
public static bool operator ==(_InputBorderGap left, _InputBorderGap other) {
return left.start == other.start && left.extent == other.extent;
public static bool operator ==(_InputBorderGap left, _InputBorderGap right) {
return left.Equals(right);
}
public bool Equals(_InputBorderGap other) {
return this.start == other.start && this.extent == other.extent;
}
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((_InputBorderGap) obj);
}
public override int GetHashCode() {

public readonly Widget counter;
public readonly Widget container;
public static bool operator ==(_Decoration left, _Decoration other) {
return left.contentPadding == other.contentPadding
&& left.floatingLabelHeight == other.floatingLabelHeight
&& left.floatingLabelProgress == other.floatingLabelProgress
&& left.border == other.border
&& left.borderGap == other.borderGap
&& left.icon == other.icon
&& left.input == other.input
&& left.label == other.label
&& left.hint == other.hint
&& left.prefix == other.prefix
&& left.suffix == other.suffix
&& left.prefixIcon == other.prefixIcon
&& left.suffixIcon == other.suffixIcon
&& left.helperError == other.helperError
&& left.counter == other.counter
&& left.container == other.container;
public static bool operator ==(_Decoration left, _Decoration right) {
return left.Equals(right);
}
public static bool operator !=(_Decoration left, _Decoration right) {
return !left.Equals(right);
public static bool operator !=(_Decoration left, _Decoration other) {
return !(left == other);
public bool Equals(_Decoration other) {
return this.contentPadding == other.contentPadding
&& this.floatingLabelHeight == other.floatingLabelHeight
&& this.floatingLabelProgress == other.floatingLabelProgress
&& this.border == other.border
&& this.borderGap == other.borderGap
&& this.icon == other.icon
&& this.input == other.input
&& this.label == other.label
&& this.hint == other.hint
&& this.prefix == other.prefix
&& this.suffix == other.suffix
&& this.prefixIcon == other.prefixIcon
&& this.suffixIcon == other.suffixIcon
&& this.helperError == other.helperError
&& this.counter == other.counter
&& this.container == other.container;
}
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((_Decoration) obj);
}
public override int GetHashCode() {

Dictionary<_DecorationSlot, Element> slotToChild = new Dictionary<_DecorationSlot, Element>();
Dictionary<Element, _DecorationSlot> childToSlot = new Dictionary<Element, _DecorationSlot>();
public _Decorator widget {
public new _Decorator widget {
public _RenderDecoration renderObject {
public new _RenderDecoration renderObject {
get { return (_RenderDecoration) base.renderObject; }
}

);
}
public static bool operator ==(InputDecoration left, InputDecoration other) {
return other.icon == left.icon
&& other.labelText == left.labelText
&& other.labelStyle == left.labelStyle
&& other.helperText == left.helperText
&& other.helperStyle == left.helperStyle
&& other.hintText == left.hintText
&& other.hintStyle == left.hintStyle
&& other.errorText == left.errorText
&& other.errorStyle == left.errorStyle
&& other.errorMaxLines == left.errorMaxLines
&& other.hasFloatingPlaceholder == left.hasFloatingPlaceholder
&& other.isDense == left.isDense
&& other.contentPadding == left.contentPadding
&& other.isCollapsed == left.isCollapsed
&& other.prefixIcon == left.prefixIcon
&& other.prefix == left.prefix
&& other.prefixText == left.prefixText
&& other.prefixStyle == left.prefixStyle
&& other.suffixIcon == left.suffixIcon
&& other.suffix == left.suffix
&& other.suffixText == left.suffixText
&& other.suffixStyle == left.suffixStyle
&& other.counterText == left.counterText
&& other.counterStyle == left.counterStyle
&& other.filled == left.filled
&& other.fillColor == left.fillColor
&& other.errorBorder == left.errorBorder
&& other.focusedBorder == left.focusedBorder
&& other.focusedErrorBorder == left.focusedErrorBorder
&& other.disabledBorder == left.disabledBorder
&& other.enabledBorder == left.enabledBorder
&& other.border == left.border
&& other.enabled == left.enabled;
public static bool operator ==(InputDecoration left, InputDecoration right) {
return left.Equals(right);
}
public static bool operator !=(InputDecoration left, InputDecoration right) {
return !left.Equals(right);
public static bool operator !=(InputDecoration left, InputDecoration other) {
return !(left == other);
public bool Equals(InputDecoration other) {
return other.icon == this.icon
&& other.labelText == this.labelText
&& other.labelStyle == this.labelStyle
&& other.helperText == this.helperText
&& other.helperStyle == this.helperStyle
&& other.hintText == this.hintText
&& other.hintStyle == this.hintStyle
&& other.errorText == this.errorText
&& other.errorStyle == this.errorStyle
&& other.errorMaxLines == this.errorMaxLines
&& other.hasFloatingPlaceholder == this.hasFloatingPlaceholder
&& other.isDense == this.isDense
&& other.contentPadding == this.contentPadding
&& other.isCollapsed == this.isCollapsed
&& other.prefixIcon == this.prefixIcon
&& other.prefix == this.prefix
&& other.prefixText == this.prefixText
&& other.prefixStyle == this.prefixStyle
&& other.suffixIcon == this.suffixIcon
&& other.suffix == this.suffix
&& other.suffixText == this.suffixText
&& other.suffixStyle == this.suffixStyle
&& other.counterText == this.counterText
&& other.counterStyle == this.counterStyle
&& other.filled == this.filled
&& other.fillColor == this.fillColor
&& other.errorBorder == this.errorBorder
&& other.focusedBorder == this.focusedBorder
&& other.focusedErrorBorder == this.focusedErrorBorder
&& other.disabledBorder == this.disabledBorder
&& other.enabledBorder == this.enabledBorder
&& other.border == this.border
&& other.enabled == this.enabled;
}
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((InputDecoration) obj);
}
public override int GetHashCode() {

25
Runtime/material/outline_button.cs


}
}
public static bool operator ==(_OutlineBorder left, _OutlineBorder other) {
return left.side == other.side && left.shape == other.shape;
public static bool operator ==(_OutlineBorder left, _OutlineBorder right) {
return left.Equals(right);
}
public static bool operator !=(_OutlineBorder left, _OutlineBorder right) {
return !left.Equals(right);
public static bool operator !=(_OutlineBorder left, _OutlineBorder other) {
return left.side != other.side || left.shape != other.shape;
public bool Equals(_OutlineBorder other) {
return this.side == other.side && this.shape == other.shape;
}
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((_OutlineBorder) obj);
}
public override int GetHashCode() {

2
Runtime/material/scaffold.cs


"The context used was:\n" + context);
}
static ValueListenable<ScaffoldGeometry> geometryOf(BuildContext context) {
public static ValueListenable<ScaffoldGeometry> geometryOf(BuildContext context) {
_ScaffoldScope scaffoldScope =
(_ScaffoldScope) context.inheritFromWidgetOfExactType(typeof(_ScaffoldScope));
if (scaffoldScope == null) {

2
Runtime/material/theme.cs


using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
static class ThemeUtils {
public static class ThemeUtils {
public static readonly TimeSpan kThemeAnimationDuration = new TimeSpan(0, 0, 0, 0, 200);
}

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


get { return this._childCount; }
}
public bool debugValidateChild(RenderObject child) {
public new bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(

6
Runtime/rendering/paragraph.cs


using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using UnityEngine;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.rendering {
public enum TextOverflow {

this._textPainter.textDirection = this.textDirection;
this.markNeedsLayout();
}
}
protected Offset getOffsetForCaret(TextPosition position, Rect caretPrototype) {
D.assert(this._textPainter != null);
return this._textPainter.getOffsetForCaret(position, caretPrototype);
}
public bool softWrap {

202
Runtime/rendering/proxy_box.cs


this._debugPaint.strokeWidth = 2.0f;
this._debugPaint.style = PaintingStyle.stroke;
}
if (this._debugText == null) {
this._debugText = new TextPainter(
text: new TextSpan(

));
this._debugText.layout();
}
return true;
});
}

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

Color _color;
static Paint _transparentPaint {
protected static Paint _transparentPaint {
get { return new Paint {color = new Color(0x00000000)}; }
}

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

else {
Canvas canvas = context.canvas;
if (this.elevation != 0.0) {
//draw Shadow
/*canvas.drawRect(
offsetBounds.inflate(20.0),
_RenderPhysicalModelBase<RRect>._transparentPaint
canvas.drawRect(
offsetBounds.inflate(20.0f),
_transparentPaint
);
canvas.drawShadow(
offsetRRectAsPath,

);*/
);
}
Paint paint = new Paint {color = this.color};

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

}
else {
Canvas canvas = context.canvas;
// if (this.elevation != 0.0 && paintShadows) {
// canvas.drawRect(
// offsetBounds.inflate(20.0),
// _RenderPhysicalModelBase<Path>._transparentPaint
// );
// canvas.drawShadow(
// offsetPath,
// this.shadowColor,
// this.elevation,
// this.color.alpha != 0xFF,
// );
// }
if (this.elevation != 0.0) {
canvas.drawRect(
offsetBounds.inflate(20.0f),
_transparentPaint
);
canvas.drawShadow(
offsetPath,
this.shadowColor,
this.elevation,
this.color.alpha != 0xFF
);
}
Paint paint = new Paint {color = this.color, style = PaintingStyle.fill};
canvas.drawPath(offsetPath, paint);
context.clipPathAndPaint(offsetPath, this.clipBehavior,

properties.add(new DiagnosticsProperty<Offset>("origin", this.origin));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
properties.add(new DiagnosticsProperty<bool>("transformHitTests", this.transformHitTests));
}
}
public class RenderFittedBox : RenderProxyBox {
public RenderFittedBox(
BoxFit fit = BoxFit.contain,
Alignment alignment = null,
RenderBox child = null
) : base(child) {
this._fit = fit;
this._alignment = alignment ?? Alignment.center;
}
Alignment _resolvedAlignment;
void _resolve() {
if (this._resolvedAlignment != null) {
return;
}
this._resolvedAlignment = this.alignment;
}
void _markNeedResolution() {
this._resolvedAlignment = null;
this.markNeedsPaint();
}
public BoxFit fit {
get { return this._fit; }
set {
if (this._fit == value) {
return;
}
this._fit = value;
this._clearPaintData();
this.markNeedsPaint();
}
}
BoxFit _fit;
public Alignment alignment {
get { return this._alignment; }
set {
D.assert(value != null);
if (this._alignment == value) {
return;
}
this._alignment = value;
this._clearPaintData();
this._markNeedResolution();
}
}
Alignment _alignment;
protected override void performLayout() {
if (this.child != null) {
this.child.layout(new BoxConstraints(), parentUsesSize: true);
this.size = this.constraints.constrainSizeAndAttemptToPreserveAspectRatio(this.child.size);
this._clearPaintData();
}
else {
this.size = this.constraints.smallest;
}
}
bool? _hasVisualOverflow;
Matrix3 _transform;
void _clearPaintData() {
this._hasVisualOverflow = null;
this._transform = null;
}
void _updatePaintData() {
if (this._transform != null) {
return;
}
if (this.child == null) {
this._hasVisualOverflow = false;
this._transform = Matrix3.I();
}
else {
this._resolve();
Size childSize = this.child.size;
FittedSizes sizes = FittedSizes.applyBoxFit(this._fit, childSize, this.size);
float scaleX = sizes.destination.width / sizes.source.width;
float scaleY = sizes.destination.height / sizes.source.height;
Rect sourceRect = this._resolvedAlignment.inscribe(sizes.source, Offset.zero & childSize);
Rect destinationRect = this._resolvedAlignment.inscribe(sizes.destination, Offset.zero & this.size);
this._hasVisualOverflow = sourceRect.width < childSize.width || sourceRect.height < childSize.height;
this._transform = Matrix3.makeTrans(destinationRect.left, destinationRect.top);
this._transform.postScale(scaleX, scaleY);
this._transform.postTranslate(-sourceRect.left, -sourceRect.top);
}
}
void _paintChildWithTransform(PaintingContext context, Offset offset) {
Offset childOffset = this._transform.getAsTranslation();
if (childOffset == null) {
context.pushTransform(this.needsCompositing, offset, this._transform, base.paint);
}
else {
base.paint(context, offset + childOffset);
}
}
public override void paint(PaintingContext context, Offset offset) {
if (this.size.isEmpty) {
return;
}
this._updatePaintData();
if (this.child != null) {
if (this._hasVisualOverflow == true) {
context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size,
this._paintChildWithTransform);
}
else {
this._paintChildWithTransform(context, offset);
}
}
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.size.isEmpty) {
return false;
}
this._updatePaintData();
Matrix3 inverse = Matrix3.I();
if (!this._transform.invert(inverse)) {
return false;
}
position = inverse.mapPoint(position);
return base.hitTestChildren(result, position: position);
}
public override void applyPaintTransform(RenderObject child, Matrix3 transform) {
if (this.size.isEmpty) {
transform.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
}
else {
this._updatePaintData();
transform.postConcat(this._transform);
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<BoxFit>("fit", this.fit));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
}
}

8
Runtime/rendering/sliver_persistent_header.cs


}
D.assert(this.child.hasSize);
D.assert(this.constraints.axis != null);
switch (this.constraints.axis) {
case Axis.vertical:
return this.child.size.height;

}
protected void layoutChild(float scrollOffset, float maxExtent, bool overlapsContent = false) {
D.assert(maxExtent != null);
D.assert(this.constraints == this.constraints);
D.assert(constraints == this.constraints);
this.updateChild(shrinkOffset, overlapsContent);
});
this._lastShrinkOffset = shrinkOffset;

public override void paint(PaintingContext context, Offset offset) {
if (this.child != null && this.geometry.visible) {
D.assert(this.constraints.axisDirection != null);
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(this.constraints.axisDirection,
this.constraints.growthDirection)) {
case AxisDirection.up:

protected override void performLayout() {
float? maxExtent = this.maxExtent;
if (this._lastActualScrollOffset != null &&
((this.constraints.scrollOffset < this._lastActualScrollOffset) ||
if (((this.constraints.scrollOffset < this._lastActualScrollOffset) ||
(this._effectiveScrollOffset < maxExtent))) {
float delta = this._lastActualScrollOffset - this.constraints.scrollOffset;
bool allowFloatingExpansion = this.constraints.userScrollDirection == ScrollDirection.forward;

1
Runtime/rendering/stack.cs


}
public static RelativeRect lerp(RelativeRect a, RelativeRect b, float t) {
D.assert(t != null);
if (a == null && b == null) {
return null;
}

86
Runtime/ui/geometry.cs


namespace Unity.UIWidgets.ui {
public static class MathUtils {
const float _valueNearlyZero = 1f / (1 << 12);
public static bool isConvexPolygon(Offset[] polygonVerts, int polygonSize) {
if (polygonSize < 3) {
return false;
}
float lastArea = 0;
float lastPerpDot = 0;
int prevIndex = polygonSize - 1;
int currIndex = 0;
int nextIndex = 1;
Offset origin = polygonVerts[0];
Vector2 v0 = (polygonVerts[currIndex] - polygonVerts[prevIndex]).toVector();
Vector2 v1 = (polygonVerts[nextIndex] - polygonVerts[currIndex]).toVector();
Vector2 w0 = (polygonVerts[currIndex] - origin).toVector();
Vector2 w1 = (polygonVerts[nextIndex] - origin).toVector();
for (int i = 0; i < polygonSize; i++) {
if (!polygonVerts[i].isFinite) {
return false;
}
float perpDot = v0.cross(v1);
if (lastPerpDot * perpDot < 0) {
return false;
}
if (0 != perpDot) {
lastPerpDot = perpDot;
}
float quadArea = w0.cross(w1);
if (quadArea * lastArea < 0) {
return false;
}
if (0 != quadArea) {
lastArea = quadArea;
}
prevIndex = currIndex;
currIndex = nextIndex;
nextIndex = (currIndex + 1) % polygonSize;
v0 = v1;
v1 = (polygonVerts[nextIndex] - polygonVerts[currIndex]).toVector();
w0 = w1;
w1 = (polygonVerts[nextIndex] - origin).toVector();
}
return true;
}
public static float cross(this Vector2 vector1, Vector2 vector2) {
return Vector3.Cross(new Vector3(vector1.x, vector1.y, 0f), new Vector3(vector2.x, vector2.y, 0f)).z;
}
public static bool valueNearlyZero(this float x, float? tolerance = null) {
tolerance = tolerance ?? _valueNearlyZero;
return Mathf.Abs(x) <= tolerance;
}
public static float clamp(this float value, float min, float max) {
if (value < min) {
value = min;

this.left * scaleX, this.top * scaleY.Value,
this.right * scaleX, this.bottom * scaleY.Value);
}
public Rect outset(float dx, float dy) {
return new Rect(this.left - dx, this.top - dy, this.right + dx, this.bottom + dy);
}
public Offset[] toQuad() {
Offset[] dst = new Offset[4];
dst[0] = new Offset(this.left, this.top);
dst[1] = new Offset(this.right, this.top);
dst[2] = new Offset(this.right, this.bottom);
dst[3] = new Offset(this.left, this.bottom);
return dst;
}
public Rect inflate(float delta) {
return fromLTRB(this.left - delta, this.top - delta, this.right + delta, this.bottom + delta);

return fromLTRB(
Mathf.Floor(this.left), Mathf.Floor(this.top),
Mathf.Ceil(this.right), Mathf.Ceil(this.bottom));
}
public Rect roundOut(float devicePixelRatio) {
return fromLTRB(
Mathf.Floor(this.left * devicePixelRatio) / devicePixelRatio,
Mathf.Floor(this.top * devicePixelRatio) / devicePixelRatio,
Mathf.Ceil(this.right * devicePixelRatio) / devicePixelRatio,
Mathf.Ceil(this.bottom * devicePixelRatio) / devicePixelRatio);
}
public Rect roundIn() {

6
Runtime/ui/matrix.cs


).normalize();
}
public Offset[] mapRectToQuad(Rect rect) {
Offset[] dst = rect.toQuad();
this.mapPoints(dst, dst);
return dst;
}
public static bool operator ==(Matrix3 a, Matrix3 b) {
if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) {
return true;

8
Runtime/ui/painting/canvas.cs


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

void drawLine(Offset from, Offset to, Paint paint);
void drawRect(Rect rect, Paint paint);
void drawShadow(Path path, Color color, float elevation, bool transparentOccluder);
void drawRRect(RRect rect, Paint paint);

path = path,
paint = new Paint(paint),
});
}
public void drawShadow(Path path, Color color, float elevation, bool transparentOccluder) {
float dpr = Window.instance.devicePixelRatio;
PhysicalShapeLayer.drawShadow(this, path, color, elevation, transparentOccluder, dpr);
}
public void drawRect(Rect rect, Paint paint) {

6
Runtime/ui/painting/canvas_impl.cs


readonly List<RenderLayer> _layers = new List<RenderLayer>();
RenderLayer _currentLayer;
Rect _lastScissor;
public PictureFlusher(RenderTexture renderTexture, float devicePixelRatio, MeshPool meshPool) {
D.assert(renderTexture);

}
void _tryAddScissor(RenderLayer layer, Rect scissor) {
if (scissor == layer.lastScissor) {
if (scissor == this._lastScissor) {
return;
}

layer.lastScissor = scissor;
this._lastScissor = scissor;
}
bool _applyClip(Rect queryBounds) {

public readonly ClipStack clipStack = new ClipStack();
public uint lastClipGenId;
public Rect lastClipBounds;
public Rect lastScissor;
public bool ignoreClip = true;
Vector4? _viewport;

39
Runtime/ui/painting/path.cs


this._appendCommands(vals.ToArray());
}
public Path transform(Matrix3 mat) {
Path ret = new Path();
var i = 0;
while (i < this._commands.Count) {
var cmd = (PathCommand) this._commands[i];
switch (cmd) {
case PathCommand.moveTo:
var res_move = mat.mapXY(this._commands[i + 1], this._commands[i + 2]);
ret.moveTo(res_move.dx, res_move.dy);
i += 3;
break;
case PathCommand.lineTo:
var res_lineto = mat.mapXY(this._commands[i + 1], this._commands[i + 2]);
ret.lineTo(res_lineto.dx, res_lineto.dy);
i += 3;
break;
case PathCommand.bezierTo:
var res1 = mat.mapXY(this._commands[i + 1], this._commands[i + 2]);
var res2 = mat.mapXY(this._commands[i + 3], this._commands[i + 4]);
var res3 = mat.mapXY(this._commands[i + 5], this._commands[i + 6]);
ret.bezierTo(res1.dx, res1.dy, res2.dx, res2.dy, res3.dx, res3.dy);
i += 7;
break;
case PathCommand.close:
i++;
break;
case PathCommand.winding:
i += 2;
break;
default:
D.assert(false, "unknown cmd: " + cmd);
break;
}
}
return ret;
}
void _transformCommands(List<float> commands, Matrix3 mat) {
if (mat == null) {
return;

35
Runtime/widgets/basic.cs


}
}
public class FittedBox : SingleChildRenderObjectWidget {
public FittedBox(
Key key = null,
BoxFit fit = BoxFit.contain,
Alignment alignment = null,
Widget child = null
) : base(key: key, child: child) {
this.fit = fit;
this.alignment = alignment ?? Alignment.center;
}
public readonly BoxFit fit;
public readonly Alignment alignment;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderFittedBox(
fit: this.fit,
alignment: this.alignment
);
}
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
RenderFittedBox renderObject = _renderObject as RenderFittedBox;
renderObject.fit = this.fit;
renderObject.alignment = this.alignment;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<BoxFit>("fit", this.fit));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
}
}
public class FractionalTranslation : SingleChildRenderObjectWidget {
public FractionalTranslation(Key key = null, Offset translation = null,
bool transformHitTests = true, Widget child = null) : base(key: key, child: child) {

24
Runtime/widgets/binding.cs


RenderObjectToWidgetElement<RenderBox> _renderViewElement;
public void detachRootWidget() {
this.pipelineOwner.rootNode = null;
void unMountAll(Element element) {
element.visitChildren(unMountAll);
element.deactivate();
element.unmount();
}
if (this._renderViewElement != null) {
this._renderViewElement.visitChildren(unMountAll);
this._renderViewElement.deactivate();
this._renderViewElement.unmount();
this._renderViewElement = null;
if (this._renderViewElement == null) {
return;
this.attachRootWidget(null);
this.buildOwner.buildScope(this._renderViewElement);
this.buildOwner.finalizeTree();
this.pipelineOwner.rootNode = null;
this._renderViewElement.deactivate();
this._renderViewElement.unmount();
this._renderViewElement = null;
}
public void attachRootWidget(Widget rootWidget) {

6
Runtime/widgets/framework.cs


return true;
}
return ReferenceEquals(this.componentKey1, other.componentKey1) &&
ReferenceEquals(this.componentKey2, other.componentKey2);
return Equals(this.componentKey1, other.componentKey1) &&
Equals(this.componentKey2, other.componentKey2);
}
public override bool Equals(object obj) {

return true;
});
if (_registry.getOrDefault(compKey) == element) {
if (_registry[compKey] == element) {
_registry.Remove(compKey);
_removedKeys.Add(compKey);
}

2
Runtime/widgets/media_query.cs


return of(context, nullOk: true)?.textScaleFactor ?? 1.0f;
}
static bool boldTextOverride(BuildContext context) {
public static bool boldTextOverride(BuildContext context) {
return of(context, nullOk: true)?.boldText ?? false;
}

10
Runtime/widgets/scroll_physics.cs


}
}
public virtual float dragStartDistanceMotionThreshold {
public virtual float? dragStartDistanceMotionThreshold {
if (this.parent == null) {
return 0.0f;
}
return this.parent.dragStartDistanceMotionThreshold;
return this.parent?.dragStartDistanceMotionThreshold;
}
}

Mathf.Min(0.000816f * Mathf.Pow(existingVelocity.abs(), 1.967f), 40000.0f);
}
public override float dragStartDistanceMotionThreshold {
public override float? dragStartDistanceMotionThreshold {
get { return 3.5f; }
}
}

4
Runtime/widgets/sliver_persistent_header.cs


bool floating = false
) : base(key: key) {
D.assert(del != null);
D.assert(pinned != null);
D.assert(floating != null);
this.del = del;
this.pinned = pinned;
this.floating = floating;

public _SliverPersistentHeaderElement(_SliverPersistentHeaderRenderObjectWidget widget) : base(widget) {
}
public _SliverPersistentHeaderRenderObjectWidget widget {
public new _SliverPersistentHeaderRenderObjectWidget widget {
get { return (_SliverPersistentHeaderRenderObjectWidget) base.widget; }
}

24
Samples/UIWidgetSample/MaterialSample.cs


namespace UIWidgetsSample {
public class MaterialSample : UIWidgetsSamplePanel {
int testCaseId = 4;
int testCaseId = 2;
List<Widget> testCases = new List<Widget> {
new MaterialButtonWidget(),

new TableWidget()
new TableWidget(),
new BottomAppBarWidget()
};
protected override Widget createWidget() {

protected override void OnEnable() {
base.OnEnable();
FontManager.instance.addFont(Resources.Load<Font>(path: "MaterialIcons-Regular"));
}
}
class BottomAppBarWidget : StatelessWidget {
public BottomAppBarWidget(Key key = null) : base(key) {
}
public override Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Color.clear,
bottomNavigationBar: new BottomAppBar(
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: new List<Widget> {
new IconButton(icon: new Icon(Unity.UIWidgets.material.Icons.menu), onPressed: () => { }),
new IconButton(icon: new Icon(Unity.UIWidgets.material.Icons.account_balance), onPressed: () => { })
})));
}
}

2
Samples/UIWidgetsGallery/demo/colors_demo.cs


public readonly int threshold;
public bool isValid {
get { return this.name != null && this.primary != null && this.threshold != null; }
get { return this.name != null && this.primary != null; }
}
}

62
Samples/UIWidgetsGallery/gallery/demo.cs


using Unity.UIWidgets.painting;
using Unity.UIWidgets.service;
using Unity.UIWidgets.widgets;
using UnityEngine;
class ComponentDemoTabData {
public class ComponentDemoTabData {
public ComponentDemoTabData(
Widget demoWidget = null,
string exampleCodeTag = null,

public readonly string documentationUrl;
public static bool operator ==(ComponentDemoTabData left, ComponentDemoTabData right) {
return right.tabName == left.tabName
&& right.description == left.description
&& right.documentationUrl == left.documentationUrl;
return left.Equals(right);
return right.tabName != left.tabName
|| right.description != left.description
|| right.documentationUrl != left.documentationUrl;
return !left.Equals(right);
}
public bool Equals(ComponentDemoTabData other) {
return other.tabName == this.tabName
&& other.description == this.description
&& other.documentationUrl == this.documentationUrl;
}
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((ComponentDemoTabData) obj);
}
public override int GetHashCode() {

}
class TabbedComponentDemoScaffold : StatelessWidget {
public class TabbedComponentDemoScaffold : StatelessWidget {
public TabbedComponentDemoScaffold(
string title = null,
List<ComponentDemoTabData> demos = null,

}
class FullScreenCodeDialog : StatefulWidget {
public class FullScreenCodeDialog : StatefulWidget {
public FullScreenCodeDialog(Key key = null, string exampleCodeTag = null) : base(key: key) {
this.exampleCodeTag = exampleCodeTag;
}

}
}
class FullScreenCodeDialogState : State<FullScreenCodeDialog> {
public class FullScreenCodeDialogState : State<FullScreenCodeDialog> {
public FullScreenCodeDialogState() {
}

base.didChangeDependencies();
string code = new ExampleCodeParser().getExampleCode(this.widget.exampleCodeTag, DefaultAssetBundle.of(this.context));
string code =
new ExampleCodeParser().getExampleCode(this.widget.exampleCodeTag, DefaultAssetBundle.of(this.context));
if (this.mounted) {
this.setState(() => { this._exampleCode = code; });
}

title: new Text("Example code")
),
body: body
);
}
}
class MaterialDemoDocumentationButton : StatelessWidget {
public MaterialDemoDocumentationButton(string routeName, Key key = null) : base(key: key) {
this.documentationUrl = DemoUtils.kDemoDocumentationUrl[routeName];
D.assert(DemoUtils.kDemoDocumentationUrl[routeName] != null,
"A documentation URL was not specified for demo route $routeName in kAllGalleryDemos"
);
}
public readonly string documentationUrl;
public override Widget build(BuildContext context) {
return new IconButton(
icon: new Icon(Icons.library_books),
tooltip: "API documentation",
onPressed: () => Application.OpenURL(this.documentationUrl)
);
}
}

74
Samples/UIWidgetsGallery/gallery/demos.cs


routeName: TypographyDemo.routeName,
buildRoute: (BuildContext context) => new TypographyDemo()
),
//
// // Material Components
// new GalleryDemo(
// title: "Backdrop",
// subtitle: "Select a front layer from back layer",
// icon: GalleryIcons.backdrop,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: BackdropDemo.routeName,
// buildRoute: (BuildContext context) => BackdropDemo()
// ),
// new GalleryDemo(
// title: "Bottom app bar",
// subtitle: "Optional floating action button notch",
// icon: GalleryIcons.bottom_app_bar,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: BottomAppBarDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/BottomAppBar-class.html",
// buildRoute: (BuildContext context) => BottomAppBarDemo()
// ),
// new GalleryDemo(
// title: "Bottom navigation",
// subtitle: "Bottom navigation with cross-fading views",
// icon: GalleryIcons.bottom_navigation,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: BottomNavigationDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/BottomNavigationBar-class.html",
// buildRoute: (BuildContext context) => BottomNavigationDemo()
// ),
// Material Components
new GalleryDemo(
title: "Backdrop",
subtitle: "Select a front layer from back layer",
icon: GalleryIcons.backdrop,
category: DemoUtils._kMaterialComponents,
routeName: BackdropDemo.routeName,
buildRoute: (BuildContext context) => new BackdropDemo()
),
new GalleryDemo(
title: "Bottom app bar",
subtitle: "Optional floating action button notch",
icon: GalleryIcons.bottom_app_bar,
category: DemoUtils._kMaterialComponents,
routeName: BottomAppBarDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/BottomAppBar-class.html",
buildRoute: (BuildContext context) => new BottomAppBarDemo()
),
new GalleryDemo(
title: "Bottom navigation",
subtitle: "Bottom navigation with cross-fading views",
icon: GalleryIcons.bottom_navigation,
category: DemoUtils._kMaterialComponents,
routeName: BottomNavigationDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/BottomNavigationBar-class.html",
buildRoute: (BuildContext context) => new BottomNavigationDemo()
),
// new GalleryDemo(
// title: "Bottom sheet: Modal",
// subtitle: "A dismissable bottom sheet",

// documentationUrl: "https://docs.flutter.io/flutter/material/FloatingActionButton-class.html",
// buildRoute: (BuildContext context) => TabsFabDemo()
// ),
// new GalleryDemo(
// title: "Cards",
// subtitle: "Baseline cards with rounded corners",
// icon: GalleryIcons.cards,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: CardsDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/Card-class.html",
// buildRoute: (BuildContext context) => CardsDemo()
// ),
new GalleryDemo(
title: "Cards",
subtitle: "Baseline cards with rounded corners",
icon: GalleryIcons.cards,
category: DemoUtils._kMaterialComponents,
routeName: CardsDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/Card-class.html",
buildRoute: (BuildContext context) => new CardsDemo()
),
// new GalleryDemo(
// title: "Chips",
// subtitle: "Labeled with delete buttons and avatars",

110
Runtime/material/bottom_app_bar.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
public class BottomAppBar : StatefulWidget {
public BottomAppBar(
Key key = null,
Color color = null,
float elevation = 8.0f,
NotchedShape shape = null,
Clip clipBehavior = Clip.none,
float notchMargin = 4.0f,
Widget child = null
) : base(key: key) {
D.assert(elevation >= 0.0f);
this.child = child;
this.color = color;
this.elevation = elevation;
this.shape = shape;
this.clipBehavior = clipBehavior;
this.notchMargin = notchMargin;
}
public readonly Widget child;
public readonly Color color;
public readonly float elevation;
public readonly NotchedShape shape;
public readonly Clip clipBehavior;
public readonly float notchMargin;
public override State createState() {
return new _BottomAppBarState();
}
}
class _BottomAppBarState : State<BottomAppBar> {
ValueListenable<ScaffoldGeometry> geometryListenable;
public override void didChangeDependencies() {
base.didChangeDependencies();
this.geometryListenable = Scaffold.geometryOf(this.context);
}
public override Widget build(BuildContext context) {
CustomClipper<Path> clipper = this.widget.shape != null
? (CustomClipper<Path>) new _BottomAppBarClipper(
geometry: this.geometryListenable,
shape: this.widget.shape,
notchMargin: this.widget.notchMargin
)
: new ShapeBorderClipper(shape: new RoundedRectangleBorder());
return new PhysicalShape(
clipper: clipper,
elevation: this.widget.elevation,
color: this.widget.color ?? Theme.of(context).bottomAppBarColor,
clipBehavior: this.widget.clipBehavior,
child: new Material(
type: MaterialType.transparency,
child: this.widget.child == null
? null
: new SafeArea(child: this.widget.child)
)
);
}
}
class _BottomAppBarClipper : CustomClipper<Path> {
public _BottomAppBarClipper(
ValueListenable<ScaffoldGeometry> geometry,
NotchedShape shape,
float notchMargin
) : base(reclip: geometry) {
D.assert(geometry != null);
D.assert(shape != null);
this.geometry = geometry;
this.shape = shape;
this.notchMargin = notchMargin;
}
public readonly ValueListenable<ScaffoldGeometry> geometry;
public readonly NotchedShape shape;
public readonly float notchMargin;
public override Path getClip(Size size) {
Rect appBar = Offset.zero & size;
if (this.geometry.value.floatingActionButtonArea == null) {
Path path = new Path();
path.addRect(appBar);
return path;
}
Rect button = this.geometry.value.floatingActionButtonArea
.translate(0.0f, (this.geometry.value.bottomNavigationBarTop * -1.0f) ?? 0.0f);
return this.shape.getOuterPath(appBar, button.inflate(this.notchMargin));
}
public override bool shouldReclip(CustomClipper<Path> oldClipper) {
return (oldClipper as _BottomAppBarClipper).geometry != this.geometry;
}
}
}

3
Runtime/material/bottom_app_bar.cs.meta


fileFormatVersion: 2
guid: aa89369405044a62a19225b2c20815f6
timeCreated: 1553156127

592
Runtime/material/bottom_navigation_bar.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
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;
using Transform = Unity.UIWidgets.widgets.Transform;
namespace Unity.UIWidgets.material {
class BottomNavigationBarUtils {
public const float _kActiveFontSize = 14.0f;
public const float _kInactiveFontSize = 12.0f;
public const float _kTopMargin = 6.0f;
public const float _kBottomMargin = 8.0f;
}
public enum BottomNavigationBarType {
fix,
shifting
}
public class BottomNavigationBar : StatefulWidget {
public BottomNavigationBar(
Key key = null,
List<BottomNavigationBarItem> items = null,
ValueChanged<int> onTap = null,
int currentIndex = 0,
BottomNavigationBarType? type = null,
Color fixedColor = null,
float iconSize = 24.0f
) : base(key: key) {
D.assert(items != null);
D.assert(items.Count >= 2);
D.assert(items.All((BottomNavigationBarItem item) => item.title != null) == true,
"Every item must have a non-null title"
);
D.assert(0 <= currentIndex && currentIndex < items.Count);
this.items = items;
this.onTap = onTap;
this.currentIndex = currentIndex;
this.type = type ?? (items.Count <= 3 ? BottomNavigationBarType.fix : BottomNavigationBarType.shifting);
this.fixedColor = fixedColor;
this.iconSize = iconSize;
}
public readonly List<BottomNavigationBarItem> items;
public readonly ValueChanged<int> onTap;
public readonly int currentIndex;
public readonly BottomNavigationBarType? type;
public readonly Color fixedColor;
public readonly float iconSize;
public override State createState() {
return new _BottomNavigationBarState();
}
}
class _BottomNavigationTile : StatelessWidget {
public _BottomNavigationTile(
BottomNavigationBarType? type,
BottomNavigationBarItem item,
Animation<float> animation,
float? iconSize = null,
VoidCallback onTap = null,
ColorTween colorTween = null,
float? flex = null,
bool selected = false,
string indexLabel = null
) {
this.type = type;
this.item = item;
this.animation = animation;
this.iconSize = iconSize;
this.onTap = onTap;
this.colorTween = colorTween;
this.flex = flex;
this.selected = selected;
this.indexLabel = indexLabel;
}
public readonly BottomNavigationBarType? type;
public readonly BottomNavigationBarItem item;
public readonly Animation<float> animation;
public readonly float? iconSize;
public readonly VoidCallback onTap;
public readonly ColorTween colorTween;
public readonly float? flex;
public readonly bool selected;
public readonly string indexLabel;
Widget _buildIcon() {
float tweenStart;
Color iconColor;
switch (this.type) {
case BottomNavigationBarType.fix:
tweenStart = 8.0f;
iconColor = this.colorTween.evaluate(this.animation);
break;
case BottomNavigationBarType.shifting:
tweenStart = 16.0f;
iconColor = Colors.white;
break;
default:
throw new Exception("Unknown BottomNavigationBarType: " + this.type);
}
return new Align(
alignment: Alignment.topCenter,
heightFactor: 1.0f,
child: new Container(
margin: EdgeInsets.only(
top: new FloatTween(
begin: tweenStart,
end: BottomNavigationBarUtils._kTopMargin
).evaluate(this.animation)
),
child: new IconTheme(
data: new IconThemeData(
color: iconColor,
size: this.iconSize
),
child: this.selected ? this.item.activeIcon : this.item.icon
)
)
);
}
Widget _buildFixedLabel() {
float t = new FloatTween(
begin: BottomNavigationBarUtils._kInactiveFontSize / BottomNavigationBarUtils._kActiveFontSize,
end: 1.0f
).evaluate(this.animation);
return new Align(
alignment: Alignment.bottomCenter,
heightFactor: 1.0f,
child: new Container(
margin: EdgeInsets.only(bottom: BottomNavigationBarUtils._kBottomMargin),
child: DefaultTextStyle.merge(
style: new TextStyle(
fontSize: BottomNavigationBarUtils._kActiveFontSize,
color: this.colorTween.evaluate(this.animation)
),
child: new Transform(
transform: Matrix3.makeAll(t, 0, 0, 0, t, 0, 0, 0, t),
alignment: Alignment.bottomCenter,
child: this.item.title
)
)
)
);
}
Widget _buildShiftingLabel() {
return new Align(
alignment: Alignment.bottomCenter,
heightFactor: 1.0f,
child: new Container(
margin: EdgeInsets.only(
bottom: new FloatTween(
begin: 2.0f,
end: BottomNavigationBarUtils._kBottomMargin
).evaluate(this.animation)
),
child: new FadeTransition(
opacity: this.animation,
child: DefaultTextStyle.merge(
style: new TextStyle(
fontSize: BottomNavigationBarUtils._kActiveFontSize,
color: Colors.white
),
child: this.item.title
)
)
)
);
}
public override Widget build(BuildContext context) {
int size;
Widget label;
switch (this.type) {
case BottomNavigationBarType.fix:
size = 1;
label = this._buildFixedLabel();
break;
case BottomNavigationBarType.shifting:
size = ((this.flex * 1000.0f) ?? 0.0f).round();
label = this._buildShiftingLabel();
break;
default:
throw new Exception("Unknown BottomNavigationBarType: " + this.type);
}
return new Expanded(
flex: size,
child: new Stack(
children: new List<Widget> {
new InkResponse(
onTap: this.onTap == null ? (GestureTapCallback) null : () => { this.onTap(); },
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {this._buildIcon(), label}
)
)
}
)
);
}
}
class _BottomNavigationBarState : TickerProviderStateMixin<BottomNavigationBar> {
public List<AnimationController> _controllers = new List<AnimationController> { };
public List<CurvedAnimation> _animations;
Queue<_Circle> _circles = new Queue<_Circle>();
Color _backgroundColor;
static readonly Animatable<float> _flexTween = new FloatTween(begin: 1.0f, end: 1.5f);
public _BottomNavigationBarState() {
}
void _resetState() {
foreach (AnimationController controller in this._controllers) {
controller.dispose();
}
foreach (_Circle circle in this._circles) {
circle.dispose();
}
this._circles.Clear();
this._controllers = new List<AnimationController>(capacity: this.widget.items.Count);
for (int index = 0; index < this.widget.items.Count; index++) {
AnimationController controller = new AnimationController(
duration: ThemeUtils.kThemeAnimationDuration,
vsync: this
);
controller.addListener(this._rebuild);
this._controllers.Add(controller);
}
this._animations = new List<CurvedAnimation>(capacity: this.widget.items.Count);
for (int index = 0; index < this.widget.items.Count; index++) {
this._animations.Add(new CurvedAnimation(
parent: this._controllers[index],
curve: Curves.fastOutSlowIn,
reverseCurve: Curves.fastOutSlowIn.flipped
));
}
this._controllers[this.widget.currentIndex].setValue(1.0f);
this._backgroundColor = this.widget.items[this.widget.currentIndex].backgroundColor;
}
public override void initState() {
base.initState();
this._resetState();
}
void _rebuild() {
this.setState(() => { });
}
public override void dispose() {
foreach (AnimationController controller in this._controllers) {
controller.dispose();
}
foreach (_Circle circle in this._circles) {
circle.dispose();
}
base.dispose();
}
public float _evaluateFlex(Animation<float> animation) {
return _flexTween.evaluate(animation);
}
void _pushCircle(int index) {
if (this.widget.items[index].backgroundColor != null) {
_Circle circle = new _Circle(
state: this,
index: index,
color: this.widget.items[index].backgroundColor,
vsync: this
);
circle.controller.addStatusListener(
(AnimationStatus status) => {
switch (status) {
case AnimationStatus.completed:
this.setState(() => {
_Circle cir = this._circles.Dequeue();
this._backgroundColor = cir.color;
cir.dispose();
});
break;
case AnimationStatus.dismissed:
case AnimationStatus.forward:
case AnimationStatus.reverse:
break;
}
}
);
this._circles.Enqueue(circle);
}
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
base.didUpdateWidget(_oldWidget);
BottomNavigationBar oldWidget = _oldWidget as BottomNavigationBar;
if (this.widget.items.Count != oldWidget.items.Count) {
this._resetState();
return;
}
if (this.widget.currentIndex != oldWidget.currentIndex) {
switch (this.widget.type) {
case BottomNavigationBarType.fix:
break;
case BottomNavigationBarType.shifting:
this._pushCircle(this.widget.currentIndex);
break;
}
this._controllers[oldWidget.currentIndex].reverse();
this._controllers[this.widget.currentIndex].forward();
}
else {
if (this._backgroundColor != this.widget.items[this.widget.currentIndex].backgroundColor) {
this._backgroundColor = this.widget.items[this.widget.currentIndex].backgroundColor;
}
}
}
List<Widget> _createTiles() {
MaterialLocalizations localizations = MaterialLocalizations.of(this.context);
D.assert(localizations != null);
List<Widget> children = new List<Widget> { };
switch (this.widget.type) {
case BottomNavigationBarType.fix:
ThemeData themeData = Theme.of(this.context);
TextTheme textTheme = themeData.textTheme;
Color themeColor;
switch (themeData.brightness) {
case Brightness.light:
themeColor = themeData.primaryColor;
break;
case Brightness.dark:
themeColor = themeData.accentColor;
break;
default:
throw new Exception("Unknown brightness: " + themeData.brightness);
}
ColorTween colorTween = new ColorTween(
begin: textTheme.caption.color,
end: this.widget.fixedColor ?? themeColor
);
for (int i = 0; i < this.widget.items.Count; i += 1) {
int index = i;
children.Add(
new _BottomNavigationTile(this.widget.type, this.widget.items[i], this._animations[i],
this.widget.iconSize,
onTap: () => {
if (this.widget.onTap != null) {
this.widget.onTap(index);
}
},
colorTween: colorTween,
selected: i == this.widget.currentIndex,
indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: this.widget.items.Count)
)
);
}
break;
case BottomNavigationBarType.shifting:
for (int i = 0; i < this.widget.items.Count; i += 1) {
int index = i;
children.Add(
new _BottomNavigationTile(this.widget.type, this.widget.items[i], this._animations[i],
this.widget.iconSize,
onTap: () => {
if (this.widget.onTap != null) {
this.widget.onTap(index);
}
},
flex:
this._evaluateFlex(this._animations[i]),
selected: i == this.widget.currentIndex,
indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: this.widget.items.Count)
)
);
}
break;
}
return children;
}
Widget _createContainer(List<Widget> tiles) {
return DefaultTextStyle.merge(
overflow: TextOverflow.ellipsis,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: tiles
)
);
}
public override Widget build(BuildContext context) {
D.assert(WidgetsD.debugCheckHasDirectionality(context));
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
float additionalBottomPadding =
Mathf.Max(MediaQuery.of(context).padding.bottom - BottomNavigationBarUtils._kBottomMargin, 0.0f);
Color backgroundColor = null;
switch (this.widget.type) {
case BottomNavigationBarType.fix:
break;
case BottomNavigationBarType.shifting:
backgroundColor = this._backgroundColor;
break;
}
return new Stack(
children: new List<Widget> {
Positioned.fill(
child: new Material( // Casts shadow.
elevation: 8.0f,
color: backgroundColor
)
),
new ConstrainedBox(
constraints: new BoxConstraints(
minHeight: Constants.kBottomNavigationBarHeight + additionalBottomPadding),
child: new Stack(
children: new List<Widget> {
Positioned.fill(
child: new CustomPaint(
painter: new _RadialPainter(
circles: this._circles.ToList()
)
)
),
new Material( // Splashes.
type: MaterialType.transparency,
child: new Padding(
padding: EdgeInsets.only(bottom: additionalBottomPadding),
child: MediaQuery.removePadding(
context: context,
removeBottom: true,
child: this._createContainer(this._createTiles())
)
)
)
}
)
)
}
);
}
}
class _Circle {
public _Circle(
_BottomNavigationBarState state = null,
int? index = null,
Color color = null,
TickerProvider vsync = null
) {
D.assert(state != null);
D.assert(index != null);
D.assert(color != null);
this.state = state;
this.index = index;
this.color = color;
this.controller = new AnimationController(
duration: ThemeUtils.kThemeAnimationDuration,
vsync: vsync
);
this.animation = new CurvedAnimation(
parent: this.controller,
curve: Curves.fastOutSlowIn
);
this.controller.forward();
}
public readonly _BottomNavigationBarState state;
public readonly int? index;
public readonly Color color;
public readonly AnimationController controller;
public readonly CurvedAnimation animation;
public float horizontalLeadingOffset {
get {
float weightSum(IEnumerable<Animation<float>> animations) {
return animations.Select(this.state._evaluateFlex).Sum();
}
float allWeights = weightSum(this.state._animations);
float leadingWeights = weightSum(this.state._animations.GetRange(0, this.index ?? 0));
return (leadingWeights + this.state._evaluateFlex(this.state._animations[this.index ?? 0]) / 2.0f) /
allWeights;
}
}
public void dispose() {
this.controller.dispose();
}
}
class _RadialPainter : AbstractCustomPainter {
public _RadialPainter(
List<_Circle> circles
) {
D.assert(circles != null);
this.circles = circles;
}
public readonly List<_Circle> circles;
static float _maxRadius(Offset center, Size size) {
float maxX = Mathf.Max(center.dx, size.width - center.dx);
float maxY = Mathf.Max(center.dy, size.height - center.dy);
return Mathf.Sqrt(maxX * maxX + maxY * maxY);
}
public override bool shouldRepaint(CustomPainter _oldPainter) {
_RadialPainter oldPainter = _oldPainter as _RadialPainter;
if (this.circles == oldPainter.circles) {
return false;
}
if (this.circles.Count != oldPainter.circles.Count) {
return true;
}
for (int i = 0; i < this.circles.Count; i += 1) {
if (this.circles[i] != oldPainter.circles[i]) {
return true;
}
}
return false;
}
public override void paint(Canvas canvas, Size size) {
foreach (_Circle circle in this.circles) {
Paint paint = new Paint();
paint.color = circle.color;
Rect rect = Rect.fromLTWH(0.0f, 0.0f, size.width, size.height);
canvas.clipRect(rect);
float leftFraction = circle.horizontalLeadingOffset;
Offset center = new Offset(leftFraction * size.width, size.height / 2.0f);
FloatTween radiusTween = new FloatTween(
begin: 0.0f,
end: _maxRadius(center, size)
);
canvas.drawCircle(
center,
radiusTween.evaluate(circle.animation),
paint
);
}
}
}
}

3
Runtime/material/bottom_navigation_bar.cs.meta


fileFormatVersion: 2
guid: 6b8f793d1b8d4004b2c19c1c085752c3
timeCreated: 1553161698

183
Runtime/material/radio.cs


using System;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.material {
class RadioUtils {
public const float _kOuterRadius = 8.0f;
public const float _kInnerRadius = 4.5f;
}
public class Radio<T> : StatefulWidget where T : class {
public Radio(
Key key = null,
T value = null,
T groupValue = null,
ValueChanged<T> onChanged = null,
Color activeColor = null,
MaterialTapTargetSize? materialTapTargetSize = null
) : base(key: key) {
D.assert(value != null);
D.assert(groupValue != null);
D.assert(onChanged != null);
this.value = value;
this.groupValue = groupValue;
this.onChanged = onChanged;
this.activeColor = activeColor;
this.materialTapTargetSize = materialTapTargetSize;
}
public readonly T value;
public readonly T groupValue;
public readonly ValueChanged<T> onChanged;
public readonly Color activeColor;
public readonly MaterialTapTargetSize? materialTapTargetSize;
public override State createState() {
return new _RadioState<T>();
}
}
class _RadioState<T> : TickerProviderStateMixin<Radio<T>> where T : class {
bool _enabled {
get { return this.widget.onChanged != null; }
}
Color _getInactiveColor(ThemeData themeData) {
return this._enabled ? themeData.unselectedWidgetColor : themeData.disabledColor;
}
void _handleChanged(bool? selected) {
if (selected == true) {
this.widget.onChanged(this.widget.value);
}
}
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterial(context));
ThemeData themeData = Theme.of(context);
Size size;
switch (this.widget.materialTapTargetSize ?? themeData.materialTapTargetSize) {
case MaterialTapTargetSize.padded:
size = new Size(2 * Constants.kRadialReactionRadius + 8.0f,
2 * Constants.kRadialReactionRadius + 8.0f);
break;
case MaterialTapTargetSize.shrinkWrap:
size = new Size(2 * Constants.kRadialReactionRadius, 2 * Constants.kRadialReactionRadius);
break;
default:
throw new Exception("Unknown material tap target size");
}
BoxConstraints additionalConstraints = BoxConstraints.tight(size);
return new _RadioRenderObjectWidget(
selected: this.widget.value == this.widget.groupValue,
activeColor: this.widget.activeColor ?? themeData.toggleableActiveColor,
inactiveColor: this._getInactiveColor(themeData),
onChanged: this._enabled ? this._handleChanged : (ValueChanged<bool?>) null,
additionalConstraints: additionalConstraints,
vsync: this
);
}
}
class _RadioRenderObjectWidget : LeafRenderObjectWidget {
public _RadioRenderObjectWidget(
Key key = null,
bool? selected = null,
Color activeColor = null,
Color inactiveColor = null,
BoxConstraints additionalConstraints = null,
ValueChanged<bool?> onChanged = null,
TickerProvider vsync = null
) : base(key: key) {
D.assert(selected != null);
D.assert(activeColor != null);
D.assert(inactiveColor != null);
D.assert(additionalConstraints != null);
D.assert(vsync != null);
this.selected = selected;
this.activeColor = activeColor;
this.inactiveColor = inactiveColor;
this.additionalConstraints = additionalConstraints;
this.onChanged = onChanged;
this.vsync = vsync;
}
public readonly bool? selected;
public readonly Color activeColor;
public readonly Color inactiveColor;
public readonly BoxConstraints additionalConstraints;
public readonly ValueChanged<bool?> onChanged;
public readonly TickerProvider vsync;
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderRadio(
value: this.selected,
activeColor: this.activeColor,
inactiveColor: this.inactiveColor,
onChanged: this.onChanged,
vsync: this.vsync,
additionalConstraints: this.additionalConstraints
);
}
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
_RenderRadio renderObject = _renderObject as _RenderRadio;
renderObject.value = this.selected;
renderObject.activeColor = this.activeColor;
renderObject.inactiveColor = this.inactiveColor;
renderObject.onChanged = this.onChanged;
renderObject.additionalConstraints = this.additionalConstraints;
renderObject.vsync = this.vsync;
}
}
class _RenderRadio : RenderToggleable {
public _RenderRadio(
bool? value,
Color activeColor,
Color inactiveColor,
ValueChanged<bool?> onChanged,
BoxConstraints additionalConstraints,
TickerProvider vsync
) : base(
value: value,
tristate: false,
activeColor: activeColor,
inactiveColor: inactiveColor,
onChanged: onChanged,
additionalConstraints: additionalConstraints,
vsync: vsync
) {
}
public override void paint(PaintingContext context, Offset offset) {
Canvas canvas = context.canvas;
this.paintRadialReaction(canvas, offset,
new Offset(Constants.kRadialReactionRadius, Constants.kRadialReactionRadius));
Offset center = (offset & this.size).center;
Color radioColor = this.onChanged != null ? this.activeColor : this.inactiveColor;
Paint paint = new Paint();
paint.color = Color.lerp(this.inactiveColor, radioColor, this.position.value);
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 2.0f;
canvas.drawCircle(center, RadioUtils._kOuterRadius, paint);
if (!this.position.isDismissed) {
paint.style = PaintingStyle.fill;
canvas.drawCircle(center, RadioUtils._kInnerRadius * this.position.value, paint);
}
}
}
}

3
Runtime/material/radio.cs.meta


fileFormatVersion: 2
guid: 1328fb437a4047c49b51dfe3a2c3d106
timeCreated: 1553154501

71
Runtime/painting/notched_shapes.cs


using System.Collections.Generic;
using Unity.UIWidgets.ui;
using UnityEngine;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.painting {
public abstract class NotchedShape {
public NotchedShape() {
}
public abstract Path getOuterPath(Rect host, Rect guest);
}
public class CircularNotchedRectangle : NotchedShape {
public CircularNotchedRectangle() {
}
public override Path getOuterPath(Rect host, Rect guest) {
if (!host.overlaps(guest)) {
Path path = new Path();
path.addRect(host);
return path;
}
float notchRadius = guest.width / 2.0f;
const float s1 = 15.0f;
const float s2 = 1.0f;
float r = notchRadius;
float a = -1.0f * r - s2;
float b = host.top - guest.center.dy;
float n2 = Mathf.Sqrt(b * b * r * r * (a * a + b * b - r * r));
float p2xA = ((a * r * r) - n2) / (a * a + b * b);
float p2xB = ((a * r * r) + n2) / (a * a + b * b);
float p2yA = Mathf.Sqrt(r * r - p2xA * p2xA);
float p2yB = Mathf.Sqrt(r * r - p2xB * p2xB);
List<Offset> p = new List<Offset>(6);
p[0] = new Offset(a - s1, b);
p[1] = new Offset(a, b);
float cmp = b < 0 ? -1.0f : 1.0f;
p[2] = cmp * p2yA > cmp * p2yB ? new Offset(p2xA, p2yA) : new Offset(p2xB, p2yB);
p[3] = new Offset(-1.0f * p[2].dx, p[2].dy);
p[4] = new Offset(-1.0f * p[1].dx, p[1].dy);
p[5] = new Offset(-1.0f * p[0].dx, p[0].dy);
for (int i = 0; i < p.Count; i += 1) {
p[i] += guest.center;
}
Path ret = new Path();
ret.moveTo(host.left, host.top);
ret.lineTo(p[0].dx, p[0].dy);
ret.quadTo(p[1].dx, p[1].dy, p[2].dx, p[2].dy);
// TODO: replace this lineTo() with arcToPoint when arcToPoint is ready
ret.lineTo(p[3].dx, p[3].dy);
// ret.arcToPoint(p[3], p[3], radius: Radius.circular(notchRadius), clockwise: false);
ret.quadTo(p[4].dx, p[4].dy, p[5].dx, p[5].dy);
ret.lineTo(host.right, host.top);
ret.lineTo(host.right, host.bottom);
ret.lineTo(host.left, host.bottom);
ret.close();
return ret;
}
}
}

3
Runtime/painting/notched_shapes.cs.meta


fileFormatVersion: 2
guid: c89c524fa7c242aa91900b63841be8b3
timeCreated: 1553153571

181
Runtime/ui/painting/shadow_utils.cs


using UnityEngine;
namespace Unity.UIWidgets.ui {
public static class ShadowUtils {
public const bool _drawShadowFlag = false;
public const float kAmbientHeightFactor = 1.0f / 128.0f;
public const float kAmbientGeomFactor = 64.0f;
public const float kBlurSigmaScale = 0.57735f;
public const float kMaxAmbientRadius = 300 * kAmbientHeightFactor * kAmbientGeomFactor;
public static float divideAndPin(float numer, float denom, float min, float max) {
return (numer / denom).clamp(min, max);
}
public static float ambientBlurRadius(float height) {
return Mathf.Min(height * kAmbientHeightFactor * kAmbientGeomFactor, kMaxAmbientRadius);
}
public static float ambientRecipAlpha(float height) {
return 1.0f + Mathf.Max(height * kAmbientHeightFactor, 0.0f);
}
public static float spotBlurRadius(float occluderZ, float lightZ, float lightRadius) {
return lightRadius * divideAndPin(occluderZ, lightZ - occluderZ, 0.0f, 0.95f);
}
public static void getSpotParams(float occluderZ, float lightX, float lightY, float lightZ,
float lightRadius,
ref float blurRadius, ref float scale, ref Vector2 translate) {
float zRatio = divideAndPin(occluderZ, lightZ - occluderZ, 0.0f, 0.95f);
blurRadius = lightRadius * zRatio;
scale = divideAndPin(lightZ, lightZ - occluderZ, 1.0f, 1.95f);
translate = new Vector2(-zRatio * lightX, -zRatio * lightY);
}
public static float convertRadiusToSigma(float radius) {
return radius > 0 ? kBlurSigmaScale * radius + 0.5f : 0.0f;
}
public static void computeTonalColors(Color inAmbientColor, Color inSpotColor,
ref Color outAmbientColor, ref Color outSpotColor) {
outAmbientColor = Color.fromARGB(inAmbientColor.alpha, 0, 0, 0);
outSpotColor = inSpotColor;
}
public static bool getSpotShadowTransform(Vector3 lightPos, float lightRadius, Matrix3 ctm,
Vector3 zPlaneParams, Rect pathBounds, Matrix3 shadowTransform, ref float radius) {
float heightFunc(float x, float y) {
return zPlaneParams.x * x + zPlaneParams.y * y + zPlaneParams.z;
}
float occluderHeight = heightFunc(pathBounds.center.dx, pathBounds.center.dy);
if (!ctm.hasPerspective()) {
float scale = 0.0f;
Vector2 translate = new Vector2();
getSpotParams(occluderHeight, lightPos.x, lightPos.y, lightPos.z, lightRadius, ref radius, ref scale,
ref translate);
shadowTransform.setScaleTranslate(scale, scale, translate.x, translate.y);
shadowTransform.preConcat(ctm);
}
else {
if (pathBounds.width.valueNearlyZero() || pathBounds.height.valueNearlyZero()) {
return false;
}
Offset[] pts = ctm.mapRectToQuad(pathBounds);
if (!MathUtils.isConvexPolygon(pts, 4)) {
return false;
}
Vector3[] pts3D = new Vector3[4];
float z = heightFunc(pathBounds.left, pathBounds.top);
pts3D[0] = new Vector3(pts[0].dx, pts[0].dy, z);
z = heightFunc(pathBounds.right, pathBounds.top);
pts3D[1] = new Vector3(pts[1].dx, pts[1].dy, z);
z = heightFunc(pathBounds.right, pathBounds.bottom);
pts3D[2] = new Vector3(pts[2].dx, pts[2].dy, z);
z = heightFunc(pathBounds.left, pathBounds.bottom);
pts3D[3] = new Vector3(pts[3].dx, pts[3].dy, z);
for (int i = 0; i < 4; i++) {
float dz = lightPos.z - pts3D[i].z;
if (dz.valueNearlyZero()) {
return false;
}
float zRatio = pts3D[i].z / dz;
pts3D[i].x -= (lightPos.x - pts3D[i].x) * zRatio;
pts3D[i].y -= (lightPos.y - pts3D[i].y) * zRatio;
pts3D[i].z = 1f;
}
Vector3 h0 = Vector3.Cross(Vector3.Cross(pts3D[1], pts3D[0]), Vector3.Cross(pts3D[2], pts3D[3]));
Vector3 h1 = Vector3.Cross(Vector3.Cross(pts3D[0], pts3D[3]), Vector3.Cross(pts3D[1], pts3D[2]));
Vector3 h2 = Vector3.Cross(Vector3.Cross(pts3D[0], pts3D[2]), Vector3.Cross(pts3D[1], pts3D[3]));
if (h2.z.valueNearlyZero()) {
return false;
}
Vector3 v = pts3D[3] - pts3D[0];
Vector3 w = h0 - pts3D[0];
float perpDot = v.x * w.y - v.y * w.x;
if (perpDot > 0) {
h0 = -h0;
}
v = pts3D[1] - pts3D[0];
perpDot = v.x * w.y - v.y * w.x;
if (perpDot < 0) {
h1 = -h1;
}
shadowTransform.setAll(h0.x / h2.z, h1.x / h2.z, h2.x / h2.z,
h0.y / h2.z, h1.y / h2.z, h2.y / h2.z,
h0.z / h2.z, h1.z / h2.z, 1);
Matrix3 toHomogeneous = Matrix3.I();
float xScale = 2.0f / (pathBounds.right - pathBounds.left);
float yScale = 2.0f / (pathBounds.bottom - pathBounds.top);
toHomogeneous.setAll(xScale, 0, -xScale * pathBounds.left - 1,
0, yScale, -yScale * pathBounds.top - 1,
0, 0, 1);
shadowTransform.preConcat(toHomogeneous);
radius = spotBlurRadius(occluderHeight, lightPos.z, lightRadius);
}
return true;
}
public static void drawShadow(Canvas canvas, Path path, Vector3 zPlaneParams, Vector3 devLightPos,
float lightRadius, Color ambientColor, Color spotColor, int flags) {
if (!_drawShadowFlag) {
return;
}
Matrix3 viewMatrix = canvas.getTotalMatrix();
//ambient light
Path devSpacePath = path.transform(viewMatrix);
float devSpaceOutset = ambientBlurRadius(zPlaneParams.z);
float oneOverA = ambientRecipAlpha(zPlaneParams.z);
float blurRadius = 0.5f * devSpaceOutset * oneOverA;
float strokeWidth = 0.5f * (devSpaceOutset - blurRadius);
Paint paint = new Paint {color = ambientColor, strokeWidth = strokeWidth, style = PaintingStyle.fill};
canvas.save();
canvas.setMatrix(Matrix3.I());
float sigma = convertRadiusToSigma(blurRadius);
paint.maskFilter = MaskFilter.blur(BlurStyle.normal, sigma);
canvas.drawPath(devSpacePath, paint);
canvas.restore();
//spot light
Matrix3 shadowMatrix = Matrix3.I();
float radius = 0.0f;
if (!getSpotShadowTransform(devLightPos, lightRadius, viewMatrix, zPlaneParams, path.getBounds(),
shadowMatrix, ref radius)) {
return;
}
canvas.save();
canvas.setMatrix(shadowMatrix);
Paint paint2 = new Paint {color = spotColor};
float sigma2 = convertRadiusToSigma(radius);
paint2.maskFilter = MaskFilter.blur(BlurStyle.normal, sigma2);
canvas.drawPath(path, paint2);
canvas.restore();
}
}
}

27
Runtime/widgets/bottom_navigation_bar_item.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.widgets {
public class BottomNavigationBarItem {
public BottomNavigationBarItem(
Widget icon = null,
Widget title = null,
Widget activeIcon = null,
Color backgroundColor = null
) {
D.assert(icon != null);
this.icon = icon;
this.activeIcon = activeIcon ?? icon;
this.title = title;
this.backgroundColor = backgroundColor;
}
public readonly Widget icon;
public readonly Widget activeIcon;
public readonly Widget title;
public readonly Color backgroundColor;
}
}

3
Runtime/widgets/bottom_navigation_bar_item.cs.meta


fileFormatVersion: 2
guid: 7000f1f897684e08a0831ca5d920589f
timeCreated: 1553162159

423
Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Image = Unity.UIWidgets.widgets.Image;
using Material = Unity.UIWidgets.material.Material;
namespace UIWidgetsGallery.gallery {
class BackdropDemoConstants {
public static readonly List<Category> allCategories = new List<Category> {
new Category(
title: "Accessories",
assets: new List<string> {
"products/belt",
"products/earrings",
"products/backpack",
"products/hat",
"products/scarf",
"products/sunnies"
}
),
new Category(
title: "Blue",
assets: new List<string> {
"products/backpack",
"products/cup",
"products/napkins",
"products/top"
}
),
new Category(
title: "Cold Weather",
assets: new List<string> {
"products/jacket",
"products/jumper",
"products/scarf",
"products/sweater",
"products/sweats"
}
),
new Category(
title: "Home",
assets: new List<string> {
"products/cup",
"products/napkins",
"products/planters",
"products/table",
"products/teaset"
}
),
new Category(
title: "Tops",
assets: new List<string> {
"products/jumper",
"products/shirt",
"products/sweater",
"products/top"
}
),
new Category(
title: "Everything",
assets: new List<string> {
"products/backpack",
"products/belt",
"products/cup",
"products/dress",
"products/earrings",
"products/flatwear",
"products/hat",
"products/jacket",
"products/jumper",
"products/napkins",
"products/planters",
"products/scarf",
"products/shirt",
"products/sunnies",
"products/sweater",
"products/sweats",
"products/table",
"products/teaset",
"products/top"
}
),
};
}
public class Category {
public Category(string title = null, List<string> assets = null) {
this.title = title;
this.assets = assets;
}
public readonly string title;
public readonly List<string> assets;
public override string ToString() {
return $"{this.GetType()}('{this.title}')";
}
}
public class CategoryView : StatelessWidget {
public CategoryView(Key key = null, Category category = null) : base(key: key) {
this.category = category;
}
public readonly Category category;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new ListView(
key: new PageStorageKey<Category>(this.category),
padding: EdgeInsets.symmetric(
vertical: 16.0f,
horizontal: 64.0f
),
children: this.category.assets.Select<string, Widget>((string asset) => {
return new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: new List<Widget> {
new Card(
child: new Container(
width: 144.0f,
alignment: Alignment.center,
child: new Column(
children: new List<Widget> {
Image.asset(
asset,
fit: BoxFit.contain
),
new Container(
padding: EdgeInsets.only(bottom: 16.0f),
alignment: Alignment.center,
child: new Text(
asset,
style: theme.textTheme.caption
)
),
}
)
)
),
new SizedBox(height: 24.0f)
}
);
}).ToList()
);
}
}
public class BackdropPanel : StatelessWidget {
public BackdropPanel(
Key key = null,
VoidCallback onTap = null,
GestureDragUpdateCallback onVerticalDragUpdate = null,
GestureDragEndCallback onVerticalDragEnd = null,
Widget title = null,
Widget child = null
) : base(key: key) {
this.onTap = onTap;
this.onVerticalDragUpdate = onVerticalDragUpdate;
this.onVerticalDragEnd = onVerticalDragEnd;
this.title = title;
this.child = child;
}
public readonly VoidCallback onTap;
public readonly GestureDragUpdateCallback onVerticalDragUpdate;
public readonly GestureDragEndCallback onVerticalDragEnd;
public readonly Widget title;
public readonly Widget child;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Material(
elevation: 2.0f,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0f),
topRight: Radius.circular(16.0f)
),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: new List<Widget> {
new GestureDetector(
behavior: HitTestBehavior.opaque,
onVerticalDragUpdate: this.onVerticalDragUpdate,
onVerticalDragEnd: this.onVerticalDragEnd,
onTap: this.onTap != null ? (GestureTapCallback) (() => { this.onTap(); }) : null,
child: new Container(
height: 48.0f,
padding: EdgeInsets.only(left: 16.0f),
alignment: Alignment.centerLeft,
child: new DefaultTextStyle(
style: theme.textTheme.subhead,
child: new Tooltip(
message: "Tap to dismiss",
child: this.title
)
)
)
),
new Divider(height: 1.0f),
new Expanded(child: this.child)
}
)
);
}
}
public class BackdropTitle : AnimatedWidget {
public BackdropTitle(
Key key = null,
Listenable listenable = null
) : base(key: key, listenable: listenable) {
}
protected override Widget build(BuildContext context) {
Animation<float> animation = (Animation<float>) this.listenable;
return new DefaultTextStyle(
style: Theme.of(context).primaryTextTheme.title,
softWrap: false,
overflow: TextOverflow.ellipsis,
child: new Stack(
children: new List<Widget> {
new Opacity(
opacity: new CurvedAnimation(
parent: new ReverseAnimation(animation),
curve: new Interval(0.5f, 1.0f)
).value,
child: new Text("Select a Category")
),
new Opacity(
opacity: new CurvedAnimation(
parent: animation,
curve: new Interval(0.5f, 1.0f)
).value,
child: new Text("Asset Viewer")
),
}
)
);
}
}
public class BackdropDemo : StatefulWidget {
public const string routeName = "/material/backdrop";
public override State createState() {
return new _BackdropDemoState();
}
}
class _BackdropDemoState : SingleTickerProviderStateMixin<BackdropDemo> {
GlobalKey _backdropKey = GlobalKey.key(debugLabel: "Backdrop");
AnimationController _controller;
Category _category = BackdropDemoConstants.allCategories[0];
public override void initState() {
base.initState();
this._controller = new AnimationController(
duration: new TimeSpan(0, 0, 0, 0, 300),
value: 1.0f,
vsync: this
);
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
void _changeCategory(Category category) {
this.setState(() => {
this._category = category;
this._controller.fling(velocity: 2.0f);
});
}
bool _backdropPanelVisible {
get {
AnimationStatus status = this._controller.status;
return status == AnimationStatus.completed || status == AnimationStatus.forward;
}
}
void _toggleBackdropPanelVisibility() {
this._controller.fling(velocity: this._backdropPanelVisible ? -2.0f : 2.0f);
}
float? _backdropHeight {
get {
RenderBox renderBox = (RenderBox) this._backdropKey.currentContext.findRenderObject();
return renderBox.size.height;
}
}
void _handleDragUpdate(DragUpdateDetails details) {
if (this._controller.isAnimating || this._controller.status == AnimationStatus.completed) {
return;
}
this._controller.setValue(this._controller.value -
details.primaryDelta / (this._backdropHeight ?? details.primaryDelta) ?? 0.0f);
}
void _handleDragEnd(DragEndDetails details) {
if (this._controller.isAnimating || this._controller.status == AnimationStatus.completed) {
return;
}
float? flingVelocity = details.velocity.pixelsPerSecond.dy / this._backdropHeight;
if (flingVelocity < 0.0f) {
this._controller.fling(velocity: Mathf.Max(2.0f, -flingVelocity ?? 0.0f));
}
else if (flingVelocity > 0.0f) {
this._controller.fling(velocity: Mathf.Min(-2.0f, -flingVelocity ?? 0.0f));
}
else {
this._controller.fling(velocity: this._controller.value < 0.5f ? -2.0f : 2.0f);
}
}
Widget _buildStack(BuildContext context, BoxConstraints constraints) {
const float panelTitleHeight = 48.0f;
Size panelSize = constraints.biggest;
float panelTop = panelSize.height - panelTitleHeight;
Animation<RelativeRect> panelAnimation = this._controller.drive(
new RelativeRectTween(
begin: RelativeRect.fromLTRB(
0.0f,
panelTop - MediaQuery.of(context).padding.bottom,
0.0f,
panelTop - panelSize.height
),
end: RelativeRect.fromLTRB(0.0f, 0.0f, 0.0f, 0.0f)
)
);
ThemeData theme = Theme.of(context);
List<Widget> backdropItems = BackdropDemoConstants.allCategories.Select<Category, Widget>(
(Category category) => {
bool selected = category == this._category;
return new Material(
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0f))
),
color: selected
? Colors.white.withOpacity(0.25f)
: Colors.transparent,
child: new ListTile(
title: new Text(category.title),
selected: selected,
onTap: () => { this._changeCategory(category); }
)
);
}).ToList();
return new Container(
key: this._backdropKey,
color: theme.primaryColor,
child: new Stack(
children: new List<Widget> {
new ListTileTheme(
iconColor: theme.primaryIconTheme.color,
textColor: theme.primaryTextTheme.title.color.withOpacity(0.6f),
selectedColor: theme.primaryTextTheme.title.color,
child: new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0f),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: backdropItems
)
)
),
new PositionedTransition(
rect: panelAnimation,
child: new BackdropPanel(
onTap: this._toggleBackdropPanelVisibility,
onVerticalDragUpdate: this._handleDragUpdate,
onVerticalDragEnd: this._handleDragEnd,
title: new Text(this._category.title),
child: new CategoryView(category: this._category)
)
),
}
)
);
}
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
elevation: 0.0f,
title: new BackdropTitle(
listenable: this._controller.view
),
actions: new List<Widget> {
new IconButton(
onPressed: this._toggleBackdropPanelVisibility,
icon: new AnimatedIcon(
icon: AnimatedIcons.close_menu,
progress: this._controller.view
)
)
}
),
body: new LayoutBuilder(
builder: this._buildStack
)
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs.meta


fileFormatVersion: 2
guid: 98bee0a7e51f4f2d9c8670daf147a15f
timeCreated: 1553145970

523
Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
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;
using Material = Unity.UIWidgets.material.Material;
using Rect = Unity.UIWidgets.ui.Rect;
namespace UIWidgetsGallery.gallery {
public class BottomAppBarDemo : StatefulWidget {
public const string routeName = "/material/bottom_app_bar";
public override State createState() {
return new _BottomAppBarDemoState();
}
}
class _BottomAppBarDemoState : State<BottomAppBarDemo> {
static readonly GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>.key();
static readonly _ChoiceValue<Widget> kNoFab = new _ChoiceValue<Widget>(
title: "None",
label: "do not show a floating action button",
value: null
);
static readonly _ChoiceValue<Widget> kCircularFab = new _ChoiceValue<Widget>(
title: "Circular",
label: "circular floating action button",
value: new FloatingActionButton(
onPressed: _showSnackbar,
child: new Icon(Icons.add),
backgroundColor: Colors.orange
)
);
static readonly _ChoiceValue<Widget> kDiamondFab = new _ChoiceValue<Widget>(
title: "Diamond",
label: "diamond shape floating action button",
value: new _DiamondFab(
onPressed: _showSnackbar,
child: new Icon(Icons.add)
)
);
static readonly _ChoiceValue<bool> kShowNotchTrue = new _ChoiceValue<bool>(
title: "On",
label: "show bottom appbar notch",
value: true
);
static readonly _ChoiceValue<bool> kShowNotchFalse = new _ChoiceValue<bool>(
title: "Off",
label: "do not show bottom appbar notch",
value: false
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabEndDocked =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Attached - End",
label: "floating action button is docked at the end of the bottom app bar",
value: FloatingActionButtonLocation.endDocked
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabCenterDocked =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Attached - Center",
label: "floating action button is docked at the center of the bottom app bar",
value: FloatingActionButtonLocation.centerDocked
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabEndFloat =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Free - End",
label: "floating action button floats above the end of the bottom app bar",
value: FloatingActionButtonLocation.endFloat
);
static readonly _ChoiceValue<FloatingActionButtonLocation> kFabCenterFloat =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Free - Center",
label: "floating action button is floats above the center of the bottom app bar",
value: FloatingActionButtonLocation.centerFloat
);
static void _showSnackbar() {
const string text =
"When the Scaffold's floating action button location changes, " +
"the floating action button animates to its new position." +
"The BottomAppBar adapts its shape appropriately.";
_scaffoldKey.currentState.showSnackBar(
new SnackBar(content: new Text(text))
);
}
static readonly List<_NamedColor> kBabColors = new List<_NamedColor> {
new _NamedColor(null, "Clear"),
new _NamedColor(new Color(0xFFFFC100), "Orange"),
new _NamedColor(new Color(0xFF91FAFF), "Light Blue"),
new _NamedColor(new Color(0xFF00D1FF), "Cyan"),
new _NamedColor(new Color(0xFF00BCFF), "Cerulean"),
new _NamedColor(new Color(0xFF009BEE), "Blue")
};
_ChoiceValue<Widget> _fabShape = kCircularFab;
_ChoiceValue<bool> _showNotch = kShowNotchTrue;
_ChoiceValue<FloatingActionButtonLocation> _fabLocation = kFabEndDocked;
Color _babColor = kBabColors.First().color;
void _onShowNotchChanged(_ChoiceValue<bool> value) {
this.setState(() => { this._showNotch = value; });
}
void _onFabShapeChanged(_ChoiceValue<Widget> value) {
this.setState(() => { this._fabShape = value; });
}
void _onFabLocationChanged(_ChoiceValue<FloatingActionButtonLocation> value) {
this.setState(() => { this._fabLocation = value; });
}
void _onBabColorChanged(Color value) {
this.setState(() => { this._babColor = value; });
}
public override Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text("Bottom app bar"),
elevation: 0.0f,
actions: new List<Widget> {
new MaterialDemoDocumentationButton(BottomAppBarDemo.routeName),
new IconButton(
icon: new Icon(Icons.sentiment_very_satisfied),
onPressed: () => {
this.setState(() => {
this._fabShape = this._fabShape == kCircularFab ? kDiamondFab : kCircularFab;
});
}
)
}
),
body: new ListView(
padding: EdgeInsets.only(bottom: 88.0f),
children: new List<Widget> {
new _AppBarDemoHeading("FAB Shape"),
new _RadioItem<Widget>(kCircularFab, this._fabShape, this._onFabShapeChanged),
new _RadioItem<Widget>(kDiamondFab, this._fabShape, this._onFabShapeChanged),
new _RadioItem<Widget>(kNoFab, this._fabShape, this._onFabShapeChanged),
new Divider(),
new _AppBarDemoHeading("Notch"),
new _RadioItem<bool>(kShowNotchTrue, this._showNotch, this._onShowNotchChanged),
new _RadioItem<bool>(kShowNotchFalse, this._showNotch, this._onShowNotchChanged),
new Divider(),
new _AppBarDemoHeading("FAB Position"),
new _RadioItem<FloatingActionButtonLocation>(kFabEndDocked, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabCenterDocked, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabEndFloat, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabCenterFloat, this._fabLocation,
this._onFabLocationChanged),
new Divider(),
new _AppBarDemoHeading("App bar color"),
new _ColorsItem(kBabColors, this._babColor, this._onBabColorChanged)
}
),
floatingActionButton:
this._fabShape.value,
floatingActionButtonLocation:
this._fabLocation.value,
bottomNavigationBar: new _DemoBottomAppBar(
color: this._babColor,
fabLocation: this._fabLocation.value,
shape: this._selectNotch()
)
);
}
NotchedShape _selectNotch() {
if (!this._showNotch.value) {
return null;
}
if (this._fabShape == kCircularFab) {
return new CircularNotchedRectangle();
}
if (this._fabShape == kDiamondFab) {
return new _DiamondNotchedRectangle();
}
return null;
}
}
class _ChoiceValue<T> {
public _ChoiceValue(T value, string title, string label) {
this.value = value;
this.title = title;
this.label = label;
}
public readonly T value;
public readonly string title;
string label; // For the Semantics widget that contains title
public override string ToString() {
return $"{this.GetType()}('{this.title}')";
}
}
class _RadioItem<T> : StatelessWidget {
public _RadioItem(_ChoiceValue<T> value, _ChoiceValue<T> groupValue, ValueChanged<_ChoiceValue<T>> onChanged) {
this.value = value;
this.groupValue = groupValue;
this.onChanged = onChanged;
}
_ChoiceValue<T> value;
_ChoiceValue<T> groupValue;
ValueChanged<_ChoiceValue<T>> onChanged;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Container(
height: 56.0f,
padding: EdgeInsets.only(left: 16.0f),
alignment: Alignment.centerLeft,
child: new Row(
children: new List<Widget> {
new Radio<_ChoiceValue<T>>(
value: this.value,
groupValue: this.groupValue,
onChanged: this.onChanged
),
new Expanded(
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => { this.onChanged(this.value); },
child: new Text(this.value.title,
style: theme.textTheme.subhead
)
)
)
}
)
);
}
}
class _NamedColor {
public _NamedColor(Color color, string name) {
this.color = color;
this.name = name;
}
public readonly Color color;
public readonly string name;
}
class _ColorsItem : StatelessWidget {
public _ColorsItem(List<_NamedColor> colors, Color selectedColor, ValueChanged<Color> onChanged) {
this.colors = colors;
this.selectedColor = selectedColor;
this.onChanged = onChanged;
}
List<_NamedColor> colors;
public readonly Color selectedColor;
ValueChanged<Color> onChanged;
public override Widget build(BuildContext context) {
return new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: this.colors.Select<_NamedColor, Widget>((_NamedColor namedColor) => {
return new RawMaterialButton(
onPressed: () => { this.onChanged(namedColor.color); },
constraints: BoxConstraints.tightFor(
width: 32.0f,
height: 32.0f
),
fillColor: namedColor.color,
shape: new CircleBorder(
side: new BorderSide(
color: namedColor.color == this.selectedColor ? Colors.black : new Color(0xFFD5D7DA),
width: 2.0f
)
)
);
}).ToList()
);
}
}
class _AppBarDemoHeading : StatelessWidget {
public _AppBarDemoHeading(string text) {
this.text = text;
}
public readonly string text;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Container(
height: 48.0f,
padding: EdgeInsets.only(left: 56.0f),
alignment: Alignment.centerLeft,
child: new Text(this.text,
style: theme.textTheme.body1.copyWith(
color: theme.primaryColor
)
)
);
}
}
class _DemoBottomAppBar : StatelessWidget {
public _DemoBottomAppBar(
Color color = null,
FloatingActionButtonLocation fabLocation = null,
NotchedShape shape = null
) {
this.color = color;
this.fabLocation = fabLocation;
this.shape = shape;
}
public readonly Color color;
public readonly FloatingActionButtonLocation fabLocation;
public readonly NotchedShape shape;
static readonly List<FloatingActionButtonLocation> kCenterLocations = new List<FloatingActionButtonLocation> {
FloatingActionButtonLocation.centerDocked,
FloatingActionButtonLocation.centerFloat
};
public override Widget build(BuildContext context) {
List<Widget> rowContents = new List<Widget> {
new IconButton(
icon: new Icon(Icons.menu),
onPressed: () => {
BottomSheetUtils.showModalBottomSheet<object>(
context: context,
builder: (BuildContext _context) => new _DemoDrawer()
);
}
)
};
if (kCenterLocations.Contains(this.fabLocation)) {
rowContents.Add(
new Expanded(child: new SizedBox())
);
}
rowContents.AddRange(new List<Widget> {
new IconButton(
icon: new Icon(Icons.search),
onPressed: () => {
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("This is a dummy search action."))
);
}
),
new IconButton(
icon: new Icon(
Theme.of(context).platform == RuntimePlatform.Android
? Icons.more_vert
: Icons.more_horiz
),
onPressed: () => {
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("This is a dummy menu action."))
);
}
)
});
return new BottomAppBar(
color: this.color,
child: new Row(children: rowContents),
shape: this.shape
);
}
}
class _DemoDrawer : StatelessWidget {
public _DemoDrawer() {
}
public override Widget build(BuildContext context) {
return new Drawer(
child: new Column(
children: new List<Widget> {
new ListTile(
leading: new Icon(Icons.search),
title: new Text("Search")
),
new ListTile(
leading: new Icon(Icons.threed_rotation),
title: new Text("3D")
)
}
)
);
}
}
class _DiamondFab : StatelessWidget {
public _DiamondFab(
Widget child,
VoidCallback onPressed
) {
this.child = child;
this.onPressed = onPressed;
}
public readonly Widget child;
public readonly VoidCallback onPressed;
public override Widget build(BuildContext context) {
return new Material(
shape: new _DiamondBorder(),
color: Colors.orange,
child: new InkWell(
onTap: this.onPressed == null ? (GestureTapCallback) null : () => { this.onPressed(); },
child: new Container(
width: 56.0f,
height: 56.0f,
child: IconTheme.merge(
data: new IconThemeData(color: Theme.of(context).accentIconTheme.color),
child: this.child
)
)
),
elevation: 6.0f
);
}
}
class _DiamondNotchedRectangle : NotchedShape {
public _DiamondNotchedRectangle() {
}
public override Path getOuterPath(Rect host, Rect guest) {
if (!host.overlaps(guest)) {
Path path = new Path();
path.addRect(host);
return path;
}
D.assert(guest.width > 0.0f);
Rect intersection = guest.intersect(host);
float notchToCenter =
intersection.height * (guest.height / 2.0f)
/ (guest.width / 2.0f);
Path ret = new Path();
ret.moveTo(host.left, host.top);
ret.lineTo(guest.center.dx - notchToCenter, host.top);
ret.lineTo(guest.left + guest.width / 2.0f, guest.bottom);
ret.lineTo(guest.center.dx + notchToCenter, host.top);
ret.lineTo(host.right, host.top);
ret.lineTo(host.right, host.bottom);
ret.lineTo(host.left, host.bottom);
ret.close();
return ret;
}
}
class _DiamondBorder : ShapeBorder {
public _DiamondBorder() {
}
public override EdgeInsets dimensions {
get { return EdgeInsets.only(); }
}
public override Path getInnerPath(Rect rect) {
return this.getOuterPath(rect);
}
public override Path getOuterPath(Rect rect) {
Path path = new Path();
path.moveTo(rect.left + rect.width / 2.0f, rect.top);
path.lineTo(rect.right, rect.top + rect.height / 2.0f);
path.lineTo(rect.left + rect.width / 2.0f, rect.bottom);
path.lineTo(rect.left, rect.top + rect.height / 2.0f);
path.close();
return path;
}
public override void paint(Canvas canvas, Rect rect) {
}
public override ShapeBorder scale(float t) {
return null;
}
}
}

3
Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs.meta


fileFormatVersion: 2
guid: 7c1d20efeafe42699212e2147c0828af
timeCreated: 1553149093

228
Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.gallery {
public class NavigationIconView {
public NavigationIconView(
Widget icon = null,
Widget activeIcon = null,
string title = null,
Color color = null,
TickerProvider vsync = null
) {
this._icon = icon;
this._color = color;
this._title = title;
this.item = new BottomNavigationBarItem(
icon: icon,
activeIcon: activeIcon,
title: new Text(title),
backgroundColor: color
);
this.controller = new AnimationController(
duration: ThemeUtils.kThemeAnimationDuration,
vsync: vsync
);
this._animation = this.controller.drive(new CurveTween(
curve: new Interval(0.5f, 1.0f, curve: Curves.fastOutSlowIn)
));
}
readonly Widget _icon;
readonly Color _color;
readonly string _title;
public readonly BottomNavigationBarItem item;
public readonly AnimationController controller;
Animation<float> _animation;
public FadeTransition transition(BottomNavigationBarType type, BuildContext context) {
Color iconColor;
if (type == BottomNavigationBarType.shifting) {
iconColor = this._color;
}
else {
ThemeData themeData = Theme.of(context);
iconColor = themeData.brightness == Brightness.light
? themeData.primaryColor
: themeData.accentColor;
}
return new FadeTransition(
opacity: this._animation,
child: new SlideTransition(
position: this._animation.drive(
new OffsetTween(
begin: new Offset(0.0f, 0.02f), // Slightly down.
end: Offset.zero
)
),
child: new IconTheme(
data: new IconThemeData(
color: iconColor,
size: 120.0f
),
child: this._icon
)
)
);
}
}
public class CustomIcon : StatelessWidget {
public override Widget build(BuildContext context) {
IconThemeData iconTheme = IconTheme.of(context);
return new Container(
margin: EdgeInsets.all(4.0f),
width: iconTheme.size - 8.0f,
height: iconTheme.size - 8.0f,
color: iconTheme.color
);
}
}
public class CustomInactiveIcon : StatelessWidget {
public override Widget build(BuildContext context) {
IconThemeData iconTheme = IconTheme.of(context);
return new Container(
margin: EdgeInsets.all(4.0f),
width: iconTheme.size - 8.0f,
height: iconTheme.size - 8.0f,
decoration: new BoxDecoration(
border: Border.all(color: iconTheme.color, width: 2.0f)
)
);
}
}
public class BottomNavigationDemo : StatefulWidget {
public const string routeName = "/material/bottom_navigation";
public override State createState() {
return new _BottomNavigationDemoState();
}
}
class _BottomNavigationDemoState : TickerProviderStateMixin<BottomNavigationDemo> {
int _currentIndex = 0;
BottomNavigationBarType _type = BottomNavigationBarType.shifting;
List<NavigationIconView> _navigationViews;
public override void initState() {
base.initState();
this._navigationViews = new List<NavigationIconView> {
new NavigationIconView(
icon: new Icon(Icons.access_alarm),
title: "Alarm",
color: Colors.deepPurple,
vsync: this
),
new NavigationIconView(
activeIcon: new CustomIcon(),
icon: new CustomInactiveIcon(),
title: "Box",
color: Colors.deepOrange,
vsync: this
),
new NavigationIconView(
activeIcon: new Icon(Icons.cloud),
icon: new Icon(Icons.cloud_queue),
title: "Cloud",
color: Colors.teal,
vsync: this
),
new NavigationIconView(
activeIcon: new Icon(Icons.favorite),
icon: new Icon(Icons.favorite_border),
title: "Favorites",
color: Colors.indigo,
vsync: this
),
new NavigationIconView(
icon: new Icon(Icons.event_available),
title: "Event",
color: Colors.pink,
vsync: this
)
};
this._navigationViews[this._currentIndex].controller.setValue(1.0f);
}
public override void dispose() {
foreach (NavigationIconView view in this._navigationViews) {
view.controller.dispose();
}
base.dispose();
}
Widget _buildTransitionsStack() {
List<FadeTransition> transitions = new List<FadeTransition> { };
foreach (NavigationIconView view in this._navigationViews) {
transitions.Add(view.transition(this._type, this.context));
}
transitions.Sort((FadeTransition a, FadeTransition b) => {
Animation<float> aAnimation = a.opacity;
Animation<float> bAnimation = b.opacity;
float aValue = aAnimation.value;
float bValue = bAnimation.value;
return aValue.CompareTo(bValue);
});
return new Stack(children: transitions.Select<FadeTransition, Widget>(w => w).ToList());
}
public override Widget build(BuildContext context) {
BottomNavigationBar botNavBar = new BottomNavigationBar(
items: this._navigationViews.Select((NavigationIconView navigationView) => navigationView.item)
.ToList(),
currentIndex: this._currentIndex,
type: this._type,
onTap: (int index) => {
this.setState(() => {
this._navigationViews[this._currentIndex].controller.reverse();
this._currentIndex = index;
this._navigationViews[this._currentIndex].controller.forward();
});
}
);
return new Scaffold(
appBar: new AppBar(
title: new Text("Bottom navigation"),
actions: new List<Widget> {
new MaterialDemoDocumentationButton(BottomNavigationDemo.routeName),
new PopupMenuButton<BottomNavigationBarType>(
onSelected: (BottomNavigationBarType value) => {
this.setState(() => { this._type = value; });
},
itemBuilder: (BuildContext _context) => new List<PopupMenuEntry<BottomNavigationBarType>> {
new PopupMenuItem<BottomNavigationBarType>(
value: BottomNavigationBarType.fix,
child: new Text("Fixed")
),
new PopupMenuItem<BottomNavigationBarType>(
value: BottomNavigationBarType.shifting,
child: new Text("Shifting")
)
}
)
}
),
body: new Center(
child: this._buildTransitionsStack()
),
bottomNavigationBar: botNavBar
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs.meta


fileFormatVersion: 2
guid: d279028b09c04c2b8ab3fba122868004
timeCreated: 1553221768

217
Samples/UIWidgetsGallery/demo/material/cards_demo.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using Image = Unity.UIWidgets.widgets.Image;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsGallery.gallery {
class CardsDemoConstants {
public static readonly List<TravelDestination> destinations = new List<TravelDestination> {
new TravelDestination(
assetName: "india_thanjavur_market",
title: "Top 10 Cities to Visit in Tamil Nadu",
description: new List<string> {
"Number 10",
"Thanjavur",
"Thanjavur, Tamil Nadu"
}
),
new TravelDestination(
assetName: "india_chettinad_silk_maker",
title: "Artisans of Southern India",
description: new List<string> {
"Silk Spinners",
"Chettinad",
"Sivaganga, Tamil Nadu"
}
)
};
}
public class TravelDestination {
public TravelDestination(
string assetName = null,
string title = null,
List<string> description = null
) {
this.assetName = assetName;
this.title = title;
this.description = description;
}
public readonly string assetName;
public readonly string title;
public readonly List<string> description;
public bool isValid {
get { return this.assetName != null && this.title != null && this.description?.Count == 3; }
}
}
public class TravelDestinationItem : StatelessWidget {
public TravelDestinationItem(Key key = null, TravelDestination destination = null, ShapeBorder shape = null)
: base(key: key) {
D.assert(destination != null && destination.isValid);
this.destination = destination;
this.shape = shape;
}
public const float height = 366.0f;
public readonly TravelDestination destination;
public readonly ShapeBorder shape;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
TextStyle titleStyle = theme.textTheme.headline.copyWith(color: Colors.white);
TextStyle descriptionStyle = theme.textTheme.subhead;
return new SafeArea(
top: false,
bottom: false,
child: new Container(
padding: EdgeInsets.all(8.0f),
height: height,
child: new Card(
shape: this.shape,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget> {
new SizedBox(
height: 184.0f,
child: new Stack(
children: new List<Widget> {
Positioned.fill(
child: Image.asset(this.destination.assetName,
fit: BoxFit.cover
)
),
new Positioned(
bottom: 16.0f,
left: 16.0f,
right: 16.0f,
child: new FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: new Text(this.destination.title,
style: titleStyle
)
)
)
}
)
),
new Expanded(
child: new Padding(
padding: EdgeInsets.fromLTRB(16.0f, 16.0f, 16.0f, 0.0f),
child: new DefaultTextStyle(
softWrap: false,
overflow: TextOverflow.ellipsis,
style: descriptionStyle,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget> {
new Padding(
padding: EdgeInsets.only(bottom: 8.0f),
child: new Text(this.destination.description[0],
style: descriptionStyle.copyWith(color: Colors.black54)
)
),
new Text(this.destination.description[1]),
new Text(this.destination.description[2])
}
)
)
)
),
ButtonTheme.bar(
child: new ButtonBar(
alignment: MainAxisAlignment.start,
children: new List<Widget> {
new FlatButton(
child: new Text("SHARE"),
textColor: Colors.amber.shade500,
onPressed: () => {
/* do nothing */
}
),
new FlatButton(
child: new Text("EXPLORE"),
textColor: Colors.amber.shade500,
onPressed: () => {
/* do nothing */
}
)
}
)
),
}
)
)
)
);
}
}
public class CardsDemo : StatefulWidget {
public const string routeName = "/material/cards";
public override State createState() {
return new _CardsDemoState();
}
}
class _CardsDemoState : State<CardsDemo> {
ShapeBorder _shape;
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Travel stream"),
actions: new List<Widget> {
new MaterialDemoDocumentationButton(CardsDemo.routeName),
new IconButton(
icon: new Icon(
Icons.sentiment_very_satisfied
),
onPressed: () => {
this.setState(() => {
this._shape = this._shape != null
? null
: new RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0f),
topRight: Radius.circular(16.0f),
bottomLeft: Radius.circular(2.0f),
bottomRight: Radius.circular(2.0f)
)
);
});
}
)
}
),
body: new ListView(
itemExtent: TravelDestinationItem.height,
padding: EdgeInsets.only(top: 8.0f, left: 8.0f, right: 8.0f),
children: CardsDemoConstants.destinations.Select<TravelDestination, Widget>(
(TravelDestination destination) => {
return new Container(
margin: EdgeInsets.only(bottom: 8.0f),
child: new TravelDestinationItem(
destination: destination,
shape: this._shape
)
);
}).ToList()
)
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/cards_demo.cs.meta


fileFormatVersion: 2
guid: f199ea32d87544c892f57b8af0fcbb03
timeCreated: 1553136548

1001
Tests/Resources/india_chettinad_silk_maker.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/india_chettinad_silk_maker.png.meta


fileFormatVersion: 2
guid: 759295bbc368246a0877963ba053ed5d
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/india_thanjavur_market.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/india_thanjavur_market.png.meta


fileFormatVersion: 2
guid: 69711c649948f4cb1ad20b82f1926a29
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

8
Tests/Resources/products.meta


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

1001
Tests/Resources/products/backpack.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/products/backpack.png.meta


fileFormatVersion: 2
guid: 674a904c9f4234b9ba9f78eb37f237fe
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/products/belt.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/products/belt.png.meta


fileFormatVersion: 2
guid: 8a6d8f5795ade4d2abc66cd64533f8ac
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

406
Tests/Resources/products/cup.png

之前 之后
宽度: 672  |  高度: 672  |  大小: 106 KiB

88
Tests/Resources/products/cup.png.meta


fileFormatVersion: 2
guid: 7443ec2c33a954d6ea65634db88ec9de
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/products/deskset.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/products/deskset.png.meta


fileFormatVersion: 2
guid: 9181044e6c0c4467b933708e3834f35e
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

702
Tests/Resources/products/dress.png

之前 之后
宽度: 660  |  高度: 660  |  大小: 215 KiB

88
Tests/Resources/products/dress.png.meta


fileFormatVersion: 2
guid: 452e42b2f60134df48d45ab49a21d8ec
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/products/earrings.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/products/earrings.png.meta


fileFormatVersion: 2
guid: 7619ea1564ba546ab91b5f0ab38a9f6b
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

408
Tests/Resources/products/flatwear.png

之前 之后
宽度: 672  |  高度: 672  |  大小: 110 KiB

88
Tests/Resources/products/flatwear.png.meta


fileFormatVersion: 2
guid: 2a94339103e7e40219169f13b5ce7013
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

852
Tests/Resources/products/hat.png

之前 之后
宽度: 741  |  高度: 741  |  大小: 224 KiB

88
Tests/Resources/products/hat.png.meta


fileFormatVersion: 2
guid: 1c9bf8d4be2ec4909968b137cca6a5a5
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

702
Tests/Resources/products/jacket.png

之前 之后
宽度: 658  |  高度: 658  |  大小: 226 KiB

88
Tests/Resources/products/jacket.png.meta


fileFormatVersion: 2
guid: 39dfc9119bacf4b85b0d265fae8a101f
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

676
Tests/Resources/products/jumper.png

之前 之后
宽度: 663  |  高度: 663  |  大小: 194 KiB

88
Tests/Resources/products/jumper.png.meta


fileFormatVersion: 2
guid: 4de6e7bd13cc942acaf79ea01980376e
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/products/kitchen_quattro.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/products/kitchen_quattro.png.meta


fileFormatVersion: 2
guid: d02d7a685bb6643ab841d43ee08037a1
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/products/napkins.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/products/napkins.png.meta


fileFormatVersion: 2
guid: 2cfec1ff4da1c4180a77badc07700991
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

984
Tests/Resources/products/planters.png

之前 之后
宽度: 675  |  高度: 675  |  大小: 266 KiB

88
Tests/Resources/products/planters.png.meta


fileFormatVersion: 2
guid: d6cfe1d64e50b4921b6127378911cf72
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

908
Tests/Resources/products/platter.png

之前 之后
宽度: 896  |  高度: 672  |  大小: 245 KiB

88
Tests/Resources/products/platter.png.meta


fileFormatVersion: 2
guid: 5670aeff677b64088bebe4eca1226f4d
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/products/scarf.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/products/scarf.png.meta


fileFormatVersion: 2
guid: cbceefcfd006d450c82769c232fc553e
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

808
Tests/Resources/products/shirt.png

之前 之后
宽度: 662  |  高度: 662  |  大小: 253 KiB

88
Tests/Resources/products/shirt.png.meta


fileFormatVersion: 2
guid: 62306f72bb1ce45babf84b36b72a517c
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

360
Tests/Resources/products/sunnies.png

之前 之后
宽度: 672  |  高度: 672  |  大小: 102 KiB

88
Tests/Resources/products/sunnies.png.meta


fileFormatVersion: 2
guid: 86fa61eb0c5b14c9380cc7996cc0eb05
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

807
Tests/Resources/products/sweater.png

之前 之后
宽度: 658  |  高度: 658  |  大小: 228 KiB

88
Tests/Resources/products/sweater.png.meta


fileFormatVersion: 2
guid: 62ba7ebbec25c471daaf40bb55f357ad
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

967
Tests/Resources/products/sweats.png

之前 之后
宽度: 660  |  高度: 660  |  大小: 273 KiB

88
Tests/Resources/products/sweats.png.meta


fileFormatVersion: 2
guid: 2c1f449cb818546b6aac2487bf16ea91
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

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

正在加载...
取消
保存