zng/
dialog.rs

1#![cfg(feature = "dialog")]
2
3//! Message dialogs, file and folder dialogs, notifications.
4//!
5//! The [`DIALOG`] service provides custom and modal native dialogs.
6//!
7//! ```
8//! use zng::prelude::*;
9//!
10//! # fn example() {
11//! # let _ =
12//! Button! {
13//!     child = Text!("Info, Warn, Error");
14//!     on_click = async_hn!(|_| {
15//!         DIALOG.info("Info", "Information message.").wait_rsp().await;
16//!         DIALOG.warn("Warn", "Warning message.").wait_rsp().await;
17//!         DIALOG.error("Error", "Error message.").wait_rsp().await;
18//!     });
19//!     // dialog::native_dialogs = true;
20//! }
21//! # ; }
22//! ```
23//!
24//! The example above shows 3 custom dialogs in sequence, info, warn and error. If `dialog::native_dialogs = true` is uncommented
25//! the example shows 3 native dialogs.
26//!
27//! Custom dialogs modal widgets, rendered in the window content, instantiated using the [`Dialog!`] widget.
28//!
29//! ```
30//! use zng::prelude::*;
31//!
32//! # async fn _demo() {
33//! let r = DIALOG
34//!     .custom(dialog::Dialog! {
35//!         style_fn = dialog::WarnStyle!();
36//!         title = Text!(l10n!("save-dlg.title", "Save File?"));
37//!         content = SelectableText!(l10n!(
38//!             "save-dlg.msg",
39//!             "Save file? All unsaved changes will be lost."
40//!         ));
41//!         responses = vec![
42//!             dialog::Response::cancel(),
43//!             dialog::Response::new("discard", l10n!("save-dlg.discard", "Discard")),
44//!             dialog::Response::new("save", l10n!("save-dlg.save", "Save")),
45//!         ];
46//!     })
47//!     .wait_rsp()
48//!     .await;
49//! if r.name == "save" {
50//!     // save
51//! }
52//! # }
53//! ```
54//!
55//! The example above creates a custom dialog based on the warning dialog (`WarnStyle!`), it uses custom responses that are
56//! identified by name.
57//!
58//! Some of the dialogs provided are native by default (and only native on this release), the example below shows a native save file dialog:
59//!
60//! ```
61//! use zng::prelude::*;
62//!
63//! # async fn _demo() {
64//! let mut f = dialog::FileDialogFilters::default();
65//! f.push_filter("Text Files", ["txt", "md"]);
66//! f.push_filter("Text File", ["txt"]);
67//! f.push_filter("Markdown File", ["md"]);
68//! f.push_filter("All Files", ["*"]);
69//! let filters = f;
70//!
71//! let r = DIALOG
72//!     .save_file("Save Text", "last/save/dir", "last-name.txt", filters)
73//!     .wait_rsp()
74//!     .await
75//!     .into_path();
76//!
77//! if let Ok(Some(path)) = r {
78//!     std::fs::write(path, "contents".as_bytes()).unwrap();
79//! }
80//! # }
81//! ```
82//!
83//! # Local Notifications
84//!
85//! The service can also insert notifications in the system notification list.
86//!
87//! ```
88//! use zng::prelude::*;
89//!
90//! # async fn _demo(){
91//! let mut note = dialog::Notification::new("Test", "Test notification.");
92//! // optional *dismiss actions*
93//! note.push_action("action-1", "Action 1");
94//! note.push_action("action-2", "Action 2");
95//! // optional system cleanup timeout suggestion.
96//! note.timeout = Some(3.hours());
97//!
98//! // as explicit var to support updates
99//! let note = var(note);
100//!
101//! // insert the notification
102//! let r = DIALOG.notification(note.clone());
103//!
104//! // set a handler in case the notification is responded.
105//! r.on_rsp(hn!(|a| {
106//!     println!("Notification response: {:?}", a.value);
107//! }))
108//! .perm();
109//!
110//! // await for an explicit response up to 10 minutes.
111//! task::with_deadline(r.wait_done(), 10.minutes()).await;
112//! if r.is_waiting() {
113//!     // update the notification with a close request.
114//!     note.set(dialog::Notification::close());
115//! }
116//! # }
117//! ```
118//!
119//! The example above inserts a notification with two dismiss actions and sets a handler in case the notification is ever responded.
120//!
121//! Note that the notification is a variable, it can be updated and closed. Also note that care is taken to not keep awaiting for a response
122//! forever, notifications are not intrusive like other dialogs, users may never respond, the operating system may also ignore the timeout suggestion.
123//!
124//! [`Dialog!`]: struct@Dialog
125//!
126//! # Full API
127//!
128//! See [`zng_wgt_dialog`] for the full view API.
129
130pub use zng_wgt_dialog::{
131    AskStyle, ConfirmStyle, DIALOG, DefaultStyle, Dialog, DialogButtonArgs, DialogKind, ErrorStyle, FileDialogFilters, FileDialogResponse,
132    InfoStyle, Notification, NotificationAction, NotificationResponse, Response, Responses, WarnStyle, ask_style_fn, confirm_style_fn,
133    error_style_fn, info_style_fn, native_dialogs, warn_style_fn,
134};
135
136/// Modal dialog parent widget that fills the window.
137///
138/// Note that the actual [`DialogBackdrop!`] widget is not included in this module because it is instantiated by the [`DIALOG`] service.
139/// The backdrop can be customized by setting the [`backdrop::style_fn`].
140///
141/// ```
142/// use zng::prelude::*;
143///
144/// # fn example() {
145/// # let _ =
146/// Window! {
147///     dialog::backdrop::style_fn = Style! {
148///         replace = true;
149///         color::filter::backdrop_blur = 2;
150///     };
151/// }
152/// # ; }
153/// ```
154///
155/// The example above configures the backdrop to blur the window content when any dialog is open.
156///
157/// [`DialogBackdrop!`]: struct@zng_wgt_dialog::backdrop::DialogBackdrop
158/// [`backdrop::style_fn`]: fn@crate::dialog::backdrop::style_fn
159/// [`DIALOG`]: crate::dialog::DIALOG
160///
161/// # Full API
162///
163/// See [`zng_wgt_dialog::backdrop`] for the fill view API.
164pub mod backdrop {
165    pub use zng_wgt_dialog::backdrop::{DefaultStyle, style_fn};
166}