feat: proof of concept

This commit is contained in:
electria 2026-08-04 08:31:02 -07:00
commit 25b5c413c1
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs
4 changed files with 154 additions and 15 deletions

View file

@ -1,26 +1,88 @@
use std::{
borrow::Cow,
collections::HashMap,
env,
path::{Path, PathBuf},
};
use iced::{Color, Element, Renderer, Task, Theme, application, theme, widget};
use ignore::{WalkBuilder, types::TypesBuilder};
use image::{DynamicImage, EncodableLayout, RgbaImage};
use rayon::iter::{ParallelBridge, ParallelIterator};
use crate::SUPPORTED_TYPES;
enum Message {}
#[derive(Default)]
enum Mode {
Focused(usize),
Focused(PathBuf),
#[default]
Gallery,
}
#[derive(Default)]
struct State {
mode: Mode,
images: HashMap<PathBuf, Option<(RgbaImage, widget::image::Handle)>>,
}
impl State {
fn new() -> Self {
let mut builder = TypesBuilder::new();
builder.add_defaults();
for ext in SUPPORTED_TYPES {
builder.add("supportedImages", ext).unwrap();
}
builder.select("supportedImages");
Self {
mode: Mode::Gallery,
images: WalkBuilder::new(
env::args()
.nth(1)
.map(Cow::Owned)
.unwrap_or(Cow::Borrowed("./"))
.as_ref(),
)
.types(builder.build().unwrap())
.max_depth(Some(1))
.build()
.par_bridge()
.filter_map(|r| {
r.inspect_err(|e| eprintln!("{e}"))
.ok()
.map(|entry| entry.into_path())
})
.filter(|path| path.is_file())
.map(|path| {
let image = image::open(&path)
.inspect_err(|e| eprintln!("{e}"))
.ok()
.map(DynamicImage::into_rgba8);
let handle = image.as_ref().map(|image| {
widget::image::Handle::from_rgba(image.width(), image.height(), unsafe {
std::mem::transmute::<&[u8], &'static [u8]>(image.as_bytes())
})
});
(path, image.map(|image| (image, handle.unwrap())))
})
.collect(),
}
}
fn update(&mut self, message: Message) -> Task<Message> {
Task::none()
}
fn view(&self) -> Element<'_, Message, Theme, Renderer> {
widget::text("hiiiiiii").into()
widget::scrollable(widget::column(
self.images
.iter()
.filter_map(|(_k, v)| v.as_ref())
.map(|(_image, handle)| {
dbg!();
widget::image(handle).into()
}),
))
.into()
}
}

View file

@ -1,5 +1,13 @@
mod app;
const SUPPORTED_TYPES: &[&str; 20] = &[
"*.png", "*.PNG", "*.jpg", "*.JPG", "*.jpeg", "*.JPEG", "*.avif", "*.jxl", "*.bmp", "*.exr",
"*.ff", "*.gif", "*.hdr", "*.ico", "*.pnm", "*.qoi", "*.tga", "*.tiff", "*.webp", "*.kra",
];
fn main() -> Result<(), impl std::error::Error> {
jxl_oxide::integration::register_image_decoding_hook();
kra_image_integration::register();
app::run()
}