浏览代码

Merge pull request #86 from UnityTech/yczhang

Set antiAliasing, fix ShrineDemo, implement GridView ReorderableListView RefreshIndicator UserAccountsDrawerHeader.
/main
GitHub 6 年前
当前提交
0c130835
共有 23 个文件被更改,包括 2066 次插入26 次删除
  1. 2
      Editor/UIWidgetsPanelEditor.cs
  2. 8
      Runtime/editor/editor_window.cs
  3. 1
      Runtime/editor/rasterizer.cs
  4. 27
      Runtime/editor/surface.cs
  5. 13
      Runtime/engine/UIWidgetsPanel.cs
  6. 1
      Runtime/flow/compositor_context.cs
  7. 11
      Runtime/flow/raster_cache.cs
  8. 2
      Runtime/gestures/multidrag.cs
  9. 12
      Runtime/ui/painting/canvas_impl.cs
  10. 8
      Runtime/ui/window.cs
  11. 2
      Runtime/widgets/navigator.cs
  12. 329
      Runtime/widgets/scroll_view.cs
  13. 2
      Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs
  14. 6
      Tests/Editor/CanvasAndLayers.cs
  15. 387
      Runtime/material/refresh_indicator.cs
  16. 3
      Runtime/material/refresh_indicator.cs.meta
  17. 397
      Runtime/material/reorderable_list.cs
  18. 3
      Runtime/material/reorderable_list.cs.meta
  19. 348
      Runtime/material/user_accounts_drawer_header.cs
  20. 3
      Runtime/material/user_accounts_drawer_header.cs.meta
  21. 520
      Runtime/widgets/overscroll_indicator.cs
  22. 3
      Runtime/widgets/overscroll_indicator.cs.meta
  23. 4
      .DS_Store

2
Editor/UIWidgetsPanelEditor.cs


public override void OnInspectorGUI() {
base.OnInspectorGUI();
var pixelRatioProperty = this.serializedObject.FindProperty("devicePixelRatioOverride");
var antiAliasingProperty = this.serializedObject.FindProperty("antiAliasingOverride");
EditorGUILayout.PropertyField(antiAliasingProperty);
this.serializedObject.ApplyModifiedProperties();
}
}

8
Runtime/editor/editor_window.cs


