mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-23 04:52:01 +00:00
refactor(core/ui): new Mercury design for number input slider
This commit is contained in:
parent
7404436305
commit
7d90552d81
@ -121,6 +121,8 @@ static void _librust_qstrs(void) {
|
|||||||
MP_QSTR_bootscreen;
|
MP_QSTR_bootscreen;
|
||||||
MP_QSTR_br_code;
|
MP_QSTR_br_code;
|
||||||
MP_QSTR_br_type;
|
MP_QSTR_br_type;
|
||||||
|
MP_QSTR_brightness__change_title;
|
||||||
|
MP_QSTR_brightness__changed_title;
|
||||||
MP_QSTR_brightness__title;
|
MP_QSTR_brightness__title;
|
||||||
MP_QSTR_button;
|
MP_QSTR_button;
|
||||||
MP_QSTR_button_event;
|
MP_QSTR_button_event;
|
||||||
@ -295,6 +297,7 @@ static void _librust_qstrs(void) {
|
|||||||
MP_QSTR_instructions__learn_more;
|
MP_QSTR_instructions__learn_more;
|
||||||
MP_QSTR_instructions__shares_continue_with_x_template;
|
MP_QSTR_instructions__shares_continue_with_x_template;
|
||||||
MP_QSTR_instructions__shares_start_with_1;
|
MP_QSTR_instructions__shares_start_with_1;
|
||||||
|
MP_QSTR_instructions__swipe_horizontally;
|
||||||
MP_QSTR_instructions__swipe_up;
|
MP_QSTR_instructions__swipe_up;
|
||||||
MP_QSTR_instructions__tap_to_confirm;
|
MP_QSTR_instructions__tap_to_confirm;
|
||||||
MP_QSTR_instructions__tap_to_start;
|
MP_QSTR_instructions__tap_to_start;
|
||||||
@ -618,6 +621,8 @@ static void _librust_qstrs(void) {
|
|||||||
MP_QSTR_send__transaction_signed;
|
MP_QSTR_send__transaction_signed;
|
||||||
MP_QSTR_send__you_are_contributing;
|
MP_QSTR_send__you_are_contributing;
|
||||||
MP_QSTR_set_brightness;
|
MP_QSTR_set_brightness;
|
||||||
|
MP_QSTR_setting__adjust;
|
||||||
|
MP_QSTR_setting__apply;
|
||||||
MP_QSTR_share_words;
|
MP_QSTR_share_words;
|
||||||
MP_QSTR_share_words__words_in_order;
|
MP_QSTR_share_words__words_in_order;
|
||||||
MP_QSTR_share_words__wrote_down_all;
|
MP_QSTR_share_words__wrote_down_all;
|
||||||
|
@ -1330,7 +1330,7 @@ pub enum TranslatedString {
|
|||||||
words__settings = 929, // "Settings"
|
words__settings = 929, // "Settings"
|
||||||
words__try_again = 930, // "Try again."
|
words__try_again = 930, // "Try again."
|
||||||
reset__slip39_checklist_num_groups_x_template = 931, // "Number of groups: {0}"
|
reset__slip39_checklist_num_groups_x_template = 931, // "Number of groups: {0}"
|
||||||
brightness__title = 932, // "Change display brightness"
|
brightness__title = 932, // "Display brightness"
|
||||||
recovery__title_unlock_repeated_backup = 933, // "Multi-share backup"
|
recovery__title_unlock_repeated_backup = 933, // "Multi-share backup"
|
||||||
recovery__unlock_repeated_backup = 934, // "Create additional backup?"
|
recovery__unlock_repeated_backup = 934, // "Create additional backup?"
|
||||||
recovery__unlock_repeated_backup_verb = 935, // "Create backup"
|
recovery__unlock_repeated_backup_verb = 935, // "Create backup"
|
||||||
@ -1349,6 +1349,11 @@ pub enum TranslatedString {
|
|||||||
tutorial__title_well_done = 948, // "Well done!"
|
tutorial__title_well_done = 948, // "Well done!"
|
||||||
tutorial__lets_begin = 949, // "Learn how to use and navigate this device with ease."
|
tutorial__lets_begin = 949, // "Learn how to use and navigate this device with ease."
|
||||||
tutorial__get_started = 950, // "Get started!"
|
tutorial__get_started = 950, // "Get started!"
|
||||||
|
instructions__swipe_horizontally = 951, // "Swipe horizontally"
|
||||||
|
setting__adjust = 952, // "Adjust"
|
||||||
|
setting__apply = 953, // "Apply"
|
||||||
|
brightness__changed_title = 954, // "Display brightness changed"
|
||||||
|
brightness__change_title = 955, // "Change display brightness"
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TranslatedString {
|
impl TranslatedString {
|
||||||
@ -2673,7 +2678,7 @@ impl TranslatedString {
|
|||||||
Self::words__settings => "Settings",
|
Self::words__settings => "Settings",
|
||||||
Self::words__try_again => "Try again.",
|
Self::words__try_again => "Try again.",
|
||||||
Self::reset__slip39_checklist_num_groups_x_template => "Number of groups: {0}",
|
Self::reset__slip39_checklist_num_groups_x_template => "Number of groups: {0}",
|
||||||
Self::brightness__title => "Change display brightness",
|
Self::brightness__title => "Display brightness",
|
||||||
Self::recovery__title_unlock_repeated_backup => "Multi-share backup",
|
Self::recovery__title_unlock_repeated_backup => "Multi-share backup",
|
||||||
Self::recovery__unlock_repeated_backup => "Create additional backup?",
|
Self::recovery__unlock_repeated_backup => "Create additional backup?",
|
||||||
Self::recovery__unlock_repeated_backup_verb => "Create backup",
|
Self::recovery__unlock_repeated_backup_verb => "Create backup",
|
||||||
@ -2692,6 +2697,11 @@ impl TranslatedString {
|
|||||||
Self::tutorial__title_well_done => "Well done!",
|
Self::tutorial__title_well_done => "Well done!",
|
||||||
Self::tutorial__lets_begin => "Learn how to use and navigate this device with ease.",
|
Self::tutorial__lets_begin => "Learn how to use and navigate this device with ease.",
|
||||||
Self::tutorial__get_started => "Get started!",
|
Self::tutorial__get_started => "Get started!",
|
||||||
|
Self::instructions__swipe_horizontally => "Swipe horizontally",
|
||||||
|
Self::setting__adjust => "Adjust",
|
||||||
|
Self::setting__apply => "Apply",
|
||||||
|
Self::brightness__changed_title => "Display brightness changed",
|
||||||
|
Self::brightness__change_title => "Change display brightness",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4036,6 +4046,11 @@ impl TranslatedString {
|
|||||||
Qstr::MP_QSTR_tutorial__title_well_done => Some(Self::tutorial__title_well_done),
|
Qstr::MP_QSTR_tutorial__title_well_done => Some(Self::tutorial__title_well_done),
|
||||||
Qstr::MP_QSTR_tutorial__lets_begin => Some(Self::tutorial__lets_begin),
|
Qstr::MP_QSTR_tutorial__lets_begin => Some(Self::tutorial__lets_begin),
|
||||||
Qstr::MP_QSTR_tutorial__get_started => Some(Self::tutorial__get_started),
|
Qstr::MP_QSTR_tutorial__get_started => Some(Self::tutorial__get_started),
|
||||||
|
Qstr::MP_QSTR_instructions__swipe_horizontally => Some(Self::instructions__swipe_horizontally),
|
||||||
|
Qstr::MP_QSTR_setting__adjust => Some(Self::setting__adjust),
|
||||||
|
Qstr::MP_QSTR_setting__apply => Some(Self::setting__apply),
|
||||||
|
Qstr::MP_QSTR_brightness__changed_title => Some(Self::brightness__changed_title),
|
||||||
|
Qstr::MP_QSTR_brightness__change_title => Some(Self::brightness__change_title),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ mod keyboard;
|
|||||||
mod loader;
|
mod loader;
|
||||||
#[cfg(feature = "translations")]
|
#[cfg(feature = "translations")]
|
||||||
mod number_input;
|
mod number_input;
|
||||||
|
#[cfg(feature = "translations")]
|
||||||
pub mod number_input_slider;
|
pub mod number_input_slider;
|
||||||
mod progress;
|
mod progress;
|
||||||
#[cfg(feature = "translations")]
|
#[cfg(feature = "translations")]
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
strutil::ShortString,
|
strutil::{ShortString, TString},
|
||||||
|
translations::TR,
|
||||||
ui::{
|
ui::{
|
||||||
component::{base::ComponentExt, Child, Component, Event, EventCtx},
|
component::{base::ComponentExt, Child, Component, Event, EventCtx},
|
||||||
constant::screen,
|
constant::screen,
|
||||||
display,
|
display,
|
||||||
event::TouchEvent,
|
event::TouchEvent,
|
||||||
geometry::{Alignment, Insets, Point, Rect},
|
geometry::{Alignment, Alignment2D, Insets, Offset, Point, Rect},
|
||||||
shape::{self, Renderer},
|
shape::{self, Renderer},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::theme;
|
use super::{theme, Footer};
|
||||||
|
|
||||||
pub enum NumberInputSliderDialogMsg {
|
pub enum NumberInputSliderDialogMsg {
|
||||||
Changed(u16),
|
Changed(u16),
|
||||||
@ -18,22 +19,25 @@ pub enum NumberInputSliderDialogMsg {
|
|||||||
|
|
||||||
pub struct NumberInputSliderDialog {
|
pub struct NumberInputSliderDialog {
|
||||||
area: Rect,
|
area: Rect,
|
||||||
text_area: Rect,
|
|
||||||
input: Child<NumberInputSlider>,
|
input: Child<NumberInputSlider>,
|
||||||
|
footer: Footer<'static>,
|
||||||
min: u16,
|
min: u16,
|
||||||
max: u16,
|
max: u16,
|
||||||
val: u16,
|
val: u16,
|
||||||
|
init_val: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumberInputSliderDialog {
|
impl NumberInputSliderDialog {
|
||||||
pub fn new(min: u16, max: u16, init_value: u16) -> Self {
|
pub fn new(min: u16, max: u16, init_value: u16) -> Self {
|
||||||
Self {
|
Self {
|
||||||
area: Rect::zero(),
|
area: Rect::zero(),
|
||||||
text_area: Rect::zero(),
|
|
||||||
input: NumberInputSlider::new(min, max, init_value).into_child(),
|
input: NumberInputSlider::new(min, max, init_value).into_child(),
|
||||||
|
footer: Footer::new::<TString<'static>>(TR::instructions__swipe_horizontally.into())
|
||||||
|
.with_description::<TString<'static>>(TR::setting__adjust.into()),
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
val: init_value,
|
val: init_value,
|
||||||
|
init_val: init_value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,25 +46,50 @@ impl NumberInputSliderDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const INPUT_AREA_HEIGHT: i16 = 91;
|
||||||
|
|
||||||
impl Component for NumberInputSliderDialog {
|
impl Component for NumberInputSliderDialog {
|
||||||
type Msg = NumberInputSliderDialogMsg;
|
type Msg = NumberInputSliderDialogMsg;
|
||||||
|
|
||||||
fn place(&mut self, bounds: Rect) -> Rect {
|
fn place(&mut self, bounds: Rect) -> Rect {
|
||||||
self.area = bounds;
|
self.area = bounds;
|
||||||
let content_area = self.area.inset(Insets::top(2 * theme::BUTTON_SPACING));
|
|
||||||
let (_, content_area) = content_area.split_top(30);
|
|
||||||
let (input_area, _) = content_area.split_top(15);
|
|
||||||
let (text_area, _) = content_area.split_bottom(theme::BUTTON_HEIGHT);
|
|
||||||
|
|
||||||
self.text_area = text_area;
|
let whole_area = self.area.inset(Insets::bottom(theme::SPACING));
|
||||||
|
let (remaining, footer_area) = whole_area.split_bottom(self.footer.height());
|
||||||
|
self.footer.place(footer_area);
|
||||||
|
let content_area = remaining;
|
||||||
|
|
||||||
|
let used_area = content_area
|
||||||
|
.inset(Insets::sides(theme::SPACING))
|
||||||
|
.inset(Insets::bottom(theme::SPACING));
|
||||||
|
|
||||||
|
let input_area = Rect::snap(
|
||||||
|
used_area.center(),
|
||||||
|
Offset::new(used_area.width(), INPUT_AREA_HEIGHT),
|
||||||
|
Alignment2D::CENTER,
|
||||||
|
);
|
||||||
|
|
||||||
self.input.place(input_area.inset(Insets::sides(20)));
|
self.input.place(input_area.inset(Insets::sides(20)));
|
||||||
|
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||||
if let Some(value) = self.input.event(ctx, event) {
|
if let Some(value) = self.input.event(ctx, event) {
|
||||||
self.val = value;
|
self.val = value;
|
||||||
|
|
||||||
|
if self.val == self.init_val || self.input.inner().touching {
|
||||||
|
self.footer
|
||||||
|
.update_instruction(ctx, TR::instructions__swipe_horizontally);
|
||||||
|
self.footer.update_description(ctx, TR::setting__adjust);
|
||||||
|
ctx.request_paint();
|
||||||
|
} else {
|
||||||
|
self.footer
|
||||||
|
.update_instruction(ctx, TR::instructions__swipe_up);
|
||||||
|
self.footer.update_description(ctx, TR::setting__apply);
|
||||||
|
ctx.request_paint();
|
||||||
|
}
|
||||||
|
|
||||||
return Some(Self::Msg::Changed(value));
|
return Some(Self::Msg::Changed(value));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -72,17 +101,7 @@ impl Component for NumberInputSliderDialog {
|
|||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
self.input.render(target);
|
self.input.render(target);
|
||||||
|
self.footer.render(target);
|
||||||
let mut str = ShortString::new();
|
|
||||||
let val_pct = (100 * (self.val - self.min)) / (self.max - self.min);
|
|
||||||
|
|
||||||
unwrap!(ufmt::uwrite!(str, "{} %", val_pct));
|
|
||||||
|
|
||||||
shape::Text::new(self.text_area.center(), &str)
|
|
||||||
.with_font(theme::TEXT_NORMAL.text_font)
|
|
||||||
.with_fg(theme::TEXT_NORMAL.text_color)
|
|
||||||
.with_align(Alignment::Center)
|
|
||||||
.render(target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,9 +116,11 @@ impl crate::trace::Trace for NumberInputSliderDialog {
|
|||||||
pub struct NumberInputSlider {
|
pub struct NumberInputSlider {
|
||||||
area: Rect,
|
area: Rect,
|
||||||
touch_area: Rect,
|
touch_area: Rect,
|
||||||
|
text_area: Rect,
|
||||||
min: u16,
|
min: u16,
|
||||||
max: u16,
|
max: u16,
|
||||||
value: u16,
|
value: u16,
|
||||||
|
touching: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumberInputSlider {
|
impl NumberInputSlider {
|
||||||
@ -108,20 +129,27 @@ impl NumberInputSlider {
|
|||||||
Self {
|
Self {
|
||||||
area: Rect::zero(),
|
area: Rect::zero(),
|
||||||
touch_area: Rect::zero(),
|
touch_area: Rect::zero(),
|
||||||
|
text_area: Rect::zero(),
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
value,
|
value,
|
||||||
|
touching: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slider_eval(&mut self, pos: Point, ctx: &mut EventCtx) -> Option<u16> {
|
pub fn touch_eval(
|
||||||
if self.touch_area.contains(pos) {
|
&mut self,
|
||||||
|
pos: Point,
|
||||||
|
ctx: &mut EventCtx,
|
||||||
|
force_bubble_up: bool,
|
||||||
|
) -> Option<u16> {
|
||||||
|
if self.touching {
|
||||||
let filled = pos.x - self.area.x0;
|
let filled = pos.x - self.area.x0;
|
||||||
let filled = filled.clamp(0, self.area.width());
|
let filled = filled.clamp(0, self.area.width());
|
||||||
let val_pct = (filled as u16 * 100) / self.area.width() as u16;
|
let val_pct = (filled as u16 * 100) / self.area.width() as u16;
|
||||||
let val = (val_pct * (self.max - self.min)) / 100 + self.min;
|
let val = (val_pct * (self.max - self.min)) / 100 + self.min;
|
||||||
|
|
||||||
if val != self.value {
|
if val != self.value || force_bubble_up {
|
||||||
self.value = val;
|
self.value = val;
|
||||||
ctx.request_paint();
|
ctx.request_paint();
|
||||||
return Some(self.value);
|
return Some(self.value);
|
||||||
@ -136,16 +164,26 @@ impl Component for NumberInputSlider {
|
|||||||
|
|
||||||
fn place(&mut self, bounds: Rect) -> Rect {
|
fn place(&mut self, bounds: Rect) -> Rect {
|
||||||
self.area = bounds;
|
self.area = bounds;
|
||||||
self.touch_area = bounds.outset(Insets::new(40, 20, 40, 20)).clamp(screen());
|
self.touch_area = bounds.outset(Insets::new(0, 20, 0, 20)).clamp(screen());
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||||
if let Event::Touch(touch_event) = event {
|
if let Event::Touch(touch_event) = event {
|
||||||
return match touch_event {
|
return match touch_event {
|
||||||
TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx),
|
TouchEvent::TouchStart(pos) => {
|
||||||
TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx),
|
if self.touch_area.contains(pos) {
|
||||||
TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx),
|
self.touching = true;
|
||||||
|
ctx.request_paint();
|
||||||
|
}
|
||||||
|
self.touch_eval(pos, ctx, true)
|
||||||
|
}
|
||||||
|
TouchEvent::TouchMove(pos) => self.touch_eval(pos, ctx, false),
|
||||||
|
TouchEvent::TouchEnd(pos) => {
|
||||||
|
self.touching = false;
|
||||||
|
ctx.request_paint();
|
||||||
|
self.touch_eval(pos, ctx, true)
|
||||||
|
}
|
||||||
TouchEvent::TouchAbort => None,
|
TouchEvent::TouchAbort => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -160,16 +198,24 @@ impl Component for NumberInputSlider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
|
let (top_left_shape, top_right_shape, bot_left_shape, bot_right_shape) =
|
||||||
|
shape::CornerHighlight::from_rect(
|
||||||
|
self.area,
|
||||||
|
if self.touching {
|
||||||
|
theme::GREY_DARK
|
||||||
|
} else {
|
||||||
|
theme::WHITE
|
||||||
|
},
|
||||||
|
theme::BG,
|
||||||
|
);
|
||||||
|
top_left_shape.render(target);
|
||||||
|
top_right_shape.render(target);
|
||||||
|
bot_left_shape.render(target);
|
||||||
|
bot_right_shape.render(target);
|
||||||
|
|
||||||
let val_pct = (100 * (self.value - self.min)) / (self.max - self.min);
|
let val_pct = (100 * (self.value - self.min)) / (self.max - self.min);
|
||||||
|
|
||||||
shape::Bar::new(self.area)
|
let inner = self.area.inset(Insets::uniform(10));
|
||||||
.with_radius(2)
|
|
||||||
.with_thickness(2)
|
|
||||||
.with_bg(theme::BG)
|
|
||||||
.with_fg(theme::FG)
|
|
||||||
.render(target);
|
|
||||||
|
|
||||||
let inner = self.area.inset(Insets::uniform(1));
|
|
||||||
|
|
||||||
let fill_to = (val_pct as i16 * inner.width()) / 100;
|
let fill_to = (val_pct as i16 * inner.width()) / 100;
|
||||||
|
|
||||||
@ -177,8 +223,26 @@ impl Component for NumberInputSlider {
|
|||||||
|
|
||||||
shape::Bar::new(inner)
|
shape::Bar::new(inner)
|
||||||
.with_radius(1)
|
.with_radius(1)
|
||||||
.with_bg(theme::FG)
|
.with_bg(if self.touching {
|
||||||
|
theme::WHITE
|
||||||
|
} else {
|
||||||
|
theme::GREY_EXTRA_DARK
|
||||||
|
})
|
||||||
.render(target);
|
.render(target);
|
||||||
|
|
||||||
|
let mut str = ShortString::new();
|
||||||
|
let val_pct = (100 * (self.value - self.min)) / (self.max - self.min);
|
||||||
|
|
||||||
|
unwrap!(ufmt::uwrite!(str, "{} %", val_pct));
|
||||||
|
|
||||||
|
if !self.touching {
|
||||||
|
let text_height = theme::TEXT_BOLD.text_font.line_height();
|
||||||
|
shape::Text::new(self.area.center() + Offset::new(0, text_height / 2), &str)
|
||||||
|
.with_font(theme::TEXT_BOLD.text_font)
|
||||||
|
.with_fg(theme::TEXT_BOLD.text_color)
|
||||||
|
.with_align(Alignment::Center)
|
||||||
|
.render(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ use crate::{
|
|||||||
ui::{
|
ui::{
|
||||||
component::{base::ComponentExt, swipe_detect::SwipeSettings, SwipeDirection},
|
component::{base::ComponentExt, swipe_detect::SwipeSettings, SwipeDirection},
|
||||||
flow::{
|
flow::{
|
||||||
base::{Decision, FlowMsg},
|
base::{DecisionBuilder as _, FlowMsg, StateChange},
|
||||||
flow_store, FlowState, FlowStore, SwipeFlow,
|
FlowState, SwipeFlow,
|
||||||
},
|
},
|
||||||
layout::obj::LayoutObj,
|
layout::obj::LayoutObj,
|
||||||
model_mercury::component::{
|
model_mercury::component::{
|
||||||
@ -21,7 +21,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
component::{Frame, FrameMsg, PromptScreen, VerticalMenu, VerticalMenuChoiceMsg},
|
component::{Frame, FrameMsg, PromptScreen, StatusScreen, VerticalMenu, VerticalMenuChoiceMsg},
|
||||||
theme,
|
theme,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,41 +30,35 @@ pub enum SetBrightness {
|
|||||||
Slider,
|
Slider,
|
||||||
Menu,
|
Menu,
|
||||||
Confirm,
|
Confirm,
|
||||||
|
Confirmed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlowState for SetBrightness {
|
impl FlowState for SetBrightness {
|
||||||
fn handle_swipe(&self, direction: SwipeDirection) -> Decision<Self> {
|
#[inline]
|
||||||
|
fn index(&'static self) -> usize {
|
||||||
|
*self as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
|
||||||
match (self, direction) {
|
match (self, direction) {
|
||||||
(SetBrightness::Menu, SwipeDirection::Right) => {
|
(Self::Menu, SwipeDirection::Right) => Self::Slider.swipe(direction),
|
||||||
Decision::Goto(SetBrightness::Slider, direction)
|
(Self::Slider, SwipeDirection::Up) => Self::Confirm.swipe(direction),
|
||||||
}
|
(Self::Confirm, SwipeDirection::Down) => Self::Slider.swipe(direction),
|
||||||
(SetBrightness::Slider, SwipeDirection::Up) => {
|
(Self::Confirm, SwipeDirection::Left) => Self::Menu.swipe(direction),
|
||||||
Decision::Goto(SetBrightness::Confirm, direction)
|
(Self::Confirmed, SwipeDirection::Up) => self.return_msg(FlowMsg::Confirmed),
|
||||||
}
|
_ => self.do_nothing(),
|
||||||
(SetBrightness::Confirm, SwipeDirection::Down) => {
|
|
||||||
Decision::Goto(SetBrightness::Slider, direction)
|
|
||||||
}
|
|
||||||
(SetBrightness::Confirm, SwipeDirection::Left) => {
|
|
||||||
Decision::Goto(SetBrightness::Menu, direction)
|
|
||||||
}
|
|
||||||
_ => Decision::Nothing,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_event(&self, msg: FlowMsg) -> Decision<Self> {
|
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
|
||||||
match (self, msg) {
|
match (self, msg) {
|
||||||
(SetBrightness::Slider, FlowMsg::Info) => {
|
(Self::Slider, FlowMsg::Info) => Self::Menu.swipe_left(),
|
||||||
Decision::Goto(SetBrightness::Menu, SwipeDirection::Left)
|
(Self::Menu, FlowMsg::Cancelled) => Self::Slider.swipe_right(),
|
||||||
}
|
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
|
||||||
(SetBrightness::Menu, FlowMsg::Cancelled) => {
|
(Self::Confirm, FlowMsg::Confirmed) => Self::Confirmed.swipe_up(),
|
||||||
Decision::Goto(SetBrightness::Slider, SwipeDirection::Right)
|
(Self::Confirm, FlowMsg::Info) => Self::Menu.swipe_left(),
|
||||||
}
|
(Self::Confirmed, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||||
(SetBrightness::Menu, FlowMsg::Choice(0)) => Decision::Return(FlowMsg::Cancelled),
|
_ => self.do_nothing(),
|
||||||
(SetBrightness::Confirm, FlowMsg::Confirmed) => Decision::Return(FlowMsg::Confirmed),
|
|
||||||
(SetBrightness::Confirm, FlowMsg::Info) => {
|
|
||||||
Decision::Goto(SetBrightness::Menu, SwipeDirection::Left)
|
|
||||||
}
|
|
||||||
_ => Decision::Nothing,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,8 +81,8 @@ impl SetBrightness {
|
|||||||
current.unwrap_or(theme::backlight::get_backlight_normal()),
|
current.unwrap_or(theme::backlight::get_backlight_normal()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.with_subtitle(TR::homescreen__settings_subtitle.into())
|
||||||
.with_menu_button()
|
.with_menu_button()
|
||||||
.with_footer(TR::instructions__swipe_up.into(), None)
|
|
||||||
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
|
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
|
||||||
.map(|msg| match msg {
|
.map(|msg| match msg {
|
||||||
FrameMsg::Content(NumberInputSliderDialogMsg::Changed(n)) => {
|
FrameMsg::Content(NumberInputSliderDialogMsg::Changed(n)) => {
|
||||||
@ -111,7 +105,7 @@ impl SetBrightness {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let content_confirm = Frame::left_aligned(
|
let content_confirm = Frame::left_aligned(
|
||||||
TR::brightness__title.into(),
|
TR::brightness__change_title.into(),
|
||||||
SwipeContent::new(PromptScreen::new_tap_to_confirm()),
|
SwipeContent::new(PromptScreen::new_tap_to_confirm()),
|
||||||
)
|
)
|
||||||
.with_footer(TR::instructions__tap_to_confirm.into(), None)
|
.with_footer(TR::instructions__tap_to_confirm.into(), None)
|
||||||
@ -126,12 +120,19 @@ impl SetBrightness {
|
|||||||
FrameMsg::Button(_) => Some(FlowMsg::Info),
|
FrameMsg::Button(_) => Some(FlowMsg::Info),
|
||||||
});
|
});
|
||||||
|
|
||||||
let store = flow_store()
|
let content_confirmed = Frame::left_aligned(
|
||||||
.add(content_slider)?
|
TR::brightness__changed_title.into(),
|
||||||
.add(content_menu)?
|
SwipeContent::new(StatusScreen::new_success()).with_no_attach_anim(),
|
||||||
.add(content_confirm)?;
|
)
|
||||||
|
.with_footer(TR::instructions__swipe_up.into(), None)
|
||||||
|
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
|
||||||
|
.map(move |_msg| Some(FlowMsg::Confirmed));
|
||||||
|
|
||||||
let res = SwipeFlow::new(SetBrightness::Slider, store)?;
|
let res = SwipeFlow::new(&SetBrightness::Slider)?
|
||||||
|
.with_page(&SetBrightness::Slider, content_slider)?
|
||||||
|
.with_page(&SetBrightness::Menu, content_menu)?
|
||||||
|
.with_page(&SetBrightness::Confirm, content_confirm)?
|
||||||
|
.with_page(&SetBrightness::Confirmed, content_confirmed)?;
|
||||||
|
|
||||||
Ok(LayoutObj::new(res)?.into())
|
Ok(LayoutObj::new(res)?.into())
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ use super::{
|
|||||||
CoinJoinProgress, FidoConfirm, FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg,
|
CoinJoinProgress, FidoConfirm, FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg,
|
||||||
Lockscreen, MnemonicInput, MnemonicKeyboard, MnemonicKeyboardMsg, PassphraseKeyboard,
|
Lockscreen, MnemonicInput, MnemonicKeyboard, MnemonicKeyboardMsg, PassphraseKeyboard,
|
||||||
PassphraseKeyboardMsg, PinKeyboard, PinKeyboardMsg, Progress, PromptScreen,
|
PassphraseKeyboardMsg, PinKeyboard, PinKeyboardMsg, Progress, PromptScreen,
|
||||||
SelectWordCount, SelectWordCountMsg, SetBrightnessDialog, Slip39Input, StatusScreen,
|
SelectWordCount, SelectWordCountMsg, Slip39Input, StatusScreen, SwipeUpScreen,
|
||||||
SwipeUpScreen, SwipeUpScreenMsg, VerticalMenu, VerticalMenuChoiceMsg,
|
SwipeUpScreenMsg, VerticalMenu, VerticalMenuChoiceMsg,
|
||||||
},
|
},
|
||||||
flow, theme,
|
flow, theme,
|
||||||
};
|
};
|
||||||
|
@ -79,7 +79,9 @@ class TR:
|
|||||||
bitcoin__unverified_external_inputs: str = "The transaction contains unverified external inputs."
|
bitcoin__unverified_external_inputs: str = "The transaction contains unverified external inputs."
|
||||||
bitcoin__valid_signature: str = "The signature is valid."
|
bitcoin__valid_signature: str = "The signature is valid."
|
||||||
bitcoin__voting_rights: str = "Voting rights to:"
|
bitcoin__voting_rights: str = "Voting rights to:"
|
||||||
brightness__title: str = "Change display brightness"
|
brightness__change_title: str = "Change display brightness"
|
||||||
|
brightness__changed_title: str = "Display brightness changed"
|
||||||
|
brightness__title: str = "Display brightness"
|
||||||
buttons__abort: str = "Abort"
|
buttons__abort: str = "Abort"
|
||||||
buttons__access: str = "Access"
|
buttons__access: str = "Access"
|
||||||
buttons__again: str = "Again"
|
buttons__again: str = "Again"
|
||||||
@ -385,6 +387,7 @@ class TR:
|
|||||||
instructions__learn_more: str = "Learn more"
|
instructions__learn_more: str = "Learn more"
|
||||||
instructions__shares_continue_with_x_template: str = "Continue with Share #{0}"
|
instructions__shares_continue_with_x_template: str = "Continue with Share #{0}"
|
||||||
instructions__shares_start_with_1: str = "Start with share #1"
|
instructions__shares_start_with_1: str = "Start with share #1"
|
||||||
|
instructions__swipe_horizontally: str = "Swipe horizontally"
|
||||||
instructions__swipe_up: str = "Swipe up"
|
instructions__swipe_up: str = "Swipe up"
|
||||||
instructions__tap_to_confirm: str = "Tap to confirm"
|
instructions__tap_to_confirm: str = "Tap to confirm"
|
||||||
instructions__tap_to_start: str = "Tap to start"
|
instructions__tap_to_start: str = "Tap to start"
|
||||||
@ -742,6 +745,8 @@ class TR:
|
|||||||
send__transaction_id: str = "Transaction ID:"
|
send__transaction_id: str = "Transaction ID:"
|
||||||
send__transaction_signed: str = "Transaction signed"
|
send__transaction_signed: str = "Transaction signed"
|
||||||
send__you_are_contributing: str = "You are contributing:"
|
send__you_are_contributing: str = "You are contributing:"
|
||||||
|
setting__adjust: str = "Adjust"
|
||||||
|
setting__apply: str = "Apply"
|
||||||
share_words__words_in_order: str = " words in order."
|
share_words__words_in_order: str = " words in order."
|
||||||
share_words__wrote_down_all: str = "I wrote down all "
|
share_words__wrote_down_all: str = "I wrote down all "
|
||||||
sign_message__bytes_template: str = "{0} Bytes"
|
sign_message__bytes_template: str = "{0} Bytes"
|
||||||
|
@ -81,7 +81,9 @@
|
|||||||
"bitcoin__unverified_external_inputs": "The transaction contains unverified external inputs.",
|
"bitcoin__unverified_external_inputs": "The transaction contains unverified external inputs.",
|
||||||
"bitcoin__valid_signature": "The signature is valid.",
|
"bitcoin__valid_signature": "The signature is valid.",
|
||||||
"bitcoin__voting_rights": "Voting rights to:",
|
"bitcoin__voting_rights": "Voting rights to:",
|
||||||
"brightness__title": "Change display brightness",
|
"brightness__title": "Display brightness",
|
||||||
|
"brightness__change_title": "Change display brightness",
|
||||||
|
"brightness__changed_title": "Display brightness changed",
|
||||||
"buttons__abort": "Abort",
|
"buttons__abort": "Abort",
|
||||||
"buttons__access": "Access",
|
"buttons__access": "Access",
|
||||||
"buttons__again": "Again",
|
"buttons__again": "Again",
|
||||||
@ -388,6 +390,7 @@
|
|||||||
"instructions__shares_continue_with_x_template": "Continue with Share #{0}",
|
"instructions__shares_continue_with_x_template": "Continue with Share #{0}",
|
||||||
"instructions__shares_start_with_1": "Start with share #1",
|
"instructions__shares_start_with_1": "Start with share #1",
|
||||||
"instructions__swipe_up": "Swipe up",
|
"instructions__swipe_up": "Swipe up",
|
||||||
|
"instructions__swipe_horizontally": "Swipe horizontally",
|
||||||
"instructions__tap_to_confirm": "Tap to confirm",
|
"instructions__tap_to_confirm": "Tap to confirm",
|
||||||
"instructions__tap_to_start": "Tap to start",
|
"instructions__tap_to_start": "Tap to start",
|
||||||
"joint__title": "Joint transaction",
|
"joint__title": "Joint transaction",
|
||||||
@ -744,6 +747,8 @@
|
|||||||
"send__transaction_id": "Transaction ID:",
|
"send__transaction_id": "Transaction ID:",
|
||||||
"send__transaction_signed": "Transaction signed",
|
"send__transaction_signed": "Transaction signed",
|
||||||
"send__you_are_contributing": "You are contributing:",
|
"send__you_are_contributing": "You are contributing:",
|
||||||
|
"setting__adjust": "Adjust",
|
||||||
|
"setting__apply": "Apply",
|
||||||
"share_words__words_in_order": " words in order.",
|
"share_words__words_in_order": " words in order.",
|
||||||
"share_words__wrote_down_all": "I wrote down all ",
|
"share_words__wrote_down_all": "I wrote down all ",
|
||||||
"sign_message__bytes_template": "{0} Bytes",
|
"sign_message__bytes_template": "{0} Bytes",
|
||||||
|
@ -949,5 +949,10 @@
|
|||||||
"947": "tutorial__title_hold",
|
"947": "tutorial__title_hold",
|
||||||
"948": "tutorial__title_well_done",
|
"948": "tutorial__title_well_done",
|
||||||
"949": "tutorial__lets_begin",
|
"949": "tutorial__lets_begin",
|
||||||
"950": "tutorial__get_started"
|
"950": "tutorial__get_started",
|
||||||
|
"951": "instructions__swipe_horizontally",
|
||||||
|
"952": "setting__adjust",
|
||||||
|
"953": "setting__apply",
|
||||||
|
"954": "brightness__changed_title",
|
||||||
|
"955": "brightness__change_title"
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"current": {
|
"current": {
|
||||||
"merkle_root": "f8fe7da5605cc8f5136d8d77b526df530daddbb6795e7c7fa1906822d3dd2a10",
|
"merkle_root": "c94efabb9554eea2adb7f312469fa8b366503bbdb57dd7f92fa67b23dc63bb97",
|
||||||
"datetime": "2024-07-08T22:50:20.632650",
|
"datetime": "2024-07-15T09:41:37.793874",
|
||||||
"commit": "c9c4bf63623d411384737662ec2aefc88824812d"
|
"commit": "5935708ac86d336364e5ab78fc5fd67b19402eaf"
|
||||||
},
|
},
|
||||||
"history": [
|
"history": [
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user