Skip to content

Commit 3879e42

Browse files
committed
TMP
1 parent f672118 commit 3879e42

10 files changed

+69
-156
lines changed

masonry/src/box_constraints.rs

+24-87
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ use vello::kurbo::Size;
88
/// The layout strategy for Masonry is strongly inspired by Flutter,
99
/// and this struct is similar to the [Flutter BoxConstraints] class.
1010
///
11-
/// At the moment, it represents simply a minimum and maximum size.
11+
/// At the moment, it represents only a maximum size.
1212
/// A widget's [`layout`] method should choose an appropriate size that
13-
/// meets these constraints.
13+
/// meets that constraint.
14+
/// The algorithm is supposed to use a minimum constraint, but we're phasing that out.
1415
///
1516
/// Further, a container widget should compute appropriate constraints
1617
/// for each of its child widgets, and pass those down when recursing.
@@ -23,7 +24,6 @@ use vello::kurbo::Size;
2324
/// [rounded away from zero]: Size::expand
2425
#[derive(Clone, Copy, Debug, PartialEq)]
2526
pub struct BoxConstraints {
26-
min: Size,
2727
max: Size,
2828
}
2929

@@ -32,7 +32,6 @@ impl BoxConstraints {
3232
///
3333
/// Can be satisfied by any nonnegative size.
3434
pub const UNBOUNDED: BoxConstraints = BoxConstraints {
35-
min: Size::ZERO,
3635
max: Size::new(f64::INFINITY, f64::INFINITY),
3736
};
3837

@@ -44,37 +43,8 @@ impl BoxConstraints {
4443
/// so that the layout is aligned to integers.
4544
///
4645
/// [rounded away from zero]: Size::expand
47-
pub fn new(min: Size, max: Size) -> BoxConstraints {
48-
BoxConstraints {
49-
min: min.expand(),
50-
max: max.expand(),
51-
}
52-
}
53-
54-
/// Create a "tight" box constraints object.
55-
///
56-
/// A "tight" constraint can only be satisfied by a single size.
57-
///
58-
/// The given size is also [rounded away from zero],
59-
/// so that the layout is aligned to integers.
60-
///
61-
/// [rounded away from zero]: Size::expand
62-
pub fn tight(size: Size) -> BoxConstraints {
63-
let size = size.expand();
64-
BoxConstraints {
65-
min: size,
66-
max: size,
67-
}
68-
}
69-
70-
/// Create a "loose" version of the constraints.
71-
///
72-
/// Make a version with zero minimum size, but the same maximum size.
73-
pub fn loosen(&self) -> BoxConstraints {
74-
BoxConstraints {
75-
min: Size::ZERO,
76-
max: self.max,
77-
}
46+
pub fn new(max: Size) -> BoxConstraints {
47+
BoxConstraints { max: max.expand() }
7848
}
7949

8050
/// Clamp a given size so that it fits within the constraints.
@@ -84,19 +54,14 @@ impl BoxConstraints {
8454
///
8555
/// [rounded away from zero]: Size::expand
8656
pub fn constrain(&self, size: impl Into<Size>) -> Size {
87-
size.into().expand().clamp(self.min, self.max)
57+
size.into().expand().clamp(Size::ZERO, self.max)
8858
}
8959

9060
/// Returns the max size of these constraints.
9161
pub fn max(&self) -> Size {
9262
self.max
9363
}
9464

95-
/// Returns the min size of these constraints.
96-
pub fn min(&self) -> Size {
97-
self.min
98-
}
99-
10065
/// Whether there is an upper bound on the width.
10166
pub fn is_width_bounded(&self) -> bool {
10267
self.max.width.is_finite()
@@ -115,62 +80,38 @@ impl BoxConstraints {
11580
return;
11681
}
11782

118-
if self.min.width.is_nan() {
119-
debug_panic!("Minimum width constraint passed to {name} is NaN");
120-
}
121-
if self.min.height.is_nan() {
122-
debug_panic!("Minimum height constraint passed to {name} is NaN");
123-
}
12483
if self.max.width.is_nan() {
12584
debug_panic!("Maximum width constraint passed to {name} is NaN");
12685
}
12786
if self.max.height.is_nan() {
12887
debug_panic!("Maximum height constraint passed to {name} is NaN");
12988
}
13089

131-
if self.min.width.is_infinite() {
132-
debug_panic!("Infinite minimum width constraint passed to {name}");
133-
}
134-
if self.min.height.is_infinite() {
135-
debug_panic!("Infinite minimum height constraint passed to {name}");
136-
}
137-
138-
if !(0.0 <= self.min.width
139-
&& self.min.width <= self.max.width
140-
&& 0.0 <= self.min.height
141-
&& self.min.height <= self.max.height
142-
&& self.min.expand() == self.min
143-
&& self.max.expand() == self.max)
144-
{
90+
if !(0.0 <= self.max.width && 0.0 <= self.max.height && self.max.expand() == self.max) {
14591
debug_panic!("Bad BoxConstraints passed to {name}: {self:?}",);
14692
}
14793
}
14894

149-
/// Shrink min and max constraints by size
95+
/// Shrink max constraint by size
15096
///
15197
/// The given size is also [rounded away from zero],
15298
/// so that the layout is aligned to integers.
15399
///
154100
/// [rounded away from zero]: Size::expand
155101
pub fn shrink(&self, diff: impl Into<Size>) -> BoxConstraints {
156102
let diff = diff.into().expand();
157-
let min = Size::new(
158-
(self.min().width - diff.width).max(0.),
159-
(self.min().height - diff.height).max(0.),
160-
);
161103
let max = Size::new(
162104
(self.max().width - diff.width).max(0.),
163105
(self.max().height - diff.height).max(0.),
164106
);
165107

166-
BoxConstraints::new(min, max)
108+
BoxConstraints::new(max)
167109
}
168110

169111
/// Test whether these constraints contain the given `Size`.
170112
pub fn contains(&self, size: impl Into<Size>) -> bool {
171113
let size = size.into();
172-
(self.min.width <= size.width && size.width <= self.max.width)
173-
&& (self.min.height <= size.height && size.height <= self.max.height)
114+
(size.width <= self.max.width) && (size.height <= self.max.height)
174115
}
175116

176117
/// Find the `Size` within these `BoxConstraint`s that minimises the difference between the
@@ -203,9 +144,9 @@ impl BoxConstraints {
203144

204145
// Then we check if any `Size`s with our desired aspect ratio are inside the constraints.
205146
// TODO this currently outputs garbage when things are < 0 - See https://github.com/linebender/xilem/issues/377
206-
let min_w_min_h = self.min.height / self.min.width;
207-
let max_w_min_h = self.min.height / self.max.width;
208-
let min_w_max_h = self.max.height / self.min.width;
147+
let min_w_min_h = 0.0 / 0.0;
148+
let max_w_min_h = 0.0 / self.max.width;
149+
let min_w_max_h = self.max.height / 0.0;
209150
let max_w_max_h = self.max.height / self.max.width;
210151

211152
// When the aspect ratio line crosses the constraints, the closest point must be one of the
@@ -219,22 +160,22 @@ impl BoxConstraints {
219160
if aspect_ratio > min_w_max_h {
220161
// outside max height min width
221162
Size {
222-
width: self.min.width,
163+
width: 0.0,
223164
height: self.max.height,
224165
}
225166
} else if aspect_ratio < max_w_min_h {
226167
// outside min height max width
227168
Size {
228169
width: self.max.width,
229-
height: self.min.height,
170+
height: 0.0,
230171
}
231172
} else if aspect_ratio > min_w_min_h {
232173
// hits the constraints on the min width line
233-
if width < self.min.width {
174+
if width < 0.0 {
234175
// we take the point on the min width
235176
Size {
236-
width: self.min.width,
237-
height: self.min.width * aspect_ratio,
177+
width: 0.0,
178+
height: 0.0 * aspect_ratio,
238179
}
239180
} else if aspect_ratio < max_w_max_h {
240181
// exits through max.width
@@ -251,11 +192,11 @@ impl BoxConstraints {
251192
}
252193
} else {
253194
// final case is where we hit constraints on the min height line
254-
if width < self.min.width {
195+
if width < 0.0 {
255196
// take the point on the min height
256197
Size {
257-
width: self.min.height * aspect_ratio.recip(),
258-
height: self.min.height,
198+
width: 0.0 * aspect_ratio.recip(),
199+
height: 0.0,
259200
}
260201
} else if aspect_ratio > max_w_max_h {
261202
// exit thru max height
@@ -278,13 +219,11 @@ impl BoxConstraints {
278219
mod tests {
279220
use super::*;
280221

281-
fn bc(min_width: f64, min_height: f64, max_width: f64, max_height: f64) -> BoxConstraints {
282-
BoxConstraints::new(
283-
Size::new(min_width, min_height),
284-
Size::new(max_width, max_height),
285-
)
222+
fn bc(_min_width: f64, _min_height: f64, max_width: f64, max_height: f64) -> BoxConstraints {
223+
BoxConstraints::new(Size::new(max_width, max_height))
286224
}
287225

226+
// TODO - Fix this test
288227
#[test]
289228
fn constrain_aspect_ratio() {
290229
for (bc, aspect_ratio, width, output) in [
@@ -373,7 +312,5 @@ mod tests {
373312
fn unbounded() {
374313
assert!(!BoxConstraints::UNBOUNDED.is_width_bounded());
375314
assert!(!BoxConstraints::UNBOUNDED.is_height_bounded());
376-
377-
assert_eq!(BoxConstraints::UNBOUNDED.min(), Size::ZERO);
378315
}
379316
}

masonry/src/widget/align.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl Widget for Align {
9696
}
9797

9898
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
99-
let size = ctx.run_layout(&mut self.child, &bc.loosen());
99+
let size = ctx.run_layout(&mut self.child, &bc);
100100

101101
log_size_warnings(size);
102102

masonry/src/widget/button.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ impl Widget for Button {
127127

128128
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
129129
let padding = Size::new(LABEL_INSETS.x_value(), LABEL_INSETS.y_value());
130-
let label_bc = bc.shrink(padding).loosen();
130+
let label_bc = bc.shrink(padding);
131131

132132
let label_size = ctx.run_layout(&mut self.label, &label_bc);
133133

masonry/src/widget/flex.rs

+10-21
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ impl Flex {
126126
cross_alignment: CrossAxisAlignment::Center,
127127
main_alignment: MainAxisAlignment::Start,
128128
fill_major_axis: false,
129-
old_bc: BoxConstraints::tight(Size::ZERO),
129+
old_bc: BoxConstraints::new(Size::ZERO),
130130
gap: None,
131131
}
132132
}
@@ -701,21 +701,10 @@ impl Axis {
701701
}
702702

703703
/// Generate constraints with new values on the major axis.
704-
pub(crate) fn constraints(
705-
self,
706-
bc: &BoxConstraints,
707-
min_major: f64,
708-
major: f64,
709-
) -> BoxConstraints {
704+
pub(crate) fn constraints(self, bc: &BoxConstraints, major: f64) -> BoxConstraints {
710705
match self {
711-
Axis::Horizontal => BoxConstraints::new(
712-
Size::new(min_major, bc.min().height),
713-
Size::new(major, bc.max().height),
714-
),
715-
Axis::Vertical => BoxConstraints::new(
716-
Size::new(bc.min().width, min_major),
717-
Size::new(bc.max().width, major),
718-
),
706+
Axis::Horizontal => BoxConstraints::new(Size::new(major, bc.max().height)),
707+
Axis::Vertical => BoxConstraints::new(Size::new(bc.max().width, major)),
719708
}
720709
}
721710
}
@@ -923,10 +912,10 @@ impl Widget for Flex {
923912

924913
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
925914
// we loosen our constraints when passing to children.
926-
let loosened_bc = bc.loosen();
915+
let loosened_bc = bc;
927916

928917
// minor-axis values for all children
929-
let mut minor = self.direction.minor(bc.min());
918+
let mut minor = 0_f64;
930919
// these two are calculated but only used if we're baseline aligned
931920
let mut max_above_baseline = 0_f64;
932921
let mut max_below_baseline = 0_f64;
@@ -1021,7 +1010,7 @@ impl Widget for Flex {
10211010
remainder = desired_major - actual_major;
10221011

10231012
let old_size = ctx.widget_state.layout_rect().size();
1024-
let child_bc = self.direction.constraints(&loosened_bc, 0.0, actual_major);
1013+
let child_bc = self.direction.constraints(&loosened_bc, actual_major);
10251014
let child_size = ctx.run_layout(widget, &child_bc);
10261015

10271016
if old_size != child_size {
@@ -1057,8 +1046,8 @@ impl Widget for Flex {
10571046
(remaining - major_flex).max(0.0)
10581047
} else {
10591048
// if we are *not* expected to fill our available space this usually
1060-
// means we don't have any extra, unless dictated by our constraints.
1061-
(self.direction.major(bc.min()) - (major_non_flex + major_flex)).max(0.0)
1049+
// means we don't have any extra
1050+
0.0
10621051
};
10631052

10641053
let mut spacing = Spacing::new(self.main_alignment, extra, self.children.len());
@@ -1099,7 +1088,7 @@ impl Widget for Flex {
10991088
.pack(self.direction.major(child_size), minor_dim)
11001089
.into();
11011090
if ctx.widget_state.layout_rect().size() != fill_size {
1102-
let child_bc = BoxConstraints::tight(fill_size);
1091+
let child_bc = BoxConstraints::new(fill_size);
11031092
//TODO: this is the second call of layout on the same child, which
11041093
// is bad, because it can lead to exponential increase in layout calls
11051094
// when used multiple times in the widget hierarchy.

masonry/src/widget/grid.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl Widget for Grid {
274274
(child.width as f64 * width_unit - self.grid_spacing).max(0.0),
275275
(child.height as f64 * height_unit - self.grid_spacing).max(0.0),
276276
);
277-
let child_bc = BoxConstraints::new(cell_size, cell_size);
277+
let child_bc = BoxConstraints::new(cell_size);
278278
let _ = ctx.run_layout(&mut child.widget, &child_bc);
279279
ctx.place_child(
280280
&mut child.widget,

masonry/src/widget/image.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl Widget for Image {
8787
// the image.
8888
let image_size = Size::new(self.image_data.width as f64, self.image_data.height as f64);
8989
if image_size.is_zero_area() {
90-
let size = bc.min();
90+
let size = Size::ZERO;
9191
return size;
9292
}
9393
let image_aspect_ratio = image_size.height / image_size.width;

masonry/src/widget/portal.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,9 @@ impl<W: Widget> Widget for Portal<W> {
360360

361361
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
362362
// TODO - How Portal handles BoxConstraints is due for a rework
363-
let min_child_size = if self.must_fill { bc.min() } else { Size::ZERO };
364363
let max_child_size = bc.max();
365364

366-
let child_bc = BoxConstraints::new(min_child_size, max_child_size);
365+
let child_bc = BoxConstraints::new(max_child_size);
367366

368367
let content_size = ctx.run_layout(&mut self.child, &child_bc);
369368
let portal_size = bc.constrain(content_size);

0 commit comments

Comments
 (0)