protected override float queryDevicePixelRatio() {
return EditorGUIUtility.pixelsPerPoint;
}
protected override int queryAntiAliasing() {
return Window.defaultAntiAliasing;
}
protected override Vector2 queryWindowSize() {
return this.editorWindow.position.size;

public void OnEnable() {
this._devicePixelRatio = this.queryDevicePixelRatio();
this._antiAliasing = this.queryAntiAliasing();
var size = this.queryWindowSize();
this._lastWindowWidth = size.x;
this._lastWindowHeight = size.y;

}
protected abstract float queryDevicePixelRatio();
protected abstract int queryAntiAliasing();
return new EditorWindowSurface();
return new EditorWindowSurface(antiAliasing: this.antiAliasing);
}
void _beginFrame() {

1
Runtime/editor/rasterizer.cs


using System;
using Unity.UIWidgets.flow;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.editor {
public class Rasterizer {

27
Runtime/editor/surface.cs


SurfaceFrame acquireFrame(Size size, float devicePixelRatio);
MeshPool getMeshPool();
int getAntiAliasing();
}
public class EditorWindowSurface : Surface {

GrSurface _surface;
readonly DrawToTargetFunc _drawToTargetFunc;
MeshPool _meshPool = new MeshPool();
int _antiAliasing;
public EditorWindowSurface(DrawToTargetFunc drawToTargetFunc = null) {
public int getAntiAliasing() {
return this._antiAliasing;
}
public EditorWindowSurface(DrawToTargetFunc drawToTargetFunc = null, int antiAliasing = Window.defaultAntiAliasing) {
this._antiAliasing = antiAliasing;
}
public SurfaceFrame acquireFrame(Size size, float devicePixelRatio) {

this._surface = null;
}
this._surface = new GrSurface(size, devicePixelRatio, this._meshPool);
this._surface = new GrSurface(size, devicePixelRatio, this._meshPool, this._antiAliasing);
}
}

CommandBufferCanvas _canvas;
int _antiAliasing;
public int getAntiAliasing() {
return this._antiAliasing;
}
public RenderTexture getRenderTexture() {
return this._renderTexture;
}

this._canvas = new CommandBufferCanvas(
this._renderTexture, this.devicePixelRatio, this._meshPool);
this._renderTexture, this.devicePixelRatio, this._meshPool, this._antiAliasing);
public GrSurface(Size size, float devicePixelRatio, MeshPool meshPool) {
public GrSurface(Size size, float devicePixelRatio, MeshPool meshPool, int antiAliasing = Window.defaultAntiAliasing) {
this._antiAliasing = antiAliasing;
var desc = new RenderTextureDescriptor(
(int) this.size.width, (int) this.size.height,

};
if (QualitySettings.antiAliasing != 0) {
desc.msaaSamples = QualitySettings.antiAliasing;
if (antiAliasing != 0) {
desc.msaaSamples = antiAliasing;
}
this._renderTexture = new RenderTexture(desc);

13
Runtime/engine/UIWidgetsPanel.cs


}
protected override Surface createSurface() {
return new EditorWindowSurface(this._uiWidgetsPanel.applyRenderTexture);
return new EditorWindowSurface(this._uiWidgetsPanel.applyRenderTexture, this._antiAliasing);
}
public override GUIContent titleContent {

protected override float queryDevicePixelRatio() {
return this._uiWidgetsPanel.devicePixelRatio;
}
protected override int queryAntiAliasing() {
return this._uiWidgetsPanel.antiAliasing;
}
protected override Vector2 queryWindowSize() {

static Event _repaintEvent;
[SerializeField] protected float devicePixelRatioOverride;
[SerializeField] protected int antiAliasingOverride = Window.defaultAntiAliasing;
WindowAdapter _windowAdapter;
Texture _texture;
Vector2 _lastMouseMove;

return this.devicePixelRatioOverride > 0
? this.devicePixelRatioOverride
: this._displayMetrics.devicePixelRatio;
}
}
public int antiAliasing {
get {
return this.antiAliasingOverride >= 0 ? this.antiAliasingOverride : Window.defaultAntiAliasing;
}
}

1
Runtime/flow/compositor_context.cs


public void onGrContextCreated(Surface surface) {
this._rasterCache.clear();
this._rasterCache.meshPool = surface.getMeshPool();
this._rasterCache.antiAliasing = surface.getAntiAliasing();
}
public void onGrContextDestroyed() {

11
Runtime/flow/raster_cache.cs


MeshPool _meshPool;
public int antiAliasing {
set { this._antiAliasing = value; }
}
int _antiAliasing = Window.defaultAntiAliasing;
public MeshPool meshPool {
set { this._meshPool = value; }
}

autoGenerateMips = false,
};
if (QualitySettings.antiAliasing != 0) {
desc.msaaSamples = QualitySettings.antiAliasing;
if (this._antiAliasing != 0) {
desc.msaaSamples = this._antiAliasing;
var canvas = new CommandBufferCanvas(renderTexture, devicePixelRatio, meshPool);
var canvas = new CommandBufferCanvas(renderTexture, devicePixelRatio, meshPool, this._antiAliasing);
canvas.translate(-bounds.left, -bounds.top);
canvas.concat(transform);
canvas.drawPicture(picture);

2
Runtime/gestures/multidrag.cs


TimeSpan? delay = null)
: base(initialPosition) {
D.assert(delay != null);
this._timer = Window.instance.run(delay ?? Constants.kLongPressTimeout, this._delayPassed, true);
this._timer = Window.instance.run(delay ?? Constants.kLongPressTimeout, this._delayPassed, false);
}
Timer _timer;

12
Runtime/ui/painting/canvas_impl.cs


readonly float _fringeWidth;
readonly float _devicePixelRatio;
readonly MeshPool _meshPool;
readonly int _antiAliasing;
public PictureFlusher(RenderTexture renderTexture, float devicePixelRatio, MeshPool meshPool) {
public PictureFlusher(RenderTexture renderTexture, float devicePixelRatio, MeshPool meshPool, int antiAliasing) {
D.assert(renderTexture);
D.assert(devicePixelRatio > 0);
D.assert(meshPool != null);

this._devicePixelRatio = devicePixelRatio;
this._meshPool = meshPool;
this._antiAliasing = antiAliasing;
}
public float getDevicePixelRatio() {

autoGenerateMips = false,
};
if (QualitySettings.antiAliasing != 0) {
desc.msaaSamples = QualitySettings.antiAliasing;
if (this._antiAliasing != 0) {
desc.msaaSamples = this._antiAliasing;
}
cmdBuf.GetTemporaryRT(subLayer.rtID, desc, subLayer.filterMode);

public class CommandBufferCanvas : RecorderCanvas {
readonly PictureFlusher _flusher;
public CommandBufferCanvas(RenderTexture renderTexture, float devicePixelRatio, MeshPool meshPool)
public CommandBufferCanvas(RenderTexture renderTexture, float devicePixelRatio, MeshPool meshPool, int antiAliasing = Window.defaultAntiAliasing)
this._flusher = new PictureFlusher(renderTexture, devicePixelRatio, meshPool);
this._flusher = new PictureFlusher(renderTexture, devicePixelRatio, meshPool, antiAliasing);
}
public override float getDevicePixelRatio() {

8
Runtime/ui/window.cs


internal static Window _instance;
public const int defaultAntiAliasing = 4;
public int antiAliasing {
get { return this._antiAliasing; }
}
protected int _antiAliasing = defaultAntiAliasing;
public Size physicalSize {
get { return this._physicalSize; }

2
Runtime/widgets/navigator.cs


get { return false; }
}
public object currentResult {
public virtual object currentResult {
get { return null; }
}

329
Runtime/widgets/scroll_view.cs


using System;
using com.unity.uiwidgets.Runtime.rendering;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;

base.debugFillProperties(properties);
properties.add(new FloatProperty("itemExtent", this.itemExtent,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
public class GridView : BoxScrollView {
public GridView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
SliverGridDelegate gridDelegate = null,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null,
List<Widget> children = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
D.assert(gridDelegate != null);
this.childrenDelegate = new SliverChildListDelegate(
children ?? new List<Widget>(),
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries
);
}
public GridView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
SliverGridDelegate gridDelegate = null,
IndexedWidgetBuilder itemBuilder = null,
int? itemCount = null,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
this.gridDelegate = gridDelegate;
this.childrenDelegate = new SliverChildBuilderDelegate(
itemBuilder,
childCount: itemCount,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries
);
}
public static GridView builder(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
SliverGridDelegate gridDelegate = null,
IndexedWidgetBuilder itemBuilder = null,
int? itemCount = null,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null
) {
return new GridView(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
gridDelegate: gridDelegate,
itemBuilder: itemBuilder,
itemCount: itemCount,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
cacheExtent: cacheExtent
);
}
public GridView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
SliverGridDelegate gridDelegate = null,
SliverChildDelegate childrenDelegate = null,
float? cacheExtent = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
D.assert(gridDelegate != null);
D.assert(childrenDelegate != null);
this.gridDelegate = gridDelegate;
this.childrenDelegate = childrenDelegate;
}
public static GridView custom(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
SliverGridDelegate gridDelegate = null,
SliverChildDelegate childrenDelegate = null,
float? cacheExtent = null
) {
return new GridView(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
gridDelegate: gridDelegate,
childrenDelegate: childrenDelegate,
cacheExtent: cacheExtent
);
}
public GridView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
int? crossAxisCount = null,
float mainAxisSpacing = 0.0f,
float crossAxisSpacing = 0.0f,
float childAspectRatio = 1.0f,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null,
List<Widget> children = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent
) {
this.gridDelegate = new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount ?? 0,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio
);
this.childrenDelegate = new SliverChildListDelegate(
children ?? new List<Widget>(),
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries
);
}
public static GridView count(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
int? crossAxisCount = null,
float mainAxisSpacing = 0.0f,
float crossAxisSpacing = 0.0f,
float childAspectRatio = 1.0f,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
float? cacheExtent = null,
List<Widget> children = null
) {
return new GridView(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
crossAxisCount: crossAxisCount,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
cacheExtent: cacheExtent,
children: children
);
}
public GridView(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
float? maxCrossAxisExtent = null,
float mainAxisSpacing = 0.0f,
float crossAxisSpacing = 0.0f,
float childAspectRatio = 1.0f,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
List<Widget> children = null
) : base(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding
) {
this.gridDelegate = new SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: maxCrossAxisExtent ?? 0,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio
);
this.childrenDelegate = new SliverChildListDelegate(
children ?? new List<Widget> { },
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries
);
}
public static GridView extent(
Key key = null,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller = null,
bool? primary = null,
ScrollPhysics physics = null,
bool shrinkWrap = false,
EdgeInsets padding = null,
float? maxCrossAxisExtent = null,
float mainAxisSpacing = 0.0f,
float crossAxisSpacing = 0.0f,
float childAspectRatio = 1.0f,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
List<Widget> children = null
) {
return new GridView(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
maxCrossAxisExtent: maxCrossAxisExtent,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
children: children
);
}
public readonly SliverGridDelegate gridDelegate;
public readonly SliverChildDelegate childrenDelegate;
protected override Widget buildChildLayout(BuildContext context) {
return new SliverGrid(
layoutDelegate: this.childrenDelegate,
gridDelegate: this.gridDelegate
);
}
}
}

2
Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs


public Order order;
public new Order currentResult {
public override object currentResult {
get { return this.order; }
}

6
Tests/Editor/CanvasAndLayers.cs


static Texture2D texture6;
int _antiAliasing = Window.defaultAntiAliasing;
CanvasAndLayers() {
this._options = new Action[] {
this.drawPloygon4,

autoGenerateMips = false,
};
if (QualitySettings.antiAliasing != 0) {
desc.msaaSamples = QualitySettings.antiAliasing;
if (this._antiAliasing != 0) {
desc.msaaSamples = this._antiAliasing;
}
this._renderTexture = RenderTexture.GetTemporary(desc);

387
Runtime/material/refresh_indicator.cs


using System;
using System.Collections.Generic;
using RSG;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;
namespace Unity.UIWidgets.material {
class RefreshIndicatorUtils {
public const float _kDragContainerExtentPercentage = 0.25f;
public const float _kDragSizeFactorLimit = 1.5f;
public static readonly TimeSpan _kIndicatorSnapDuration = new TimeSpan(0, 0, 0, 0, 150);
public static readonly TimeSpan _kIndicatorScaleDuration = new TimeSpan(0, 0, 0, 0, 200);
}
public delegate Promise RefreshCallback();
enum _RefreshIndicatorMode {
drag, // Pointer is down.
armed, // Dragged far enough that an up event will run the onRefresh callback.
snap, // Animating to the indicator"s final "displacement".
refresh, // Running the refresh callback.
done, // Animating the indicator"s fade-out after refreshing.
canceled, // Animating the indicator"s fade-out after not arming.
}
public class RefreshIndicator : StatefulWidget {
public RefreshIndicator(
Key key = null,
Widget child = null,
float displacement = 40.0f,
RefreshCallback onRefresh = null,
Color color = null,
Color backgroundColor = null,
ScrollNotificationPredicate notificationPredicate = null
) : base(key: key) {
D.assert(child != null);
D.assert(onRefresh != null);
this.child = child;
this.displacement = displacement;
this.onRefresh = onRefresh;
this.color = color;
this.backgroundColor = backgroundColor;
this.notificationPredicate = notificationPredicate ?? ScrollNotification.defaultScrollNotificationPredicate;
}
public readonly Widget child;
public readonly float displacement;
public readonly RefreshCallback onRefresh;
public readonly Color color;
public readonly Color backgroundColor;
public readonly ScrollNotificationPredicate notificationPredicate;
public override State createState() {
return new RefreshIndicatorState();
}
}
public class RefreshIndicatorState : TickerProviderStateMixin<RefreshIndicator> {
AnimationController _positionController;
AnimationController _scaleController;
Animation<float> _positionFactor;
Animation<float> _scaleFactor;
Animation<float> _value;
Animation<Color> _valueColor;
_RefreshIndicatorMode? _mode;
Promise _pendingRefreshFuture;
bool? _isIndicatorAtTop;
float? _dragOffset;
static readonly Animatable<float> _threeQuarterTween = new FloatTween(begin: 0.0f, end: 0.75f);
static readonly Animatable<float> _kDragSizeFactorLimitTween =
new FloatTween(begin: 0.0f, end: RefreshIndicatorUtils._kDragSizeFactorLimit);
static readonly Animatable<float> _oneToZeroTween = new FloatTween(begin: 1.0f, end: 0.0f);
public RefreshIndicatorState() {
}
public override void initState() {
base.initState();
this._positionController = new AnimationController(vsync: this);
this._positionFactor = this._positionController.drive(_kDragSizeFactorLimitTween);
this._value =
this._positionController
.drive(_threeQuarterTween); // The "value" of the circular progress indicator during a drag.
this._scaleController = new AnimationController(vsync: this);
this._scaleFactor = this._scaleController.drive(_oneToZeroTween);
}
public override void didChangeDependencies() {
ThemeData theme = Theme.of(this.context);
this._valueColor = this._positionController.drive(
new ColorTween(
begin: (this.widget.color ?? theme.accentColor).withOpacity(0.0f),
end: (this.widget.color ?? theme.accentColor).withOpacity(1.0f)
).chain(new CurveTween(
curve: new Interval(0.0f, 1.0f / RefreshIndicatorUtils._kDragSizeFactorLimit)
))
);
base.didChangeDependencies();
}
public override void dispose() {
this._positionController.dispose();
this._scaleController.dispose();
base.dispose();
}
bool _handleScrollNotification(ScrollNotification notification) {
if (!this.widget.notificationPredicate(notification)) {
return false;
}
if (notification is ScrollStartNotification && notification.metrics.extentBefore() == 0.0f &&
this._mode == null && this._start(notification.metrics.axisDirection)) {
this.setState(() => { this._mode = _RefreshIndicatorMode.drag; });
return false;
}
bool? indicatorAtTopNow = null;
switch (notification.metrics.axisDirection) {
case AxisDirection.down:
indicatorAtTopNow = true;
break;
case AxisDirection.up:
indicatorAtTopNow = false;
break;
case AxisDirection.left:
case AxisDirection.right:
indicatorAtTopNow = null;
break;
}
if (indicatorAtTopNow != this._isIndicatorAtTop) {
if (this._mode == _RefreshIndicatorMode.drag || this._mode == _RefreshIndicatorMode.armed) {
this._dismiss(_RefreshIndicatorMode.canceled);
}
}
else if (notification is ScrollUpdateNotification) {
if (this._mode == _RefreshIndicatorMode.drag || this._mode == _RefreshIndicatorMode.armed) {
if (notification.metrics.extentBefore() > 0.0f) {
this._dismiss(_RefreshIndicatorMode.canceled);
}
else {
this._dragOffset -= (notification as ScrollUpdateNotification).scrollDelta;
this._checkDragOffset(notification.metrics.viewportDimension);
}
}
if (this._mode == _RefreshIndicatorMode.armed &&
(notification as ScrollUpdateNotification).dragDetails == null) {
this._show();
}
}
else if (notification is OverscrollNotification) {
if (this._mode == _RefreshIndicatorMode.drag || this._mode == _RefreshIndicatorMode.armed) {
this._dragOffset -= (notification as OverscrollNotification).overscroll / 2.0f;
this._checkDragOffset(notification.metrics.viewportDimension);
}
}
else if (notification is ScrollEndNotification) {
switch (this._mode) {
case _RefreshIndicatorMode.armed:
this._show();
break;
case _RefreshIndicatorMode.drag:
this._dismiss(_RefreshIndicatorMode.canceled);
break;
default:
break;
}
}
return false;
}
bool _handleGlowNotification(OverscrollIndicatorNotification notification) {
if (notification.depth != 0 || !notification.leading) {
return false;
}
if (this._mode == _RefreshIndicatorMode.drag) {
notification.disallowGlow();
return true;
}
return false;
}
bool _start(AxisDirection direction) {
D.assert(this._mode == null);
D.assert(this._isIndicatorAtTop == null);
D.assert(this._dragOffset == null);
switch (direction) {
case AxisDirection.down:
this._isIndicatorAtTop = true;
break;
case AxisDirection.up:
this._isIndicatorAtTop = false;
break;
case AxisDirection.left:
case AxisDirection.right:
this._isIndicatorAtTop = null;
return false;
}
this._dragOffset = 0.0f;
this._scaleController.setValue(0.0f);
this._positionController.setValue(0.0f);
return true;
}
void _checkDragOffset(float containerExtent) {
D.assert(this._mode == _RefreshIndicatorMode.drag || this._mode == _RefreshIndicatorMode.armed);
float? newValue = this._dragOffset /
(containerExtent * RefreshIndicatorUtils._kDragContainerExtentPercentage);
if (this._mode == _RefreshIndicatorMode.armed) {
newValue = Mathf.Max(newValue ?? 0.0f, 1.0f / RefreshIndicatorUtils._kDragSizeFactorLimit);
}
this._positionController.setValue(newValue?.clamp(0.0f, 1.0f) ?? 0.0f); // this triggers various rebuilds
if (this._mode == _RefreshIndicatorMode.drag && this._valueColor.value.alpha == 0xFF) {
this._mode = _RefreshIndicatorMode.armed;
}
}
IPromise _dismiss(_RefreshIndicatorMode newMode) {
D.assert(newMode == _RefreshIndicatorMode.canceled || newMode == _RefreshIndicatorMode.done);
this.setState(() => { this._mode = newMode; });
switch (this._mode) {
case _RefreshIndicatorMode.done:
return this._scaleController
.animateTo(1.0f, duration: RefreshIndicatorUtils._kIndicatorScaleDuration).Then(() => {
if (this.mounted && this._mode == newMode) {
this._dragOffset = null;
this._isIndicatorAtTop = null;
this.setState(() => { this._mode = null; });
}
});
case _RefreshIndicatorMode.canceled:
return this._positionController
.animateTo(0.0f, duration: RefreshIndicatorUtils._kIndicatorScaleDuration).Then(() => {
if (this.mounted && this._mode == newMode) {
this._dragOffset = null;
this._isIndicatorAtTop = null;
this.setState(() => { this._mode = null; });
}
});
default:
throw new Exception("Unknown refresh indicator mode: " + this._mode);
}
}
void _show() {
D.assert(this._mode != _RefreshIndicatorMode.refresh);
D.assert(this._mode != _RefreshIndicatorMode.snap);
Promise completer = new Promise();
this._pendingRefreshFuture = completer;
this._mode = _RefreshIndicatorMode.snap;
this._positionController
.animateTo(1.0f / RefreshIndicatorUtils._kDragSizeFactorLimit,
duration: RefreshIndicatorUtils._kIndicatorSnapDuration)
.Then(() => {
if (this.mounted && this._mode == _RefreshIndicatorMode.snap) {
D.assert(this.widget.onRefresh != null);
this.setState(() => { this._mode = _RefreshIndicatorMode.refresh; });
Promise refreshResult = this.widget.onRefresh();
D.assert(() => {
if (refreshResult == null) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: new UIWidgetsError(
"The onRefresh callback returned null.\n" +
"The RefreshIndicator onRefresh callback must return a Promise."
),
context: "when calling onRefresh",
library: "material library"
));
}
return true;
});
if (refreshResult == null) {
return;
}
refreshResult.Then(() => {
if (this.mounted && this._mode == _RefreshIndicatorMode.refresh) {
completer.Resolve();
this._dismiss(_RefreshIndicatorMode.done);
}
});
}
});
}
Promise show(bool atTop = true) {
if (this._mode != _RefreshIndicatorMode.refresh && this._mode != _RefreshIndicatorMode.snap) {
if (this._mode == null) {
this._start(atTop ? AxisDirection.down : AxisDirection.up);
}
this._show();
}
return this._pendingRefreshFuture;
}
GlobalKey _key = GlobalKey.key();
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
Widget child = new NotificationListener<ScrollNotification>(
key: this._key,
onNotification: this._handleScrollNotification,
child: new NotificationListener<OverscrollIndicatorNotification>(
onNotification: this._handleGlowNotification,
child: this.widget.child
)
);
if (this._mode == null) {
D.assert(this._dragOffset == null);
D.assert(this._isIndicatorAtTop == null);
return child;
}
D.assert(this._dragOffset != null);
D.assert(this._isIndicatorAtTop != null);
bool showIndeterminateIndicator =
this._mode == _RefreshIndicatorMode.refresh || this._mode == _RefreshIndicatorMode.done;
return new Stack(
children: new List<Widget> {
child,
new Positioned(
top: this._isIndicatorAtTop == true ? 0.0f : (float?) null,
bottom: this._isIndicatorAtTop != true ? 0.0f : (float?) null,
left: 0.0f,
right: 0.0f,
child: new SizeTransition(
axisAlignment: this._isIndicatorAtTop == true ? 1.0f : -1.0f,
sizeFactor: this._positionFactor, // this is what brings it down
child: new Container(
padding: this._isIndicatorAtTop == true
? EdgeInsets.only(top: this.widget.displacement)
: EdgeInsets.only(bottom: this.widget.displacement),
alignment: this._isIndicatorAtTop == true
? Alignment.topCenter
: Alignment.bottomCenter,
child: new ScaleTransition(
scale: this._scaleFactor,
child: new AnimatedBuilder(
animation: this._positionController,
builder: (BuildContext _context, Widget _child) => {
return new RefreshProgressIndicator(
value: showIndeterminateIndicator ? (float?) null : this._value.value,
valueColor: this._valueColor,
backgroundColor: this.widget.backgroundColor
);
}
)
)
)
)
)
}
);
}
}
}

3
Runtime/material/refresh_indicator.cs.meta


fileFormatVersion: 2
guid: 74dd879101fe4541a5b42619cf4f309c
timeCreated: 1554344854

397
Runtime/material/reorderable_list.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.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
namespace Unity.UIWidgets.material {
public delegate void ReorderCallback(int oldIndex, int newIndex);
public class ReorderableListView : StatefulWidget {
public ReorderableListView(
Widget header = null,
List<Widget> children = null,
ReorderCallback onReorder = null,
Axis scrollDirection = Axis.vertical,
EdgeInsets padding = null
) {
D.assert(onReorder != null);
D.assert(children != null);
D.assert(
children.All((Widget w) => w.key != null),
"All children of this widget must have a key."
);
this.header = header;
this.children = children;
this.scrollDirection = scrollDirection;
this.padding = padding;
this.onReorder = onReorder;
}
public readonly Widget header;
public readonly List<Widget> children;
public readonly Axis scrollDirection;
public readonly EdgeInsets padding;
public readonly ReorderCallback onReorder;
public override State createState() {
return new _ReorderableListViewState();
}
}
class _ReorderableListViewState : State<ReorderableListView> {
GlobalKey _overlayKey = GlobalKey.key(debugLabel: "$ReorderableListView overlay key");
OverlayEntry _listOverlayEntry;
public override void initState() {
base.initState();
this._listOverlayEntry = new OverlayEntry(
opaque: true,
builder: (BuildContext context) => {
return new _ReorderableListContent(
header: this.widget.header,
children: this.widget.children,
scrollDirection: this.widget.scrollDirection,
onReorder: this.widget.onReorder,
padding: this.widget.padding
);
}
);
}
public override Widget build(BuildContext context) {
return new Overlay(
key: this._overlayKey,
initialEntries: new List<OverlayEntry> {
this._listOverlayEntry
});
}
}
class _ReorderableListContent : StatefulWidget {
public _ReorderableListContent(
Widget header,
List<Widget> children,
Axis scrollDirection,
EdgeInsets padding,
ReorderCallback onReorder
) {
this.header = header;
this.children = children;
this.scrollDirection = scrollDirection;
this.padding = padding;
this.onReorder = onReorder;
}
public readonly Widget header;
public readonly List<Widget> children;
public readonly Axis scrollDirection;
public readonly EdgeInsets padding;
public readonly ReorderCallback onReorder;
public override State createState() {
return new _ReorderableListContentState();
}
}
class _ReorderableListContentState : TickerProviderStateMixin<_ReorderableListContent> {
const float _defaultDropAreaExtent = 100.0f;
const float _dropAreaMargin = 8.0f;
readonly TimeSpan _reorderAnimationDuration = new TimeSpan(0, 0, 0, 0, 200);
readonly TimeSpan _scrollAnimationDuration = new TimeSpan(0, 0, 0, 0, 200);
ScrollController _scrollController;
AnimationController _entranceController;
AnimationController _ghostController;
Key _dragging;
Size _draggingFeedbackSize;
int _dragStartIndex = 0;
int _ghostIndex = 0;
int _currentIndex = 0;
int _nextIndex = 0;
bool _scrolling = false;
float _dropAreaExtent {
get {
if (this._draggingFeedbackSize == null) {
return _defaultDropAreaExtent;
}
float dropAreaWithoutMargin;
switch (this.widget.scrollDirection) {
case Axis.horizontal:
dropAreaWithoutMargin = this._draggingFeedbackSize.width;
break;
case Axis.vertical:
default:
dropAreaWithoutMargin = this._draggingFeedbackSize.height;
break;
}
return dropAreaWithoutMargin + _dropAreaMargin;
}
}
public override void initState() {
base.initState();
this._entranceController = new AnimationController(vsync: this, duration: this._reorderAnimationDuration);
this._ghostController = new AnimationController(vsync: this, duration: this._reorderAnimationDuration);
this._entranceController.addStatusListener(this._onEntranceStatusChanged);
}
public override void didChangeDependencies() {
this._scrollController = PrimaryScrollController.of(this.context) ?? new ScrollController();
base.didChangeDependencies();
}
public override void dispose() {
this._entranceController.dispose();
this._ghostController.dispose();
base.dispose();
}
void _requestAnimationToNextIndex() {
if (this._entranceController.isCompleted) {
this._ghostIndex = this._currentIndex;
if (this._nextIndex == this._currentIndex) {
return;
}
this._currentIndex = this._nextIndex;
this._ghostController.reverse(from: 1.0f);
this._entranceController.forward(from: 0.0f);
}
}
void _onEntranceStatusChanged(AnimationStatus status) {
if (status == AnimationStatus.completed) {
this.setState(() => { this._requestAnimationToNextIndex(); });
}
}
void _scrollTo(BuildContext context) {
if (this._scrolling) {
return;
}
RenderObject contextObject = context.findRenderObject();
RenderAbstractViewport viewport = RenderViewportUtils.of(contextObject);
D.assert(viewport != null);
float margin = this._dropAreaExtent;
float scrollOffset = this._scrollController.offset;
float topOffset = Mathf.Max(this._scrollController.position.minScrollExtent,
viewport.getOffsetToReveal(contextObject, 0.0f).offset - margin
);
float bottomOffset = Mathf.Min(this._scrollController.position.maxScrollExtent,
viewport.getOffsetToReveal(contextObject, 1.0f).offset + margin
);
bool onScreen = scrollOffset <= topOffset && scrollOffset >= bottomOffset;
if (!onScreen) {
this._scrolling = true;
this._scrollController.position.animateTo(
scrollOffset < bottomOffset ? bottomOffset : topOffset,
duration: this._scrollAnimationDuration,
curve: Curves.easeInOut
).Then(() => { this.setState(() => { this._scrolling = false; }); });
}
}
Widget _buildContainerForScrollDirection(List<Widget> children = null) {
switch (this.widget.scrollDirection) {
case Axis.horizontal:
return new Row(children: children);
case Axis.vertical:
default:
return new Column(children: children);
}
}
Widget _wrap(Widget toWrap, int index, BoxConstraints constraints) {
D.assert(toWrap.key != null);
GlobalObjectKey<State<_ReorderableListContent>> keyIndexGlobalKey = new GlobalObjectKey<State<_ReorderableListContent>>(toWrap.key);
void onDragStarted() {
this.setState(() => {
this._dragging = toWrap.key;
this._dragStartIndex = index;
this._ghostIndex = index;
this._currentIndex = index;
this._entranceController.setValue(1.0f);
this._draggingFeedbackSize = keyIndexGlobalKey.currentContext.size;
});
}
void reorder(int startIndex, int endIndex) {
this.setState(() => {
if (startIndex != endIndex) {
this.widget.onReorder(startIndex, endIndex);
}
this._ghostController.reverse(from: 0.1f);
this._entranceController.reverse(from: 0.1f);
this._dragging = null;
});
}
void onDragEnded() {
reorder(this._dragStartIndex, this._currentIndex);
}
Widget wrapWithKeyedSubtree() {
return new KeyedSubtree(
key: keyIndexGlobalKey,
child: toWrap
);
}
Widget buildDragTarget(BuildContext context, List<Key> acceptedCandidates, List<Key> rejectedCandidates) {
Widget toWrapWithKeyedSubtree = wrapWithKeyedSubtree();
Widget child = new LongPressDraggable<Key>(
maxSimultaneousDrags: 1,
axis: this.widget.scrollDirection,
data: toWrap.key,
feedback: new Container(
alignment: Alignment.topLeft,
// These constraints will limit the cross axis of the drawn widget.
constraints: constraints,
child: new Material(
elevation: 6.0f,
child: toWrapWithKeyedSubtree
)
),
child: this._dragging == toWrap.key ? new SizedBox() : toWrapWithKeyedSubtree,
childWhenDragging: new SizedBox(),
dragAnchor: DragAnchor.child,
onDragStarted: onDragStarted,
onDragCompleted: onDragEnded,
onDraggableCanceled: (Velocity velocity, Offset offset) => { onDragEnded(); }
);
if (index >= this.widget.children.Count) {
child = toWrap;
}
Widget spacing;
switch (this.widget.scrollDirection) {
case Axis.horizontal:
spacing = new SizedBox(width: this._dropAreaExtent);
break;
case Axis.vertical:
default:
spacing = new SizedBox(height: this._dropAreaExtent);
break;
}
if (this._currentIndex == index) {
return this._buildContainerForScrollDirection(children: new List<Widget> {
new SizeTransition(
sizeFactor: this._entranceController,
axis: this.widget.scrollDirection,
child: spacing
),
child
});
}
if (this._ghostIndex == index) {
return this._buildContainerForScrollDirection(children: new List<Widget> {
new SizeTransition(
sizeFactor: this._ghostController,
axis: this.widget.scrollDirection,
child: spacing
),
child
});
}
return child;
}
return new Builder(builder: (BuildContext context) => {
return new DragTarget<Key>(
builder: buildDragTarget,
onWillAccept: (Key toAccept) => {
this.setState(() => {
this._nextIndex = index;
this._requestAnimationToNextIndex();
});
this._scrollTo(context);
return this._dragging == toAccept && toAccept != toWrap.key;
},
onAccept: (Key accepted) => { },
onLeave: (Key leaving) => { }
);
});
}
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
return new LayoutBuilder(builder: (BuildContext _, BoxConstraints constraints) => {
List<Widget> wrappedChildren = new List<Widget> { };
if (this.widget.header != null) {
wrappedChildren.Add(this.widget.header);
}
for (int i = 0; i < this.widget.children.Count; i += 1) {
wrappedChildren.Add(this._wrap(this.widget.children[i], i, constraints));
}
Key endWidgetKey = Key.key("DraggableList - End Widget");
Widget finalDropArea;
switch (this.widget.scrollDirection) {
case Axis.horizontal:
finalDropArea = new SizedBox(
key: endWidgetKey,
width: _defaultDropAreaExtent,
height: constraints.maxHeight
);
break;
case Axis.vertical:
default:
finalDropArea = new SizedBox(
key: endWidgetKey,
height: _defaultDropAreaExtent,
width: constraints.maxWidth
);
break;
}
wrappedChildren.Add(this._wrap(
finalDropArea, this.widget.children.Count,
constraints)
);
return new SingleChildScrollView(
scrollDirection: this.widget.scrollDirection,
child: this._buildContainerForScrollDirection(children: wrappedChildren),
padding: this.widget.padding,
controller: this._scrollController
);
});
}
}
}

3
Runtime/material/reorderable_list.cs.meta


fileFormatVersion: 2
guid: 730da7185538491389639e2cc7099a21
timeCreated: 1554301017

348
Runtime/material/user_accounts_drawer_header.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.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Transform = Unity.UIWidgets.widgets.Transform;
namespace Unity.UIWidgets.material {
class UserAccountsDrawerHeaderUtils {
public const float _kAccountDetailsHeight = 56.0f;
}
class _AccountPictures : StatelessWidget {
public _AccountPictures(
Key key = null,
Widget currentAccountPicture = null,
List<Widget> otherAccountsPictures = null
) : base(key: key) {
this.currentAccountPicture = currentAccountPicture;
this.otherAccountsPictures = otherAccountsPictures;
}
public readonly Widget currentAccountPicture;
public readonly List<Widget> otherAccountsPictures;
public override Widget build(BuildContext context) {
return new Stack(
children: new List<Widget> {
new Positioned(
top: 0.0f,
right: 0.0f,
child: new Row(
children: (this.otherAccountsPictures ?? new List<Widget> { })
.GetRange(0, Math.Min(3, this.otherAccountsPictures?.Count ?? 0))
.Select<Widget, Widget>(
(Widget picture) => {
return new Padding(
padding: EdgeInsets.only(left: 8.0f),
child: new Container(
padding: EdgeInsets.only(left: 8.0f, bottom: 8.0f),
width: 48.0f,
height: 48.0f,
child: picture
)
);
}).ToList()
)
),
new Positioned(
top: 0.0f,
child: new SizedBox(
width: 72.0f,
height: 72.0f,
child: this.currentAccountPicture
)
)
}
);
}
}
class _AccountDetails : StatefulWidget {
public _AccountDetails(
Key key = null,
Widget accountName = null,
Widget accountEmail = null,
VoidCallback onTap = null,
bool? isOpen = null
) : base(key: key) {
D.assert(accountName != null);
D.assert(accountEmail != null);
this.accountName = accountName;
this.accountEmail = accountEmail;
this.onTap = onTap;
this.isOpen = isOpen;
}
public readonly Widget accountName;
public readonly Widget accountEmail;
public readonly VoidCallback onTap;
public readonly bool? isOpen;
public override State createState() {
return new _AccountDetailsState();
}
}
class _AccountDetailsState : SingleTickerProviderStateMixin<_AccountDetails> {
Animation<float> _animation;
AnimationController _controller;
public override void initState() {
base.initState();
this._controller = new AnimationController(
value: this.widget.isOpen == true ? 1.0f : 0.0f,
duration: new TimeSpan(0, 0, 0, 0, 200),
vsync: this
);
this._animation = new CurvedAnimation(
parent: this._controller,
curve: Curves.fastOutSlowIn,
reverseCurve: Curves.fastOutSlowIn.flipped
);
this._animation.addListener(() => this.setState(() => { }));
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
base.didUpdateWidget(_oldWidget);
_AccountDetails oldWidget = _oldWidget as _AccountDetails;
if (this._animation.status == AnimationStatus.dismissed ||
this._animation.status == AnimationStatus.reverse) {
this._controller.forward();
}
else {
this._controller.reverse();
}
}
public override Widget build(BuildContext context) {
D.assert(WidgetsD.debugCheckHasDirectionality(context));
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
ThemeData theme = Theme.of(context);
List<Widget> children = new List<Widget> { };
if (this.widget.accountName != null) {
Widget accountNameLine = new LayoutId(
id: _AccountDetailsLayout.accountName,
child: new Padding(
padding: EdgeInsets.symmetric(vertical: 2.0f),
child: new DefaultTextStyle(
style: theme.primaryTextTheme.body2,
overflow: TextOverflow.ellipsis,
child: this.widget.accountName
)
)
);
children.Add(accountNameLine);
}
if (this.widget.accountEmail != null) {
Widget accountEmailLine = new LayoutId(
id: _AccountDetailsLayout.accountEmail,
child: new Padding(
padding: EdgeInsets.symmetric(vertical: 2.0f),
child: new DefaultTextStyle(
style: theme.primaryTextTheme.body1,
overflow: TextOverflow.ellipsis,
child: this.widget.accountEmail
)
)
);
children.Add(accountEmailLine);
}
if (this.widget.onTap != null) {
MaterialLocalizations localizations = MaterialLocalizations.of(context);
Widget dropDownIcon = new LayoutId(
id: _AccountDetailsLayout.dropdownIcon,
child: new SizedBox(
height: UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
width: UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
child: new Center(
child: Transform.rotate(
degree: this._animation.value * Mathf.PI,
child: new Icon(
Icons.arrow_drop_down,
color: Colors.white
)
)
)
)
);
children.Add(dropDownIcon);
}
Widget accountDetails = new CustomMultiChildLayout(
layoutDelegate: new _AccountDetailsLayout(),
children: children
);
if (this.widget.onTap != null) {
accountDetails = new InkWell(
onTap: this.widget.onTap == null ? (GestureTapCallback) null : () => { this.widget.onTap(); },
child: accountDetails
);
}
return new SizedBox(
height: UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
child: accountDetails
);
}
}
class _AccountDetailsLayout : MultiChildLayoutDelegate {
public _AccountDetailsLayout() {
}
public const string accountName = "accountName";
public const string accountEmail = "accountEmail";
public const string dropdownIcon = "dropdownIcon";
public override void performLayout(Size size) {
Size iconSize = null;
if (this.hasChild(dropdownIcon)) {
iconSize = this.layoutChild(dropdownIcon, BoxConstraints.loose(size));
this.positionChild(dropdownIcon, this._offsetForIcon(size, iconSize));
}
string bottomLine = this.hasChild(accountEmail)
? accountEmail
: (this.hasChild(accountName) ? accountName : null);
if (bottomLine != null) {
Size constraintSize = iconSize == null ? size : size - new Offset(iconSize.width, 0.0f);
iconSize = iconSize ?? new Size(UserAccountsDrawerHeaderUtils._kAccountDetailsHeight,
UserAccountsDrawerHeaderUtils._kAccountDetailsHeight);
Size bottomLineSize = this.layoutChild(bottomLine, BoxConstraints.loose(constraintSize));
Offset bottomLineOffset = this._offsetForBottomLine(size, iconSize, bottomLineSize);
this.positionChild(bottomLine, bottomLineOffset);
if (bottomLine == accountEmail && this.hasChild(accountName)) {
Size nameSize = this.layoutChild(accountName, BoxConstraints.loose(constraintSize));
this.positionChild(accountName, this._offsetForName(size, nameSize, bottomLineOffset));
}
}
}
public override bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) {
return true;
}
Offset _offsetForIcon(Size size, Size iconSize) {
return new Offset(size.width - iconSize.width, size.height - iconSize.height);
}
Offset _offsetForBottomLine(Size size, Size iconSize, Size bottomLineSize) {
float y = size.height - 0.5f * iconSize.height - 0.5f * bottomLineSize.height;
return new Offset(0.0f, y);
}
Offset _offsetForName(Size size, Size nameSize, Offset bottomLineOffset) {
float y = bottomLineOffset.dy - nameSize.height;
return new Offset(0.0f, y);
}
}
public class UserAccountsDrawerHeader : StatefulWidget {
public UserAccountsDrawerHeader(
Key key = null,
Decoration decoration = null,
EdgeInsets margin = null,
Widget currentAccountPicture = null,
List<Widget> otherAccountsPictures = null,
Widget accountName = null,
Widget accountEmail = null,
VoidCallback onDetailsPressed = null
) : base(key: key) {
D.assert(accountName != null);
D.assert(accountEmail != null);
this.decoration = decoration;
this.margin = margin ?? EdgeInsets.only(bottom: 8.0f);
this.currentAccountPicture = currentAccountPicture;
this.otherAccountsPictures = otherAccountsPictures;
this.accountName = accountName;
this.accountEmail = accountEmail;
this.onDetailsPressed = onDetailsPressed;
}
public readonly Decoration decoration;
public readonly EdgeInsets margin;
public readonly Widget currentAccountPicture;
public readonly List<Widget> otherAccountsPictures;
public readonly Widget accountName;
public readonly Widget accountEmail;
public readonly VoidCallback onDetailsPressed;
public override State createState() {
return new _UserAccountsDrawerHeaderState();
}
}
class _UserAccountsDrawerHeaderState : State<UserAccountsDrawerHeader> {
bool _isOpen = false;
void _handleDetailsPressed() {
this.setState(() => { this._isOpen = !this._isOpen; });
this.widget.onDetailsPressed();
}
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterial(context));
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context));
return new DrawerHeader(
decoration: this.widget.decoration ?? new BoxDecoration(
color: Theme.of(context).primaryColor
),
margin: this.widget.margin,
padding: EdgeInsets.only(top: 16.0f, left: 16.0f),
child: new SafeArea(
bottom: false,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: new List<Widget> {
new Expanded(
child: new Padding(
padding: EdgeInsets.only(right: 16.0f),
child: new _AccountPictures(
currentAccountPicture: this.widget.currentAccountPicture,
otherAccountsPictures: this.widget.otherAccountsPictures
)
)
),
new _AccountDetails(
accountName: this.widget.accountName,
accountEmail: this.widget.accountEmail,
isOpen: this._isOpen,
onTap: this.widget.onDetailsPressed == null
? (VoidCallback) null
: () => { this._handleDetailsPressed(); })
}
)
)
);
}
}
}

