better_web_view/
dialog.rs

1use ffi::{self, DialogFlags, DialogType};
2use std::{ffi::CString, path::PathBuf};
3use crate::{read_str, WVResult, WebView};
4
5const STR_BUF_SIZE: usize = 4096;
6
7/// A builder for opening a new dialog window.
8#[derive(Debug)]
9pub struct DialogBuilder<'a: 'b, 'b, T: 'a> {
10    webview: &'b mut WebView<'a, T>,
11}
12
13impl<'a: 'b, 'b, T: 'a> DialogBuilder<'a, 'b, T> {
14    /// Creates a new dialog builder for a WebView.
15    pub fn new(webview: &'b mut WebView<'a, T>) -> DialogBuilder<'a, 'b, T> {
16        DialogBuilder { webview }
17    }
18
19    fn dialog(
20        &mut self,
21        title: String,
22        arg: String,
23        dialog_type: DialogType,
24        dialog_flags: DialogFlags,
25    ) -> WVResult<String> {
26        let mut s = [0u8; STR_BUF_SIZE];
27
28        let title_cstr = CString::new(title)?;
29        let arg_cstr = CString::new(arg)?;
30
31        unsafe {
32            ffi::webview_dialog(
33                self.webview.inner,
34                dialog_type,
35                dialog_flags,
36                title_cstr.as_ptr(),
37                arg_cstr.as_ptr(),
38                s.as_mut_ptr() as _,
39                s.len(),
40            );
41        }
42
43        Ok(read_str(&s))
44    }
45
46    /// Opens a new open file dialog and returns the chosen file path.
47    pub fn open_file<S, P>(&mut self, title: S, default_file: P) -> WVResult<Option<PathBuf>>
48    where
49        S: Into<String>,
50        P: Into<PathBuf>,
51    {
52        self.dialog(
53            title.into(),
54            default_file.into().to_string_lossy().into_owned(),
55            DialogType::Open,
56            DialogFlags::FILE,
57        )
58        .map(|path| {
59            if path.is_empty() {
60                None
61            } else {
62                Some(PathBuf::from(path))
63            }
64        })
65    }
66
67    /// Opens a new choose directory dialog as returns the chosen directory path.
68    pub fn choose_directory<S, P>(
69        &mut self,
70        title: S,
71        default_directory: P,
72    ) -> WVResult<Option<PathBuf>>
73    where
74        S: Into<String>,
75        P: Into<PathBuf>,
76    {
77        self.dialog(
78            title.into(),
79            default_directory.into().to_string_lossy().into_owned(),
80            DialogType::Open,
81            DialogFlags::DIRECTORY,
82        )
83        .map(|path| {
84            if path.is_empty() {
85                None
86            } else {
87                Some(PathBuf::from(path))
88            }
89        })
90    }
91
92    /// Opens an info alert dialog.
93    pub fn info<TS, MS>(&mut self, title: TS, message: MS) -> WVResult
94    where
95        TS: Into<String>,
96        MS: Into<String>,
97    {
98        self.dialog(
99            title.into(),
100            message.into(),
101            DialogType::Alert,
102            DialogFlags::INFO,
103        )
104        .map(|_| ())
105    }
106
107    /// Opens a warning alert dialog.
108    pub fn warning<TS, MS>(&mut self, title: TS, message: MS) -> WVResult
109    where
110        TS: Into<String>,
111        MS: Into<String>,
112    {
113        self.dialog(
114            title.into(),
115            message.into(),
116            DialogType::Alert,
117            DialogFlags::WARNING,
118        )
119        .map(|_| ())
120    }
121
122    /// Opens an error alert dialog.
123    pub fn error<TS, MS>(&mut self, title: TS, message: MS) -> WVResult
124    where
125        TS: Into<String>,
126        MS: Into<String>,
127    {
128        self.dialog(
129            title.into(),
130            message.into(),
131            DialogType::Alert,
132            DialogFlags::ERROR,
133        )
134        .map(|_| ())
135    }
136}