浏览代码

scroller updates.

/main
kg 6 年前
当前提交
410818cb
共有 47 个文件被更改,包括 4567 次插入1522 次删除
  1. 5
      Assets/UIWidgets/Tests/Menu.cs
  2. 2
      Assets/UIWidgets/foundation/assertions.cs
  3. 58
      Assets/UIWidgets/foundation/debug.cs
  4. 64
      Assets/UIWidgets/foundation/diagnostics.cs
  5. 4
      Assets/UIWidgets/painting/border_radius.cs
  6. 20
      Assets/UIWidgets/painting/decoration.cs
  7. 37
      Assets/UIWidgets/painting/matrix_utils.cs
  8. 2
      Assets/UIWidgets/rendering/automatic_keep_alive.cs
  9. 857
      Assets/UIWidgets/rendering/box.cs
  10. 12
      Assets/UIWidgets/rendering/editable.cs
  11. 12
      Assets/UIWidgets/rendering/flex.cs
  12. 2
      Assets/UIWidgets/rendering/image.cs
  13. 268
      Assets/UIWidgets/rendering/layer.cs
  14. 871
      Assets/UIWidgets/rendering/object.cs
  15. 237
      Assets/UIWidgets/rendering/object.mixin.gen.cs
  16. 72
      Assets/UIWidgets/rendering/object.mixin.njk
  17. 12
      Assets/UIWidgets/rendering/paragraph.cs
  18. 530
      Assets/UIWidgets/rendering/proxy_box.cs
  19. 28
      Assets/UIWidgets/rendering/proxy_box.mixin.gen.cs
  20. 28
      Assets/UIWidgets/rendering/proxy_box.mixin.njk
  21. 54
      Assets/UIWidgets/rendering/shifted_box.cs
  22. 475
      Assets/UIWidgets/rendering/sliver.cs
  23. 29
      Assets/UIWidgets/rendering/sliver_fixed_extent_list.cs
  24. 33
      Assets/UIWidgets/rendering/sliver_list.cs
  25. 151
      Assets/UIWidgets/rendering/sliver_multi_box_adaptor.cs
  26. 86
      Assets/UIWidgets/rendering/sliver_padding.cs
  27. 46
      Assets/UIWidgets/rendering/view.cs
  28. 10
      Assets/UIWidgets/ui/compositing.cs
  29. 14
      Assets/UIWidgets/ui/geometry.cs
  30. 29
      Assets/UIWidgets/ui/painting/canvas.cs
  31. 8
      Assets/UIWidgets/ui/painting/canvas_impl.cs
  32. 7
      Assets/UIWidgets/ui/painting/painting.cs
  33. 9
      Assets/UIWidgets/widgets/basic.cs
  34. 4
      Assets/UIWidgets/widgets/framework.cs
  35. 2
      Assets/UIWidgets/widgets/scroll_controller.cs
  36. 4
      Assets/UIWidgets/widgets/scroll_notification.mixin.gen.cs
  37. 2
      Assets/UIWidgets/widgets/scroll_notification.mixin.njk
  38. 2
      Assets/UIWidgets/widgets/scroll_position.cs
  39. 12
      Assets/UIWidgets/widgets/sliver.cs
  40. 4
      Assets/UIWidgets/widgets/viewport.cs
  41. 79
      Assets/UIWidgets/Tests/ScrollViews.cs
  42. 3
      Assets/UIWidgets/Tests/ScrollViews.cs.meta
  43. 48
      Assets/UIWidgets/painting/clip.cs
  44. 3
      Assets/UIWidgets/painting/clip.cs.meta
  45. 1001
      Assets/UIWidgets/rendering/viewport.cs
  46. 853
      Assets/UIWidgets/rendering/viewpoint.cs
  47. 0
      /Assets/UIWidgets/rendering/viewport.cs.meta

5
Assets/UIWidgets/Tests/Menu.cs


public static void renderWidgets() {
EditorWindow.GetWindow(typeof(Widgets));
}
[MenuItem("UIWidgetsTests/ScrollViews")]
public static void renderScrollViews() {
EditorWindow.GetWindow(typeof(ScrollViews));
}
}
}

2
Assets/UIWidgets/foundation/assertions.cs


if (_errorCount == 0 || forceReport) {
Debug.LogError(details.ToString());
} else {
Debug.LogWarning("Another exception was thrown: " + details.exceptionAsString());
Debug.LogWarning("Another exception was thrown: " + details);
}
_errorCount += 1;

58
Assets/UIWidgets/foundation/debug.cs


