Skip to content

Commit

Permalink
feat: Use custom filebrowser instead of rfd
Browse files Browse the repository at this point in the history
  • Loading branch information
woelper committed Feb 9, 2024
1 parent 4e06ca7 commit de581a9
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ basis-universal = "0.3.1"
heif = ["libheif-rs"]
avif_native = ["avif-decode"]
dav1d = ["libavif-image"]
default = ["turbo", "file_open", "avif_native", "update"]
default = ["turbo", "avif_native", "update"]
file_open = ["rfd"]
turbo = ["turbojpeg"]
update = ["self_update"]
Expand Down
2 changes: 2 additions & 0 deletions src/appstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub struct OculanteState {
pub redraw: bool,
pub first_start: bool,
pub toasts: Toasts,
pub filebrowser_id: Option<String>
}

impl OculanteState {
Expand Down Expand Up @@ -147,6 +148,7 @@ impl Default for OculanteState {
redraw: Default::default(),
first_start: true,
toasts: Toasts::default().with_anchor(egui_notify::Anchor::BottomLeft),
filebrowser_id: None,
}
}
}
179 changes: 179 additions & 0 deletions src/filebrowser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
use super::utils::SUPPORTED_EXTENSIONS;
use anyhow::{Context, Result};
use dirs;
use egui_phosphor::variants::regular::*;
use notan::egui::{self, *};
use std::io::Write;

use std::{
fs::{self, read_to_string, File},
path::{Path, PathBuf},
};

fn load_recent_dir() -> Result<PathBuf> {
Ok(PathBuf::from(read_to_string(
dirs::cache_dir()
.context("Can't get temp dir")?
.join(".efd_history"),
)?))
}

fn save_recent_dir(p: &Path) -> Result<()> {
let p = if p.is_file() {
p.parent().context("Can't get parent")?.to_path_buf()
} else {
p.to_path_buf()
};

let mut f = File::create(
dirs::cache_dir()
.context("Can't get temp dir")?
.join(".efd_history"),
)?;
write!(f, "{}", p.to_string_lossy())?;
Ok(())
}

pub fn browse<F: FnMut(Option<&PathBuf>)>(save: bool, mut callback: F, ctx: &egui::Context) {
let mut path = ctx
.data(|r| r.get_temp::<PathBuf>(Id::new("FBPATH")))
.unwrap_or(load_recent_dir().unwrap_or_default());

let mut open = true;

egui::Window::new("Browse")
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
.collapsible(false)
.open(&mut open)
.resizable(true)
.default_width(500.)
.default_height(600.)
// .auto_sized()
.show(ctx, |ui| {
let d = fs::read_dir(&path).ok();
ui.horizontal(|ui| {
ui.allocate_ui_with_layout(
Vec2::new(120., ui.available_height()),
Layout::top_down_justified(Align::LEFT),
|ui| {
if let Some(d) = dirs::desktop_dir() {
if ui.button(format!("{DESKTOP} Desktop")).clicked() {
path = d;
}
}
if let Some(d) = dirs::home_dir() {
if ui.button(format!("{HOUSE} Home")).clicked() {
path = d;
}
}
if let Some(d) = dirs::document_dir() {
if ui.button(format!("{FILE} Documents")).clicked() {
path = d;
}
}
if let Some(d) = dirs::download_dir() {
if ui.button(format!("{DOWNLOAD} Downloads")).clicked() {
path = d;
}
}
if let Some(d) = dirs::picture_dir() {
if ui.button(format!("{IMAGES} Pictures")).clicked() {
path = d;
}
}
},
);

ui.vertical(|ui| {
if ui.button(ARROW_BEND_LEFT_UP).clicked() {
if let Some(d) = path.parent() {
let p = d.to_path_buf();
path = p;
}
}

egui::ScrollArea::new([false, true])
// .max_width(500.)
.min_scrolled_height(500.)
.auto_shrink([true, false])
.show(ui, |ui| match d {
Some(contents) => {
egui::Grid::new("browser")
.striped(true)
.num_columns(0)
.min_col_width(ui.available_width())
.show(ui, |ui| {
for de in contents
.into_iter()
.flat_map(|x| x)
.filter(|de| {
!de.file_name().to_string_lossy().starts_with(".")
})
.filter(|de| {
de.path().is_dir()
|| SUPPORTED_EXTENSIONS.contains(
&de.path()
.extension()
.map(|ext| {
ext.to_string_lossy().to_string()
})
.unwrap_or_default()
.to_lowercase()
.as_str(),
)
})
{
if de.path().is_dir() {
if ui
.add(
egui::Button::new(format!(
"{FOLDER} {}",
de.file_name()
.to_string_lossy()
.chars()
.take(50)
.collect::<String>()
))
.frame(false),
)
.clicked()
{
path = de.path();
}
} else {
if ui
.add(
egui::Button::new(format!(
"{IMAGE_SQUARE} {}",
de.file_name()
.to_string_lossy()
.chars()
.take(50)
.collect::<String>()
))
.frame(false),
)
.clicked()
{
_ = save_recent_dir(&de.path());
callback(Some(&de.path()));
// self.result = Some(de.path().to_path_buf());
}
}
ui.end_row();
}
});
}
None => {
ui.label("no contents");
}
});
});
});

ctx.data_mut(|w| w.insert_temp(Id::new("FBPATH"), path));
});
if !open {
ctx.memory_mut(|w| w.close_popup());
}
}
23 changes: 23 additions & 0 deletions src/image_editing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fmt;
use std::num::NonZeroU32;
use std::path::{Path, PathBuf};

