Merge pull request #217 from Unity-Technologies/shiyun_datepicker

datepicker scroll fix
This commit is contained in:
Xingwei Zhu 2021-07-30 17:20:17 +08:00 коммит произвёл GitHub
Родитель 8b5ac2be9b e478c0d0dc
Коммит 370764a970
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 1101 добавлений и 1005 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,28 +1,28 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using Unity.UIWidgets.animation; using Unity.UIWidgets.animation;
using Unity.UIWidgets.async; using Unity.UIWidgets.async;
using Unity.UIWidgets.external;
using Unity.UIWidgets.foundation; using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting; using Unity.UIWidgets.painting;
using Unity.UIWidgets.physics; using Unity.UIWidgets.physics;
using Unity.UIWidgets.rendering; using Unity.UIWidgets.rendering;
using Unity.UIWidgets.external;
using Unity.UIWidgets.scheduler; using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui; using Unity.UIWidgets.ui;
using UnityEngine; using UnityEngine;
namespace Unity.UIWidgets.widgets { namespace Unity.UIWidgets.widgets {
public interface ListWheelChildDelegate { public interface ListWheelChildDelegate {
Widget build(BuildContext context, int index);
int? estimatedChildCount { get; } int? estimatedChildCount { get; }
Widget build(BuildContext context, int index);
int trueIndexOf(int index); int trueIndexOf(int index);
bool shouldRebuild(ListWheelChildDelegate oldDelegate); bool shouldRebuild(ListWheelChildDelegate oldDelegate);
} }
public class ListWheelChildListDelegate : ListWheelChildDelegate { public class ListWheelChildListDelegate : ListWheelChildDelegate {
public readonly List<Widget> children;
public ListWheelChildListDelegate( public ListWheelChildListDelegate(
List<Widget> children List<Widget> children
) { ) {
@ -30,8 +30,6 @@ namespace Unity.UIWidgets.widgets {
this.children = children; this.children = children;
} }
public readonly List<Widget> children;
public int? estimatedChildCount { public int? estimatedChildCount {
get { return children.Count; } get { return children.Count; }
} }
@ -41,7 +39,7 @@ namespace Unity.UIWidgets.widgets {
return null; return null;
} }
return new IndexedSemantics(child: children[index], index: index); return new IndexedSemantics(child: children[index: index], index: index);
} }
public int trueIndexOf(int index) { public int trueIndexOf(int index) {
@ -54,6 +52,8 @@ namespace Unity.UIWidgets.widgets {
} }
public class ListWheelChildLoopingListDelegate : ListWheelChildDelegate { public class ListWheelChildLoopingListDelegate : ListWheelChildDelegate {
public readonly List<Widget> children;
public ListWheelChildLoopingListDelegate( public ListWheelChildLoopingListDelegate(
List<Widget> children List<Widget> children
) { ) {
@ -61,21 +61,21 @@ namespace Unity.UIWidgets.widgets {
this.children = children; this.children = children;
} }
public readonly List<Widget> children;
public int? estimatedChildCount { public int? estimatedChildCount {
get { return null; } get { return null; }
} }
public int trueIndexOf(int index) { public int trueIndexOf(int index) {
var result = index % children.Count;
return index % children.Count; if (index < 0) {result = result + children.Count; }
return result;
} }
public Widget build(BuildContext context, int index) { public Widget build(BuildContext context, int index) {
if (children.isEmpty()) { if (children.isEmpty()) {
return null; return null;
} }
return new IndexedSemantics(child: children[Mathf.Abs(index % children.Count)]); return new IndexedSemantics(child: children[Mathf.Abs(index % children.Count)]);
} }
@ -85,6 +85,10 @@ namespace Unity.UIWidgets.widgets {
} }
public class ListWheelChildBuilderDelegate : ListWheelChildDelegate { public class ListWheelChildBuilderDelegate : ListWheelChildDelegate {
public readonly IndexedWidgetBuilder builder;
public readonly int? childCount;
public ListWheelChildBuilderDelegate( public ListWheelChildBuilderDelegate(
IndexedWidgetBuilder builder, IndexedWidgetBuilder builder,
int? childCount = null int? childCount = null
@ -94,17 +98,13 @@ namespace Unity.UIWidgets.widgets {
this.childCount = childCount; this.childCount = childCount;
} }
public readonly IndexedWidgetBuilder builder;
public readonly int? childCount;
public int? estimatedChildCount { public int? estimatedChildCount {
get { return childCount; } get { return childCount; }
} }
public Widget build(BuildContext context, int index) { public Widget build(BuildContext context, int index) {
if (childCount == null) { if (childCount == null) {
Widget child = builder(context, index); var child = builder(context: context, index: index);
return child == null ? null : new IndexedSemantics(child: child); return child == null ? null : new IndexedSemantics(child: child);
} }
@ -112,7 +112,7 @@ namespace Unity.UIWidgets.widgets {
return null; return null;
} }
return new IndexedSemantics(child: builder(context, index)); return new IndexedSemantics(child: builder(context: context, index: index));
} }
public int trueIndexOf(int index) { public int trueIndexOf(int index) {
@ -127,31 +127,33 @@ namespace Unity.UIWidgets.widgets {
class ListWheelScrollViewUtils { class ListWheelScrollViewUtils {
public static int _getItemFromOffset( public static int _getItemFromOffset(
float offset , float offset,
float itemExtent , float itemExtent,
float minScrollExtent , float minScrollExtent,
float maxScrollExtent float maxScrollExtent
) { ) {
return (_clipOffsetToScrollableRange(offset, minScrollExtent, maxScrollExtent) / itemExtent).round(); return (_clipOffsetToScrollableRange(offset: offset, minScrollExtent: minScrollExtent,
maxScrollExtent: maxScrollExtent) / itemExtent).round();
} }
public static float _clipOffsetToScrollableRange( public static float _clipOffsetToScrollableRange(
float offset, float offset,
float minScrollExtent, float minScrollExtent,
float maxScrollExtent float maxScrollExtent
) { ) {
return Mathf.Min(Mathf.Max(offset, minScrollExtent), maxScrollExtent); return Mathf.Min(Mathf.Max(a: offset, b: minScrollExtent), b: maxScrollExtent);
} }
} }
public class FixedExtentScrollController : ScrollController { public class FixedExtentScrollController : ScrollController {
public readonly int initialItem;
public FixedExtentScrollController( public FixedExtentScrollController(
int initialItem = 0 int initialItem = 0
) { ) {
this.initialItem = initialItem; this.initialItem = initialItem;
} }
public readonly int initialItem;
public int selectedItem { public int selectedItem {
get { get {
D.assert(positions.isNotEmpty(), D.assert(positions.isNotEmpty(),
@ -162,7 +164,7 @@ namespace Unity.UIWidgets.widgets {
() => () =>
"The selectedItem property cannot be read when multiple scroll views are attached to the same FixedExtentScrollController." "The selectedItem property cannot be read when multiple scroll views are attached to the same FixedExtentScrollController."
); );
_FixedExtentScrollPosition position = (_FixedExtentScrollPosition) this.position; var position = (_FixedExtentScrollPosition) this.position;
return position.itemIndex; return position.itemIndex;
} }
} }
@ -175,20 +177,22 @@ namespace Unity.UIWidgets.widgets {
if (!hasClients) { if (!hasClients) {
return null; return null;
} }
List<Future> futures = new List<Future>();
foreach (_FixedExtentScrollPosition position in positions.Cast<_FixedExtentScrollPosition>()) { var futures = new List<Future>();
foreach (var position in positions.Cast<_FixedExtentScrollPosition>()) {
futures.Add(position.animateTo( futures.Add(position.animateTo(
itemIndex * position.itemExtent, itemIndex * position.itemExtent,
duration: duration, duration: duration,
curve: curve curve: curve
)); ));
} }
return Future.wait<object>(futures);
return Future.wait<object>(futures: futures);
} }
public void jumpToItem(int itemIndex) { public void jumpToItem(int itemIndex) {
foreach (_FixedExtentScrollPosition position in positions.Cast<_FixedExtentScrollPosition>()) { foreach (var position in positions.Cast<_FixedExtentScrollPosition>()) {
position.jumpTo(itemIndex * position.itemExtent); position.jumpTo(itemIndex * position.itemExtent);
} }
} }
@ -221,17 +225,17 @@ namespace Unity.UIWidgets.widgets {
public class FixedExtentMetrics : FixedScrollMetrics, IFixedExtentMetrics { public class FixedExtentMetrics : FixedScrollMetrics, IFixedExtentMetrics {
public FixedExtentMetrics( public FixedExtentMetrics(
float minScrollExtent , float minScrollExtent,
float maxScrollExtent, float maxScrollExtent,
float pixels , float pixels,
float viewportDimension , float viewportDimension,
AxisDirection axisDirection , AxisDirection axisDirection,
int itemIndex int itemIndex
) : base( ) : base(
minScrollExtent: minScrollExtent , minScrollExtent: minScrollExtent,
maxScrollExtent: maxScrollExtent , maxScrollExtent: maxScrollExtent,
pixels: pixels , pixels: pixels,
viewportDimension: viewportDimension , viewportDimension: viewportDimension,
axisDirection: axisDirection axisDirection: axisDirection
) { ) {
this.itemIndex = itemIndex; this.itemIndex = itemIndex;
@ -248,16 +252,14 @@ namespace Unity.UIWidgets.widgets {
int? itemIndex = null int? itemIndex = null
) { ) {
return new FixedExtentMetrics( return new FixedExtentMetrics(
minScrollExtent: minScrollExtent ?? this.minScrollExtent, minScrollExtent ?? this.minScrollExtent,
maxScrollExtent: maxScrollExtent ?? this.maxScrollExtent, maxScrollExtent ?? this.maxScrollExtent,
pixels: pixels ?? this.pixels, pixels ?? this.pixels,
viewportDimension: viewportDimension ?? this.viewportDimension, viewportDimension ?? this.viewportDimension,
axisDirection: axisDirection ?? this.axisDirection, axisDirection ?? this.axisDirection,
itemIndex: itemIndex ?? this.itemIndex itemIndex ?? this.itemIndex
); );
} }
} }
class _FixedExtentScrollPosition : ScrollPositionWithSingleContext, IFixedExtentMetrics { class _FixedExtentScrollPosition : ScrollPositionWithSingleContext, IFixedExtentMetrics {
@ -271,7 +273,7 @@ namespace Unity.UIWidgets.widgets {
) : base( ) : base(
physics: physics, physics: physics,
context: context, context: context,
initialPixels: _getItemExtentFromScrollContext(context) * (initialItem ?? 0.0f), _getItemExtentFromScrollContext(context: context) * (initialItem ?? 0.0f),
keepScrollOffset: keepScrollOffset, keepScrollOffset: keepScrollOffset,
oldPosition: oldPosition, oldPosition: oldPosition,
debugLabel: debugLabel debugLabel: debugLabel
@ -282,13 +284,8 @@ namespace Unity.UIWidgets.widgets {
); );
} }
static float _getItemExtentFromScrollContext(ScrollContext context) {
_FixedExtentScrollableState scrollable = (_FixedExtentScrollableState) context;
return scrollable.itemExtent;
}
public float itemExtent { public float itemExtent {
get { return _getItemExtentFromScrollContext(context); } get { return _getItemExtentFromScrollContext(context: context); }
} }
@ -313,17 +310,24 @@ namespace Unity.UIWidgets.widgets {
int? itemIndex = null int? itemIndex = null
) { ) {
return new FixedExtentMetrics( return new FixedExtentMetrics(
minScrollExtent: minScrollExtent ?? this.minScrollExtent, minScrollExtent ?? this.minScrollExtent,
maxScrollExtent: maxScrollExtent ?? this.maxScrollExtent, maxScrollExtent ?? this.maxScrollExtent,
pixels: pixels ?? this.pixels, pixels ?? this.pixels,
viewportDimension: viewportDimension ?? this.viewportDimension, viewportDimension ?? this.viewportDimension,
axisDirection: axisDirection ?? this.axisDirection, axisDirection ?? this.axisDirection,
itemIndex: itemIndex ?? this.itemIndex itemIndex ?? this.itemIndex
); );
} }
static float _getItemExtentFromScrollContext(ScrollContext context) {
var scrollable = (_FixedExtentScrollableState) context;
return scrollable.itemExtent;
}
} }
class _FixedExtentScrollable : Scrollable { class _FixedExtentScrollable : Scrollable {
public readonly float itemExtent;
public _FixedExtentScrollable( public _FixedExtentScrollable(
float itemExtent, float itemExtent,
Key key = null, Key key = null,
@ -331,7 +335,6 @@ namespace Unity.UIWidgets.widgets {
ScrollController controller = null, ScrollController controller = null,
ScrollPhysics physics = null, ScrollPhysics physics = null,
ViewportBuilder viewportBuilder = null ViewportBuilder viewportBuilder = null
) : base( ) : base(
key: key, key: key,
axisDirection: axisDirection, axisDirection: axisDirection,
@ -342,8 +345,6 @@ namespace Unity.UIWidgets.widgets {
this.itemExtent = itemExtent; this.itemExtent = itemExtent;
} }
public readonly float itemExtent;
public override State createState() { public override State createState() {
return new _FixedExtentScrollableState(); return new _FixedExtentScrollableState();
} }
@ -352,7 +353,7 @@ namespace Unity.UIWidgets.widgets {
class _FixedExtentScrollableState : ScrollableState { class _FixedExtentScrollableState : ScrollableState {
public float itemExtent { public float itemExtent {
get { get {
_FixedExtentScrollable actualWidget = (_FixedExtentScrollable) widget; var actualWidget = (_FixedExtentScrollable) widget;
return actualWidget.itemExtent; return actualWidget.itemExtent;
} }
} }
@ -362,10 +363,11 @@ namespace Unity.UIWidgets.widgets {
public class FixedExtentScrollPhysics : ScrollPhysics { public class FixedExtentScrollPhysics : ScrollPhysics {
public FixedExtentScrollPhysics( public FixedExtentScrollPhysics(
ScrollPhysics parent = null ScrollPhysics parent = null
) : base(parent: parent) { } ) : base(parent: parent) {
}
public override ScrollPhysics applyTo(ScrollPhysics ancestor) { public override ScrollPhysics applyTo(ScrollPhysics ancestor) {
return new FixedExtentScrollPhysics(parent: buildParent(ancestor)); return new FixedExtentScrollPhysics(buildParent(ancestor: ancestor));
} }
public override Simulation createBallisticSimulation(ScrollMetrics position, float velocity) { public override Simulation createBallisticSimulation(ScrollMetrics position, float velocity) {
@ -375,30 +377,30 @@ namespace Unity.UIWidgets.widgets {
"the FixedExtentScrollController" "the FixedExtentScrollController"
); );
_FixedExtentScrollPosition metrics = (_FixedExtentScrollPosition) position; var metrics = (_FixedExtentScrollPosition) position;
if ((velocity <= 0.0f && metrics.pixels <= metrics.minScrollExtent) || if (velocity <= 0.0f && metrics.pixels <= metrics.minScrollExtent ||
(velocity >= 0.0f && metrics.pixels >= metrics.maxScrollExtent)) { velocity >= 0.0f && metrics.pixels >= metrics.maxScrollExtent) {
return base.createBallisticSimulation(metrics, velocity); return base.createBallisticSimulation(position: metrics, velocity: velocity);
} }
Simulation testFrictionSimulation = var testFrictionSimulation =
base.createBallisticSimulation(metrics, velocity); base.createBallisticSimulation(position: metrics, velocity: velocity);
if (testFrictionSimulation != null if (testFrictionSimulation != null
&& (testFrictionSimulation.x(float.PositiveInfinity) == metrics.minScrollExtent && (testFrictionSimulation.x(time: float.PositiveInfinity) == metrics.minScrollExtent
|| testFrictionSimulation.x(float.PositiveInfinity) == metrics.maxScrollExtent)) { || testFrictionSimulation.x(time: float.PositiveInfinity) == metrics.maxScrollExtent)) {
return base.createBallisticSimulation(metrics, velocity); return base.createBallisticSimulation(position: metrics, velocity: velocity);
} }
int settlingItemIndex = ListWheelScrollViewUtils._getItemFromOffset( var settlingItemIndex = ListWheelScrollViewUtils._getItemFromOffset(
offset: testFrictionSimulation?.x(float.PositiveInfinity) ?? metrics.pixels, testFrictionSimulation?.x(time: float.PositiveInfinity) ?? metrics.pixels,
itemExtent: metrics.itemExtent, itemExtent: metrics.itemExtent,
minScrollExtent: metrics.minScrollExtent, minScrollExtent: metrics.minScrollExtent,
maxScrollExtent: metrics.maxScrollExtent maxScrollExtent: metrics.maxScrollExtent
); );
float settlingPixels = settlingItemIndex * metrics.itemExtent; var settlingPixels = settlingItemIndex * metrics.itemExtent;
if (velocity.abs() < tolerance.velocity if (velocity.abs() < tolerance.velocity
&& (settlingPixels - metrics.pixels).abs() < tolerance.distance) { && (settlingPixels - metrics.pixels).abs() < tolerance.distance) {
@ -407,24 +409,40 @@ namespace Unity.UIWidgets.widgets {
if (settlingItemIndex == metrics.itemIndex) { if (settlingItemIndex == metrics.itemIndex) {
return new SpringSimulation( return new SpringSimulation(
spring, spring: spring,
metrics.pixels, start: metrics.pixels,
settlingPixels, end: settlingPixels,
velocity, velocity: velocity,
tolerance: tolerance tolerance: tolerance
); );
} }
return FrictionSimulation.through( return FrictionSimulation.through(
metrics.pixels, startPosition: metrics.pixels,
settlingPixels, endPosition: settlingPixels,
velocity, startVelocity: velocity,
tolerance.velocity * velocity.sign() tolerance.velocity * velocity.sign()
); );
} }
} }
public class ListWheelScrollView : StatefulWidget { public class ListWheelScrollView : StatefulWidget {
public readonly bool clipToSize;
public readonly ScrollController controller;
public readonly float diameterRatio;
public readonly float itemExtent;
public readonly float magnification;
public readonly float offAxisFraction;
public readonly ValueChanged<int> onSelectedItemChanged;
public readonly float overAndUnderCenterOpacity;
public readonly float perspective;
public readonly ScrollPhysics physics;
public readonly bool renderChildrenOutsideViewport;
public readonly float squeeze;
public readonly bool useMagnifier;
public ListWheelChildDelegate childDelegate;
public ListWheelScrollView( public ListWheelScrollView(
List<Widget> children, List<Widget> children,
float itemExtent, float itemExtent,
@ -471,7 +489,7 @@ namespace Unity.UIWidgets.widgets {
this.renderChildrenOutsideViewport = renderChildrenOutsideViewport; this.renderChildrenOutsideViewport = renderChildrenOutsideViewport;
} }
public ListWheelScrollView ( public ListWheelScrollView(
float itemExtent, float itemExtent,
Key key = null, Key key = null,
ScrollController controller = null, ScrollController controller = null,
@ -489,17 +507,17 @@ namespace Unity.UIWidgets.widgets {
ListWheelChildDelegate childDelegate = null ListWheelChildDelegate childDelegate = null
) : base(key: key) { ) : base(key: key) {
D.assert(childDelegate != null); D.assert(childDelegate != null);
D.assert(diameterRatio > 0.0, ()=>RenderListWheelViewport.diameterRatioZeroMessage); D.assert(diameterRatio > 0.0, () => RenderListWheelViewport.diameterRatioZeroMessage);
D.assert(perspective > 0); D.assert(perspective > 0);
D.assert(perspective <= 0.01,()=> RenderListWheelViewport.perspectiveTooHighMessage); D.assert(perspective <= 0.01, () => RenderListWheelViewport.perspectiveTooHighMessage);
D.assert(magnification > 0); D.assert(magnification > 0);
D.assert(overAndUnderCenterOpacity >= 0 && overAndUnderCenterOpacity <= 1); D.assert(overAndUnderCenterOpacity >= 0 && overAndUnderCenterOpacity <= 1);
D.assert(itemExtent != null); D.assert(itemExtent != null);
D.assert(itemExtent > 0); D.assert(itemExtent > 0);
D.assert(squeeze > 0); D.assert(squeeze > 0);
D.assert( D.assert(
!renderChildrenOutsideViewport || !clipToSize,()=> !renderChildrenOutsideViewport || !clipToSize, () =>
RenderListWheelViewport.clipToSizeAndRenderChildrenOutsideViewportConflict RenderListWheelViewport.clipToSizeAndRenderChildrenOutsideViewportConflict
); );
this.controller = controller; this.controller = controller;
this.physics = physics; this.physics = physics;
@ -517,28 +535,13 @@ namespace Unity.UIWidgets.widgets {
this.childDelegate = childDelegate; this.childDelegate = childDelegate;
} }
public readonly ScrollController controller;
public readonly ScrollPhysics physics;
public readonly float diameterRatio;
public readonly float perspective;
public readonly float offAxisFraction;
public readonly bool useMagnifier;
public readonly float magnification;
public readonly float itemExtent;
public readonly float overAndUnderCenterOpacity;
public readonly float squeeze;
public readonly ValueChanged<int> onSelectedItemChanged;
public readonly bool clipToSize;
public readonly bool renderChildrenOutsideViewport;
public ListWheelChildDelegate childDelegate;
public override State createState() { public override State createState() {
return new _ListWheelScrollViewState(); return new _ListWheelScrollViewState();
} }
} }
class _ListWheelScrollViewState : State<ListWheelScrollView> { class _ListWheelScrollViewState : State<ListWheelScrollView> {
int _lastReportedItemIndex = 0; int _lastReportedItemIndex;
ScrollController scrollController; ScrollController scrollController;
public override void initState() { public override void initState() {
@ -550,26 +553,26 @@ namespace Unity.UIWidgets.widgets {
} }
public override void didUpdateWidget(StatefulWidget oldWidget) { public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget); base.didUpdateWidget(oldWidget: oldWidget);
if (widget.controller != null && widget.controller != scrollController) { if (widget.controller != null && widget.controller != scrollController) {
ScrollController oldScrollController = scrollController; var oldScrollController = scrollController;
SchedulerBinding.instance.addPostFrameCallback((_) => { oldScrollController.dispose(); }); SchedulerBinding.instance.addPostFrameCallback(_ => { oldScrollController.dispose(); });
scrollController = widget.controller; scrollController = widget.controller;
} }
} }
public override Widget build(BuildContext context) { public override Widget build(BuildContext context) {
return new NotificationListener<ScrollNotification>( return new NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) => { onNotification: notification => {
if (notification.depth == 0 if (notification.depth == 0
&& widget.onSelectedItemChanged != null && widget.onSelectedItemChanged != null
&& notification is ScrollUpdateNotification && notification is ScrollUpdateNotification
&& notification.metrics is FixedExtentMetrics metrics) { && notification.metrics is FixedExtentMetrics metrics) {
int currentItemIndex = metrics.itemIndex; var currentItemIndex = metrics.itemIndex;
if (currentItemIndex != _lastReportedItemIndex) { if (currentItemIndex != _lastReportedItemIndex) {
_lastReportedItemIndex = currentItemIndex; _lastReportedItemIndex = currentItemIndex;
int trueIndex = widget.childDelegate.trueIndexOf(currentItemIndex); var trueIndex = widget.childDelegate.trueIndexOf(index: currentItemIndex);
widget.onSelectedItemChanged(trueIndex); widget.onSelectedItemChanged(value: trueIndex);
} }
} }
@ -579,7 +582,7 @@ namespace Unity.UIWidgets.widgets {
controller: scrollController, controller: scrollController,
physics: widget.physics, physics: widget.physics,
itemExtent: widget.itemExtent, itemExtent: widget.itemExtent,
viewportBuilder: (BuildContext _context, ViewportOffset _offset) => { viewportBuilder: (_context, _offset) => {
return new ListWheelViewport( return new ListWheelViewport(
diameterRatio: widget.diameterRatio, diameterRatio: widget.diameterRatio,
perspective: widget.perspective, perspective: widget.perspective,
@ -587,7 +590,7 @@ namespace Unity.UIWidgets.widgets {
useMagnifier: widget.useMagnifier, useMagnifier: widget.useMagnifier,
magnification: widget.magnification, magnification: widget.magnification,
overAndUnderCenterOpacity: widget.overAndUnderCenterOpacity, overAndUnderCenterOpacity: widget.overAndUnderCenterOpacity,
itemExtent: widget.itemExtent , itemExtent: widget.itemExtent,
squeeze: widget.squeeze, squeeze: widget.squeeze,
clipToSize: widget.clipToSize, clipToSize: widget.clipToSize,
renderChildrenOutsideViewport: widget.renderChildrenOutsideViewport, renderChildrenOutsideViewport: widget.renderChildrenOutsideViewport,
@ -601,36 +604,68 @@ namespace Unity.UIWidgets.widgets {
} }
public class ListWheelElement : RenderObjectElement, IListWheelChildManager { public class ListWheelElement : RenderObjectElement, IListWheelChildManager {
public ListWheelElement(ListWheelViewport widget) : base(widget) { } readonly SplayTree<int, Element> _childElements = new SplayTree<int, Element>();
readonly Dictionary<int, Widget> _childWidgets = new Dictionary<int, Widget>();
public ListWheelElement(ListWheelViewport widget) : base(widget: widget) {
}
public new ListWheelViewport widget { public new ListWheelViewport widget {
get { return (ListWheelViewport) base.widget; } get { return (ListWheelViewport) base.widget; }
} }
public new RenderListWheelViewport renderObject { public new RenderListWheelViewport renderObject {
get { return (RenderListWheelViewport)base.renderObject; } get { return (RenderListWheelViewport) base.renderObject; }
}
readonly Dictionary<int, Widget> _childWidgets = new Dictionary<int, Widget>();
readonly SplayTree<int, Element> _childElements = new SplayTree<int, Element>();
public override void update(Widget newWidget) {
ListWheelViewport oldWidget = widget;
base.update(newWidget);
ListWheelChildDelegate newDelegate = ((ListWheelViewport) newWidget).childDelegate;
ListWheelChildDelegate oldDelegate = oldWidget.childDelegate;
if (newDelegate != oldDelegate &&
(newDelegate.GetType() != oldDelegate.GetType() || newDelegate.shouldRebuild(oldDelegate))) {
performRebuild();
}
} }
public int? childCount { public int? childCount {
get { return widget.childDelegate.estimatedChildCount; } get { return widget.childDelegate.estimatedChildCount; }
} }
public bool childExistsAt(int index) {
return retrieveWidget(index: index) != null;
}
public void createChild(int index, RenderBox after) {
owner.buildScope(this, () => {
var insertFirst = after == null;
D.assert(insertFirst || _childElements.getOrDefault(index - 1) != null);
var newChild = updateChild(_childElements.getOrDefault(key: index), retrieveWidget(index: index),
newSlot: index);
if (newChild != null) {
_childElements[key: index] = newChild;
}
else {
_childElements.Remove(key: index);
}
});
}
public void removeChild(RenderBox child) {
var index = renderObject.indexOf(child: child);
owner.buildScope(this, () => {
D.assert(_childElements.ContainsKey(key: index));
var result = updateChild(_childElements[key: index], null, newSlot: index);
D.assert(result == null);
_childElements.Remove(key: index);
D.assert(!_childElements.ContainsKey(key: index));
});
}
public override void update(Widget newWidget) {
var oldWidget = widget;
base.update(newWidget: newWidget);
var newDelegate = ((ListWheelViewport) newWidget).childDelegate;
var oldDelegate = oldWidget.childDelegate;
if (newDelegate != oldDelegate &&
(newDelegate.GetType() != oldDelegate.GetType() ||
newDelegate.shouldRebuild(oldDelegate: oldDelegate))) {
performRebuild();
}
}
protected override void performRebuild() { protected override void performRebuild() {
_childWidgets.Clear(); _childWidgets.Clear();
base.performRebuild(); base.performRebuild();
@ -638,58 +673,29 @@ namespace Unity.UIWidgets.widgets {
return; return;
} }
int firstIndex = _childElements.First()?.Key ?? 0; var firstIndex = _childElements.First()?.Key ?? 0;
int lastIndex = _childElements.Last()?.Key ?? _childElements.Count; var lastIndex = _childElements.Last()?.Key ?? _childElements.Count;
for (int index = firstIndex; index <= lastIndex; ++index) { for (var index = firstIndex; index <= lastIndex; ++index) {
Element newChild = updateChild(_childElements[index], retrieveWidget(index), index); var newChild = updateChild(_childElements[key: index], retrieveWidget(index: index), newSlot: index);
if (newChild != null) { if (newChild != null) {
_childElements[index] = newChild; _childElements[key: index] = newChild;
} }
else { else {
_childElements.Remove(index); _childElements.Remove(key: index);
} }
} }
} }
Widget retrieveWidget(int index) { Widget retrieveWidget(int index) {
return _childWidgets.putIfAbsent(index, return _childWidgets.putIfAbsent(key: index,
() => { return widget.childDelegate.build(this, index); }); () => { return widget.childDelegate.build(this, index: index); });
}
public bool childExistsAt(int index) {
return retrieveWidget(index) != null;
}
public void createChild(int index, RenderBox after) {
owner.buildScope(this, () => {
bool insertFirst = after == null;
D.assert(insertFirst || _childElements.getOrDefault(index - 1) != null);
Element newChild = updateChild(_childElements.getOrDefault(index), retrieveWidget(index), index);
if (newChild != null) {
_childElements[index] = newChild;
}
else {
_childElements.Remove(index);
}
});
}
public void removeChild(RenderBox child) {
int index = renderObject.indexOf(child);
owner.buildScope(this, () => {
D.assert(_childElements.ContainsKey(index));
Element result = updateChild(_childElements[index], null, index);
D.assert(result == null);
_childElements.Remove(index);
D.assert(!_childElements.ContainsKey(index));
});
} }
protected override Element updateChild(Element child, Widget newWidget, object newSlot) { protected override Element updateChild(Element child, Widget newWidget, object newSlot) {
ListWheelParentData oldParentData = (ListWheelParentData) child?.renderObject?.parentData; var oldParentData = (ListWheelParentData) child?.renderObject?.parentData;
Element newChild = base.updateChild(child, newWidget, newSlot); var newChild = base.updateChild(child: child, newWidget: newWidget, newSlot: newSlot);
ListWheelParentData newParentData = (ListWheelParentData) newChild?.renderObject?.parentData; var newParentData = (ListWheelParentData) newChild?.renderObject?.parentData;
if (newParentData != null) { if (newParentData != null) {
newParentData.index = (int) newSlot; newParentData.index = (int) newSlot;
if (oldParentData != null) { if (oldParentData != null) {
@ -701,15 +707,16 @@ namespace Unity.UIWidgets.widgets {
} }
protected override void insertChildRenderObject(RenderObject child, object slot) { protected override void insertChildRenderObject(RenderObject child, object slot) {
RenderListWheelViewport renderObject = this.renderObject; var renderObject = this.renderObject;
D.assert(renderObject.debugValidateChild(child)); D.assert(renderObject.debugValidateChild(child: child));
int slotNum = (int) slot; var slotNum = (int) slot;
renderObject.insert(child as RenderBox, after: _childElements.getOrDefault(slotNum - 1)?.renderObject as RenderBox); renderObject.insert(child as RenderBox,
_childElements.getOrDefault(slotNum - 1)?.renderObject as RenderBox);
D.assert(renderObject == this.renderObject); D.assert(renderObject == this.renderObject);
} }
protected override void moveChildRenderObject(RenderObject child, dynamic slot) { protected override void moveChildRenderObject(RenderObject child, dynamic slot) {
string moveChildRenderObjectErrorMessage = var moveChildRenderObjectErrorMessage =
"Currently we maintain the list in contiguous increasing order, so " + "Currently we maintain the list in contiguous increasing order, so " +
"moving children around is not allowed."; "moving children around is not allowed.";
D.assert(false, () => moveChildRenderObjectErrorMessage); D.assert(false, () => moveChildRenderObjectErrorMessage);
@ -722,7 +729,7 @@ namespace Unity.UIWidgets.widgets {
public override void visitChildren(ElementVisitor visitor) { public override void visitChildren(ElementVisitor visitor) {
foreach (var item in _childElements) { foreach (var item in _childElements) {
visitor(item.Value); visitor(element: item.Value);
} }
} }
@ -733,6 +740,20 @@ namespace Unity.UIWidgets.widgets {
} }
public class ListWheelViewport : RenderObjectWidget { public class ListWheelViewport : RenderObjectWidget {
public readonly ListWheelChildDelegate childDelegate;
public readonly bool clipToSize;
public readonly float diameterRatio;
public readonly float? itemExtent;
public readonly float magnification;
public readonly float offAxisFraction;
public readonly ViewportOffset offset;
public readonly float overAndUnderCenterOpacity;
public readonly float perspective;
public readonly bool renderChildrenOutsideViewport;
public readonly float squeeze;
public readonly bool useMagnifier;
public ListWheelViewport( public ListWheelViewport(
Key key = null, Key key = null,
float diameterRatio = RenderListWheelViewport.defaultDiameterRatio, float diameterRatio = RenderListWheelViewport.defaultDiameterRatio,
@ -774,25 +795,12 @@ namespace Unity.UIWidgets.widgets {
this.childDelegate = childDelegate; this.childDelegate = childDelegate;
} }
public readonly float diameterRatio;
public readonly float perspective;
public readonly float offAxisFraction;
public readonly bool useMagnifier;
public readonly float magnification;
public readonly float overAndUnderCenterOpacity;
public readonly float? itemExtent;
public readonly float squeeze;
public readonly bool clipToSize;
public readonly bool renderChildrenOutsideViewport;
public readonly ViewportOffset offset;
public readonly ListWheelChildDelegate childDelegate;
public override Element createElement() { public override Element createElement() {
return new ListWheelElement(this); return new ListWheelElement(this);
} }
public override RenderObject createRenderObject(BuildContext context) { public override RenderObject createRenderObject(BuildContext context) {
ListWheelElement childManager = (ListWheelElement) context; var childManager = (ListWheelElement) context;
return new RenderListWheelViewport( return new RenderListWheelViewport(
childManager: childManager, childManager: childManager,
offset: offset, offset: offset,
@ -802,7 +810,7 @@ namespace Unity.UIWidgets.widgets {
useMagnifier: useMagnifier, useMagnifier: useMagnifier,
magnification: magnification, magnification: magnification,
overAndUnderCenterOpacity: overAndUnderCenterOpacity, overAndUnderCenterOpacity: overAndUnderCenterOpacity,
itemExtent: itemExtent ?? 1.0f , itemExtent: itemExtent ?? 1.0f,
squeeze: squeeze, squeeze: squeeze,
clipToSize: clipToSize, clipToSize: clipToSize,
renderChildrenOutsideViewport: renderChildrenOutsideViewport renderChildrenOutsideViewport: renderChildrenOutsideViewport

Просмотреть файл

@ -1,4 +1,3 @@
using System;
using Unity.UIWidgets.foundation; using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting; using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui; using Unity.UIWidgets.ui;
@ -28,37 +27,37 @@ namespace Unity.UIWidgets.widgets {
) { ) {
if (it is IPageMetrics) { if (it is IPageMetrics) {
return new PageMetrics( return new PageMetrics(
minScrollExtent: minScrollExtent ?? it.minScrollExtent, minScrollExtent ?? it.minScrollExtent,
maxScrollExtent: maxScrollExtent ?? it.maxScrollExtent, maxScrollExtent ?? it.maxScrollExtent,
pixels: pixels ?? it.pixels, pixels ?? it.pixels,
viewportDimension: viewportDimension ?? it.viewportDimension, viewportDimension ?? it.viewportDimension,
axisDirection: axisDirection ?? it.axisDirection, axisDirection ?? it.axisDirection,
viewportFraction: viewportFraction ?? ((IPageMetrics) it).viewportFraction viewportFraction ?? ((IPageMetrics) it).viewportFraction
); );
} }
if (it is IFixedExtentMetrics) { if (it is IFixedExtentMetrics) {
return new FixedExtentMetrics( return new FixedExtentMetrics(
minScrollExtent: minScrollExtent ?? it.minScrollExtent, minScrollExtent ?? it.minScrollExtent,
maxScrollExtent: maxScrollExtent ?? it.maxScrollExtent, maxScrollExtent ?? it.maxScrollExtent,
pixels: pixels ?? it.pixels, pixels ?? it.pixels,
viewportDimension: viewportDimension ?? it.viewportDimension, viewportDimension ?? it.viewportDimension,
axisDirection: axisDirection ?? it.axisDirection, axisDirection ?? it.axisDirection,
itemIndex: ((IFixedExtentMetrics) it).itemIndex itemIndex: ((IFixedExtentMetrics) it).itemIndex
); );
} }
return new FixedScrollMetrics( return new FixedScrollMetrics(
minScrollExtent: minScrollExtent ?? it.minScrollExtent, minScrollExtent ?? it.minScrollExtent,
maxScrollExtent: maxScrollExtent ?? it.maxScrollExtent, maxScrollExtent ?? it.maxScrollExtent,
pixels: pixels ?? it.pixels, pixels ?? it.pixels,
viewportDimension: viewportDimension ?? it.viewportDimension, viewportDimension ?? it.viewportDimension,
axisDirection: axisDirection ?? it.axisDirection axisDirection ?? it.axisDirection
); );
} }
public static Axis axis(this ScrollMetrics it) { public static Axis axis(this ScrollMetrics it) {
return AxisUtils.axisDirectionToAxis(it.axisDirection); return AxisUtils.axisDirectionToAxis(axisDirection: it.axisDirection);
} }
public static bool outOfRange(this ScrollMetrics it) { public static bool outOfRange(this ScrollMetrics it) {
@ -76,8 +75,8 @@ namespace Unity.UIWidgets.widgets {
public static float extentInside(this ScrollMetrics it) { public static float extentInside(this ScrollMetrics it) {
D.assert(it.minScrollExtent <= it.maxScrollExtent); D.assert(it.minScrollExtent <= it.maxScrollExtent);
return it.viewportDimension return it.viewportDimension
- (it.minScrollExtent - it.pixels).clamp(0, it.viewportDimension) - (it.minScrollExtent - it.pixels).clamp(0, max: it.viewportDimension)
- (it.pixels - it.maxScrollExtent).clamp(0, it.viewportDimension); - (it.pixels - it.maxScrollExtent).clamp(0, max: it.viewportDimension);
} }
public static float extentAfter(this ScrollMetrics it) { public static float extentAfter(this ScrollMetrics it) {
@ -100,15 +99,15 @@ namespace Unity.UIWidgets.widgets {
this.axisDirection = axisDirection; this.axisDirection = axisDirection;
} }
public float minScrollExtent { get; private set; } public float minScrollExtent { get; }
public float maxScrollExtent { get; private set; } public float maxScrollExtent { get; }
public float pixels { get; private set; } public float pixels { get; }
public float viewportDimension { get; private set; } public float viewportDimension { get; }
public AxisDirection axisDirection { get; private set; } public AxisDirection axisDirection { get; }
public override string ToString() { public override string ToString() {
return $"{GetType()}({this.extentBefore():F1})..[{this.extentInside():F1}]..{this.extentAfter():F1})"; return $"{GetType()}({this.extentBefore():F1})..[{this.extentInside():F1}]..{this.extentAfter():F1})";