using System;
using System.Diagnostics;
using UIWidgets.painting;
using UIWidgets.ui;
namespace UIWidgets.foundation {
public static class D {

public static bool debugPrintGestureArenaDiagnostics = true;
public static bool debugPrintHitTestResults = false;
public static bool debugPaintBaselinesEnabled = false;
public static bool debugPrintScheduleFrameStacks = false;
public static bool debugPaintSizeEnabled = false;
public static bool debugRepaintRainbowEnabled = false;
public static bool debugPaintLayerBordersEnabled = false;
public static bool debugPrintScheduleFrameStacks = false;
public static bool debugPrintMarkNeedsLayoutStacks = false;
public static bool debugPrintLayouts = false;
public static bool debugDisableClipLayers = false;
public static bool debugDisableOpacityLayers = false;
public static bool debugPrintMarkNeedsPaintStacks = false;
public static bool debugCheckIntrinsicSizes = false;
// public static Color debugCurrentRepaintColor = Color.fromfromAHSV(0.4, 60.0, 1.0, 1.0);;
public static void _debugDrawDoubleRect(Canvas canvas, Rect outerRect, Rect innerRect, Color color) {
// final Path path = new Path()
// ..fillType = PathFillType.evenOdd
// ..addRect(outerRect)
// ..addRect(innerRect);
// final Paint paint = new Paint()
// ..color = color;
// canvas.drawPath(path, paint);
}
public static void debugPaintPadding(Canvas canvas, Rect outerRect, Rect innerRect, double outlineWidth = 2.0) {
D.assert(() => {
if (innerRect != null && !innerRect.isEmpty) {
_debugDrawDoubleRect(canvas, outerRect, innerRect, new Color(0x900090FF));
} else {
_debugDrawDoubleRect(canvas, innerRect.inflate(outlineWidth).intersect(outerRect), innerRect,
new Color(0xFF0090FF));
Paint paint = new Paint();
paint.color = new Color(0x90909090);
canvas.drawRect(outerRect, BorderWidth.zero, BorderRadius.zero, paint);
}
return true;
});
}
}
[Serializable]

64
Assets/UIWidgets/foundation/diagnostics.cs


using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIWidgets.ui;
namespace UIWidgets.foundation {
public enum DiagnosticLevel {

}
}
public class IntProperty : _NumProperty<int> {
public IntProperty(String name, int value,
String ifNull = null,
bool showName = true,
String unit = null,
Object defaultValue = null,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
value,
ifNull: ifNull,
showName: showName,
unit: unit,
defaultValue: defaultValue,
level: level
) {
}
protected override String numberToString() {
return this.value.ToString();
}
}
public class DoubleProperty : _NumProperty<double?> {
public DoubleProperty(string name, double? value,
string ifNull = null,

}
}
public class PercentProperty : DoubleProperty {
public PercentProperty(string name, double fraction,
string ifNull = null,
bool showName = true,
string tooltip = null,
string unit = null,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
fraction,
ifNull: ifNull,
showName: showName,
tooltip: tooltip,
unit: unit,
level: level
) {
}
protected override string valueToString(TextTreeConfiguration parentConfiguration = null) {
if (this.value == null) {
return "null";
}
return this.unit != null ? this.numberToString() + " " + this.unit : this.numberToString();
}
protected override string numberToString() {
if (this.value == null) {
return "null";
}
return (this.value.Value.clamp(0.0, 1.0) * 100).ToString("F1") + "%";
}
}
public class FlagProperty : DiagnosticsProperty<bool> {
public FlagProperty(String name,

) {
var v = this.value;
var tree = v as DiagnosticableTree;
return tree != null ? tree.toStringShort() : v.ToString();
return tree != null ? tree.toStringShort() : v != null ? v.ToString() : "null";
}
public override string toDescription(

protected DiagnosticableTree() {
}
public string toStringShallow(
public virtual string toStringShallow(
String joiner = ", ",
DiagnosticLevel minLevel = DiagnosticLevel.debug
) {

return result.ToString();
}
string toStringDeep(
public virtual string toStringDeep(
String prefixLineOne = "",
String prefixOtherLines = null,
DiagnosticLevel minLevel = DiagnosticLevel.debug

4
Assets/UIWidgets/painting/border_radius.cs


return new BorderWidth(top, right, bottom, left);
}
public static BorderWidth all(double width) {
return BorderWidth.only(width, width, width, width);
}
public static readonly BorderWidth zero = BorderWidth.only();
public readonly double top;

20
Assets/UIWidgets/painting/decoration.cs


using UIWidgets.ui;
namespace UIWidgets.painting {
public abstract class Decoration {
public abstract class Decoration : Diagnosticable {
}
public override string toStringShort() {
return this.GetType().ToString();
}
public virtual bool debugAssertIsValid() {
return true;
}
public virtual EdgeInsets padding {

public virtual bool isComplex {
get { return false; }
}
public virtual bool hitTest(Size size, Offset position) {
return true;
}
public abstract class BoxPainter {
protected BoxPainter(VoidCallback onChanged = null) {
this.onChanged = onChanged;

37
Assets/UIWidgets/painting/matrix_utils.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
using UnityEngine;
using Rect = UIWidgets.ui.Rect;

}
public static Rect transformRect(Matrix4x4 transform, Offset[] points, out bool isRect) {
if (points == null || points.Length != 4) {
throw new Exception("expected 4 points");
}
D.assert(points != null && points.Length == 4, "expected 4 points");
var topLeft = MatrixUtils.transformPoint(transform, points[0]);
var topRight = MatrixUtils.transformPoint(transform, points[1]);

public static Rect transformRect(Matrix4x4 transform, Rect rect) {
bool isRect;
return MatrixUtils.transformRect(transform, rect, out isRect);
}
public static Rect inverseTransformRect(Matrix4x4 transform, Rect rect) {
D.assert(rect != null);
D.assert(transform.determinant != 0.0);
if (transform.isIdentity) {
return rect;
}
transform = transform.inverse;
return MatrixUtils.transformRect(transform, rect);
}
public static Offset getAsTranslation(ref Matrix4x4 transform) {
if (transform.m00 == 1.0 &&
transform.m10 == 0.0 &&
transform.m20 == 0.0 &&
transform.m30 == 0.0 &&
transform.m01 == 0.0 &&
transform.m11 == 1.0 &&
transform.m21 == 0.0 &&
transform.m31 == 0.0 &&
transform.m02 == 0.0 &&
transform.m12 == 0.0 &&
transform.m22 == 1.0 &&
transform.m32 == 0.0 &&
transform.m23 == 0.0 &&
transform.m33 == 1.0) {
return new Offset(transform.m03, transform.m13);
}
return null;
}
}
}

2
Assets/UIWidgets/rendering/automatic_keep_alive.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.scheduler;

Key key = null,
Widget child = null
) : base(key: key) {
this.child = child;
}
public readonly Widget child;

857
Assets/UIWidgets/rendering/box.cs
文件差异内容过多而无法显示
查看文件

12
Assets/UIWidgets/rendering/editable.cs


return Rect.fromLTWH(0.0, 0.0, _kCaretWidth, preferredLineHeight).shift(caretOffset + _paintOffset);
}
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
_layoutText(constraints.maxWidth);
return _textPainter.computeDistanceToActualBaseline(baseline);
}

}
public override void performLayout() {
protected override void performLayout() {
_layoutText(constraints.maxWidth);
_caretPrototype = Rect.fromLTWH(0.0, _kCaretHeightOffset, _kCaretWidth,
preferredLineHeight - 2.0 * _kCaretHeightOffset);

12
Assets/UIWidgets/rendering/flex.cs


}
}
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
return this._getIntrinsicSize(
sizingDirection: Axis.horizontal,
extent: height,

public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
return this._getIntrinsicSize(
sizingDirection: Axis.horizontal,
extent: height,

public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
return this._getIntrinsicSize(
sizingDirection: Axis.vertical,
extent: width,

public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
return this._getIntrinsicSize(
sizingDirection: Axis.vertical,
extent: width,

public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
if (this._direction == Axis.horizontal) {
return this.defaultComputeDistanceToHighestActualBaseline(baseline);
}

return 0;
}
public override void performLayout() {
protected override void performLayout() {
int totalFlex = 0;
int totalChildren = 0;
double maxMainSize = this._direction == Axis.horizontal

2
Assets/UIWidgets/rendering/image.cs


));
}
public override void performLayout() {
protected override void performLayout() {
this.size = _sizeForConstraints(constraints);
}

268
Assets/UIWidgets/rendering/layer.cs


using UIWidgets.foundation;
using System.Collections.Generic;
using UIWidgets.foundation;
public abstract class Layer : AbstractNode {
public abstract class Layer : AbstractNodeMixinDiagnosticableTree {
public new ContainerLayer parent {
get { return (ContainerLayer) base.parent; }
}

}
public Layer _nextSibling;
internal Layer _nextSibling;
public Layer _previousSibling;
internal Layer _previousSibling;
public virtual void remove() {
if (this.parent != null) {

public void replaceWith(Layer newLayer) {
D.assert(this.parent != null);
D.assert(this.attached == this.parent.attached);
D.assert(newLayer.parent == null);
D.assert(newLayer._nextSibling == null);
D.assert(newLayer._previousSibling == null);
D.assert(!newLayer.attached);
newLayer._nextSibling = this.nextSibling;
if (this._nextSibling != null) {
this._nextSibling._previousSibling = newLayer;

this._previousSibling._nextSibling = newLayer;
}
D.assert(() => {
Layer node = this;
while (node.parent != null)
node = node.parent;
D.assert(node != newLayer);
return true;
});
D.assert(newLayer.attached == this.parent.attached);
if (this.parent.firstChild == this) {
this.parent._firstChild = newLayer;
}

this._nextSibling = null;
this._previousSibling = null;
this.parent.dropChild(this);
D.assert(!this.attached);
public object debugCreator;
public override string toStringShort() {
return base.toStringShort() + (this.owner == null ? "DETACHED" : "");
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<object>("owner", this.owner,
level: this.parent != null ? DiagnosticLevel.hidden : DiagnosticLevel.info,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DiagnosticsProperty<object>("creator", this.debugCreator,
defaultValue: Diagnostics.kNullDefaultValue, level: DiagnosticLevel.debug));
}
public PictureLayer(Rect canvasBounds) {
this.canvasBounds = canvasBounds;
}
public readonly Rect canvasBounds;
public bool isComplexHint = false;
public bool willChangeHint = false;
builder.addPicture(layerOffset, this.picture);
builder.addPicture(layerOffset, this.picture,
isComplexHint: this.isComplexHint, willChangeHint: this.willChangeHint);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Rect>("paint bounds", this.canvasBounds));
}
}

}
public Layer _firstChild;
internal Layer _firstChild;
public Layer _lastChild;
internal Layer _lastChild;
bool _debugUltimatePreviousSiblingOf(Layer child, Layer equals = null) {
D.assert(child.attached == this.attached);
while (child.previousSibling != null) {
D.assert(child.previousSibling != child);
child = child.previousSibling;
D.assert(child.attached == this.attached);
}
return child == equals;
}
bool _debugUltimateNextSiblingOf(Layer child, Layer equals = null) {
D.assert(child.attached == this.attached);
while (child._nextSibling != null) {
D.assert(child._nextSibling != child);
child = child._nextSibling;
D.assert(child.attached == this.attached);
}
return child == equals;
}
public override void attach(object owner) {
base.attach(owner);

}
public void append(Layer child) {
D.assert(child != this);
D.assert(child != this.firstChild);
D.assert(child != this.lastChild);
D.assert(child.parent == null);
D.assert(!child.attached);
D.assert(child.nextSibling == null);
D.assert(child.previousSibling == null);
D.assert(() => {
Layer node = this;
while (node.parent != null)
node = node.parent;
D.assert(node != child);
return true;
});
this.adoptChild(child);
child._previousSibling = this.lastChild;
if (this.lastChild != null) {

if (this._firstChild == null) {
this._firstChild = child;
}
D.assert(child.attached == this.attached);
D.assert(child.parent == this);
D.assert(child.attached == this.attached);
D.assert(this._debugUltimatePreviousSiblingOf(child, equals: this.firstChild));
D.assert(this._debugUltimateNextSiblingOf(child, equals: this.lastChild));
D.assert(this.firstChild == child);
this._firstChild = child.nextSibling;
} else {
child._previousSibling._nextSibling = child.nextSibling;

D.assert(this.lastChild == child);
D.assert((this.firstChild == null) == (this.lastChild == null));
D.assert(this.firstChild == null || this.firstChild.attached == this.attached);
D.assert(this.lastChild == null || this.lastChild.attached == this.attached);
D.assert(this.firstChild == null ||
this._debugUltimateNextSiblingOf(this.firstChild, equals: this.lastChild));
D.assert(this.lastChild == null ||
this._debugUltimatePreviousSiblingOf(this.lastChild, equals: this.firstChild));
D.assert(!child.attached);
}
public void removeAllChildren() {

child._previousSibling = null;
child._nextSibling = null;
D.assert(child.attached == this.attached);
this.dropChild(child);
child = next;
}

child = child.nextSibling;
}
}
public virtual void applyTransform(Layer child, ref Matrix4x4 transform) {
D.assert(child != null);
}
public override List<DiagnosticsNode> debugDescribeChildren() {
var children = new List<DiagnosticsNode>();
if (this.firstChild == null) {
return children;
}
Layer child = this.firstChild;
int count = 1;
while (true) {
children.Add(child.toDiagnosticsNode(name: "child " + count));
if (child == this.lastChild) {
break;
}
count += 1;
child = child.nextSibling;
}
return children;
}
}
public class OffsetLayer : ContainerLayer {

public override void addToScene(SceneBuilder builder, Offset layerOffset) {
this.addChildrenToScene(builder, this.offset + layerOffset);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Offset>("offset", this.offset));
public ClipRectLayer(Rect clipRect) {
public ClipRectLayer(
Rect clipRect = null,
Clip clipBehavior = Clip.hardEdge
) {
D.assert(clipBehavior != Clip.none);
this._clipBehavior = clipBehavior;
}
public readonly Rect clipRect;
public Clip clipBehavior {
get { return this._clipBehavior; }
set {
D.assert(value != Clip.none);
this._clipBehavior = value;
}
public Rect clipRect;
Clip _clipBehavior;
builder.pushClipRect(this.clipRect.shift(layerOffset));
bool enabled = true;
D.assert(() => {
enabled = !D.debugDisableClipLayers;
return true;
});
if (enabled) {
builder.pushClipRect(this.clipRect.shift(layerOffset), clipBehavior: this.clipBehavior);
}
builder.pop();
if (enabled) {
builder.pop();
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Rect>("clipRect", this.clipRect));
public ClipRRectLayer(RRect clipRRect) {
public ClipRRectLayer(
RRect clipRRect = null,
Clip clipBehavior = Clip.hardEdge
) {
D.assert(clipBehavior != Clip.none);
this._clipBehavior = clipBehavior;
public RRect clipRRect;
public readonly RRect clipRRect;
public Clip clipBehavior {
get { return this._clipBehavior; }
set {
D.assert(value != Clip.none);
this._clipBehavior = value;
}
}
Clip _clipBehavior;
builder.pushClipRRect(this.clipRRect.shift(layerOffset));
bool enabled = true;
D.assert(() => {
enabled = !D.debugDisableClipLayers;
return true;
});
if (enabled) {
builder.pushClipRRect(this.clipRRect.shift(layerOffset), clipBehavior: this.clipBehavior);
}
builder.pop();
if (enabled) {
builder.pop();
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<RRect>("clipRRect", this.clipRRect));
public TransformLayer(Matrix4x4 transform, Offset offset = null) : base(offset) {
public TransformLayer(Matrix4x4 transform = default(Matrix4x4), Offset offset = null) : base(offset) {
this._transform = transform;
}

}
public Matrix4x4 _transform;
public Matrix4x4 _lastEffectiveTransform;
Matrix4x4 _transform;
Matrix4x4 _lastEffectiveTransform;
public override void addToScene(SceneBuilder builder, Offset layerOffset) {
this._lastEffectiveTransform = this.transform;

this.addChildrenToScene(builder, Offset.zero);
builder.pop();
}
public override void applyTransform(Layer child, ref Matrix4x4 transform) {
D.assert(child != null);
transform = transform * this._lastEffectiveTransform;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Matrix4x4>("transform", this.transform));
}
public OpacityLayer(int alpha) {
public OpacityLayer(int alpha = 255) {
this.alpha = alpha;
}

builder.pushOpacity(this.alpha);
bool enabled = true;
D.assert(() => {
enabled = !D.debugDisableOpacityLayers;
return true;
});
if (enabled) {
builder.pushOpacity(this.alpha);
}
builder.pop();
if (enabled) {
builder.pop();
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new IntProperty("alpha", this.alpha));
}
}
}

871
Assets/UIWidgets/rendering/object.cs
文件差异内容过多而无法显示
查看文件

237
Assets/UIWidgets/rendering/object.mixin.gen.cs


namespace UIWidgets.rendering {
public abstract class RenderObjectWithChildMixinRenderObject<ChildType> : RenderObject, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {

return true;
}
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public override void attach(object owner) {
base.attach(owner);
if (this._child != null) {

visitor(this._child);
}
}
}
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
public override List<DiagnosticsNode> debugDescribeChildren() {
return this.child != null
? new List<DiagnosticsNode>{this.child.toDiagnosticsNode(name: "child")}
: new List<DiagnosticsNode>();
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {

return true;
}
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public override void attach(object owner) {
base.attach(owner);
if (this._child != null) {

visitor(this._child);
}
}
public override List<DiagnosticsNode> debugDescribeChildren() {
return this.child != null
? new List<DiagnosticsNode>{this.child.toDiagnosticsNode(name: "child")}
: new List<DiagnosticsNode>();
}
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {

return true;
}
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public override void attach(object owner) {
base.attach(owner);
if (this._child != null) {

visitor(this._child);
}
}
public override List<DiagnosticsNode> debugDescribeChildren() {
return this.child != null
? new List<DiagnosticsNode>{this.child.toDiagnosticsNode(name: "child")}
: new List<DiagnosticsNode>();
}
}

public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
D.assert(this.previousSibling == null);
D.assert(this.nextSibling == null);
// if (this.previousSibling != null) {
// var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
// previousSiblingParentData.nextSibling = this.nextSibling;
// }
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
// if (this.nextSibling != null) {
// var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
// nextSiblingParentData.previousSibling = this.previousSibling;
// }
this.previousSibling = null;
this.nextSibling = null;
// this.previousSibling = null;
// this.nextSibling = null;
}
}

public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
D.assert(this.previousSibling == null);
D.assert(this.nextSibling == null);
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
// if (this.previousSibling != null) {
// var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
// previousSiblingParentData.nextSibling = this.nextSibling;
// }
this.previousSibling = null;
this.nextSibling = null;
// if (this.nextSibling != null) {
// var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
// nextSiblingParentData.previousSibling = this.previousSibling;
// }
// this.previousSibling = null;
// this.nextSibling = null;
}
}

public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
D.assert(this.previousSibling == null);
D.assert(this.nextSibling == null);
// if (this.previousSibling != null) {
// var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
// previousSiblingParentData.nextSibling = this.nextSibling;
// }
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
// if (this.nextSibling != null) {
// var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
// nextSiblingParentData.previousSibling = this.previousSibling;
// }
this.previousSibling = null;
this.nextSibling = null;
// this.previousSibling = null;
// this.nextSibling = null;
}
}

public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
D.assert(this.previousSibling == null);
D.assert(this.nextSibling == null);
// if (this.previousSibling != null) {
// var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
// previousSiblingParentData.nextSibling = this.nextSibling;
// }
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
// if (this.nextSibling != null) {
// var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
// nextSiblingParentData.previousSibling = this.previousSibling;
// }
this.previousSibling = null;
this.nextSibling = null;
// this.previousSibling = null;
// this.nextSibling = null;
}
}

