mimick/library/masonry/
load.rs1use gdk4::Texture;
10use gtk::prelude::*;
11
12use crate::api_client::ThumbnailSize;
13use crate::library::asset_model::LibraryAssetModel;
14use crate::library::asset_object::AssetObject;
15use crate::library::masonry::quality::fallback_bucket;
16use crate::library::thumbnail_cache::ThumbnailCache;
17
18pub(crate) fn collect_dims(model: &LibraryAssetModel) -> Vec<(u32, u32)> {
19 let n = model.n_items();
20 let mut out = Vec::with_capacity(n as usize);
21 for i in 0..n {
22 if let Some(obj) = model.item(i).and_downcast::<AssetObject>() {
23 out.push((obj.property::<u32>("width"), obj.property::<u32>("height")));
24 } else {
25 out.push((0, 0));
26 }
27 }
28 out
29}
30
31pub(crate) async fn load_with_fallback<F: Fn() -> bool>(
34 cache: &ThumbnailCache,
35 asset_id: &str,
36 requested: ThumbnailSize,
37 is_cancelled: &F,
38) -> Result<Texture, String> {
39 let mut current = requested;
40 loop {
41 match cache
42 .load_thumbnail_cancellable(asset_id, current, is_cancelled)
43 .await
44 {
45 Ok(tex) => return Ok(tex),
46 Err(e) if e.contains("404") => match fallback_bucket(current) {
47 Some(next) => {
48 log::debug!(
49 "masonry fallback id={} {:?} -> {:?} ({})",
50 asset_id,
51 current,
52 next,
53 e
54 );
55 current = next;
56 }
57 None => return Err(e),
58 },
59 Err(e) => return Err(e),
60 }
61 }
62}
63
64pub(crate) fn propagate_dimensions(
66 model: &LibraryAssetModel,
67 asset_id: &str,
68 tex: &Texture,
69) -> bool {
70 let n = model.n_items();
71 for i in 0..n {
72 if let Some(obj) = model.item(i).and_downcast::<AssetObject>()
73 && obj.property::<String>("id") == asset_id
74 {
75 let w = obj.property::<u32>("width");
76 let h = obj.property::<u32>("height");
77 if w == 0 || h == 0 {
78 obj.set_property("width", tex.width() as u32);
79 obj.set_property("height", tex.height() as u32);
80 return true;
81 }
82 return false;
83 }
84 }
85 false
86}