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
//! A wrapper around the asynchronous NBGL [nbgl_useCaseAction](https://github.com/LedgerHQ/ledger-secure-sdk/blob/master/lib_nbgl/src/nbgl_use_case.c#L3730) C API binding.
//!
//! Draws a page to represent an action, described in a centered info (with given icon),
//! thanks to a button at the bottom of the page.
use super::*;
/// A builder to create and show an action page.
pub struct NbglAction<'a> {
message: CString,
action_text: CString,
glyph: Option<&'a NbglGlyph<'a>>,
}
impl SyncNBGL for NbglAction<'_> {}
impl<'a> NbglAction<'a> {
/// Creates a new action page builder.
pub fn new() -> NbglAction<'a> {
NbglAction {
message: CString::default(),
action_text: CString::default(),
glyph: None,
}
}
/// Sets the message to display in the center of the page.
/// # Arguments
/// * `message` - The main message to display in the center of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn message(self, message: &'a str) -> NbglAction<'a> {
NbglAction {
message: CString::new(message).unwrap(),
..self
}
}
/// Sets the text to display on the button at the bottom of the page.
/// # Arguments
/// * `action_text` - The text to display on the button at the bottom of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn action_text(self, action_text: &'a str) -> NbglAction<'a> {
NbglAction {
action_text: CString::new(action_text).unwrap(),
..self
}
}
/// Sets the icon to display in the center of the page.
/// # Arguments
/// * `glyph` - The icon to display in the center of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn glyph(self, glyph: &'a NbglGlyph<'a>) -> NbglAction<'a> {
NbglAction {
glyph: Some(glyph),
..self
}
}
fn show_internal(self) -> SyncNbgl {
unsafe {
let icon: nbgl_icon_details_t = match self.glyph {
Some(g) => g.into(),
None => nbgl_icon_details_t::default(),
};
self.ux_sync_init();
nbgl_useCaseAction(
&icon as *const nbgl_icon_details_t,
self.message.as_ptr() as *const c_char,
self.action_text.as_ptr() as *const c_char,
Some(continue_callback),
);
self.ux_sync_wait(false)
}
}
/// Shows the action page.
/// # Returns
/// Returns `Ok(())` when the action button is pressed,
/// or `Err(u8)` with the error code in case of an error.
#[cfg(feature = "io_new")]
pub fn show<const N: usize>(self, _comm: &mut crate::io::Comm<N>) -> Result<(), u8> {
let ret = self.show_internal();
match ret {
SyncNbgl::UxSyncRetContinue => Ok(()),
_ => Err(u8::from(ret)),
}
}
/// Shows the action page.
#[cfg(not(feature = "io_new"))]
pub fn show(self) -> SyncNbgl {
self.show_internal()
}
}