|
5 | 5 | #[cfg(any(dialog_open, dialog_save))]
|
6 | 6 | use std::path::{Path, PathBuf};
|
7 | 7 |
|
| 8 | +#[cfg(not(target_os = "linux"))] |
| 9 | +macro_rules! run_dialog { |
| 10 | + ($e:expr, $h: ident) => {{ |
| 11 | + std::thread::spawn(move || { |
| 12 | + let response = $e; |
| 13 | + $h(response); |
| 14 | + }); |
| 15 | + }}; |
| 16 | +} |
| 17 | + |
| 18 | +#[cfg(target_os = "linux")] |
| 19 | +macro_rules! run_dialog { |
| 20 | + ($e:expr, $h: ident) => {{ |
| 21 | + std::thread::spawn(move || { |
| 22 | + let context = glib::MainContext::default(); |
| 23 | + context.invoke_with_priority(glib::PRIORITY_HIGH, move || { |
| 24 | + let response = $e; |
| 25 | + $h(response); |
| 26 | + }); |
| 27 | + }); |
| 28 | + }}; |
| 29 | +} |
| 30 | + |
8 | 31 | /// The file dialog builder.
|
9 | 32 | /// Constructs file picker dialogs that can select single/multiple files or directories.
|
10 | 33 | #[cfg(any(dialog_open, dialog_save))]
|
@@ -44,55 +67,57 @@ impl FileDialogBuilder {
|
44 | 67 | }
|
45 | 68 |
|
46 | 69 | /// Pick one file.
|
47 |
| - pub fn pick_file(self) -> Option<PathBuf> { |
48 |
| - self.0.pick_file() |
| 70 | + pub fn pick_file<F: FnOnce(Option<PathBuf>) + Send + 'static>(self, f: F) { |
| 71 | + run_dialog!(self.0.pick_file(), f) |
49 | 72 | }
|
50 | 73 |
|
51 | 74 | /// Pick multiple files.
|
52 |
| - pub fn pick_files(self) -> Option<Vec<PathBuf>> { |
53 |
| - self.0.pick_files() |
| 75 | + pub fn pick_files<F: FnOnce(Option<Vec<PathBuf>>) + Send + 'static>(self, f: F) { |
| 76 | + run_dialog!(self.0.pick_files(), f) |
54 | 77 | }
|
55 | 78 |
|
56 | 79 | /// Pick one folder.
|
57 |
| - pub fn pick_folder(self) -> Option<PathBuf> { |
58 |
| - self.0.pick_folder() |
| 80 | + pub fn pick_folder<F: FnOnce(Option<PathBuf>) + Send + 'static>(self, f: F) { |
| 81 | + run_dialog!(self.0.pick_folder(), f) |
59 | 82 | }
|
60 | 83 |
|
61 | 84 | /// Opens save file dialog.
|
62 |
| - pub fn save_file(self) -> Option<PathBuf> { |
63 |
| - self.0.save_file() |
| 85 | + pub fn save_file<F: FnOnce(Option<PathBuf>) + Send + 'static>(self, f: F) { |
| 86 | + run_dialog!(self.0.save_file(), f) |
64 | 87 | }
|
65 | 88 | }
|
66 | 89 |
|
67 |
| -/// Response for the ask dialog |
68 |
| -#[derive(Debug, Clone, PartialEq, Eq)] |
69 |
| -pub enum AskResponse { |
70 |
| - /// User confirmed. |
71 |
| - Yes, |
72 |
| - /// User denied. |
73 |
| - No, |
74 |
| -} |
75 |
| - |
76 |
| -/// Displays a dialog with a message and an optional title with a "yes" and a "no" button |
77 |
| -pub fn ask(title: impl AsRef<str>, message: impl AsRef<str>) -> AskResponse { |
78 |
| - match rfd::MessageDialog::new() |
79 |
| - .set_title(title.as_ref()) |
80 |
| - .set_description(message.as_ref()) |
81 |
| - .set_buttons(rfd::MessageButtons::YesNo) |
82 |
| - .set_level(rfd::MessageLevel::Info) |
83 |
| - .show() |
84 |
| - { |
85 |
| - true => AskResponse::Yes, |
86 |
| - false => AskResponse::No, |
87 |
| - } |
| 90 | +/// Displays a dialog with a message and an optional title with a "yes" and a "no" button. |
| 91 | +pub fn ask<F: FnOnce(bool) + Send + 'static>( |
| 92 | + title: impl AsRef<str>, |
| 93 | + message: impl AsRef<str>, |
| 94 | + f: F, |
| 95 | +) { |
| 96 | + let title = title.as_ref().to_string(); |
| 97 | + let message = message.as_ref().to_string(); |
| 98 | + run_dialog!( |
| 99 | + rfd::MessageDialog::new() |
| 100 | + .set_title(&title) |
| 101 | + .set_description(&message) |
| 102 | + .set_buttons(rfd::MessageButtons::YesNo) |
| 103 | + .set_level(rfd::MessageLevel::Info) |
| 104 | + .show(), |
| 105 | + f |
| 106 | + ) |
88 | 107 | }
|
89 | 108 |
|
90 |
| -/// Displays a message dialog |
| 109 | +/// Displays a message dialog. |
91 | 110 | pub fn message(title: impl AsRef<str>, message: impl AsRef<str>) {
|
92 |
| - rfd::MessageDialog::new() |
93 |
| - .set_title(title.as_ref()) |
94 |
| - .set_description(message.as_ref()) |
95 |
| - .set_buttons(rfd::MessageButtons::Ok) |
96 |
| - .set_level(rfd::MessageLevel::Info) |
97 |
| - .show(); |
| 111 | + let title = title.as_ref().to_string(); |
| 112 | + let message = message.as_ref().to_string(); |
| 113 | + let cb = |_| {}; |
| 114 | + run_dialog!( |
| 115 | + rfd::MessageDialog::new() |
| 116 | + .set_title(&title) |
| 117 | + .set_description(&message) |
| 118 | + .set_buttons(rfd::MessageButtons::Ok) |
| 119 | + .set_level(rfd::MessageLevel::Info) |
| 120 | + .show(), |
| 121 | + cb |
| 122 | + ) |
98 | 123 | }
|
0 commit comments