Move the library grid's cells and selection onto their own Slint global
AppWindow carried the grid's loaded window of cells, the keyboard cursor, drag and drop, the held-row long-press state, columns and cell size, the scroll and viewport bookkeeping, the photo roll's pick and centre-request, and the local-only/reorder/collection-filing gestures that act on a selection, as properties and callbacks on the root component. That state now lives in the `Library` global declared in library.slint, next to the structs (LibraryCell, TimelineBar, KeywordRow, PersonChip) it and the grid's other components already share; Rust reaches it through window.global::<Library>() instead of window.set_/get_/on_/invoke_ on the root, the same change collections.slint's `Collections` global made for the sidebar. library-visible stays on AppWindow: it is computed from active-page and active-view, the shell's own routing state, which a global cannot read. Everything else still prefixed library- — the timeline, the filter bar, ratings and flags, keywording, and the routes and status lines — stays on the window for now and moves in the commits that follow.
This commit is contained in:
@@ -14,7 +14,7 @@ use dr_catalog::Catalog;
|
||||
use slint::ComponentHandle;
|
||||
|
||||
use crate::library;
|
||||
use crate::{AppWindow, TimelineBar, View};
|
||||
use crate::{AppWindow, Library, TimelineBar, View};
|
||||
|
||||
use super::controller::LibraryController;
|
||||
use super::filter_bar::{push_people_chips, refilter};
|
||||
@@ -484,8 +484,12 @@ fn scrub_to(window: &AppWindow, ctl: &Rc<LibraryController>, when: i64) {
|
||||
// Move the viewport as well as the window. Cells are drawn at their
|
||||
// absolute place in the library, so loading rows around image 15,000 while
|
||||
// the viewport sits at row 0 shows an empty grid until the user scrolls.
|
||||
window.set_library_scroll_to(position as i32);
|
||||
window.set_library_scroll_token(window.get_library_scroll_token() + 1);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_scroll_to(position as i32);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_scroll_token(window.global::<Library>().get_library_scroll_token() + 1);
|
||||
load_window(window, ctl);
|
||||
}
|
||||
|
||||
@@ -506,7 +510,7 @@ fn scrub_to(window: &AppWindow, ctl: &Rc<LibraryController>, when: i64) {
|
||||
/// delete — after removing one frame from a wall of twenty thousand, the next
|
||||
/// one you want is the one that just moved into its place.
|
||||
pub fn restore_position(window: &AppWindow, ctl: &Rc<LibraryController>) {
|
||||
let total = window.get_library_total().max(0) as usize;
|
||||
let total = window.global::<Library>().get_library_total().max(0) as usize;
|
||||
if total == 0 {
|
||||
return;
|
||||
}
|
||||
@@ -522,8 +526,12 @@ pub fn restore_position(window: &AppWindow, ctl: &Rc<LibraryController>) {
|
||||
// `resume_at` is what the grid last reported as its first visible image,
|
||||
// which is the thing the photographer is actually looking at.
|
||||
let anchor = ctl.resume_at.get().min(total - 1);
|
||||
window.set_library_scroll_to(anchor as i32);
|
||||
window.set_library_scroll_token(window.get_library_scroll_token() + 1);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_scroll_to(anchor as i32);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_scroll_token(window.global::<Library>().get_library_scroll_token() + 1);
|
||||
}
|
||||
|
||||
/// Format a bucket start for the histogram's hover label.
|
||||
@@ -765,7 +773,7 @@ pub(crate) fn apply_place(
|
||||
|
||||
// The filter and the scope have both moved the window to the top; this is
|
||||
// what puts it back, and it has to run after them for that reason.
|
||||
let total = window.get_library_total().max(0) as usize;
|
||||
let total = window.global::<Library>().get_library_total().max(0) as usize;
|
||||
let resolved = resolved.filter(|(at, _)| *at < total);
|
||||
match resolved {
|
||||
Some((at, _)) => {
|
||||
@@ -786,16 +794,18 @@ pub(crate) fn apply_place(
|
||||
if let Some((at, Found::Photograph)) = resolved {
|
||||
if let Some(open) = ctl.open_image.borrow().clone() {
|
||||
window.set_active_view(View::Develop);
|
||||
window.set_library_roll_centre(true);
|
||||
window.global::<Library>().set_library_roll_centre(true);
|
||||
let offset = *ctl.offset.borrow();
|
||||
if let Some(row) = at.checked_sub(offset) {
|
||||
window.set_library_roll_current(row as i32);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_roll_current(row as i32);
|
||||
}
|
||||
open(place.path.clone());
|
||||
// After the open, which resets the readout to "1 of 1" on its
|
||||
// way in — the same ordering `report_position` documents.
|
||||
window.set_index(at as i32);
|
||||
window.set_total(window.get_library_total());
|
||||
window.set_total(window.global::<Library>().get_library_total());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -884,7 +894,9 @@ fn push_filter(window: &AppWindow, ctl: &Rc<LibraryController>) {
|
||||
Some(dr_types::FlagState::Reject) => 2,
|
||||
_ => 0,
|
||||
});
|
||||
window.set_library_local_only(filter.local_only);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_local_only(filter.local_only);
|
||||
ctl.local_only.set(filter.local_only);
|
||||
window.set_library_filter_eyes_open(filter.eyes_open);
|
||||
push_people_chips(window, ctl);
|
||||
@@ -925,7 +937,7 @@ pub(super) fn resume_position(
|
||||
coll: &Rc<crate::collections_ui::CollectionsController>,
|
||||
focus: Option<usize>,
|
||||
) {
|
||||
let total = window.get_library_total().max(0) as usize;
|
||||
let total = window.global::<Library>().get_library_total().max(0) as usize;
|
||||
if total == 0 {
|
||||
// Files named on the command line: there is no grid behind them, and
|
||||
// an ordinal read off the readout would name a row of nothing.
|
||||
@@ -955,12 +967,16 @@ pub(super) fn resume_position(
|
||||
// Before the grid is shown, not after: the markup gates it on an `if`, and
|
||||
// the rebuilt Flickable reads `scroll-to` in its `init`. Setting these
|
||||
// afterwards would leave that init to run against the previous position.
|
||||
window.set_library_scroll_to(anchor as i32);
|
||||
window.set_library_scroll_token(window.get_library_scroll_token() + 1);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_scroll_to(anchor as i32);
|
||||
window
|
||||
.global::<Library>()
|
||||
.set_library_scroll_token(window.global::<Library>().get_library_scroll_token() + 1);
|
||||
|
||||
if let Some(at) = focus {
|
||||
coll.set_cursor(Some(at));
|
||||
window.set_library_cursor(at as i32);
|
||||
window.global::<Library>().set_library_cursor(at as i32);
|
||||
}
|
||||
|
||||
// The view has moved, so the capture-time marker has to move with it.
|
||||
|
||||
Reference in New Issue
Block a user