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:
parent
d99e1eedd2
commit
a353c35b78
@ -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,
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user