mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
_RenderDecorator.computeDryBaseline
(#146365)
Depends on https://github.com/flutter/flutter/pull/146363 No test because the consistency of the `computeDryBaseline` implementations is checked at paint time.
This commit is contained in:
parent
21da3a8063
commit
f76eda1e7f
@ -697,12 +697,14 @@ class _Decoration {
|
||||
// all of the renderer children of a _RenderDecoration.
|
||||
class _RenderDecorationLayout {
|
||||
const _RenderDecorationLayout({
|
||||
required this.inputConstraints,
|
||||
required this.baseline,
|
||||
required this.containerHeight,
|
||||
required this.subtextSize,
|
||||
required this.size,
|
||||
});
|
||||
|
||||
final BoxConstraints inputConstraints;
|
||||
final double baseline;
|
||||
final double containerHeight;
|
||||
final _SubtextSize? subtextSize;
|
||||
@ -903,6 +905,10 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
static double _getBaseline(RenderBox box, BoxConstraints boxConstraints) {
|
||||
return ChildLayoutHelper.getBaseline(box, boxConstraints, TextBaseline.alphabetic) ?? box.size.height;
|
||||
}
|
||||
static double _getDryBaseline(RenderBox box, BoxConstraints boxConstraints) {
|
||||
return ChildLayoutHelper.getDryBaseline(box, boxConstraints, TextBaseline.alphabetic)
|
||||
?? ChildLayoutHelper.dryLayoutChild(box, boxConstraints).height;
|
||||
}
|
||||
|
||||
static BoxParentData _boxParentData(RenderBox box) => box.parentData! as BoxParentData;
|
||||
|
||||
@ -943,7 +949,11 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
// Returns a value used by performLayout to position all of the renderers.
|
||||
// This method applies layout to all of the renderers except the container.
|
||||
// For convenience, the container is laid out in performLayout().
|
||||
_RenderDecorationLayout _layout(BoxConstraints constraints) {
|
||||
_RenderDecorationLayout _layout(
|
||||
BoxConstraints constraints, {
|
||||
required ChildLayouter layoutChild,
|
||||
required _ChildBaselineGetter getBaseline,
|
||||
}) {
|
||||
assert(
|
||||
constraints.maxWidth < double.infinity,
|
||||
'An InputDecorator, which is typically created by a TextField, cannot '
|
||||
@ -958,7 +968,8 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
final BoxConstraints boxConstraints = constraints.loosen();
|
||||
|
||||
// Layout all the widgets used by InputDecorator
|
||||
final double iconWidth = (icon?..layout(boxConstraints, parentUsesSize: true))?.size.width ?? 0.0;
|
||||
final RenderBox? icon = this.icon;
|
||||
final double iconWidth = icon == null ? 0.0 : layoutChild(icon, boxConstraints).width;
|
||||
final BoxConstraints containerConstraints = boxConstraints.deflate(EdgeInsets.only(left: iconWidth));
|
||||
final BoxConstraints contentConstraints = containerConstraints.deflate(EdgeInsets.only(left: contentPadding.horizontal));
|
||||
|
||||
@ -966,26 +977,27 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
// occupied by the icon and counter.
|
||||
final _SubtextSize? subtextSize = _computeSubtextSizes(
|
||||
constraints: contentConstraints,
|
||||
layoutChild: ChildLayoutHelper.layoutChild,
|
||||
getBaseline: _getBaseline,
|
||||
layoutChild: layoutChild,
|
||||
getBaseline: getBaseline,
|
||||
);
|
||||
|
||||
final RenderBox? prefixIcon = this.prefixIcon;
|
||||
final RenderBox? suffixIcon = this.suffixIcon;
|
||||
final Size prefixIconSize = (prefixIcon?..layout(containerConstraints, parentUsesSize: true))?.size ?? Size.zero;
|
||||
final Size suffixIconSize = (suffixIcon?..layout(containerConstraints, parentUsesSize: true))?.size ?? Size.zero;
|
||||
final Size prefixIconSize = prefixIcon == null ? Size.zero : layoutChild(prefixIcon, containerConstraints);
|
||||
final Size suffixIconSize = suffixIcon == null ? Size.zero : layoutChild(suffixIcon, containerConstraints);
|
||||
final RenderBox? prefix = this.prefix;
|
||||
final RenderBox? suffix = this.suffix;
|
||||
final Size prefixSize = (prefix?..layout(contentConstraints, parentUsesSize: true))?.size ?? Size.zero;
|
||||
final Size suffixSize = (suffix?..layout(contentConstraints, parentUsesSize: true))?.size ?? Size.zero;
|
||||
final Size prefixSize = prefix == null ? Size.zero : layoutChild(prefix, contentConstraints);
|
||||
final Size suffixSize = suffix == null ? Size.zero : layoutChild(suffix, contentConstraints);
|
||||
|
||||
final EdgeInsetsDirectional accessoryHorizontalInsets = EdgeInsetsDirectional.only(
|
||||
start: iconWidth + prefixSize.width + (prefixIcon == null ? contentPadding.start : prefixIcon.size.width),
|
||||
end: suffixSize.width + (suffixIcon == null ? contentPadding.end : suffixIcon.size.width),
|
||||
start: iconWidth + prefixSize.width + (prefixIcon == null ? contentPadding.start : prefixIconSize.width),
|
||||
end: suffixSize.width + (suffixIcon == null ? contentPadding.end : suffixIconSize.width),
|
||||
);
|
||||
|
||||
final double inputWidth = math.max(0.0, constraints.maxWidth - accessoryHorizontalInsets.horizontal);
|
||||
final RenderBox? label = this.label;
|
||||
final double topHeight;
|
||||
if (label != null) {
|
||||
final double suffixIconSpace = decoration.border.isOutline
|
||||
? lerpDouble(suffixIconSize.width, 0.0, decoration.floatingLabelProgress)!
|
||||
@ -995,18 +1007,21 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
constraints.maxWidth - (iconWidth + contentPadding.horizontal + prefixIconSize.width + suffixIconSpace),
|
||||
);
|
||||
|
||||
// Increase the available width for the label when it is scaled down.
|
||||
final double invertedLabelScale = lerpDouble(1.00, 1 / _kFinalLabelScale, decoration.floatingLabelProgress)!;
|
||||
// Increase the available width for the label when it is scaled down.
|
||||
final double invertedLabelScale = lerpDouble(1.00, 1 / _kFinalLabelScale, decoration.floatingLabelProgress)!;
|
||||
final BoxConstraints labelConstraints = boxConstraints.copyWith(maxWidth: labelWidth * invertedLabelScale);
|
||||
label.layout(labelConstraints, parentUsesSize: true);
|
||||
layoutChild(label, labelConstraints);
|
||||
|
||||
final double labelHeight = decoration.floatingLabelHeight;
|
||||
topHeight = decoration.border.isOutline
|
||||
? math.max(labelHeight - getBaseline(label, labelConstraints), 0.0)
|
||||
: labelHeight;
|
||||
} else {
|
||||
topHeight = 0.0;
|
||||
}
|
||||
|
||||
// The height of the input needs to accommodate label above and counter and
|
||||
// helperError below, when they exist.
|
||||
final double labelHeight = label == null ? 0 : decoration.floatingLabelHeight;
|
||||
final double topHeight = decoration.border.isOutline
|
||||
? math.max(labelHeight - (label?.getDistanceToBaseline(TextBaseline.alphabetic) ?? 0.0), 0.0)
|
||||
: labelHeight;
|
||||
final double bottomHeight = subtextSize?.bottomHeight ?? 0.0;
|
||||
final Offset densityOffset = decoration.visualDensity.baseSizeAdjustment;
|
||||
final BoxConstraints inputConstraints = boxConstraints
|
||||
@ -1015,17 +1030,18 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
|
||||
final RenderBox? input = this.input;
|
||||
final RenderBox? hint = this.hint;
|
||||
final Size inputSize = (input?..layout(inputConstraints, parentUsesSize: true))?.size ?? Size.zero;
|
||||
final Size hintSize = (hint?..layout(boxConstraints.tighten(width: inputWidth), parentUsesSize: true))?.size ?? Size.zero;
|
||||
final double inputBaseline = input == null ? 0.0 : _getBaseline(input, inputConstraints);
|
||||
final double hintBaseline = hint == null ? 0.0 : _getBaseline(hint, boxConstraints.tighten(width: inputWidth));
|
||||
final Size inputSize = input == null ? Size.zero : layoutChild(input, inputConstraints);
|
||||
final Size hintSize = hint == null ? Size.zero : layoutChild(hint, boxConstraints.tighten(width: inputWidth));
|
||||
final double inputBaseline = input == null ? 0.0 : getBaseline(input, inputConstraints);
|
||||
final double hintBaseline = hint == null ? 0.0 : getBaseline(hint, boxConstraints.tighten(width: inputWidth));
|
||||
|
||||
// The field can be occupied by a hint or by the input itself
|
||||
final double inputHeight = math.max(hintSize.height, inputSize.height);
|
||||
final double inputInternalBaseline = math.max(inputBaseline, hintBaseline);
|
||||
|
||||
final double prefixBaseline = prefix == null ? 0.0 : _getBaseline(prefix, contentConstraints);
|
||||
final double suffixBaseline = suffix == null ? 0.0 : _getBaseline(suffix, contentConstraints);
|
||||
final double prefixBaseline = prefix == null ? 0.0 : getBaseline(prefix, contentConstraints);
|
||||
final double suffixBaseline = suffix == null ? 0.0 : getBaseline(suffix, contentConstraints);
|
||||
|
||||
// Calculate the amount that prefix/suffix affects height above and below
|
||||
// the input.
|
||||
final double fixHeight = math.max(prefixBaseline, suffixBaseline);
|
||||
@ -1117,6 +1133,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
}
|
||||
|
||||
return _RenderDecorationLayout(
|
||||
inputConstraints: inputConstraints,
|
||||
containerHeight: containerHeight,
|
||||
baseline: baseline,
|
||||
subtextSize: subtextSize,
|
||||
@ -1237,27 +1254,51 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
@override
|
||||
double computeDistanceToActualBaseline(TextBaseline baseline) {
|
||||
final RenderBox? input = this.input;
|
||||
return input == null
|
||||
? 0.0
|
||||
: _boxParentData(input).offset.dy + (input.getDistanceToActualBaseline(baseline) ?? 0.0);
|
||||
if (input == null) {
|
||||
return 0.0;
|
||||
}
|
||||
return _boxParentData(input).offset.dy + (input.getDistanceToActualBaseline(baseline) ?? input.size.height);
|
||||
}
|
||||
|
||||
// Records where the label was painted.
|
||||
Matrix4? _labelTransform;
|
||||
|
||||
@override
|
||||
double? computeDryBaseline(covariant BoxConstraints constraints, TextBaseline baseline) {
|
||||
final RenderBox? input = this.input;
|
||||
if (input == null) {
|
||||
return 0.0;
|
||||
}
|
||||
final _RenderDecorationLayout layout = _layout(
|
||||
constraints,
|
||||
layoutChild: ChildLayoutHelper.dryLayoutChild,
|
||||
getBaseline: _getDryBaseline,
|
||||
);
|
||||
return switch (baseline) {
|
||||
TextBaseline.alphabetic => 0.0,
|
||||
TextBaseline.ideographic => (input.getDryBaseline(layout.inputConstraints, TextBaseline.ideographic) ?? input.getDryLayout(layout.inputConstraints).height) - (input.getDryBaseline(layout.inputConstraints, TextBaseline.alphabetic) ?? input.getDryLayout(layout.inputConstraints).height),
|
||||
} + layout.baseline;
|
||||
}
|
||||
|
||||
@override
|
||||
Size computeDryLayout(BoxConstraints constraints) {
|
||||
assert(debugCannotComputeDryLayout(
|
||||
reason: 'Layout requires baseline metrics, which are only available after a full layout.',
|
||||
));
|
||||
return Size.zero;
|
||||
final _RenderDecorationLayout layout = _layout(
|
||||
constraints,
|
||||
layoutChild: ChildLayoutHelper.dryLayoutChild,
|
||||
getBaseline: _getDryBaseline,
|
||||
);
|
||||
return constraints.constrain(layout.size);
|
||||
}
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
final BoxConstraints constraints = this.constraints;
|
||||
_labelTransform = null;
|
||||
final _RenderDecorationLayout layout = _layout(constraints);
|
||||
final _RenderDecorationLayout layout = _layout(
|
||||
constraints,
|
||||
layoutChild: ChildLayoutHelper.layoutChild,
|
||||
getBaseline: _getBaseline,
|
||||
);
|
||||
size = constraints.constrain(layout.size);
|
||||
assert(size.width == constraints.constrainWidth(layout.size.width));
|
||||
assert(size.height == constraints.constrainHeight(layout.size.height));
|
||||
|
Loading…
Reference in New Issue
Block a user