Crates.io | egui-file-dialog |
lib.rs | egui-file-dialog |
version | 0.7.0 |
source | src |
created_at | 2024-02-03 15:42:24.885648 |
updated_at | 2024-10-01 18:08:19.068195 |
description | An easy-to-use file dialog for egui |
homepage | https://github.com/fluxxcode/egui-file-dialog |
repository | https://github.com/fluxxcode/egui-file-dialog |
max_upload_size | |
id | 1125501 |
size | 353,617 |
This repository provides an easy-to-use and customizable file dialog (a.k.a. file explorer, file picker) for 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.
The latest changes included in the next release can be found in the CHANGELOG.md file on the develop branch.
Currently only tested on Linux and Windows!
Detailed examples that can be run can be found in the examples folder.
The following example shows the basic use of the file dialog with eframe to select a file.
Cargo.toml:
[dependencies]
eframe = "0.29.1"
egui-file-dialog = "0.7.0"
main.rs:
use std::path::PathBuf;
use eframe::egui;
use egui_file_dialog::FileDialog;
struct MyApp {
file_dialog: FileDialog,
selected_file: Option<PathBuf>,
}
impl MyApp {
pub fn new(_cc: &eframe::CreationContext) -> Self {
Self {
// Create a new file dialog object
file_dialog: FileDialog::new(),
selected_file: 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 file").clicked() {
// Open the file dialog to select a file.
self.file_dialog.select_file();
}
ui.label(format!("Selected file: {:?}", self.selected_file));
// 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());
}
});
}
}
fn main() -> eframe::Result<()> {
eframe::run_native(
"File dialog demo",
eframe::NativeOptions::default(),
Box::new(|ctx| Box::new(MyApp::new(ctx))),
)
}
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 ALT + ← Backspace |
forward | Go forward | Mouse button 2 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 |
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.
FileDialog::show_*
methodsFileDialog::set_file_icon
(Currently only unicode is supported)FileDialog::keybindings
. See KeybindingsSince 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
.
The following example shows how a single file dialog can be customized.
If you need to configure multiple file dialog objects with the same or almost the same options, it is a good idea to use FileDialogConfig
and FileDialog::with_config
(See FileDialogConfig
on docs.rs).
use std::path::PathBuf;
use std::sync::Arc;
use egui_file_dialog::FileDialog;
FileDialog::new()
.initial_directory(PathBuf::from("/path/to/app"))
.default_file_name("app.cfg")
.default_size([600.0, 400.0])
.resizable(false)
.show_new_folder_button(false)
.show_search(false)
.show_path_edit_button(false)
// Add a new quick access section to the left sidebar
.add_quick_access("Project", |s| {
s.add_path("☆ Examples", "examples");
s.add_path("📷 Media", "media");
s.add_path("📂 Source", "src");
})
// Markdown files should use the "document with text (U+1F5B9)" icon
.set_file_icon(
"🖹",
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:
The smallest possible dialog can be generated with the following configuration:
FileDialog::new()
.title_bar(false)
.show_top_panel(false)
.show_left_panel(false)
For desktop applications it is often necessary to offer different languages. While the dialog currently only offers English labels by default, the labels are fully customizable. This makes it possible to adapt the labels to different languages.
The following example shows how the labels can be changed to display the file dialog in English or German.
Checkout examples/multilingual
for the full example.
use egui_file_dialog::{FileDialog, FileDialogLabels};
enum Language {
English,
German,
}
fn get_labels_german() -> FileDialogLabels {
FileDialogLabels {
title_select_directory: "📁 Ordner Öffnen".to_string(),
title_select_file: "📂 Datei Öffnen".to_string(),
title_save_file: "📥 Datei Speichern".to_string(),
// ... See examples/multilingual for the other labels
..Default::default()
}
}
/// Updates the labels of the file dialog.
/// Should be called every time the user selects a different language.
fn update_labels(language: &Language, file_dialog: &mut FileDialog) {
*file_dialog.labels_mut() = match language {
// English labels are used by default
Language::English => FileDialogLabels::default(),
// Use custom labels for German
Language::German => get_labels_german(),
};
}
The file dialog currently requires the following persistent data to be stored across multiple file dialog objects:
FileDialog::show_pinned_folders
)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 and the serde
feature enabled.
Checkout examples/persistence
for the full example.
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(),
);
}
}