Split collections_ui::wire into one function per section
The 1,457-line wire() registered every collections-sidebar and grid-drag callback in one function, sectioned only by comment. Lift each section into its own fn: wire_selection (split further into wire_selection and wire_selection_filing, since the original section ran to 375 lines), wire_drag, wire_trash, wire_trash_from_grid, wire_tree_navigation, wire_create, wire_rename, wire_remove, wire_row_drag (the tree row's own hold-drag, which the original "remove" comment's span covered but which is really a separate feature), wire_row_menu, and wire_membership. wire() itself now just coerces the shared closures to trait objects and calls each in the original order. visible_ids is coerced to Rc<dyn Fn() -> Vec<ImageId>> at the top, alongside on_scope_changed and session, so the new functions take plain trait objects instead of threading a generic parameter through every one of them.
This commit is contained in:
File diff suppressed because one or more lines are too long
+166
-47
@@ -1672,17 +1672,52 @@ pub fn wire<S, R, P, C>(
|
||||
P: Fn(usize, usize) -> Vec<ImageId> + 'static,
|
||||
C: Fn() -> Option<dr_sync::Connection> + 'static,
|
||||
{
|
||||
// Coerced to trait objects here rather than at each use: `start_trash` and
|
||||
// `drain_trash` are shared by three callbacks, and a generic parameter would
|
||||
// make each of them a separate instantiation for no gain.
|
||||
// Coerced to trait objects here rather than at each use: each is shared by
|
||||
// several of the functions below, and a generic parameter would make every
|
||||
// one of them a separate instantiation for no gain.
|
||||
let on_scope_changed: Rc<dyn Fn()> = Rc::new(on_scope_changed);
|
||||
let visible_ids = Rc::new(visible_ids);
|
||||
let visible_ids: Rc<dyn Fn() -> Vec<ImageId>> = Rc::new(visible_ids);
|
||||
// A shift-click asks the catalog what lies between its two ends, and the
|
||||
// catalog belongs to the grid's controller — see `span_source`.
|
||||
*ctl.span_source.borrow_mut() = Some(Rc::new(span_ids));
|
||||
let session: Rc<dyn Fn() -> Option<dr_sync::Connection>> = Rc::new(session);
|
||||
|
||||
// --- selection ---------------------------------------------------------
|
||||
wire_selection(window, &ctl, &catalog, &visible_ids, &on_scope_changed);
|
||||
wire_selection_filing(window, &ctl, &catalog, &visible_ids, &on_scope_changed);
|
||||
wire_drag(
|
||||
window,
|
||||
&ctl,
|
||||
&catalog,
|
||||
&visible_ids,
|
||||
&on_scope_changed,
|
||||
&session,
|
||||
);
|
||||
wire_trash(window, &ctl, &catalog, &session, &on_scope_changed);
|
||||
wire_trash_from_grid(
|
||||
window,
|
||||
&ctl,
|
||||
&catalog,
|
||||
&session,
|
||||
&on_scope_changed,
|
||||
&visible_ids,
|
||||
);
|
||||
wire_tree_navigation(window, &ctl, &catalog, &on_scope_changed);
|
||||
wire_create(window, &ctl, &catalog);
|
||||
wire_rename(window, &ctl, &catalog);
|
||||
wire_remove(window, &ctl, &catalog, &visible_ids, &on_scope_changed);
|
||||
wire_row_drag(window, &ctl, &catalog);
|
||||
wire_row_menu(window, &ctl, &catalog, &on_scope_changed, &visible_ids);
|
||||
wire_membership(window, &ctl, &catalog, &visible_ids, &on_scope_changed);
|
||||
}
|
||||
|
||||
/// Selection.
|
||||
fn wire_selection(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
visible_ids: &Rc<dyn Fn() -> Vec<ImageId>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
@@ -1882,7 +1917,17 @@ pub fn wire<S, R, P, C>(
|
||||
sync_selection(&w, &ctl, &ids);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Selection, continued: turning it into a collection, toggling the
|
||||
/// mode, and filing it into one that already exists.
|
||||
fn wire_selection_filing(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
visible_ids: &Rc<dyn Fn() -> Vec<ImageId>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
) {
|
||||
// TRACES: FR-CAT-5
|
||||
// A collection holding exactly what is selected.
|
||||
//
|
||||
@@ -2056,12 +2101,20 @@ pub fn wire<S, R, P, C>(
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- drag --------------------------------------------------------------
|
||||
//
|
||||
// Slint owns the gesture (see the preamble). What is left here is the
|
||||
// payload — the image ids the drop will act on — and the spring.
|
||||
|
||||
/// Drag.
|
||||
///
|
||||
/// Slint owns the gesture (see the preamble). What is left here is the
|
||||
/// payload — the image ids the drop will act on — and the spring.
|
||||
fn wire_drag(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
visible_ids: &Rc<dyn Fn() -> Vec<ImageId>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
session: &Rc<dyn Fn() -> Option<dr_sync::Connection>>,
|
||||
) {
|
||||
// TRACES: FR-CAT-7
|
||||
// **What arms the drag, not what it carries.**
|
||||
//
|
||||
@@ -2335,13 +2388,21 @@ pub fn wire<S, R, P, C>(
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- trash -------------------------------------------------------------
|
||||
//
|
||||
// TRACES: FR-CAT-15
|
||||
// A drop here is a *soft delete*: the file moves to a trash folder on the
|
||||
// server and the catalog records where it came from. Nothing is destroyed
|
||||
// until the user empties it, which is a separate, deliberate action.
|
||||
/// Trash.
|
||||
///
|
||||
/// TRACES: FR-CAT-15
|
||||
/// A drop here is a *soft delete*: the file moves to a trash folder on the
|
||||
/// server and the catalog records where it came from. Nothing is destroyed
|
||||
/// until the user empties it, which is a separate, deliberate action.
|
||||
fn wire_trash(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
session: &Rc<dyn Fn() -> Option<dr_sync::Connection>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
@@ -2379,19 +2440,27 @@ pub fn wire<S, R, P, C>(
|
||||
start_restore(&w, &ctl, &catalog, &session, &chosen, &reload);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- trash from the grid ----------------------------------------------
|
||||
//
|
||||
// Until now the only route to the trash was dragging onto the sidebar row.
|
||||
// These two are the direct gestures: the trash target on a cell's rating
|
||||
// strip, and the `Delete` key.
|
||||
//
|
||||
// Both land here rather than in `library_ui` because everything the
|
||||
// operation needs — the selection, the session closure, `start_trash` and
|
||||
// its drain — already lives in this module. Reaching them from the grid
|
||||
// side would mean either duplicating the worker plumbing or moving it, and
|
||||
// trash is one feature whichever component happens to trigger it.
|
||||
|
||||
/// Trash from the grid.
|
||||
///
|
||||
/// Until now the only route to the trash was dragging onto the sidebar row.
|
||||
/// These two are the direct gestures: the trash target on a cell's rating
|
||||
/// strip, and the `Delete` key.
|
||||
///
|
||||
/// Both land here rather than in `library_ui` because everything the
|
||||
/// operation needs — the selection, the session closure, `start_trash` and
|
||||
/// its drain — already lives in this module. Reaching them from the grid
|
||||
/// side would mean either duplicating the worker plumbing or moving it, and
|
||||
/// trash is one feature whichever component happens to trigger it.
|
||||
fn wire_trash_from_grid(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
session: &Rc<dyn Fn() -> Option<dr_sync::Connection>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
visible_ids: &Rc<dyn Fn() -> Vec<ImageId>>,
|
||||
) {
|
||||
// The trash glyph on one cell. Acts on that photograph alone: the pointer
|
||||
// named it, and a click that silently trashed an entire selection would be
|
||||
// exactly the trap the strip's other targets are laid out to avoid.
|
||||
@@ -2494,8 +2563,15 @@ pub fn wire<S, R, P, C>(
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- tree navigation ---------------------------------------------------
|
||||
/// Tree navigation.
|
||||
fn wire_tree_navigation(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
@@ -2554,8 +2630,14 @@ pub fn wire<S, R, P, C>(
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- create ------------------------------------------------------------
|
||||
/// Create.
|
||||
fn wire_create(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
@@ -2574,14 +2656,19 @@ pub fn wire<S, R, P, C>(
|
||||
create_child(&w, &ctl, cat, *ctl.scope.borrow());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- rename ------------------------------------------------------------
|
||||
//
|
||||
// Inline in the row, opened by a double-click or `F2`. The gesture is worth
|
||||
// the field rather than a dialog: renaming is how a hierarchy gets tidied,
|
||||
// and it is done in runs of several — a modal per collection would make
|
||||
// that a chore.
|
||||
|
||||
/// Rename.
|
||||
///
|
||||
/// Inline in the row, opened by a double-click or `F2`. The gesture is worth
|
||||
/// the field rather than a dialog: renaming is how a hierarchy gets tidied,
|
||||
/// and it is done in runs of several — a modal per collection would make
|
||||
/// that a chore.
|
||||
fn wire_rename(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
@@ -2656,8 +2743,16 @@ pub fn wire<S, R, P, C>(
|
||||
w.set_collection_error(slint::SharedString::new());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- remove from the collection being shown ---------------------------
|
||||
/// Remove from the collection being shown.
|
||||
fn wire_remove(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
visible_ids: &Rc<dyn Fn() -> Vec<ImageId>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
@@ -2697,7 +2792,15 @@ pub fn wire<S, R, P, C>(
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// The tree row's own hold-drag: lift a row, drag it onto another to
|
||||
/// reparent, or onto the root to un-nest it.
|
||||
fn wire_row_drag(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
) {
|
||||
// TRACES: FR-CAT-7 | FR-UI-2 | FR-UI-3 | FR-UI-4
|
||||
// The hold on a sidebar row: it arms the drag that rearranges the tree,
|
||||
// and it opens the row menu. Which one the user gets is decided on release
|
||||
@@ -2836,15 +2939,23 @@ pub fn wire<S, R, P, C>(
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- the row menu ------------------------------------------------------
|
||||
//
|
||||
// Right-click, or a long press on touch. This gesture used to *delete an
|
||||
// empty collection outright* and refuse with an error message otherwise,
|
||||
// which was wrong in both directions at once: the destructive half fired
|
||||
// with no confirmation and nothing on screen said it would, and the
|
||||
// refusing half meant a collection holding anything could not be deleted
|
||||
// at all — the user emptied it by hand and then did the same thing.
|
||||
/// The row menu.
|
||||
///
|
||||
/// Right-click, or a long press on touch. This gesture used to *delete an
|
||||
/// empty collection outright* and refuse with an error message otherwise,
|
||||
/// which was wrong in both directions at once: the destructive half fired
|
||||
/// with no confirmation and nothing on screen said it would, and the
|
||||
/// refusing half meant a collection holding anything could not be deleted
|
||||
/// at all — the user emptied it by hand and then did the same thing.
|
||||
fn wire_row_menu(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
visible_ids: &Rc<dyn Fn() -> Vec<ImageId>>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
@@ -3044,8 +3155,16 @@ pub fn wire<S, R, P, C>(
|
||||
close_row_menu(&w, &ctl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- where the selection is filed --------------------------------------
|
||||
/// Where the selection is filed.
|
||||
fn wire_membership(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<CollectionsController>,
|
||||
catalog: &Rc<RefCell<Option<Catalog>>>,
|
||||
visible_ids: &Rc<dyn Fn() -> Vec<ImageId>>,
|
||||
on_scope_changed: &Rc<dyn Fn()>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
|
||||
Reference in New Issue
Block a user