Commit 055c919f authored by Ian Hickson's avatar Ian Hickson

Allow children to overflow above a Baseline widget (#3573)

Turns out a common use for Baseline is making sure that the child's
baseline is higher than it otherwise would be, e.g. with the Material
font or other symbols.
parent 770e17cf
......@@ -824,9 +824,19 @@ class RenderCustomSingleChildLayoutBox extends RenderShiftedBox {
/// Shifts the child down such that the child's baseline (or the
/// bottom of the child, if the child has no baseline) is [baseline]
/// logical pixels below the top of this box, then sizes this box to
/// contain the child. If [baseline] is less than the distance from
/// the top of the child to the baseline of the child, then the child
/// is top-aligned instead.
/// contain the child.
///
/// If [baseline] is less than the distance from the top of the child
/// to the baseline of the child, then the child will overflow the top
/// of the box. This is typically not desireable, in particular, that
/// part of the child will not be found when doing hit tests, so the
/// user cannot interact with that part of the child.
///
/// This box will be sized so that its bottom is coincident with the
/// bottom of the child. This means if this box shifts the child down,
/// there will be space between the top of this box and the top of the
/// child, but there is never space between the bottom of the child
/// and the bottom of the box.
class RenderBaseline extends RenderShiftedBox {
/// Creates a [RenderBaseline] object.
///
......@@ -870,7 +880,7 @@ class RenderBaseline extends RenderShiftedBox {
if (child != null) {
child.layout(constraints.loosen(), parentUsesSize: true);
final double childBaseline = child.getDistanceToBaseline(baselineType);
final double actualBaseline = math.max(baseline, childBaseline);
final double actualBaseline = baseline;
final double top = actualBaseline - childBaseline;
final BoxParentData childParentData = child.parentData;
childParentData.offset = new Offset(0.0, top);
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:test/test.dart';
import 'rendering_tester.dart';
void main() {
test("RenderBaseline", () {
RenderBaseline parent;
RenderSizedBox child;
RenderBox root = new RenderPositionedBox(
alignment: FractionalOffset.topLeft,
child: parent = new RenderBaseline(
baseline: 0.0,
baselineType: TextBaseline.alphabetic,
child: child = new RenderSizedBox(new Size(100.0, 100.0))
)
);
BoxParentData childParentData = child.parentData;
layout(root, phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(-100.0));
expect(parent.size, equals(new Size(100.0, 0.0)));
parent.baseline = 25.0;
layout(root, phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(-75.0));
expect(parent.size, equals(new Size(100.0, 25.0)));
parent.baseline = 90.0;
layout(root, phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(-10.0));
expect(parent.size, equals(new Size(100.0, 90.0)));
parent.baseline = 100.0;
layout(root, phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(0.0));
expect(parent.size, equals(new Size(100.0, 100.0)));
parent.baseline = 110.0;
layout(root, phase: EnginePhase.layout);
expect(childParentData.offset.dx, equals(0.0));
expect(childParentData.offset.dy, equals(10.0));
expect(parent.size, equals(new Size(100.0, 110.0)));
});
}
......@@ -105,3 +105,15 @@ class TestCallbackPainter extends CustomPainter {
@override
bool shouldRepaint(TestCallbackPainter oldPainter) => true;
}
class RenderSizedBox extends RenderBox {
RenderSizedBox(this._size);
final Size _size;
@override
void performLayout() {
size = constraints.constrain(_size);
}
}
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