Replace placement calls with region nodes
This commit is contained in:
1 parent
f437495309
commit
71c9c39523
23 files changed
+374
-170
No files matched your search
@@ -29,14 +29,15 @@ impl Widget for Aligned {
|
||||
// Drawn where it may be too big only when the aligned axes are not
|
||||
// already known, then given its aligned box once its size is known.
|
||||
let had_size = known.is_some();
|
||||
let size = known.unwrap_or_else(|| painter.place(&self.inner, UiRegion::FULL).size());
|
||||
let size =
|
||||
known.unwrap_or_else(|| painter.widget_within(&self.inner, UiRegion::FULL).size());
|
||||
let region = match self.align.tuple() {
|
||||
(Some(x), Some(y)) => size.to_uivec2().align(RegionAlign { x, y }),
|
||||
(Some(x), None) => UiRegion::new(size.x.apply_leftover().align(x), UiSpan::FULL),
|
||||
(None, Some(y)) => UiRegion::new(UiSpan::FULL, size.y.apply_leftover().align(y)),
|
||||
(None, None) => UiRegion::FULL,
|
||||
};
|
||||
let placed = painter.place(&self.inner, region).size();
|
||||
let placed = painter.widget_within(&self.inner, region).size();
|
||||
if had_size { placed } else { size }
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,12 @@ impl Widget for Scroll {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
let container_len = painter.px_len(self.axis);
|
||||
// Draw in the whole container only when its scrolling-axis length is
|
||||
// not already known, then place it at the scrolled offset.
|
||||
// not already known, then draw it at the scrolled offset.
|
||||
let (answer_len, measured) = match painter.known_len(&self.inner, self.axis, UiRegion::FULL)
|
||||
{
|
||||
Some(len) => (len, None),
|
||||
None => {
|
||||
let size = painter.place(&self.inner, UiRegion::FULL).size();
|
||||
let size = painter.widget_within(&self.inner, UiRegion::FULL).size();
|
||||
(size.axis(self.axis), Some(size))
|
||||
}
|
||||
};
|
||||
@@ -43,7 +43,7 @@ impl Widget for Scroll {
|
||||
|
||||
let mut region = UiRegion::FULL.offset(Vec2::from_axis(self.axis, -self.amt, 0.0));
|
||||
region.axis_mut(self.axis).end = region.axis(self.axis).start.offset(self.content_len);
|
||||
let placed = painter.place(&self.inner, region).size();
|
||||
let placed = painter.widget_within(&self.inner, region).size();
|
||||
measured.unwrap_or_else(|| Size::from_axis(self.axis, answer_len, placed.axis(!self.axis)))
|
||||
}
|
||||
}
|
||||
|
||||
+16
-12
@@ -21,8 +21,8 @@ pub struct Span {
|
||||
impl Widget for Span {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
let axis = self.dir.axis;
|
||||
// A length for every child before any is placed: from its own hint
|
||||
// where it has one, and from drawing it where it does not.
|
||||
// A length for every child before their final boxes are chosen: from
|
||||
// a hint where one exists, and from drawing otherwise.
|
||||
let mut cursor = UiScalar::rel_min();
|
||||
let mut lens = Vec::with_capacity(self.children.len());
|
||||
for child in &self.children {
|
||||
@@ -33,7 +33,7 @@ impl Widget for Span {
|
||||
let region = UiRegion::from_axis(axis, span, UiSpan::FULL);
|
||||
let len = match painter.known_len(child, axis, region) {
|
||||
Some(len) => len,
|
||||
None => painter.place(child, region).len(axis),
|
||||
None => painter.widget_within(child, region).len(axis),
|
||||
};
|
||||
cursor.px += len.px + self.gap;
|
||||
cursor.rel += len.rel;
|
||||
@@ -47,24 +47,28 @@ impl Widget for Span {
|
||||
// beside 300 px is full at 600 and overfull at 400. The answer is
|
||||
// the same on either side of the length the fixed parts alone fill.
|
||||
let fixed = 1.0 - total.rel;
|
||||
let shares = total.leftover > 0.0 && fixed * painter.px_len(axis) > total.px;
|
||||
let mut shares = false;
|
||||
if total.leftover > 0.0 {
|
||||
let range = if fixed > 0.0 {
|
||||
let current = painter.px_len(axis);
|
||||
let holds = if fixed > 0.0 {
|
||||
let full = total.px / fixed;
|
||||
shares = current > full;
|
||||
match shares {
|
||||
true => full..=f32::INFINITY,
|
||||
false => f32::NEG_INFINITY..=full,
|
||||
true => Holds::exact(full.next_up()..=f32::INFINITY),
|
||||
false => Holds::exact(f32::NEG_INFINITY..=full),
|
||||
}
|
||||
} else if fixed < 0.0 {
|
||||
let full = total.px / fixed;
|
||||
shares = current < full;
|
||||
match shares {
|
||||
true => f32::NEG_INFINITY..=full,
|
||||
false => full..=f32::INFINITY,
|
||||
true => Holds::exact(f32::NEG_INFINITY..=full.next_down()),
|
||||
false => Holds::exact(full..=f32::INFINITY),
|
||||
}
|
||||
} else {
|
||||
f32::NEG_INFINITY..=f32::INFINITY
|
||||
shares = total.px < 0.0;
|
||||
Holds::ANY
|
||||
};
|
||||
painter.holds(axis, range);
|
||||
painter.holds(axis, holds);
|
||||
}
|
||||
|
||||
let mut start = UiScalar::rel_min();
|
||||
@@ -93,7 +97,7 @@ impl Widget for Span {
|
||||
if self.dir.sign == Sign::Neg {
|
||||
region.flip(axis);
|
||||
}
|
||||
let placed = painter.place(child, region);
|
||||
let placed = painter.widget_within(child, region);
|
||||
if self.ortho == OrthoSize::Children {
|
||||
let used = placed.len(!axis);
|
||||
// Choosing between a fixed and a relative length from the
|
||||
|
||||
+11
-1
@@ -31,6 +31,14 @@ widget_trait! {
|
||||
}
|
||||
}
|
||||
|
||||
fn region_node(self) -> impl WidgetIdFn<Rsc, WL::Widget> {
|
||||
|state| {
|
||||
let id = self.add(state);
|
||||
state.ui_mut().widgets.set_region_node(id, true);
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
fn sized(self, size: impl Into<Size>) -> impl WidgetFn<Rsc, SetSize> {
|
||||
let size = size.into();
|
||||
move |state| SetSize {
|
||||
@@ -85,7 +93,9 @@ widget_trait! {
|
||||
|
||||
fn scrollable(self) -> impl WidgetIdFn<Rsc, Scroll> where Rsc: HasEvents {
|
||||
move |state| {
|
||||
Scroll::new(self.add_strong(state), Axis::Y)
|
||||
let inner = self.add(state);
|
||||
state.ui_mut().widgets.set_region_node(inner, true);
|
||||
Scroll::new(inner.upgrade(state), Axis::Y)
|
||||
.on(CursorSense::Scroll, |ctx, rsc| {
|
||||
let delta = ctx.data.scroll_delta.y * 50.0;
|
||||
ctx.widget(rsc).scroll(delta);
|
||||
|
||||
Reference in new issue
Block a user