Skip to content

Commit

Permalink
Implemented better filters for file browser
Browse files Browse the repository at this point in the history
File browser now accepts a predicate for running on paths to determine
if it should be shown or not.
  • Loading branch information
purrie committed Mar 10, 2023
1 parent ff1d468 commit 5dcc724
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 17 deletions.
2 changes: 1 addition & 1 deletion ROADMAP.org
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This document contains ideas and goals for the project as well as description of
- Pentagonal frames
- Hexagonal frames
- Turned hexagonal frames
- Octagonal frames

*** Round Thin
Most thin frames won't be very visible so they don't need anything elaborate on the frame itself.

Expand Down
16 changes: 14 additions & 2 deletions src/token_maker.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashSet;
use std::path::PathBuf;
use std::sync::Arc;

use iced::widget::{
Expand Down Expand Up @@ -161,7 +162,7 @@ impl Application for TokenMaker {
match message {
Message::LookForImage => {
self.operation = Mode::FileBrowser(BrowsingFor::Token);
self.data.file.set_target(Target::Filtered("png".into()));
self.data.file.set_filter(image_filter);
self.data.file.refresh_path().unwrap();
Command::none()
}
Expand Down Expand Up @@ -221,7 +222,7 @@ impl Application for TokenMaker {

Message::LookForFrame => {
self.operation = Mode::FileBrowser(BrowsingFor::Frame);
self.data.file.set_target(Target::Filtered("png".into()));
self.data.file.set_filter(image_filter);
self.data.file.refresh_path().unwrap();
Command::none()
}
Expand Down Expand Up @@ -716,3 +717,14 @@ impl PersistentKey for PersistentData {
}
}
}

fn image_filter(path: &PathBuf) -> bool {
let Some(ext) = path.extension().and_then(|x| Some(x.to_string_lossy().to_lowercase())) else {
return false;
};

match ext.as_str() {
"png" | "webp" | "jpg" | "jpeg" => true,
_ => false,
}
}
37 changes: 23 additions & 14 deletions src/widgets/file_browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ pub enum BrowsingResult {
pub enum Target {
#[default]
File,
Filtered(String),
Filtered(Box<dyn Fn(&PathBuf) -> bool>),
Directory,
}

#[allow(unused)]
impl Browser {
/// Creates a browser and sets its current directory to supplied path
pub fn new<P: Into<PathBuf>>(path: P) -> Self {
Self {
path: path.into(),
Expand All @@ -45,6 +46,8 @@ impl Browser {
target: Target::File,
}
}

/// Creates a browser and sets browser path to home directory
pub fn start_at_home() -> Self {
let path = dirs::home_dir().unwrap();
Self {
Expand All @@ -54,25 +57,37 @@ impl Browser {
target: Target::File,
}
}

/// Sets current path for the browser
pub fn set_path<P: Into<PathBuf>>(&mut self, path: P) {
self.path = path.into()
}

/// Peeks current path of the browser
pub fn get_path(&self) -> &PathBuf {
&self.path
}

/// Sets target to file with supplied filter function
pub fn set_filter<F: Fn(&PathBuf) -> bool + 'static>(&mut self, filter: F) {
self.target = Target::Filtered(Box::new(filter));
}

/// Sets target to filter out specific results in the browser
pub fn set_target(&mut self, target: Target) {
self.target = target;
}

/// Updates browser cache with files and directories from current path
pub fn refresh_path(&mut self) -> Result<(), std::io::Error> {
self.dir.clear();
let dir = std::fs::read_dir(&self.path)?;
for f in dir {
if let Ok(f) = f {
let path = f.path();
match &self.target {
Target::Filtered(f) if !is_filter_match(&f, &path) && path.is_file() => {
continue
}
// skipping files the filter deems unwanted
Target::Filtered(f) if path.is_file() && f(&path) == false => continue,
Target::Directory if path.is_file() => continue,
_ => self.dir.push(path),
}
Expand All @@ -81,6 +96,7 @@ impl Browser {

Ok(())
}

pub fn update(&mut self, message: BrowserOperation) -> Result<BrowsingResult, std::io::Error> {
match message {
BrowserOperation::MoveUp => {
Expand Down Expand Up @@ -162,7 +178,7 @@ impl Browser {
(Target::File, Some(p)) if p.is_file() => {
button("Accept").on_press(BrowserOperation::Accept)
}
(Target::Filtered(filter), Some(p)) if is_filter_match(&filter, &p) => {
(Target::Filtered(filter), Some(p)) if filter(&p) => {
button("Accept").on_press(BrowserOperation::Accept)
}
(Target::Directory, _) => button("Accept").on_press(BrowserOperation::Accept),
Expand All @@ -172,13 +188,12 @@ impl Browser {
let ui = col![
row![
button("Cancel").on_press(BrowserOperation::Cancel),
text("|"),
move_up,
text("|"),
text(format!("Directory: {}", self.path.to_string_lossy())),
horizontal_space(Length::Fill),
accept
]
.spacing(10)
.height(Length::Shrink)
.width(Length::Fill),
scrollable(file_list).height(Length::Fill),
Expand All @@ -188,14 +203,8 @@ impl Browser {

container(ui)
}

pub fn view(&self) -> Element<BrowserOperation, Renderer> {
self.view_raw().into()
}
}

fn is_filter_match(filter: &str, path: &PathBuf) -> bool {
path.extension()
.and_then(|x| x.to_str())
.and_then(|x| if x == filter { Some(()) } else { None })
.is_some()
}

0 comments on commit 5dcc724

Please sign in to comment.