Skip to content

Commit

Permalink
Release v0.6.0 (#137)
Browse files Browse the repository at this point in the history
* Fix path edit size and focus (#102)

* Fix path edit size

* Fix path edit focus when pressing checkmark

* Update CHANGELOG.md

* Ability to pin folders to the left sidebar (#100)

* Add show_pinned_folders option

* Implement pin and unpin option

* Update CHANGELOG.md

* Deprecate FileDialog::overwrite_config (#103)

* Deprecate FileDialog::overwrite_config

* Update CHANGELOG.md

* Implement persistent storage (#104)

* Add serde dependency

* Implement serialize and deserialize for FileDialogStorage

* Add feature persistence

* Update CHANGELOG.md

* Move storage to config and add builder methods (#105)

* Move storage to config, add builder methods

* Update CHANGELOG.md

* Add option to overwrite a file (#106)


* Implement modal actions

* Finish modal UI

* Add option to allow overwriting a file

* Update CHANGELOG.md

* Persistence example (#107)

* Add example

* Update CHANGELOG.md

* Restructure config module (#109)

* Restructure config module

* Update CHANGELOG.md

* Fix new 1.78 clippy errors

* Keyboard navigation (#110)

* Implement keybindings

* Improve reset method

* Set cursor to end of text fields

* Update changelog

* Move FileDialogStorage to config module

* Fix submit not working when saving a file

* Hidden files and folders (#111)

* Implement show hidden files and folders option

* Implement config options

* Update changelog

* Implement keep focus option (#112)

* Implement keep focus option

* Update changelog.md

* Improve navigation (#113)

* Close path edit on submit

* Exec selection keybinding if any widget is focused

* Select first item when updating search value

* Submit dialog when exiting search using enter

* Update changelog

* Improve submit and cancel keybindings

* Submit directory when no other item is selected

* Rename persistence feature to serde (#114)

* Document breaking changes in changelog (#115)

* Implement modal option (#118)

* Implement modal

* Update changelog

* Make DirectoryEntry publicly reachable (#119)

* Update changelog (#120)

* Fix modal (#121)

* Remove keep_focus option

* Fix modal

* Implement file filters (#124)

* Implement file filters

* Update changelog

* Home directory shortcut (#125)

* Cleanup edit_search_on_text_input

* Implement home_edit_path keybinding

* Fix clippy error

* Implement multi selection (#127)

* Implement multi selection

* Update changelog

* Implement keybinding select_all

* Improve ID handling (#128)

* Improve ID handling

* Update changelog

* Add multi_selection example (#129)

* Add multi_selection example

* Update changelog

* File Dialog doesnt implement the Send Bound (#131)

* modified FileDialog to be Send

* Update changelog (#132)

* Update to egui 0.28 (#133)

* Update to egui 0.28

* Also update dependencies

Use workspace dependencies to make updating easier

* Ok-wrap the App struct in the examples

The new API expects a Result

* Add serde and ron features to sandbox example

* Add eframe persistence feature (#134)

* Prepare README.md for v0.6.0 release (#108)

* Add table of contents

* Fix table of contents

* Remove description from table of contents

* Add persistence section

* Update CHANGELOG.md

* Document keybindings

* Fix arrow icons

* Move keybindings up

* Update README.md

* Add show hidden feature to readme

* Update readme

* Rename persistence feature

* Add description to keybindings

* Update feature list

* Fix incorrect feature in persistent section

* Add file filter feature to readme

* Add home_edit_path to keybinding list

* Update examples

* Update demo image

* Reduce size of demo screenshot

* Update eframe version in README.md

* Use take_selected in README example

* Update changelog

* Update crate documentation (#135)

* Update crate documentation in lib.rs

* Update changelog

* Prepare release v0.6.0 (#136)

* Increase crate version

* Update changelog

---------

Co-authored-by: crumblingstatue <radiantstatue@gmail.com>
Co-authored-by: nat3 <121395237+nat3Github@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 3, 2024
1 parent 6b2f284 commit 2bb654c
Show file tree
Hide file tree
Showing 33 changed files with 2,606 additions and 570 deletions.
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
# egui-file-dialog changelog

## 2024-07-03 - v0.6.0 - Keyboard navigation, multi selection, pinable folders and more
### 🚨 Breaking Changes
- Updated `egui` from version `0.27.1` to version `0.28.0` [#133](https://github.com/fluxxcode/egui-file-dialog/pull/133) (thanks [@crumblingstatue](https://github.com/crumblingstatue)!)
- Added `DialogMode::SelectMultiple` and `DialogState::SelectedMultiple` [#127](https://github.com/fluxxcode/egui-file-dialog/pull/127)
- Added new labels to `FileDialogLabels` [#100](https://github.com/fluxxcode/egui-file-dialog/pull/100), [#111](https://github.com/fluxxcode/egui-file-dialog/pull/111), [#127](https://github.com/fluxxcode/egui-file-dialog/pull/127)
- Added new configuration values to `FileDialogConfig` [#100](https://github.com/fluxxcode/egui-file-dialog/pull/100), [#104](https://github.com/fluxxcode/egui-file-dialog/pull/104), [#106](https://github.com/fluxxcode/egui-file-dialog/pull/106), [#110](https://github.com/fluxxcode/egui-file-dialog/pull/110), [#111](https://github.com/fluxxcode/egui-file-dialog/pull/111), [#118](https://github.com/fluxxcode/egui-file-dialog/pull/118)

### ✨ Features
- Added the ability to pin folders to the left sidebar and enable or disable the feature with `FileDialog::show_pinned_folders` [#100](https://github.com/fluxxcode/egui-file-dialog/pull/100)
- Added `FileDialogConfig::storage`, `FileDialog::storage` and `FileDialog::storage_mut` to be able to save and load persistent data [#104](https://github.com/fluxxcode/egui-file-dialog/pull/104) and [#105](https://github.com/fluxxcode/egui-file-dialog/pull/105)
- Added new modal and option `FileDialog::allow_file_overwrite` to allow overwriting an already existing file when the dialog is in `DialogMode::SaveFile` mode [#106](https://github.com/fluxxcode/egui-file-dialog/pull/106)
- Implemented customizable keyboard navigation using `FileDialogKeybindings` and `FileDialog::keybindings` [#110](https://github.com/fluxxcode/egui-file-dialog/pull/110)
- Implemented show hidden files and folders option [#111](https://github.com/fluxxcode/egui-file-dialog/pull/111)
- The dialog is now displayed as a modal window by default. This can be disabled with `FileDialog::as_modal`. The color of the modal overlay can be adjusted using `FileDialog::modal_overlay_color`. [#118](https://github.com/fluxxcode/egui-file-dialog/pull/118)
- Added `FileDialog::add_file_filter` and `FileDialog::default_file_filter` to add file filters that can be selected by the user from a drop-down menu at the bottom [#124](https://github.com/fluxxcode/egui-file-dialog/pull/124)
- Implemented selection of multiple files and folders at once, using `FileDialog::select_multiple`, `FileDialog::selected_multiple` and `FileDialog::take_selected_multiple` [#127](https://github.com/fluxxcode/egui-file-dialog/pull/127)

### ☢️ Deprecated
- Deprecated `FileDialog::overwrite_config`. Use `FileDialog::with_config` and `FileDialog::config_mut` instead [#103](https://github.com/fluxxcode/egui-file-dialog/pull/103)

### 🐛 Bug Fixes
- Fixed the size of the path edit input box and fixed an issue where the path edit would not close when clicking the apply button [#102](https://github.com/fluxxcode/egui-file-dialog/pull/102)

### 🔧 Changes
- Restructured `config` module and fixed new `1.78` clippy warnings [#109](https://github.com/fluxxcode/egui-file-dialog/pull/109)
- The reload button has been changed to a menu button. This menu contains the reload button and the “Show hidden" option [#111](https://github.com/fluxxcode/egui-file-dialog/pull/111)
- Minor navigation improvements [#113](https://github.com/fluxxcode/egui-file-dialog/pull/113)
- Made `DirectoryEntry` public reachable [#119](https://github.com/fluxxcode/egui-file-dialog/pull/119) (thanks [@crumblingstatue](https://github.com/crumblingstatue)!)
- Improved handling of internal IDs [#128](https://github.com/fluxxcode/egui-file-dialog/pull/128)
- Made file dialog `Send` [#131](https://github.com/fluxxcode/egui-file-dialog/pull/131) (thanks [@nat3](https://github.com/nat3Github)!)

### 📚 Documentation
- Added `persistence` example showing how to save the persistent data of the file dialog [#107](https://github.com/fluxxcode/egui-file-dialog/pull/107)
- Reworked `README.md` [#108](https://github.com/fluxxcode/egui-file-dialog/pull/108https://github.com/fluxxcode/egui-file-dialog/pull/108)
- Added `multi_selection` example showing how to select multiple files and folders at once [#129](https://github.com/fluxxcode/egui-file-dialog/pull/129)
- Updated crate documentation in `lib.rs` [#135](https://github.com/fluxxcode/egui-file-dialog/pull/135)
- Use workspace dependencies in examples [#133](https://github.com/fluxxcode/egui-file-dialog/pull/133) (thanks [@crumblingstatue](https://github.com/crumblingstatue)!)

## 2024-03-30 - v0.5.0 - egui update and QoL changes
### 🚨 Breaking Changes
- Updated `egui` from version `0.26.0` to version `0.27.1` [#97](https://github.com/fluxxcode/egui-file-dialog/pull/97)
Expand Down
14 changes: 12 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
[workspace]
members = [
"examples/*"

]
[workspace.dependencies]
eframe = { version = "0.28.0", default-features = false, features = ["glow", "persistence"] }

[package]
name = "egui-file-dialog"
description = "An easy-to-use file dialog for egui"
version = "0.5.0"
version = "0.6.0"
edition = "2021"
authors = ["fluxxcode"]
repository = "https://github.com/fluxxcode/egui-file-dialog"
Expand All @@ -17,10 +20,17 @@ license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
egui = "0.27.1"
egui = "0.28.0"

# Used to fetch user folders
directories = "5.0"

# Used to fetch disks
sysinfo = { version = "0.30.5", default-features = false }

# Used for persistent storage
serde = { version = "1", features = ["derive"], optional = true}

[features]
default = ["serde"]
serde = ["dep:serde"]
135 changes: 107 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,49 @@
[![Total lines of code ](https://sloc.xyz/github/fluxxcode/egui-file-dialog/)](https://github.com/fluxxcode/egui-file-dialog/)
[![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/fluxxcode/egui-file-dialog/blob/master/LICENSE)

<details>
<summary>Table of contents</summary>

1. [Features](#features)
1. [Example](#example)
1. [Keybindings](#keybindings)
1. [Customization](#customization)
1. [Multilingual support](#multilingual-support)
1. [Persistent data](#persistent-data)

</details>

This repository provides an easy-to-use and customizable file dialog (a.k.a. file explorer, file picker) for [egui](https://github.com/emilk/egui).

The file dialog is intended for use by desktop applications, allowing the use of a file dialog directly within the egui application without relying on the operating system's file explorer. This also ensures that the file dialog looks the same and provides the same functionality on all platforms.

<img src="media/demo.png">

The project is currently in a very early version. Some planned features are still missing and some improvements still need to be made. See the [Planned features](#Planned-features) section for some of the features to be implemented in the future.

The latest changes included in the next release can be found in the [CHANGELOG.md](https://github.com/fluxxcode/egui-file-dialog/blob/develop/CHANGELOG.md) file on the develop branch.

**Currently only tested on Linux and Windows!**

## Features
- Select a file or a directory
- Save a file (Prompt user for a destination path)
- Dialog to ask the user if the existing file should be overwritten
- Select multiple files and folders at once (ctrl/shift + click)
- Open the dialog in a normal or modal window
- Create a new folder
- Keyboard navigation
- Option to show or hide hidden files and folders
- Navigation buttons to open the parent or previous directories
- Search for items in a directory
- Add file filters the user can select from a dropdown
- Shortcut for user directories (Home, Documents, ...) and system disks
- Pin folders to the left sidebar
- Manually edit the path via text
- Customization highlights:
- Customize which areas and functions of the dialog are visible
- Customize the text labels used by the dialog to enable multilingual support
- Customize file and folder icons
- Add custom quick access sections to the left sidebar

## Planned features
The following lists some of the features that are currently missing but are planned for the future!
- Selection of multiple directory items at once
- Pinnable folders for quick access [#42](https://github.com/fluxxcode/egui-file-dialog/issues/42)
- Only show files with a specific file extension (The user can already filter files by file extension using the search, but there is currently no backend method for this or a dropdown to be able to select from predefined file extensions.)
- Keyboard input [#70](https://github.com/fluxxcode/egui-file-dialog/issues/70)
- Context menus, for example for renaming, deleting or copying files or directories
- Option to show or hide hidden files and folders
- Customize keybindings used by the file dialog

## Example
Detailed examples that can be run can be found in the [examples](https://github.com/fluxxcode/egui-file-dialog/tree/master/examples) folder.
Expand All @@ -49,8 +58,8 @@ The following example shows the basic use of the file dialog with [eframe](https
Cargo.toml:
```toml
[dependencies]
eframe = "0.27.1"
egui-file-dialog = "0.5.0"
eframe = "0.28.0"
egui-file-dialog = "0.6.0"
```

main.rs:
Expand Down Expand Up @@ -85,8 +94,11 @@ impl eframe::App for MyApp {

ui.label(format!("Selected file: {:?}", self.selected_file));

// Update the dialog and check if the user selected a file
if let Some(path) = self.file_dialog.update(ctx).selected() {
// Update the dialog
self.file_dialog.update(ctx);

// Check if the user selected a file.
if let Some(path) = self.file_dialog.take_selected() {
self.selected_file = Some(path.to_path_buf());
}
});
Expand All @@ -102,13 +114,32 @@ fn main() -> eframe::Result<()> {
}
```

## Keybindings
Keybindings can be used in the file dialog for easier navigation. All keybindings can be configured from the backend with `FileDialogKeyBindings` and `FileDialog::keybindings`. \
The following table lists all available keybindings and their default values.
| Name | Description | Default |
| --- | --- | --- |
| submit | Submit the current action or open the currently selected folder | `Enter` |
| cancel | Cancel the current action | `Escape` |
| parent | Open the parent directory | `ALT` + `` |
| back | Go back | `Mouse button 1` <br/> `ALT` + `` <br/> `Backspace` |
| forward | Go forward | `Mouse button 2` <br/> `ALT` + `` |
| reload | Reload the file dialog data and the currently open directory | `F5` |
| new_folder | Open the dialog to create a new folder | `CTRL` + `N` |
| edit_path | Text edit the current path | `/` |
| home_edit_path | Open the home directory and start text editing the path | `~` |
| selection_up | Move the selection one item up | `` |
| selection_down | Move the selection one item down | `` |
| select_all | Select every item in the directory when using the file dialog to select multiple files and folders | `CTRL` + `A` |

## Customization
Many things can be customized so that the dialog can be used in different situations. \
A few highlights of the customization are listed below. For all possible customization options, see the documentation on [docs.rs](https://docs.rs/egui-file-dialog/latest/egui_file_dialog/struct.FileDialog.html).

- Set which areas and functions of the dialog are visible using `FileDialog::show_*` methods
- Update the text labels that the dialog uses. See [Multilingual support](#multilingual-support)
- Customize file and folder icons using `FileDialog::set_file_icon` (Currently only unicode is supported)
- Customize keybindings used by the file dialog using `FileDialog::keybindings`. See [Keybindings](#keybindings)

Since the dialog uses the egui style to look like the rest of the application, the appearance can be customized with `egui::Style` and `egui::Context::set_style`.

Expand All @@ -134,26 +165,24 @@ FileDialog::new()
s.add_path("📷 Media", "media");
s.add_path("📂 Source", "src");
})
// Markdown and text files should use the "document with text (U+1F5B9)" icon
// Markdown files should use the "document with text (U+1F5B9)" icon
.set_file_icon(
"🖹",
Arc::new(|path| {
match path
.extension()
.unwrap_or_default()
.to_str()
.unwrap_or_default()
{
"md" => true,
"txt" => true,
_ => false,
}
}),
Arc::new(|path| path.extension().unwrap_or_default() == "md"),
)
// .gitignore files should use the "web-github (U+E624)" icon
.set_file_icon(
"",
Arc::new(|path| path.file_name().unwrap_or_default() == ".gitignore"),
)
// Add file filters the user can select in the bottom right
.add_file_filter(
"PNG files",
Arc::new(|p| p.extension().unwrap_or_default() == "png"),
)
.add_file_filter(
"Rust source files",
Arc::new(|p| p.extension().unwrap_or_default() == "rs"),
);
```
With the options the dialog then looks like this:
Expand Down Expand Up @@ -206,3 +235,53 @@ fn update_labels(language: &Language, file_dialog: &mut FileDialog) {
};
}
```

## Persistent data
The file dialog currently requires the following persistent data to be stored across multiple file dialog objects:

- Folders the user pinned to the left sidebar (`FileDialog::show_pinned_folders`)
- If hidden files and folders should be visible (`FileDialog::show_hidden_option`)

If one of the above feature is activated, the data should be saved by the application. Otherwise, frustrating situations could arise for the user and the features would not offer much added value.

All data that needs to be stored permanently is contained in the `FileDialogStorage` struct. This struct can be accessed using `FileDialog::storage` or `FileDialog::storage_mut` to save or load the persistent data. \
By default the feature `serde` is enabled, which implements `serde::Serialize` and `serde::Deserialize` for the objects to be saved. However, the objects can also be accessed without the feature enabled.

The following example shows how the data can be saved with [eframe](https://github.com/emilk/egui/tree/master/crates/eframe) and the `serde` feature enabled. \
Checkout `examples/persistence` for the full example.

```rust
use egui_file_dialog::FileDialog;

struct MyApp {
file_dialog: FileDialog,
}

impl MyApp {
pub fn new(cc: &eframe::CreationContext) -> Self {
let mut file_dialog = FileDialog::default();

// Load the persistent data of the file dialog.
// Alternatively, you can also use the `FileDialog::storage` builder method.
if let Some(storage) = cc.storage {
*file_dialog.storage_mut() =
eframe::get_value(storage, "file_dialog_storage").unwrap_or_default()
}

Self {
file_dialog,
}
}
}

impl eframe::App for MyApp {
fn save(&mut self, storage: &mut dyn eframe::Storage) {
// Save the persistent data of the file dialog
eframe::set_value(
storage,
"file_dialog_storage",
self.file_dialog.storage_mut(),
);
}
}
```
10 changes: 10 additions & 0 deletions examples/multi_selection/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "multi_selection"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
eframe = { workspace = true }
egui-file-dialog = { path = "../../"}
7 changes: 7 additions & 0 deletions examples/multi_selection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Example showing how to select multiple files and folders at once.

```
cargo run -p multi_selection
```

![](screenshot.png)
Binary file added examples/multi_selection/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions examples/multi_selection/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::path::PathBuf;

use eframe::egui;
use egui_file_dialog::FileDialog;

struct MyApp {
file_dialog: FileDialog,
selected_items: Option<Vec<PathBuf>>,
}

impl MyApp {
pub fn new(_cc: &eframe::CreationContext) -> Self {
Self {
file_dialog: FileDialog::new(),
selected_items: None,
}
}
}

impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
if ui.button("Select multiple").clicked() {
self.file_dialog.select_multiple();
}

ui.label("Selected items:");

if let Some(items) = &self.selected_items {
for item in items {
ui.label(format!("{:?}", item));
}
} else {
ui.label("None");
}

self.file_dialog.update(ctx);

if let Some(items) = self.file_dialog.take_selected_multiple() {
self.selected_items = Some(items);
}
});
}
}

fn main() -> eframe::Result<()> {
eframe::run_native(
"File dialog example",
eframe::NativeOptions::default(),
Box::new(|ctx| Ok(Box::new(MyApp::new(ctx)))),
)
}
2 changes: 1 addition & 1 deletion examples/multilingual/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
eframe = { version = "0.27.1", default-features = false, features = ["glow"] }
eframe = { workspace = true }
egui-file-dialog = { path = "../../"}
Loading

0 comments on commit 2bb654c

Please sign in to comment.