diff --git a/core/embed/rust/src/ui/layout_jefferson/theme/mod.rs b/core/embed/rust/src/ui/layout_jefferson/theme/mod.rs index 4f0d43f95a..9df083f223 100644 --- a/core/embed/rust/src/ui/layout_jefferson/theme/mod.rs +++ b/core/embed/rust/src/ui/layout_jefferson/theme/mod.rs @@ -13,6 +13,7 @@ use crate::{ use super::component::{ButtonStyle, ButtonStyleSheet, ResultStyle}; +pub const CONFIRM_HOLD_DURATION: Duration = Duration::from_millis(1500); pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); // Color palette. @@ -99,25 +100,51 @@ pub const fn button_default() -> ButtonStyleSheet { ButtonStyleSheet { normal: &ButtonStyle { font: Font::DEMIBOLD, - text_color: FG, + text_color: GREY_LIGHT, button_color: BG, - icon_color: FG, + icon_color: GREY_LIGHT, background_color: BG, }, active: &ButtonStyle { font: Font::DEMIBOLD, - text_color: FG, - button_color: BG, - icon_color: FG, + text_color: GREY_LIGHT, + button_color: GREY_SUPER_DARK, + icon_color: GREY_LIGHT, background_color: BG, }, disabled: &ButtonStyle { font: Font::DEMIBOLD, - text_color: FG, + text_color: GREY_LIGHT, + button_color: GREY_DARK, + icon_color: GREY_LIGHT, + background_color: GREY_DARK, + }, + } +} + +pub const fn button_confirm() -> ButtonStyleSheet { + ButtonStyleSheet { + normal: &ButtonStyle { + font: Font::DEMIBOLD, + text_color: GREEN_LIGHT, button_color: BG, - icon_color: FG, + icon_color: GREEN_LIGHT, background_color: BG, }, + active: &ButtonStyle { + font: Font::DEMIBOLD, + text_color: GREEN, + button_color: GREY_SUPER_DARK, + icon_color: GREEN, + background_color: BG, + }, + disabled: &ButtonStyle { + font: Font::DEMIBOLD, + text_color: GREY_LIGHT, + button_color: GREY_DARK, + icon_color: GREY_LIGHT, + background_color: GREY_DARK, + }, } } diff --git a/core/embed/rust/src/ui/layout_jefferson/ui_firmware.rs b/core/embed/rust/src/ui/layout_jefferson/ui_firmware.rs index a69172068a..6e11688688 100644 --- a/core/embed/rust/src/ui/layout_jefferson/ui_firmware.rs +++ b/core/embed/rust/src/ui/layout_jefferson/ui_firmware.rs @@ -3,10 +3,14 @@ use crate::{ io::BinaryData, micropython::{gc::Gc, list::List, obj::Obj}, strutil::TString, + translations::TR, ui::{ component::{ - text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort}, - Empty, + text::{ + op::OpTextLayout, + paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort}, + }, + Empty, FormattedText, }, layout::{ obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, @@ -19,23 +23,60 @@ use crate::{ }, }; -use super::{theme, UIJefferson}; +use super::{ + component::{ActionBar, Button, GenericScreen, Header, Hint}, + theme, UIJefferson, +}; impl FirmwareUI for UIJefferson { fn confirm_action( - _title: TString<'static>, - _action: Option>, - _description: Option>, + title: TString<'static>, + action: Option>, + description: Option>, _subtitle: Option>, - _verb: Option>, + verb: Option>, _verb_cancel: Option>, - _hold: bool, + hold: bool, _hold_danger: bool, - _reverse: bool, + reverse: bool, _prompt_screen: bool, _prompt_title: Option>, ) -> Result { - Err::, Error>(Error::ValueError(c"not implemented")) + let action = action.unwrap_or("".into()); + let description = description.unwrap_or("".into()); + let formatted_text = { + let ops = if !reverse { + let mut ops_text = OpTextLayout::new(theme::TEXT_NORMAL); + OpTextLayout::new(theme::TEXT_NORMAL) + .text_normal(action) + .newline() + .text_normal(description) + } else { + OpTextLayout::new(theme::TEXT_NORMAL) + .text_normal(description) + .newline() + .text_demibold(action) + }; + + FormattedText::new(ops).vertically_centered() + }; + + let verb = verb.unwrap_or(TR::buttons__confirm.into()); + let right_button = if hold { + Button::with_text(verb).with_long_press(theme::CONFIRM_HOLD_DURATION) + } else { + Button::with_text(verb) + }; + let screen = GenericScreen::new(formatted_text) + .with_header(Header::new(title)) + // .with_hint(Hint::new_instruction(description, None)) + .with_hint(Hint::new_page_counter()) + .with_action_bar(ActionBar::new_paginate( + Button::with_icon(theme::ICON_CHEVRON_LEFT), + right_button, + )); + let layout = RootComponent::new(screen); + Ok(layout) } fn confirm_address(