mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-03 16:56:07 +00:00
feat(eckhart): improve ActionBar content
- button content is moved towards the center a bit - shrink left button at the last page of paginated component - change the order of render in `TextScreen` to account for Header overlay. If the main content reaches the Header area, we do not want to overlay it during Hold to Confirm animation
This commit is contained in:
parent
cea2d5f72f
commit
5edb72ebe9
@ -256,7 +256,7 @@ impl Button {
|
|||||||
let y_offset = Offset::y(self.content_height() / 2);
|
let y_offset = Offset::y(self.content_height() / 2);
|
||||||
let start_of_baseline = match self.text_align {
|
let start_of_baseline = match self.text_align {
|
||||||
Alignment::Start => self.area.left_center() + self.content_offset,
|
Alignment::Start => self.area.left_center() + self.content_offset,
|
||||||
Alignment::Center => self.area.center(),
|
Alignment::Center => self.area.center() + self.content_offset,
|
||||||
Alignment::End => self.area.right_center() - self.content_offset,
|
Alignment::End => self.area.right_center() - self.content_offset,
|
||||||
} + y_offset;
|
} + y_offset;
|
||||||
text.map(|text| {
|
text.map(|text| {
|
||||||
@ -273,7 +273,7 @@ impl Button {
|
|||||||
let subtext_y_offset = Offset::y(self.content_height() / 2);
|
let subtext_y_offset = Offset::y(self.content_height() / 2);
|
||||||
let start_of_baseline = match self.text_align {
|
let start_of_baseline = match self.text_align {
|
||||||
Alignment::Start => self.area.left_center() + self.content_offset,
|
Alignment::Start => self.area.left_center() + self.content_offset,
|
||||||
Alignment::Center => self.area.center(),
|
Alignment::Center => self.area.center() + self.content_offset,
|
||||||
Alignment::End => self.area.right_center() - self.content_offset,
|
Alignment::End => self.area.right_center() - self.content_offset,
|
||||||
};
|
};
|
||||||
let text_baseline = start_of_baseline - text_y_offset;
|
let text_baseline = start_of_baseline - text_y_offset;
|
||||||
@ -296,7 +296,7 @@ impl Button {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
ButtonContent::Icon(icon) => {
|
ButtonContent::Icon(icon) => {
|
||||||
shape::ToifImage::new(self.area.center(), icon.toif)
|
shape::ToifImage::new(self.area.center() + self.content_offset, icon.toif)
|
||||||
.with_align(Alignment2D::CENTER)
|
.with_align(Alignment2D::CENTER)
|
||||||
.with_fg(style.icon_color)
|
.with_fg(style.icon_color)
|
||||||
.with_alpha(alpha)
|
.with_alpha(alpha)
|
||||||
|
@ -22,9 +22,8 @@ pub struct ActionBar {
|
|||||||
/// Optional left button, can be shorter than the right one
|
/// Optional left button, can be shorter than the right one
|
||||||
left_button: Option<Button>,
|
left_button: Option<Button>,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
/// Whether the left button is short
|
/// Whether the left button is short (default: true)
|
||||||
left_short: bool,
|
left_short: bool,
|
||||||
// TODO: review cloning() of those fields
|
|
||||||
// Storage of original button content for paginated component
|
// Storage of original button content for paginated component
|
||||||
left_original: Option<(ButtonContent, ButtonStyleSheet)>,
|
left_original: Option<(ButtonContent, ButtonStyleSheet)>,
|
||||||
right_original: Option<(ButtonContent, ButtonStyleSheet)>,
|
right_original: Option<(ButtonContent, ButtonStyleSheet)>,
|
||||||
@ -55,7 +54,6 @@ impl ActionBar {
|
|||||||
pub const ACTION_BAR_HEIGHT: i16 = 90; // [px]
|
pub const ACTION_BAR_HEIGHT: i16 = 90; // [px]
|
||||||
const SPACER_WIDTH: i16 = 4; // [px]
|
const SPACER_WIDTH: i16 = 4; // [px]
|
||||||
const LEFT_SMALL_BUTTON_WIDTH: i16 = 120; // [px]
|
const LEFT_SMALL_BUTTON_WIDTH: i16 = 120; // [px]
|
||||||
/// TODO: use this offset
|
|
||||||
/// offset for button content to move it towards center
|
/// offset for button content to move it towards center
|
||||||
const BUTTON_CONTENT_OFFSET: Offset = Offset::x(12); // [px]
|
const BUTTON_CONTENT_OFFSET: Offset = Offset::x(12); // [px]
|
||||||
const BUTTON_EXPAND_TOUCH: Insets = Insets::top(Self::ACTION_BAR_HEIGHT);
|
const BUTTON_EXPAND_TOUCH: Insets = Insets::top(Self::ACTION_BAR_HEIGHT);
|
||||||
@ -81,8 +79,13 @@ impl ActionBar {
|
|||||||
Mode::Double {
|
Mode::Double {
|
||||||
pager: Pager::single_page(),
|
pager: Pager::single_page(),
|
||||||
},
|
},
|
||||||
Some(left.with_expanded_touch_area(Self::BUTTON_EXPAND_TOUCH)),
|
Some(
|
||||||
right.with_expanded_touch_area(Self::BUTTON_EXPAND_TOUCH),
|
left.with_expanded_touch_area(Self::BUTTON_EXPAND_TOUCH)
|
||||||
|
.with_content_offset(Self::BUTTON_CONTENT_OFFSET),
|
||||||
|
),
|
||||||
|
right
|
||||||
|
.with_expanded_touch_area(Self::BUTTON_EXPAND_TOUCH)
|
||||||
|
.with_content_offset(Self::BUTTON_CONTENT_OFFSET * -1.0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +102,11 @@ impl ActionBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, new_pager: Pager) {
|
pub fn update(&mut self, new_pager: Pager) {
|
||||||
|
// TODO: review `clone()` of `left_content`/`right_content`
|
||||||
match &mut self.mode {
|
match &mut self.mode {
|
||||||
Mode::Double { pager } => {
|
Mode::Double { pager } => {
|
||||||
|
let old_is_last = pager.is_last();
|
||||||
|
let new_is_last = new_pager.is_last();
|
||||||
*pager = new_pager;
|
*pager = new_pager;
|
||||||
// Update left button - show original content/style only on first page
|
// Update left button - show original content/style only on first page
|
||||||
if let Some(btn) = &mut self.left_button {
|
if let Some(btn) = &mut self.left_button {
|
||||||
@ -123,14 +129,17 @@ impl ActionBar {
|
|||||||
self.right_button.set_content(Self::PAGINATE_RIGHT_CONTENT);
|
self.right_button.set_content(Self::PAGINATE_RIGHT_CONTENT);
|
||||||
self.right_button.set_stylesheet(*Self::PAGINATE_STYLESHEET);
|
self.right_button.set_stylesheet(*Self::PAGINATE_STYLESHEET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're entering or leaving the last page and left_short is true,
|
||||||
|
// we need to update the button placement
|
||||||
|
if self.left_short && (old_is_last != new_is_last) {
|
||||||
|
self.place_buttons(self.area);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: changing the left button to short/equal on paginated last page?
|
|
||||||
// TODO: single button which is disabled for "Continue in the app" screen
|
|
||||||
|
|
||||||
fn new(mode: Mode, left_button: Option<Button>, right_button: Button) -> Self {
|
fn new(mode: Mode, left_button: Option<Button>, right_button: Button) -> Self {
|
||||||
let (left_original, right_original) = match mode {
|
let (left_original, right_original) = match mode {
|
||||||
Mode::Double { .. } => (
|
Mode::Double { .. } => (
|
||||||
@ -159,20 +168,20 @@ impl ActionBar {
|
|||||||
right_button,
|
right_button,
|
||||||
left_button,
|
left_button,
|
||||||
area: Rect::zero(),
|
area: Rect::zero(),
|
||||||
left_short: false,
|
left_short: true,
|
||||||
left_original,
|
left_original,
|
||||||
right_original,
|
right_original,
|
||||||
htc_anim,
|
htc_anim,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle right button at the last page, this includes:
|
/// Handle event of the right button at the last page, this includes:
|
||||||
/// - Single button mode
|
/// - Single button mode
|
||||||
/// - Double button mode at single page component
|
/// - Double button mode at single page component
|
||||||
/// - Double button mode at last page of paginated component
|
/// - Double button mode at last page of paginated component
|
||||||
/// The function takes care about triggering the correct action to
|
/// The function takes care about triggering the correct action to
|
||||||
/// HoldToConfirm or returning the correct message out of the ActionBar.
|
/// HoldToConfirm or returning the correct message out of the ActionBar.
|
||||||
fn right_button_at_last_page(
|
fn event_right_button_at_last_page(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
msg: ButtonMsg,
|
msg: ButtonMsg,
|
||||||
@ -213,20 +222,15 @@ impl ActionBar {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for ActionBar {
|
|
||||||
type Msg = ActionBarMsg;
|
|
||||||
|
|
||||||
fn place(&mut self, bounds: Rect) -> Rect {
|
|
||||||
debug_assert_eq!(bounds.height(), Self::ACTION_BAR_HEIGHT);
|
|
||||||
|
|
||||||
|
fn place_buttons(&mut self, bounds: Rect) {
|
||||||
match &self.mode {
|
match &self.mode {
|
||||||
Mode::Single => {
|
Mode::Single => {
|
||||||
self.right_button.place(bounds);
|
self.right_button.place(bounds);
|
||||||
}
|
}
|
||||||
Mode::Double { .. } => {
|
Mode::Double { pager } => {
|
||||||
let (left, right) = if self.left_short {
|
if self.left_short {
|
||||||
|
let (left, right) = if pager.is_last() {
|
||||||
let (left, rest) = bounds.split_left(Self::LEFT_SMALL_BUTTON_WIDTH);
|
let (left, rest) = bounds.split_left(Self::LEFT_SMALL_BUTTON_WIDTH);
|
||||||
let (_, right) = rest.split_left(Self::SPACER_WIDTH);
|
let (_, right) = rest.split_left(Self::SPACER_WIDTH);
|
||||||
(left, right)
|
(left, right)
|
||||||
@ -234,13 +238,23 @@ impl Component for ActionBar {
|
|||||||
let (left, _spacer, right) = bounds.split_center(Self::SPACER_WIDTH);
|
let (left, _spacer, right) = bounds.split_center(Self::SPACER_WIDTH);
|
||||||
(left, right)
|
(left, right)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(btn) = &mut self.left_button {
|
if let Some(btn) = &mut self.left_button {
|
||||||
btn.place(left);
|
btn.place(left);
|
||||||
}
|
}
|
||||||
self.right_button.place(right);
|
self.right_button.place(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for ActionBar {
|
||||||
|
type Msg = ActionBarMsg;
|
||||||
|
|
||||||
|
fn place(&mut self, bounds: Rect) -> Rect {
|
||||||
|
debug_assert_eq!(bounds.height(), Self::ACTION_BAR_HEIGHT);
|
||||||
|
self.place_buttons(bounds);
|
||||||
self.area = bounds;
|
self.area = bounds;
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
@ -251,7 +265,7 @@ impl Component for ActionBar {
|
|||||||
Mode::Single => {
|
Mode::Single => {
|
||||||
// Only handle confirm button
|
// Only handle confirm button
|
||||||
if let Some(msg) = self.right_button.event(ctx, event) {
|
if let Some(msg) = self.right_button.event(ctx, event) {
|
||||||
return self.right_button_at_last_page(ctx, msg);
|
return self.event_right_button_at_last_page(ctx, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mode::Double { pager } => {
|
Mode::Double { pager } => {
|
||||||
@ -261,7 +275,7 @@ impl Component for ActionBar {
|
|||||||
return Some(ActionBarMsg::Cancelled);
|
return Some(ActionBarMsg::Cancelled);
|
||||||
}
|
}
|
||||||
if let Some(msg) = self.right_button.event(ctx, event) {
|
if let Some(msg) = self.right_button.event(ctx, event) {
|
||||||
return self.right_button_at_last_page(ctx, msg);
|
return self.event_right_button_at_last_page(ctx, msg);
|
||||||
}
|
}
|
||||||
} else if pager.is_first() && !pager.is_single() {
|
} else if pager.is_first() && !pager.is_single() {
|
||||||
// First page of multiple - go back and next page
|
// First page of multiple - go back and next page
|
||||||
@ -277,7 +291,7 @@ impl Component for ActionBar {
|
|||||||
return Some(ActionBarMsg::Prev);
|
return Some(ActionBarMsg::Prev);
|
||||||
}
|
}
|
||||||
if let Some(msg) = self.right_button.event(ctx, event) {
|
if let Some(msg) = self.right_button.event(ctx, event) {
|
||||||
return self.right_button_at_last_page(ctx, msg);
|
return self.event_right_button_at_last_page(ctx, msg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Middle pages - navigations up/down
|
// Middle pages - navigations up/down
|
||||||
|
@ -124,9 +124,9 @@ where
|
|||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
self.header.render(target);
|
self.header.render(target);
|
||||||
self.content.render(target);
|
|
||||||
self.hint.render(target);
|
self.hint.render(target);
|
||||||
self.action_bar.render(target);
|
self.action_bar.render(target);
|
||||||
|
self.content.render(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user