nvdialog_rs/
dialog_box.rs

1/*
2 *  The MIT License (MIT)
3 *
4 *  Copyright (c) 2022-2025 Aggelos Tselios
5 *
6 *  Permission is hereby granted, free of charge, to any person obtaining a copy
7 *  of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 *  furnished to do so, subject to the following conditions:
12 *
13 *  The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25use crate::{Error, Object};
26use nvdialog_sys::ffi::*;
27use std::ffi::{c_void, CString};
28
29/// An enumeration of the different types of dialogs that can be created.
30///
31/// This enum is used to specify the type of dialog to be created when calling
32/// the appropriate dialog creation functions. The different variants represent
33/// different types of dialogs that can be used to communicate with the user.
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum DialogType {
36    /// A simple dialog box with no specific type.
37    Simple,
38    /// A warning dialog box, indicating that the user should be cautious or take
39    /// extra care when performing the action.
40    Warning,
41    /// An error dialog box, indicating that an error has occurred and the user should
42    /// take some action to resolve it.
43    Error,
44}
45
46/// A struct representing a dialog box.
47///
48/// This struct provides a simple interface for creating and showing different types of dialog
49/// boxes, such as message boxes or question boxes. Once a dialog box is created using the
50/// `DialogBox::new` method, it can be shown to the user using the `DialogBox::show` method.
51///
52/// # Examples
53///
54/// Showing a simple dialog box:
55///
56/// ```
57/// use my_{DialogBox, DialogType};
58///
59/// let mut dialog_box = DialogBox::new("My App", "Hello World", DialogType::Simple);
60/// dialog_box.show();
61/// ```
62///
63/// # Safety
64/// Showing the same dialog box more than once is **undefined behavior** and depending on
65/// the platform, may or may not raise an error.
66/// # FFI
67/// Corresponds to `NvdDialogBox`.
68pub struct DialogBox {
69    raw: *mut NvdDialogBox,
70}
71
72impl DialogBox {
73    /// Creates a new instance of `DialogBox` with the given `title`, `msg` and `dialog_type`.
74    ///
75    /// # Arguments
76    ///
77    /// * `title` - The title of the dialog box.
78    ///
79    /// * `msg` - The message to display in the dialog box.
80    ///
81    /// * `dialog_type` - The type of dialog box to display, either `Simple`, `Warning` or `Error`.
82    ///
83    /// # Returns
84    ///
85    /// Returns `Ok(DialogBox)` if the dialog box was successfully created, otherwise
86    /// returns `Err(Error)` with the error converted from NvDialog's error code.
87    ///
88    /// # Panics
89    /// This function will panic if `CString::new` fails to convert the given `title` or `msg`
90    /// to a null-terminated byte string.
91    pub fn new<S: AsRef<str>>(title: S, msg: S, dialog_type: DialogType) -> Result<Self, Error> {
92        let _type = match dialog_type {
93            DialogType::Simple => 0xff,
94            DialogType::Warning => 0xff + 1,
95            DialogType::Error => 0xff + 2,
96        };
97
98        let title = CString::new(title.as_ref()).expect("CString::new error");
99        let msg = CString::new(msg.as_ref()).expect("CString::new error");
100
101        let raw = unsafe {
102            let raw = nvd_dialog_box_new(title.as_ptr(), msg.as_ptr(), _type);
103            if raw.is_null() {
104                return Err(Error::from(nvd_get_error() as i32));
105            }
106            raw
107        };
108
109        Ok(Self { raw })
110    }
111
112    pub fn set_accept_label<S: AsRef<str>>(&mut self, label: S) {
113        let label = CString::new(label.as_ref()).expect("CString::new error");
114        unsafe {
115            nvd_dialog_box_set_accept_text(self.raw, label.as_ptr());
116        }
117    }
118}
119
120impl Object for DialogBox {
121    type NativeType = NvdDialogBox;
122    type ReturnValue = ();
123
124    fn get_raw(&self) -> *mut Self::NativeType {
125        self.raw
126    }
127
128    fn show(&self) {
129        unsafe {
130            nvd_show_dialog(self.raw);
131        }
132    }
133
134    fn free(&mut self) {
135        unsafe {
136            nvd_free_object(self.raw as *mut c_void);
137        }
138    }
139}
140
141impl Drop for DialogBox {
142    fn drop(&mut self) {
143        self.free();
144    }
145}