3
Runtime/material/user_accounts_drawer_header.cs.meta


fileFormatVersion: 2
guid: fb34d1a7ff484d05b8074a10730d51a5
timeCreated: 1554352270

520
Runtime/widgets/overscroll_indicator.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.async;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.physics;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
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.widgets {
public class GlowingOverscrollIndicator : StatefulWidget {
public GlowingOverscrollIndicator(
Key key = null,
bool showLeading = true,
bool showTrailing = true,
AxisDirection axisDirection = AxisDirection.up,
Color color = null,
ScrollNotificationPredicate notificationPredicate = null,
Widget child = null
) : base(key: key) {
D.assert(color != null);
this.showLeading = showLeading;
this.showTrailing = showTrailing;
this.axisDirection = axisDirection;
this.child = child;
this.color = color;
this.notificationPredicate = notificationPredicate ?? ScrollNotification.defaultScrollNotificationPredicate;
}
public readonly bool showLeading;
public readonly bool showTrailing;
public readonly AxisDirection axisDirection;
public Axis axis {
get { return AxisUtils.axisDirectionToAxis(this.axisDirection); }
}
public readonly Color color;
public readonly ScrollNotificationPredicate notificationPredicate;
public readonly Widget child;
public override State createState() {
return new _GlowingOverscrollIndicatorState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<AxisDirection>("axisDirection", this.axisDirection));
string showDescription;
if (this.showLeading && this.showTrailing) {
showDescription = "both sides";
}
else if (this.showLeading) {
showDescription = "leading side only";
}
else if (this.showTrailing) {
showDescription = "trailing side only";
}
else {
showDescription = "neither side (!)";
}
properties.add(new MessageProperty("show", showDescription));
properties.add(new DiagnosticsProperty<Color>("color", this.color, showName: false));
}
}
class _GlowingOverscrollIndicatorState : TickerProviderStateMixin<GlowingOverscrollIndicator> {
_GlowController _leadingController;
_GlowController _trailingController;
Listenable _leadingAndTrailingListener;
public override void initState() {
base.initState();
this._leadingController =
new _GlowController(vsync: this, color: this.widget.color, axis: this.widget.axis);
this._trailingController =
new _GlowController(vsync: this, color: this.widget.color, axis: this.widget.axis);
this._leadingAndTrailingListener = ListenableUtils.merge(new List<Listenable>
{this._leadingController, this._trailingController});
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
base.didUpdateWidget(_oldWidget);
GlowingOverscrollIndicator oldWidget = _oldWidget as GlowingOverscrollIndicator;
if (oldWidget.color != this.widget.color || oldWidget.axis != this.widget.axis) {
this._leadingController.color = this.widget.color;
this._leadingController.axis = this.widget.axis;
this._trailingController.color = this.widget.color;
this._trailingController.axis = this.widget.axis;
}
}
Type _lastNotificationType;
Dictionary<bool, bool> _accepted = new Dictionary<bool, bool> {{false, true}, {true, true}};
bool _handleScrollNotification(ScrollNotification notification) {
if (!this.widget.notificationPredicate(notification)) {
return false;
}
if (notification is OverscrollNotification) {
_GlowController controller;
OverscrollNotification _notification = notification as OverscrollNotification;
if (_notification.overscroll < 0.0f) {
controller = this._leadingController;
}
else if (_notification.overscroll > 0.0f) {
controller = this._trailingController;
}
else {
throw new Exception("overscroll is 0.0f!");
}
bool isLeading = controller == this._leadingController;
if (this._lastNotificationType != typeof(OverscrollNotification)) {
OverscrollIndicatorNotification confirmationNotification =
new OverscrollIndicatorNotification(leading: isLeading);
confirmationNotification.dispatch(this.context);
this._accepted[isLeading] = confirmationNotification._accepted;
}
D.assert(controller != null);
D.assert(_notification.metrics.axis() == this.widget.axis);
if (this._accepted[isLeading]) {
if (_notification.velocity != 0.0f) {
D.assert(_notification.dragDetails == null);
controller.absorbImpact(_notification.velocity.abs());
}
else {
D.assert(_notification.overscroll != 0.0f);
if (_notification.dragDetails != null) {
D.assert(_notification.dragDetails.globalPosition != null);
RenderBox renderer = (RenderBox) _notification.context.findRenderObject();
D.assert(renderer != null);
D.assert(renderer.hasSize);
Size size = renderer.size;
Offset position = renderer.globalToLocal(_notification.dragDetails.globalPosition);
switch (_notification.metrics.axis()) {
case Axis.horizontal:
controller.pull(_notification.overscroll.abs(), size.width,
position.dy.clamp(0.0f, size.height), size.height);
break;
case Axis.vertical:
controller.pull(_notification.overscroll.abs(), size.height,
position.dx.clamp(0.0f, size.width), size.width);
break;
}
}
}
}
}
else if (notification is ScrollEndNotification || notification is ScrollUpdateNotification) {
if ((notification as ScrollEndNotification).dragDetails != null) {
this._leadingController.scrollEnd();
this._trailingController.scrollEnd();
}
}
this._lastNotificationType = notification.GetType();
return false;
}
public override void dispose() {
this._leadingController.dispose();
this._trailingController.dispose();
base.dispose();
}
public override Widget build(BuildContext context) {
return new NotificationListener<ScrollNotification>(
onNotification: this._handleScrollNotification,
child: new RepaintBoundary(
child: new CustomPaint(
foregroundPainter: new _GlowingOverscrollIndicatorPainter(
leadingController: this.widget.showLeading ? this._leadingController : null,
trailingController: this.widget.showTrailing ? this._trailingController : null,
axisDirection: this.widget.axisDirection,
repaint: this._leadingAndTrailingListener
),
child: new RepaintBoundary(
child: this.widget.child
)
)
)
);
}
}
enum _GlowState {
idle,
absorb,
pull,
recede
}
class _GlowController : ChangeNotifier {
public _GlowController(
TickerProvider vsync,
Color color,
Axis axis
) {
D.assert(vsync != null);
D.assert(color != null);
this._color = color;
this._axis = axis;
this._glowController = new AnimationController(vsync: vsync);
this._glowController.addStatusListener(this._changePhase);
Animation<float> decelerator = new CurvedAnimation(
parent: this._glowController,
curve: Curves.decelerate
);
decelerator.addListener(this.notifyListeners);
this._glowOpacity = decelerator.drive(this._glowOpacityTween);
this._glowSize = decelerator.drive(this._glowSizeTween);
this._displacementTicker = vsync.createTicker(this._tickDisplacement);
}
_GlowState _state = _GlowState.idle;
AnimationController _glowController;
Timer _pullRecedeTimer;
FloatTween _glowOpacityTween = new FloatTween(begin: 0.0f, end: 0.0f);
Animation<float> _glowOpacity;
FloatTween _glowSizeTween = new FloatTween(begin: 0.0f, end: 0.0f);
Animation<float> _glowSize;
Ticker _displacementTicker;
TimeSpan? _displacementTickerLastElapsed;
float _displacementTarget = 0.5f;
float _displacement = 0.5f;
float _pullDistance = 0.0f;
public Color color {
get { return this._color; }
set {
D.assert(this.color != null);
if (this.color == value) {
return;
}
this._color = value;
this.notifyListeners();
}
}
Color _color;
public Axis axis {
get { return this._axis; }
set {
if (this.axis == value) {
return;
}
this._axis = value;
this.notifyListeners();
}
}
Axis _axis;
readonly TimeSpan _recedeTime = new TimeSpan(0, 0, 0, 0, 600);
readonly TimeSpan _pullTime = new TimeSpan(0, 0, 0, 0, 167);
readonly TimeSpan _pullHoldTime = new TimeSpan(0, 0, 0, 0, 167);
readonly TimeSpan _pullDecayTime = new TimeSpan(0, 0, 0, 0, 2000);
static readonly TimeSpan _crossAxisHalfTime = new TimeSpan(0, 0, 0, 0, (1000.0f / 60.0f).round());
const float _maxOpacity = 0.5f;
const float _pullOpacityGlowFactor = 0.8f;
const float _velocityGlowFactor = 0.00006f;
const float _sqrt3 = 1.73205080757f; // Mathf.Sqrt(3)
const float _widthToHeightFactor = (3.0f / 4.0f) * (2.0f - _sqrt3);
const float _minVelocity = 100.0f; // logical pixels per second
const float _maxVelocity = 10000.0f; // logical pixels per second
public override void dispose() {
this._glowController.dispose();
this._displacementTicker.dispose();
this._pullRecedeTimer?.cancel();
base.dispose();
}
public void absorbImpact(float velocity) {
D.assert(velocity >= 0.0f);
this._pullRecedeTimer?.cancel();
this._pullRecedeTimer = null;
velocity = velocity.clamp(_minVelocity, _maxVelocity);
this._glowOpacityTween.begin = this._state == _GlowState.idle ? 0.3f : this._glowOpacity.value;
this._glowOpacityTween.end =
(velocity * _velocityGlowFactor).clamp(this._glowOpacityTween.begin, _maxOpacity);
this._glowSizeTween.begin = this._glowSize.value;
this._glowSizeTween.end = Mathf.Min(0.025f + 7.5e-7f * velocity * velocity, 1.0f);
this._glowController.duration = new TimeSpan(0, 0, 0, 0, (0.15f + velocity * 0.02f).round());
this._glowController.forward(from: 0.0f);
this._displacement = 0.5f;
this._state = _GlowState.absorb;
}
public void pull(float overscroll, float extent, float crossAxisOffset, float crossExtent) {
this._pullRecedeTimer?.cancel();
this._pullDistance +=
overscroll / 200.0f; // This factor is magic. Not clear why we need it to match Android.
this._glowOpacityTween.begin = this._glowOpacity.value;
this._glowOpacityTween.end =
Mathf.Min(this._glowOpacity.value + overscroll / extent * _pullOpacityGlowFactor, _maxOpacity);
float height = Mathf.Min(extent, crossExtent * _widthToHeightFactor);
this._glowSizeTween.begin = this._glowSize.value;
this._glowSizeTween.end = Mathf.Max(1.0f - 1.0f / (0.7f * Mathf.Sqrt(this._pullDistance * height)),
this._glowSize.value);
this._displacementTarget = crossAxisOffset / crossExtent;
if (this._displacementTarget != this._displacement) {
if (!this._displacementTicker.isTicking) {
D.assert(this._displacementTickerLastElapsed == null);
this._displacementTicker.start();
}
}
else {
this._displacementTicker.stop();
this._displacementTickerLastElapsed = null;
}
this._glowController.duration = this._pullTime;
if (this._state != _GlowState.pull) {
this._glowController.forward(from: 0.0f);
this._state = _GlowState.pull;
}
else {
if (!this._glowController.isAnimating) {
D.assert(this._glowController.value == 1.0f);
this.notifyListeners();
}
}
this._pullRecedeTimer =
Window.instance.run(this._pullHoldTime, () => this._recede(this._pullDecayTime));
}
public void scrollEnd() {
if (this._state == _GlowState.pull) {
this._recede(this._recedeTime);
}
}
void _changePhase(AnimationStatus status) {
if (status != AnimationStatus.completed) {
return;
}
switch (this._state) {
case _GlowState.absorb:
this._recede(this._recedeTime);
break;
case _GlowState.recede:
this._state = _GlowState.idle;
this._pullDistance = 0.0f;
break;
case _GlowState.pull:
case _GlowState.idle:
break;
}
}
void _recede(TimeSpan duration) {
if (this._state == _GlowState.recede || this._state == _GlowState.idle) {
return;
}
this._pullRecedeTimer?.cancel();
this._pullRecedeTimer = null;
this._glowOpacityTween.begin = this._glowOpacity.value;
this._glowOpacityTween.end = 0.0f;
this._glowSizeTween.begin = this._glowSize.value;
this._glowSizeTween.end = 0.0f;
this._glowController.duration = duration;
this._glowController.forward(from: 0.0f);
this._state = _GlowState.recede;
}
void _tickDisplacement(TimeSpan elapsed) {
if (this._displacementTickerLastElapsed != null) {
float? t = elapsed.Milliseconds - this._displacementTickerLastElapsed?.Milliseconds;
this._displacement = this._displacementTarget - (this._displacementTarget - this._displacement) *
Mathf.Pow(2.0f, (-t ?? 0.0f) / _crossAxisHalfTime.Milliseconds);
this.notifyListeners();
}
if (PhysicsUtils.nearEqual(this._displacementTarget, this._displacement,
Tolerance.defaultTolerance.distance)) {
this._displacementTicker.stop();
this._displacementTickerLastElapsed = null;
}
else {
this._displacementTickerLastElapsed = elapsed;
}
}
public void paint(Canvas canvas, Size size) {
if (this._glowOpacity.value == 0.0f) {
return;
}
float baseGlowScale = size.width > size.height ? size.height / size.width : 1.0f;
float radius = size.width * 3.0f / 2.0f;
float height = Mathf.Min(size.height, size.width * _widthToHeightFactor);
float scaleY = this._glowSize.value * baseGlowScale;
Rect rect = Rect.fromLTWH(0.0f, 0.0f, size.width, height);
Offset center = new Offset((size.width / 2.0f) * (0.5f + this._displacement), height - radius);
Paint paint = new Paint();
paint.color = this.color.withOpacity(this._glowOpacity.value);
canvas.save();
canvas.scale(1.0f, scaleY);
canvas.clipRect(rect);
canvas.drawCircle(center, radius, paint);
canvas.restore();
}
}
class _GlowingOverscrollIndicatorPainter : AbstractCustomPainter {
public _GlowingOverscrollIndicatorPainter(
_GlowController leadingController,
_GlowController trailingController,
AxisDirection axisDirection,
Listenable repaint
) : base(
repaint: repaint
) {
this.leadingController = leadingController;
this.trailingController = trailingController;
this.axisDirection = axisDirection;
}
public readonly _GlowController leadingController;
public readonly _GlowController trailingController;
public readonly AxisDirection axisDirection;
const float piOver2 = Mathf.PI / 2.0f;
void _paintSide(Canvas canvas, Size size, _GlowController controller, AxisDirection axisDirection,
GrowthDirection growthDirection) {
if (controller == null) {
return;
}
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(axisDirection, growthDirection)) {
case AxisDirection.up:
controller.paint(canvas, size);
break;
case AxisDirection.down:
canvas.save();
canvas.translate(0.0f, size.height);
canvas.scale(1.0f, -1.0f);
controller.paint(canvas, size);
canvas.restore();
break;
case AxisDirection.left:
canvas.save();
canvas.rotate(piOver2);
canvas.scale(1.0f, -1.0f);
controller.paint(canvas, new Size(size.height, size.width));
canvas.restore();
break;
case AxisDirection.right:
canvas.save();
canvas.translate(size.width, 0.0f);
canvas.rotate(piOver2);
controller.paint(canvas, new Size(size.height, size.width));
canvas.restore();
break;
}
}
public override void paint(Canvas canvas, Size size) {
this._paintSide(canvas, size, this.leadingController, this.axisDirection, GrowthDirection.reverse);
this._paintSide(canvas, size, this.trailingController, this.axisDirection, GrowthDirection.forward);
}
public override bool shouldRepaint(CustomPainter _oldDelegate) {
_GlowingOverscrollIndicatorPainter oldDelegate = _oldDelegate as _GlowingOverscrollIndicatorPainter;
return oldDelegate.leadingController != this.leadingController
|| oldDelegate.trailingController != this.trailingController;
}
}
public class OverscrollIndicatorNotification : ViewportNotificationMixinNotification {
public OverscrollIndicatorNotification(
bool leading
) {
this.leading = leading;
}
public readonly bool leading;
internal bool _accepted = true;
public void disallowGlow() {
this._accepted = false;
}
protected override void debugFillDescription(List<string> description) {
base.debugFillDescription(description);
description.Add($"side: {(this.leading ? "leading edge" : "trailing edge")}");
}
}
}

