Give a panorama a wide cell in the grid
A 4:1 composite drawn in one square cell is a strip a few pixels high. A photograph about twice as wide as it is tall (1.9 and up) now spans two columns, three from 2.9, with a thumbnail class of its own whose long edge is sized for that width; on the tablet, or where the columns are too few to put it beside anything, it takes the whole row. Rows are computed in one place, library_ui::layout. The grid is a lattice of slots: each cell is drawn at the slot Rust gives it, and a wide cell that would not fit in what is left of a row starts the next one, leaving the gap empty so the grid still reads in capture order. The scrollbar spans the slots, a scroll reports a slot that the layout turns back into an ordinal, and scrubs, restores and the cursor go through the same conversion. Up and down step by rows through the layout rather than by a row's worth of ordinals; left and right, a shift-click's run, burst folding and the timeline are ordinal-based and unchanged. The window's own read carries each photograph's w and h, so the cells know their shape with no query per cell. Where the wide ones sit in the whole list is one query, run when what the grid lists changes or when a window finds the layout out of date, and a library with no panorama answers it from a partial index created on first use (images_wide), not a schema bump. The merge makes the wide thumbnail for a wide composite along with the others.
This commit is contained in:
@@ -115,10 +115,16 @@ impl Reduced {
|
||||
}
|
||||
}
|
||||
|
||||
/// Which size classes a composite of this shape is thumbnailed at.
|
||||
/// Which size classes a composite of this shape is thumbnailed at: the two
|
||||
/// every photograph has, and the wide one where the grid will give it a
|
||||
/// wide cell.
|
||||
pub fn classes(width: u32, height: u32) -> Vec<ThumbSize> {
|
||||
let _ = (width, height);
|
||||
vec![ThumbSize::Grid, ThumbSize::Large]
|
||||
let aspect = width as f32 / height.max(1) as f32;
|
||||
let mut out = vec![ThumbSize::Grid, ThumbSize::Large];
|
||||
if crate::library_ui::layout::natural_span(Some(aspect)) > 1 {
|
||||
out.push(ThumbSize::Wide);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Develop the reduced composite as develop would open the file, and render
|
||||
@@ -190,6 +196,12 @@ pub fn render(
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_panorama_is_thumbnailed_for_its_wide_cell_and_a_squat_merge_is_not() {
|
||||
assert_eq!(classes(22_000, 5_600).last(), Some(&ThumbSize::Wide));
|
||||
assert!(!classes(9_000, 6_000).contains(&ThumbSize::Wide));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_reduction_averages_its_boxes_and_the_ragged_edge() {
|
||||
// 5 × 3 by 2: boxes of 2 × 2, then 1 × 2 at the right, 2 × 1 and
|
||||
@@ -286,7 +298,8 @@ mod tests {
|
||||
eprintln!("no GPU; skipping");
|
||||
return;
|
||||
};
|
||||
let (width, height, white) = (3000u32, 760u32, 13_023u32);
|
||||
// Past `SOURCE_EDGE`, so the thumbnails come from a reduced copy.
|
||||
let (width, height, white) = (4600u32, 1160u32, 13_023u32);
|
||||
let pixels = composite(width, height, white);
|
||||
let profile = profile(white);
|
||||
let header = dr_export::SourceMetadata {
|
||||
@@ -298,8 +311,8 @@ mod tests {
|
||||
let crop = dr_export::Rect {
|
||||
x: 40,
|
||||
y: 30,
|
||||
width: 2900,
|
||||
height: 700,
|
||||
width: 4500,
|
||||
height: 1080,
|
||||
};
|
||||
|
||||
// Develop's side: the whole composite written as the merge writes
|
||||
@@ -328,7 +341,8 @@ mod tests {
|
||||
let mut developed = crate::open_session(&ctx, decoder, &bytes, &meta).unwrap();
|
||||
|
||||
// The merge's side: the same bands, reduced as they pass.
|
||||
let mut reduced = Reduced::new(width, height, 1500);
|
||||
let mut reduced = Reduced::new(width, height, SOURCE_EDGE);
|
||||
assert_eq!(reduced.factor(), 2);
|
||||
for first in (0..height).step_by(rows_per_strip as usize) {
|
||||
let rows = rows_per_strip.min(height - first);
|
||||
let from = (first * width * 3) as usize;
|
||||
@@ -345,7 +359,7 @@ mod tests {
|
||||
&header,
|
||||
Some(crop),
|
||||
decoder,
|
||||
&[ThumbSize::Grid, ThumbSize::Large],
|
||||
&[ThumbSize::Grid, ThumbSize::Large, ThumbSize::Wide],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user