1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-27 01:48:17 +00:00

fix(core/rust/ui): avoid flickering in hold to confirm

[no changelog]
This commit is contained in:
Martin Milata 2022-10-13 12:48:37 +02:00
parent a7c3a07ef1
commit be7f1c3f7e
3 changed files with 45 additions and 28 deletions

View File

@ -221,7 +221,6 @@ where
} }
Some(ButtonMsg::Clicked) => { Some(ButtonMsg::Clicked) => {
if loader.is_completely_grown(now) { if loader.is_completely_grown(now) {
loader.reset();
return true; return true;
} else { } else {
loader.start_shrinking(ctx, now); loader.start_shrinking(ctx, now);

View File

@ -118,6 +118,8 @@ impl Component for Loader {
fn place(&mut self, bounds: Rect) -> Rect { fn place(&mut self, bounds: Rect) -> Rect {
// Current loader API only takes Y-offset relative to screen center, which we // Current loader API only takes Y-offset relative to screen center, which we
// compute from the bounds center point. // compute from the bounds center point.
// NOTE: SwipeHoldPage relies on Loader being X-centered regardless of bounds.
// If this changes then SwipeHoldPage needs to be changed too.
let screen_center = constant::screen().center(); let screen_center = constant::screen().center();
self.offset_y = bounds.center().y - screen_center.y; self.offset_y = bounds.center().y - screen_center.y;
Rect::from_center_and_size(screen_center + Offset::y(self.offset_y), Self::SIZE) Rect::from_center_and_size(screen_center + Offset::y(self.offset_y), Self::SIZE)

View File

@ -59,38 +59,25 @@ where
// paint. // paint.
self.fade = Some(theme::BACKLIGHT_NORMAL); self.fade = Some(theme::BACKLIGHT_NORMAL);
} }
}
impl<T, U> Component for SwipePage<T, U> /// Like `place()` but returns area for loader (content + scrollbar) to be
where /// used in SwipeHoldPage.
T: Paginate, fn place_get_content_area(&mut self, bounds: Rect) -> Rect {
T: Component, let mut layout = PageLayout::new(bounds);
U: Component,
{
type Msg = PageMsg<T::Msg, U::Msg>;
fn place(&mut self, bounds: Rect) -> Rect {
let layout = PageLayout::new(bounds);
self.pad.place(bounds); self.pad.place(bounds);
self.swipe.place(bounds); self.swipe.place(bounds);
self.hint.place(layout.hint); self.hint.place(layout.hint);
let buttons_area = self.buttons.place(layout.buttons); let buttons_area = self.buttons.place(layout.buttons);
let buttons_height = buttons_area.height() + theme::BUTTON_SPACING; layout.set_buttons_height(buttons_area.height());
self.scrollbar self.scrollbar.place(layout.scrollbar);
.place(layout.scrollbar.inset(Insets::bottom(buttons_height)));
// Layout the content. Try to fit it on a single page first, and reduce the area // Layout the content. Try to fit it on a single page first, and reduce the area
// to make space for a scrollbar if it doesn't fit. // to make space for a scrollbar if it doesn't fit.
self.content.place( self.content.place(layout.content_single_page);
layout
.content_single_page
.inset(Insets::bottom(buttons_height)),
);
let page_count = { let page_count = {
let count = self.content.page_count(); let count = self.content.page_count();
if count > 1 { if count > 1 {
self.content self.content.place(layout.content);
.place(layout.content.inset(Insets::bottom(buttons_height)));
self.content.page_count() // Make sure to re-count it with the self.content.page_count() // Make sure to re-count it with the
// new size. // new size.
} else { } else {
@ -103,6 +90,20 @@ where
self.scrollbar.set_count_and_active_page(page_count, 0); self.scrollbar.set_count_and_active_page(page_count, 0);
self.setup_swipe(); self.setup_swipe();
layout.content_single_page.union(layout.scrollbar)
}
}
impl<T, U> Component for SwipePage<T, U>
where
T: Paginate,
T: Component,
U: Component,
{
type Msg = PageMsg<T::Msg, U::Msg>;
fn place(&mut self, bounds: Rect) -> Rect {
self.place_get_content_area(bounds);
bounds bounds
} }
@ -215,11 +216,19 @@ impl PageLayout {
hint, hint,
} }
} }
pub fn set_buttons_height(&mut self, height: i16) {
let buttons_inset = Insets::bottom(height + theme::BUTTON_SPACING);
self.content_single_page = self.content_single_page.inset(buttons_inset);
self.content = self.content.inset(buttons_inset);
self.scrollbar = self.scrollbar.inset(buttons_inset);
}
} }
pub struct SwipeHoldPage<T> { pub struct SwipeHoldPage<T> {
inner: SwipePage<T, FixedHeightBar<CancelHold>>, inner: SwipePage<T, FixedHeightBar<CancelHold>>,
loader: Loader, loader: Loader,
pad: Pad,
} }
impl<T> SwipeHoldPage<T> impl<T> SwipeHoldPage<T>
@ -232,6 +241,7 @@ where
Self { Self {
inner: SwipePage::new(content, buttons, background), inner: SwipePage::new(content, buttons, background),
loader: Loader::new(), loader: Loader::new(),
pad: Pad::with_background(background),
} }
} }
@ -240,6 +250,7 @@ where
Self { Self {
inner: SwipePage::new(content, buttons, background), inner: SwipePage::new(content, buttons, background),
loader: Loader::new(), loader: Loader::new(),
pad: Pad::with_background(background),
} }
} }
} }
@ -252,8 +263,9 @@ where
type Msg = PageMsg<T::Msg, CancelConfirmMsg>; type Msg = PageMsg<T::Msg, CancelConfirmMsg>;
fn place(&mut self, bounds: Rect) -> Rect { fn place(&mut self, bounds: Rect) -> Rect {
self.inner.place(bounds); let content_area = self.inner.place_get_content_area(bounds);
self.loader.place(self.inner.pad.area); self.loader.place(content_area);
self.pad.place(content_area);
bounds bounds
} }
@ -272,23 +284,27 @@ where
event, event,
button_msg, button_msg,
&mut self.loader, &mut self.loader,
&mut self.inner.pad, &mut self.pad,
&mut self.inner.content, &mut self.inner.content,
) { ) {
return Some(PageMsg::Controls(CancelConfirmMsg::Confirmed)); return Some(PageMsg::Controls(CancelConfirmMsg::Confirmed));
} }
if self.inner.pad.will_paint().is_some() {
self.inner.buttons.request_complete_repaint(ctx);
}
None None
} }
fn paint(&mut self) { fn paint(&mut self) {
self.pad.paint();
self.inner.pad.paint(); self.inner.pad.paint();
if self.loader.is_animating() { if self.loader.is_animating() {
self.loader.paint() self.loader.paint()
} else { } else {
self.inner.content.paint(); self.inner.content.paint();
} if self.inner.scrollbar.has_pages() {
if self.inner.scrollbar.has_pages() { self.inner.scrollbar.paint();
self.inner.scrollbar.paint(); }
} }
if self.inner.scrollbar.has_next_page() { if self.inner.scrollbar.has_next_page() {
self.inner.hint.paint(); self.inner.hint.paint();