Skip to content

Commit

Permalink
refactor(core/ui): optimize brightness settings for Mercury
Browse files Browse the repository at this point in the history
  • Loading branch information
ibz committed Jul 2, 2024
1 parent a01a787 commit 1ce7237
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,21 @@ use crate::{
constant::screen,
display,
event::TouchEvent,
geometry::{Alignment, Grid, Insets, Point, Rect},
geometry::{Alignment, Insets, Point, Rect},
shape::{self, Renderer},
},
};

use super::{theme, Button, ButtonMsg};
use super::theme;

pub enum NumberInputSliderDialogMsg {
Changed(u16),
Confirmed,
Cancelled,
}

pub struct NumberInputSliderDialog {
area: Rect,
text_area: Rect,
input: Child<NumberInputSlider>,
cancel_button: Child<Button>,
confirm_button: Child<Button>,
min: u16,
max: u16,
val: u16,
Expand All @@ -35,12 +31,6 @@ impl NumberInputSliderDialog {
area: Rect::zero(),
text_area: Rect::zero(),
input: NumberInputSlider::new(min, max, init_value).into_child(),
cancel_button: Button::with_text("CANCEL".into())
.styled(theme::button_cancel())
.into_child(),
confirm_button: Button::with_text("CONFIRM".into())
.styled(theme::button_confirm())
.into_child(),
min,
max,
val: init_value,
Expand All @@ -57,18 +47,14 @@ impl Component for NumberInputSliderDialog {

fn place(&mut self, bounds: Rect) -> Rect {
self.area = bounds;
let button_height = theme::BUTTON_HEIGHT;
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, button_area) = content_area.split_bottom(button_height);
let (text_area, _) = content_area.split_bottom(theme::BUTTON_HEIGHT);

self.text_area = text_area;

let grid = Grid::new(button_area, 1, 2).with_spacing(theme::KEYBOARD_SPACING);
self.input.place(input_area.inset(Insets::sides(20)));
self.cancel_button.place(grid.row_col(0, 0));
self.confirm_button.place(grid.row_col(0, 1));
bounds
}

Expand All @@ -77,19 +63,11 @@ impl Component for NumberInputSliderDialog {
self.val = value;
return Some(Self::Msg::Changed(value));
}
if let Some(ButtonMsg::Clicked) = self.cancel_button.event(ctx, event) {
return Some(Self::Msg::Cancelled);
}
if let Some(ButtonMsg::Clicked) = self.confirm_button.event(ctx, event) {
return Some(Self::Msg::Confirmed);
};
None
}

fn paint(&mut self) {
self.input.paint();
self.cancel_button.paint();
self.confirm_button.paint();
}

fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
Expand All @@ -105,17 +83,12 @@ impl Component for NumberInputSliderDialog {
.with_fg(theme::TEXT_NORMAL.text_color)
.with_align(Alignment::Center)
.render(target);

self.cancel_button.render(target);
self.confirm_button.render(target);
}

#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
sink(self.area);
self.input.bounds(sink);
self.cancel_button.bounds(sink);
self.confirm_button.bounds(sink);
}
}

Expand All @@ -124,8 +97,6 @@ impl crate::trace::Trace for NumberInputSliderDialog {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("NumberInputSliderDialog");
t.child("input", &self.input);
t.child("cancel_button", &self.cancel_button);
t.child("confirm_button", &self.confirm_button);
}
}

Expand Down
13 changes: 2 additions & 11 deletions core/embed/rust/src/ui/model_mercury/component/set_brightness.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{
storage,
trezorhal::display,
ui::{
component::{Component, Event, EventCtx},
Expand All @@ -11,7 +10,6 @@ use crate::{
use super::{
super::theme,
number_input_slider::{NumberInputSliderDialog, NumberInputSliderDialogMsg},
CancelConfirmMsg,
};

pub struct SetBrightnessDialog(NumberInputSliderDialog);
Expand All @@ -28,7 +26,7 @@ impl SetBrightnessDialog {
}

impl Component for SetBrightnessDialog {
type Msg = CancelConfirmMsg;
type Msg = NumberInputSliderDialogMsg;

fn place(&mut self, bounds: Rect) -> Rect {
self.0.place(bounds)
Expand All @@ -38,14 +36,7 @@ impl Component for SetBrightnessDialog {
match self.0.event(ctx, event) {
Some(NumberInputSliderDialogMsg::Changed(value)) => {
display::backlight(value as _);
None
}
Some(NumberInputSliderDialogMsg::Cancelled) => Some(CancelConfirmMsg::Cancelled),
Some(NumberInputSliderDialogMsg::Confirmed) => {
match storage::set_brightness(self.0.value() as _) {
Ok(_) => Some(CancelConfirmMsg::Confirmed),
Err(_) => Some(CancelConfirmMsg::Cancelled), // TODO: handle error
}
Some(NumberInputSliderDialogMsg::Changed(value))
}
None => None,
}
Expand Down
114 changes: 98 additions & 16 deletions core/embed/rust/src/ui/model_mercury/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
qstr::Qstr,
util,
},
storage,
strutil::TString,
translations::TR,
trezorhal::model,
Expand All @@ -34,14 +35,14 @@ use crate::{
},
Border, Component, FormattedText, Label, Never, SwipeDirection, Timeout,
},
flow::Swipable,
flow::{Swipable, base::{FlowMsg, Decision}, SwipeFlow, flow_store, FlowState, FlowStore},
geometry,
layout::{
obj::{ComponentMsgObj, LayoutObj},
result::{CANCELLED, CONFIRMED, INFO},
util::{upy_disable_animation, ConfirmBlob, PropsList},
},
model_mercury::component::{check_homescreen_format, SwipeContent},
model_mercury::component::{check_homescreen_format, SwipeContent, number_input_slider::NumberInputSliderDialogMsg},
},
};

Expand Down Expand Up @@ -216,15 +217,6 @@ where
}
}

