Step along the roll by library ordinal, and keep its mark on the open photograph
In a library's develop view the arrows, space, A and D opened `library-roll-pick(library-roll-current ± 1)`. `roll-current` is a row of the loaded window, set when a photograph was opened and never again. Two things followed on any library larger than one window: - Holding D stopped dead at the end of the loaded window: the pick of a row past `ctl.paths` found no path and did nothing, a few screenfuls into a library of thousands. A stopped at its start the same way. - Any reload of the window — a background sync, a judgement that drops the open frame out of a filter — left `roll-current` on a row that now held another photograph. The roll marked it, develop's rating keys judged it, and the next step walked on from it. The keys now call `library-roll-step(delta)`, and Rust steps as `move_cursor` does in the grid: from the open photograph's ordinal (`index`, which `report_position` already keeps), clamped to the library, loading the window around the target only when it lies outside. The window-bringing half of `place_cursor` is shared for this as `bring_window_to`, so the grid cursor and the roll move the window the same way. Catalog reads stay proportional to the window: one `load_window` per window crossed, none per step within it. The open photograph is also remembered by image id. Every `load_window` finds it again in the rows it just read (a scan of one window, no query), puts `roll-current` and `index` back on it, or takes the mark off when it is not there. When it is missing but its ordinal is still inside the window, it has left the grid and its successor moved up into its place, so the next step forward lands on that ordinal instead of skipping the successor. A click on the roll still reports a row; it is right because the cells it is drawn from and `ctl.paths` are replaced together, and it now goes through the same open path as a step. Fixes #64.
This commit is contained in:
@@ -128,6 +128,22 @@ pub struct LibraryController {
|
||||
/// quarter-window above the view. Restoring that as a viewport position
|
||||
/// would land the user consistently short of where they were.
|
||||
pub(super) resume_at: std::cell::Cell<usize>,
|
||||
/// The photograph open in develop, by catalog id, when it was opened from
|
||||
/// this library.
|
||||
///
|
||||
/// **An id, not a row of the loaded window.** The roll marks a row and the
|
||||
/// keyboard steps from one, but a row only names a photograph until the
|
||||
/// window is next re-read — a step past its edge, a background sync, a
|
||||
/// judgement that drops the frame out of a filter. Each reload finds this
|
||||
/// id again in the new window (see `window::follow_open`) and puts the
|
||||
/// roll's mark, and the ordinal `index` reports, back on it.
|
||||
pub(super) roll_open: std::cell::Cell<Option<i64>>,
|
||||
/// The open photograph was not in the window last read, although the
|
||||
/// ordinal it held still was: it has left the grid — a judgement under a
|
||||
/// filter, most often — and the photograph after it has moved up into its
|
||||
/// place. A step forward is then onto that ordinal, not past it, or the
|
||||
/// frame that closed the gap would be skipped.
|
||||
pub(super) roll_left: std::cell::Cell<bool>,
|
||||
/// How many cells to load, derived from what the viewport can show.
|
||||
///
|
||||
/// A fixed count is wrong in both directions: too small on a maximised 4K
|
||||
@@ -430,6 +446,8 @@ impl LibraryController {
|
||||
thumb_class: RefCell::new(Vec::new()),
|
||||
offset: RefCell::new(0),
|
||||
resume_at: std::cell::Cell::new(0),
|
||||
roll_open: std::cell::Cell::new(None),
|
||||
roll_left: std::cell::Cell::new(false),
|
||||
window: RefCell::new((INITIAL_VIEWPORT_CELLS * SCREENFULS).max(MIN_WINDOW)),
|
||||
viewport_cells: std::cell::Cell::new(INITIAL_VIEWPORT_CELLS),
|
||||
library_facts: RefCell::new(None),
|
||||
|
||||
Reference in New Issue
Block a user