Skip to content

Commit

Permalink
WIP dialogs
Browse files Browse the repository at this point in the history
  • Loading branch information
woelper committed Feb 8, 2024
1 parent 4e06ca7 commit 9a700ce
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 23 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,22 @@ trash = "3.1"
lutgen = {version ="0.9.0", features = ["lutgen-palettes"]}
libheif-rs = { version = "0.22.0", default-features = false, optional = true}
egui-phosphor = "=0.3.0"
egui-notify = "0.10.0"
egui-notify = "=0.10.0"
ktx2 = "0.3.0"
wgpu = "0.19"
thiserror = "1.0.51"
bitflags = "2.4.1"
flate2 = "1.0.28"
ruzstd = "0.5.0"
basis-universal = "0.3.1"
egui_file = "=0.11.1"

[features]
heif = ["libheif-rs"]
avif_native = ["avif-decode"]
dav1d = ["libavif-image"]
default = ["turbo", "file_open", "avif_native", "update"]
file_open = ["rfd"]
default = ["turbo", "avif_native", "update"]
rfd_dialogs = ["rfd"]
turbo = ["turbojpeg"]
update = ["self_update"]

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Mac

### Cargo Features
If you disable `turbo` (on by default), the turbojpeg library will not be used to open jpeg images. You won't need Nasm to be installed.
The feature `file_open` will enable/disable a file open dialog. This pulls in additional dependencies and is enabled by default.
The feature `rfd_dialogs` will enable/disable a file open dialog. This pulls in additional dependencies and is disabled by default.

### Shortcuts:
`mouse wheel` = zoom
Expand Down
6 changes: 5 additions & 1 deletion src/appstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use crate::{
settings::PersistentSettings,
utils::{ExtendedImageInfo, Frame, Player},
};
use egui_file::FileDialog;
use egui_notify::Toasts;
use image::RgbaImage;
use nalgebra::Vector2;
use notan::{egui::epaint::ahash::HashMap, prelude::Texture, AppState};
use std::{
path::PathBuf,
path::{Path, PathBuf},
sync::mpsc::{self, Receiver, Sender},
};

Expand Down Expand Up @@ -88,6 +89,8 @@ pub struct OculanteState {
pub redraw: bool,
pub first_start: bool,
pub toasts: Toasts,
// pub open_file_dialog: Option<(FileDialog, Box<dyn FnMut(&Path)>)>,
pub open_file_dialog: Option<FileDialog>,
}

impl OculanteState {
Expand Down Expand Up @@ -147,6 +150,7 @@ impl Default for OculanteState {
redraw: Default::default(),
first_start: true,
toasts: Toasts::default().with_anchor(egui_notify::Anchor::BottomLeft),
open_file_dialog: None,
}
}
}
29 changes: 27 additions & 2 deletions src/image_editing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use std::path::{Path, PathBuf};

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

use anyhow::Result;
use egui_file::FileDialog;
use evalexpr::*;
use fast_image_resize as fr;
use image::{imageops, DynamicImage, RgbaImage};
Expand Down Expand Up @@ -187,7 +189,7 @@ impl ImageOperation {
}

// Add functionality about how to draw UI here
pub fn ui(&mut self, ui: &mut Ui) -> Response {
pub fn ui(&mut self, ui: &mut Ui, state: &mut OculanteState) -> Response {
// ui.label_i(&format!("{}", self));
match self {
Self::Brightness(val) => ui.slider_styled(val, -255..=255),
Expand Down Expand Up @@ -259,14 +261,37 @@ impl ImageOperation {
}
});

#[cfg(feature = "file_open")]


if ui
.button("Load from disk")
.on_hover_ui(|ui| {
ui.label("Load Hald CLUT");
})
.clicked()
{
#[cfg(not(feature = "rfd_dialogs"))]
{
let func = Box::new({
move |path: &std::path::Path| {
*lut_name = path.to_string_lossy().to_string();
// let parent = path
// .parent()
// .map(|p| p.to_path_buf())
// .unwrap_or_default();
// ui.ctx()
// .data_mut(|w| w.insert_persisted(Id::new("lutsrc"), parent));
}
});

let mut dialog = FileDialog::open_file(None);
// .show_files_filter(filter)
dialog.open()
;
state.open_file_dialog = Some(dialog);
}

#[cfg(feature = "rfd_dialogs")]
if let Some(lut_file) = rfd::FileDialog::new()
.set_directory(last_folder.unwrap_or_default())
.pick_file()
Expand Down
95 changes: 92 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ fn event(app: &mut App, state: &mut OculanteState, evt: Event) {
}
}
}
#[cfg(feature = "file_open")]