impl ComponentMsgObj for SetBrightnessDialog {
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
match msg {
CancelConfirmMsg::Confirmed => Ok(CONFIRMED.as_obj()),
CancelConfirmMsg::Cancelled => Ok(CANCELLED.as_obj()),
}
}
}

impl ComponentMsgObj for Progress {
fn msg_try_into_obj(&self, _msg: Self::Msg) -> Result<Obj, Error> {
unreachable!()
Expand Down Expand Up @@ -1024,14 +1016,104 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}

#[derive(Copy, Clone, PartialEq, Eq, ToPrimitive)]
pub enum SetBrightnessAction {
Slider,
Menu,
Confirm,
}

impl FlowState for SetBrightnessAction {
fn handle_swipe(&self, direction: SwipeDirection) -> Decision<Self> {
match (self, direction) {
(SetBrightnessAction::Menu, SwipeDirection::Right) => {
Decision::Goto(SetBrightnessAction::Slider, direction)
}
(SetBrightnessAction::Slider, SwipeDirection::Up) => {
Decision::Goto(SetBrightnessAction::Confirm, direction)
}
(SetBrightnessAction::Confirm, SwipeDirection::Down) => {
Decision::Goto(SetBrightnessAction::Slider, direction)
}
(SetBrightnessAction::Confirm, SwipeDirection::Left) => {
Decision::Goto(SetBrightnessAction::Menu, direction)
}
_ => Decision::Nothing,
}
}

fn handle_event(&self, msg: FlowMsg) -> Decision<Self> {
match (self, msg) {
(SetBrightnessAction::Slider, FlowMsg::Info) => {
Decision::Goto(SetBrightnessAction::Menu, SwipeDirection::Left)
}
(SetBrightnessAction::Menu, FlowMsg::Cancelled) => {
Decision::Goto(SetBrightnessAction::Slider, SwipeDirection::Right)
}
(SetBrightnessAction::Menu, FlowMsg::Choice(0)) => Decision::Return(FlowMsg::Cancelled),
(SetBrightnessAction::Confirm, FlowMsg::Confirmed) => Decision::Return(FlowMsg::Confirmed),
(SetBrightnessAction::Confirm, FlowMsg::Info) => {
Decision::Goto(SetBrightnessAction::Menu, SwipeDirection::Left)
}
_ => Decision::Nothing,
}
}
}

static mut BRIGHTNESS: u16 = 0;

extern "C" fn new_set_brightness(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let current: Option<u16> = kwargs.get(Qstr::MP_QSTR_current)?.try_into_option()?;
let obj = LayoutObj::new(Frame::centered(
TR::brightness__title.into(),
SetBrightnessDialog::new(current),
))?;
Ok(obj.into())

let content_slider = Frame::centered(TR::brightness__title.into(), SetBrightnessDialog::new(current))
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
.map(|msg| match msg {
FrameMsg::Content(NumberInputSliderDialogMsg::Changed(n)) => {
unsafe { BRIGHTNESS = n; }
None
},
FrameMsg::Button(_) => Some(FlowMsg::Info),
});

let content_menu = Frame::left_aligned("".into(),
VerticalMenu::empty().danger(theme::ICON_CANCEL, TR::buttons__cancel.into())
)
.with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.map(move |msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => {
Some(FlowMsg::Choice(i))
},
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
});

let content_confirm = Frame::left_aligned(TR::brightness__title.into(),
SwipeContent::new(PromptScreen::new_tap_to_confirm()))
.with_footer(TR::instructions__tap_to_confirm.into(), None)
.with_menu_button()
.with_swipe(SwipeDirection::Down, SwipeSettings::default())
.with_swipe(SwipeDirection::Left, SwipeSettings::default())
.map(move |msg| match msg {
FrameMsg::Content(()) => {
match storage::set_brightness(unsafe { BRIGHTNESS } as _) {
Ok(_) => Some(FlowMsg::Confirmed),
Err(_) => Some(FlowMsg::Cancelled),
}
},
FrameMsg::Button(_) => Some(FlowMsg::Info),
});

let store = flow_store()
.add(content_slider)?
.add(content_menu)?
.add(content_confirm)?;

let res = SwipeFlow::new(SetBrightnessAction::Slider, store)?;

Ok(LayoutObj::new(res)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
Expand Down

0 comments on commit 1ce7237

Please sign in to comment.