Commit e9ac6d30 authored by Adam Barth's avatar Adam Barth

RenderBox should use Offset for child offset

Previously we used Position, which makes it harder to accumulate offsets
when walking the render tree.
parent 31bc220d
......@@ -111,8 +111,8 @@ class _ModalBottomSheetLayout extends OneChildLayoutDelegate {
);
}
Point getPositionForChild(Size size, Size childSize) {
return new Point(0.0, size.height - childSize.height * progress);
Offset getPositionForChild(Size size, Size childSize) {
return new Offset(0.0, size.height - childSize.height * progress);
}
bool shouldRelayout(_ModalBottomSheetLayout oldDelegate) {
......
......@@ -44,14 +44,14 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
if (isChild(_Child.toolBar)) {
toolBarSize = layoutChild(_Child.toolBar, toolBarConstraints);
positionChild(_Child.toolBar, Point.origin);
positionChild(_Child.toolBar, Offset.zero);
}
if (isChild(_Child.body)) {
final double bodyHeight = size.height - toolBarSize.height;
final BoxConstraints bodyConstraints = toolBarConstraints.tightenHeight(bodyHeight);
layoutChild(_Child.body, bodyConstraints);
positionChild(_Child.body, new Point(0.0, toolBarSize.height));
positionChild(_Child.body, new Offset(0.0, toolBarSize.height));
}
// The BottomSheet and the SnackBar are anchored to the bottom of the parent,
......@@ -69,12 +69,12 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
if (isChild(_Child.bottomSheet)) {
bottomSheetSize = layoutChild(_Child.bottomSheet, fullWidthConstraints);
positionChild(_Child.bottomSheet, new Point((size.width - bottomSheetSize.width) / 2.0, size.height - bottomSheetSize.height));
positionChild(_Child.bottomSheet, new Offset((size.width - bottomSheetSize.width) / 2.0, size.height - bottomSheetSize.height));
}
if (isChild(_Child.snackBar)) {
snackBarSize = layoutChild(_Child.snackBar, fullWidthConstraints);
positionChild(_Child.snackBar, new Point(0.0, size.height - snackBarSize.height));
positionChild(_Child.snackBar, new Offset(0.0, size.height - snackBarSize.height));
}
if (isChild(_Child.floatingActionButton)) {
......@@ -85,12 +85,12 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
fabY = math.min(fabY, size.height - snackBarSize.height - fabSize.height - _kFloatingActionButtonMargin);
if (bottomSheetSize.height > 0.0)
fabY = math.min(fabY, size.height - bottomSheetSize.height - fabSize.height / 2.0);
positionChild(_Child.floatingActionButton, new Point(fabX, fabY));
positionChild(_Child.floatingActionButton, new Offset(fabX, fabY));
}
if (isChild(_Child.drawer)) {
layoutChild(_Child.drawer, looseConstraints);
positionChild(_Child.drawer, Point.origin);
positionChild(_Child.drawer, Offset.zero);
}
}
}
......
......@@ -141,7 +141,7 @@ class _RenderTabBar extends RenderBox with
while (child != null) {
child.layout(tabConstraints);
final _TabBarParentData childParentData = child.parentData;
childParentData.position = new Point(x, 0.0);
childParentData.offset = new Offset(x, 0.0);
x += tabWidth;
child = childParentData.nextSibling;
}
......@@ -159,7 +159,7 @@ class _RenderTabBar extends RenderBox with
while (child != null) {
child.layout(tabConstraints, parentUsesSize: true);
final _TabBarParentData childParentData = child.parentData;
childParentData.position = new Point(x, 0.0);
childParentData.offset = new Offset(x, 0.0);
x += child.size.width;
child = childParentData.nextSibling;
}
......@@ -226,7 +226,7 @@ class _RenderTabBar extends RenderBox with
final Size size = new Size(selectedTab.size.width, _kTabIndicatorHeight);
final _TabBarParentData selectedTabParentData = selectedTab.parentData;
final Point point = new Point(
selectedTabParentData.position.x,
selectedTabParentData.offset.dx,
_tabBarHeight - _kTabIndicatorHeight
);
canvas.drawRect((point + offset) & size, new Paint()..color = indicatorColor);
......
......@@ -113,7 +113,7 @@ class AutoLayoutParentData extends ContainerBoxParentDataMixin<RenderBox> with _
height: _bottomEdge.value - _topEdge.value
);
_renderBox.layout(size);
position = new Point(_leftEdge.value, _topEdge.value);
offset = new Offset(_leftEdge.value, _topEdge.value);
}
List<al.Constraint> _constructImplicitConstraints() {
......
......@@ -96,8 +96,8 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
return minExtent;
BoxParentData parentData = child.parentData;
return isVertical ?
math.max(minExtent, parentData.position.y + child.size.height) :
math.max(minExtent, parentData.position.x + child.size.width);
math.max(minExtent, parentData.offset.dy + child.size.height) :
math.max(minExtent, parentData.offset.dx + child.size.width);
}
void performLayout() {
......@@ -107,7 +107,7 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
while (child != null) {
child.layout(innerConstraints, parentUsesSize: true);
final BlockParentData childParentData = child.parentData;
childParentData.position = isVertical ? new Point(0.0, position) : new Point(position, 0.0);
childParentData.offset = isVertical ? new Offset(0.0, position) : new Offset(position, 0.0);
position += isVertical ? child.size.height : child.size.width;
assert(child.parentData == childParentData);
child = childParentData.nextSibling;
......
......@@ -316,17 +316,15 @@ class BoxHitTestEntry extends HitTestEntry {
/// Parent data used by [RenderBox] and its subclasses.
class BoxParentData extends ParentData {
// TODO(abarth): Switch to using an Offset rather than a Point here. This
// value is really the offset from the parent.
Point _position = Point.origin;
/// The point at which to paint the child in the parent's coordinate system
Point get position => _position;
void set position(Point value) {
/// The offset at which to paint the child in the parent's coordinate system
Offset get offset => _offset;
Offset _offset = Offset.zero;
void set offset(Offset value) {
assert(RenderObject.debugDoingLayout);
_position = value;
_offset = value;
}
Offset get offset => _position.toOffset();
String toString() => 'position=$position';
String toString() => 'offset=$offset';
}
/// Abstract ParentData subclass for RenderBox subclasses that want the
......@@ -631,8 +629,8 @@ abstract class RenderBox extends RenderObject {
void applyPaintTransform(RenderObject child, Matrix4 transform) {
assert(child.parent == this);
BoxParentData childParentData = child.parentData;
Point position = childParentData.position;
transform.translate(position.x, position.y);
Offset offset = childParentData.offset;
transform.translate(offset.dx, offset.dy);
}
/// Convert the given point from the global coodinate system to the local
......@@ -766,7 +764,7 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
final ParentDataType childParentData = child.parentData;
double result = child.getDistanceToActualBaseline(baseline);
if (result != null)
return result + childParentData.position.y;
return result + childParentData.offset.dy;
child = childParentData.nextSibling;
}
return null;
......@@ -784,7 +782,7 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
final ParentDataType childParentData = child.parentData;
double candidate = child.getDistanceToActualBaseline(baseline);
if (candidate != null) {
candidate += childParentData.position.y;
candidate += childParentData.offset.dy;
if (result != null)
result = math.min(result, candidate);
else
......@@ -804,8 +802,8 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
ChildType child = lastChild;
while (child != null) {
final ParentDataType childParentData = child.parentData;
Point transformed = new Point(position.x - childParentData.position.x,
position.y - childParentData.position.y);
Point transformed = new Point(position.x - childParentData.offset.dx,
position.y - childParentData.offset.dy);
if (child.hitTest(result, position: transformed))
return true;
child = childParentData.previousSibling;
......
......@@ -47,11 +47,11 @@ abstract class MultiChildLayoutDelegate {
}
/// Specify the child's origin relative to this origin.
void positionChild(Object childId, Point position) {
void positionChild(Object childId, Offset offset) {
final RenderBox child = _idToChild[childId];
assert(child != null);
final MultiChildLayoutParentData childParentData = child.parentData;
childParentData.position = position;
childParentData.offset = offset;
}
void _callPerformLayout(Size size, BoxConstraints constraints, RenderBox firstChild) {
......
......@@ -530,10 +530,10 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}
switch (_direction) {
case FlexDirection.horizontal:
childParentData.position = new Point(childMainPosition, childCrossPosition);
childParentData.offset = new Offset(childMainPosition, childCrossPosition);
break;
case FlexDirection.vertical:
childParentData.position = new Point(childCrossPosition, childMainPosition);
childParentData.offset = new Offset(childCrossPosition, childMainPosition);
break;
}
childMainPosition += _getMainSize(child) + betweenSpace;
......
......@@ -125,7 +125,7 @@ class RenderGrid extends RenderBox with ContainerRenderObjectMixin<RenderBox, Gr
double x = (column + 1) * metrics.childPadding + (column * metrics.childSize.width);
double y = (row + 1) * metrics.childPadding + (row * metrics.childSize.height);
final GridParentData childParentData = child.parentData;
childParentData.position = new Point(x, y);
childParentData.offset = new Offset(x, y);
column += 1;
if (column >= metrics.childrenPerRow) {
......
......@@ -49,7 +49,7 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
result = child.getDistanceToActualBaseline(baseline);
final BoxParentData childParentData = child.parentData;
if (result != null)
result += childParentData.position.y;
result += childParentData.offset.dy;
} else {
result = super.computeDistanceToActualBaseline(baseline);
}
......@@ -66,8 +66,8 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
bool hitTestChildren(HitTestResult result, { Point position }) {
if (child != null) {
final BoxParentData childParentData = child.parentData;
final Point childPosition = new Point(position.x - childParentData.position.x,
position.y - childParentData.position.y);
final Point childPosition = new Point(position.x - childParentData.offset.dx,
position.y - childParentData.offset.dy);
return child.hitTest(result, position: childPosition);
}
return false;
......@@ -146,7 +146,7 @@ class RenderPadding extends RenderShiftedBox {
BoxConstraints innerConstraints = constraints.deflate(padding);
child.layout(innerConstraints, parentUsesSize: true);
final BoxParentData childParentData = child.parentData;
childParentData.position = new Point(padding.left, padding.top);
childParentData.offset = new Offset(padding.left, padding.top);
size = constraints.constrain(new Size(
padding.left + child.size.width + padding.right,
padding.top + child.size.height + padding.bottom
......@@ -238,7 +238,7 @@ class RenderPositionedBox extends RenderShiftedBox {
size = constraints.constrain(new Size(shrinkWrapWidth ? child.size.width * (_widthFactor ?? 1.0) : double.INFINITY,
shrinkWrapHeight ? child.size.height * (_heightFactor ?? 1.0) : double.INFINITY));
final BoxParentData childParentData = child.parentData;
childParentData.position = _alignment.alongOffset(size - child.size).toPoint();
childParentData.offset = _alignment.alongOffset(size - child.size);
} else {
size = constraints.constrain(new Size(shrinkWrapWidth ? 0.0 : double.INFINITY,
shrinkWrapHeight ? 0.0 : double.INFINITY));
......@@ -260,7 +260,7 @@ class OneChildLayoutDelegate {
BoxConstraints getConstraintsForChild(BoxConstraints constraints) => constraints;
/// Returns the position where the child should be placed given the size of this object and the size of the child.
Point getPositionForChild(Size size, Size childSize) => Point.origin;
Offset getPositionForChild(Size size, Size childSize) => Offset.zero;
/// Override this method to return true when the child needs to be laid out.
bool shouldRelayout(OneChildLayoutDelegate oldDelegate) => true;
......@@ -328,7 +328,7 @@ class RenderCustomOneChildLayoutBox extends RenderShiftedBox {
assert(childConstraints.isNormalized);
child.layout(childConstraints, parentUsesSize: !childConstraints.isTight);
final BoxParentData childParentData = child.parentData;
childParentData.position = delegate.getPositionForChild(size, childConstraints.isTight ? childConstraints.smallest : child.size);
childParentData.offset = delegate.getPositionForChild(size, childConstraints.isTight ? childConstraints.smallest : child.size);
}
}
}
......@@ -376,7 +376,7 @@ class RenderBaseline extends RenderShiftedBox {
size = constraints.constrain(child.size);
double delta = baseline - child.getDistanceToBaseline(baselineType);
final BoxParentData childParentData = child.parentData;
childParentData.position = new Point(0.0, delta);
childParentData.offset = new Offset(0.0, delta);
} else {
performResize();
}
......
......@@ -303,7 +303,7 @@ abstract class RenderStackBase extends RenderBox
hasNonPositionedChildren = true;
child.layout(constraints, parentUsesSize: true);
childParentData.position = Point.origin;
childParentData.offset = Offset.zero;
final Size childSize = child.size;
width = math.max(width, childSize.width);
......@@ -328,7 +328,7 @@ abstract class RenderStackBase extends RenderBox
final StackParentData childParentData = child.parentData;
if (!childParentData.isPositioned) {
childParentData.position = alignment.alongOffset(size - child.size).toPoint();
childParentData.offset = alignment.alongOffset(size - child.size);
} else {
BoxConstraints childConstraints = const BoxConstraints();
......@@ -362,7 +362,7 @@ abstract class RenderStackBase extends RenderBox
if (y < 0.0 || y + child.size.height > size.height)
_hasVisualOverflow = true;
childParentData.position = new Point(x, y);
childParentData.offset = new Offset(x, y);
}
assert(child.parentData == childParentData);
......@@ -475,8 +475,8 @@ class RenderIndexedStack extends RenderStackBase {
assert(position != null);
RenderBox child = _childAtIndex();
final StackParentData childParentData = child.parentData;
Point transformed = new Point(position.x - childParentData.position.x,
position.y - childParentData.position.y);
Point transformed = new Point(position.x - childParentData.offset.dx,
position.y - childParentData.offset.dy);
return child.hitTest(result, position: transformed);
}
......
......@@ -135,7 +135,7 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
child.layout(_getInnerConstraints(constraints), parentUsesSize: true);
size = constraints.constrain(child.size);
final BoxParentData childParentData = child.parentData;
childParentData.position = Point.origin;
childParentData.offset = Offset.zero;
} else {
performResize();
}
......
......@@ -87,7 +87,7 @@ void main() {
layout(paddedBox);
BoxParentData parentData = coloredBox.parentData;
expect(parentData.position.x, isNot(equals(0.0)));
expect(parentData.offset.dx, isNot(equals(0.0)));
paddedBox.child = null;
RenderConstrainedBox constraintedBox = new RenderConstrainedBox(
......@@ -96,6 +96,6 @@ void main() {
layout(constraintedBox);
parentData = coloredBox.parentData;
expect(parentData.position.x, equals(0.0));
expect(parentData.offset.dx, equals(0.0));
});
}
......@@ -27,10 +27,10 @@ class TestOneChildLayoutDelegate extends OneChildLayoutDelegate {
);
}
Point getPositionForChild(Size size, Size childSize) {
Offset getPositionForChild(Size size, Size childSize) {
sizeFromGetPositionForChild = size;
childSizeFromGetPositionForChild = childSize;
return Point.origin;
return Offset.zero;
}
bool shouldRelayoutCalled = false;
......
......@@ -28,14 +28,14 @@ void main() {
duration: const Duration(seconds: 10)
);
final List<Size> sizes = <Size>[];
final List<Point> positions = <Point>[];
final List<Offset> positions = <Offset>[];
final GlobalKey key = new GlobalKey();
void recordMetrics() {
RenderBox box = key.currentContext.findRenderObject();
BoxParentData boxParentData = box.parentData;
sizes.add(box.size);
positions.add(boxParentData.position);
positions.add(boxParentData.offset);
}
tester.pumpWidget(
......@@ -69,7 +69,7 @@ void main() {
recordMetrics();
expect(sizes, equals([const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0)]));
expect(positions, equals([const Point(10.0, 10.0), const Point(10.0, 10.0), const Point(17.0, 17.0), const Point(24.0, 24.0), const Point(45.0, 45.0), const Point(80.0, 80.0)]));
expect(positions, equals([const Offset(10.0, 10.0), const Offset(10.0, 10.0), const Offset(17.0, 17.0), const Offset(24.0, 24.0), const Offset(45.0, 45.0), const Offset(80.0, 80.0)]));
});
});
......
......@@ -123,11 +123,11 @@ void main() {
Element child0 = tester.findElementByKey(child0Key);
final StackParentData child0RenderObjectParentData = child0.renderObject.parentData;
expect(child0RenderObjectParentData.position, equals(const Point(0.0, 0.0)));
expect(child0RenderObjectParentData.offset, equals(const Offset(0.0, 0.0)));
Element child1 = tester.findElementByKey(child1Key);
final StackParentData child1RenderObjectParentData = child1.renderObject.parentData;
expect(child1RenderObjectParentData.position, equals(const Point(5.0, 5.0)));
expect(child1RenderObjectParentData.offset, equals(const Offset(5.0, 5.0)));
});
});
......@@ -233,8 +233,8 @@ void main() {
expect(parentData.left, equals(10.0));
expect(parentData.width, equals(11.0));
expect(parentData.height, equals(12.0));
expect(parentData.position.x, equals(10.0));
expect(parentData.position.y, equals(0.0));
expect(parentData.offset.dx, equals(10.0));
expect(parentData.offset.dy, equals(0.0));
expect(renderBox.size.width, equals(11.0));
expect(renderBox.size.height, equals(12.0));
......@@ -258,8 +258,8 @@ void main() {
expect(parentData.left, isNull);
expect(parentData.width, equals(11.0));
expect(parentData.height, equals(12.0));
expect(parentData.position.x, equals(779.0));
expect(parentData.position.y, equals(0.0));
expect(parentData.offset.dx, equals(779.0));
expect(parentData.offset.dy, equals(0.0));
expect(renderBox.size.width, equals(11.0));
expect(renderBox.size.height, equals(12.0));
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment