mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-13 06:36:06 +00:00
feat(eckhart): full-screen QR screen component
This commit is contained in:
parent
8adc45d296
commit
89d9a066f3
@ -4,6 +4,7 @@ mod hint;
|
||||
mod hold_to_confirm;
|
||||
mod keyboard;
|
||||
mod number_input_screen;
|
||||
mod qr_screen;
|
||||
mod select_word_screen;
|
||||
mod share_words;
|
||||
mod text_screen;
|
||||
@ -24,6 +25,7 @@ pub use keyboard::{
|
||||
word_count_screen::{SelectWordCountMsg, SelectWordCountScreen},
|
||||
};
|
||||
pub use number_input_screen::{NumberInputScreen, NumberInputScreenMsg};
|
||||
pub use qr_screen::{QrMsg, QrScreen};
|
||||
pub use select_word_screen::{SelectWordMsg, SelectWordScreen};
|
||||
#[cfg(feature = "translations")]
|
||||
pub use share_words::{ShareWordsScreen, ShareWordsScreenMsg};
|
||||
|
134
core/embed/rust/src/ui/layout_eckhart/firmware/qr_screen.rs
Normal file
134
core/embed/rust/src/ui/layout_eckhart/firmware/qr_screen.rs
Normal file
@ -0,0 +1,134 @@
|
||||
use crate::{
|
||||
strutil::TString,
|
||||
ui::{
|
||||
component::{swipe_detect::SwipeConfig, Component, Event, EventCtx, Qr},
|
||||
flow::Swipable,
|
||||
geometry::{Insets, Rect},
|
||||
shape::{self, Renderer},
|
||||
util::Pager,
|
||||
},
|
||||
};
|
||||
|
||||
use super::super::{
|
||||
firmware::{theme, ActionBar, Header, HeaderMsg},
|
||||
constant::SCREEN,
|
||||
};
|
||||
|
||||
pub enum QrMsg {
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
pub struct QrScreen {
|
||||
header: Header,
|
||||
qr: Qr,
|
||||
action_bar: Option<ActionBar>,
|
||||
pad: Rect,
|
||||
}
|
||||
|
||||
impl QrScreen {
|
||||
const QR_PADDING: i16 = 8;
|
||||
const QR_HEIGHT: i16 = 300;
|
||||
const QR_PAD_RADIUS: i16 = 12;
|
||||
|
||||
pub fn new(qr: Qr) -> Self {
|
||||
Self {
|
||||
header: Header::new(TString::empty()),
|
||||
qr,
|
||||
action_bar: None,
|
||||
pad: Rect::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_header(mut self, header: Header) -> Self {
|
||||
self.header = header;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_action_bar(mut self, action_bar: ActionBar) -> Self {
|
||||
self.action_bar = Some(action_bar);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for QrScreen {
|
||||
type Msg = QrMsg;
|
||||
|
||||
fn place(&mut self, bounds: Rect) -> Rect {
|
||||
// assert full screen
|
||||
debug_assert_eq!(bounds.height(), SCREEN.height());
|
||||
debug_assert_eq!(bounds.width(), SCREEN.width());
|
||||
|
||||
let (header_area, mut rest) = bounds.split_top(Header::HEADER_HEIGHT);
|
||||
if let Some(action_bar) = &mut self.action_bar {
|
||||
let action_bar_area;
|
||||
(rest, action_bar_area) = rest.split_bottom(ActionBar::ACTION_BAR_HEIGHT);
|
||||
action_bar.place(action_bar_area);
|
||||
}
|
||||
let (qr_pad, _) = rest.split_top(Self::QR_HEIGHT + 2 * Self::QR_PADDING);
|
||||
|
||||
let side_padding = (SCREEN.width() - Self::QR_HEIGHT - 2 * Self::QR_PADDING) / 2;
|
||||
let qr_pad = qr_pad.inset(Insets::sides(side_padding));
|
||||
|
||||
self.pad = qr_pad;
|
||||
|
||||
self.header.place(header_area);
|
||||
self.qr.place(qr_pad.shrink(Self::QR_PADDING));
|
||||
|
||||
bounds
|
||||
}
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||
if let Some(HeaderMsg::Cancelled) = self.header.event(ctx, event) {
|
||||
return Some(QrMsg::Cancelled);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||
// Render white QR pad
|
||||
shape::Bar::new(self.pad)
|
||||
.with_bg(theme::FG)
|
||||
.with_fg(theme::FG)
|
||||
.with_radius(Self::QR_PAD_RADIUS)
|
||||
.render(target);
|
||||
|
||||
self.header.render(target);
|
||||
self.qr.render(target);
|
||||
self.action_bar.render(target);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "micropython")]
|
||||
impl Swipable for QrScreen {
|
||||
fn get_swipe_config(&self) -> SwipeConfig {
|
||||
SwipeConfig::new()
|
||||
}
|
||||
|
||||
fn get_pager(&self) -> Pager {
|
||||
Pager::single_page()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl crate::trace::Trace for QrScreen {
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.component("QrScreen");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{super::super::constant::SCREEN, *};
|
||||
|
||||
#[test]
|
||||
fn test_component_heights_fit_screen() {
|
||||
assert!(
|
||||
QrScreen::QR_HEIGHT
|
||||
+ 2 * QrScreen::QR_PADDING
|
||||
+ Header::HEADER_HEIGHT
|
||||
+ ActionBar::ACTION_BAR_HEIGHT
|
||||
<= SCREEN.height(),
|
||||
"Components overflow the screen height",
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user