kg
6 年前
当前提交
410818cb
共有 47 个文件被更改,包括 4567 次插入 和 1522 次删除
-
5Assets/UIWidgets/Tests/Menu.cs
-
2Assets/UIWidgets/foundation/assertions.cs
-
58Assets/UIWidgets/foundation/debug.cs
-
64Assets/UIWidgets/foundation/diagnostics.cs
-
4Assets/UIWidgets/painting/border_radius.cs
-
20Assets/UIWidgets/painting/decoration.cs
-
37Assets/UIWidgets/painting/matrix_utils.cs
-
2Assets/UIWidgets/rendering/automatic_keep_alive.cs
-
857Assets/UIWidgets/rendering/box.cs
-
12Assets/UIWidgets/rendering/editable.cs
-
12Assets/UIWidgets/rendering/flex.cs
-
2Assets/UIWidgets/rendering/image.cs
-
268Assets/UIWidgets/rendering/layer.cs
-
871Assets/UIWidgets/rendering/object.cs
-
237Assets/UIWidgets/rendering/object.mixin.gen.cs
-
72Assets/UIWidgets/rendering/object.mixin.njk
-
12Assets/UIWidgets/rendering/paragraph.cs
-
530Assets/UIWidgets/rendering/proxy_box.cs
-
28Assets/UIWidgets/rendering/proxy_box.mixin.gen.cs
-
28Assets/UIWidgets/rendering/proxy_box.mixin.njk
-
54Assets/UIWidgets/rendering/shifted_box.cs
-
475Assets/UIWidgets/rendering/sliver.cs
-
29Assets/UIWidgets/rendering/sliver_fixed_extent_list.cs
-
33Assets/UIWidgets/rendering/sliver_list.cs
-
151Assets/UIWidgets/rendering/sliver_multi_box_adaptor.cs
-
86Assets/UIWidgets/rendering/sliver_padding.cs
-
46Assets/UIWidgets/rendering/view.cs
-
10Assets/UIWidgets/ui/compositing.cs
-
14Assets/UIWidgets/ui/geometry.cs
-
29Assets/UIWidgets/ui/painting/canvas.cs
-
8Assets/UIWidgets/ui/painting/canvas_impl.cs
-
7Assets/UIWidgets/ui/painting/painting.cs
-
9Assets/UIWidgets/widgets/basic.cs
-
4Assets/UIWidgets/widgets/framework.cs
-
2Assets/UIWidgets/widgets/scroll_controller.cs
-
4Assets/UIWidgets/widgets/scroll_notification.mixin.gen.cs
-
2Assets/UIWidgets/widgets/scroll_notification.mixin.njk
-
2Assets/UIWidgets/widgets/scroll_position.cs
-
12Assets/UIWidgets/widgets/sliver.cs
-
4Assets/UIWidgets/widgets/viewport.cs
-
79Assets/UIWidgets/Tests/ScrollViews.cs
-
3Assets/UIWidgets/Tests/ScrollViews.cs.meta
-
48Assets/UIWidgets/painting/clip.cs
-
3Assets/UIWidgets/painting/clip.cs.meta
-
1001Assets/UIWidgets/rendering/viewport.cs
-
853Assets/UIWidgets/rendering/viewpoint.cs
-
0/Assets/UIWidgets/rendering/viewport.cs.meta
857
Assets/UIWidgets/rendering/box.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
871
Assets/UIWidgets/rendering/object.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
using System; |
|||
using System.Linq; |
|||
using UIWidgets.editor; |
|||
using UIWidgets.painting; |
|||
using UIWidgets.widgets; |
|||
using UnityEditor; |
|||
using UnityEngine; |
|||
using Color = UIWidgets.ui.Color; |
|||
|
|||
namespace UIWidgets.Tests { |
|||
public class ScrollViews : EditorWindow { |
|||
private readonly Func<Widget>[] _options; |
|||
|
|||
private readonly string[] _optionStrings; |
|||
|
|||
private int _selected; |
|||
|
|||
ScrollViews() { |
|||
this._options = new Func<Widget>[] { |
|||
this.none, |
|||
this.listView, |
|||
}; |
|||
this._optionStrings = this._options.Select(x => x.Method.Name).ToArray(); |
|||
this._selected = 0; |
|||
|
|||
this.titleContent = new GUIContent("ScrollViews"); |
|||
} |
|||
|
|||
private WindowAdapter windowAdapter; |
|||
|
|||
[NonSerialized] private bool hasInvoked = false; |
|||
|
|||
void OnGUI() { |
|||
var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings); |
|||
if (selected != this._selected || !this.hasInvoked) { |
|||
this._selected = selected; |
|||
this.hasInvoked = true; |
|||
|
|||
var widget = this._options[this._selected](); |
|||
if (this.windowAdapter != null) { |
|||
this.windowAdapter.attachRootWidget(widget); |
|||
} |
|||
} |
|||
|
|||
if (this.windowAdapter != null) { |
|||
this.windowAdapter.OnGUI(); |
|||
} |
|||
} |
|||
|
|||
void Update() { |
|||
if (this.windowAdapter != null) { |
|||
this.windowAdapter.Update(); |
|||
} |
|||
} |
|||
|
|||
private void OnEnable() { |
|||
this.windowAdapter = new WindowAdapter(this); |
|||
} |
|||
|
|||
void OnDestroy() { |
|||
this.windowAdapter = null; |
|||
} |
|||
|
|||
Widget none() { |
|||
return null; |
|||
} |
|||
|
|||
Widget listView() { |
|||
return ListView.builder( |
|||
itemExtent: 20.0, |
|||
itemBuilder: (context, index) => { |
|||
return new Container( |
|||
color: Color.fromARGB(255, (index * 10) % 256, (index * 10) % 256, (index * 10) % 256) |
|||
); |
|||
} |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b14d32b9a23040969ca3316c86d899c3 |
|||
timeCreated: 1537352615 |
|
|||
using System; |
|||
using UIWidgets.foundation; |
|||
using UIWidgets.ui; |
|||
|
|||
namespace UIWidgets.painting { |
|||
public abstract class ClipContext { |
|||
public abstract Canvas canvas { get; } |
|||
|
|||
void _clipAndPaint(Action<bool> canvasClipCall, Clip clipBehavior, Rect bounds, Action painter) { |
|||
D.assert(canvasClipCall != null); |
|||
|
|||
this.canvas.save(); |
|||
|
|||
switch (clipBehavior) { |
|||
case Clip.none: |
|||
break; |
|||
case Clip.hardEdge: |
|||
canvasClipCall(false); |
|||
break; |
|||
case Clip.antiAlias: |
|||
canvasClipCall(true); |
|||
break; |
|||
case Clip.antiAliasWithSaveLayer: |
|||
canvasClipCall(true); |
|||
this.canvas.saveLayer(bounds, new Paint()); |
|||
break; |
|||
} |
|||
|
|||
painter(); |
|||
|
|||
if (clipBehavior == Clip.antiAliasWithSaveLayer) { |
|||
this.canvas.restore(); |
|||
} |
|||
|
|||
this.canvas.restore(); |
|||
} |
|||
|
|||
public void clipRRectAndPaint(RRect rrect, Clip clipBehavior, Rect bounds, Action painter) { |
|||
this._clipAndPaint(doAntiAias => this.canvas.clipRRect(rrect, doAntiAlias: doAntiAias), |
|||
clipBehavior, bounds, painter); |
|||
} |
|||
|
|||
public void clipRectAndPaint(Rect rect, Clip clipBehavior, Rect bounds, Action painter) { |
|||
this._clipAndPaint(doAntiAias => this.canvas.clipRect(rect, doAntiAlias: doAntiAias), |
|||
clipBehavior, bounds, painter); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: cff14a26e8ec47a594a157246716b378 |
|||
timeCreated: 1537611888 |
1001
Assets/UIWidgets/rendering/viewport.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UIWidgets.painting; |
|||
using UIWidgets.ui; |
|||
using UnityEngine; |
|||
using Rect = UIWidgets.ui.Rect; |
|||
|
|||
namespace UIWidgets.rendering { |
|||
public interface RenderAbstractViewport { |
|||
RevealedOffset getOffsetToReveal(RenderObject target, double alignment, Rect rect = null); |
|||
} |
|||
|
|||
public static class RenderAbstractViewportUtils { |
|||
public static RenderAbstractViewport of(RenderObject obj) { |
|||
while (obj != null) { |
|||
if (obj is RenderAbstractViewport) { |
|||
return (RenderAbstractViewport) obj; |
|||
} |
|||
|
|||
obj = (RenderObject) obj.parent; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public const double defaultCacheExtent = 250.0; |
|||
} |
|||
|
|||
public class RevealedOffset { |
|||
public RevealedOffset(double offset, Rect rect) { |
|||
this.offset = offset; |
|||
this.rect = rect; |
|||
} |
|||
|
|||
public readonly double offset; |
|||
public readonly Rect rect; |
|||
} |
|||
|
|||
public abstract class RenderViewportBase<ParentDataClass> : |
|||
ContainerRenderObjectMixinRenderBox<RenderSliver, ParentDataClass>, |
|||
RenderAbstractViewport |
|||
where ParentDataClass : ParentData, ContainerParentDataMixin<RenderSliver> { |
|||
protected RenderViewportBase( |
|||
AxisDirection axisDirection = AxisDirection.down, |
|||
AxisDirection crossAxisDirection = AxisDirection.right, |
|||
ViewportOffset offset = null, |
|||
double? cacheExtent = null |
|||
) { |
|||
this._axisDirection = axisDirection; |
|||
this._crossAxisDirection = crossAxisDirection; |
|||
this._offset = offset; |
|||
this._cacheExtent = cacheExtent ?? RenderAbstractViewportUtils.defaultCacheExtent; |
|||
} |
|||
|
|||
public AxisDirection axisDirection { |
|||
get { return this._axisDirection; } |
|||
set { |
|||
if (value == this._axisDirection) { |
|||
return; |
|||
} |
|||
|
|||
this._axisDirection = value; |
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public AxisDirection _axisDirection; |
|||
|
|||
public AxisDirection crossAxisDirection { |
|||
get { return this._crossAxisDirection; } |
|||
set { |
|||
if (value == this._crossAxisDirection) { |
|||
return; |
|||
} |
|||
|
|||
this._crossAxisDirection = value; |
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public AxisDirection _crossAxisDirection; |
|||
|
|||
public Axis axis { |
|||
get { return AxisUtils.axisDirectionToAxis(this.axisDirection); } |
|||
} |
|||
|
|||
public ViewportOffset offset { |
|||
get { return this._offset; } |
|||
set { |
|||
if (object.Equals(value, this._offset)) { |
|||
return; |
|||
} |
|||
|
|||
if (this.attached) { |
|||
this._offset.removeListener(this.markNeedsLayout); |
|||
} |
|||
|
|||
this._offset = value; |
|||
if (this.attached) { |
|||
this._offset.addListener(this.markNeedsLayout); |
|||
} |
|||
|
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public ViewportOffset _offset; |
|||
|
|||
public double cacheExtent { |
|||
get { return this._cacheExtent; } |
|||
set { |
|||
if (value == this._cacheExtent) { |
|||
return; |
|||
} |
|||
|
|||
this._cacheExtent = value; |
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public double _cacheExtent; |
|||
|
|||
public override void attach(object owner) { |
|||
base.attach(owner); |
|||
this._offset.addListener(this.markNeedsLayout); |
|||
} |
|||
|
|||
public override void detach() { |
|||
this._offset.removeListener(this.markNeedsLayout); |
|||
base.detach(); |
|||
} |
|||
|
|||
public override double computeMinIntrinsicWidth(double height) { |
|||
return 0.0; |
|||
} |
|||
|
|||
public override double computeMaxIntrinsicWidth(double height) { |
|||
return 0.0; |
|||
} |
|||
|
|||
public override double computeMinIntrinsicHeight(double width) { |
|||
return 0.0; |
|||
} |
|||
|
|||
public override double computeMaxIntrinsicHeight(double width) { |
|||
return 0.0; |
|||
} |
|||
|
|||
public override bool isRepaintBoundary { |
|||
get { return true; } |
|||
} |
|||
|
|||
public double layoutChildSequence( |
|||
RenderSliver child, |
|||
double scrollOffset, |
|||
double overlap, |
|||
double layoutOffset, |
|||
double remainingPaintExtent, |
|||
double mainAxisExtent, |
|||
double crossAxisExtent, |
|||
GrowthDirection growthDirection, |
|||
Func<RenderSliver, RenderSliver> advance, |
|||
double remainingCacheExtent, |
|||
double cacheOrigin |
|||
) { |
|||
double initialLayoutOffset = layoutOffset; |
|||
|
|||
ScrollDirection adjustedUserScrollDirection = |
|||
GrowthDirectionUtils.applyGrowthDirectionToScrollDirection( |
|||
this.offset.userScrollDirection, growthDirection); |
|||
|
|||
double maxPaintOffset = layoutOffset + overlap; |
|||
|
|||
while (child != null) { |
|||
double sliverScrollOffset = scrollOffset <= 0.0 ? 0.0 : scrollOffset; |
|||
double correctedCacheOrigin = Math.Max(cacheOrigin, -sliverScrollOffset); |
|||
double cacheExtentCorrection = cacheOrigin - correctedCacheOrigin; |
|||
|
|||
child.layout(new SliverConstraints( |
|||
axisDirection: this.axisDirection, |
|||
growthDirection: growthDirection, |
|||
userScrollDirection: adjustedUserScrollDirection, |
|||
scrollOffset: sliverScrollOffset, |
|||
overlap: maxPaintOffset - layoutOffset, |
|||
remainingPaintExtent: Math.Max(0.0, remainingPaintExtent - layoutOffset + initialLayoutOffset), |
|||
crossAxisExtent: crossAxisExtent, |
|||
crossAxisDirection: this.crossAxisDirection, |
|||
viewportMainAxisExtent: mainAxisExtent, |
|||
remainingCacheExtent: Math.Max(0.0, remainingCacheExtent + cacheExtentCorrection), |
|||
cacheOrigin: correctedCacheOrigin |
|||
), parentUsesSize: true); |
|||
|
|||
var childLayoutGeometry = child.geometry; |
|||
|
|||
if (childLayoutGeometry.scrollOffsetCorrection != 0.0) { |
|||
return childLayoutGeometry.scrollOffsetCorrection; |
|||
} |
|||
|
|||
double effectiveLayoutOffset = layoutOffset + childLayoutGeometry.paintOrigin; |
|||
|
|||
if (childLayoutGeometry.visible || scrollOffset > 0) { |
|||
this.updateChildLayoutOffset(child, effectiveLayoutOffset, growthDirection); |
|||
} else { |
|||
this.updateChildLayoutOffset(child, -scrollOffset + initialLayoutOffset, growthDirection); |
|||
} |
|||
|
|||
maxPaintOffset = Math.Max(effectiveLayoutOffset + childLayoutGeometry.paintExtent, maxPaintOffset); |
|||
scrollOffset -= childLayoutGeometry.scrollExtent; |
|||
layoutOffset += childLayoutGeometry.layoutExtent; |
|||
|
|||
if (childLayoutGeometry.cacheExtent != 0.0) { |
|||
remainingCacheExtent -= childLayoutGeometry.cacheExtent - cacheExtentCorrection; |
|||
cacheOrigin = Math.Min(correctedCacheOrigin + childLayoutGeometry.cacheExtent, 0.0); |
|||
} |
|||
|
|||
this.updateOutOfBandData(growthDirection, childLayoutGeometry); |
|||
|
|||
child = advance(child); |
|||
} |
|||
|
|||
return 0.0; |
|||
} |
|||
|
|||
public override void paint(PaintingContext context, Offset offset) { |
|||
if (this.firstChild == null) { |
|||
return; |
|||
} |
|||
|
|||
if (this.hasVisualOverflow) { |
|||
context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size, this._paintContents); |
|||
} else { |
|||
this._paintContents(context, offset); |
|||
} |
|||
} |
|||
|
|||
public void _paintContents(PaintingContext context, Offset offset) { |
|||
foreach (RenderSliver child in this.childrenInPaintOrder) { |
|||
if (child.geometry.visible) { |
|||
context.paintChild(child, offset + this.paintOffsetOf(child)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public RevealedOffset getOffsetToReveal(RenderObject target, double alignment, Rect rect = null) { |
|||
double leadingScrollOffset = 0.0; |
|||
double targetMainAxisExtent = 0.0; |
|||
RenderObject descendant; |
|||
rect = rect ?? target.paintBounds; |
|||
|
|||
Matrix4x4 transform; |
|||
|
|||
if (target is RenderBox) { |
|||
RenderBox targetBox = (RenderBox) target; |
|||
|
|||
RenderBox pivot = targetBox; |
|||
while (pivot.parent is RenderBox) { |
|||
pivot = (RenderBox) pivot.parent; |
|||
} |
|||
|
|||
RenderSliver pivotParent = (RenderSliver) pivot.parent; |
|||
|
|||
transform = targetBox.getTransformTo(pivot); |
|||
Rect bounds = MatrixUtils.transformRect(transform, rect); |
|||
|
|||
double offset = 0.0; |
|||
|
|||
GrowthDirection growthDirection = pivotParent.constraints.growthDirection; |
|||
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(this.axisDirection, growthDirection)) { |
|||
case AxisDirection.up: |
|||
switch (growthDirection) { |
|||
case GrowthDirection.forward: |
|||
offset = bounds.bottom; |
|||
break; |
|||
case GrowthDirection.reverse: |
|||
offset = bounds.top; |
|||
break; |
|||
} |
|||
|
|||
leadingScrollOffset = pivot.size.height - offset; |
|||
targetMainAxisExtent = bounds.height; |
|||
break; |
|||
case AxisDirection.right: |
|||
leadingScrollOffset = bounds.left; |
|||
targetMainAxisExtent = bounds.width; |
|||
break; |
|||
case AxisDirection.down: |
|||
leadingScrollOffset = bounds.top; |
|||
targetMainAxisExtent = bounds.height; |
|||
break; |
|||
case AxisDirection.left: |
|||
switch (growthDirection) { |
|||
case GrowthDirection.forward: |
|||
offset = bounds.right; |
|||
break; |
|||
case GrowthDirection.reverse: |
|||
offset = bounds.left; |
|||
break; |
|||
} |
|||
|
|||
leadingScrollOffset = pivot.size.width - offset; |
|||
targetMainAxisExtent = bounds.width; |
|||
break; |
|||
} |
|||
|
|||
descendant = pivot; |
|||
} else if (target is RenderSliver) { |
|||
RenderSliver targetSliver = (RenderSliver) target; |
|||
leadingScrollOffset = 0.0; |
|||
targetMainAxisExtent = targetSliver.geometry.scrollExtent; |
|||
descendant = targetSliver; |
|||
} else { |
|||
return new RevealedOffset(offset: this.offset.pixels, rect: rect); |
|||
} |
|||
|
|||
RenderObject child = descendant; |
|||
while (child.parent is RenderSliver) { |
|||
var parent = (RenderSliver) child.parent; |
|||
leadingScrollOffset += parent.childScrollOffset(child); |
|||
child = parent; |
|||
} |
|||
|
|||
RenderSliver sliver = (RenderSliver) child; |
|||
double extentOfPinnedSlivers = this.maxScrollObstructionExtentBefore(sliver); |
|||
leadingScrollOffset = this.scrollOffsetOf(sliver, leadingScrollOffset); |
|||
switch (sliver.constraints.growthDirection) { |
|||
case GrowthDirection.forward: |
|||
leadingScrollOffset -= extentOfPinnedSlivers; |
|||
break; |
|||
case GrowthDirection.reverse: |
|||
break; |
|||
} |
|||
|
|||
double mainAxisExtent = 0.0; |
|||
switch (this.axis) { |
|||
case Axis.horizontal: |
|||
mainAxisExtent = this.size.width - extentOfPinnedSlivers; |
|||
break; |
|||
case Axis.vertical: |
|||
mainAxisExtent = this.size.height - extentOfPinnedSlivers; |
|||
break; |
|||
} |
|||
|
|||
double targetOffset = leadingScrollOffset - (mainAxisExtent - targetMainAxisExtent) * alignment; |
|||
double offsetDifference = this.offset.pixels - targetOffset; |
|||
|
|||
transform = target.getTransformTo(this); |
|||
this.applyPaintTransform(child, ref transform); |
|||
Rect targetRect = MatrixUtils.transformRect(transform, rect); |
|||
|
|||
switch (this.axisDirection) { |
|||
case AxisDirection.down: |
|||
targetRect = targetRect.translate(0.0, offsetDifference); |
|||
break; |
|||
case AxisDirection.right: |
|||
targetRect = targetRect.translate(offsetDifference, 0.0); |
|||
break; |
|||
case AxisDirection.up: |
|||
targetRect = targetRect.translate(0.0, -offsetDifference); |
|||
break; |
|||
case AxisDirection.left: |
|||
targetRect = targetRect.translate(-offsetDifference, 0.0); |
|||
break; |
|||
} |
|||
|
|||
return new RevealedOffset(offset: targetOffset, rect: targetRect); |
|||
} |
|||
|
|||
public Offset computeAbsolutePaintOffset(RenderSliver child, double layoutOffset, |
|||
GrowthDirection growthDirection) { |
|||
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(this.axisDirection, growthDirection)) { |
|||
case AxisDirection.up: |
|||
return new Offset(0.0, this.size.height - (layoutOffset + child.geometry.paintExtent)); |
|||
case AxisDirection.right: |
|||
return new Offset(layoutOffset, 0.0); |
|||
case AxisDirection.down: |
|||
return new Offset(0.0, layoutOffset); |
|||
case AxisDirection.left: |
|||
return new Offset(this.size.width - (layoutOffset + child.geometry.paintExtent), 0.0); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
|
|||
public abstract bool hasVisualOverflow { get; } |
|||
|
|||
public abstract void updateOutOfBandData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry); |
|||
|
|||
public abstract void updateChildLayoutOffset(RenderSliver child, double layoutOffset, |
|||
GrowthDirection growthDirection); |
|||
|
|||
public abstract Offset paintOffsetOf(RenderSliver child); |
|||
|
|||
public abstract double scrollOffsetOf(RenderSliver child, double scrollOffsetWithinChild); |
|||
|
|||
public abstract double maxScrollObstructionExtentBefore(RenderSliver child); |
|||
|
|||
public abstract IEnumerable<RenderSliver> childrenInPaintOrder { get; } |
|||
} |
|||
|
|||
|
|||
public class RenderViewport : RenderViewportBase<SliverPhysicalContainerParentData> { |
|||
public RenderViewport( |
|||
AxisDirection axisDirection = AxisDirection.down, |
|||
AxisDirection crossAxisDirection = AxisDirection.right, |
|||
ViewportOffset offset = null, |
|||
double anchor = 0.0, |
|||
List<RenderSliver> children = null, |
|||
RenderSliver center = null, |
|||
double? cacheExtent = null |
|||
) : base(axisDirection, crossAxisDirection, offset, cacheExtent) { |
|||
this.addAll(children); |
|||
if (center == null && this.firstChild != null) { |
|||
this._center = this.firstChild; |
|||
} |
|||
} |
|||
|
|||
public override void setupParentData(RenderObject child) { |
|||
if (!(child.parentData is SliverPhysicalContainerParentData)) { |
|||
child.parentData = new SliverPhysicalContainerParentData(); |
|||
} |
|||
} |
|||
|
|||
public double anchor { |
|||
get { return this._anchor; } |
|||
set { |
|||
if (value != this._anchor) { |
|||
return; |
|||
} |
|||
|
|||
this._anchor = value; |
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public double _anchor; |
|||
|
|||
public RenderSliver center { |
|||
get { return this._center; } |
|||
set { |
|||
if (value == this._center) { |
|||
return; |
|||
} |
|||
|
|||
this._center = value; |
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public RenderSliver _center; |
|||
|
|||
public override bool sizedByParent { |
|||
get { return true; } |
|||
} |
|||
|
|||
public override void performResize() { |
|||
this.size = this.constraints.biggest; |
|||
|
|||
switch (this.axis) { |
|||
case Axis.vertical: |
|||
this.offset.applyViewportDimension(this.size.height); |
|||
break; |
|||
case Axis.horizontal: |
|||
this.offset.applyViewportDimension(this.size.width); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public const int _maxLayoutCycles = 10; |
|||
|
|||
public double _minScrollExtent; |
|||
public double _maxScrollExtent; |
|||
public bool _hasVisualOverflow = false; |
|||
|
|||
public override void performLayout() { |
|||
if (this.center == null) { |
|||
this._minScrollExtent = 0.0; |
|||
this._maxScrollExtent = 0.0; |
|||
this._hasVisualOverflow = false; |
|||
this.offset.applyContentDimensions(0.0, 0.0); |
|||
return; |
|||
} |
|||
|
|||
double mainAxisExtent = 0.0; |
|||
double crossAxisExtent = 0.0; |
|||
switch (this.axis) { |
|||
case Axis.vertical: |
|||
mainAxisExtent = this.size.height; |
|||
crossAxisExtent = this.size.width; |
|||
break; |
|||
case Axis.horizontal: |
|||
mainAxisExtent = this.size.width; |
|||
crossAxisExtent = this.size.height; |
|||
break; |
|||
} |
|||
|
|||
double centerOffsetAdjustment = this.center.centerOffsetAdjustment; |
|||
|
|||
int count = 0; |
|||
do { |
|||
var correction = this._attemptLayout(mainAxisExtent, crossAxisExtent, |
|||
this.offset.pixels + centerOffsetAdjustment); |
|||
if (correction != 0.0) { |
|||
this.offset.correctBy(correction); |
|||
} else { |
|||
if (this.offset.applyContentDimensions( |
|||
Math.Min(0.0, this._minScrollExtent + mainAxisExtent * this.anchor), |
|||
Math.Max(0.0, this._maxScrollExtent - mainAxisExtent * (1.0 - this.anchor)) |
|||
)) |
|||
break; |
|||
} |
|||
|
|||
count += 1; |
|||
} while (count < RenderViewport._maxLayoutCycles); |
|||
} |
|||
|
|||
public double _attemptLayout(double mainAxisExtent, double crossAxisExtent, double correctedOffset) { |
|||
this._minScrollExtent = 0.0; |
|||
this._maxScrollExtent = 0.0; |
|||
this._hasVisualOverflow = false; |
|||
|
|||
double centerOffset = mainAxisExtent * this.anchor - correctedOffset; |
|||
double reverseDirectionRemainingPaintExtent = centerOffset.clamp(0.0, mainAxisExtent); |
|||
double forwardDirectionRemainingPaintExtent = (mainAxisExtent - centerOffset).clamp(0.0, mainAxisExtent); |
|||
|
|||
double fullCacheExtent = mainAxisExtent + 2 * this.cacheExtent; |
|||
double centerCacheOffset = centerOffset + this.cacheExtent; |
|||
double reverseDirectionRemainingCacheExtent = centerCacheOffset.clamp(0.0, fullCacheExtent); |
|||
double forwardDirectionRemainingCacheExtent = |
|||
(fullCacheExtent - centerCacheOffset).clamp(0.0, fullCacheExtent); |
|||
|
|||
RenderSliver leadingNegativeChild = this.childBefore(this.center); |
|||
|
|||
if (leadingNegativeChild != null) { |
|||
double result = this.layoutChildSequence( |
|||
child: leadingNegativeChild, |
|||
scrollOffset: Math.Max(mainAxisExtent, centerOffset) - mainAxisExtent, |
|||
overlap: 0.0, |
|||
layoutOffset: forwardDirectionRemainingPaintExtent, |
|||
remainingPaintExtent: reverseDirectionRemainingPaintExtent, |
|||
mainAxisExtent: mainAxisExtent, |
|||
crossAxisExtent: crossAxisExtent, |
|||
growthDirection: GrowthDirection.reverse, |
|||
advance: this.childBefore, |
|||
remainingCacheExtent: reverseDirectionRemainingCacheExtent, |
|||
cacheOrigin: (mainAxisExtent - centerOffset).clamp(-this.cacheExtent, 0.0) |
|||
); |
|||
if (result != 0.0) { |
|||
return -result; |
|||
} |
|||
} |
|||
|
|||
return this.layoutChildSequence( |
|||
child: this.center, |
|||
scrollOffset: Math.Max(0.0, -centerOffset), |
|||
overlap: leadingNegativeChild == null ? Math.Min(0.0, -centerOffset) : 0.0, |
|||
layoutOffset: centerOffset >= mainAxisExtent ? centerOffset : reverseDirectionRemainingPaintExtent, |
|||
remainingPaintExtent: forwardDirectionRemainingPaintExtent, |
|||
mainAxisExtent: mainAxisExtent, |
|||
crossAxisExtent: crossAxisExtent, |
|||
growthDirection: GrowthDirection.forward, |
|||
advance: this.childAfter, |
|||
remainingCacheExtent: forwardDirectionRemainingCacheExtent, |
|||
cacheOrigin: centerOffset.clamp(-this.cacheExtent, 0.0) |
|||
); |
|||
} |
|||
|
|||
public override bool hasVisualOverflow { |
|||
get { return this._hasVisualOverflow; } |
|||
} |
|||
|
|||
public override void updateOutOfBandData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry) { |
|||
switch (growthDirection) { |
|||
case GrowthDirection.forward: |
|||
this._maxScrollExtent += childLayoutGeometry.scrollExtent; |
|||
break; |
|||
case GrowthDirection.reverse: |
|||
this._minScrollExtent -= childLayoutGeometry.scrollExtent; |
|||
break; |
|||
} |
|||
|
|||
if (childLayoutGeometry.hasVisualOverflow) { |
|||
this._hasVisualOverflow = true; |
|||
} |
|||
} |
|||
|
|||
public override void updateChildLayoutOffset(RenderSliver child, double layoutOffset, |
|||
GrowthDirection growthDirection) { |
|||
var childParentData = (SliverPhysicalParentData) child.parentData; |
|||
childParentData.paintOffset = this.computeAbsolutePaintOffset(child, layoutOffset, growthDirection); |
|||
} |
|||
|
|||
public override Offset paintOffsetOf(RenderSliver child) { |
|||
var childParentData = (SliverPhysicalParentData) child.parentData; |
|||
return childParentData.paintOffset; |
|||
} |
|||
|
|||
public override double scrollOffsetOf(RenderSliver child, double scrollOffsetWithinChild) { |
|||
GrowthDirection growthDirection = child.constraints.growthDirection; |
|||
switch (growthDirection) { |
|||
case GrowthDirection.forward: { |
|||
double scrollOffsetToChild = 0.0; |
|||
RenderSliver current = this.center; |
|||
while (current != child) { |
|||
scrollOffsetToChild += current.geometry.scrollExtent; |
|||
current = this.childAfter(current); |
|||
} |
|||
|
|||
return scrollOffsetToChild + scrollOffsetWithinChild; |
|||
} |
|||
case GrowthDirection.reverse: { |
|||
double scrollOffsetToChild = 0.0; |
|||
RenderSliver current = this.childBefore(this.center); |
|||
while (current != child) { |
|||
scrollOffsetToChild -= current.geometry.scrollExtent; |
|||
current = this.childBefore(current); |
|||
} |
|||
|
|||
return scrollOffsetToChild - scrollOffsetWithinChild; |
|||
} |
|||
} |
|||
|
|||
return 0.0; |
|||
} |
|||
|
|||
public override double maxScrollObstructionExtentBefore(RenderSliver child) { |
|||
GrowthDirection growthDirection = child.constraints.growthDirection; |
|||
switch (growthDirection) { |
|||
case GrowthDirection.forward: { |
|||
double pinnedExtent = 0.0; |
|||
RenderSliver current = this.center; |
|||
while (current != child) { |
|||
pinnedExtent += current.geometry.maxScrollObstructionExtent; |
|||
current = this.childAfter(current); |
|||
} |
|||
|
|||
return pinnedExtent; |
|||
} |
|||
case GrowthDirection.reverse: { |
|||
double pinnedExtent = 0.0; |
|||
RenderSliver current = this.childBefore(this.center); |
|||
while (current != child) { |
|||
pinnedExtent += current.geometry.maxScrollObstructionExtent; |
|||
current = this.childBefore(current); |
|||
} |
|||
|
|||
return pinnedExtent; |
|||
} |
|||
} |
|||
|
|||
return 0.0; |
|||
} |
|||
|
|||
public override void applyPaintTransform(RenderObject child, ref Matrix4x4 transform) { |
|||
var childParentData = (SliverPhysicalParentData) child.parentData; |
|||
childParentData.applyPaintTransform(ref transform); |
|||
} |
|||
|
|||
public override IEnumerable<RenderSliver> childrenInPaintOrder { |
|||
get { |
|||
if (this.firstChild == null) { |
|||
yield break; |
|||
} |
|||
|
|||
var child = this.firstChild; |
|||
while (child != this.center) { |
|||
yield return child; |
|||
child = this.childAfter(child); |
|||
} |
|||
|
|||
child = this.lastChild; |
|||
while (true) { |
|||
yield return child; |
|||
if (child == this.center) { |
|||
yield break; |
|||
} |
|||
|
|||
child = this.childBefore(child); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public class RenderShrinkWrappingViewport : RenderViewportBase<SliverLogicalContainerParentData> { |
|||
public RenderShrinkWrappingViewport( |
|||
AxisDirection axisDirection = AxisDirection.down, |
|||
AxisDirection crossAxisDirection = AxisDirection.right, |
|||
ViewportOffset offset = null, |
|||
List<RenderSliver> children = null |
|||
) : base( |
|||
axisDirection: axisDirection, |
|||
crossAxisDirection: crossAxisDirection, |
|||
offset: offset) { |
|||
this.addAll(children); |
|||
} |
|||
|
|||
public override void setupParentData(RenderObject child) { |
|||
if (!(child.parentData is SliverLogicalContainerParentData)) { |
|||
child.parentData = new SliverLogicalContainerParentData(); |
|||
} |
|||
} |
|||
|
|||
public double _maxScrollExtent = 0.0; |
|||
public double _shrinkWrapExtent = 0.0; |
|||
public bool _hasVisualOverflow = false; |
|||
|
|||
public override void performLayout() { |
|||
if (this.firstChild == null) { |
|||
switch (this.axis) { |
|||
case Axis.vertical: |
|||
this.size = new Size(this.constraints.maxWidth, this.constraints.minHeight); |
|||
break; |
|||
case Axis.horizontal: |
|||
this.size = new Size(this.constraints.minWidth, this.constraints.maxHeight); |
|||
break; |
|||
} |
|||
|
|||
this.offset.applyViewportDimension(0.0); |
|||
this._maxScrollExtent = 0.0; |
|||
this._shrinkWrapExtent = 0.0; |
|||
this._hasVisualOverflow = false; |
|||
this.offset.applyContentDimensions(0.0, 0.0); |
|||
return; |
|||
} |
|||
|
|||
double mainAxisExtent = 0.0; |
|||
double crossAxisExtent = 0.0; |
|||
switch (this.axis) { |
|||
case Axis.vertical: |
|||
mainAxisExtent = this.constraints.maxHeight; |
|||
crossAxisExtent = this.constraints.maxWidth; |
|||
break; |
|||
case Axis.horizontal: |
|||
mainAxisExtent = this.constraints.maxWidth; |
|||
crossAxisExtent = this.constraints.maxHeight; |
|||
break; |
|||
} |
|||
|
|||
double effectiveExtent = 0.0; |
|||
do { |
|||
var correction = this._attemptLayout(mainAxisExtent, crossAxisExtent, this.offset.pixels); |
|||
if (correction != 0.0) { |
|||
this.offset.correctBy(correction); |
|||
} else { |
|||
switch (this.axis) { |
|||
case Axis.vertical: |
|||
effectiveExtent = this.constraints.constrainHeight(this._shrinkWrapExtent); |
|||
break; |
|||
case Axis.horizontal: |
|||
effectiveExtent = this.constraints.constrainWidth(this._shrinkWrapExtent); |
|||
break; |
|||
} |
|||
|
|||
bool didAcceptViewportDimension = this.offset.applyViewportDimension(effectiveExtent); |
|||
bool didAcceptContentDimension = |
|||
this.offset.applyContentDimensions(0.0, Math.Max(0.0, this._maxScrollExtent - effectiveExtent)); |
|||
if (didAcceptViewportDimension && didAcceptContentDimension) { |
|||
break; |
|||
} |
|||
} |
|||
} while (true); |
|||
|
|||
switch (this.axis) { |
|||
case Axis.vertical: |
|||
this.size = this.constraints.constrainDimensions(crossAxisExtent, effectiveExtent); |
|||
break; |
|||
case Axis.horizontal: |
|||
this.size = this.constraints.constrainDimensions(effectiveExtent, crossAxisExtent); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public double _attemptLayout(double mainAxisExtent, double crossAxisExtent, double correctedOffset) { |
|||
this._maxScrollExtent = 0.0; |
|||
this._shrinkWrapExtent = 0.0; |
|||
this._hasVisualOverflow = false; |
|||
return this.layoutChildSequence( |
|||
child: this.firstChild, |
|||
scrollOffset: Math.Max(0.0, correctedOffset), |
|||
overlap: Math.Min(0.0, correctedOffset), |
|||
layoutOffset: 0.0, |
|||
remainingPaintExtent: mainAxisExtent, |
|||
mainAxisExtent: mainAxisExtent, |
|||
crossAxisExtent: crossAxisExtent, |
|||
growthDirection: GrowthDirection.forward, |
|||
advance: this.childAfter, |
|||
remainingCacheExtent: mainAxisExtent + 2 * this.cacheExtent, |
|||
cacheOrigin: -this.cacheExtent |
|||
); |
|||
} |
|||
|
|||
public override bool hasVisualOverflow { |
|||
get { return this._hasVisualOverflow; } |
|||
} |
|||
|
|||
public override void updateOutOfBandData(GrowthDirection growthDirection, SliverGeometry childLayoutGeometry) { |
|||
this._maxScrollExtent += childLayoutGeometry.scrollExtent; |
|||
if (childLayoutGeometry.hasVisualOverflow) { |
|||
this._hasVisualOverflow = true; |
|||
} |
|||
|
|||
this._shrinkWrapExtent += childLayoutGeometry.maxPaintExtent; |
|||
} |
|||
|
|||
public override void updateChildLayoutOffset(RenderSliver child, double layoutOffset, |
|||
GrowthDirection growthDirection) { |
|||
var childParentData = (SliverLogicalParentData) child.parentData; |
|||
childParentData.layoutOffset = layoutOffset; |
|||
} |
|||
|
|||
public override Offset paintOffsetOf(RenderSliver child) { |
|||
var childParentData = (SliverLogicalParentData) child.parentData; |
|||
return this.computeAbsolutePaintOffset(child, childParentData.layoutOffset, GrowthDirection.forward); |
|||
} |
|||
|
|||
public override double scrollOffsetOf(RenderSliver child, double scrollOffsetWithinChild) { |
|||
double scrollOffsetToChild = 0.0; |
|||
RenderSliver current = this.firstChild; |
|||
while (current != child) { |
|||
scrollOffsetToChild += current.geometry.scrollExtent; |
|||
current = this.childAfter(current); |
|||
} |
|||
|
|||
return scrollOffsetToChild + scrollOffsetWithinChild; |
|||
} |
|||
|
|||
public override double maxScrollObstructionExtentBefore(RenderSliver child) { |
|||
double pinnedExtent = 0.0; |
|||
RenderSliver current = this.firstChild; |
|||
while (current != child) { |
|||
pinnedExtent += current.geometry.maxScrollObstructionExtent; |
|||
current = this.childAfter(current); |
|||
} |
|||
|
|||
return pinnedExtent; |
|||
} |
|||
|
|||
public override void applyPaintTransform(RenderObject child, ref Matrix4x4 transform) { |
|||
Offset offset = this.paintOffsetOf((RenderSliver) child); |
|||
transform = Matrix4x4.Translate(offset.toVector()) * transform; |
|||
} |
|||
|
|||
public override IEnumerable<RenderSliver> childrenInPaintOrder { |
|||
get { |
|||
RenderSliver child = this.firstChild; |
|||
while (child != null) { |
|||
yield return child; |
|||
child = this.childAfter(child); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue