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}