use crate::filebrowser;
use crate::paint::PaintStroke;
use crate::ui::EguiExt;

Expand Down Expand Up @@ -259,6 +260,27 @@ impl ImageOperation {
}
});

#[cfg(not(feature = "file_open"))]
{
if ui.button("Load lut").clicked() {
ui.ctx().memory_mut(|w| w.open_popup(Id::new("LUT")));
}

if ui.ctx().memory(|w| w.is_popup_open(Id::new("LUT"))) {
filebrowser::browse(
false,
|p| {
if let Some(p) = p {
*lut_name = p.to_string_lossy().to_string();
}
ui.ctx().memory_mut(|w| w.close_popup());
x.mark_changed();
},
ui.ctx(),
);
}
}

#[cfg(feature = "file_open")]
if ui
.button("Load from disk")
Expand All @@ -281,6 +303,7 @@ impl ImageOperation {
}
x.mark_changed();
}

ui.label("Find more LUTs here:");

ui.hyperlink_to(
Expand Down
29 changes: 27 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use utils::*;
mod appstate;
mod image_loader;
use appstate::*;
mod filebrowser;

pub mod ktx2_loader;
// mod events;
Expand Down Expand Up @@ -418,11 +419,16 @@ fn event(app: &mut App, state: &mut OculanteState, evt: Event) {
}
}
}
#[cfg(feature = "file_open")]
if key_pressed(app, state, Browse) {
state.redraw = true;
#[cfg(feature = "file_open")]
browse_for_image_path(state);
#[cfg(not(feature = "file_open"))]
{
state.filebrowser_id = Some("OPEN_SHORTCUT".into());
}
}

if key_pressed(app, state, NextImage) {
if state.is_loaded {
next_image(state)
Expand Down Expand Up @@ -712,7 +718,7 @@ fn drawe(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut O
if let Ok(p) = state.load_channel.1.try_recv() {
state.is_loaded = false;
state.current_image = None;
state.player.load(&p, state.message_channel.0.clone());
state.player.load(&p, state.message_channel.0.clone());
if let Some(dir) = p.parent() {
state.persistent_settings.last_open_directory = dir.to_path_buf();
}
Expand Down Expand Up @@ -964,6 +970,25 @@ fn drawe(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut O
// ctx.request_repaint_after(Duration::from_secs(1));
state.toasts.show(ctx);

if let Some(id) = state.filebrowser_id.take() {
ctx.memory_mut(|w| w.open_popup(Id::new(id)));
}
#[cfg(not(feature = "file_open"))]
{
if ctx.memory(|w| w.is_popup_open(Id::new("OPEN_SHORTCUT"))) {
filebrowser::browse(
false,
|p| {
if let Some(p) = p {
let _ = state.load_channel.0.clone().send(p.to_path_buf());
}
ctx.memory_mut(|w| w.close_popup());
},
ctx,
);
}
}

if !state.persistent_settings.zen_mode {
egui::TopBottomPanel::top("menu")
.min_height(30.)
Expand Down
27 changes: 23 additions & 4 deletions src/ui.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#[cfg(feature = "file_open")]
use crate::browse_for_image_path;
use crate::{filebrowser};
use crate::{
appstate::{ImageGeometry, Message, OculanteState},
image_editing::{process_pixels, Channel, GradientStop, ImageOperation, ScaleFilter},
Expand Down Expand Up @@ -1789,14 +1788,34 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu

// ui.label("Channels");

#[cfg(feature = "file_open")]

if unframed_button(FOLDER, ui)
.on_hover_text("Browse for image")
.clicked()
{
browse_for_image_path(state)
#[cfg(feature = "file_open")]
crate::browse_for_image_path(state);
#[cfg(not(feature = "file_open"))]
ui.ctx().memory_mut(|w| w.open_popup(Id::new("OPEN")));
}

#[cfg(not(feature = "file_open"))]
{
if ui.ctx().memory(|w| w.is_popup_open(Id::new("OPEN"))) {
filebrowser::browse(
false,
|p| {
if let Some(p) = p {
let _ = state.load_channel.0.clone().send(p.to_path_buf());
}
ui.ctx().memory_mut(|w| w.close_popup());
},
ui.ctx(),
);
}
}


let mut changed_channels = false;

if key_pressed(app, state, RedChannel) {
Expand Down

0 comments on commit de581a9

Please sign in to comment.