toast/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
//! This crate provides a simplified mechanism for producing native modal
//! dialog toast messages to the underlying system.
//!
//! Dialogs are formed by creating basic builders which will ultimately create
//! and show the modal dialog until the user responds to the message.
//!
//! This has been achieved through the [`boxer_sys`] Crate, which wraps the
//! original C++ Boxer library in C bindings.
#![deny(missing_docs)]
#![deny(unused_results)]
#![deny(rust_2018_idioms)]
use boxer_sys as c;
/// The button that was selected by the user
pub enum Selection {
/// The user selected OK from an [`Buttons::OK`] or [`Buttons::OKCancel`]
OK,
/// The user selected Cancel from an [`Buttons::OKCancel`]
Cancel,
/// The user selected "Yes" from a [`Buttons::YesNo`]
Yes,
/// The user selected "No" from a [`Buttons::YesNo`]
No,
/// The user selected "Quit" from a [`Buttons::Quit`]
Quit,
/// The user did not select a button
None,
/// An internal error occurred.
Error,
}
impl Selection {
fn from_c(value: c::BoxerSelection) -> Self {
match value {
c::BoxerSelection_OKSelection => Self::OK,
c::BoxerSelection_CancelSelection => Self::Cancel,
c::BoxerSelection_YesSelection => Self::Yes,
c::BoxerSelection_NoSelection => Self::No,
c::BoxerSelection_QuitSelection => Self::Quit,
c::BoxerSelection_NoneSelection => Self::None,
c::BoxerSelection_ErrorSelection => Self::Error,
_ => Self::Error,
}
}
}
/// The buttons to present to the user.
pub enum Buttons {
/// A typical dialog with just an "OK" button.
OK,
/// A typical dialog with "OK" or "Cancel" buttons.
OKCancel,
/// A question dialog box with "Yes" or "No" buttons.
YesNo,
/// A dialog that only offers a "quit" button
Quit,
}
impl Buttons {
fn to_c(&self) -> c::BoxerButtons {
match self {
Self::OK => c::BoxerButtons_OKButtons,
Self::OKCancel => c::BoxerButtons_OKCancelButtons,
Self::YesNo => c::BoxerButtons_YesNoButtons,
Self::Quit => c::BoxerButtons_QuitButtons,
}
}
}
/// The style that the window should be created in.
enum Style {
Info,
Warning,
Error,
Question,
}
impl Style {
fn to_c(&self) -> c::BoxerStyle {
match self {
Self::Info => c::BoxerStyle_InfoStyle,
Self::Warning => c::BoxerStyle_WarningStyle,
Self::Error => c::BoxerStyle_ErrorStyle,
Self::Question => c::BoxerStyle_QuestionStyle,
}
}
}
use std::ffi::CStr;
/// The main builder class for creating a dialog window.
pub struct ToastBuilder<'a, 'b> {
style: Style,
title: &'a CStr,
message: &'b CStr,
buttons: Buttons,
}
impl<'a, 'b> ToastBuilder<'a, 'b> {
/// Create an info toast builder
pub fn info() -> Self {
Self::from_style(Style::Info)
}
/// Creates a warning toast builder
pub fn warning() -> Self {
Self::from_style(Style::Warning)
}
/// Creates an error toast builder
pub fn error() -> Self {
Self::from_style(Style::Error)
}
/// Creates a question toast builder
pub fn question() -> Self {
Self::from_style(Style::Question)
}
/// Sets the message string to display to the user.
///
/// # Parameters
///
/// * `message` - the message [`CStr`]` to display.
pub fn message_cstr(mut self, message: &'b CStr) -> Self {
self.message = message;
self
}
/// Sets the title string to display to the user.
///
/// # Parameters
///
/// * `title` - the title [`CStr`]` to use.
pub fn title_cstr(mut self, title: &'a CStr) -> Self {
self.title = title;
self
}
/// Sets the button style to display to the user.
///
/// # Parameters
///
/// * `buttons` - the buttons to display to the user.
pub fn buttons(mut self, buttons: Buttons) -> Self {
self.buttons = buttons;
self
}
/// Show the window
pub fn show(self) -> Selection {
Selection::from_c(unsafe {
Self::show_cstr(self.message, self.title, self.style, self.buttons)
})
}
/// Creates a builder with sensible defaults in the given style.
///
/// # Parameters
///
/// * `s` - the style to create a builder for
fn from_style(s: Style) -> Self {
Self {
style: s,
title: astd::ffi::cstr!("untitled"),
message: astd::ffi::cstr!(""),
buttons: Buttons::OK,
}
}
/// Shows the underlying message to the user.
unsafe fn show_cstr(message: &CStr, title: &CStr, style: Style, buttons: Buttons) -> u32 {
c::boxer_show(
message.as_ptr(),
title.as_ptr(),
style.to_c(),
buttons.to_c(),
)
}
}