Place a scroll's fitting content in the viewport, not in the window
A scroll that has not been scrolled and whose content fits asked for its content box as `Part::From(UiSpan::FULL)`. A `Part::From` span is in window lengths, so `rel(1.0)` in one is the whole window rather than the whole box, and the content landed in a window-tall box anchored at the viewport's start -- 50 px low for a 300 px viewport in a 400 px window. Saying the whole of the box as `Part::All` is the one expression that cannot mean anything else, and it is also the place the child was already asked in, so the placement becomes a no-op.
This commit is contained in:
1 parent
a30971e4c5
commit
e8a5792dcb
2 files changed
+22
-5
No files matched your search
@@ -44,7 +44,6 @@ impl Widget for Scroll {
|
|||||||
// have placed the whole scroll in a box longer than it.
|
// have placed the whole scroll in a box longer than it.
|
||||||
let slack = (self.container_len - self.content_len).max(Px::ZERO);
|
let slack = (self.container_len - self.content_len).max(Px::ZERO);
|
||||||
let anchor = slack.mul(align.rel());
|
let anchor = slack.mul(align.rel());
|
||||||
let mut content = UiSpan::FULL;
|
|
||||||
// Content that fills the viewport and has not been scrolled is the
|
// Content that fills the viewport and has not been scrolled is the
|
||||||
// viewport, and is handed back as it came. Writing the same box as
|
// viewport, and is handed back as it came. Writing the same box as
|
||||||
// its own length in pixels is the same box in another form, and the
|
// its own length in pixels is the same box in another form, and the
|
||||||
@@ -52,18 +51,20 @@ impl Widget for Scroll {
|
|||||||
// one centred in `px 900`, since halving a difference is not halving
|
// one centred in `px 900`, since halving a difference is not halving
|
||||||
// each part of it.
|
// each part of it.
|
||||||
let moved = anchor != Px::ZERO || self.amt != Px::ZERO;
|
let moved = anchor != Px::ZERO || self.amt != Px::ZERO;
|
||||||
if moved || self.content_len != self.container_len {
|
let content = match moved || self.content_len != self.container_len {
|
||||||
|
true => {
|
||||||
let start = Len::from_parts(Rel::ZERO, anchor - self.amt);
|
let start = Len::from_parts(Rel::ZERO, anchor - self.amt);
|
||||||
content = UiSpan::new(start, start.offset(self.content_len));
|
Part::From(UiSpan::new(start, start.offset(self.content_len)))
|
||||||
}
|
}
|
||||||
|
false => Part::All,
|
||||||
|
};
|
||||||
// The viewport is the inner's frame, so a fraction it declares or
|
// The viewport is the inner's frame, so a fraction it declares or
|
||||||
// reports is a fraction of what is on screen rather than of the
|
// reports is a fraction of what is on screen rather than of the
|
||||||
// content box its own answer decided. Where it goes is the content
|
// content box its own answer decided. Where it goes is the content
|
||||||
// box, scrolled: its drawing moved there, not made again there.
|
// box, scrolled: its drawing moved there, not made again there.
|
||||||
painter.place_at(
|
painter.place_at(
|
||||||
&self.inner,
|
&self.inner,
|
||||||
self.axis
|
self.axis.pair(Place::Fill(content), Place::Fill(Part::All)),
|
||||||
.pair(Place::Fill(Part::From(content)), Place::Fill(Part::All)),
|
|
||||||
);
|
);
|
||||||
// What it occupies is its box, on both axes: it clips its content to
|
// What it occupies is its box, on both axes: it clips its content to
|
||||||
// that box, so it can neither take less of one nor honestly ask for
|
// that box, so it can neither take less of one nor honestly ask for
|
||||||
|
|||||||
@@ -145,3 +145,19 @@ fn a_clipping_widget_reporting_more_than_its_box_is_caught() {
|
|||||||
h.set_root(clipper);
|
h.set_root(clipper);
|
||||||
h.frame();
|
h.frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Content that fits sits in the viewport, not in a box of the window's
|
||||||
|
/// length anchored at the viewport's start. `Part::From` takes window
|
||||||
|
/// lengths, so a `rel(1.0)` span in one is the window, and only a scroll
|
||||||
|
/// filling the window would land right.
|
||||||
|
#[test]
|
||||||
|
fn content_that_fits_is_placed_in_the_viewport_and_not_in_the_window() {
|
||||||
|
let mut h = Harness::new((400, 400));
|
||||||
|
let head = rect(Color::RED).height(100).add(&mut h.rsc);
|
||||||
|
let inner = rect(Color::BLUE).height(50).add(&mut h.rsc);
|
||||||
|
let scroll = Scroll::new(inner.add_strong(&mut h.rsc), Axis::Y).add(&mut h.rsc);
|
||||||
|
h.set_root((head, scroll).span(Dir::DOWN));
|
||||||
|
|
||||||
|
assert_corners!(h, scroll, (0, 100), (400, 400));
|
||||||
|
assert_corners!(h, inner, (0, 225), (400, 275));
|
||||||
|
}
|
||||||
Reference in new issue
Block a user