mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 14:58:09 +00:00
refactor(core/mercury): extract non-generic code from frame component
[no changelog]
This commit is contained in:
parent
f2bdd6e189
commit
873658104d
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user