return this.childAfter((ChildType) child);
}
}
}

72
Assets/UIWidgets/rendering/object.mixin.njk


namespace UIWidgets.rendering {
{% macro RenderObjectWithChildMixin(with) %}
public abstract class RenderObjectWithChildMixin{{with}}<ChildType> : {{with}}, RenderObjectWithChildMixin<ChildType>, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {

return true;
}
internal ChildType _child;
public ChildType child {
get { return this._child; }
set {
if (this._child != null) {
this.dropChild(this._child);
}
this._child = value;
if (this._child != null) {
this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public override void attach(object owner) {
base.attach(owner);
if (this._child != null) {

visitor(this._child);
}
}
public override List<DiagnosticsNode> debugDescribeChildren() {
return this.child != null
? new List<DiagnosticsNode>{this.child.toDiagnosticsNode(name: "child")}
: new List<DiagnosticsNode>();
}
}
{% endmacro %}

public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
D.assert(this.previousSibling == null);
D.assert(this.nextSibling == null);
// if (this.previousSibling != null) {
// var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
// previousSiblingParentData.nextSibling = this.nextSibling;
// }
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
// if (this.nextSibling != null) {
// var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
// nextSiblingParentData.previousSibling = this.previousSibling;
// }
this.previousSibling = null;
this.nextSibling = null;
// this.previousSibling = null;
// this.nextSibling = null;
}
}

{{ ContainerRenderObjectMixin('RenderBox') }}
{{ ContainerRenderObjectMixin('RenderSliver') }}
}

12
Assets/UIWidgets/rendering/paragraph.cs


get { return _textPainter.size; }
}
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
_layoutText();
return _textPainter.maxIntrinsicWidth;
}

return _textPainter.height;
}
public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
public override void performLayout() {
protected override void performLayout() {
_layoutTextWithConstraints(constraints);
var textSize = _textPainter.size;
var didOverflowHeight = _textPainter.didExceedMaxLines;

530
Assets/UIWidgets/rendering/proxy_box.cs


using UIWidgets.painting;
using UIWidgets.ui;
using UnityEngine;
using Color = UIWidgets.ui.Color;
namespace UIWidgets.rendering {
public class RenderProxyBox : RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox<RenderBox> {

public RenderConstrainedBox(
RenderBox child = null,
BoxConstraints additionalConstraints = null) : base(child) {
D.assert(additionalConstraints != null);
D.assert(additionalConstraints.debugAssertIsValid());
D.assert(value != null);
D.assert(value.debugAssertIsValid());
if (this._additionalConstraints == value) {
return;
}

}
}
public BoxConstraints _additionalConstraints;
BoxConstraints _additionalConstraints;
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
D.assert(width.isFinite());
if (!this._additionalConstraints.hasInfiniteWidth) {
return this._additionalConstraints.constrainWidth(width);
}

public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
D.assert(width.isFinite());
if (!this._additionalConstraints.hasInfiniteWidth) {
return this._additionalConstraints.constrainWidth(width);
}

public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
D.assert(height.isFinite());
if (!this._additionalConstraints.hasInfiniteHeight) {
return this._additionalConstraints.constrainHeight(height);
}

public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
D.assert(height.isFinite());
if (!this._additionalConstraints.hasInfiniteHeight) {
return this._additionalConstraints.constrainHeight(height);
}

public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
this.child.layout(this._additionalConstraints.enforce(this.constraints), parentUsesSize: true);
this.size = this.child.size;

}
protected override void debugPaintSize(PaintingContext context, Offset offset) {
base.debugPaintSize(context, offset);
D.assert(() => {
if (this.child == null || this.child.size.isEmpty) {
var paint = new Paint {
color = new Color(0x90909090)
};
context.canvas.drawRect(offset & this.size, BorderWidth.zero, BorderRadius.zero, paint);
}
return true;
});
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(
new DiagnosticsProperty<BoxConstraints>("additionalConstraints", this.additionalConstraints));
}
}
public class RenderLimitedBox : RenderProxyBox {

double maxHeight = double.PositiveInfinity
) : base(child) {
D.assert(maxWidth >= 0.0);
D.assert(maxHeight >= 0.0);
this._maxWidth = maxWidth;
this._maxHeight = maxHeight;
}

set {
D.assert(value >= 0.0);
if (this._maxWidth == value) {
return;
}

}
}
public double _maxWidth;
double _maxWidth;
D.assert(value >= 0.0);
if (this._maxHeight == value) {
return;
}

}
}
public double _maxHeight;
double _maxHeight;
public BoxConstraints _limitConstraints(BoxConstraints constraints) {
BoxConstraints _limitConstraints(BoxConstraints constraints) {
return new BoxConstraints(
minWidth: constraints.minWidth,
maxWidth: constraints.hasBoundedWidth

);
}
public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
this.child.layout(this._limitConstraints(this.constraints), parentUsesSize: true);
this.size = this.constraints.constrain(this.child.size);

}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DoubleProperty("maxWidth", this.maxWidth, defaultValue: double.PositiveInfinity));
properties.add(new DoubleProperty("maxHeight", this.maxHeight, defaultValue: double.PositiveInfinity));
}
}
public class RenderOpacity : RenderProxyBox {
public RenderOpacity(double opacity = 1.0, RenderBox child = null) : base(child) {
D.assert(opacity >= 0.0 && opacity <= 1.0);
this._opacity = opacity;
this._alpha = _getAlphaFromOpacity(opacity);
}
protected override bool alwaysNeedsCompositing {
get { return this.child != null && (this._alpha != 0 && this._alpha != 255); }
}
int _alpha;
static int _getAlphaFromOpacity(double opacity) {
return (opacity * 255).round();
}
public double opacity {
get { return this._opacity; }
set {
D.assert(value >= 0.0 && value <= 1.0);
if (this._opacity == value) {
return;
}
bool didNeedCompositing = this.alwaysNeedsCompositing;
this._opacity = value;
this._alpha = _getAlphaFromOpacity(this._opacity);
if (didNeedCompositing != this.alwaysNeedsCompositing) {
this.markNeedsCompositingBitsUpdate();
}
this.markNeedsPaint();
}
}
double _opacity;
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
if (this._alpha == 0) {
return;
}
}
if (this._alpha == 255) {
context.paintChild(this.child, offset);
return;
}
D.assert(this.needsCompositing);
context.pushOpacity(offset, this._alpha, base.paint);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DoubleProperty("opacity", this.opacity));
}
}

public class RenderDecoratedBox : RenderProxyBox {
public RenderDecoratedBox(
Decoration decoration,
Decoration decoration = null,
D.assert(decoration != null);
public BoxPainter _painter;
BoxPainter _painter;
D.assert(value != null);
if (value == this._decoration) {
return;
}

}
}
public Decoration _decoration;
Decoration _decoration;
public DecorationPosition position {
get { return this._position; }

}
}
public DecorationPosition _position;
DecorationPosition _position;
D.assert(value != null);
if (value == this._configuration) {
return;
}

}
}
public ImageConfiguration _configuration;
ImageConfiguration _configuration;
public override void detach() {
if (this._painter != null) {

}
public override void paint(PaintingContext context, Offset offset) {
if (this._painter == null) {
this._painter = this._decoration.createBoxPainter(this.markNeedsPaint);
}
this._painter = this._painter ?? this._decoration.createBoxPainter(this.markNeedsPaint);
var filledConfiguration = this.configuration.copyWith(size: this.size);
var filledConfiguration = this.configuration.copyWith(size: this.size);
int debugSaveCount = 0;
D.assert(() => {
debugSaveCount = context.canvas.getSaveCount();
return true;
});
D.assert(() => {
if (debugSaveCount != context.canvas.getSaveCount()) {
throw new UIWidgetsError(
this._decoration.GetType() + " painter had mismatching save and restore calls.\n" +
"Before painting the decoration, the canvas save count was $debugSaveCount. " +
"After painting it, the canvas save count was " + context.canvas.getSaveCount() + ". " +
"Every call to save() or saveLayer() must be matched by a call to restore().\n" +
"The decoration was:\n" +
" " + this.decoration + "\n" +
"The painter was:\n" +
" " + this._painter
);
}
return true;
});
if (this.decoration.isComplex) {
context.setIsComplexHint();
}
}
base.paint(context, offset);

if (this.decoration.isComplex) {
context.setIsComplexHint();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(this._decoration.toDiagnosticsNode(name: "decoration"));
properties.add(new DiagnosticsProperty<ImageConfiguration>("configuration", this.configuration));
}
}
public class RenderTransform : RenderProxyBox {
public RenderTransform(
Matrix4x4 transform,
Offset origin = null,
Alignment alignment = null,
bool transformHitTests = true,
RenderBox child = null
) : base(child) {
this.transform = transform;
this.origin = origin;
this.alignment = alignment;
this.transformHitTests = transformHitTests;
}
public Offset origin {
get { return this._origin; }
set {
if (this._origin == value) {
return;
}
this._origin = value;
this.markNeedsPaint();
}
}
Offset _origin;
public Alignment alignment {
get { return this._alignment; }
set {
if (this._alignment == value) {
return;
}
this._alignment = value;
this.markNeedsPaint();
}
}
Alignment _alignment;
public bool transformHitTests;
public Matrix4x4 transform {
set {
if (this._transform == value) {
return;
}
this._transform = value;
this.markNeedsPaint();
}
}
Matrix4x4 _transform;
public void setIdentity() {
this._transform = Matrix4x4.identity;
this.markNeedsPaint();
}
public void rotateX(double degrees) {
this._transform = Matrix4x4.Rotate(Quaternion.Euler((float) degrees, 0, 0)) * this._transform;
this.markNeedsPaint();
}
public void rotateY(double degrees) {
this._transform = Matrix4x4.Rotate(Quaternion.Euler(0, (float) degrees, 0)) * this._transform;
this.markNeedsPaint();
}
public void rotateZ(double degrees) {
this._transform = Matrix4x4.Rotate(Quaternion.Euler(0, 0, (float) degrees)) * this._transform;
this.markNeedsPaint();
}
public void translate(double x, double y = 0.0, double z = 0.0) {
this._transform = Matrix4x4.Translate(new Vector3((float) x, (float) y, (float) z)) * this._transform;
this.markNeedsPaint();
}
public void scale(double x, double y, double z) {
this._transform = Matrix4x4.Scale(new Vector3((float) x, (float) y, (float) z)) * this._transform;
this.markNeedsPaint();
}
Matrix4x4 _effectiveTransform {
get {
Alignment resolvedAlignment = this.alignment;
if (this._origin == null && resolvedAlignment == null) {
return this._transform;
}
var result = Matrix4x4.identity;
if (this._origin != null) {
result = Matrix4x4.Translate(new Vector2((float) this._origin.dx, (float) this._origin.dy)) *
result;
}
Offset translation = null;
if (resolvedAlignment != null) {
translation = resolvedAlignment.alongSize(this.size);
result = Matrix4x4.Translate(new Vector2((float) translation.dx, (float) translation.dy)) * result;
}
result = this._transform * result;
if (resolvedAlignment != null) {
result = Matrix4x4.Translate(new Vector2((float) -translation.dx, (float) -translation.dy)) *
result;
}
if (this._origin != null) {
result = Matrix4x4.Translate(new Vector2((float) -this._origin.dx, (float) -this._origin.dy)) *
result;
}
return result;
}
}
public override bool hitTest(HitTestResult result, Offset position = null) {
return this.hitTestChildren(result, position: position);
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.transformHitTests) {
var transform = this._effectiveTransform;
if (transform.determinant == 0) {
return false;
}
position = MatrixUtils.transformPoint(transform.inverse, position);
}
return base.hitTestChildren(result, position: position);
}
public override void paint(PaintingContext context, Offset offset) {
if (this.child != null) {
var transform = this._effectiveTransform;
Offset childOffset = MatrixUtils.getAsTranslation(ref transform);
if (childOffset == null) {
context.pushTransform(this.needsCompositing, offset, transform, base.paint);
} else {
base.paint(context, offset + childOffset);
}
}
}
public override void applyPaintTransform(RenderObject child, ref Matrix4x4 transform) {
transform = this._effectiveTransform * transform;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Matrix4x4>("transform matrix", this._transform));
properties.add(new DiagnosticsProperty<Offset>("origin", this.origin));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
properties.add(new DiagnosticsProperty<bool>("transformHitTests", this.transformHitTests));
}
}
public delegate void PointerDownEventListener(PointerDownEvent evt);

