feat: pick folder dialog
This commit is contained in:
parent
0c8149bd53
commit
d6549939a8
2 changed files with 65 additions and 30 deletions
|
|
@ -32,6 +32,8 @@
|
||||||
libxcb
|
libxcb
|
||||||
]
|
]
|
||||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||||
|
dbus.lib
|
||||||
|
|
||||||
vulkan-loader
|
vulkan-loader
|
||||||
wayland
|
wayland
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,10 @@
|
||||||
use std::{borrow::Cow, collections::BTreeMap, env, path::PathBuf, process};
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
collections::BTreeMap,
|
||||||
|
env,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process,
|
||||||
|
};
|
||||||
|
|
||||||
use iced::{
|
use iced::{
|
||||||
Color, Element, Event, Length, Renderer, Subscription, Task, Theme, application, event,
|
Color, Element, Event, Length, Renderer, Subscription, Task, Theme, application, event,
|
||||||
|
|
@ -6,6 +12,7 @@ use iced::{
|
||||||
};
|
};
|
||||||
use ignore::{WalkBuilder, types::TypesBuilder};
|
use ignore::{WalkBuilder, types::TypesBuilder};
|
||||||
use rayon::iter::{ParallelBridge, ParallelIterator};
|
use rayon::iter::{ParallelBridge, ParallelIterator};
|
||||||
|
use rfd::AsyncFileDialog;
|
||||||
|
|
||||||
use crate::SUPPORTED_TYPES;
|
use crate::SUPPORTED_TYPES;
|
||||||
|
|
||||||
|
|
@ -16,6 +23,8 @@ enum Message {
|
||||||
|
|
||||||
OpenImage(PathBuf),
|
OpenImage(PathBuf),
|
||||||
|
|
||||||
|
OpenPath(Option<PathBuf>),
|
||||||
|
|
||||||
KeyPressed(keyboard::Key, keyboard::Modifiers),
|
KeyPressed(keyboard::Key, keyboard::Modifiers),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,37 +38,20 @@ struct State {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn new() -> Self {
|
fn new() -> (Self, Task<Message>) {
|
||||||
let mut builder = TypesBuilder::new();
|
(
|
||||||
builder.add_defaults();
|
|
||||||
for ext in SUPPORTED_TYPES {
|
|
||||||
builder.add("supportedImages", ext).unwrap();
|
|
||||||
}
|
|
||||||
builder.select("supportedImages");
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
columns: 3,
|
columns: 3,
|
||||||
error: None,
|
error: None,
|
||||||
images: WalkBuilder::new(
|
images: BTreeMap::new(),
|
||||||
|
},
|
||||||
|
Task::done(Message::OpenPath(Some(
|
||||||
env::args()
|
env::args()
|
||||||
.nth(1)
|
.nth(1)
|
||||||
.map(Cow::Owned)
|
.unwrap_or_else(|| String::from("./"))
|
||||||
.unwrap_or(Cow::Borrowed("./"))
|
.into(),
|
||||||
.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| (path, None))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn update(&mut self, message: Message) -> Task<Message> {
|
fn update(&mut self, message: Message) -> Task<Message> {
|
||||||
match message {
|
match message {
|
||||||
|
|
@ -80,6 +72,17 @@ impl State {
|
||||||
.err()
|
.err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::OpenPath(opt_path) => {
|
||||||
|
self.error = match opt_path {
|
||||||
|
Some(_) => None,
|
||||||
|
None => Some("no path to open given".into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(path) = opt_path {
|
||||||
|
self.open_path(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message::KeyPressed(key, modifiers) => match key.as_ref() {
|
Message::KeyPressed(key, modifiers) => match key.as_ref() {
|
||||||
// input field cycling
|
// input field cycling
|
||||||
keyboard::Key::Named(keyboard::key::Named::Tab) => {
|
keyboard::Key::Named(keyboard::key::Named::Tab) => {
|
||||||
|
|
@ -90,6 +93,13 @@ impl State {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keyboard::Key::Character("o") => {
|
||||||
|
return Task::perform(
|
||||||
|
async { AsyncFileDialog::new().pick_folder().await.map(Into::into) },
|
||||||
|
Message::OpenPath,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
keyboard::Key::Character("=" | "+") => {
|
keyboard::Key::Character("=" | "+") => {
|
||||||
self.columns = (self.columns + 1).clamp(1, 10)
|
self.columns = (self.columns + 1).clamp(1, 10)
|
||||||
}
|
}
|
||||||
|
|
@ -157,6 +167,29 @@ impl State {
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn open_path(&mut self, path: impl AsRef<Path>) {
|
||||||
|
let mut builder = TypesBuilder::new();
|
||||||
|
builder.add_defaults();
|
||||||
|
for ext in SUPPORTED_TYPES {
|
||||||
|
builder.add("supportedImages", ext).unwrap();
|
||||||
|
}
|
||||||
|
builder.select("supportedImages");
|
||||||
|
|
||||||
|
self.images = WalkBuilder::new(path)
|
||||||
|
.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| (path, None))
|
||||||
|
.collect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run() -> Result<(), impl std::error::Error> {
|
pub fn run() -> Result<(), impl std::error::Error> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue