1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-19 05:58:09 +00:00

refactor(core/mercury): extract non-generic code from frame component

[no changelog]
This commit is contained in:
tychovrahe 2024-07-14 13:12:32 +02:00 committed by TychoVrahe
parent f2bdd6e189
commit 873658104d
4 changed files with 86 additions and 68 deletions

View File

@ -45,11 +45,14 @@ impl<'a> Footer<'a> {
const STYLE_INSTRUCTION: &'static TextStyle = &theme::TEXT_SUB_GREY;
const STYLE_DESCRIPTION: &'static TextStyle = &theme::TEXT_SUB_GREY_LIGHT;
pub fn new<T: Into<TString<'a>>>(instruction: T) -> Self {
pub fn new<T: Into<TString<'a>>>(
instruction: T,
description: Option<TString<'static>>,
) -> Self {
Self {
area: Rect::zero(),
instruction: instruction.into(),
content: None,
content: description.map(FooterContent::Description),
swipe_allow_down: false,
swipe_allow_up: false,
progress: 0,
@ -57,13 +60,6 @@ impl<'a> Footer<'a> {
}
}
pub fn with_description<T: Into<TString<'a>>>(self, description: T) -> Self {
Self {
content: Some(FooterContent::Description(description.into())),
..self
}
}
pub fn with_page_counter(self, max_pages: u8) -> Self {
Self {
content: Some(FooterContent::PageCounter(PageCounter::new(max_pages))),
@ -110,16 +106,17 @@ impl<'a> Footer<'a> {
}
}
pub fn with_swipe_up(self) -> Self {
Self {
swipe_allow_up: true,
..self
}
}
pub fn with_swipe_down(self) -> Self {
Self {
swipe_allow_down: true,
..self
pub fn with_swipe(self, swipe_direction: SwipeDirection) -> Self {
match swipe_direction {
SwipeDirection::Up => Self {
swipe_allow_up: true,
..self
},
SwipeDirection::Down => Self {
swipe_allow_down: true,
..self
},
_ => self,
}
}
}

View File

@ -1,4 +1,4 @@
use super::{theme, ButtonMsg, ButtonStyleSheet, CancelInfoConfirmMsg, Footer, Header};
use super::{theme, ButtonStyleSheet, CancelInfoConfirmMsg, Footer, Header};
use crate::{
strutil::TString,
ui::{
@ -84,7 +84,6 @@ impl HorizontalSwipe {
pub struct Frame<T> {
border: Insets,
bounds: Rect,
button_msg: CancelInfoConfirmMsg,
content: T,
header: Header,
footer: Option<Footer<'static>>,
@ -106,7 +105,6 @@ where
Self {
bounds: Rect::zero(),
border: theme::borders(),
button_msg: CancelInfoConfirmMsg::Cancelled,
content,
header: Header::new(alignment, title),
footer: None,
@ -145,8 +143,7 @@ where
#[inline(never)]
fn with_button(mut self, icon: Icon, msg: CancelInfoConfirmMsg, enabled: bool) -> Self {
self.header = self.header.with_button(icon, enabled);
self.button_msg = msg;
self.header = self.header.with_button(icon, enabled, msg);
self
}
@ -189,17 +186,13 @@ where
instruction: TString<'static>,
description: Option<TString<'static>>,
) -> Self {
let mut footer = Footer::new(instruction);
if let Some(description_text) = description {
footer = footer.with_description(description_text);
}
self.footer = Some(footer);
self.footer = Some(Footer::new(instruction, description));
self
}
#[inline(never)]
pub fn with_footer_counter(mut self, instruction: TString<'static>, max_value: u8) -> Self {
self.footer = Some(Footer::new(instruction).with_page_counter(max_value));
self.footer = Some(Footer::new(instruction, None).with_page_counter(max_value));
self
}
@ -213,8 +206,7 @@ where
}
pub fn update_title(&mut self, ctx: &mut EventCtx, new_title: TString<'static>) {
self.header.update_title(new_title);
ctx.request_paint();
self.header.update_title(ctx, new_title);
}
pub fn update_subtitle(
@ -223,8 +215,7 @@ where
new_subtitle: TString<'static>,
new_style: Option<TextStyle>,
) {
self.header.update_subtitle(new_subtitle, new_style);
ctx.request_paint();
self.header.update_subtitle(ctx, new_subtitle, new_style);
}
pub fn update_content<F, R>(&mut self, ctx: &mut EventCtx, update_fn: F) -> R
@ -244,11 +235,7 @@ where
#[inline(never)]
pub fn with_swipe(mut self, dir: SwipeDirection, settings: SwipeSettings) -> Self {
self.footer = self.footer.map(|f| match dir {
SwipeDirection::Up => f.with_swipe_up(),
SwipeDirection::Down => f.with_swipe_down(),
_ => f,
});
self.footer = self.footer.map(|f| f.with_swipe(dir));
self.swipe = self.swipe.with_swipe(dir, settings);
self
}
@ -275,21 +262,7 @@ where
fn place(&mut self, bounds: Rect) -> Rect {
self.bounds = bounds;
let (mut header_area, mut content_area) = bounds.split_top(TITLE_HEIGHT);
content_area = content_area.inset(Insets::top(theme::SPACING));
header_area = header_area.inset(Insets::sides(theme::SPACING));
self.header.place(header_area);
if let Some(footer) = &mut self.footer {
// FIXME: spacer at the bottom might be applied also for usage without footer
// but not for VerticalMenu
content_area = content_area.inset(Insets::bottom(theme::SPACING));
let (remaining, footer_area) = content_area.split_bottom(footer.height());
footer.place(footer_area);
content_area = remaining;
}
let content_area = frame_place(&mut self.header, &mut self.footer, bounds);
self.content.place(content_area);
@ -297,9 +270,17 @@ where
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
self.horizontal_swipe.event(event, self.swipe);
if let Some(value) = frame_event(
&mut self.horizontal_swipe,
self.swipe,
&mut self.header,
&mut self.footer,
ctx,
event,
) {
return Some(FrameMsg::Button(value));
}
self.footer.event(ctx, event);
let msg = self.content.event(ctx, event).map(FrameMsg::Content);
if let Some(count) = ctx.page_count() {
self.internal_page_cnt = count;
@ -308,9 +289,7 @@ where
if msg.is_some() {
return msg;
}
if let Some(ButtonMsg::Clicked) = self.header.event(ctx, event) {
return Some(FrameMsg::Button(self.button_msg));
}
None
}
@ -328,6 +307,37 @@ where
.render_swipe_cover(target, self.bounds);
}
}
fn frame_event(
horizontal_swipe: &mut HorizontalSwipe,
swipe_config: SwipeConfig,
header: &mut Header,
footer: &mut Option<Footer>,
ctx: &mut EventCtx,
event: Event,
) -> Option<CancelInfoConfirmMsg> {
horizontal_swipe.event(event, swipe_config);
footer.event(ctx, event);
header.event(ctx, event)
}
fn frame_place(header: &mut Header, footer: &mut Option<Footer>, bounds: Rect) -> Rect {
let (mut header_area, mut content_area) = bounds.split_top(TITLE_HEIGHT);
content_area = content_area.inset(Insets::top(theme::SPACING));
header_area = header_area.inset(Insets::sides(theme::SPACING));
header.place(header_area);
if let Some(footer) = footer {
// FIXME: spacer at the bottom might be applied also for usage without footer
// but not for VerticalMenu
content_area = content_area.inset(Insets::bottom(theme::SPACING));
let (remaining, footer_area) = content_area.split_bottom(footer.height());
footer.place(footer_area);
content_area = remaining;
}
content_area
}
#[cfg(feature = "micropython")]
impl<T> crate::ui::flow::Swipable for Frame<T> {

View File

@ -7,7 +7,7 @@ use crate::{
geometry::{Alignment, Alignment2D, Insets, Offset, Rect},
lerp::Lerp,
model_mercury::{
component::{Button, ButtonMsg, ButtonStyleSheet},
component::{Button, ButtonMsg, ButtonStyleSheet, CancelInfoConfirmMsg},
theme,
theme::TITLE_HEIGHT,
},
@ -71,6 +71,7 @@ pub struct Header {
icon: Option<Icon>,
color: Option<Color>,
title_style: TextStyle,
button_msg: CancelInfoConfirmMsg,
}
impl Header {
@ -84,6 +85,7 @@ impl Header {
icon: None,
color: None,
title_style: theme::label_title_main(),
button_msg: CancelInfoConfirmMsg::Cancelled,
}
}
#[inline(never)]
@ -107,12 +109,14 @@ impl Header {
self
}
#[inline(never)]
pub fn update_title(&mut self, title: TString<'static>) {
pub fn update_title(&mut self, ctx: &mut EventCtx, title: TString<'static>) {
self.title.set_text(title);
ctx.request_paint();
}
#[inline(never)]
pub fn update_subtitle(
&mut self,
ctx: &mut EventCtx,
new_subtitle: TString<'static>,
new_style: Option<TextStyle>,
) {
@ -126,10 +130,11 @@ impl Header {
self.subtitle = Some(Label::new(new_subtitle, self.title.alignment(), style));
}
}
ctx.request_paint();
}
#[inline(never)]
pub fn with_button(mut self, icon: Icon, enabled: bool) -> Self {
pub fn with_button(mut self, icon: Icon, enabled: bool, msg: CancelInfoConfirmMsg) -> Self {
let touch_area = Insets::uniform(BUTTON_EXPAND_BORDER);
self.button = Some(
Button::with_icon(icon)
@ -137,6 +142,7 @@ impl Header {
.initially_enabled(enabled)
.styled(theme::button_default()),
);
self.button_msg = msg;
self
}
#[inline(never)]
@ -160,7 +166,7 @@ impl Header {
}
impl Component for Header {
type Msg = ButtonMsg;
type Msg = CancelInfoConfirmMsg;
fn place(&mut self, bounds: Rect) -> Rect {
let header_area = if let Some(b) = &mut self.button {
@ -201,7 +207,11 @@ impl Component for Header {
}
}
self.button.event(ctx, event)
if let Some(ButtonMsg::Clicked) = self.button.event(ctx, event) {
return Some(self.button_msg);
};
None
}
fn paint(&mut self) {

View File

@ -1,3 +1,4 @@
use super::{theme, Footer};
use crate::{
strutil::{ShortString, TString},
translations::TR,
@ -11,8 +12,6 @@ use crate::{
},
};
use super::{theme, Footer};
pub enum NumberInputSliderDialogMsg {
Changed(u16),
}
@ -32,8 +31,10 @@ impl NumberInputSliderDialog {
Self {
area: Rect::zero(),
input: NumberInputSlider::new(min, max, init_value).into_child(),
footer: Footer::new::<TString<'static>>(TR::instructions__swipe_horizontally.into())
.with_description::<TString<'static>>(TR::setting__adjust.into()),
footer: Footer::new::<TString<'static>>(
TR::instructions__swipe_horizontally.into(),
Some(TR::setting__adjust.into()),
),
min,
max,
val: init_value,