Skip to main content

telar_platform_desktop/
dialogs.rs

1use std::path::PathBuf;
2use std::sync::Arc;
3
4use services_core::{FileDialog, FileDialogs};
5
6/// The OS file chooser, via `rfd`: the XDG portal on Linux, the native panel on macOS and Windows.
7pub struct DesktopFileDialogs;
8
9impl DesktopFileDialogs {
10    /// Installs this backend as the process's file chooser. Called by the desktop runner at startup.
11    pub fn install() {
12        services_core::set_file_dialogs(Arc::new(DesktopFileDialogs));
13    }
14}
15
16fn build(request: FileDialog) -> rfd::FileDialog {
17    let mut dialog = rfd::FileDialog::new();
18    if let Some(title) = request.title {
19        dialog = dialog.set_title(title);
20    }
21    if let Some(dir) = request.directory {
22        dialog = dialog.set_directory(dir);
23    }
24    if let Some(name) = request.file_name {
25        dialog = dialog.set_file_name(name);
26    }
27    for filter in request.filters {
28        let extensions: Vec<&str> = filter.extensions.iter().map(String::as_str).collect();
29        dialog = dialog.add_filter(filter.name, &extensions);
30    }
31    dialog
32}
33
34impl FileDialogs for DesktopFileDialogs {
35    fn open_file(&self, request: FileDialog) -> Option<PathBuf> {
36        build(request).pick_file()
37    }
38
39    fn open_files(&self, request: FileDialog) -> Vec<PathBuf> {
40        build(request).pick_files().unwrap_or_default()
41    }
42
43    fn save_file(&self, request: FileDialog) -> Option<PathBuf> {
44        build(request).save_file()
45    }
46
47    fn pick_folder(&self, request: FileDialog) -> Option<PathBuf> {
48        build(request).pick_folder()
49    }
50}