Skip to main content

mimick/library/masonry/
grid_view.rs

1//! Photos grid construction. Builds a `MasonryCanvas` inside a
2//! `ScrolledWindow`, returns it alongside the shared model + selection.
3
4use std::cell::{Cell, RefCell};
5use std::rc::Rc;
6use std::sync::Arc;
7
8use gtk::prelude::*;
9
10use super::canvas::{GridQuality, MasonryCanvas};
11use crate::app_context::AppContext;
12use crate::library::asset_model::LibraryAssetModel;
13
14pub type AssetContextMenuHandler = Rc<RefCell<Option<Box<dyn Fn(u32, f64, f64)>>>>;
15
16pub struct GridViewParts {
17    pub model: LibraryAssetModel,
18    pub scrolled: gtk::ScrolledWindow,
19    pub canvas: MasonryCanvas,
20    pub selection: gtk::MultiSelection,
21    pub context_menu_handler: AssetContextMenuHandler,
22}
23
24pub fn build_grid_view(
25    ctx: Arc<AppContext>,
26    select_toggle: gtk::ToggleButton,
27    narrow: Rc<Cell<bool>>,
28) -> GridViewParts {
29    let model = LibraryAssetModel::new();
30    let selection = gtk::MultiSelection::new(Some(model.clone()));
31    let context_menu_handler: AssetContextMenuHandler = Rc::new(RefCell::new(None));
32
33    let canvas = MasonryCanvas::new(
34        ctx.thumbnail_cache.clone(),
35        model.clone(),
36        selection.clone(),
37    );
38    canvas.set_narrow(narrow.get());
39    canvas.set_select_mode(select_toggle.is_active());
40    canvas.set_context_menu_handler(context_menu_handler.clone());
41    let initial_quality = GridQuality::parse(&ctx.config.read().data.library_grid_quality);
42    canvas.set_quality(initial_quality);
43    canvas.set_border_gap(ctx.config.read().data.grid_border_width);
44    if let Ok(color) = ctx
45        .config
46        .read()
47        .data
48        .grid_border_color
49        .parse::<gdk4::RGBA>()
50    {
51        canvas.set_border_color(color);
52    }
53    canvas.install_drag_source(ctx.clone());
54
55    {
56        let canvas = canvas.clone();
57        select_toggle.connect_toggled(move |toggle| {
58            canvas.set_select_mode(toggle.is_active());
59        });
60    }
61    {
62        let canvas = canvas.clone();
63        let toggle = select_toggle.clone();
64        canvas.set_select_mode_changer(move |on| {
65            if toggle.is_active() != on {
66                toggle.set_active(on);
67            }
68        });
69    }
70
71    let scrolled = gtk::ScrolledWindow::builder()
72        .child(&canvas)
73        .hscrollbar_policy(gtk::PolicyType::Never)
74        .vexpand(true)
75        .hexpand(true)
76        .build();
77
78    GridViewParts {
79        model,
80        scrolled,
81        canvas,
82        selection,
83        context_menu_handler,
84    }
85}