Skip to content

Commit

Permalink
documentation rewrite
Browse files Browse the repository at this point in the history
  * Move most documentation to lib.rs so it will show up on docs.rs
  * More details about GTK versus XDG Desktop Portal backends
  * Remove unneeded subsections in inline documentation
  * Consistent formating
  * Various edits for clarity
  • Loading branch information
Be-ing committed Jan 19, 2022
1 parent d0a0e4f commit 51b097d
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 123 deletions.
80 changes: 7 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,12 @@
[![Documentation](https://docs.rs/rfd/badge.svg)](https://docs.rs/rfd)
[![dependency status](https://deps.rs/crate/rfd/0.6.4/status.svg)](https://deps.rs/crate/rfd/0.6.4)

Rusty file dialogs for Windows, Linux (GTK), MacOS And WASM32.
Rusty File Dialogs is a cross platform Rust library for using native file open/save dialogs.
It provides both asynchronous and synchronous APIs. Supported platforms:

# Why RFD?
* Windows
* macOS
* Linux & BSDs (GTK3 or XDG Desktop Portal)
* WASM32 (async only)

- It uses 100% native API on all platforms, it does not spawn any processes in the background.
- It supports async/await syntax
- And if one day you decide to port your program to browser, WASM support is there for you!

# Dependencies
#### On Linux:
###### For GTK version:
- GTK3 development libraries (on debian `libgtk-3-dev` on arch `gtk3`)
###### For XFG Portal version (in case you out-out of GTK version):
- XDG Portal provider of you choice has to be present on the system. (Most distros have one by default)

# Features
- `parent` Adds a dialog parenting support via `raw-window-handle`
- `gtk3` Uses GTK for dialogs, if you know for sure that your users have XDG Portal around you can safely disable this, and drop C dependency

# Example

```rust
// Sync Dialog
let files = FileDialog::new()
.add_filter("text", &["txt", "rs"])
.add_filter("rust", &["rs", "toml"])
.set_directory("/")
.pick_file();

// Async Dialog
let file = AsyncFileDialog::new()
.add_filter("text", &["txt", "rs"])
.add_filter("rust", &["rs", "toml"])
.set_directory("/")
.pick_file()
.await;

let data = file.read().await;
```

# State

![GitHub Workflow Status](https://img.shields.io/github/workflow/status/PolyMeilex/rfd/Rust/master?style=flat-square)

| API Stability |
| ------------- |
| 🚧 |

| Feature | Linux | Windows | MacOS | Wasm32 |
| ------------ | ----- | ------- | --------- | ------ |
| SingleFile | βœ” | βœ” | βœ” | βœ” |
| MultipleFile | βœ” | βœ” | βœ” | βœ” |
| PickFolder | βœ” | βœ” | βœ” | βœ– |
| SaveFile | βœ” | βœ” | βœ” | βœ– |
| | | | | |
| Filters | βœ” | βœ” | βœ” | βœ” |
| StartingPath | βœ” | βœ” | βœ” | βœ– |
| Async | βœ” | βœ” | βœ” | βœ” |

### Difference between `MacOS Windowed App` and `MacOS NonWindowed App`

- Macos async dialog requires a started `NSApplication` instance, so dialog is truly async only when opened in windowed env like `winit`,`SDL2`, etc. otherwise it will fallback to sync dialog.
- It is also recommended to spawn dialogs on main thread, RFD can run dialogs from any thread but it is only possible in windowed app and it adds a little bit of overhead. So it is recommended to: [spawn on main and await in other thread](https://github.com/PolyMeilex/rfd/blob/master/examples/async.rs)
- NonWindowed apps will never be able to spawn dialogs from threads diferent than main
- NonWindowed apps will never be able to spawn async dialogs

# rfd-extras

AKA features that are not file related

| Feature | Linux | Windows | MacOS | Wasm32 |
| ------------- | ----- | ------- | ----- | ------ |
| MessageDialog | βœ” | βœ” | βœ” | βœ” |
| PromptDialog | | | | |
| ColorPicker | | | | |
Refer to the [documentation](https://docs.rs/rfd) for more details.
88 changes: 40 additions & 48 deletions src/file_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ pub(crate) struct Filter {
pub extensions: Vec<String>,
}

/// ## Synchronous File Dialog
/// #### Supported Platforms:
/// - Linux
/// - Windows
/// - Mac
/// Synchronous File Dialog. Supported platforms:
/// * Linux
/// * Windows
/// * Mac
#[derive(Default, Debug, Clone)]
pub struct FileDialog {
pub(crate) filters: Vec<Filter>,
Expand All @@ -41,9 +40,9 @@ impl FileDialog {
///
/// Takes in the name of the filter, and list of extensions
///
/// #### Name of the filter will be displayed on supported platforms
/// - Windows
/// - Linux
/// The name of the filter will be displayed on supported platforms:
/// * Windows
/// * Linux
///
/// On platforms that don't support filter names, all filters will be merged into one filter
pub fn add_filter(mut self, name: &str, extensions: &[&str]) -> Self {
Expand All @@ -54,31 +53,28 @@ impl FileDialog {
self
}

/// Set starting directory of the dialog.
/// #### Supported Platforms:
/// - Linux
/// - Windows
/// - Mac
/// Set starting directory of the dialog. Supported platforms:
/// * Linux ([GTK only](https://github.com/PolyMeilex/rfd/issues/42))
/// * Windows
/// * Mac
pub fn set_directory<P: AsRef<Path>>(mut self, path: P) -> Self {
self.starting_directory = Some(path.as_ref().into());
self
}

/// Set starting file name of the dialog.
/// #### Supported Platforms:
/// - Windows
/// - Linux
/// - Mac
/// Set starting file name of the dialog. Supported platforms:
/// * Windows
/// * Linux
/// * Mac
pub fn set_file_name(mut self, file_name: &str) -> Self {
self.file_name = Some(file_name.into());
self
}

/// Set the title of the dialog.
/// #### Supported Platforms:
/// - Windows
/// - Linux
/// - Mac (Only below version 10.11)
/// Set the title of the dialog. Supported platforms:
/// * Windows
/// * Linux
/// * Mac (Only below version 10.11)
pub fn set_title(mut self, title: &str) -> Self {
self.title = Some(title.into());
self
Expand Down Expand Up @@ -115,7 +111,7 @@ impl FileDialog {
/// Opens save file dialog
///
/// #### Platform specific notes regarding save dialog filters:
/// - On MacOs
/// - On macOS
/// - If filter is set, all files will be grayed out (no matter the extension sadly)
/// - If user does not type an extension MacOs will append first available extension from filters list
/// - If user types in filename with extension MacOs will check if it exists in filters list, if not it will display appropriate message
Expand All @@ -132,12 +128,11 @@ impl FileDialog {
}
}

/// ## Asynchronous File Dialog
/// #### Supported Platforms:
/// - Linux
/// - Windows
/// - Mac
/// - WASM32
/// Asynchronous File Dialog. Supported platforms:
/// * Linux
/// * Windows
/// * Mac
/// * WASM32
#[derive(Default, Debug, Clone)]
pub struct AsyncFileDialog {
file_dialog: FileDialog,
Expand All @@ -153,41 +148,38 @@ impl AsyncFileDialog {
///
/// Takes in the name of the filter, and list of extensions
///
/// #### Name of the filter will be displayed on supported platforms
/// - Windows
/// - Linux
/// The name of the filter will be displayed on supported platforms:
/// * Windows
/// * Linux
///
/// On platforms that don't support filter names, all filters will be merged into one filter
pub fn add_filter(mut self, name: &str, extensions: &[&str]) -> Self {
self.file_dialog = self.file_dialog.add_filter(name, extensions);
self
}

/// Set starting directory of the dialog.
/// #### Supported Platforms:
/// - Linux
/// - Windows
/// - Mac
/// Set starting directory of the dialog. Supported platforms:
/// * Linux ([GTK only](https://github.com/PolyMeilex/rfd/issues/42))
/// * Windows
/// * Mac
pub fn set_directory<P: AsRef<Path>>(mut self, path: P) -> Self {
self.file_dialog = self.file_dialog.set_directory(path);
self
}

/// Set starting file name of the dialog.
/// #### Supported Platforms:
/// - Windows
/// - Linux
/// - Mac
/// Set starting file name of the dialog. Supported platforms:
/// * Windows
/// * Linux
/// * Mac
pub fn set_file_name(mut self, file_name: &str) -> Self {
self.file_dialog = self.file_dialog.set_file_name(file_name);
self
}

/// Set the title of the dialog.
/// #### Supported Platforms:
/// - Windows
/// - Linux
/// - Mac (Only below version 10.11)
/// Set the title of the dialog. Supported platforms:
/// * Windows
/// * Linux
/// * Mac (Only below version 10.11)
pub fn set_title(mut self, title: &str) -> Self {
self.file_dialog = self.file_dialog.set_title(title);
self
Expand Down
109 changes: 109 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,112 @@
//! Rusty File Dialogs is a cross platform library for using native file open/save dialogs.
//! It provides both asynchronous and synchronous APIs. Supported platforms:
//!
//! * Windows
//! * macOS
//! * Linux & BSDs (GTK3 or XDG Desktop Portal)
//! * WASM32 (async only)
//!
//! # Examples
//!
//! ## Synchronous
//! ```
//! let files = FileDialog::new()
//! .add_filter("text", &["txt", "rs"])
//! .add_filter("rust", &["rs", "toml"])
//! .set_directory("/")
//! .pick_file();
//! ```
//!
//! ## Asynchronous
//! ```
//! let file = AsyncFileDialog::new()
//! .add_filter("text", &["txt", "rs"])
//! .add_filter("rust", &["rs", "toml"])
//! .set_directory("/")
//! .pick_file()
//! .await;
//!
//! let data = file.read().await;
//! ```
//!
//! # Linux & BSD backends
//!
//! On Linux & BSDs, two backends are available, one using the [GTK3 Rust bindings](https://gtk-rs.org/)
//! and the other using the [XDG Desktop Portal](https://github.com/flatpak/xdg-desktop-portal)
//! D-Bus API through [ashpd](https://github.com/bilelmoussaoui/ashpd) &
//! [zbus](https://gitlab.freedesktop.org/dbus/zbus/).
//!
//! ## GTK backend
//! The GTK backend is used with the `gtk3` Cargo feature which is enabled by default. The GTK3
//! backend requires the C library and development headers to be installed to build RFD. The package
//! names on various distributions are:
//!
//! | Distribution | Package name |
//! | --------------- | ------------ |
//! | Fedora | gtk3-devel |
//! | Arch | gtk3 |
//! | Debian & Ubuntu | libgtk-3-dev |
//!
//! ## XDG Desktop Portal backend
//! The XDG Desktop Portal backend is used when the `gtk3` feature is disabled with
//! [`default-features = false`](https://doc.rust-lang.org/cargo/reference/features.html#dependency-features). This backend will use either the GTK or KDE file dialog depending on the desktop environment
//! in use at runtime. It does not have any non-Rust
//! build dependencies, however it requires the user to have either the
//! [GTK](https://github.com/flatpak/xdg-desktop-portal-gtk),
//! [GNOME](https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome), or
//! [KDE](https://invent.kde.org/plasma/xdg-desktop-portal-kde/) XDG Desktop Portal backend installed
//! at runtime. These are typically installed by the distribution together with the desktop environment.
//! If you are packaging an application that uses RFD, ensure either one of these is installed
//! with the package. The
//! [wlroots portal backend](https://github.com/emersion/xdg-desktop-portal-wlr) does not implement the
//! D-Bus API that RFD requires (it does not interfere with the other portal implementations;
//! they can all be installed simultaneously).
//!
//! The XDG Desktop Portal has no API for message dialogs, so the [MessageDialog] and
//! [AsyncMessageDialog] structs will not build with this backend.
//!
//! # macOS non-windowed applications, async, and threading
//!
//! macOS async dialogs require an `NSApplication` instance, so the dialog is only truly async when
//! opened in windowed environment like `winit` or `SDL2`. Otherwise, it will fallback to sync dialog.
//! It is also recommended to spawn dialogs on your main thread. RFD can run dialogs from any thread
//! but it is only possible in a windowed app and it adds a little bit of overhead. So it is recommended
//! to [spawn on main and await in other thread](https://github.com/PolyMeilex/rfd/blob/master/examples/async.rs).
//! Non-windowed apps will never be able to spawn async dialogs or from threads other than the main thread.
//!
//! # Cargo features
//! * `parent`: Adds a dialog parenting support via [raw-window-handle](https://github.com/rust-windowing/raw-window-handle).
//! [Not yet implemented](https://github.com/bilelmoussaoui/ashpd/issues/40) for XDG Desktop Portal
//! backend.
//! * `gtk3`: Uses GTK for dialogs on Linux & BSDs; has no effect on Windows and macOS
//!
//! # State
//!
//! | API Stability |
//! | ------------- |
//! | 🚧 |
//!
//! | Feature | Linux | Windows | MacOS | Wasm32 |
//! | ------------ | ----- | ------- | --------- | ------ |
//! | SingleFile | βœ” | βœ” | βœ” | βœ” |
//! | MultipleFile | βœ” | βœ” | βœ” | βœ” |
//! | PickFolder | βœ” | βœ” | βœ” | βœ– |
//! | SaveFile | βœ” | βœ” | βœ” | βœ– |
//! | | | | | |
//! | Filters | βœ” ([GTK only](https://github.com/PolyMeilex/rfd/issues/42)) | βœ” | βœ” | βœ” |
//! | StartingPath | βœ” | βœ” | βœ” | βœ– |
//! | Async | βœ” | βœ” | βœ” | βœ” |
//!
//! # rfd-extras
//!
//! AKA features that are not file related
//!
//! | Feature | Linux | Windows | MacOS | Wasm32 |
//! | ------------- | ----- | ------- | ----- | ------ |
//! | MessageDialog | βœ” (GTK only) | βœ” | βœ” | βœ” |
//! | PromptDialog | | | | |
//! | ColorPicker | | | | |

mod backend;

mod file_handle;
Expand Down
12 changes: 10 additions & 2 deletions src/message_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use std::future::Future;
#[cfg(feature = "parent")]
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};

/// ## Synchronous Message Dialog
/// Synchronous Message Dialog. Supported platforms:
/// * Windows
/// * macOS
/// * Linux (GTK only)
/// * WASM
#[derive(Default, Debug, Clone)]
pub struct MessageDialog {
pub(crate) title: String,
Expand Down Expand Up @@ -77,7 +81,11 @@ impl MessageDialog {
}
}

/// ## Asynchronous Message Dialog
/// Asynchronous Message Dialog. Supported platforms:
/// * Windows
/// * macOS
/// * Linux (GTK only)
/// * WASM
#[derive(Default, Debug, Clone)]
pub struct AsyncMessageDialog(MessageDialog);

Expand Down

0 comments on commit 51b097d

Please sign in to comment.