mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-23 23:18:16 +00:00
feat(eckhart): bld wireless setup screen
[no changelog]
This commit is contained in:
parent
cf1e892d13
commit
0e2b4f4d5c
@ -11,6 +11,8 @@ mod pairing_finalization;
|
|||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
mod pairing_mode;
|
mod pairing_mode;
|
||||||
mod welcome_screen;
|
mod welcome_screen;
|
||||||
|
#[cfg(feature = "ble")]
|
||||||
|
mod wireless_setup_screen;
|
||||||
|
|
||||||
pub use bld_actionbar::{BldActionBar, BldActionBarMsg};
|
pub use bld_actionbar::{BldActionBar, BldActionBarMsg};
|
||||||
pub use bld_header::{BldHeader, BldHeaderMsg};
|
pub use bld_header::{BldHeader, BldHeaderMsg};
|
||||||
@ -24,5 +26,7 @@ pub use connect::ConnectScreen;
|
|||||||
pub use pairing_finalization::PairingFinalizationScreen;
|
pub use pairing_finalization::PairingFinalizationScreen;
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
pub use pairing_mode::PairingModeScreen;
|
pub use pairing_mode::PairingModeScreen;
|
||||||
|
#[cfg(feature = "ble")]
|
||||||
|
pub use wireless_setup_screen::WirelessSetupScreen;
|
||||||
|
|
||||||
pub use welcome_screen::BldWelcomeScreen;
|
pub use welcome_screen::BldWelcomeScreen;
|
||||||
|
@ -0,0 +1,170 @@
|
|||||||
|
use crate::{
|
||||||
|
strutil::TString,
|
||||||
|
ui::{
|
||||||
|
component::{Component, Event, EventCtx, Label},
|
||||||
|
event::BLEEvent,
|
||||||
|
geometry::{Alignment2D, Insets, Offset, Rect},
|
||||||
|
shape::{self, Renderer},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
super::{component::Button, constant::SCREEN, theme},
|
||||||
|
pairing_mode::PairingMsg,
|
||||||
|
BldActionBar, BldActionBarMsg, BldHeader, BldHeaderMsg,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Full-screen component for the wireless setup screen. It shows instructions
|
||||||
|
/// for the user and QR code to download the Trezor Suite app.
|
||||||
|
pub struct WirelessSetupScreen {
|
||||||
|
/// Header with the device name
|
||||||
|
header: BldHeader<'static>,
|
||||||
|
/// Instruction text for the user
|
||||||
|
instruction: Label<'static>,
|
||||||
|
/// Area for the QR code
|
||||||
|
qr_area: Rect,
|
||||||
|
/// Action bar to invoke more info
|
||||||
|
action_bar: BldActionBar,
|
||||||
|
/// More info section that can be toggled
|
||||||
|
more_info: MoreInfo<'static>,
|
||||||
|
/// Flag to indicate if the more info section is currently showing
|
||||||
|
more_info_showing: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MoreInfo<'a> {
|
||||||
|
header: BldHeader<'a>,
|
||||||
|
instruction_primary: Label<'a>,
|
||||||
|
instruction_secondary: Label<'a>,
|
||||||
|
action_bar: BldActionBar,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WirelessSetupScreen {
|
||||||
|
pub fn new(name: TString<'static>) -> Self {
|
||||||
|
let instruction = Label::left_aligned(
|
||||||
|
"Get the Trezor Suite app to begin setup.".into(),
|
||||||
|
theme::TEXT_NORMAL,
|
||||||
|
);
|
||||||
|
let btn = Button::with_text("More info".into()).styled(theme::button_default());
|
||||||
|
let btn_more_info = Button::with_text("More at trezor.io/start".into())
|
||||||
|
.styled(theme::button_default())
|
||||||
|
.initially_enabled(false);
|
||||||
|
let more_info = MoreInfo {
|
||||||
|
header: BldHeader::new("More info".into()).with_close_button(),
|
||||||
|
instruction_primary: Label::left_aligned(
|
||||||
|
"The Trezor Suite app is required to set up your Trezor.".into(),
|
||||||
|
theme::TEXT_NORMAL,
|
||||||
|
),
|
||||||
|
instruction_secondary: Label::left_aligned(
|
||||||
|
"Setup via USB-C isn't supported on Apple devices running iOS or iPadOS.".into(),
|
||||||
|
theme::TEXT_SMALL_GREY,
|
||||||
|
),
|
||||||
|
action_bar: BldActionBar::new_single(btn_more_info),
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
header: BldHeader::new(name),
|
||||||
|
instruction,
|
||||||
|
qr_area: Rect::zero(),
|
||||||
|
action_bar: BldActionBar::new_single(btn),
|
||||||
|
more_info,
|
||||||
|
more_info_showing: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_qr_code<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
|
if self.qr_area.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let qr_code_size = theme::bootloader::ICON_QR_TREZOR_IO_START.toif.width();
|
||||||
|
let padding = 20;
|
||||||
|
let qr_code_pad_size = qr_code_size + padding;
|
||||||
|
let pad_area = Rect::snap(
|
||||||
|
self.qr_area.center(),
|
||||||
|
Offset::new(qr_code_pad_size, qr_code_pad_size),
|
||||||
|
Alignment2D::CENTER,
|
||||||
|
);
|
||||||
|
|
||||||
|
shape::Bar::new(pad_area)
|
||||||
|
.with_fg(theme::WHITE)
|
||||||
|
.with_bg(theme::WHITE)
|
||||||
|
.with_radius(4)
|
||||||
|
.render(target);
|
||||||
|
// TODO: uncomment on space bump
|
||||||
|
// shape::ToifImage::new(
|
||||||
|
// pad_area.center(),
|
||||||
|
// theme::bootloader::ICON_QR_TREZOR_IO_START.toif,
|
||||||
|
// )
|
||||||
|
// .with_align(Alignment2D::CENTER)
|
||||||
|
// .with_fg(theme::WHITE)
|
||||||
|
// .with_bg(theme::BLACK)
|
||||||
|
// .render(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for WirelessSetupScreen {
|
||||||
|
type Msg = PairingMsg;
|
||||||
|
|
||||||
|
fn place(&mut self, _bounds: Rect) -> Rect {
|
||||||
|
let (header_area, rest) = SCREEN.split_top(theme::HEADER_HEIGHT);
|
||||||
|
let (content_area, action_bar_area) = rest.split_bottom(theme::ACTION_BAR_HEIGHT);
|
||||||
|
// let content_area = content_area.inset(theme::SIDE_INSETS);
|
||||||
|
let content_area = content_area.inset(Insets::sides(20));
|
||||||
|
|
||||||
|
self.header.place(header_area);
|
||||||
|
self.instruction.place(content_area);
|
||||||
|
self.action_bar.place(action_bar_area);
|
||||||
|
// remaining space is used for the QR code which will be rendered in the center
|
||||||
|
self.qr_area = content_area.inset(Insets::top(
|
||||||
|
self.instruction.text_height(content_area.width()) + 32,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Place the toggled MoreInfo sections accordingly
|
||||||
|
self.more_info.header.place(header_area);
|
||||||
|
self.more_info.instruction_primary.place(content_area);
|
||||||
|
self.more_info.instruction_secondary.place(
|
||||||
|
content_area.inset(Insets::top(
|
||||||
|
self.more_info
|
||||||
|
.instruction_primary
|
||||||
|
.text_height(content_area.width())
|
||||||
|
+ 32,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
self.more_info.action_bar.place(action_bar_area);
|
||||||
|
SCREEN
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||||
|
if let Some(BldActionBarMsg::Confirmed) = self.action_bar.event(ctx, event) {
|
||||||
|
self.more_info_showing = true;
|
||||||
|
}
|
||||||
|
if let Some(BldHeaderMsg::Cancelled) = self.more_info.header.event(ctx, event) {
|
||||||
|
self.more_info_showing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Event::BLE(BLEEvent::PairingRequest(code)) = event {
|
||||||
|
return Some(PairingMsg::Pairing(code));
|
||||||
|
}
|
||||||
|
if let Event::BLE(BLEEvent::PairingCanceled) = event {
|
||||||
|
return Some(PairingMsg::Cancel);
|
||||||
|
}
|
||||||
|
if let Event::BLE(BLEEvent::Disconnected) = event {
|
||||||
|
return Some(PairingMsg::Cancel);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
|
if self.more_info_showing {
|
||||||
|
self.more_info.header.render(target);
|
||||||
|
self.more_info.instruction_primary.render(target);
|
||||||
|
self.more_info.instruction_secondary.render(target);
|
||||||
|
self.more_info.action_bar.render(target);
|
||||||
|
} else {
|
||||||
|
self.header.render(target);
|
||||||
|
self.instruction.render(target);
|
||||||
|
self.action_bar.render(target);
|
||||||
|
self.render_qr_code(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
@ -9,8 +9,8 @@ use super::{
|
|||||||
component::{ButtonStyle, ButtonStyleSheet},
|
component::{ButtonStyle, ButtonStyleSheet},
|
||||||
fonts,
|
fonts,
|
||||||
},
|
},
|
||||||
BLACK, BLUE, GREEN_LIGHT, GREY, GREY_DARK, GREY_EXTRA_LIGHT, GREY_LIGHT, GREY_SUPER_DARK,
|
BLACK, BLUE, GREY, GREY_DARK, GREY_EXTRA_LIGHT, GREY_LIGHT, GREY_SUPER_DARK, ORANGE, RED,
|
||||||
ORANGE, RED, WHITE,
|
WHITE,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const BLD_BG: Color = BLACK;
|
pub const BLD_BG: Color = BLACK;
|
||||||
@ -20,6 +20,7 @@ pub const WELCOME_COLOR: Color = BLACK;
|
|||||||
|
|
||||||
// UI icons specific to bootloader (white color)
|
// UI icons specific to bootloader (white color)
|
||||||
include_icon!(ICON_SEVEN, "layout_eckhart/res/bootloader/7.toif");
|
include_icon!(ICON_SEVEN, "layout_eckhart/res/bootloader/7.toif");
|
||||||
|
// alternatively: "layout_eckhart/res/bootloader/QRCode_smaller.toif"
|
||||||
include_icon!(
|
include_icon!(
|
||||||
ICON_QR_TREZOR_IO_START,
|
ICON_QR_TREZOR_IO_START,
|
||||||
"layout_eckhart/res/bootloader/QRCode.toif"
|
"layout_eckhart/res/bootloader/QRCode.toif"
|
||||||
@ -198,12 +199,11 @@ pub fn button_welcome_screen() -> ButtonStyleSheet {
|
|||||||
icon_color: GREY_EXTRA_LIGHT,
|
icon_color: GREY_EXTRA_LIGHT,
|
||||||
background_color: BLD_BG,
|
background_color: BLD_BG,
|
||||||
},
|
},
|
||||||
// used for the "Trezor is paired" button/footer
|
|
||||||
disabled: &ButtonStyle {
|
disabled: &ButtonStyle {
|
||||||
font: fonts::FONT_SATOSHI_MEDIUM_26,
|
font: fonts::FONT_SATOSHI_MEDIUM_26,
|
||||||
text_color: GREEN_LIGHT,
|
text_color: GREY,
|
||||||
button_color: BLD_BG,
|
button_color: BLD_BG,
|
||||||
icon_color: GREEN_LIGHT,
|
icon_color: GREY,
|
||||||
background_color: BLD_FG,
|
background_color: BLD_FG,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ use ufmt::uwrite;
|
|||||||
use super::{
|
use super::{
|
||||||
bootloader::{
|
bootloader::{
|
||||||
BldActionBar, BldHeader, BldHeaderMsg, BldMenuScreen, BldTextScreen, BldWelcomeScreen,
|
BldActionBar, BldHeader, BldHeaderMsg, BldMenuScreen, BldTextScreen, BldWelcomeScreen,
|
||||||
ConnectScreen,
|
ConnectScreen, WirelessSetupScreen,
|
||||||
},
|
},
|
||||||
component::Button,
|
component::Button,
|
||||||
cshape::{render_loader, ScreenBorder},
|
cshape::{render_loader, ScreenBorder},
|
||||||
@ -94,7 +94,7 @@ pub enum BootloaderLayout {
|
|||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
PairingMode(PairingModeScreen),
|
PairingMode(PairingModeScreen),
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
WirelessSetup(PairingModeScreen),
|
WirelessSetup(WirelessSetupScreen),
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
WirelessSetupFinal(ConnectScreen),
|
WirelessSetupFinal(ConnectScreen),
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ impl BootloaderLayoutType for BootloaderLayout {
|
|||||||
BootloaderLayout::PairingMode(f) => process_frame_event::<PairingModeScreen>(f, event),
|
BootloaderLayout::PairingMode(f) => process_frame_event::<PairingModeScreen>(f, event),
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
BootloaderLayout::WirelessSetup(f) => {
|
BootloaderLayout::WirelessSetup(f) => {
|
||||||
process_frame_event::<PairingModeScreen>(f, event)
|
process_frame_event::<WirelessSetupScreen>(f, event)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
BootloaderLayout::WirelessSetupFinal(f) => {
|
BootloaderLayout::WirelessSetupFinal(f) => {
|
||||||
@ -169,11 +169,7 @@ impl BootloaderLayoutType for BootloaderLayout {
|
|||||||
|
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
fn init_wireless_setup(name: &'static str) -> Self {
|
fn init_wireless_setup(name: &'static str) -> Self {
|
||||||
// todo implement correct UI
|
let screen = WirelessSetupScreen::new(name.into());
|
||||||
let btn = Button::with_text("Cancel".into()).styled(button_default());
|
|
||||||
|
|
||||||
let screen = PairingModeScreen::new("QR_CODE".into(), name.into())
|
|
||||||
.with_action_bar(BldActionBar::new_single(btn));
|
|
||||||
Self::WirelessSetup(screen)
|
Self::WirelessSetup(screen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user