mq_edit/renderer/
image_manager.rs1use image::DynamicImage;
2use std::cell::RefCell;
3use std::collections::HashMap;
4use std::path::{Path, PathBuf};
5
6pub struct ImageManager {
8 cache: RefCell<HashMap<PathBuf, DynamicImage>>,
10 base_path: Option<PathBuf>,
12}
13
14impl ImageManager {
15 pub fn new() -> Self {
16 Self {
17 cache: RefCell::new(HashMap::new()),
18 base_path: None,
19 }
20 }
21
22 pub fn set_base_path(&mut self, path: PathBuf) {
24 self.base_path = Some(path);
25 }
26
27 fn load_image(&self, path: &str) -> Result<DynamicImage, String> {
29 let resolved_path = self.resolve_path(path)?;
30
31 let mut cache = self.cache.borrow_mut();
33 if !cache.contains_key(&resolved_path) {
34 let img =
36 image::open(&resolved_path).map_err(|e| format!("Failed to load image: {}", e))?;
37 cache.insert(resolved_path.clone(), img);
38 }
39
40 cache
41 .get(&resolved_path)
42 .cloned()
43 .ok_or_else(|| "Image not found in cache".to_string())
44 }
45
46 fn resolve_path(&self, path: &str) -> Result<PathBuf, String> {
48 let path = Path::new(path);
49
50 if path.is_absolute() {
52 return Ok(path.to_path_buf());
53 }
54
55 if let Some(base) = &self.base_path {
57 let mut resolved = base.clone();
58 resolved.pop(); resolved.push(path);
60 Ok(resolved)
61 } else {
62 std::env::current_dir()
64 .map(|cwd| cwd.join(path))
65 .map_err(|e| format!("Failed to get current directory: {}", e))
66 }
67 }
68
69 pub fn can_load_image(&self, path: &str) -> bool {
71 self.load_image(path).is_ok()
72 }
73
74 pub fn clear_cache(&self) {
76 self.cache.borrow_mut().clear();
77 }
78
79 pub fn get_dimensions(&self, path: &str) -> Result<(u32, u32), String> {
81 let img = self.load_image(path)?;
82 Ok((img.width(), img.height()))
83 }
84}
85
86impl Default for ImageManager {
87 fn default() -> Self {
88 Self::new()
89 }
90}