if key_pressed(app, state, Browse) {
state.redraw = true;
browse_for_image_path(state);
Expand Down Expand Up @@ -964,6 +964,18 @@ 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(dialog) = &mut state.open_file_dialog {
if dialog.show(ctx).selected() {
if let Some(file) = dialog.path() {


info!("{:?}", file)
}
}
}

if !state.persistent_settings.zen_mode {
egui::TopBottomPanel::top("menu")
.min_height(30.)
Expand Down Expand Up @@ -1075,10 +1087,22 @@ fn drawe(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut O
}

// Show file browser to select image to load
#[cfg(feature = "file_open")]
#[cfg(feature = "rfd_dialogs")]
fn browse_for_image_path(state: &mut OculanteState) {
let start_directory = state.persistent_settings.last_open_directory.clone();
let uppercase_lowercase_ext = [
utils::SUPPORTED_EXTENSIONS
.into_iter()
.map(|e| e.to_ascii_lowercase())
.collect::<Vec<_>>(),
utils::SUPPORTED_EXTENSIONS
.into_iter()
.map(|e| e.to_ascii_uppercase())
.collect::<Vec<_>>(),
]
.concat();

let load_sender = state.load_channel.0.clone();
let start_directory = state.persistent_settings.last_open_directory.clone();
state.redraw = true;
std::thread::spawn(move || {
let uppercase_lowercase_ext = [
Expand All @@ -1103,6 +1127,71 @@ fn browse_for_image_path(state: &mut OculanteState) {
});
}


// Show file browser to select image to load
#[cfg(not(feature = "rfd_dialogs"))]
fn browse_for_image_path(state: &mut OculanteState) {
let uppercase_lowercase_ext = [
utils::SUPPORTED_EXTENSIONS
.into_iter()
.map(|e| e.to_ascii_lowercase())
.collect::<Vec<_>>(),
utils::SUPPORTED_EXTENSIONS
.into_iter()
.map(|e| e.to_ascii_uppercase())
.collect::<Vec<_>>(),
]
.concat();

let filter = Box::new({
move |path: &std::path::Path| -> bool {
uppercase_lowercase_ext.contains(
&path.extension()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default(),
)
}
});

let load_sender = state.load_channel.0.clone();


// let function = Box::new({
// move |path: &std::path::Path| {
// let _ = load_sender.send(path.to_path_buf());
// }
// });
use egui_file::FileDialog;
let start_directory = state.persistent_settings.last_open_directory.clone();
state.redraw = true;

let mut dialog = FileDialog::open_file(Some(start_directory.clone())).filter(filter);
dialog.open();
state.open_file_dialog = Some(dialog);

// std::thread::spawn(move || {
// let uppercase_lowercase_ext = [
// utils::SUPPORTED_EXTENSIONS
// .into_iter()
// .map(|e| e.to_ascii_lowercase())
// .collect::<Vec<_>>(),
// utils::SUPPORTED_EXTENSIONS
// .into_iter()
// .map(|e| e.to_ascii_uppercase())
// .collect::<Vec<_>>(),
// ]
// .concat();
// let file_dialog_result = rfd::FileDialog::new()
// .add_filter("All Supported Image Types", &uppercase_lowercase_ext)
// .add_filter("All File Types", &["*"])
// .set_directory(start_directory)
// .pick_file();
// if let Some(file_path) = file_dialog_result {
// let _ = load_sender.send(file_path);
// }
// });
}

// Make sure offset is restricted to window size so we don't offset to infinity
fn limit_offset(app: &mut App, state: &mut OculanteState) {
let window_size = app.window().size();
Expand Down
29 changes: 16 additions & 13 deletions src/ui.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#[cfg(feature = "file_open")]
use crate::browse_for_image_path;
use crate::{
appstate::{ImageGeometry, Message, OculanteState},
Expand All @@ -17,6 +16,7 @@ use crate::{

const ICON_SIZE: f32 = 24.;

use egui_file::FileDialog;
use egui_phosphor::regular::*;

use arboard::Clipboard;
Expand Down Expand Up @@ -794,11 +794,12 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
});
ui.end_row();

modifier_stack_ui(&mut state.edit_state.image_op_stack, &mut image_changed, ui);
modifier_stack_ui( &mut image_changed, ui, state);
modifier_stack_ui(
&mut state.edit_state.pixel_op_stack,

&mut pixels_changed,
ui,
state
);

ui.label_i(&format!("{RECYCLE} Reset"));
Expand Down Expand Up @@ -1159,7 +1160,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
}
}

#[cfg(not(feature = "file_open"))]
#[cfg(not(feature = "rfd_dialogs"))]
ui.horizontal(|ui| {
ui.label("File:");
if let Some(p) = &mut state.current_path {
Expand Down Expand Up @@ -1193,7 +1194,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu


if state.current_path.is_none() && state.current_image.is_some() {
#[cfg(not(feature = "file_open"))]
#[cfg(not(feature = "rfd_dialogs"))]
{
if ui.button("Create output file").on_hover_text("This image does not have any file associated with it. Click to create a default one.").clicked() {
let dest = state.persistent_settings.last_open_directory.clone().join("untitled").with_extension(&state.edit_state.export_extension);
Expand All @@ -1203,7 +1204,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
}
}

#[cfg(feature = "file_open")]
#[cfg(feature = "rfd_dialogs")]
if state.current_image.is_some() {
if ui.button(format!("{FLOPPY_DISK} Save as...")).clicked() {

Expand Down Expand Up @@ -1458,12 +1459,12 @@ pub fn stroke_ui(
combined_response
}

fn modifier_stack_ui(stack: &mut Vec<ImageOperation>, image_changed: &mut bool, ui: &mut Ui) {
fn modifier_stack_ui( image_changed: &mut bool, ui: &mut Ui, state: &mut OculanteState) {
let mut delete: Option<usize> = None;
let mut swap: Option<(usize, usize)> = None;

// egui::Grid::new("dfdfd").num_columns(2).show(ui, |ui| {
for (i, operation) in stack.iter_mut().enumerate() {
for (i, operation) in state.edit_state.image_op_stack.iter_mut().enumerate() {
ui.label_i(&format!("{operation}"));

// let op draw itself and check for response
Expand All @@ -1472,7 +1473,7 @@ fn modifier_stack_ui(stack: &mut Vec<ImageOperation>, image_changed: &mut bool,
// ui.end_row();

// draw the image operator
if operation.ui(ui).changed() {
if operation.ui(ui, state).changed() {
*image_changed = true;
}

Expand Down Expand Up @@ -1531,12 +1532,12 @@ fn modifier_stack_ui(stack: &mut Vec<ImageOperation>, image_changed: &mut bool,
// });

if let Some(delete) = delete {
stack.remove(delete);
state.edit_state.image_op_stack.remove(delete);
}

if let Some(swap) = swap {
if swap.1 < stack.len() {
stack.swap(swap.0, swap.1);
if swap.1 < state.edit_state.image_op_stack.len() {
state.edit_state.image_op_stack.swap(swap.0, swap.1);
}
}
}
Expand Down Expand Up @@ -1789,14 +1790,16 @@ 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)
}



let mut changed_channels = false;

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

0 comments on commit 9a700ce

Please sign in to comment.