diff --git a/core/embed/rust/src/ui/model_tt/component/hold_to_confirm.rs b/core/embed/rust/src/ui/model_tt/component/hold_to_confirm.rs index 1d280ddec8..6965672075 100644 --- a/core/embed/rust/src/ui/model_tt/component/hold_to_confirm.rs +++ b/core/embed/rust/src/ui/model_tt/component/hold_to_confirm.rs @@ -221,7 +221,6 @@ where } Some(ButtonMsg::Clicked) => { if loader.is_completely_grown(now) { - loader.reset(); return true; } else { loader.start_shrinking(ctx, now); diff --git a/core/embed/rust/src/ui/model_tt/component/loader.rs b/core/embed/rust/src/ui/model_tt/component/loader.rs index cb774b04f4..09dd31983b 100644 --- a/core/embed/rust/src/ui/model_tt/component/loader.rs +++ b/core/embed/rust/src/ui/model_tt/component/loader.rs @@ -118,6 +118,8 @@ impl Component for Loader { fn place(&mut self, bounds: Rect) -> Rect { // Current loader API only takes Y-offset relative to screen center, which we // 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(); self.offset_y = bounds.center().y - screen_center.y; Rect::from_center_and_size(screen_center + Offset::y(self.offset_y), Self::SIZE) diff --git a/core/embed/rust/src/ui/model_tt/component/page.rs b/core/embed/rust/src/ui/model_tt/component/page.rs index c5a8d7acfd..8680983685 100644 --- a/core/embed/rust/src/ui/model_tt/component/page.rs +++ b/core/embed/rust/src/ui/model_tt/component/page.rs @@ -59,38 +59,25 @@ where // paint. self.fade = Some(theme::BACKLIGHT_NORMAL); } -} -impl Component for SwipePage -where - T: Paginate, - T: Component, - U: Component, -{ - type Msg = PageMsg; - - fn place(&mut self, bounds: Rect) -> Rect { - let layout = PageLayout::new(bounds); + /// Like `place()` but returns area for loader (content + scrollbar) to be + /// used in SwipeHoldPage. + fn place_get_content_area(&mut self, bounds: Rect) -> Rect { + let mut layout = PageLayout::new(bounds); self.pad.place(bounds); self.swipe.place(bounds); self.hint.place(layout.hint); let buttons_area = self.buttons.place(layout.buttons); - let buttons_height = buttons_area.height() + theme::BUTTON_SPACING; - self.scrollbar - .place(layout.scrollbar.inset(Insets::bottom(buttons_height))); + layout.set_buttons_height(buttons_area.height()); + self.scrollbar.place(layout.scrollbar); // 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. - self.content.place( - layout - .content_single_page - .inset(Insets::bottom(buttons_height)), - ); + self.content.place(layout.content_single_page); let page_count = { let count = self.content.page_count(); if count > 1 { - self.content - .place(layout.content.inset(Insets::bottom(buttons_height))); + self.content.place(layout.content); self.content.page_count() // Make sure to re-count it with the // new size. } else { @@ -103,6 +90,20 @@ where self.scrollbar.set_count_and_active_page(page_count, 0); self.setup_swipe(); + layout.content_single_page.union(layout.scrollbar) + } +} + +impl Component for SwipePage +where + T: Paginate, + T: Component, + U: Component, +{ + type Msg = PageMsg; + + fn place(&mut self, bounds: Rect) -> Rect { + self.place_get_content_area(bounds); bounds } @@ -215,11 +216,19 @@ impl PageLayout { 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 { inner: SwipePage>, loader: Loader, + pad: Pad, } impl SwipeHoldPage @@ -232,6 +241,7 @@ where Self { inner: SwipePage::new(content, buttons, background), loader: Loader::new(), + pad: Pad::with_background(background), } } @@ -240,6 +250,7 @@ where Self { inner: SwipePage::new(content, buttons, background), loader: Loader::new(), + pad: Pad::with_background(background), } } } @@ -252,8 +263,9 @@ where type Msg = PageMsg; fn place(&mut self, bounds: Rect) -> Rect { - self.inner.place(bounds); - self.loader.place(self.inner.pad.area); + let content_area = self.inner.place_get_content_area(bounds); + self.loader.place(content_area); + self.pad.place(content_area); bounds } @@ -272,23 +284,27 @@ where event, button_msg, &mut self.loader, - &mut self.inner.pad, + &mut self.pad, &mut self.inner.content, ) { return Some(PageMsg::Controls(CancelConfirmMsg::Confirmed)); } + if self.inner.pad.will_paint().is_some() { + self.inner.buttons.request_complete_repaint(ctx); + } None } fn paint(&mut self) { + self.pad.paint(); self.inner.pad.paint(); if self.loader.is_animating() { self.loader.paint() } else { self.inner.content.paint(); - } - if self.inner.scrollbar.has_pages() { - self.inner.scrollbar.paint(); + if self.inner.scrollbar.has_pages() { + self.inner.scrollbar.paint(); + } } if self.inner.scrollbar.has_next_page() { self.inner.hint.paint();