feat: clickable images

This commit is contained in:
electria 2026-08-04 16:08:26 -07:00
commit b4d155808b
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs

View file

@ -1,4 +1,4 @@
use std::{borrow::Cow, collections::HashMap, env, path::PathBuf};
use std::{borrow::Cow, collections::HashMap, env, path::PathBuf, process};
use iced::{Color, Element, Renderer, Task, Theme, application, theme, widget};
use ignore::{WalkBuilder, types::TypesBuilder};
@ -10,18 +10,15 @@ use crate::SUPPORTED_TYPES;
enum Message {
LoadImage(PathBuf),
UnloadImage(PathBuf),
OpenImage(PathBuf),
}
#[derive(Default)]
enum Mode {
Focused(PathBuf),
#[default]
Gallery,
}
#[derive(Default)]
struct State {
mode: Mode,
images: HashMap<PathBuf, Option<widget::image::Handle>>,
error: Option<String>,
}
impl State {
@ -34,7 +31,7 @@ impl State {
builder.select("supportedImages");
Self {
mode: Mode::Gallery,
error: None,
images: WalkBuilder::new(
env::args()
.nth(1)
@ -66,6 +63,14 @@ impl State {
Message::UnloadImage(path) => {
self.images.entry(path).and_modify(|e| *e = None);
}
Message::OpenImage(path) => {
self.error = process::Command::new("xdg-open")
.arg(path)
.spawn()
.map_err(|e| e.to_string())
.err()
}
}
Task::none()
@ -73,12 +78,15 @@ impl State {
fn view(&self) -> Element<'_, Message, Theme, Renderer> {
widget::scrollable(
widget::grid(self.images.iter().map(|(path, opt_handle)| {
widget::sensor(opt_handle.as_ref().map_or_else(
|| Element::from(widget::space()),
|handle| widget::image(handle).into(),
))
.on_show(|_size| Message::LoadImage(path.clone()))
.on_hide(Message::UnloadImage(path.clone()))
widget::mouse_area(
widget::sensor(opt_handle.as_ref().map_or_else(
|| Element::from(widget::space()),
|handle| widget::image(handle).into(),
))
.on_show(|_size| Message::LoadImage(path.clone()))
.on_hide(Message::UnloadImage(path.clone())),
)
.on_press(Message::OpenImage(path.clone()))
.into()
}))
.fluid(500)