diff --git a/ui/dr-ui/src/library_ui.rs b/ui/dr-ui/src/library_ui.rs index 42412a8..4749b8a 100644 --- a/ui/dr-ui/src/library_ui.rs +++ b/ui/dr-ui/src/library_ui.rs @@ -5884,13 +5884,35 @@ pub fn wire( }); } - // --- the keyboard cursor (FR-CULL-4) ----------------------------------- - // - // Walking the grid with the arrows, and opening with `Return`. Together - // with the judgement keys already bound in the grid, this is what makes a - // culling pass a keyboard job: move, rate, move, open the doubtful one, - // come back. A cull is thousands of decisions, and reaching for the mouse - // between each of them is the difference between an hour and an evening. + wire_grid_cursor_and_zoom(window, &ctl, &coll_ctl, &on_open_image); + wire_grid_sync_and_load(window, &ctl); + wire_timeline(window, &ctl); + wire_grid_routes(window, &ctl, &coll_ctl, on_leave_develop); + wire_ratings_and_flags(window, &ctl, &coll_ctl); + wire_keywords(window, &ctl, &coll_ctl); + wire_filter_ratings_and_people(window, &ctl); + wire_filter_dates(window, &ctl); + wire_filter_scope_and_offline(window, &ctl, &coll_ctl); + + // Last, and in its own module: the answers to a damaged catalog have + // nothing to do with the library view except that they run before it + // exists. + crate::recovery_ui::wire(window, &ctl, &coll_ctl); +} + +/// --- the keyboard cursor (FR-CULL-4) ----------------------------------- +/// +/// Walking the grid with the arrows, and opening with `Return`. Together +/// with the judgement keys already bound in the grid, this is what makes a +/// culling pass a keyboard job: move, rate, move, open the doubtful one, +/// come back. A cull is thousands of decisions, and reaching for the mouse +/// between each of them is the difference between an hour and an evening. +fn wire_grid_cursor_and_zoom( + window: &AppWindow, + ctl: &Rc, + coll_ctl: &Rc, + on_open_image: &OpenImage, +) { { let weak = window.as_weak(); let ctl = ctl.clone(); @@ -6011,7 +6033,11 @@ pub fn wire( crate::collections_ui::cancel_press(&w, &coll, &ctl.visible_ids()); }); } +} +/// Reload triggers for the grid: an explicit sync or thumbnail sweep, and +/// the geometry and scroll changes that move which rows are loaded. +fn wire_grid_sync_and_load(window: &AppWindow, ctl: &Rc) { // Explicit sync, for when the user wants the exchange now rather than // after the next sweep. { @@ -6212,7 +6238,11 @@ pub fn wire( load_window(&w, &ctl); }); } +} +/// The capture-time sidebar: panning, zooming and scrubbing the axis that +/// the grid's loaded window follows. +fn wire_timeline(window: &AppWindow, ctl: &Rc) { // Panning the timeline slides the visible span without changing its width. { let weak = window.as_weak(); @@ -6320,7 +6350,16 @@ pub fn wire( apply_zoom(&w, &ctl, steps); }); } +} +/// Moving between the grid and the screens around it: the launch screen, +/// develop, and a manual rescan. +fn wire_grid_routes( + window: &AppWindow, + ctl: &Rc, + coll_ctl: &Rc, + on_leave_develop: Rc, +) { // Grid → launch screen. The route that was missing: once past the launch // screen there was no way back to it, so a library pointed at the wrong // folder could not be changed without clearing stored state by hand. @@ -6379,9 +6418,14 @@ pub fn wire( start_rescan(&w, &ctl, &coll_ctl); }); } +} - // --- ratings and flags (FR-CAT-5, FR-CULL-4) -------------------------- - +/// --- ratings and flags (FR-CAT-5, FR-CULL-4) -------------------------- +fn wire_ratings_and_flags( + window: &AppWindow, + ctl: &Rc, + coll_ctl: &Rc, +) { // Clicking a star rates *that cell*, not the selection. The pointer names // one photograph unambiguously, and a click that silently rated forty // others would be a trap — the keyboard is the bulk gesture. @@ -6483,13 +6527,19 @@ pub fn wire( } }); } +} - // --- keywords (FR-CAT-5, FR-CAT-6) ------------------------------------ - // - // Three callbacks and no state of their own: the sheet's open/shut is local - // to the `.slint` file, and what a keyword applies to is the grid selection - // the collections controller already owns. A second copy of either here is - // a second thing that can disagree with the first. +/// --- keywords (FR-CAT-5, FR-CAT-6) ------------------------------------ +/// +/// Three callbacks and no state of their own: the sheet's open/shut is local +/// to the `.slint` file, and what a keyword applies to is the grid selection +/// the collections controller already owns. A second copy of either here is +/// a second thing that can disagree with the first. +fn wire_keywords( + window: &AppWindow, + ctl: &Rc, + coll_ctl: &Rc, +) { { let weak = window.as_weak(); let ctl = ctl.clone(); @@ -6517,12 +6567,14 @@ pub fn wire( apply_keyword(&w, &ctl, word.as_str(), false); }); } +} - // --- the filter bar --------------------------------------------------- - // - // Each of these narrows what the grid *queries*, so all three reset the - // scroll offset: the window's position was an ordinal into a different - // set of images and means nothing once the set changes. +/// --- the filter bar --------------------------------------------------- +/// +/// Each of these narrows what the grid *queries*, so all three reset the +/// scroll offset: the window's position was an ordinal into a different +/// set of images and means nothing once the set changes. +fn wire_filter_ratings_and_people(window: &AppWindow, ctl: &Rc) { { let weak = window.as_weak(); let ctl = ctl.clone(); @@ -6691,7 +6743,11 @@ pub fn wire( refilter(&w, &ctl); }); } +} +/// The date-range filter: turned on from the timeline's own visible span, +/// dragged along the axis, or typed as two dates. +fn wire_filter_dates(window: &AppWindow, ctl: &Rc) { // Turn the range on, over the period the histogram is showing. // // The range is taken from the timeline rather than typed into two date @@ -6860,7 +6916,15 @@ pub fn wire( refilter(&w, &ctl); }); } +} +/// Whether the grid is scoped to what is available offline, and the +/// prompt those controls open. +fn wire_filter_scope_and_offline( + window: &AppWindow, + ctl: &Rc, + coll_ctl: &Rc, +) { // TRACES: FR-CAT-9 // "On this device" — the images openable without a server. Composes with // the rating terms rather than replacing them: "five-star frames I can @@ -6959,11 +7023,6 @@ pub fn wire( start_rescan(&w, &ctl, &coll_ctl); }); } - - // Last, and in its own module: the answers to a damaged catalog have - // nothing to do with the library view except that they run before it - // exists. - crate::recovery_ui::wire(window, &ctl, &coll_ctl); } /// Reload the grid after the filter changed.