Measure the grid against the grid, not the whole view
`cell-size`, `columns` and `visible-rows` were all derived from the LibraryGrid's own width and height. The cells are not drawn in that box: the capture-time axis is a sibling of the grid, 96px of it, and the header takes another 44px off the top. So `columns` counted the timeline as room for thumbnails and fitted one more column than there was space for. The last column started inside the Flickable and ended outside it — clipped, with no sideways scroll to reach it. At the 180px size class on a phone in portrait the timeline is a quarter of the screen, which is most of a column. `visible-rows` was wrong the same way and fed `capacity`, so every window over-fetched by the ratio of the header to the viewport. Both now read `grid-area`, the layout the cells actually live in. That is a descendant, and reading a descendant's geometry is the shape that causes binding loops elsewhere in this UI — but not here: nothing derived from these feeds back into the layout. The cells are placed absolutely inside the Flickable and a Flickable's layout constraints are a bare `stretch: 1` that its viewport cannot influence.
This commit is contained in:
@@ -933,6 +933,25 @@ export component LibraryGrid inherits Rectangle {
|
||||
/// below, which is this capped to what the grid can hold.
|
||||
in property <length> requested-cell-size: 180px;
|
||||
|
||||
// --- what the grid is measured against ---------------------------------
|
||||
//
|
||||
// **`grid-area`, not `self`.** Every quantity below describes the box the
|
||||
// cells are actually drawn in, and that box is *not* this component: the
|
||||
// capture-time axis is a sibling of it, 96px wide, and the header sits
|
||||
// above it. Measuring against `self.width` therefore counted the timeline
|
||||
// as room for thumbnails and fitted one more column than there was space
|
||||
// for — the last column ran off the right-hand edge, clipped by the
|
||||
// Flickable, with no way to scroll sideways to it. At 180px cells that is
|
||||
// a whole column lost on a phone in portrait, where 96px of 400 is a
|
||||
// quarter of the screen.
|
||||
//
|
||||
// Reading a descendant's geometry is safe here because nothing derived
|
||||
// from it feeds back into the layout: the cells are placed absolutely
|
||||
// inside the Flickable, and a Flickable's own layout constraints are a
|
||||
// bare `stretch: 1` that its viewport cannot influence. That is the loop
|
||||
// the comments on `panel-visible` in app.slint warn about, and this is not
|
||||
// an instance of it.
|
||||
|
||||
/// The drawn cell, never wider than the column it has to sit in.
|
||||
///
|
||||
/// `columns` floors to a minimum of one, so a cell larger than the grid
|
||||
@@ -946,9 +965,10 @@ export component LibraryGrid inherits Rectangle {
|
||||
/// choice intact — rotate to landscape, or close the sidebar, and the
|
||||
/// thumbnails grow back to the size that was asked for.
|
||||
property <length> cell-size:
|
||||
min(root.requested-cell-size, max(64px, self.width - 2 * Theme.gap));
|
||||
min(root.requested-cell-size, max(64px, grid-area.width - 2 * Theme.gap));
|
||||
|
||||
property <int> columns: max(1, floor((self.width - Theme.gap) / (cell-size + Theme.gap)));
|
||||
property <int> columns:
|
||||
max(1, floor((grid-area.width - Theme.gap) / (cell-size + Theme.gap)));
|
||||
// Reported out so Rust can place month headings: a heading belongs on a
|
||||
// cell that begins a row, and only the grid knows how wide a row is.
|
||||
changed columns => { root.columns-changed(root.columns); }
|
||||
@@ -960,7 +980,8 @@ export component LibraryGrid inherits Rectangle {
|
||||
// Derived rather than a constant: a fixed window is simultaneously too
|
||||
// small on a maximised 4K window — where three screenfuls fit inside it —
|
||||
// and wasteful on a narrow one.
|
||||
property <int> visible-rows: max(1, ceil(self.height / (cell-size + Theme.gap)));
|
||||
property <int> visible-rows:
|
||||
max(1, ceil(grid-area.height / (cell-size + Theme.gap)));
|
||||
property <int> capacity: root.columns * (root.visible-rows * 3);
|
||||
changed capacity => { root.capacity-changed(root.capacity); }
|
||||
/// Rows the *whole library* occupies, which is what the scrollbar spans.
|
||||
@@ -1418,7 +1439,7 @@ export component LibraryGrid inherits Rectangle {
|
||||
zoom(d) => { root.timeline-zoom(d); }
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
grid-area := VerticalLayout {
|
||||
horizontal-stretch: 1;
|
||||
|
||||
// --- empty state --------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user