Merge: the wire sections lifted into named functions, beside the module splits
This commit is contained in:
+84
-25
@@ -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.
|
||||
|
||||
+95
-29
@@ -421,10 +421,26 @@ pub(crate) fn wire(
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
rows: &Rc<VecModel<ParamRow>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
wire_segment(window, session, rows, redraw);
|
||||
wire_mask_refine(window, session, rows, redraw);
|
||||
wire_gradient_drag(window, session, redraw);
|
||||
wire_region_select(window, session, rows, redraw);
|
||||
wire_stack(window, session, rows, redraw);
|
||||
wire_edge_treatment(window, session, redraw);
|
||||
wire_layers_paint(window, session, rows, redraw);
|
||||
wire_layers_parts(window, session, rows, redraw);
|
||||
}
|
||||
|
||||
/// --- computing the region map -----------------------------------------
|
||||
fn wire_segment(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
rows: &Rc<VecModel<ParamRow>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
let running: Rc<RefCell<Running>> = Rc::default();
|
||||
|
||||
// --- computing the region map -----------------------------------------
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let session = session.clone();
|
||||
@@ -468,13 +484,20 @@ pub(crate) fn wire(
|
||||
watch(&w, id, rx, &session, &rows, &redraw, &running);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- refining one subject's mask ---------------------------------------
|
||||
//
|
||||
// Its own `Running` slot rather than sharing the segmentation one: the
|
||||
// two answer different questions (the whole frame's subjects versus one
|
||||
// already-found instance) and there is no reason a refine in flight
|
||||
// should block a fresh "Find subjects", or the reverse.
|
||||
/// --- refining one subject's mask ---------------------------------------
|
||||
///
|
||||
/// Its own `Running` slot rather than sharing the segmentation one: the
|
||||
/// two answer different questions (the whole frame's subjects versus one
|
||||
/// already-found instance) and there is no reason a refine in flight
|
||||
/// should block a fresh "Find subjects", or the reverse.
|
||||
fn wire_mask_refine(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
rows: &Rc<VecModel<ParamRow>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
let refining: Rc<RefCell<Running>> = Rc::default();
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
@@ -511,16 +534,22 @@ pub(crate) fn wire(
|
||||
watch_refine(&w, session_id, rx, &session, &rows, &redraw, &running);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- dragging a gradient on the photograph ----------------------------
|
||||
//
|
||||
// The geometry the gesture started from, held for its duration.
|
||||
//
|
||||
// **A drag is applied to where the mask was when the press landed**, not
|
||||
// to where it was one frame ago. Accumulating frame by frame would let the
|
||||
// clamps compound — a radius dragged past its limit and back would not
|
||||
// return to where it started — and would make the result depend on how
|
||||
// many events the pointer happened to deliver.
|
||||
/// --- dragging a gradient on the photograph ----------------------------
|
||||
///
|
||||
/// The geometry the gesture started from, held for its duration.
|
||||
///
|
||||
/// **A drag is applied to where the mask was when the press landed**, not
|
||||
/// to where it was one frame ago. Accumulating frame by frame would let the
|
||||
/// clamps compound — a radius dragged past its limit and back would not
|
||||
/// return to where it started — and would make the result depend on how
|
||||
/// many events the pointer happened to deliver.
|
||||
fn wire_gradient_drag(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
let dragging: Rc<RefCell<Option<dr_pipeline::mask::MaskSource>>> = Rc::new(RefCell::new(None));
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
@@ -571,8 +600,15 @@ pub(crate) fn wire(
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- selecting on the photograph --------------------------------------
|
||||
/// --- selecting on the photograph --------------------------------------
|
||||
fn wire_region_select(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
rows: &Rc<VecModel<ParamRow>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let session = session.clone();
|
||||
@@ -596,8 +632,15 @@ pub(crate) fn wire(
|
||||
redraw(&w);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- the stack ---------------------------------------------------------
|
||||
/// --- the stack ---------------------------------------------------------
|
||||
fn wire_stack(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
rows: &Rc<VecModel<ParamRow>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let session = session.clone();
|
||||
@@ -724,12 +767,18 @@ pub(crate) fn wire(
|
||||
redraw(&w);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- the edge treatment -------------------------------------------------
|
||||
//
|
||||
// All four read one distance field, so all four are live: nothing here
|
||||
// rebuilds anything except a compound morphology, which `develop` keys on
|
||||
// separately.
|
||||
/// --- the edge treatment -------------------------------------------------
|
||||
///
|
||||
/// All four read one distance field, so all four are live: nothing here
|
||||
/// rebuilds anything except a compound morphology, which `develop` keys on
|
||||
/// separately.
|
||||
fn wire_edge_treatment(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let session = session.clone();
|
||||
@@ -853,13 +902,20 @@ pub(crate) fn wire(
|
||||
redraw(&w);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- adding layers ------------------------------------------------------
|
||||
// TRACES: FR-DEV-19b
|
||||
// Painting. Three handlers for one gesture, and the middle one runs per
|
||||
// pointer report — so it does the least it can: map the point, record it,
|
||||
// redraw. No sync, because nothing the panel shows changes while a finger
|
||||
// is down, and rebuilding eight rows a frame is how a brush starts to lag.
|
||||
/// --- adding layers ------------------------------------------------------
|
||||
/// TRACES: FR-DEV-19b
|
||||
/// Painting. Three handlers for one gesture, and the middle one runs per
|
||||
/// pointer report — so it does the least it can: map the point, record it,
|
||||
/// redraw. No sync, because nothing the panel shows changes while a finger
|
||||
/// is down, and rebuilding eight rows a frame is how a brush starts to lag.
|
||||
fn wire_layers_paint(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
rows: &Rc<VecModel<ParamRow>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let session = session.clone();
|
||||
@@ -1014,6 +1070,16 @@ pub(crate) fn wire(
|
||||
redraw(&w);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Parts of the active mask, and the buttons that add a new layer —
|
||||
/// gradient, brush, range, category or subject.
|
||||
fn wire_layers_parts(
|
||||
window: &AppWindow,
|
||||
session: &Rc<RefCell<Option<DevelopSession>>>,
|
||||
rows: &Rc<VecModel<ParamRow>>,
|
||||
redraw: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
// TRACES: FR-DEV-19a
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
|
||||
+48
-16
@@ -403,14 +403,26 @@ pub fn wire<F, G>(
|
||||
F: Fn(&Settings) + 'static,
|
||||
G: Fn(&AppWindow) + 'static,
|
||||
{
|
||||
let on_budget_changed = Rc::new(on_budget_changed);
|
||||
let on_budget_changed: Rc<dyn Fn(&Settings)> = Rc::new(on_budget_changed);
|
||||
// Run when the page opens, to fill in figures this module does not own —
|
||||
// the face-indexing coverage, which lives in the catalog. Read here rather
|
||||
// than kept up to date continuously, because it is only ever looked at
|
||||
// when this page is on screen and it is two counts and an indexed scan.
|
||||
let on_open: Rc<dyn Fn(&AppWindow)> = Rc::new(on_open);
|
||||
|
||||
// --- opening and closing -------------------------------------------
|
||||
wire_open_close(window, &controller, &on_open);
|
||||
wire_cache(window, &controller, &on_budget_changed);
|
||||
wire_faces(window, &controller, &on_budget_changed);
|
||||
wire_export(window, &controller);
|
||||
wire_reset(window, &controller, &on_budget_changed);
|
||||
}
|
||||
|
||||
/// --- opening and closing -------------------------------------------
|
||||
fn wire_open_close(
|
||||
window: &AppWindow,
|
||||
controller: &Rc<SettingsController>,
|
||||
on_open: &Rc<dyn Fn(&AppWindow)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let on_open = on_open.clone();
|
||||
@@ -435,12 +447,18 @@ pub fn wire<F, G>(
|
||||
w.set_show_settings(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- cache ---------------------------------------------------------
|
||||
//
|
||||
// A budget arrives as typed text. An unparseable entry leaves the previous
|
||||
// value in place and `render` puts the stored one back in the field, so a
|
||||
// typo is visibly rejected rather than silently shrinking a cache.
|
||||
/// --- cache ---------------------------------------------------------
|
||||
///
|
||||
/// A budget arrives as typed text. An unparseable entry leaves the previous
|
||||
/// value in place and `render` puts the stored one back in the field, so a
|
||||
/// typo is visibly rejected rather than silently shrinking a cache.
|
||||
fn wire_cache(
|
||||
window: &AppWindow,
|
||||
controller: &Rc<SettingsController>,
|
||||
on_budget_changed: &Rc<dyn Fn(&Settings)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = controller.clone();
|
||||
@@ -546,14 +564,20 @@ pub fn wire<F, G>(
|
||||
render(&w, &ctl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- faces ---------------------------------------------------------
|
||||
//
|
||||
// TRACES: FR-CULL-8
|
||||
// Notified like a budget change, because the effect is outside this
|
||||
// page: the library controller carries the pipeline id into the next
|
||||
// sync, and the coverage line under the picker has to be re-counted
|
||||
// under the new id — which the caller's `on_budget_changed` does.
|
||||
/// --- faces ---------------------------------------------------------
|
||||
///
|
||||
/// TRACES: FR-CULL-8
|
||||
/// Notified like a budget change, because the effect is outside this
|
||||
/// page: the library controller carries the pipeline id into the next
|
||||
/// sync, and the coverage line under the picker has to be re-counted
|
||||
/// under the new id — which the caller's `on_budget_changed` does.
|
||||
fn wire_faces(
|
||||
window: &AppWindow,
|
||||
controller: &Rc<SettingsController>,
|
||||
on_budget_changed: &Rc<dyn Fn(&Settings)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = controller.clone();
|
||||
@@ -568,8 +592,10 @@ pub fn wire<F, G>(
|
||||
render(&w, &ctl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- export --------------------------------------------------------
|
||||
/// --- export --------------------------------------------------------
|
||||
fn wire_export(window: &AppWindow, controller: &Rc<SettingsController>) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = controller.clone();
|
||||
@@ -797,8 +823,14 @@ pub fn wire<F, G>(
|
||||
render(&w, &ctl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- reset ---------------------------------------------------------
|
||||
/// --- reset ---------------------------------------------------------
|
||||
fn wire_reset(
|
||||
window: &AppWindow,
|
||||
controller: &Rc<SettingsController>,
|
||||
on_budget_changed: &Rc<dyn Fn(&Settings)>,
|
||||
) {
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = controller.clone();
|
||||
|
||||
Reference in New Issue
Block a user