public PointerCancelEventListener onPointerCancel;
public override void performResize() {
protected override void performResize() {
this.size = this.constraints.biggest;
}

}
}
public class RenderTransform : RenderProxyBox {
public RenderTransform(
Matrix4x4 transform,
Offset origin,
Alignment alignment,
TextDirection textDirection,
RenderBox child = null,
bool transformHitTests = true
) {
this.transform = transform;
this.origin = origin;
this.alignment = alignment;
this.textDirection = textDirection;
this.child = child;
this.transformHitTests = transformHitTests;
public class RenderRepaintBoundary : RenderProxyBox {
public RenderRepaintBoundary(
RenderBox child = null
) : base(child) {
public Offset origin {
get { return _origin; }
set {
if (_origin.Equals(value)) {
return;
}
public override bool isRepaintBoundary {
get { return true; }
}
_origin = value;
markNeedsPaint();
}
public int debugSymmetricPaintCount {
get { return this._debugSymmetricPaintCount; }
private Offset _origin;
public Alignment alignment {
get { return _alignment; }
set {
if (_alignment.Equals(value)) {
return;
}
int _debugSymmetricPaintCount = 0;
_alignment = value;
markNeedsPaint();
}
public int debugAsymmetricPaintCount {
get { return this._debugAsymmetricPaintCount; }
private Alignment _alignment;
int _debugAsymmetricPaintCount = 0;
public TextDirection textDirection {
get { return _textDirection; }
set {
if (_textDirection.Equals(value)) {
return;
}
_textDirection = value;
markNeedsPaint();
}
public void debugResetMetrics() {
D.assert(() => {
this._debugSymmetricPaintCount = 0;
this._debugAsymmetricPaintCount = 0;
return true;
});
private TextDirection _textDirection;
public bool transformHitTests;
public Matrix4x4 transform {
set {
if (_transform.Equals(value)) {
return;
public override void debugRegisterRepaintBoundaryPaint(bool includedParent = true, bool includedChild = false) {
D.assert(() => {
if (includedParent && includedChild) {
this._debugSymmetricPaintCount += 1;
} else {
this._debugAsymmetricPaintCount += 1;
_transform = value;
}
}
private Matrix4x4 _transform;
}
public class RenderOpacity : RenderProxyBox {
public RenderOpacity(RenderBox child = null, double opacity = 1.0) : base(child) {
D.assert(opacity >= 0.0 && opacity <= 1.0);
this._opacity = opacity;
this._alpha = _getAlphaFromOpacity(opacity);
}
public override bool alwaysNeedsCompositing {
get { return base.alwaysNeedsCompositing; }
return true;
});
private int _alpha;
private static int _getAlphaFromOpacity(double opacity) {
return (opacity * 255).round();
}
public double opacity {
get { return _opacity; }
set {
D.assert(value >= 0.0 && value <= 1.0);
if (_opacity == value) {
return;
}
bool didNeedCompositing = alwaysNeedsCompositing;
bool wasVisible = _alpha != 0;
_opacity = value;
_alpha = _getAlphaFromOpacity(_opacity);
if (didNeedCompositing != alwaysNeedsCompositing) {
markNeedsCompositingBitsUpdate();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
bool inReleaseMode = true;
D.assert(() => {
inReleaseMode = false;
if (this.debugSymmetricPaintCount + this.debugAsymmetricPaintCount == 0) {
properties.add(new MessageProperty("usefulness ratio", "no metrics collected yet (never painted)"));
} else {
double fraction = (double) this.debugAsymmetricPaintCount /
(this.debugSymmetricPaintCount + this.debugAsymmetricPaintCount);
markNeedsPaint();
}
}
private double _opacity;
string diagnosis;
if (this.debugSymmetricPaintCount + this.debugAsymmetricPaintCount < 5) {
diagnosis = "insufficient data to draw conclusion (less than five repaints)";
} else if (fraction > 0.9) {
diagnosis = "this is an outstandingly useful repaint boundary and should definitely be kept";
} else if (fraction > 0.5) {
diagnosis = "this is a useful repaint boundary and should be kept";
} else if (fraction > 0.30) {
diagnosis =
"this repaint boundary is probably useful, but maybe it would be more useful in tandem with adding more repaint boundaries elsewhere";
} else if (fraction > 0.1) {
diagnosis = "this repaint boundary does sometimes show value, though currently not that often";
} else if (this.debugAsymmetricPaintCount == 0) {
diagnosis = "this repaint boundary is astoundingly ineffectual and should be removed";
} else {
diagnosis = "this repaint boundary is not very effective and should probably be removed";
}
public override void paint(PaintingContext context, Offset offset) {
if (child != null) {
if (_alpha == 0) {
return;
properties.add(new PercentProperty("metrics", fraction, unit: "useful",
tooltip: this.debugSymmetricPaintCount + " bad vs " + this.debugAsymmetricPaintCount + " good"));
properties.add(new MessageProperty("diagnosis", diagnosis));
}
if (_alpha == 255) {
context.paintChild(child, offset);
return;
return true;
});
if (inReleaseMode) {
properties.add(DiagnosticsNode.message("(run in checked mode to collect repaint boundary statistics)"));
D.assert(needsCompositing);
context.pushOpacity(offset, _alpha, base.paint);
}
}
public class RenderRepaintBoundary : RenderProxyBox {
public RenderRepaintBoundary(
RenderBox child = null
) : base(child) {
}
public override bool isRepaintBoundary {
get { return true; }
}
}

28
Assets/UIWidgets/rendering/proxy_box.mixin.gen.cs


}
}
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMinIntrinsicWidth(height);
}

public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMaxIntrinsicWidth(height);
}

public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMinIntrinsicHeight(width);
}

public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(width);
}

public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
if (this.child != null) {
return this.child.getDistanceToActualBaseline(baseline);
}

public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
this.child.layout(this.constraints, parentUsesSize: true);
this.size = this.child.size;

}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.child != null) {
return this.child.hitTest(result, position);
}
return false;
}
public override void applyPaintTransform(RenderObject child, ref Matrix4x4 transform) {
}

}
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.child != null) {
return this.child.hitTest(result, position);
}
return false;
}
}

28
Assets/UIWidgets/rendering/proxy_box.mixin.njk


}
}
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMinIntrinsicWidth(height);
}

public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMaxIntrinsicWidth(height);
}

public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMinIntrinsicHeight(width);
}

public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(width);
}

public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
if (this.child != null) {
return this.child.getDistanceToActualBaseline(baseline);
}

public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
this.child.layout(this.constraints, parentUsesSize: true);
this.size = this.child.size;

}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.child != null) {
return this.child.hitTest(result, position);
}
return false;
}
public override void applyPaintTransform(RenderObject child, ref Matrix4x4 transform) {
}

}
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.child != null) {
return this.child.hitTest(result, position);
}
return false;
}
}
{% endmacro %}

54
Assets/UIWidgets/rendering/shifted_box.cs


this.child = child;
}
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMinIntrinsicWidth(height);
}

public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMaxIntrinsicWidth(height);
}

public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMinIntrinsicHeight(width);
}

public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(width);
}

