Move the library's routes and status onto its own Slint global
The scan/opening/status/error lines, offline mode and its retry, pinning a collection offline, the sync and thumbnail-sweep state, and the callbacks that route the grid to a rescan, a sync, another library, a panorama merge or an export — the last of what AppWindow still carried under the library- prefix — move onto the `Library` global started earlier on this branch. Rust reaches them through window.global::<Library>() rather than window.set_/get_/on_/invoke_ on the root. library-visible is the one name that stays: it is computed from active-page and active-view, the shell's own routing state, which a global cannot read. AppWindow now declares no other library- property or callback.
This commit is contained in:
+40
-32
@@ -31,8 +31,8 @@ use crate::spots_ui;
|
||||
use crate::{
|
||||
apply_crop_aspect, batch_request, drain_outbox, export, groups_in_rail, refresh_export_label,
|
||||
render_open_frame, sync_crop_aspect, sync_film, sync_framing, sync_rows, Adjustments,
|
||||
AppWindow, Develop, DevelopSession, Framing, Inspection, ParamRow, Peaking, Render, Steps,
|
||||
ViewMode,
|
||||
AppWindow, Develop, DevelopSession, Framing, Inspection, Library, ParamRow, Peaking, Render,
|
||||
Steps, ViewMode,
|
||||
};
|
||||
|
||||
/// Shared state the develop screen's callbacks capture.
|
||||
@@ -285,7 +285,7 @@ fn wire_export(window: &AppWindow, w: &DevelopWiring) {
|
||||
// buttons share a worker slot, so starting a second run would
|
||||
// drop the first's drain — leaving a batch still writing files
|
||||
// with no progress row and a button that never comes back.
|
||||
if w.get_export_busy() || w.get_library_exporting() {
|
||||
if w.get_export_busy() || w.global::<Library>().get_library_exporting() {
|
||||
w.set_export_status("An export is already running".into());
|
||||
return;
|
||||
}
|
||||
@@ -316,42 +316,50 @@ fn wire_export(window: &AppWindow, w: &DevelopWiring) {
|
||||
let library = library.clone();
|
||||
let collections = collections.clone();
|
||||
let start = start.clone();
|
||||
window.on_library_export_selection(move || {
|
||||
let Some(w) = weak.upgrade() else { return };
|
||||
// See the develop button above for why one run excludes the
|
||||
// other. The button is a cancel by then, so this only catches
|
||||
// a batch started from develop and left running.
|
||||
if w.get_library_exporting() || w.get_export_busy() {
|
||||
w.set_library_status("An export is already running".into());
|
||||
return;
|
||||
}
|
||||
window
|
||||
.global::<Library>()
|
||||
.on_library_export_selection(move || {
|
||||
let Some(w) = weak.upgrade() else { return };
|
||||
// See the develop button above for why one run excludes the
|
||||
// other. The button is a cancel by then, so this only catches
|
||||
// a batch started from develop and left running.
|
||||
if w.global::<Library>().get_library_exporting() || w.get_export_busy() {
|
||||
w.global::<Library>()
|
||||
.set_library_status("An export is already running".into());
|
||||
return;
|
||||
}
|
||||
|
||||
let sources = library.export_sources(&collections.selected());
|
||||
if sources.is_empty() {
|
||||
// Said out loud rather than ignored, matching what a paste
|
||||
// or a judgement keystroke does with an empty selection.
|
||||
w.set_library_status("Select an image first".into());
|
||||
return;
|
||||
}
|
||||
let sources = library.export_sources(&collections.selected());
|
||||
if sources.is_empty() {
|
||||
// Said out loud rather than ignored, matching what a paste
|
||||
// or a judgement keystroke does with an empty selection.
|
||||
w.global::<Library>()
|
||||
.set_library_status("Select an image first".into());
|
||||
return;
|
||||
}
|
||||
|
||||
w.set_library_exporting(true);
|
||||
w.set_library_status(format!("Exporting {} images…", sources.len()).into());
|
||||
start(&w, sources, export::Reporting::Library);
|
||||
});
|
||||
w.global::<Library>().set_library_exporting(true);
|
||||
w.global::<Library>()
|
||||
.set_library_status(format!("Exporting {} images…", sources.len()).into());
|
||||
start(&w, sources, export::Reporting::Library);
|
||||
});
|
||||
}
|
||||
|
||||
// TRACES: NFR-ARCH-3
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
window.on_library_cancel_export(move || {
|
||||
cancel.borrow().cancel();
|
||||
if let Some(w) = weak.upgrade() {
|
||||
// The worker stops at the next point it is safe to — which
|
||||
// may be a frame away — so the button says "asked for" and
|
||||
// not "done". The drain writes the real answer.
|
||||
w.set_library_status("Cancelling the export…".into());
|
||||
}
|
||||
});
|
||||
window
|
||||
.global::<Library>()
|
||||
.on_library_cancel_export(move || {
|
||||
cancel.borrow().cancel();
|
||||
if let Some(w) = weak.upgrade() {
|
||||
// The worker stops at the next point it is safe to — which
|
||||
// may be a frame away — so the button says "asked for" and
|
||||
// not "done". The drain writes the real answer.
|
||||
w.global::<Library>()
|
||||
.set_library_status("Cancelling the export…".into());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user