3
Runtime/widgets/overscroll_indicator.cs.meta


fileFormatVersion: 2
guid: b87c58140c4b442e82a27b804f8502c7
timeCreated: 1554348404

4
.DS_Store


Bud1 GELOG.  @� @� @� @ CHANGELOG.mdIlocblob�(������CHANGELOG.md.metaIlocblob;�������CONTRIBUTING.mdIlocblob��������CONTRIBUTING.md.metaIlocblob�������Documentation~Ilocblob��������EditorIlocblob�������� Editor.metaIlocblob;������
LICENSE.mdIlocblob�������LICENSE.md.metaIlocblob������ package.jsonIlocblob�������package.json.metaIlocblob������� QAReport.mdIlocblob;x������QAReport.md.metaIlocblob�x������ README-ZH.mdIlocblob7������� README.mdIlocblobx������README.md.metaIlocblob�x������RuntimeIlocblob�x������ Runtime.metaIlocblob;�������SamplesIlocblob�������� Samples.metaIlocblob�������scriptsIlocblob�������� scripts.metaIlocblob��������TestsIlocblob;X������
Tests.metaIlocblob�X������Third Party Notices.mdIlocblobX������Third Party Notices.md.metaIlocblob�X������!UIWidgetCleanupPlugin.DotSettingsIlocblob�X������&UIWidgetCleanupPlugin.DotSettings.metaIlocblob;������� E DSDB `� @� @� @;X������
Tests.metaIlocblob�X������Third Party Notices.mdIlocblobX������Third Party Notices.md.metaIlocblob�X������!UIWidgetCleanupPlugin.DotSettingsIlocblob�X������&UIWidgetCleanupPlugin.DotSettings.metaIlocblob;�������
正在加载...
取消
保存