@@ -10,17 +10,10 @@ import 'box.dart';
1010import 'debug.dart' ;
1111import 'debug_overflow_indicator.dart' ;
1212import 'layer.dart' ;
13+ import 'layout_helper.dart' ;
1314import 'object.dart' ;
1415import 'stack.dart' show RelativeRect;
1516
16- /// Signature for a function that transforms a [BoxConstraints] to another
17- /// [BoxConstraints] .
18- ///
19- /// Used by [RenderConstraintsTransformBox] and [ConstraintsTransformBox] .
20- /// Typically the caller requires the returned [BoxConstraints] to be
21- /// [BoxConstraints.isNormalized] .
22- typedef BoxConstraintsTransform = BoxConstraints Function (BoxConstraints );
23-
2417/// Abstract class for one-child-layout render boxes that provide control over
2518/// the child's position.
2619abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixin <RenderBox > {
@@ -635,83 +628,71 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
635628 }
636629}
637630
638- /// A [RenderBox] that applies an arbitrary transform to its [constraints]
639- /// before sizing its child using the new constraints, treating any overflow as
640- /// error.
631+ /// Renders a box, imposing no constraints on its child, allowing the child to
632+ /// render at its "natural" size.
641633///
642- /// This [RenderBox] sizes its child using a [BoxConstraints] created by
643- /// applying [constraintsTransform] to this [RenderBox] 's own [constraints] .
644- /// This box will then attempt to adopt the same size, within the limits of its
645- /// own constraints. If it ends up with a different size, it will align the
646- /// child based on [alignment] . If the box cannot expand enough to accommodate
647- /// the entire child, the child will be clipped if [clipBehavior] is not
648- /// [Clip.none] .
634+ /// This allows a child to render at the size it would render if it were alone
635+ /// on an infinite canvas with no constraints. This box will then attempt to
636+ /// adopt the same size, within the limits of its own constraints. If it ends
637+ /// up with a different size, it will align the child based on [alignment] .
638+ /// If the box cannot expand enough to accommodate the entire child, the
639+ /// child will be clipped.
649640///
650641/// In debug mode, if the child overflows the box, a warning will be printed on
651642/// the console, and black and yellow striped areas will appear where the
652643/// overflow occurs.
653644///
654- /// When [child] is null, this [RenderBox] takes the smallest possible size and
655- /// never overflows.
656- ///
657- /// This [RenderBox] can be used to ensure some of [child] 's natrual dimensions
658- /// are honored, and get an early warning during development otherwise. For
659- /// instance, if [child] requires a minimum height to fully display its content,
660- /// [constraintsTransform] can be set to a function that removes the `maxHeight`
661- /// constraint from the incoming [BoxConstraints] , so that if the parent
662- /// [RenderObject] fails to provide enough vertical space, a warning will be
663- /// displayed in debug mode, while still allowing [child] to grow vertically.
664- ///
665645/// See also:
666646///
667- /// * [ConstraintsTransformBox] , the widget that makes use of this
668- /// [RenderObject] and exposes the same functionality.
669647/// * [RenderConstrainedBox] , which renders a box which imposes constraints
670648/// on its child.
671649/// * [RenderConstrainedOverflowBox] , which renders a box that imposes different
672650/// constraints on its child than it gets from its parent, possibly allowing
673651/// the child to overflow the parent.
674- /// * [RenderUnconstrainedBox] which allows its children to render themselves
675- /// unconstrained, expands to fit them, and considers overflow to be an error.
676- class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugOverflowIndicatorMixin {
677- /// Creates a [RenderBox] that sizes itself to the child and modifies the
678- /// [constraints] before passing it down to that child.
652+ /// * [RenderSizedOverflowBox] , a render object that is a specific size but
653+ /// passes its original constraints through to its child, which it allows to
654+ /// overflow.
655+ class RenderUnconstrainedBox extends RenderAligningShiftedBox with DebugOverflowIndicatorMixin {
656+ /// Create a render object that sizes itself to the child but does not
657+ /// pass the [constraints] down to that child.
679658 ///
680- /// The [alignment] and [clipBehavior] must not be null.
681- RenderConstraintsTransformBox ({
659+ /// The [alignment] must not be null.
660+ RenderUnconstrainedBox ({
682661 required AlignmentGeometry alignment,
683662 required TextDirection ? textDirection,
684- required BoxConstraintsTransform constraintsTransform ,
663+ Axis ? constrainedAxis ,
685664 RenderBox ? child,
686665 Clip clipBehavior = Clip .none,
687666 }) : assert (alignment != null ),
688667 assert (clipBehavior != null ),
689- assert (constraintsTransform != null ),
690- _constraintsTransform = constraintsTransform,
668+ _constrainedAxis = constrainedAxis,
691669 _clipBehavior = clipBehavior,
692670 super .mixin (alignment, textDirection, child);
693671
694- /// {@macro flutter.widgets.constraintsTransform}
695- BoxConstraintsTransform get constraintsTransform => _constraintsTransform;
696- BoxConstraintsTransform _constraintsTransform;
697- set constraintsTransform (BoxConstraintsTransform value) {
698- if (_constraintsTransform == value)
672+ /// The axis to retain constraints on, if any.
673+ ///
674+ /// If not set, or set to null (the default), neither axis will retain its
675+ /// constraints. If set to [Axis.vertical] , then vertical constraints will
676+ /// be retained, and if set to [Axis.horizontal] , then horizontal constraints
677+ /// will be retained.
678+ Axis ? get constrainedAxis => _constrainedAxis;
679+ Axis ? _constrainedAxis;
680+ set constrainedAxis (Axis ? value) {
681+ if (_constrainedAxis == value)
699682 return ;
700- _constraintsTransform = value;
701- // The RenderObject only needs layout if the new transform maps the current
702- // `constraints` to a different value, or the render object has never been
703- // laid out before.
704- final bool needsLayout = _childConstraints == null
705- || _childConstraints != value (constraints);
706- if (needsLayout)
707- markNeedsLayout ();
683+ _constrainedAxis = value;
684+ markNeedsLayout ();
708685 }
709686
687+ Rect _overflowContainerRect = Rect .zero;
688+ Rect _overflowChildRect = Rect .zero;
689+ bool _isOverflowing = false ;
690+
710691 /// {@macro flutter.material.Material.clipBehavior}
711692 ///
712693 /// Defaults to [Clip.none] , and must not be null.
713694 Clip get clipBehavior => _clipBehavior;
714- Clip _clipBehavior;
695+ Clip _clipBehavior = Clip .none ;
715696 set clipBehavior (Clip value) {
716697 assert (value != null );
717698 if (value != _clipBehavior) {
@@ -721,33 +702,49 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
721702 }
722703 }
723704
705+ Size _calculateSizeWithChild ({required BoxConstraints constraints, required ChildLayouter layoutChild}) {
706+ assert (child != null );
707+ // Let the child lay itself out at it's "natural" size, but if
708+ // constrainedAxis is non-null, keep any constraints on that axis.
709+ final BoxConstraints childConstraints;
710+ if (constrainedAxis != null ) {
711+ switch (constrainedAxis! ) {
712+ case Axis .horizontal:
713+ childConstraints = BoxConstraints (maxWidth: constraints.maxWidth, minWidth: constraints.minWidth);
714+ break ;
715+ case Axis .vertical:
716+ childConstraints = BoxConstraints (maxHeight: constraints.maxHeight, minHeight: constraints.minHeight);
717+ break ;
718+ }
719+ } else {
720+ childConstraints = const BoxConstraints ();
721+ }
722+ return constraints.constrain (layoutChild (child! , childConstraints));
723+ }
724+
724725 @override
725726 Size computeDryLayout (BoxConstraints constraints) {
726- final Size ? childSize = child? .getDryLayout (constraintsTransform (constraints));
727- return childSize == null ? constraints.smallest : constraints.constrain (childSize);
727+ if (child == null ) {
728+ return constraints.smallest;
729+ }
730+ return _calculateSizeWithChild (
731+ constraints: constraints,
732+ layoutChild: ChildLayoutHelper .dryLayoutChild,
733+ );
728734 }
729735
730- Rect _overflowContainerRect = Rect .zero;
731- Rect _overflowChildRect = Rect .zero;
732- bool _isOverflowing = false ;
733-
734- BoxConstraints ? _childConstraints;
735-
736736 @override
737737 void performLayout () {
738738 final BoxConstraints constraints = this .constraints;
739- final RenderBox ? child = this .child;
740739 if (child != null ) {
741- final BoxConstraints childConstraints = constraintsTransform (constraints);
742- assert (childConstraints != null );
743- assert (childConstraints.isNormalized, '$childConstraints is not normalized' );
744- _childConstraints = childConstraints;
745- child.layout (childConstraints, parentUsesSize: true );
746- size = constraints.constrain (child.size);
740+ size = _calculateSizeWithChild (
741+ constraints: constraints,
742+ layoutChild: ChildLayoutHelper .layoutChild,
743+ );
747744 alignChild ();
748- final BoxParentData childParentData = child.parentData! as BoxParentData ;
745+ final BoxParentData childParentData = child! .parentData! as BoxParentData ;
749746 _overflowContainerRect = Offset .zero & size;
750- _overflowChildRect = childParentData.offset & child.size;
747+ _overflowChildRect = childParentData.offset & child! .size;
751748 } else {
752749 size = constraints.smallest;
753750 _overflowContainerRect = Rect .zero;
@@ -800,94 +797,6 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
800797 }
801798}
802799
803- /// Renders a box, imposing no constraints on its child, allowing the child to
804- /// render at its "natural" size.
805- ///
806- /// The class is deprecated, use [RenderConstraintsTransformBox] instead.
807- ///
808- /// This allows a child to render at the size it would render if it were alone
809- /// on an infinite canvas with no constraints. This box will then attempt to
810- /// adopt the same size, within the limits of its own constraints. If it ends
811- /// up with a different size, it will align the child based on [alignment] .
812- /// If the box cannot expand enough to accommodate the entire child, the
813- /// child will be clipped.
814- ///
815- /// In debug mode, if the child overflows the box, a warning will be printed on
816- /// the console, and black and yellow striped areas will appear where the
817- /// overflow occurs.
818- ///
819- /// See also:
820- ///
821- /// * [RenderConstrainedBox] , which renders a box which imposes constraints
822- /// on its child.
823- /// * [RenderConstrainedOverflowBox] , which renders a box that imposes different
824- /// constraints on its child than it gets from its parent, possibly allowing
825- /// the child to overflow the parent.
826- /// * [RenderSizedOverflowBox] , a render object that is a specific size but
827- /// passes its original constraints through to its child, which it allows to
828- /// overflow.
829- ///
830- @Deprecated (
831- 'Use RenderConstraintsTransformBox instead. '
832- 'This feature was deprecated after v2.1.0-11.0.pre.'
833- )
834- class RenderUnconstrainedBox extends RenderConstraintsTransformBox {
835- /// Create a render object that sizes itself to the child but does not
836- /// pass the [constraints] down to that child.
837- ///
838- /// The [alignment] and [clipBehavior] must not be null.
839- @Deprecated (
840- 'Use RenderConstraintsTransformBox instead. '
841- 'This feature was deprecated after v2.1.0-11.0.pre.'
842- )
843- RenderUnconstrainedBox ({
844- required AlignmentGeometry alignment,
845- required TextDirection ? textDirection,
846- Axis ? constrainedAxis,
847- RenderBox ? child,
848- Clip clipBehavior = Clip .none,
849- }) : assert (alignment != null ),
850- assert (clipBehavior != null ),
851- _constrainedAxis = constrainedAxis,
852- super (
853- alignment: alignment,
854- textDirection: textDirection,
855- child: child,
856- clipBehavior: clipBehavior,
857- constraintsTransform: _convertAxis (constrainedAxis),
858- );
859-
860- /// The axis to retain constraints on, if any.
861- ///
862- /// If not set, or set to null (the default), neither axis will retain its
863- /// constraints. If set to [Axis.vertical] , then vertical constraints will
864- /// be retained, and if set to [Axis.horizontal] , then horizontal constraints
865- /// will be retained.
866- Axis ? get constrainedAxis => _constrainedAxis;
867- Axis ? _constrainedAxis;
868- set constrainedAxis (Axis ? value) {
869- if (_constrainedAxis == value)
870- return ;
871- _constrainedAxis = value;
872- constraintsTransform = _convertAxis (constrainedAxis);
873- }
874-
875- static BoxConstraints _unconstrained (BoxConstraints constraints) => const BoxConstraints ();
876- static BoxConstraints _widthConstrained (BoxConstraints constraints) => constraints.widthConstraints ();
877- static BoxConstraints _heightConstrained (BoxConstraints constraints) => constraints.heightConstraints ();
878- static BoxConstraintsTransform _convertAxis (Axis ? constrainedAxis) {
879- if (constrainedAxis == null ) {
880- return _unconstrained;
881- }
882- switch (constrainedAxis) {
883- case Axis .horizontal:
884- return _widthConstrained;
885- case Axis .vertical:
886- return _heightConstrained;
887- }
888- }
889- }
890-
891800/// A render object that is a specific size but passes its original constraints
892801/// through to its child, which it allows to overflow.
893802///
0 commit comments