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/display.rs

230 lines
4.9 KiB

use crate::{micropython::time, time::Duration, trezorhal::display};
#[cfg(not(feature = "model_tt"))]
use crate::ui::model_t1::constant;
#[cfg(feature = "model_tt")]
use crate::ui::model_tt::constant;
use super::geometry::{Offset, Point, Rect};
pub fn width() -> i32 {
display::width()
}
pub fn height() -> i32 {
display::height()
}
pub fn size() -> Offset {
Offset::new(width(), height())
}
pub fn screen() -> Rect {
Rect::from_top_left_and_size(Point::zero(), size())
}
pub fn backlight() -> i32 {
display::backlight(-1)
}
pub fn set_backlight(val: i32) {
display::backlight(val);
}
pub fn fade_backlight(target: i32) {
const BACKLIGHT_DELAY: Duration = Duration::from_millis(14);
const BACKLIGHT_STEP: usize = 15;
let current = backlight();
if current < target {
for val in (current..target).step_by(BACKLIGHT_STEP) {
set_backlight(val);
time::sleep(BACKLIGHT_DELAY);
}
} else {
for val in (target..current).rev().step_by(BACKLIGHT_STEP) {
set_backlight(val);
time::sleep(BACKLIGHT_DELAY);
}
}
}
pub fn rect(r: Rect, fg_color: Color) {
display::bar(r.x0, r.y0, r.width(), r.height(), fg_color.into());
}
pub fn rounded_rect(r: Rect, fg_color: Color, bg_color: Color, radius: u8) {
display::bar_radius(
r.x0,
r.y0,
r.width(),
r.height(),
fg_color.into(),
bg_color.into(),
radius,
);
}
pub fn icon(center: Point, data: &[u8], fg_color: Color, bg_color: Color) {
let toif_info = display::toif_info(data).unwrap();
assert!(toif_info.grayscale);
let r = Rect::from_center_and_size(
center,
Offset::new(toif_info.width.into(), toif_info.height.into()),
);
display::icon(
r.x0,
r.y0,
r.width(),
r.height(),
&data[12..], // Skip TOIF header.
fg_color.into(),
bg_color.into(),
);
}
// Used on T1 only.
pub fn rounded_rect1(r: Rect, fg_color: Color, bg_color: Color) {
display::bar(r.x0, r.y0, r.width(), r.height(), fg_color.into());
let corners = [
r.top_left(),
r.top_right() + Offset::new(-1, 0),
r.bottom_right() + Offset::new(-1, -1),
r.bottom_left() + Offset::new(0, -1),
];
for p in corners.iter() {
display::bar(p.x, p.y, 1, 1, bg_color.into());
}
}
// Used on T1 only.
pub fn dotted_line(start: Point, width: i32, color: Color) {
for x in (start.x..width).step_by(2) {
display::bar(x, start.y, 1, 1, color.into());
}
}
pub const LOADER_MIN: u16 = 0;
pub const LOADER_MAX: u16 = 1000;
pub fn loader(
progress: u16,
y_offset: i32,
fg_color: Color,
bg_color: Color,
icon: Option<(&[u8], Color)>,
) {
display::loader(
progress,
false,
y_offset,
fg_color.into(),
bg_color.into(),
icon.map(|i| i.0),
icon.map(|i| i.1.into()).unwrap_or(0),
);
}
pub fn loader_indeterminate(
progress: u16,
y_offset: i32,
fg_color: Color,
bg_color: Color,
icon: Option<(&[u8], Color)>,
) {
display::loader(
progress,
true,
y_offset,
fg_color.into(),
bg_color.into(),
icon.map(|i| i.0),
icon.map(|i| i.1.into()).unwrap_or(0),
);
}
pub fn text(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color: Color) {
display::text(
baseline.x,
baseline.y,
text,
font.0,
fg_color.into(),
bg_color.into(),
);
}
pub fn text_width(text: &[u8], font: Font) -> i32 {
display::text_width(text, font.0)
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Font(i32);
impl Font {
pub const fn new(id: i32) -> Self {
Self(id)
}
pub fn text_width(self, text: &[u8]) -> i32 {
text_width(text, self)
}
pub fn text_height(self) -> i32 {
display::text_height(self.0)
}
pub fn line_height(self) -> i32 {
constant::LINE_SPACE + self.text_height()
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Color(u16);
impl Color {
pub const fn from_u16(val: u16) -> Self {
Self(val)
}
pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
let r = (r as u16 & 0xF8) << 8;
let g = (g as u16 & 0xFC) << 3;
let b = (b as u16 & 0xF8) >> 3;
Self(r | g | b)
}
pub const fn r(self) -> u8 {
(self.0 >> 8) as u8 & 0xF8
}
pub const fn g(self) -> u8 {
(self.0 >> 3) as u8 & 0xFC
}
pub const fn b(self) -> u8 {
(self.0 << 3) as u8 & 0xF8
}
pub fn to_u16(self) -> u16 {
self.0
}
pub fn neg(self) -> Self {
Self(!self.0)
}
}
impl From<u16> for Color {
fn from(val: u16) -> Self {
Self(val)
}
}
impl From<Color> for u16 {
fn from(val: Color) -> Self {
val.to_u16()
}
}