You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/embed/rust/src/ui/model_mercury/component/error.rs

107 lines
3.0 KiB

use crate::ui::{
component::{Child, Component, Event, EventCtx, Label, Never, Pad},
constant::screen,
geometry::{Alignment2D, Point, Rect},
shape,
shape::Renderer,
};
use crate::ui::model_mercury::{
component::{ResultFooter, ResultStyle},
constant::WIDTH,
theme::{FATAL_ERROR_COLOR, ICON_WARNING40, RESULT_FOOTER_START, RESULT_PADDING, WHITE},
};
const ICON_TOP: i16 = 23;
const TITLE_AREA_START: i16 = 70;
const MESSAGE_AREA_START: i16 = 116;
#[cfg(feature = "bootloader")]
const STYLE: &ResultStyle = &crate::ui::model_mercury::theme::bootloader::RESULT_WIPE;
#[cfg(not(feature = "bootloader"))]
const STYLE: &ResultStyle = &super::theme::RESULT_ERROR;
pub struct ErrorScreen<'a, T> {
bg: Pad,
title: Child<Label<T>>,
message: Child<Label<T>>,
footer: Child<ResultFooter<'a, T>>,
}
impl<T: AsRef<str>> ErrorScreen<'_, T> {
pub fn new(title: T, message: T, footer: T) -> Self {
let title = Label::centered(title, STYLE.title_style());
let message = Label::centered(message, STYLE.message_style());
let footer = ResultFooter::new(
Label::centered(footer, STYLE.title_style()).vertically_centered(),
STYLE,
);
Self {
bg: Pad::with_background(FATAL_ERROR_COLOR).with_clear(),
title: Child::new(title),
message: Child::new(message),
footer: Child::new(footer),
}
}
}
impl<T: AsRef<str>> Component for ErrorScreen<'_, T> {
type Msg = Never;
fn place(&mut self, _bounds: Rect) -> Rect {
self.bg.place(screen());
let title_area = Rect::new(
Point::new(RESULT_PADDING, TITLE_AREA_START),
Point::new(WIDTH - RESULT_PADDING, MESSAGE_AREA_START),
);
self.title.place(title_area);
let message_area = Rect::new(
Point::new(RESULT_PADDING, MESSAGE_AREA_START),
Point::new(WIDTH - RESULT_PADDING, RESULT_FOOTER_START),
);
self.message.place(message_area);
let (_, bottom_area) = ResultFooter::<T>::split_bounds();
self.footer.place(bottom_area);
screen()
}
fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option<Self::Msg> {
None
}
fn paint(&mut self) {
self.bg.paint();
let icon = ICON_WARNING40;
icon.draw(
Point::new(screen().center().x, ICON_TOP),
Alignment2D::TOP_CENTER,
WHITE,
FATAL_ERROR_COLOR,
);
self.title.paint();
self.message.paint();
self.footer.paint();
}
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
self.bg.render(target);
let icon = ICON_WARNING40;
shape::ToifImage::new(Point::new(screen().center().x, ICON_TOP), icon.toif)
.with_fg(WHITE)
.with_bg(FATAL_ERROR_COLOR)
.with_align(Alignment2D::TOP_CENTER)
.render(target);
self.title.render(target);
self.message.render(target);
self.footer.render(target);
}
}