Split library_ui::wire into one function per section

wire() registered every grid callback in one 1,214-line function behind
four section comments, two of which were themselves far over 300 lines
with no further markers. Each fenced section becomes its own function,
called from wire() in the original order with the section's own comment
kept as its doc comment:

- "the keyboard cursor (FR-CULL-4)" (496 lines) splits at its own topic
  breaks into wire_grid_cursor_and_zoom (cursor movement, cell zoom and
  pinch), wire_grid_sync_and_load (explicit sync/thumbnail requests and
  the reloads a changed viewport, column count or scroll position
  trigger), wire_timeline (the capture-time sidebar) and wire_grid_routes
  (grid/launch/develop navigation and a manual rescan).
- "ratings and flags" and "keywords" were already under 300 lines and
  become one function each.
- "the filter bar" (447 lines) splits into wire_filter_ratings_and_people
  (which keeps the section's own comment), wire_filter_dates and
  wire_filter_scope_and_offline.

The three callbacks registered before the first section comment
(on_settings_xmp_reload, on_library_cell_clicked, on_library_roll_pick)
and the trailing crate::recovery_ui::wire call stay directly in wire(),
since neither is inside a fenced section.
This commit is contained in:
2026-09-20 17:25:00 +02:00
parent 59605f9fbb
commit bd3b993b90
+84 -25
View File
@@ -5884,13 +5884,35 @@ pub fn wire<F>(
});
}
// --- 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<LibraryController>,
coll_ctl: &Rc<crate::collections_ui::CollectionsController>,
on_open_image: &OpenImage,
) {
{
let weak = window.as_weak();
let ctl = ctl.clone();
@@ -6011,7 +6033,11 @@ pub fn wire<F>(
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<LibraryController>) {
// Explicit sync, for when the user wants the exchange now rather than
// after the next sweep.
{
@@ -6212,7 +6238,11 @@ pub fn wire<F>(
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<LibraryController>) {
// Panning the timeline slides the visible span without changing its width.
{
let weak = window.as_weak();
@@ -6320,7 +6350,16 @@ pub fn wire<F>(
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<LibraryController>,
coll_ctl: &Rc<crate::collections_ui::CollectionsController>,
on_leave_develop: Rc<dyn Fn()>,
) {
// 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<F>(
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<LibraryController>,
coll_ctl: &Rc<crate::collections_ui::CollectionsController>,
) {
// 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<F>(
}
});
}
}
// --- 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<LibraryController>,
coll_ctl: &Rc<crate::collections_ui::CollectionsController>,
) {
{
let weak = window.as_weak();
let ctl = ctl.clone();
@@ -6517,12 +6567,14 @@ pub fn wire<F>(
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<LibraryController>) {
{
let weak = window.as_weak();
let ctl = ctl.clone();
@@ -6691,7 +6743,11 @@ pub fn wire<F>(
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<LibraryController>) {
// 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<F>(
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<LibraryController>,
coll_ctl: &Rc<crate::collections_ui::CollectionsController>,
) {
// 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<F>(
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.