mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-26 16:38:12 +00:00
refactor(eckhart): move pairing cancel button to menu
[no changelog]
This commit is contained in:
parent
a7f6bf5bda
commit
785f52f082
@ -879,8 +879,7 @@ extern "C" fn new_show_pairing_code(n_args: usize, args: *const Obj, kwargs: *mu
|
|||||||
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||||
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||||
let code: TString = kwargs.get(Qstr::MP_QSTR_code)?.try_into()?;
|
let code: TString = kwargs.get(Qstr::MP_QSTR_code)?.try_into()?;
|
||||||
let button: bool = kwargs.get_or(Qstr::MP_QSTR_button, true)?;
|
let layout = ModelUI::show_pairing_code(title, description, code)?;
|
||||||
let layout = ModelUI::show_pairing_code(title, description, code, button)?;
|
|
||||||
let layout_obj = LayoutObj::new_root(layout)?;
|
let layout_obj = LayoutObj::new_root(layout)?;
|
||||||
Ok(layout_obj.into())
|
Ok(layout_obj.into())
|
||||||
};
|
};
|
||||||
@ -1695,7 +1694,6 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
|||||||
/// title: str,
|
/// title: str,
|
||||||
/// description: str,
|
/// description: str,
|
||||||
/// code: str,
|
/// code: str,
|
||||||
/// button: bool = True,
|
|
||||||
/// ) -> LayoutObj[UiResult]:
|
/// ) -> LayoutObj[UiResult]:
|
||||||
/// """Pairing device: second screen (pairing code).
|
/// """Pairing device: second screen (pairing code).
|
||||||
/// Returns on BLEEvent::{PairingCanceled, Disconnected}."""
|
/// Returns on BLEEvent::{PairingCanceled, Disconnected}."""
|
||||||
|
@ -625,6 +625,7 @@ pub enum FlowMsg {
|
|||||||
Next,
|
Next,
|
||||||
Choice(usize),
|
Choice(usize),
|
||||||
Text(ShortString),
|
Text(ShortString),
|
||||||
|
Number(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "micropython")]
|
#[cfg(feature = "micropython")]
|
||||||
@ -640,6 +641,7 @@ impl TryFrom<FlowMsg> for crate::micropython::obj::Obj {
|
|||||||
FlowMsg::Info => Ok(result::INFO.as_obj()),
|
FlowMsg::Info => Ok(result::INFO.as_obj()),
|
||||||
FlowMsg::Choice(i) => i.try_into(),
|
FlowMsg::Choice(i) => i.try_into(),
|
||||||
FlowMsg::Text(s) => s.as_str().try_into(),
|
FlowMsg::Text(s) => s.as_str().try_into(),
|
||||||
|
FlowMsg::Number(i) => i.try_into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,19 @@ use crate::ui::{
|
|||||||
event::BLEEvent,
|
event::BLEEvent,
|
||||||
geometry::Rect,
|
geometry::Rect,
|
||||||
shape::Renderer,
|
shape::Renderer,
|
||||||
|
util::Pager,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(all(feature = "micropython", feature = "touch"))]
|
||||||
|
use crate::ui::{component::swipe_detect::SwipeConfig, flow::Swipable};
|
||||||
|
|
||||||
pub struct BLEHandler<T> {
|
pub struct BLEHandler<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
waiting_for_pairing: bool,
|
waiting_for_pairing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BLEHandlerMsg<T> {
|
pub enum BLEHandlerMsg<TMsg> {
|
||||||
Content(T),
|
Content(TMsg),
|
||||||
PairingCode(u32),
|
PairingCode(u32),
|
||||||
Cancelled,
|
Cancelled,
|
||||||
}
|
}
|
||||||
@ -25,6 +29,19 @@ impl<T> BLEHandler<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "micropython", feature = "touch"))]
|
||||||
|
impl<T> Swipable for BLEHandler<T>
|
||||||
|
where
|
||||||
|
T: Component,
|
||||||
|
{
|
||||||
|
fn get_pager(&self) -> Pager {
|
||||||
|
Pager::single_page()
|
||||||
|
}
|
||||||
|
fn get_swipe_config(&self) -> SwipeConfig {
|
||||||
|
SwipeConfig::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Component for BLEHandler<T>
|
impl<T> Component for BLEHandler<T>
|
||||||
where
|
where
|
||||||
T: Component,
|
T: Component,
|
||||||
|
@ -35,7 +35,7 @@ pub mod timeout;
|
|||||||
pub use bar::Bar;
|
pub use bar::Bar;
|
||||||
pub use base::{Child, Component, ComponentExt, Event, EventCtx, FlowMsg, Never, Timer};
|
pub use base::{Child, Component, ComponentExt, Event, EventCtx, FlowMsg, Never, Timer};
|
||||||
#[cfg(feature = "ble")]
|
#[cfg(feature = "ble")]
|
||||||
pub use ble::BLEHandler;
|
pub use ble::{BLEHandler, BLEHandlerMsg};
|
||||||
pub use border::Border;
|
pub use border::Border;
|
||||||
pub use button_request::{ButtonRequestExt, SendButtonRequest};
|
pub use button_request::{ButtonRequestExt, SendButtonRequest};
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
|
@ -896,14 +896,13 @@ impl FirmwareUI for UIBolt {
|
|||||||
title: TString<'static>,
|
title: TString<'static>,
|
||||||
description: TString<'static>,
|
description: TString<'static>,
|
||||||
code: TString<'static>,
|
code: TString<'static>,
|
||||||
button: bool,
|
|
||||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
Self::confirm_action(
|
Self::confirm_action(
|
||||||
title,
|
title,
|
||||||
Some(code),
|
Some(code),
|
||||||
Some(description),
|
Some(description),
|
||||||
None,
|
None,
|
||||||
button.then_some(TR::buttons__confirm.into()),
|
None,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -1093,7 +1093,6 @@ impl FirmwareUI for UICaesar {
|
|||||||
_title: TString<'static>,
|
_title: TString<'static>,
|
||||||
_description: TString<'static>,
|
_description: TString<'static>,
|
||||||
_code: TString<'static>,
|
_code: TString<'static>,
|
||||||
_button: bool,
|
|
||||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
Err::<RootComponent<Empty, ModelUI>, Error>(Error::ValueError(
|
Err::<RootComponent<Empty, ModelUI>, Error>(Error::ValueError(
|
||||||
c"show_pairing_code not supported",
|
c"show_pairing_code not supported",
|
||||||
|
@ -920,7 +920,6 @@ impl FirmwareUI for UIDelizia {
|
|||||||
_title: TString<'static>,
|
_title: TString<'static>,
|
||||||
_description: TString<'static>,
|
_description: TString<'static>,
|
||||||
_code: TString<'static>,
|
_code: TString<'static>,
|
||||||
_button: bool,
|
|
||||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
Err::<RootComponent<Empty, ModelUI>, Error>(Error::ValueError(
|
Err::<RootComponent<Empty, ModelUI>, Error>(Error::ValueError(
|
||||||
c"show_pairing_code not supported",
|
c"show_pairing_code not supported",
|
||||||
|
@ -13,6 +13,7 @@ pub mod prompt_backup;
|
|||||||
pub mod request_number;
|
pub mod request_number;
|
||||||
pub mod request_passphrase;
|
pub mod request_passphrase;
|
||||||
pub mod show_danger;
|
pub mod show_danger;
|
||||||
|
pub mod show_pairing_code;
|
||||||
pub mod show_share_words;
|
pub mod show_share_words;
|
||||||
|
|
||||||
#[cfg(feature = "universal_fw")]
|
#[cfg(feature = "universal_fw")]
|
||||||
@ -30,4 +31,5 @@ pub use prompt_backup::PromptBackup;
|
|||||||
pub use request_number::new_request_number;
|
pub use request_number::new_request_number;
|
||||||
pub use request_passphrase::RequestPassphrase;
|
pub use request_passphrase::RequestPassphrase;
|
||||||
pub use show_danger::ShowDanger;
|
pub use show_danger::ShowDanger;
|
||||||
|
pub use show_pairing_code::new_show_pairing_code;
|
||||||
pub use show_share_words::new_show_share_words_flow;
|
pub use show_share_words::new_show_share_words_flow;
|
||||||
|
107
core/embed/rust/src/ui/layout_eckhart/flow/show_pairing_code.rs
Normal file
107
core/embed/rust/src/ui/layout_eckhart/flow/show_pairing_code.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
use crate::{
|
||||||
|
error,
|
||||||
|
strutil::TString,
|
||||||
|
translations::TR,
|
||||||
|
ui::{
|
||||||
|
component::{text::op::OpTextLayout, ComponentExt, FormattedText},
|
||||||
|
flow::{
|
||||||
|
base::{Decision, DecisionBuilder as _},
|
||||||
|
FlowController, FlowMsg, SwipeFlow,
|
||||||
|
},
|
||||||
|
geometry::{Alignment, Direction},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "ble")]
|
||||||
|
use crate::ui::component::BLEHandlerMsg;
|
||||||
|
|
||||||
|
use super::super::{
|
||||||
|
component::Button,
|
||||||
|
firmware::{
|
||||||
|
Header, ShortMenuVec, TextScreen, TextScreenMsg, VerticalMenu, VerticalMenuScreen,
|
||||||
|
VerticalMenuScreenMsg,
|
||||||
|
},
|
||||||
|
fonts, theme,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum ShowPairingCode {
|
||||||
|
Main,
|
||||||
|
Menu,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlowController for ShowPairingCode {
|
||||||
|
#[inline]
|
||||||
|
fn index(&'static self) -> usize {
|
||||||
|
*self as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_swipe(&'static self, _direction: Direction) -> Decision {
|
||||||
|
self.do_nothing()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||||
|
match (self, msg) {
|
||||||
|
(Self::Main, FlowMsg::Cancelled) => self.return_msg(FlowMsg::Cancelled),
|
||||||
|
(Self::Main, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||||
|
(Self::Main, FlowMsg::Info) => Self::Menu.goto(),
|
||||||
|
(Self::Main, FlowMsg::Number(pairing_code)) => {
|
||||||
|
self.return_msg(FlowMsg::Number(pairing_code))
|
||||||
|
}
|
||||||
|
(Self::Menu, FlowMsg::Choice(..)) => self.return_msg(FlowMsg::Cancelled),
|
||||||
|
(Self::Menu, FlowMsg::Cancelled) => Self::Main.goto(),
|
||||||
|
_ => self.do_nothing(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_show_pairing_code(
|
||||||
|
title: TString<'static>,
|
||||||
|
description: TString<'static>,
|
||||||
|
code: TString<'static>,
|
||||||
|
) -> Result<SwipeFlow, error::Error> {
|
||||||
|
let mut ops = OpTextLayout::new(theme::firmware::TEXT_REGULAR);
|
||||||
|
ops.add_text(description, fonts::FONT_SATOSHI_REGULAR_38)
|
||||||
|
.add_newline()
|
||||||
|
.add_newline()
|
||||||
|
.add_newline()
|
||||||
|
.add_alignment(Alignment::Center)
|
||||||
|
.add_text(code, fonts::FONT_SATOSHI_EXTRALIGHT_72);
|
||||||
|
let screen =
|
||||||
|
TextScreen::new(FormattedText::new(ops)).with_header(Header::new(title).with_menu_button());
|
||||||
|
|
||||||
|
#[cfg(feature = "ble")]
|
||||||
|
let main_content = crate::ui::component::BLEHandler::new(screen, false).map(|msg| match msg {
|
||||||
|
BLEHandlerMsg::Cancelled => Some(FlowMsg::Cancelled),
|
||||||
|
BLEHandlerMsg::Content(TextScreenMsg::Cancelled) => Some(FlowMsg::Cancelled),
|
||||||
|
BLEHandlerMsg::Content(TextScreenMsg::Confirmed) => Some(FlowMsg::Confirmed),
|
||||||
|
BLEHandlerMsg::Content(TextScreenMsg::Menu) => Some(FlowMsg::Info),
|
||||||
|
BLEHandlerMsg::PairingCode(code) => Some(FlowMsg::Number(code)),
|
||||||
|
});
|
||||||
|
#[cfg(not(feature = "ble"))]
|
||||||
|
let main_content = screen.map(|msg| match msg {
|
||||||
|
TextScreenMsg::Cancelled => Some(FlowMsg::Cancelled),
|
||||||
|
TextScreenMsg::Confirmed => Some(FlowMsg::Confirmed),
|
||||||
|
TextScreenMsg::Menu => Some(FlowMsg::Info),
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut menu = VerticalMenu::<ShortMenuVec>::empty();
|
||||||
|
menu.item(Button::new_menu_item(
|
||||||
|
TR::buttons__cancel.into(),
|
||||||
|
theme::menu_item_title_orange(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let menu_content = VerticalMenuScreen::new(menu)
|
||||||
|
.with_header(Header::new(TString::empty()).with_close_button())
|
||||||
|
.map(move |msg| match msg {
|
||||||
|
VerticalMenuScreenMsg::Selected(i) => Some(FlowMsg::Choice(i)),
|
||||||
|
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut flow = SwipeFlow::new(&ShowPairingCode::Main)?;
|
||||||
|
flow.add_page(&ShowPairingCode::Main, main_content)?
|
||||||
|
.add_page(&ShowPairingCode::Menu, menu_content)?;
|
||||||
|
|
||||||
|
Ok(flow)
|
||||||
|
}
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
ComponentExt as _, Empty, FormattedText, Timeout,
|
ComponentExt as _, Empty, FormattedText, Timeout,
|
||||||
},
|
},
|
||||||
geometry::{Alignment, LinearPlacement, Offset},
|
geometry::{LinearPlacement, Offset},
|
||||||
layout::{
|
layout::{
|
||||||
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
||||||
util::{ConfirmValueParams, PropsList, RecoveryType, StrOrBytes},
|
util::{ConfirmValueParams, PropsList, RecoveryType, StrOrBytes},
|
||||||
@ -1083,27 +1083,9 @@ impl FirmwareUI for UIEckhart {
|
|||||||
title: TString<'static>,
|
title: TString<'static>,
|
||||||
description: TString<'static>,
|
description: TString<'static>,
|
||||||
code: TString<'static>,
|
code: TString<'static>,
|
||||||
button: bool,
|
|
||||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
let mut ops = OpTextLayout::new(theme::firmware::TEXT_REGULAR);
|
let flow = flow::show_pairing_code::new_show_pairing_code(title, description, code)?;
|
||||||
ops.add_text(description, fonts::FONT_SATOSHI_REGULAR_38)
|
Ok(flow)
|
||||||
.add_newline()
|
|
||||||
.add_newline()
|
|
||||||
.add_newline()
|
|
||||||
.add_alignment(Alignment::Center)
|
|
||||||
.add_text(code, fonts::FONT_SATOSHI_EXTRALIGHT_72);
|
|
||||||
let mut screen = TextScreen::new(FormattedText::new(ops));
|
|
||||||
if button {
|
|
||||||
screen = screen
|
|
||||||
.with_header(Header::new(title))
|
|
||||||
.with_action_bar(ActionBar::new_cancel_confirm());
|
|
||||||
} else {
|
|
||||||
screen = screen.with_header(Header::new(title).with_close_button());
|
|
||||||
}
|
|
||||||
#[cfg(feature = "ble")]
|
|
||||||
let screen = crate::ui::component::BLEHandler::new(screen, false);
|
|
||||||
let layout = RootComponent::new(screen);
|
|
||||||
Ok(layout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_info(
|
fn show_info(
|
||||||
|
@ -329,7 +329,6 @@ pub trait FirmwareUI {
|
|||||||
title: TString<'static>,
|
title: TString<'static>,
|
||||||
description: TString<'static>,
|
description: TString<'static>,
|
||||||
code: TString<'static>,
|
code: TString<'static>,
|
||||||
button: bool,
|
|
||||||
) -> Result<impl LayoutMaybeTrace, Error>;
|
) -> Result<impl LayoutMaybeTrace, Error>;
|
||||||
|
|
||||||
fn show_info(
|
fn show_info(
|
||||||
|
@ -576,7 +576,6 @@ def show_pairing_code(
|
|||||||
title: str,
|
title: str,
|
||||||
description: str,
|
description: str,
|
||||||
code: str,
|
code: str,
|
||||||
button: bool = True,
|
|
||||||
) -> LayoutObj[UiResult]:
|
) -> LayoutObj[UiResult]:
|
||||||
"""Pairing device: second screen (pairing code).
|
"""Pairing device: second screen (pairing code).
|
||||||
Returns on BLEEvent::{PairingCanceled, Disconnected}."""
|
Returns on BLEEvent::{PairingCanceled, Disconnected}."""
|
||||||
|
@ -32,7 +32,6 @@ async def pair_new_device() -> None:
|
|||||||
title="Bluetooth pairing",
|
title="Bluetooth pairing",
|
||||||
description="Pairing code match?",
|
description="Pairing code match?",
|
||||||
code=f"{code:0>6}",
|
code=f"{code:0>6}",
|
||||||
button=True,
|
|
||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user