WIP - icon screen redesign

grdddj/tt_success_screen_redesign
grdddj 11 months ago
parent 87c7d7f028
commit 67ef4b21d1

@ -104,6 +104,10 @@ impl BlendedImage {
self.area_color, self.area_color,
); );
} }
pub fn height(&self) -> i16 {
self.bg.toif.size().y
}
} }
impl Component for BlendedImage { impl Component for BlendedImage {

@ -156,6 +156,13 @@ where
chr = 0; chr = 0;
} }
} }
pub fn current_height(&self) -> i16 {
self.visible
.iter()
.map(|layout| layout.bounds.height())
.sum()
}
} }
impl<T> Component for Paragraphs<T> impl<T> Component for Paragraphs<T>

@ -7,9 +7,10 @@ use crate::{
paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt}, paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt},
TextStyle, TextStyle,
}, },
Child, Component, Event, EventCtx, Never, Child, Component, Event, EventCtx, Never, Paginate,
}, },
geometry::{Insets, LinearPlacement, Rect}, geometry::{Insets, Rect},
util::ResultExt,
}, },
}; };
@ -102,6 +103,10 @@ where
T: StringType, T: StringType,
U: Component, U: Component,
{ {
pub const ICON_AREA_PADDING: i16 = 2;
pub const TEXT_BUTTON_PADDING: i16 = 15;
pub const TEXT_ICON_PADDING: i16 = 20;
pub fn new(icon: BlendedImage, title: T, controls: U) -> Self { pub fn new(icon: BlendedImage, title: T, controls: U) -> Self {
Self { Self {
image: Child::new(icon), image: Child::new(icon),
@ -109,12 +114,19 @@ where
&theme::TEXT_DEMIBOLD, &theme::TEXT_DEMIBOLD,
title, title,
) )
.centered()])) .centered()])),
.with_placement( controls: Child::new(controls),
LinearPlacement::vertical() }
.align_at_center() }
.with_spacing(Self::VALUE_SPACE),
), pub fn from_paragraphs(
icon: BlendedImage,
paragraphs: Paragraphs<ParagraphVecShort<T>>,
controls: U,
) -> Self {
Self {
image: Child::new(icon),
paragraphs,
controls: Child::new(controls), controls: Child::new(controls),
} }
} }
@ -148,15 +160,10 @@ where
Paragraph::new(&theme::TEXT_NORMAL_OFF_WHITE, l2).centered(), Paragraph::new(&theme::TEXT_NORMAL_OFF_WHITE, l2).centered(),
Paragraph::new(&theme::TEXT_DEMIBOLD, l3).centered(), Paragraph::new(&theme::TEXT_DEMIBOLD, l3).centered(),
]) ])
.into_paragraphs() .into_paragraphs(),
.with_placement(LinearPlacement::vertical().align_at_center()),
controls: Child::new(controls), controls: Child::new(controls),
} }
} }
pub const ICON_AREA_PADDING: i16 = 2;
pub const ICON_AREA_HEIGHT: i16 = 60;
pub const VALUE_SPACE: i16 = 5;
} }
impl<T, U> Component for IconDialog<T, U> impl<T, U> Component for IconDialog<T, U>
@ -172,9 +179,24 @@ where
.inset(Insets::top(Self::ICON_AREA_PADDING)); .inset(Insets::top(Self::ICON_AREA_PADDING));
let controls_area = self.controls.place(bounds); let controls_area = self.controls.place(bounds);
let content_area = bounds.inset(Insets::bottom(controls_area.height())); let content_area = bounds.inset(Insets::bottom(
controls_area.height() + Self::TEXT_BUTTON_PADDING,
));
let (image_area, content_area) = content_area.split_top(Self::ICON_AREA_HEIGHT); // Determining the height of the content and image for placing them correctly.
// There are always fixes paddings between components.
self.paragraphs.place(content_area);
// if self.paragraphs.page_count() > 1 {
// Err::<(), ()>(()).assert_if_debugging_ui("Must be single page");
// }
let content_height = self.paragraphs.current_height();
let (image_area, content_area) = content_area.split_bottom(content_height);
let image_area = image_area.inset(Insets::bottom(Self::TEXT_ICON_PADDING));
let image_height = self.image.inner().height();
// if image_height < image_area.height() {
// Err::<(), ()>(()).assert_if_debugging_ui("Not enough space for image");
// }
let (_, image_area) = image_area.split_bottom(image_height);
self.image.place(image_area); self.image.place(image_area);
self.paragraphs.place(content_area); self.paragraphs.place(content_area);

