diff --git a/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs b/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs index 9d056a441e..5fce9d5e2d 100644 --- a/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/bootloader/mod.rs @@ -36,8 +36,9 @@ use super::theme::BLACK; #[cfg(feature = "new_rendering")] use crate::ui::{ constant, - display::toif::Toif, + display::{toif::Toif, LOADER_MAX}, geometry::{Alignment, Alignment2D}, + model_mercury::shapes::render_loader, shape, shape::render_on_display, }; @@ -122,19 +123,18 @@ impl ModelMercuryFeatures { let center_text_offset: i16 = 10; let center = SCREEN.center() + Offset::y(loader_offset); let inactive_color = bg_color.blend(fg_color, 85); + let end = ((progress as i32 * 8 * shape::PI4 as i32) / 1000) as i16; - shape::Circle::new(center, constant::LOADER_OUTER) - .with_bg(inactive_color) - .render(target); - - shape::Circle::new(center, constant::LOADER_OUTER) - .with_bg(fg_color) - .with_end_angle(360.0 * progress as f32 / 1000.0) - .render(target); - - shape::Circle::new(center, constant::LOADER_INNER + 2) - .with_bg(bg_color) - .render(target); + render_loader( + center, + inactive_color, + fg_color, + bg_color, + 0, + end, + progress >= LOADER_MAX, + target, + ); if let Some((icon, color)) = icon { shape::ToifImage::new(center, icon.toif) diff --git a/core/embed/rust/src/ui/model_mercury/component/loader.rs b/core/embed/rust/src/ui/model_mercury/component/loader.rs index ed564bdb1e..f12e8e3087 100644 --- a/core/embed/rust/src/ui/model_mercury/component/loader.rs +++ b/core/embed/rust/src/ui/model_mercury/component/loader.rs @@ -5,8 +5,9 @@ use crate::{ ui::{ animation::Animation, component::{Component, Event, EventCtx, Pad}, - display::{self, toif::Icon, Color}, + display::{self, toif::Icon, Color, LOADER_MAX}, geometry::{Alignment2D, Offset, Rect}, + model_mercury::shapes::render_loader, shape::{self, Renderer}, util::animation_disabled, }, @@ -52,7 +53,7 @@ impl Loader { pub fn with_styles(styles: LoaderStyleSheet) -> Self { Self { - pad: Pad::with_background(styles.normal.background_color), + pad: Pad::with_background(styles.active.background_color), state: State::Initial, growing_duration: Duration::from_millis(GROWING_DURATION_MS), shrinking_duration: Duration::from_millis(SHRINKING_DURATION_MS), @@ -190,17 +191,13 @@ impl Component for Loader { let now = Instant::now(); if let Some(progress) = self.progress(now) { - let style = if progress < display::LOADER_MAX { - self.styles.normal - } else { - self.styles.active - }; + let style = self.styles.active; self.pad.paint(); display::loader( progress, self.offset_y, - style.loader_color, + style.active, style.background_color, style.icon, ); @@ -216,30 +213,29 @@ impl Component for Loader { let now = Instant::now(); if let Some(progress) = self.progress(now) { - let style = if progress < display::LOADER_MAX { - self.styles.normal - } else { - self.styles.active - }; + let style = self.styles.active; self.pad.render(target); let center = self.pad.area.center(); - let inactive_color = Color::black().blend(style.loader_color, 85); + let inactive_color = style.inactive; + let active_color = style.active; + let background_color = style.background_color; - shape::Circle::new(center, constant::LOADER_OUTER) - .with_bg(inactive_color) - .render(target); + let end = ((progress as i32 * 8 * shape::PI4 as i32) / 1000) as i16; + let start = 0; - shape::Circle::new(center, constant::LOADER_OUTER) - .with_bg(style.loader_color) - .with_end_angle(360.0 * progress as f32 / 1000.0) - .render(target); - - shape::Circle::new(center, constant::LOADER_INNER) - .with_bg(style.background_color) - .render(target); + render_loader( + center, + inactive_color, + active_color, + background_color, + start, + end, + progress >= LOADER_MAX, + target, + ); if let Some((icon, color)) = style.icon { shape::ToifImage::new(center, icon.toif) @@ -252,13 +248,13 @@ impl Component for Loader { } pub struct LoaderStyleSheet { - pub normal: &'static LoaderStyle, pub active: &'static LoaderStyle, } pub struct LoaderStyle { pub icon: Option<(Icon, Color)>, - pub loader_color: Color, + pub active: Color, + pub inactive: Color, pub background_color: Color, } diff --git a/core/embed/rust/src/ui/model_mercury/component/progress.rs b/core/embed/rust/src/ui/model_mercury/component/progress.rs index 6943792738..aaa1cd6bd4 100644 --- a/core/embed/rust/src/ui/model_mercury/component/progress.rs +++ b/core/embed/rust/src/ui/model_mercury/component/progress.rs @@ -9,9 +9,9 @@ use crate::{ text::paragraphs::{Paragraph, Paragraphs}, Child, Component, Event, EventCtx, Label, Never, Pad, }, - display::{self, Font}, + display::{self, Font, LOADER_MAX}, geometry::{Insets, Offset, Rect}, - model_mercury::constant, + model_mercury::{constant, shapes::render_loader}, shape, shape::Renderer, util::animation_disabled, @@ -112,9 +112,9 @@ impl Component for Progress { self.title.render(target); let center = constant::screen().center() + Offset::y(self.loader_y_offset); - let active_color = theme::FG; + let active_color = theme::GREEN_LIGHT; let background_color = theme::BG; - let inactive_color = background_color.blend(active_color, 85); + let inactive_color = theme::GREY_EXTRA_DARK; let (start, end) = if self.indeterminate { let start = (self.value - 100) % 1000; @@ -127,23 +127,16 @@ impl Component for Progress { (0, end) }; - shape::Circle::new(center, constant::LOADER_OUTER) - .with_bg(inactive_color) - .render(target); - - shape::Circle::new(center, constant::LOADER_OUTER) - .with_bg(active_color) - .with_start_angle(start) - .with_end_angle(end) - .render(target); - - shape::Circle::new(center, constant::LOADER_INNER + 2) - .with_bg(active_color) - .render(target); - - shape::Circle::new(center, constant::LOADER_INNER) - .with_bg(background_color) - .render(target); + render_loader( + center, + inactive_color, + active_color, + background_color, + start, + end, + !self.indeterminate && self.value >= LOADER_MAX, + target, + ); self.description_pad.render(target); self.description.render(target); diff --git a/core/embed/rust/src/ui/model_mercury/mod.rs b/core/embed/rust/src/ui/model_mercury/mod.rs index dcb0009305..cb3336af4b 100644 --- a/core/embed/rust/src/ui/model_mercury/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/mod.rs @@ -11,6 +11,7 @@ pub mod flow; #[cfg(feature = "micropython")] pub mod layout; pub mod screens; +pub mod shapes; pub struct ModelMercuryFeatures; diff --git a/core/embed/rust/src/ui/model_mercury/shapes.rs b/core/embed/rust/src/ui/model_mercury/shapes.rs new file mode 100644 index 0000000000..8d1770c7ba --- /dev/null +++ b/core/embed/rust/src/ui/model_mercury/shapes.rs @@ -0,0 +1,32 @@ +use crate::ui::{display::Color, geometry::Point, model_mercury::constant, shape, shape::Renderer}; + +pub fn render_loader<'s>( + center: Point, + inactive_color: Color, + active_color: Color, + background_color: Color, + start: i16, + end: i16, + full: bool, + target: &mut impl Renderer<'s>, +) { + shape::Circle::new(center, constant::LOADER_OUTER) + .with_bg(inactive_color) + .render(target); + + if full { + shape::Circle::new(center, constant::LOADER_OUTER) + .with_bg(active_color) + .render(target); + } else { + shape::Circle::new(center, constant::LOADER_OUTER) + .with_bg(active_color) + .with_start_angle(start) + .with_end_angle(end) + .render(target); + } + + shape::Circle::new(center, constant::LOADER_INNER + 2) + .with_bg(background_color) + .render(target); +} diff --git a/core/embed/rust/src/ui/model_mercury/theme/mod.rs b/core/embed/rust/src/ui/model_mercury/theme/mod.rs index b8546870c5..27b5af85a2 100644 --- a/core/embed/rust/src/ui/model_mercury/theme/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/theme/mod.rs @@ -581,14 +581,10 @@ pub const fn button_clear() -> ButtonStyleSheet { pub const fn loader_default() -> LoaderStyleSheet { LoaderStyleSheet { - normal: &LoaderStyle { - icon: None, - loader_color: FG, - background_color: BG, - }, active: &LoaderStyle { icon: None, - loader_color: GREEN, + active: GREEN_LIGHT, + inactive: GREY_EXTRA_DARK, background_color: BG, }, } @@ -596,14 +592,10 @@ pub const fn loader_default() -> LoaderStyleSheet { pub const fn loader_lock_icon() -> LoaderStyleSheet { LoaderStyleSheet { - normal: &LoaderStyle { - icon: Some((ICON_LOCK_BIG, FG)), - loader_color: FG, - background_color: BG, - }, active: &LoaderStyle { icon: Some((ICON_LOCK_BIG, FG)), - loader_color: GREEN, + active: GREEN_LIGHT, + inactive: GREY_EXTRA_DARK, background_color: BG, }, }