mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-21 05:58:09 +00:00
fix(core/ui): style update: paging
[no changelog]
This commit is contained in:
parent
e16a37b0cf
commit
ea3d05d5e3
@ -2,10 +2,10 @@ use crate::ui::{
|
|||||||
component::{
|
component::{
|
||||||
base::ComponentExt,
|
base::ComponentExt,
|
||||||
paginated::{AuxPageMsg, PageMsg},
|
paginated::{AuxPageMsg, PageMsg},
|
||||||
Component, Event, EventCtx, FixedHeightBar, Label, Pad, Paginate,
|
Component, Event, EventCtx, FixedHeightBar, Pad, Paginate,
|
||||||
},
|
},
|
||||||
display::{self, toif::Icon, Color},
|
display::{self, toif::Icon, Color},
|
||||||
geometry::{Insets, Rect},
|
geometry::{Grid, Insets, Rect},
|
||||||
model_tt::component::{Button, ButtonMsg},
|
model_tt::component::{Button, ButtonMsg},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -14,14 +14,19 @@ use super::{
|
|||||||
theme, CancelConfirmMsg, Loader, ScrollBar, Swipe, SwipeDirection,
|
theme, CancelConfirmMsg, Loader, ScrollBar, Swipe, SwipeDirection,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SwipePage<T, U> {
|
pub struct SwipePage<T, U>
|
||||||
|
where
|
||||||
|
U: Component,
|
||||||
|
{
|
||||||
content: T,
|
content: T,
|
||||||
buttons: U,
|
buttons: U,
|
||||||
pad: Pad,
|
pad: Pad,
|
||||||
swipe: Swipe,
|
swipe: Swipe,
|
||||||
scrollbar: ScrollBar,
|
scrollbar: ScrollBar,
|
||||||
hint: Label<&'static str>,
|
button_prev: Button<&'static str>,
|
||||||
button_back: Option<Button<&'static str>>,
|
button_next: Button<&'static str>,
|
||||||
|
button_prev_exits: bool,
|
||||||
|
is_go_back: Option<fn(&U::Msg) -> bool>,
|
||||||
swipe_left: bool,
|
swipe_left: bool,
|
||||||
fade: Option<u16>,
|
fade: Option<u16>,
|
||||||
}
|
}
|
||||||
@ -39,15 +44,25 @@ where
|
|||||||
scrollbar: ScrollBar::vertical(),
|
scrollbar: ScrollBar::vertical(),
|
||||||
swipe: Swipe::new(),
|
swipe: Swipe::new(),
|
||||||
pad: Pad::with_background(background),
|
pad: Pad::with_background(background),
|
||||||
hint: Label::centered("SWIPE TO CONTINUE", theme::label_page_hint()),
|
button_prev: Button::with_icon(Icon::new(theme::ICON_UP)),
|
||||||
button_back: None,
|
button_next: Button::with_icon(Icon::new(theme::ICON_DOWN)),
|
||||||
|
button_prev_exits: false,
|
||||||
|
is_go_back: None,
|
||||||
swipe_left: false,
|
swipe_left: false,
|
||||||
fade: None,
|
fade: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_back_button(mut self) -> Self {
|
pub fn with_back_button(mut self) -> Self {
|
||||||
self.button_back = Some(Button::with_icon(Icon::new(theme::ICON_BACK)));
|
self.button_prev_exits = true;
|
||||||
|
self.button_prev = Button::with_icon(Icon::new(theme::ICON_BACK));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If `controls` message matches the function then we will go page back
|
||||||
|
/// instead of propagating the message to parent component.
|
||||||
|
pub fn with_go_back(mut self, is_go_back: fn(&U::Msg) -> bool) -> Self {
|
||||||
|
self.is_go_back = Some(is_go_back);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +81,12 @@ where
|
|||||||
// Adjust the swipe parameters according to the scrollbar.
|
// Adjust the swipe parameters according to the scrollbar.
|
||||||
self.setup_swipe();
|
self.setup_swipe();
|
||||||
|
|
||||||
|
// Enable/disable prev/next buttons.
|
||||||
|
self.button_prev
|
||||||
|
.enable_if(ctx, self.scrollbar.has_previous_page());
|
||||||
|
self.button_next
|
||||||
|
.enable_if(ctx, self.scrollbar.has_next_page());
|
||||||
|
|
||||||
// Change the page in the content, make sure it gets completely repainted and
|
// Change the page in the content, make sure it gets completely repainted and
|
||||||
// clear the background under it.
|
// clear the background under it.
|
||||||
self.content.change_page(self.scrollbar.active_page);
|
self.content.change_page(self.scrollbar.active_page);
|
||||||
@ -83,13 +104,8 @@ where
|
|||||||
let mut layout = PageLayout::new(bounds);
|
let mut layout = PageLayout::new(bounds);
|
||||||
self.pad.place(bounds);
|
self.pad.place(bounds);
|
||||||
self.swipe.place(bounds);
|
self.swipe.place(bounds);
|
||||||
|
self.button_prev.place(layout.button_prev);
|
||||||
if self.button_back.is_some() {
|
self.button_next.place(layout.button_next);
|
||||||
self.button_back.place(layout.hint_button);
|
|
||||||
self.hint.place(layout.hint_button_hint);
|
|
||||||
} else {
|
|
||||||
self.hint.place(layout.hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
let buttons_area = self.buttons.place(layout.buttons);
|
let buttons_area = self.buttons.place(layout.buttons);
|
||||||
layout.set_buttons_height(buttons_area.height());
|
layout.set_buttons_height(buttons_area.height());
|
||||||
@ -160,13 +176,31 @@ where
|
|||||||
}
|
}
|
||||||
if !self.scrollbar.has_next_page() {
|
if !self.scrollbar.has_next_page() {
|
||||||
if let Some(msg) = self.buttons.event(ctx, event) {
|
if let Some(msg) = self.buttons.event(ctx, event) {
|
||||||
|
// Handle the case when one of the controls buttons is configured to go back a
|
||||||
|
// page.
|
||||||
|
if let Some(f) = self.is_go_back {
|
||||||
|
if f(&msg) {
|
||||||
|
self.scrollbar.go_to_previous_page();
|
||||||
|
self.on_page_change(ctx);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Some(PageMsg::Controls(msg));
|
return Some(PageMsg::Controls(msg));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Some(ButtonMsg::Clicked) = self.button_back.event(ctx, event) {
|
if let Some(ButtonMsg::Clicked) = self.button_prev.event(ctx, event) {
|
||||||
|
if self.button_prev_exits {
|
||||||
return Some(PageMsg::Aux(AuxPageMsg::GoBack));
|
return Some(PageMsg::Aux(AuxPageMsg::GoBack));
|
||||||
}
|
}
|
||||||
self.hint.event(ctx, event);
|
self.scrollbar.go_to_previous_page();
|
||||||
|
self.on_page_change(ctx);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if let Some(ButtonMsg::Clicked) = self.button_next.event(ctx, event) {
|
||||||
|
self.scrollbar.go_to_next_page();
|
||||||
|
self.on_page_change(ctx);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -178,8 +212,8 @@ where
|
|||||||
self.scrollbar.paint();
|
self.scrollbar.paint();
|
||||||
}
|
}
|
||||||
if self.scrollbar.has_next_page() {
|
if self.scrollbar.has_next_page() {
|
||||||
self.button_back.paint();
|
self.button_prev.paint();
|
||||||
self.hint.paint();
|
self.button_next.paint();
|
||||||
} else {
|
} else {
|
||||||
self.buttons.paint();
|
self.buttons.paint();
|
||||||
}
|
}
|
||||||
@ -196,8 +230,8 @@ where
|
|||||||
if !self.scrollbar.has_next_page() {
|
if !self.scrollbar.has_next_page() {
|
||||||
self.buttons.bounds(sink);
|
self.buttons.bounds(sink);
|
||||||
} else {
|
} else {
|
||||||
self.button_back.bounds(sink);
|
self.button_prev.bounds(sink);
|
||||||
self.hint.bounds(sink);
|
self.button_next.bounds(sink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +240,7 @@ where
|
|||||||
impl<T, U> crate::trace::Trace for SwipePage<T, U>
|
impl<T, U> crate::trace::Trace for SwipePage<T, U>
|
||||||
where
|
where
|
||||||
T: crate::trace::Trace,
|
T: crate::trace::Trace,
|
||||||
U: crate::trace::Trace,
|
U: crate::trace::Trace + Component,
|
||||||
{
|
{
|
||||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||||
t.open("SwipePage");
|
t.open("SwipePage");
|
||||||
@ -227,21 +261,15 @@ pub struct PageLayout {
|
|||||||
pub scrollbar: Rect,
|
pub scrollbar: Rect,
|
||||||
/// Controls displayed on last page.
|
/// Controls displayed on last page.
|
||||||
pub buttons: Rect,
|
pub buttons: Rect,
|
||||||
/// Swipe to continue (unless back button enabled).
|
pub button_prev: Rect,
|
||||||
pub hint: Rect,
|
pub button_next: Rect,
|
||||||
/// Optional back button on every page.
|
|
||||||
pub hint_button: Rect,
|
|
||||||
/// Hint area when back button is enabled.
|
|
||||||
pub hint_button_hint: Rect,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PageLayout {
|
impl PageLayout {
|
||||||
const SCROLLBAR_WIDTH: i16 = 15;
|
const SCROLLBAR_WIDTH: i16 = 8;
|
||||||
const SCROLLBAR_SPACE: i16 = 5;
|
const SCROLLBAR_SPACE: i16 = 5;
|
||||||
const HINT_OFF: i16 = 19;
|
|
||||||
|
|
||||||
pub fn new(area: Rect) -> Self {
|
pub fn new(area: Rect) -> Self {
|
||||||
let (_, hint) = area.split_bottom(Self::HINT_OFF);
|
|
||||||
let (buttons, _space) = area.split_right(theme::CONTENT_BORDER);
|
let (buttons, _space) = area.split_right(theme::CONTENT_BORDER);
|
||||||
let (_space, content) = area.split_left(theme::CONTENT_BORDER);
|
let (_space, content) = area.split_left(theme::CONTENT_BORDER);
|
||||||
let (content_single_page, _space) = content.split_right(theme::CONTENT_BORDER);
|
let (content_single_page, _space) = content.split_right(theme::CONTENT_BORDER);
|
||||||
@ -249,20 +277,18 @@ impl PageLayout {
|
|||||||
content.split_right(Self::SCROLLBAR_SPACE + Self::SCROLLBAR_WIDTH);
|
content.split_right(Self::SCROLLBAR_SPACE + Self::SCROLLBAR_WIDTH);
|
||||||
let (_space, scrollbar) = scrollbar.split_left(Self::SCROLLBAR_SPACE);
|
let (_space, scrollbar) = scrollbar.split_left(Self::SCROLLBAR_SPACE);
|
||||||
|
|
||||||
let (_, one_row_buttons) = area.split_bottom(theme::button_rows(1));
|
let (_, one_row_buttons) = area.split_bottom(theme::BUTTON_HEIGHT);
|
||||||
let (hint_button, hint_button_hint) = one_row_buttons.split_left(one_row_buttons.height());
|
let grid = Grid::new(one_row_buttons, 1, 2).with_spacing(theme::BUTTON_SPACING);
|
||||||
let vertical_inset = (hint_button_hint.height() - Self::HINT_OFF) / 2;
|
let button_prev = grid.row_col(0, 0);
|
||||||
let hint_button_hint =
|
let button_next = grid.row_col(0, 1);
|
||||||
hint_button_hint.inset(Insets::new(vertical_inset, 0, vertical_inset, 0));
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
content_single_page,
|
content_single_page,
|
||||||
content,
|
content,
|
||||||
scrollbar,
|
scrollbar,
|
||||||
buttons,
|
buttons,
|
||||||
hint,
|
button_prev,
|
||||||
hint_button,
|
button_next,
|
||||||
hint_button_hint,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +391,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.inner.scrollbar.has_next_page() {
|
if self.inner.scrollbar.has_next_page() {
|
||||||
self.inner.hint.paint();
|
self.inner.button_prev.paint();
|
||||||
|
self.inner.button_next.paint();
|
||||||
} else {
|
} else {
|
||||||
self.inner.buttons.paint();
|
self.inner.buttons.paint();
|
||||||
}
|
}
|
||||||
|
@ -565,11 +565,11 @@ pub const fn button_bar<T>(inner: T) -> FixedHeightBar<T> {
|
|||||||
/// | 14 |
|
/// | 14 |
|
||||||
/// +----------+
|
/// +----------+
|
||||||
pub const fn borders() -> Insets {
|
pub const fn borders() -> Insets {
|
||||||
Insets::new(13, 10, 14, 10)
|
Insets::new(6, 6, 6, 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn borders_scroll() -> Insets {
|
pub const fn borders_scroll() -> Insets {
|
||||||
Insets::new(13, 5, 14, 10)
|
Insets::new(6, 6, 6, 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn borders_horizontal_scroll() -> Insets {
|
pub const fn borders_horizontal_scroll() -> Insets {
|
||||||
@ -577,5 +577,5 @@ pub const fn borders_horizontal_scroll() -> Insets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const fn borders_notification() -> Insets {
|
pub const fn borders_notification() -> Insets {
|
||||||
Insets::new(48, 10, 14, 10)
|
Insets::new(48, 6, 6, 6)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user