@ -1065,6 +1065,13 @@ extern "C" fn new_show_mismatch() -> Obj {
let url: StrBuffer = "trezor.io/support".into(); let url: StrBuffer = "trezor.io/support".into();
let button = "QUIT"; let button = "QUIT";
let paragraphs = ParagraphVecShort::from_iter([
Paragraph::new(&theme::TEXT_DEMIBOLD, title).centered(),
Paragraph::new(&theme::TEXT_NORMAL_OFF_WHITE, description).centered(),
Paragraph::new(&theme::TEXT_DEMIBOLD, url).centered(),
])
.into_paragraphs();
let icon = BlendedImage::new( let icon = BlendedImage::new(
theme::IMAGE_BG_OCTAGON, theme::IMAGE_BG_OCTAGON,
theme::IMAGE_FG_WARN, theme::IMAGE_FG_WARN,
@ -1072,19 +1079,15 @@ extern "C" fn new_show_mismatch() -> Obj {
theme::FG, theme::FG,
theme::BG, theme::BG,
); );
let obj = LayoutObj::new( let obj = LayoutObj::new(IconDialog::from_paragraphs(
IconDialog::new( icon,
icon, paragraphs,
title, Button::cancel_confirm(
Button::cancel_confirm( Button::with_icon(theme::ICON_BACK),
Button::with_icon(theme::ICON_BACK), Button::with_text(button).styled(theme::button_reset()),
Button::with_text(button).styled(theme::button_reset()), true,
true, ),
), ))?;
)
.with_description(description)
.with_text(&theme::TEXT_DEMIBOLD, url),
)?;
Ok(obj.into()) Ok(obj.into())
}; };

@ -1102,6 +1102,9 @@ async def confirm_signverify(
) )
# TODO: currently used only in FIDO
# If we used button instead of timeout, we could use show_warning there
# and delete this completely
async def show_error_popup( async def show_error_popup(
title: str, title: str,
description: str, description: str,
@ -1197,16 +1200,16 @@ async def pin_mismatch_popup(
await button_request("pin_mismatch", code=BR_TYPE_OTHER) await button_request("pin_mismatch", code=BR_TYPE_OTHER)
title = "Wipe code mismatch" if is_wipe_code else "PIN mismatch" title = "Wipe code mismatch" if is_wipe_code else "PIN mismatch"
description = "wipe codes" if is_wipe_code else "PINs" description = "wipe codes" if is_wipe_code else "PINs"
return await show_error_popup( return await show_warning(
title, title,
f"The {description} you entered do not match.", f"Entered {description} do not match!",
button="TRY AGAIN", button="TRY AGAIN",
) )
async def wipe_code_same_as_pin_popup() -> None: async def wipe_code_same_as_pin_popup() -> None:
await button_request("wipe_code_same_as_pin", code=BR_TYPE_OTHER) await button_request("wipe_code_same_as_pin", code=BR_TYPE_OTHER)
return await show_error_popup( return await show_warning(
"Invalid wipe code", "Invalid wipe code",
"The wipe code must be different from your PIN.", "The wipe code must be different from your PIN.",
button="TRY AGAIN", button="TRY AGAIN",

Loading…
Cancel
Save