1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 04:18:10 +00:00

fix(core/ui): draw hold-to-confirm loader over dialog title

[no changelog]
This commit is contained in:
Martin Milata 2023-10-05 23:19:12 +02:00
parent d99e1eedd2
commit a353c35b78
2 changed files with 27 additions and 17 deletions

View File

@ -2,7 +2,7 @@ use crate::{
time::{Duration, Instant}, time::{Duration, Instant},
ui::{ ui::{
animation::Animation, animation::Animation,
component::{Component, Event, EventCtx}, component::{Component, Event, EventCtx, Pad},
display::{self, toif::Icon, Color}, display::{self, toif::Icon, Color},
geometry::{Offset, Rect}, geometry::{Offset, Rect},
model_tt::constant, model_tt::constant,
@ -27,7 +27,7 @@ enum State {
} }
pub struct Loader { pub struct Loader {
offset_y: i16, pub pad: Pad,
state: State, state: State,
growing_duration: Duration, growing_duration: Duration,
shrinking_duration: Duration, shrinking_duration: Duration,
@ -38,12 +38,13 @@ impl Loader {
pub const SIZE: Offset = Offset::new(120, 120); pub const SIZE: Offset = Offset::new(120, 120);
pub fn new() -> Self { pub fn new() -> Self {
let styles = theme::loader_default();
Self { Self {
offset_y: 0, pad: Pad::with_background(styles.normal.background_color),
state: State::Initial, state: State::Initial,
growing_duration: Duration::from_millis(GROWING_DURATION_MS), growing_duration: Duration::from_millis(GROWING_DURATION_MS),
shrinking_duration: Duration::from_millis(SHRINKING_DURATION_MS), shrinking_duration: Duration::from_millis(SHRINKING_DURATION_MS),
styles: theme::loader_default(), styles,
} }
} }
@ -130,13 +131,8 @@ impl Component for Loader {
type Msg = LoaderMsg; type Msg = LoaderMsg;
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 self.pad.place(bounds);
// compute from the bounds center point. Rect::from_center_and_size(bounds.center(), Self::SIZE)
// 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)
} }
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> { fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
@ -177,9 +173,15 @@ impl Component for Loader {
self.styles.active self.styles.active
}; };
// Current loader API only takes Y-offset relative to screen center, which we
// compute from the bounds center point.
let screen_center = constant::screen().center();
let offset_y = self.pad.area.center().y - screen_center.y;
self.pad.paint();
display::loader( display::loader(
progress, progress,
self.offset_y, offset_y,
style.loader_color, style.loader_color,
style.background_color, style.background_color,
style.icon, style.icon,

View File

@ -2,6 +2,7 @@ use crate::{
time::Instant, time::Instant,
ui::{ ui::{
component::{paginated::PageMsg, Component, ComponentExt, Event, EventCtx, Pad, Paginate}, component::{paginated::PageMsg, Component, ComponentExt, Event, EventCtx, Pad, Paginate},
constant,
display::{self, Color}, display::{self, Color},
geometry::{Insets, Rect}, geometry::{Insets, Rect},
util::animation_disabled, util::animation_disabled,
@ -153,6 +154,14 @@ where
self.cancel_from_any_page || !self.scrollbar.has_previous_page() self.cancel_from_any_page || !self.scrollbar.has_previous_page()
} }
/// Area for drawing loader (and black rectangle behind it). Can be outside
/// bounds as we repaint entire UI tree after hiding the loader.
const fn loader_area() -> Rect {
constant::screen()
.inset(theme::borders())
.inset(Insets::bottom(theme::BUTTON_HEIGHT + theme::BUTTON_SPACING))
}
fn handle_swipe( fn handle_swipe(
&mut self, &mut self,
ctx: &mut EventCtx, ctx: &mut EventCtx,
@ -225,12 +234,12 @@ where
let now = Instant::now(); let now = Instant::now();
if let Some(LoaderMsg::ShrunkCompletely) = loader.event(ctx, event) { if let Some(LoaderMsg::ShrunkCompletely) = loader.event(ctx, event) {
// Clear the remnants of the loader.
self.pad.clear();
// Switch it to the initial state, so we stop painting it. // Switch it to the initial state, so we stop painting it.
loader.reset(); loader.reset();
// Re-draw the whole content tree. // Re-draw the whole content tree.
self.content.request_complete_repaint(ctx); self.content.request_complete_repaint(ctx);
// Loader overpainted our bounds, repaint entire screen from scratch.
ctx.request_repaint_root()
// This can be a result of an animation frame event, we should take // This can be a result of an animation frame event, we should take
// care to not short-circuit here and deliver the event to the // care to not short-circuit here and deliver the event to the
// content as well. // content as well.
@ -238,7 +247,7 @@ where
match button_msg { match button_msg {
Some(ButtonMsg::Pressed) => { Some(ButtonMsg::Pressed) => {
loader.start_growing(ctx, now); loader.start_growing(ctx, now);
self.pad.clear(); // Clear the remnants of the content. loader.pad.clear(); // Clear the remnants of the content.
} }
Some(ButtonMsg::Released) => { Some(ButtonMsg::Released) => {
loader.start_shrinking(ctx, now); loader.start_shrinking(ctx, now);
@ -313,8 +322,7 @@ 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();
let content_area = layout.content_single_page.union(layout.scrollbar); self.loader.place(Self::loader_area());
self.loader.place(content_area);
bounds bounds
} }