Skip to content

Commit 4d0d489

Browse files
SaadArdatiBirjuVachhani
authored andcommitted
ListTiles & Constraints #1
1 parent 5785899 commit 4d0d489

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+327
-136
lines changed

lib/src/api/mixins.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,11 +579,11 @@ mixin GeometryMixin on BaseNode {
579579
/// If an image is in the fills, allow shrink-wrapping up to to a fixed
580580
/// minimum.
581581
@override
582-
SizeC minimumInternalSize({
582+
BoxConstraintsModel internalConstraints({
583583
required SizeFit horizontalFit,
584584
required SizeFit verticalFit,
585585
}) {
586-
SizeC resultSize = super.minimumInternalSize(
586+
BoxConstraintsModel resultSize = super.internalConstraints(
587587
horizontalFit: horizontalFit,
588588
verticalFit: verticalFit,
589589
);
@@ -620,7 +620,12 @@ mixin GeometryMixin on BaseNode {
620620
}
621621
}
622622

623-
resultSize = resultSize | size;
623+
resultSize = resultSize.enforce(
624+
BoxConstraintsModel(
625+
minWidth: size.width,
626+
minHeight: size.height,
627+
),
628+
);
624629
}
625630
}
626631
return resultSize;

lib/src/api/models/box_constraints.dart

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@ class BoxConstraintsModel with EquatableMixin, SerializableMixin {
3535
this.maxHeight,
3636
});
3737

38+
/// Creates a new instance of this class with the same values as the given
39+
/// instance.
40+
/// This class uses nullable values for all properties, therefore a standard
41+
/// copyWith method is not possible.
42+
///
43+
/// For individual properties, use [updateMinWidth], [updateMaxWidth],
44+
/// [updateMinHeight], and [updateMaxHeight] instead.
45+
BoxConstraintsModel copy() => BoxConstraintsModel(
46+
minWidth: minWidth,
47+
maxWidth: maxWidth,
48+
minHeight: minHeight,
49+
maxHeight: maxHeight,
50+
);
51+
3852
/// Duplicates instance of this class with given [minWidth] value override.
3953
BoxConstraintsModel updateMinWidth(double? value) => BoxConstraintsModel(
4054
minWidth: value,
@@ -177,6 +191,66 @@ class BoxConstraintsModel with EquatableMixin, SerializableMixin {
177191
);
178192
}
179193

194+
/// Creates a union [BoxConstraintsModel] from the current
195+
/// [BoxConstraintsModel] and the provided [constraints].
196+
///
197+
/// The resulting [BoxConstraintsModel] will have the minimum with and height
198+
/// that's the biggest of the two, and the maximum width and height that's
199+
/// the smallest of the two.
200+
BoxConstraintsModel union(BoxConstraintsModel constraints) {
201+
return BoxConstraintsModel(
202+
minWidth: (minWidth == null)
203+
? constraints.minWidth
204+
: (constraints.minWidth == null)
205+
? minWidth
206+
: max(minWidth!, constraints.minWidth!),
207+
maxWidth: (maxWidth == null)
208+
? constraints.maxWidth
209+
: (constraints.maxWidth == null)
210+
? maxWidth
211+
: min(maxWidth!, constraints.maxWidth!),
212+
minHeight: (minHeight == null)
213+
? constraints.minHeight
214+
: (constraints.minHeight == null)
215+
? minHeight
216+
: max(minHeight!, constraints.minHeight!),
217+
maxHeight: (maxHeight == null)
218+
? constraints.maxHeight
219+
: (constraints.maxHeight == null)
220+
? maxHeight
221+
: min(maxHeight!, constraints.maxHeight!),
222+
);
223+
}
224+
225+
/// Similar to [union], but will only clamp the minimums and maximums
226+
/// if the passed [constraints] of the relevant parameter is not null.
227+
///
228+
/// So for example, if the passed [constraints] has a null min width,
229+
/// instead of returning a [BoxConstraintsModel] with a null min width,
230+
/// it just returns its own if available.
231+
/// Otherwise, it takes the biggest of the two min widths.
232+
///
233+
/// Another example, if the passed [constraints] has a null max width,
234+
/// instead of returning a [BoxConstraintsModel] with a null max width,
235+
/// it just returns its own if available.
236+
/// Otherwise, it takes the smallest of the two max widths.
237+
BoxConstraintsModel unionNonNull(BoxConstraintsModel constraints) {
238+
return BoxConstraintsModel(
239+
minWidth: constraints.minWidth == null
240+
? minWidth
241+
: max(minWidth ?? 0, constraints.minWidth!),
242+
maxWidth: constraints.maxWidth == null
243+
? maxWidth
244+
: min(maxWidth ?? double.infinity, constraints.maxWidth!),
245+
minHeight: constraints.minHeight == null
246+
? minHeight
247+
: max(minHeight ?? 0, constraints.minHeight!),
248+
maxHeight: constraints.maxHeight == null
249+
? maxHeight
250+
: min(maxHeight ?? double.infinity, constraints.maxHeight!),
251+
);
252+
}
253+
180254
/// Whether this constraints is the same as no constraints which is the
181255
/// default value.
182256
bool get isDefault =>

lib/src/api/models/size.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ class SizeC with SerializableMixin, EquatableMixin {
7171
/// Returns scaled down size by given [scale].
7272
SizeC operator /(double scale) => SizeC(width / scale, height / scale);
7373

74-
/// Max of two sizes operator.
75-
operator |(SizeC size) =>
76-
SizeC(max(width, size.width), max(height, size.height));
77-
7874
/// Adds given [size] to this size and returns the result.
7975
SizeC add(SizeC size) => SizeC(width + size.width, height + size.height);
8076

lib/src/api/node_processor.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ extension BaseNodeUpdateExtension on BaseNode {
100100
OuterNodeBox? outerBoxLocal,
101101
OuterNodeBox? outerBoxGlobal,
102102
NodeBox? middleBoxLocal,
103+
BoxConstraintsModel? constraints,
103104
int? rotationDegrees,
104105
bool resetRetainedBox = true,
105106
bool recursivelyCalculateChildrenGlobalBoxes = true,
@@ -114,6 +115,7 @@ extension BaseNodeUpdateExtension on BaseNode {
114115
outerBoxLocal: outerBoxLocal,
115116
outerBoxGlobal: outerBoxGlobal,
116117
basicBoxLocal: middleBoxLocal,
118+
constraints: constraints,
117119
rotationDegrees: rotationDegrees,
118120
resetRetainedBox: resetRetainedBox,
119121
recursivelyCalculateChildrenGlobalBoxes:
@@ -163,6 +165,41 @@ class NodeProcessor {
163165
NodeProcessor.getNode = getNode;
164166
}
165167

168+
/// There are normal [constraints] field, but they do not tell the full
169+
/// story of provided node's true constraints.
170+
///
171+
/// The [constraints] field is what is manually set by the user. However,
172+
/// we have additional constraints that are computed for different nodes.
173+
/// Material components may provide additional internal
174+
/// constraints. Images may provide their original sizes when shrink-wrapping,
175+
/// ListTiles provide a minimum size that the leading node must have, etc...
176+
///
177+
/// This function will take the [internalConstraints] and union them to the
178+
/// [constraints] field to get a reinforced set of constraints.
179+
static BoxConstraintsModel resolveConstraints(
180+
BaseNode node, {
181+
SizeFit? horizontalFit,
182+
SizeFit? verticalFit,
183+
}) {
184+
BoxConstraintsModel resolved = node.internalConstraints(
185+
horizontalFit: horizontalFit ?? node.horizontalFit,
186+
verticalFit: verticalFit ?? node.verticalFit,
187+
);
188+
189+
if (node.id != kRootNode) {
190+
final BaseNode parent = getNode(node.parentID);
191+
final BoxConstraintsModel? relegatedConstraints =
192+
parent.relegatedConstraintsToChildren(node);
193+
if (relegatedConstraints != null) {
194+
final parentResolved =
195+
relegatedConstraints.unionNonNull(resolveConstraints(parent));
196+
resolved = resolved.unionNonNull(parentResolved);
197+
}
198+
}
199+
200+
return node.constraints.unionNonNull(resolved);
201+
}
202+
166203
/// Update the global rotation for given [node] with [newRotationDegrees].
167204
static void updateGlobalRotation({
168205
required BaseNode node,
@@ -219,6 +256,7 @@ class NodeProcessor {
219256
OuterNodeBox? outerBoxLocal,
220257
OuterNodeBox? outerBoxGlobal,
221258
NodeBox? basicBoxLocal,
259+
BoxConstraintsModel? constraints,
222260
int? rotationDegrees,
223261
bool resetRetainedBox = true,
224262
bool recursivelyCalculateChildrenGlobalBoxes = true,
@@ -233,13 +271,18 @@ class NodeProcessor {
233271
outerBoxGlobal != null && globalParentBoundingBoxPos != null;
234272
final bool localOuterBoxChanged = outerBoxLocal != null;
235273
final bool localMiddleBoxChanged = basicBoxLocal != null;
274+
final bool constraintsChanged = constraints != null;
236275

237276
if (alignmentChanged) node._alignment = alignment;
238277
if (marginChanged) node._margin = margin;
239278
if (paddingChanged) node._padding = padding;
240279
if (localMiddleBoxChanged) node._basicBoxLocal = basicBoxLocal;
241280
if (localOuterBoxChanged) node._outerBoxLocal = outerBoxLocal;
242281
if (outerBoxGlobal != null) node._outerBoxGlobal = outerBoxGlobal;
282+
if (constraintsChanged) {
283+
node._constraints = constraints;
284+
}
285+
node._resolvedConstraints = resolveConstraints(node);
243286

244287
node.updateNodeRotation(rotationDegrees ?? node.rotationDegrees);
245288

lib/src/api/nodes/accordion_node.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/src/api/nodes/app_bar_node.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class AppBarNode extends SceneNode
6161
Map toJson() => _$AppBarNodeToJson(this);
6262

6363
@override
64-
SizeC minimumInternalSize({
64+
BoxConstraintsModel internalConstraints({
6565
required SizeFit horizontalFit,
6666
required SizeFit verticalFit,
6767
}) {
@@ -78,7 +78,12 @@ class AppBarNode extends SceneNode
7878
minHeight = properties.titleStyle.fontSize + 16;
7979
}
8080
minHeight = min(56, minHeight);
81-
return SizeC(0, minHeight);
81+
return super
82+
.internalConstraints(
83+
horizontalFit: horizontalFit, verticalFit: verticalFit)
84+
.unionNonNull(
85+
BoxConstraintsModel(minHeight: minHeight),
86+
);
8287
}
8388
}
8489

lib/src/api/nodes/app_bar_node.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/src/api/nodes/auto_placeholder_node.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)