public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
double? result;
if (this.child != null) {

public EdgeInsets _padding;
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMinIntrinsicWidth(Math.Max(0.0, height - this._padding.vertical)) +
this._padding.horizontal;

}
public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
if (this.child != null) {
return this.child.getMaxIntrinsicWidth(Math.Max(0.0, height - this._padding.vertical)) +
this._padding.horizontal;

}
public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMinIntrinsicHeight(Math.Max(0.0, width - this._padding.horizontal)) +
this._padding.vertical;

}
public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
if (this.child != null) {
return this.child.getMaxIntrinsicHeight(Math.Max(0.0, width - this._padding.horizontal)) +
this._padding.vertical;

}
public override void performLayout() {
protected override void performLayout() {
if (this.child == null) {
this.size = this.constraints.constrain(this._padding.inflateSize(Size.zero));
return;

public double? _heightFactor;
public override void performLayout() {
protected override void performLayout() {
bool shrinkWrapWidth = this._widthFactor != null || double.IsPositiveInfinity(this.constraints.maxWidth);
bool shrinkWrapHeight = this._heightFactor != null || double.IsPositiveInfinity(this.constraints.maxHeight);

);
}
public override bool sizedByParent {
protected override bool sizedByParent {
public override void performResize() {
protected override void performResize() {
public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
this.child.layout(this._getInnerConstraints(this.constraints), parentUsesSize: true);
this.alignChild();

public Rect _overflowChildRect = Rect.zero;
public bool _isOverflowing = false;
public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
BoxConstraints childConstraints = null;
if (this.constrainedAxis != null) {

public Size _requestedSize;
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
protected override double? computeDistanceToActualBaseline(TextBaseline baseline) {
if (this.child != null) {
return this.child.getDistanceToActualBaseline(baseline);
}

public override void performLayout() {
protected override void performLayout() {
this.size = this.constraints.constrain(this._requestedSize);
if (this.child != null) {
this.child.layout(this.constraints);

);
}
public override double computeMinIntrinsicWidth(double height) {
protected override double computeMinIntrinsicWidth(double height) {
double result;
if (this.child == null) {
result = base.computeMinIntrinsicWidth(height);

return result / (this._widthFactor ?? 1.0);
}
public override double computeMaxIntrinsicWidth(double height) {
protected override double computeMaxIntrinsicWidth(double height) {
double result;
if (this.child == null) {
result = base.computeMaxIntrinsicWidth(height);

return result / (this._widthFactor ?? 1.0);
}
public override double computeMinIntrinsicHeight(double width) {
protected override double computeMinIntrinsicHeight(double width) {
double result;
if (this.child == null) {
result = base.computeMinIntrinsicHeight(width);

return result / (this._heightFactor ?? 1.0);
}
public override double computeMaxIntrinsicHeight(double width) {
protected override double computeMaxIntrinsicHeight(double width) {
double result;
if (this.child == null) {
result = base.computeMaxIntrinsicHeight(width);

return result / (this._heightFactor ?? 1.0);
}
public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
this.child.layout(this._getInnerConstraints(this.constraints), parentUsesSize: true);
this.size = this.constraints.constrain(this.child.size);

public TextBaseline _baselineType;
public override void performLayout() {
protected override void performLayout() {
if (this.child != null) {
this.child.layout(this.constraints.loosen(), parentUsesSize: true);
double? childBaseline = this.child.getDistanceToBaseline(this.baselineType);

475
Assets/UIWidgets/rendering/sliver.cs


using System;
using System.Text;
using UIWidgets.foundation;
using UIWidgets.gestures;
using Canvas = UIWidgets.ui.Canvas;
using Rect = UIWidgets.ui.Rect;
namespace UIWidgets.rendering {

);
}
D.assert(false);
public override bool debugAssertIsValid(
bool isAppliedConstraint = false,
InformationCollector informationCollector = null
) {
D.assert(() => {
var verify = new Action<bool, string>((bool check, string message) => {
if (check) {
return;
}
var information = new StringBuilder();
if (informationCollector != null) {
informationCollector(information);
}
throw new UIWidgetsError(string.Format(
"{0} is not valid: {1}\n{2}The offending constraints were: \n {3}",
this.GetType(), message, information, this));
});
verify(this.scrollOffset >= 0.0, "The \"scrollOffset\" is negative.");
verify(this.crossAxisExtent >= 0.0, "The \"crossAxisExtent\" is negative.");
verify(
AxisUtils.axisDirectionToAxis(this.axisDirection) !=
AxisUtils.axisDirectionToAxis(this.crossAxisDirection),
"The \"axisDirection\" and the \"crossAxisDirection\" are along the same axis.");
verify(this.viewportMainAxisExtent >= 0.0, "The \"viewportMainAxisExtent\" is negative.");
verify(this.remainingPaintExtent >= 0.0, "The \"remainingPaintExtent\" is negative.");
verify(this.remainingCacheExtent >= 0.0, "The \"remainingCacheExtent\" is negative.");
verify(this.cacheOrigin <= 0.0, "The \"cacheOrigin\" is positive.");
verify(this.isNormalized, "The constraints are not normalized.");
return true;
});
return true;
}
public bool Equals(SliverConstraints other) {
if (object.ReferenceEquals(null, other)) return false;
if (object.ReferenceEquals(this, other)) return true;

}
public static bool operator ==(SliverConstraints left, SliverConstraints right) {
return Equals(left, right);
return object.Equals(left, right);
return !Equals(left, right);
return !object.Equals(left, right);
}
public override String ToString() {
return string.Format(
"SliverConstraints({0}, {1}, {2}, scrollOffset: {3:F1}, remainingPaintExtent: {4:F1}, " +
"{5}crossAxisExtent: {6:F1}, crossAxisDirection: {7}, " +
"viewportMainAxisExtent: {8:F1}, remainingCacheExtent: {9:F1} " +
"cacheOrigin: {10:F1})", this.axisDirection, this.growthDirection, this.userScrollDirection,
this.scrollOffset, this.remainingCacheExtent,
this.overlap != 0.0 ? "overlap: " + this.overlap.ToString("F1") + ", " : "",
this.crossAxisExtent, this.crossAxisDirection,
this.viewportMainAxisExtent, this.remainingCacheExtent, this.cacheOrigin);
public class SliverGeometry {
public class SliverGeometry : Diagnosticable {
public SliverGeometry(
double scrollExtent = 0.0,
double paintExtent = 0.0,

double? hitTestExtent = null,
bool? visible = null,
bool hasVisualOverflow = false,
double scrollOffsetCorrection = 0.0,
double? scrollOffsetCorrection = null,
D.assert(scrollOffsetCorrection != 0.0);
this.scrollExtent = scrollExtent;
this.paintExtent = paintExtent;
this.paintOrigin = paintOrigin;

public readonly double hitTestExtent;
public readonly bool visible;
public readonly bool hasVisualOverflow;
public readonly double scrollOffsetCorrection;
public readonly double? scrollOffsetCorrection;
}
public class SliverPhysicalParentData : ParentData {
public Offset paintOffset = Offset.zero;
internal static string _debugCompareFloats(string labelA, double valueA, string labelB, double valueB) {
if (valueA.ToString("F1") != valueB.ToString("F1")) {
return string.Format("The {0} is {1:F1}, but the {2} is {3:F1}. ", labelA, valueA, labelB, valueB);
}
public void applyPaintTransform(ref Matrix4x4 transform) {
transform = Matrix4x4.Translate(this.paintOffset.toVector()) * transform;
return string.Format(
"The {0} is {1}, but the {2} is {3}. " +
"Maybe you have fallen prey to floating point rounding errors, and should explicitly " +
"apply the min() or max() functions, or the clamp() method, to the {2}? ",
labelA, valueA, labelB, valueB);
}
public bool debugAssertIsValid(InformationCollector informationCollector = null) {
D.assert(() => {
var verify = new Action<bool, string>((bool check, string message) => {
if (check)
return;
var information = new StringBuilder();
if (informationCollector != null) {
informationCollector(information);
}
throw new UIWidgetsError(string.Format("{0} is not valid: {1}\n{2}", this.GetType(), message,
information));
});
verify(this.scrollExtent >= 0.0, "The \"scrollExtent\" is negative.");
verify(this.paintExtent >= 0.0, "The \"paintExtent\" is negative.");
verify(this.layoutExtent >= 0.0, "The \"layoutExtent\" is negative.");
verify(this.cacheExtent >= 0.0, "The \"cacheExtent\" is negative.");
if (this.layoutExtent > this.paintExtent) {
verify(false,
"The \"layoutExtent\" exceeds the \"paintExtent\".\n" +
_debugCompareFloats("paintExtent", paintExtent, "layoutExtent", layoutExtent)
);
}
if (this.maxPaintExtent < this.paintExtent) {
verify(false,
"The \"maxPaintExtent\" is less than the \"paintExtent\".\n" +
_debugCompareFloats("maxPaintExtent", this.maxPaintExtent, "paintExtent", this.paintExtent) +
"By definition, a sliver can\"t paint more than the maximum that it can paint!"
);
}
verify(this.hitTestExtent >= 0.0, "The \"hitTestExtent\" is negative.");
verify(this.scrollOffsetCorrection != 0.0, "The \"scrollOffsetCorrection\" is zero.");
return true;
});
return true;
}
public override string toStringShort() {
return this.GetType().ToString();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DoubleProperty("scrollExtent", this.scrollExtent));
if (this.paintExtent > 0.0) {
properties.add(new DoubleProperty("paintExtent", this.paintExtent,
unit: this.visible ? null : " but not painting"));
} else if (this.paintExtent == 0.0) {
if (this.visible) {
properties.add(new DoubleProperty("paintExtent", this.paintExtent,
unit: this.visible ? null : " but visible"));
}
properties.add(new FlagProperty("visible", value: this.visible, ifFalse: "hidden"));
} else {
properties.add(new DoubleProperty("paintExtent", this.paintExtent, tooltip: "!"));
}
properties.add(new DoubleProperty("paintOrigin", this.paintOrigin,
defaultValue: 0.0));
properties.add(new DoubleProperty("layoutExtent", this.layoutExtent,
defaultValue: this.paintExtent));
properties.add(new DoubleProperty("maxPaintExtent", this.maxPaintExtent));
properties.add(new DoubleProperty("hitTestExtent", this.hitTestExtent,
defaultValue: this.paintExtent));
properties.add(new DiagnosticsProperty<bool>("hasVisualOverflow", this.hasVisualOverflow,
defaultValue: false));
properties.add(new DoubleProperty("scrollOffsetCorrection", this.scrollOffsetCorrection,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DoubleProperty("cacheExtent", this.cacheExtent,
defaultValue: 0.0));
public class SliverPhysicalContainerParentData : ContainerParentDataMixinSliverPhysicalParentData<RenderSliver> {
public class SliverHitTestEntry : HitTestEntry {
public SliverHitTestEntry(RenderSliver target,
double mainAxisPosition = 0.0,
double crossAxisPosition = 0.0
) : base(target) {
this.mainAxisPosition = mainAxisPosition;
this.crossAxisPosition = crossAxisPosition;
}
public new RenderSliver target {
get { return (RenderSliver) base.target; }
}
public readonly double mainAxisPosition;
public readonly double crossAxisPosition;
public override string ToString() {
return string.Format("{0}@(mainAix: {1}, crossAix: {2})", this.target.GetType(), this.mainAxisPosition,
this.crossAxisPosition);
}
public override string ToString() {
return "layoutOffset=" + this.layoutOffset.ToString("F1");
}
}
public class SliverLogicalContainerParentData : ContainerParentDataMixinSliverLogicalParentData<RenderSliver> {

public class SliverPhysicalParentData : ParentData {
public Offset paintOffset = Offset.zero;
public void applyPaintTransform(ref Matrix4x4 transform) {
transform = Matrix4x4.Translate(this.paintOffset.toVector()) * transform;
}
public override string ToString() {
return "paintOffset=" + this.paintOffset;
}
}
public class SliverPhysicalContainerParentData : ContainerParentDataMixinSliverPhysicalParentData<RenderSliver> {
}
public abstract class RenderSliver : RenderObject {
public new SliverConstraints constraints {
get { return (SliverConstraints) base.constraints; }

get { return this._geometry; }
set { this._geometry = value; }
set {
D.assert(!(this.debugDoingThisResize && this.debugDoingThisLayout));
D.assert(this.sizedByParent || !this.debugDoingThisResize);
D.assert(() => {
if ((this.sizedByParent && this.debugDoingThisResize) ||
(!this.sizedByParent && this.debugDoingThisLayout)) {
return true;
}
D.assert(!this.debugDoingThisResize);
string contract = "", violation = "", hint = "";
if (this.debugDoingThisLayout) {
D.assert(this.sizedByParent);
violation = "It appears that the geometry setter was called from performLayout().";
hint = "";
} else {
violation =
"The geometry setter was called from outside layout (neither performResize() nor performLayout() were being run for this object).";
if (this.owner != null && this.owner.debugDoingLayout) {
hint =
"Only the object itself can set its geometry. It is a contract violation for other objects to set it.";
}
}
if (this.sizedByParent) {
contract =
"Because this RenderSliver has sizedByParent set to true, it must set its geometry in performResize().";
} else {
contract =
"Because this RenderSliver has sizedByParent set to false, it must set its geometry in performLayout().";
}
throw new UIWidgetsError(
"RenderSliver geometry setter called incorrectly.\n" +
violation + "\n" +
hint + "\n" +
contract + "\n" +
"The RenderSliver in question is:\n" +
" " + this
);
});
this._geometry = value;
}
public SliverGeometry _geometry;
SliverGeometry _geometry;
public override Rect paintBounds {
get {

);
}
D.assert(false);
public override void performResize() {
protected override void debugResetSize() {
}
protected override void debugAssertDoesMeetConstraints() {
D.assert(this.geometry.debugAssertIsValid(
informationCollector: (information) => {
information.AppendLine("The RenderSliver that returned the offending geometry was:");
information.AppendLine(" " + this.toStringShallow(joiner: "\n "));
}));
D.assert(() => {
if (this.geometry.paintExtent > this.constraints.remainingPaintExtent) {
throw new UIWidgetsError(
"SliverGeometry has a paintOffset that exceeds the remainingPaintExtent from the constraints.\n" +
"The render object whose geometry violates the constraints is the following:\n" +
" " + this.toStringShallow(joiner: "\n ") + "\n" +
SliverGeometry._debugCompareFloats(
"remainingPaintExtent", this.constraints.remainingPaintExtent,
"paintExtent", this.geometry.paintExtent) +
"The paintExtent must cause the child sliver to paint within the viewport, and so " +
"cannot exceed the remainingPaintExtent."
);
}
return true;
});
}
protected override void performResize() {
D.assert(false);
}
public double centerOffsetAdjustment {

public bool hitTest(HitTestResult result, double mainAxisPosition = 0, double crossAxisPosition = 0) {
if (mainAxisPosition >= 0.0 && mainAxisPosition < this.geometry.hitTestExtent &&
crossAxisPosition >= 0.0 && crossAxisPosition < this.constraints.crossAxisExtent) {
if (this.hitTestChildren(result, mainAxisPosition: mainAxisPosition,
crossAxisPosition: crossAxisPosition) ||
this.hitTestSelf(mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition)) {
result.add(new SliverHitTestEntry(
this,
mainAxisPosition: mainAxisPosition,
crossAxisPosition: crossAxisPosition
));
return true;
}
}
return false;
}
protected virtual bool hitTestSelf(double mainAxisPosition = 0, double crossAxisPosition = 0) {
return false;
}
protected virtual bool hitTestChildren(HitTestResult result, double mainAxisPosition = 0,
double crossAxisPosition = 0) {
return false;
}
D.assert(from <= to);
double a = constraints.scrollOffset;
double b = constraints.scrollOffset + constraints.remainingPaintExtent;
return (to.clamp(a, b) - from.clamp(a, b)).clamp(0.0, constraints.remainingPaintExtent);

D.assert(from <= to);
double a = constraints.scrollOffset + constraints.cacheOrigin;
double b = constraints.scrollOffset + constraints.remainingCacheExtent;
return (to.clamp(a, b) - from.clamp(a, b)).clamp(0.0, constraints.remainingCacheExtent);

D.assert(() => { throw new UIWidgetsError(this.GetType() + " does not implement childPosition."); });
return 0.0;
}

public virtual double childScrollOffset(RenderObject child) {
D.assert(child.parent == this);
D.assert(() => { throw new UIWidgetsError(this.GetType() + " does not implement applyPaintTransform."); });
public Size getAbsoluteSizeRelativeToOrigin() {
internal Size getAbsoluteSizeRelativeToOrigin() {
D.assert(this.geometry != null);
D.assert(!this.debugNeedsLayout);
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(
this.constraints.axisDirection, this.constraints.growthDirection)) {
case AxisDirection.up:

return new Size(-this.geometry.paintExtent, this.constraints.crossAxisExtent);
}
D.assert(false);
void _debugDrawArrow(Canvas canvas, Paint paint, Offset p0, Offset p1, GrowthDirection direction) {
D.assert(() => {
if (p0 == p1) {
return true;
}
D.assert(p0.dx == p1.dx || p0.dy == p1.dy);
double d = (p1 - p0).distance * 0.2;
Offset temp;
double dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
switch (direction) {
case GrowthDirection.forward:
dx1 = dx2 = dy1 = dy2 = d;
break;
case GrowthDirection.reverse:
temp = p0;
p0 = p1;
p1 = temp;
dx1 = dx2 = dy1 = dy2 = -d;
break;
}
if (p0.dx == p1.dx) {
dx2 = -dx2;
} else {
dy2 = -dy2;
}
// canvas.drawPath(
// new Path()
// ..moveTo(p0.dx, p0.dy)
// ..lineTo(p1.dx, p1.dy)
// ..moveTo(p1.dx - dx1, p1.dy - dy1)
// ..lineTo(p1.dx, p1.dy)
// ..lineTo(p1.dx - dx2, p1.dy - dy2),
// paint
// );
return true;
});
}
public override void debugPaint(PaintingContext context, Offset offset) {
D.assert(() => {
if (D.debugPaintSizeEnabled) {
double strokeWidth = Math.Min(4.0, this.geometry.paintExtent / 30.0);
Paint paint = new Paint();
// ..color = const Color(0xFF33CC33)
// ..strokeWidth = strokeWidth
// ..style = PaintingStyle.stroke
// ..maskFilter = new MaskFilter.blur(BlurStyle.solid, strokeWidth);
double arrowExtent = this.geometry.paintExtent;
double padding = Math.Max(2.0, strokeWidth);
Canvas canvas = context.canvas;
// canvas.drawCircle(
// offset.translate(padding, padding),
// padding * 0.5,
// paint,
// );
switch (constraints.axis) {
case Axis.vertical:
// canvas.drawLine(
// offset,
// offset.translate(constraints.crossAxisExtent, 0.0),
// paint,
// );
this._debugDrawArrow(
canvas,
paint,
offset.translate(this.constraints.crossAxisExtent * 1.0 / 4.0, padding),
offset.translate(this.constraints.crossAxisExtent * 1.0 / 4.0, arrowExtent - padding),
this.constraints.normalizedGrowthDirection
);
this._debugDrawArrow(
canvas,
paint,
offset.translate(this.constraints.crossAxisExtent * 3.0 / 4.0, padding),
offset.translate(this.constraints.crossAxisExtent * 3.0 / 4.0, arrowExtent - padding),
this.constraints.normalizedGrowthDirection
);
break;
case Axis.horizontal:
// canvas.drawLine(
// offset,
// offset.translate(0.0, constraints.crossAxisExtent),
// paint,
// );
this._debugDrawArrow(
canvas,
paint,
offset.translate(padding, this.constraints.crossAxisExtent * 1.0 / 4.0),
offset.translate(arrowExtent - padding, this.constraints.crossAxisExtent * 1.0 / 4.0),
this.constraints.normalizedGrowthDirection
);
this._debugDrawArrow(
canvas,
paint,
offset.translate(padding, this.constraints.crossAxisExtent * 3.0 / 4.0),
offset.translate(arrowExtent - padding, this.constraints.crossAxisExtent * 3.0 / 4.0),
this.constraints.normalizedGrowthDirection
);
break;
}
}
return true;
});
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<SliverGeometry>("geometry", this.geometry));
}
D.assert(constraints != null);
switch (constraints.axisDirection) {
case AxisDirection.up:
case AxisDirection.left:

return rightWayUp;
}
public static bool hitTestBoxChild(this RenderSliver it, HitTestResult result, RenderBox child,
double mainAxisPosition = 0.0, double crossAxisPosition = 0.0) {
bool rightWayUp = _getRightWayUp(it.constraints);
double absolutePosition = mainAxisPosition - it.childMainAxisPosition(child);
double absoluteCrossAxisPosition = crossAxisPosition - it.childCrossAxisPosition(child);
switch (it.constraints.axis) {
case Axis.horizontal:
if (!rightWayUp) {
absolutePosition = child.size.width - absolutePosition;
}
return child.hitTest(result, position: new Offset(absolutePosition, absoluteCrossAxisPosition));
case Axis.vertical:
if (!rightWayUp) {
absolutePosition = child.size.height - absolutePosition;
}
return child.hitTest(result, position: new Offset(absoluteCrossAxisPosition, absolutePosition));
}
return false;
}
bool rightWayUp = RenderSliverHelpers._getRightWayUp(it.constraints);
bool rightWayUp = _getRightWayUp(it.constraints);
double delta = it.childMainAxisPosition(child);
double crossAxisDelta = it.childCrossAxisPosition(child);
switch (it.constraints.axis) {

}
}
protected override bool hitTestChildren(HitTestResult result, double mainAxisPosition = 0.0,
double crossAxisPosition = 0.0) {
D.assert(this.geometry.hitTestExtent > 0.0);
if (this.child != null) {
return this.hitTestBoxChild(result, this.child, mainAxisPosition: mainAxisPosition,
crossAxisPosition: crossAxisPosition);
}
return false;
}
D.assert(child != null);
D.assert(child == this.child);
var childParentData = (SliverPhysicalParentData) child.parentData;
childParentData.applyPaintTransform(ref transform);
}

) : base(child) {
}
public override void performLayout() {
protected override void performLayout() {
if (this.child == null) {
this.geometry = SliverGeometry.zero;
return;

double paintedChildSize = this.calculatePaintOffset(this.constraints, from: 0.0, to: childExtent);
double cacheExtent = this.calculateCacheOffset(this.constraints, from: 0.0, to: childExtent);
D.assert(paintedChildSize.isFinite());
D.assert(paintedChildSize >= 0.0);
this.geometry = new SliverGeometry(
scrollExtent: childExtent,

29
Assets/UIWidgets/rendering/sliver_fixed_extent_list.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.rendering {

public abstract double itemExtent { get; set; }
public double indexToLayoutOffset(double itemExtent, int index) {
protected double indexToLayoutOffset(double itemExtent, int index) {
public int getMinChildIndexForScrollOffset(double scrollOffset, double itemExtent) {
protected int getMinChildIndexForScrollOffset(double scrollOffset, double itemExtent) {
public int getMaxChildIndexForScrollOffset(double scrollOffset, double itemExtent) {
protected int getMaxChildIndexForScrollOffset(double scrollOffset, double itemExtent) {
public double? estimateMaxScrollOffset(SliverConstraints constraints,
protected double estimateMaxScrollOffset(SliverConstraints constraints,
int firstIndex = 0,
int lastIndex = 0,
double leadingScrollOffset = 0.0,

);
}
public double computeMaxScrollOffset(SliverConstraints constraints, double itemExtent) {
protected double computeMaxScrollOffset(SliverConstraints constraints, double itemExtent) {
public override void performLayout() {
protected override void performLayout() {
this.childManager.didStartLayout();
this.childManager.setDidUnderflow(false);

D.assert(scrollOffset >= 0.0);
D.assert(remainingExtent >= 0.0);
double targetEndScrollOffset = scrollOffset + remainingExtent;
BoxConstraints childConstraints = this.constraints.asBoxConstraints(

int firstIndex = this.getMinChildIndexForScrollOffset(scrollOffset, itemExtent);
int? targetLastIndex = !double.IsInfinity(targetEndScrollOffset)
int? targetLastIndex = targetEndScrollOffset.isFinite()
? this.getMaxChildIndexForScrollOffset(targetEndScrollOffset, itemExtent)
: (int?) null;

var childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
childParentData.layoutOffset = this.indexToLayoutOffset(itemExtent, index);
D.assert(childParentData.index == index);
trailingChildWithLayout = trailingChildWithLayout ?? child;
}

}
trailingChildWithLayout = child;
D.assert(child != null);
var childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
childParentData.layoutOffset = this.indexToLayoutOffset(itemExtent, childParentData.index);
}

double trailingScrollOffset = this.indexToLayoutOffset(itemExtent, lastIndex + 1);
D.assert(firstIndex == 0 || this.childScrollOffset(firstChild) <= scrollOffset);
D.assert(this.debugAssertChildListIsNonEmptyAndContiguous());
D.assert(this.indexOf(firstChild) == firstIndex);
D.assert(targetLastIndex == null || lastIndex <= targetLastIndex);
double estimatedMaxScrollOffset = this.estimateMaxScrollOffset(
this.constraints,
firstIndex: firstIndex,

).Value;
);
double paintExtent = this.calculatePaintOffset(
this.constraints,

hasVisualOverflow: (targetLastIndexForPaint != null && lastIndex >= targetLastIndexForPaint)
|| this.constraints.scrollOffset > 0.0
);
if (estimatedMaxScrollOffset == trailingScrollOffset) {
this.childManager.setDidUnderflow(true);
}

33
Assets/UIWidgets/rendering/sliver_list.cs


using System;
using UIWidgets.foundation;
namespace UIWidgets.rendering {
public class RenderSliverList : RenderSliverMultiBoxAdaptor {

}
public override void performLayout() {
protected override void performLayout() {
D.assert(scrollOffset >= 0.0);
D.assert(remainingExtent >= 0.0);
double targetEndScrollOffset = scrollOffset + remainingExtent;
BoxConstraints childConstraints = this.constraints.asBoxConstraints();
int leadingGarbage = 0;

if (firstChildScrollOffset < 0.0) {
double correction = 0.0;
while (earliestUsefulChild != null) {
correction += this.paintExtentOf(firstChild);
D.assert(this.firstChild == earliestUsefulChild);
correction += this.paintExtentOf(this.firstChild);
earliestUsefulChild =
this.insertAndLayoutLeadingChild(childConstraints, parentUsesSize: true);
}

} else {
var childParentData = (SliverMultiBoxAdaptorParentData) earliestUsefulChild.parentData;
childParentData.layoutOffset = firstChildScrollOffset;
D.assert(earliestUsefulChild == this.firstChild);
leadingChildWithLayout = earliestUsefulChild;
trailingChildWithLayout = trailingChildWithLayout ?? earliestUsefulChild;
}

D.assert(earliestUsefulChild == this.firstChild);
D.assert(this.childScrollOffset(earliestUsefulChild) <= scrollOffset);
if (leadingChildWithLayout == null) {
earliestUsefulChild.layout(childConstraints, parentUsesSize: true);
leadingChildWithLayout = earliestUsefulChild;

double endScrollOffset = this.childScrollOffset(child) + this.paintExtentOf(child);
Func<bool> advance = () => {
D.assert(child != null);
if (child == trailingChildWithLayout) {
inLayoutRange = false;
}

index += 1;
if (!inLayoutRange) {
if (child == null || this.indexOf(child) != index) {
child = insertAndLayoutChild(childConstraints,
child = this.insertAndLayoutChild(childConstraints,
after: trailingChildWithLayout,
parentUsesSize: true
);

trailingChildWithLayout = child;
}
D.assert(child != null);
D.assert(childParentData.index == index);
endScrollOffset = this.childScrollOffset(child) + this.paintExtentOf(child);
return true;
};

if (!advance()) {
D.assert(leadingGarbage == this.childCount);
D.assert(child == null);
D.assert(this.firstChild == this.lastChild);
double extent = this.childScrollOffset(this.lastChild) + this.paintExtentOf(this.lastChild);
this.geometry = new SliverGeometry(
scrollExtent: extent,

this.collectGarbage(leadingGarbage, trailingGarbage);
double estimatedMaxScrollOffset;
D.assert(this.debugAssertChildListIsNonEmptyAndContiguous());
double? estimatedMaxScrollOffset;
if (reachedEnd) {
estimatedMaxScrollOffset = endScrollOffset;
} else {

lastIndex: this.indexOf(this.lastChild),
leadingScrollOffset: this.childScrollOffset(this.firstChild),
trailingScrollOffset: endScrollOffset
).Value;
);
D.assert(estimatedMaxScrollOffset >= endScrollOffset - this.childScrollOffset(this.firstChild));
}
double paintExtent = this.calculatePaintOffset(

double targetEndScrollOffsetForPaint =
this.constraints.scrollOffset + this.constraints.remainingPaintExtent;
this.geometry = new SliverGeometry(
scrollExtent: estimatedMaxScrollOffset,
scrollExtent: estimatedMaxScrollOffset.Value,
maxPaintExtent: estimatedMaxScrollOffset,
maxPaintExtent: estimatedMaxScrollOffset.Value,
hasVisualOverflow: endScrollOffset > targetEndScrollOffsetForPaint ||
this.constraints.scrollOffset > 0.0
);

151
Assets/UIWidgets/rendering/sliver_multi_box_adaptor.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.ui;
using UnityEngine;

void removeChild(RenderBox child);
double? estimateMaxScrollOffset(
double estimateMaxScrollOffset(
SliverConstraints constraints,
int firstIndex = 0,
int lastIndex = 0,

void didStartLayout();
void didFinishLayout();
bool debugAssertChildListLocked();
}

public bool keepAlive = false;
public bool _keptAlive = false;
internal bool _keptAlive = false;
public override string ToString() {
return string.Format(
"index={0}; {1}{2}", this.index, this.keepAlive ? "keeyAlive; " : "", base.ToString());
}
}
public abstract class RenderSliverMultiBoxAdaptor

) {
D.assert(childManager != null);
this._childManager = childManager;
}

}
}
public RenderSliverBoxChildManager childManager {
protected RenderSliverBoxChildManager childManager {
public RenderSliverBoxChildManager _childManager;
readonly RenderSliverBoxChildManager _childManager;
public readonly Dictionary<int, RenderBox> _keepAliveBucket = new Dictionary<int, RenderBox>();
readonly Dictionary<int, RenderBox> _keepAliveBucket = new Dictionary<int, RenderBox>();
protected override void adoptChild(AbstractNodeMixinDiagnosticableTree childNode) {
base.adoptChild(childNode);

}
}
bool _debugAssertChildListLocked() {
return this.childManager.debugAssertChildListLocked();
}
D.assert(this.firstChild != null);
D.assert(() => {
int index = this.indexOf(this.firstChild);
RenderBox childAfter = this.childAfter(this.firstChild);
while (childAfter != null) {
D.assert(this.indexOf(childAfter) > index);
index = this.indexOf(childAfter);
childAfter = this.childAfter(childAfter);
}
return true;
});
}
public override void remove(RenderBox child) {

return;
}
D.assert(this._keepAliveBucket[childParentData.index] == child);
this._keepAliveBucket.Remove(childParentData.index);
this.dropChild(child);
}

}
void _createOrObtainChild(int index, RenderBox after = null) {
this.invokeLayoutCallback<SliverConstraints>((SliverConstraints constraints) => {
this.invokeLayoutCallback<SliverConstraints>(constraints => {
D.assert(constraints == this.constraints);
D.assert(childParentData._keptAlive);
this.dropChild(child);
child.parentData = childParentData;
this.insert(child, after: after);

public void _destroyOrCacheChild(RenderBox child) {
var childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
if (childParentData.keepAlive) {
D.assert(!childParentData._keptAlive);
this.remove(child);
this._keepAliveBucket[childParentData.index] = child;
child.parentData = childParentData;

D.assert(child.parent == this);
D.assert(child.parent == null);
}
}

}
}
public bool addInitialChild(int index = 0, double layoutOffset = 0.0) {
protected bool addInitialChild(int index = 0, double layoutOffset = 0.0) {
D.assert(this._debugAssertChildListLocked());
D.assert(this.firstChild == null);
D.assert(this.firstChild == this.lastChild);
D.assert(this.indexOf(this.firstChild) == index);
var firstChildParentData = (SliverMultiBoxAdaptorParentData) this.firstChild.parentData;
firstChildParentData.layoutOffset = layoutOffset;
return true;

return false;
}
public RenderBox insertAndLayoutLeadingChild(BoxConstraints childConstraints, bool parentUsesSize = false) {
protected RenderBox insertAndLayoutLeadingChild(BoxConstraints childConstraints, bool parentUsesSize = false) {
D.assert(this._debugAssertChildListLocked());
int index = this.indexOf(this.firstChild) - 1;
this._createOrObtainChild(index, after: null);
if (this.indexOf(this.firstChild) == index) {

return null;
}
public RenderBox insertAndLayoutChild(
protected RenderBox insertAndLayoutChild(
D.assert(this._debugAssertChildListLocked());
D.assert(after != null);
int index = this.indexOf(after) + 1;
this._createOrObtainChild(index, after: after);
RenderBox child = this.childAfter(after);

return null;
}
public void collectGarbage(int leadingGarbage, int trailingGarbage) {
this.invokeLayoutCallback<SliverConstraints>((SliverConstraints constraints) => {
protected void collectGarbage(int leadingGarbage, int trailingGarbage) {
D.assert(this._debugAssertChildListLocked());
D.assert(this.childCount >= leadingGarbage + trailingGarbage);
this.invokeLayoutCallback<SliverConstraints>(constraints => {
while (leadingGarbage > 0) {
this._destroyOrCacheChild(this.firstChild);
leadingGarbage -= 1;

trailingGarbage -= 1;
}
this._keepAliveBucket.Values.Where((RenderBox child) => {
this._keepAliveBucket.Values.Where(child => {
D.assert(this._keepAliveBucket.Values.Where(child => {
var childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
return !childParentData.keepAlive;
}).ToList().isEmpty());
D.assert(child != null);
public double paintExtentOf(RenderBox child) {
protected double paintExtentOf(RenderBox child) {
D.assert(child != null);
D.assert(child.hasSize);
switch (this.constraints.axis) {
case Axis.horizontal:
return child.size.width;

return 0.0;
}
protected override bool hitTestChildren(HitTestResult result, double mainAxisPosition = 0.0,
double crossAxisPosition = 0.0) {
RenderBox child = this.lastChild;
while (child != null) {
if (this.hitTestBoxChild(result, child, mainAxisPosition: mainAxisPosition,
crossAxisPosition: crossAxisPosition)) {
return true;
}
child = this.childBefore(child);
}
return false;
}
D.assert(child != null);
D.assert(child.parent == this);
var childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
return childParentData.layoutOffset;
}

child = this.childAfter(child);
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(DiagnosticsNode.message(this.firstChild != null
? "currently live children: " + this.indexOf(this.firstChild) + " to " + this.indexOf(this.lastChild)
: "no children current live"));
}
public bool debugAssertChildListIsNonEmptyAndContiguous() {
D.assert(() => {
D.assert(this.firstChild != null);
int index = this.indexOf(this.firstChild);
RenderBox child = this.childAfter(this.firstChild);
while (child != null) {
index += 1;
D.assert(this.indexOf(child) == index);
child = this.childAfter(child);
}
return true;
});
return true;
}
public override List<DiagnosticsNode> debugDescribeChildren() {
var children = new List<DiagnosticsNode>();
if (this.firstChild != null) {
RenderBox child = this.firstChild;
while (true) {
var childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;
children.Add(child.toDiagnosticsNode(name: "child with index " + childParentData.index));
if (child == this.lastChild) {
break;
}
child = childParentData.nextSibling;
}
}
if (this._keepAliveBucket.isNotEmpty()) {
List<int> indices = this._keepAliveBucket.Keys.ToList();
indices.Sort();
foreach (int index in indices) {
children.Add(this._keepAliveBucket[index].toDiagnosticsNode(
name: "child with index " + index + " (kept alive offstage)",
style: DiagnosticsTreeStyle.offstage
));
}
}
return children;
}
}
}

86
Assets/UIWidgets/rendering/sliver_padding.cs


using System;
using UIWidgets.foundation;
using UIWidgets.gestures;
using Rect = UIWidgets.ui.Rect;
namespace UIWidgets.rendering {
public class RenderSliverPadding : RenderObjectWithChildMixinRenderSliver<RenderSliver> {

) {
D.assert(padding != null);
D.assert(padding.isNonNegative);
this._padding = padding;
this.child = child;
}

set {
D.assert(value != null);
D.assert(value.isNonNegative);
if (this._padding == value) {
return;
}

}
}
public EdgeInsets _padding;
EdgeInsets _padding;
D.assert(this.constraints != null);
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(
this.constraints.axisDirection, this.constraints.growthDirection)) {
case AxisDirection.up:

public double afterPadding {
get {
D.assert(this.constraints != null);
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(
this.constraints.axisDirection, this.constraints.growthDirection)) {
case AxisDirection.up:

}
public double mainAxisPadding {
get { return this._padding.along(this.constraints.axis); }
get {
D.assert(this.constraints != null);
return this._padding.along(this.constraints.axis);
}
D.assert(this.constraints != null);
switch (this.constraints.axis) {
case Axis.horizontal:
return this._padding.vertical;

D.assert(false);
return 0.0;
}
}

}
}
public override void performLayout() {
protected override void performLayout() {
double beforePadding = this.beforePadding;
double afterPadding = this.afterPadding;
double mainAxisPadding = this.mainAxisPadding;

);
SliverGeometry childLayoutGeometry = this.child.geometry;
if (childLayoutGeometry.scrollOffsetCorrection != 0.0) {
if (childLayoutGeometry.scrollOffsetCorrection != null) {
this.geometry = new SliverGeometry(
scrollOffsetCorrection: childLayoutGeometry.scrollOffsetCorrection
);

this._padding.top);
break;
}
D.assert(childParentData.paintOffset != null);
D.assert(beforePadding == this.beforePadding);
D.assert(afterPadding == this.afterPadding);
D.assert(mainAxisPadding == this.mainAxisPadding);
D.assert(crossAxisPadding == this.crossAxisPadding);
}
protected override bool hitTestChildren(HitTestResult result, double mainAxisPosition = 0.0,
double crossAxisPosition = 0.0) {
if (this.child != null && this.child.geometry.hitTestExtent > 0.0) {
return this.child.hitTest(result,
mainAxisPosition: mainAxisPosition - this.childMainAxisPosition(this.child),
crossAxisPosition: crossAxisPosition - this.childCrossAxisPosition(this.child));
}
return false;
D.assert(child != null);
D.assert(child == this.child);
D.assert(child != null);
D.assert(child == this.child);
D.assert(this.constraints != null);
switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(
this.constraints.axisDirection, this.constraints.growthDirection)) {
case AxisDirection.up:

}
public override double childScrollOffset(RenderObject child) {
D.assert(child.parent == this);
D.assert(child != null);
D.assert(child == this.child);
var childParentData = (SliverPhysicalParentData) child.parentData;
childParentData.applyPaintTransform(ref transform);
}

var childParentData = (SliverPhysicalParentData) this.child.parentData;
context.paintChild(this.child, offset + childParentData.paintOffset);
}
}
public override void debugPaint(PaintingContext context, Offset offset) {
base.debugPaint(context, offset);
D.assert(() => {
if (D.debugPaintSizeEnabled) {
Size parentSize = this.getAbsoluteSizeRelativeToOrigin();
Rect outerRect = offset & parentSize;
Size childSize = null;
Rect innerRect = null;
if (this.child != null) {
childSize = this.child.getAbsoluteSizeRelativeToOrigin();
var childParentData = (SliverPhysicalParentData) this.child.parentData;
innerRect = (offset + childParentData.paintOffset) & childSize;
D.assert(innerRect.top >= outerRect.top);
D.assert(innerRect.left >= outerRect.left);
D.assert(innerRect.right <= outerRect.right);
D.assert(innerRect.bottom <= outerRect.bottom);
}
D.debugPaintPadding(context.canvas, outerRect, innerRect);
}
return true;
});
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", this.padding));
}
}
}

46
Assets/UIWidgets/rendering/view.cs


using System;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.ui;
using UnityEngine;

public RenderView(
RenderBox child = null,
ViewConfiguration configuration = null) {
D.assert(configuration != null);
this.child = child;
this._configuration = configuration;
}

}
public Size _size = Size.zero;
Size _size = Size.zero;
D.assert(value != null);
if (value == this._configuration) {
return;
}

}
}
public ViewConfiguration _configuration;
ViewConfiguration _configuration;
D.assert(this.owner != null);
public Matrix4x4 _rootTransform;
Matrix4x4 _rootTransform;
public Layer _updateMatricesAndCreateNewRootLayer() {
this._rootTransform = this.configuration.toMatrix();

}
public override void performResize() {
throw new NotImplementedException();
protected override void debugAssertDoesMeetConstraints() {
D.assert(false);
}
protected override void performResize() {
D.assert(false);
public override void performLayout() {
protected override void performLayout() {
D.assert(this._size.isFinite);
if (this.child != null) {
this.child.layout(BoxConstraints.tight(this._size));
}

this.layer.addToScene(builder, Offset.zero);
var scene = builder.build();
Window.instance.render(scene);
scene.dispose();
D.assert(() => {
// if (D.debugRepaintRainbowEnabled || D.debugRepaintTextRainbowEnabled) {
// debugCurrentRepaintColor =
// debugCurrentRepaintColor.withHue((debugCurrentRepaintColor.hue + 2.0) % 360.0);
// }
return true;
});
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
D.assert(() => {
properties.add(DiagnosticsNode.message("debug mode enabled"));
return true;
});
properties.add(new DiagnosticsProperty<Size>("window size", Window.instance.physicalSize,
tooltip: "in physical pixels"));
properties.add(new DoubleProperty("device pixel ratio", Window.instance.devicePixelRatio,
tooltip: "physical pixels per logical pixel"));
properties.add(new DiagnosticsProperty<ViewConfiguration>("configuration", this.configuration,
tooltip: "in logical pixels"));
}
}
}

10
Assets/UIWidgets/ui/compositing.cs


this._layerBuilder.pushTransform(matrix);
}
public void pushClipRect(Rect rect) {
public void pushClipRect(Rect rect, Clip clipBehavior = Clip.hardEdge) {
public void pushClipRRect(RRect rrect) {
public void pushClipRRect(RRect rrect, Clip clipBehavior = Clip.antiAlias) {
this._layerBuilder.pushClipRRect(rrect);
}

this._layerBuilder.pop();
}
public void addPicture(Offset offset, Picture picture) {
public void addPicture(Offset offset, Picture picture,
bool isComplexHint = false, bool willChangeHint = false) {
this._layerBuilder.addPicture(offset, picture);
}

public Layer takeLayer() {
return this._rootLayer;
}
public void dispose() {
}
}
}

14
Assets/UIWidgets/ui/geometry.cs


return Math.Sign(value);
}
public static bool isInfinite(this double it) {
return double.IsInfinity(it);
}
public static bool isNaN(this double it) {
return double.IsNaN(it);
}
public static double lerpDouble(double a, double b, double t) {
return a + (b - a) * t;
}

}
public static int floor(this double value) {
return (int) Math.Floor(value);
}

public Rect inflate(double delta) {
return Rect.fromLTRB(this.left - delta, this.top - delta, this.right + delta, this.bottom + delta);
}
public Rect deflate(double delta) {
return this.inflate(-delta);
}
public Rect intersect(Rect other) {

29
Assets/UIWidgets/ui/painting/canvas.cs


void restore();
void clipRect(Rect rect);
int getSaveCount();
void clipRRect(RRect rrect);
void clipRect(Rect rect, bool doAntiAlias = true);
void clipRRect(RRect rrect, bool doAntiAlias = true);
void drawTextBlob(TextBlob textBlob, double x, double y);
}

this._recorder = recorder;
}
private readonly PictureRecorder _recorder;
readonly PictureRecorder _recorder;
int _saveCount = 1;
public void drawPloygon4(Offset[] points, Paint paint) {
this._recorder.addDrawCmd(new DrawPloygon4 {

}
public void drawImageRect(Rect src, Rect dst, Paint paint, Image image) {
this._recorder.addDrawCmd(new DrawImageRect
{
this._recorder.addDrawCmd(new DrawImageRect {
paint = paint,
image = image,
src = src,

}
public void save() {
this._saveCount++;
this._saveCount++;
this._recorder.addDrawCmd(new DrawSaveLayer {
rect = rect,
paint = paint,

public void restore() {
this._saveCount--;
public void clipRect(Rect rect) {
public int getSaveCount() {
return this._saveCount;
}
public void clipRect(Rect rect, bool doAntiAlias = true) {
public void clipRRect(RRect rrect) {
public void clipRRect(RRect rrect, bool doAntiAlias = true) {
public void drawTextBlob(TextBlob textBlob, double x, double y)
{
public void drawTextBlob(TextBlob textBlob, double x, double y) {
this._recorder.addDrawCmd(new DrawTextBlob() {
textBlob = textBlob,
x = x,

}
}
}

8
Assets/UIWidgets/ui/painting/canvas_impl.cs


}
}
public void clipRect(Rect rect) {
public int getSaveCount() {
return this._stack.Count + 1;
}
public void clipRect(Rect rect, bool doAntiAlias = true) {
if (rect.isInfinite) {
return;
}

public void clipRRect(RRect rect) {
public void clipRRect(RRect rect, bool doAntiAlias = true) {
if (rect.isInfinite) {
return;
}

7
Assets/UIWidgets/ui/painting/painting.cs


}
}
public enum Clip {
none,
hardEdge,
antiAlias,
antiAliasWithSaveLayer,
}
public class Paint {
public Color color;
public double blurSigma;

9
Assets/UIWidgets/widgets/basic.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.rendering;

public BoxConstraints constraints;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderConstrainedBox(additionalConstraints: constraints);
return new RenderConstrainedBox(additionalConstraints: this.constraints);
((RenderConstrainedBox) renderObject)._additionalConstraints = constraints;
((RenderConstrainedBox) renderObject).additionalConstraints = this.constraints;
}
}

transform: transform,
origin: origin,
alignment: alignment,
textDirection: Directionality.of(context),
transformHitTests: transformHitTests
);
}

((RenderTransform) renderObject).origin = origin;
((RenderTransform) renderObject).alignment = alignment;
((RenderTransform) renderObject).textDirection = Directionality.of(context);
((RenderTransform) renderObject).transformHitTests = transformHitTests;
}
}

}
public static List<RepaintBoundary> wrapAll(List<Widget> widgets) {
List<RepaintBoundary> result = new List<RepaintBoundary>(widgets.Count);
List<RepaintBoundary> result = Enumerable.Repeat((RepaintBoundary) null, widgets.Count).ToList();
for (int i = 0; i < result.Count; ++i) {
result[i] = RepaintBoundary.wrap(widgets[i], i);
}

4
Assets/UIWidgets/widgets/framework.cs


var newChildren = oldChildren.Count == newWidgets.Count
? oldChildren
: new List<Element>(newWidgets.Count);
: Enumerable.Repeat((Element) null, newWidgets.Count).ToList();
Element previousChild = null;

public override void mount(Element parent, object newSlot) {
base.mount(parent, newSlot);
this._children = new List<Element>(this.widget.children.Count);
this._children = Enumerable.Repeat((Element) null, this.widget.children.Count).ToList();
Element previousChild = null;
for (int i = 0; i < this._children.Count; i += 1) {
Element newChild = this.inflateWidget(this.widget.children[i], previousChild);

2
Assets/UIWidgets/widgets/scroll_controller.cs


Curve curve
) {
D.assert(this._positions.isNotEmpty(), "ScrollController not attached to any scroll views.");
List<IPromise> animations = new List<IPromise>(this._positions.Count);
List<IPromise> animations = Enumerable.Repeat((IPromise) null, this._positions.Count).ToList();
for (int i = 0; i < this._positions.Count; i += 1) {
animations[i] = this._positions[i].animateTo(to, duration: duration, curve: curve);
}

4
Assets/UIWidgets/widgets/scroll_notification.mixin.gen.cs


public abstract class ViewportNotificationMixinNotification : Notification {
public int depth {
get { return _depth; }
get { return this._depth; }
}
int _depth = 0;

public abstract class ViewportNotificationMixinLayoutChangedNotification : LayoutChangedNotification {
public int depth {
get { return _depth; }
get { return this._depth; }
}
int _depth = 0;

2
Assets/UIWidgets/widgets/scroll_notification.mixin.njk


{% macro ViewportNotificationMixin(with) %}
public abstract class ViewportNotificationMixin{{with}} : {{with}} {
public int depth {
get { return _depth; }
get { return this._depth; }
}
int _depth = 0;

2
Assets/UIWidgets/widgets/scroll_position.cs


Curve curve = null
) {
D.assert(renderObject.attached);
RenderAbstractViewport viewport = RenderAbstractViewportUtils.of(renderObject);
RenderAbstractViewport viewport = RenderViewportUtils.of(renderObject);
D.assert(viewport != null);
double target = viewport.getOffsetToReveal(renderObject, alignment).offset.clamp(

12
Assets/UIWidgets/widgets/sliver.cs


bool addRepaintBoundaries = true
) {
D.assert(builder != null);
this.builder = build;
this.builder = builder;
public readonly IndexedWidgetBuilder builder;

Element newChild;
try {
this._currentlyUpdatingChildIndex = index;
newChild = this.updateChild(this._childElements[index], this._build(index), index);
this._childElements.TryGetValue(index, out newChild);
newChild = this.updateChild(newChild, this._build(index), index);
}
finally {
this._currentlyUpdatingChildIndex = null;

}
Element newChild = base.updateChild(child, newWidget, newSlot);
if (child != null && child.renderObject != null) {
if (newChild != null && newChild.renderObject != null) {
newParentData = (SliverMultiBoxAdaptorParentData) newChild.renderObject.parentData;
}

return trailingScrollOffset + averageExtent * remainingCount;
}
public double? estimateMaxScrollOffset(SliverConstraints constraints,
public double estimateMaxScrollOffset(SliverConstraints constraints,
int firstIndex = 0,
int lastIndex = 0,
double leadingScrollOffset = 0,

4
Assets/UIWidgets/widgets/viewport.cs


Viewport.getDefaultCrossAxisDirection(context, this.axisDirection),
anchor: this.anchor,
offset: this.offset,
cacheExtent: this.cacheExtent
cacheExtent: this.cacheExtent ?? RenderViewportUtils.defaultCacheExtent
);
}

Viewport.getDefaultCrossAxisDirection(context, this.axisDirection);
renderObject.anchor = this.anchor;
renderObject.offset = this.offset;
renderObject.cacheExtent = this.cacheExtent ?? RenderAbstractViewportUtils.defaultCacheExtent;
renderObject.cacheExtent = this.cacheExtent ?? RenderViewportUtils.defaultCacheExtent;
}
public override Element createElement() {

79
Assets/UIWidgets/Tests/ScrollViews.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)
);
}
);
}
}
}

3
Assets/UIWidgets/Tests/ScrollViews.cs.meta


fileFormatVersion: 2
guid: b14d32b9a23040969ca3316c86d899c3
timeCreated: 1537352615

48
Assets/UIWidgets/painting/clip.cs


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);
}
}
}

3
Assets/UIWidgets/painting/clip.cs.meta


fileFormatVersion: 2
guid: cff14a26e8ec47a594a157246716b378
timeCreated: 1537611888

1001
Assets/UIWidgets/rendering/viewport.cs
文件差异内容过多而无法显示
查看文件

853
Assets/UIWidgets/rendering/viewpoint.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);
}
}
}
}
}

/Assets/UIWidgets/rendering/viewpoint.cs.meta → /Assets/UIWidgets/rendering/viewport.cs.meta

正在加载...
取消
保存