mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-26 07:11:25 +00:00
fix(core/rust/ui): adjust spacing for confirm_action
[no changelog]
This commit is contained in:
parent
5378492ea9
commit
ab0eef5de0
@ -34,7 +34,9 @@ where
|
||||
break; // TODO: We should consider if there's more content
|
||||
// to render.
|
||||
}
|
||||
LayoutFit::OutOfBounds { processed_chars } => {
|
||||
LayoutFit::OutOfBounds {
|
||||
processed_chars, ..
|
||||
} => {
|
||||
page_count += 1;
|
||||
char_offset += processed_chars;
|
||||
self.set_char_offset(char_offset);
|
||||
@ -62,7 +64,9 @@ where
|
||||
break; // TODO: We should consider if there's more content
|
||||
// to render.
|
||||
}
|
||||
LayoutFit::OutOfBounds { processed_chars } => {
|
||||
LayoutFit::OutOfBounds {
|
||||
processed_chars, ..
|
||||
} => {
|
||||
active_page += 1;
|
||||
char_offset += processed_chars;
|
||||
self.set_char_offset(char_offset);
|
||||
|
@ -29,6 +29,13 @@ pub struct TextLayout {
|
||||
/// Bounding box restricting the layout dimensions.
|
||||
pub bounds: Rect,
|
||||
|
||||
/// Additional space before beginning of text, can be negative to shift text
|
||||
/// upwards.
|
||||
pub padding_top: i32,
|
||||
/// Additional space between end of text and bottom of bounding box, can be
|
||||
/// negative.
|
||||
pub padding_bottom: i32,
|
||||
|
||||
/// Background color.
|
||||
pub background_color: Color,
|
||||
/// Text color. Can be overridden by `Op::Color`.
|
||||
@ -78,6 +85,8 @@ impl TextLayout {
|
||||
pub fn new<T: DefaultTextTheme>(bounds: Rect) -> Self {
|
||||
Self {
|
||||
bounds,
|
||||
padding_top: 0,
|
||||
padding_bottom: 0,
|
||||
background_color: T::BACKGROUND_COLOR,
|
||||
text_color: T::TEXT_COLOR,
|
||||
text_font: T::TEXT_FONT,
|
||||
@ -95,10 +104,7 @@ impl TextLayout {
|
||||
}
|
||||
|
||||
pub fn initial_cursor(&self) -> Point {
|
||||
Point::new(
|
||||
self.bounds.top_left().x,
|
||||
self.bounds.top_left().y + self.text_font.line_height(),
|
||||
)
|
||||
self.bounds.top_left() + Offset::y(self.text_font.text_height() + self.padding_top)
|
||||
}
|
||||
|
||||
pub fn layout_ops<'o>(
|
||||
@ -107,7 +113,7 @@ impl TextLayout {
|
||||
cursor: &mut Point,
|
||||
sink: &mut dyn LayoutSink,
|
||||
) -> LayoutFit {
|
||||
let init_cursor: Point = *cursor;
|
||||
let init_cursor = *cursor;
|
||||
let mut total_processed_chars = 0;
|
||||
|
||||
for op in ops {
|
||||
@ -124,11 +130,14 @@ impl TextLayout {
|
||||
} => {
|
||||
total_processed_chars += processed_chars;
|
||||
}
|
||||
LayoutFit::OutOfBounds { processed_chars } => {
|
||||
LayoutFit::OutOfBounds {
|
||||
processed_chars, ..
|
||||
} => {
|
||||
total_processed_chars += processed_chars;
|
||||
|
||||
return LayoutFit::OutOfBounds {
|
||||
processed_chars: total_processed_chars,
|
||||
height: self.layout_height(init_cursor, *cursor),
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -137,10 +146,7 @@ impl TextLayout {
|
||||
|
||||
LayoutFit::Fitting {
|
||||
processed_chars: total_processed_chars,
|
||||
size: Offset::new(
|
||||
self.bounds.width(),
|
||||
cursor.y - init_cursor.y + self.text_font.line_height(),
|
||||
),
|
||||
height: self.layout_height(init_cursor, *cursor),
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,13 +156,17 @@ impl TextLayout {
|
||||
cursor: &mut Point,
|
||||
sink: &mut dyn LayoutSink,
|
||||
) -> LayoutFit {
|
||||
let init_cursor: Point = *cursor;
|
||||
let init_cursor = *cursor;
|
||||
let bottom = (self.bounds.y1 - self.padding_bottom).max(self.bounds.y0);
|
||||
let mut remaining_text = text;
|
||||
|
||||
// Check if bounding box is high enough for at least one line.
|
||||
if cursor.y > self.bounds.y1 {
|
||||
if cursor.y > bottom {
|
||||
sink.out_of_bounds();
|
||||
return LayoutFit::OutOfBounds { processed_chars: 0 };
|
||||
return LayoutFit::OutOfBounds {
|
||||
processed_chars: 0,
|
||||
height: 0,
|
||||
};
|
||||
}
|
||||
|
||||
while !remaining_text.is_empty() {
|
||||
@ -185,7 +195,7 @@ impl TextLayout {
|
||||
sink.hyphen(*cursor, self);
|
||||
}
|
||||
// Check the amount of vertical space we have left.
|
||||
if cursor.y + span.advance.y > self.bounds.y1 {
|
||||
if cursor.y + span.advance.y > bottom {
|
||||
if !remaining_text.is_empty() {
|
||||
// Append ellipsis to indicate more content is available, but only if we
|
||||
// haven't already appended a hyphen.
|
||||
@ -205,6 +215,7 @@ impl TextLayout {
|
||||
|
||||
return LayoutFit::OutOfBounds {
|
||||
processed_chars: text.len() - remaining_text.len(),
|
||||
height: self.layout_height(init_cursor, *cursor),
|
||||
};
|
||||
} else {
|
||||
// Advance the cursor to the beginning of the next line.
|
||||
@ -220,38 +231,42 @@ impl TextLayout {
|
||||
|
||||
LayoutFit::Fitting {
|
||||
processed_chars: text.len(),
|
||||
size: Offset::new(
|
||||
self.bounds.width(),
|
||||
cursor.y - init_cursor.y + self.text_font.line_height(),
|
||||
),
|
||||
height: self.layout_height(init_cursor, *cursor),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn measure_ops_height(self, ops: &mut dyn Iterator<Item = Op>) -> i32 {
|
||||
match self.layout_ops(ops, &mut self.initial_cursor(), &mut TextNoOp) {
|
||||
LayoutFit::Fitting { size, .. } => size.y,
|
||||
LayoutFit::OutOfBounds { processed_chars: 0 } => 0,
|
||||
_ => self.bounds.height(),
|
||||
}
|
||||
self.layout_ops(ops, &mut self.initial_cursor(), &mut TextNoOp)
|
||||
.height()
|
||||
}
|
||||
|
||||
pub fn measure_text_height(self, text: &[u8]) -> i32 {
|
||||
match self.layout_text(text, &mut self.initial_cursor(), &mut TextNoOp) {
|
||||
LayoutFit::Fitting { size, .. } => size.y,
|
||||
LayoutFit::OutOfBounds { processed_chars: 0 } => 0,
|
||||
_ => self.bounds.height(),
|
||||
}
|
||||
self.layout_text(text, &mut self.initial_cursor(), &mut TextNoOp)
|
||||
.height()
|
||||
}
|
||||
|
||||
fn layout_height(&self, init_cursor: Point, end_cursor: Point) -> i32 {
|
||||
self.padding_top
|
||||
+ self.text_font.text_height()
|
||||
+ (end_cursor.y - init_cursor.y)
|
||||
+ self.padding_bottom
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LayoutFit {
|
||||
/// Entire content fits. Bounding box is returned in `size`.
|
||||
Fitting {
|
||||
processed_chars: usize,
|
||||
size: Offset,
|
||||
},
|
||||
/// Entire content fits. Vertical size is returned in `height`.
|
||||
Fitting { processed_chars: usize, height: i32 },
|
||||
/// Content fits partially or not at all.
|
||||
OutOfBounds { processed_chars: usize },
|
||||
OutOfBounds { processed_chars: usize, height: i32 },
|
||||
}
|
||||
|
||||
impl LayoutFit {
|
||||
pub fn height(&self) -> i32 {
|
||||
match self {
|
||||
LayoutFit::Fitting { height, .. } => *height,
|
||||
LayoutFit::OutOfBounds { height, .. } => *height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Visitor for text segment operations.
|
||||
|
@ -9,7 +9,15 @@ use crate::ui::{
|
||||
use super::layout::{DefaultTextTheme, LayoutFit, TextLayout, TextNoOp, TextRenderer};
|
||||
|
||||
pub const MAX_PARAGRAPHS: usize = 6;
|
||||
pub const DEFAULT_SPACING: i32 = 3;
|
||||
/// Maximum space between paragraphs. Actual result may be smaller (even 0) if
|
||||
/// it would make paragraphs overflow the bounding box.
|
||||
pub const DEFAULT_SPACING: i32 = 0;
|
||||
/// Offset of paragraph text from the top of the paragraph bounding box. Tweak
|
||||
/// these values to get nice alignment of baselines relative to the surrounding
|
||||
/// components.
|
||||
pub const PARAGRAPH_TOP_SPACE: i32 = -1;
|
||||
/// Offset of paragraph bounding box bottom relative to bottom of its text.
|
||||
pub const PARAGRAPH_BOTTOM_SPACE: i32 = 5;
|
||||
|
||||
pub struct Paragraphs<T> {
|
||||
area: Rect,
|
||||
@ -53,6 +61,8 @@ where
|
||||
content,
|
||||
TextLayout {
|
||||
text_font,
|
||||
padding_top: PARAGRAPH_TOP_SPACE,
|
||||
padding_bottom: PARAGRAPH_BOTTOM_SPACE,
|
||||
..TextLayout::new::<D>(self.area)
|
||||
},
|
||||
);
|
||||
@ -228,9 +238,9 @@ where
|
||||
&mut TextNoOp,
|
||||
);
|
||||
match fit {
|
||||
LayoutFit::Fitting { size, .. } => {
|
||||
LayoutFit::Fitting { height, .. } => {
|
||||
// Text fits, update remaining area.
|
||||
remaining_area = remaining_area.inset(Insets::top(size.y));
|
||||
remaining_area = remaining_area.inset(Insets::top(height));
|
||||
|
||||
// Continue with start of next paragraph.
|
||||
current.par += 1;
|
||||
@ -238,7 +248,9 @@ where
|
||||
progress = true;
|
||||
break;
|
||||
}
|
||||
LayoutFit::OutOfBounds { processed_chars } => {
|
||||
LayoutFit::OutOfBounds {
|
||||
processed_chars, ..
|
||||
} => {
|
||||
// Text does not fit, assume whatever fits takes the entire remaining area.
|
||||
current.chr += processed_chars;
|
||||
if processed_chars == 0 && !progress {
|
||||
|
@ -2,7 +2,7 @@ use super::theme;
|
||||
use crate::ui::{
|
||||
component::{Child, Component, ComponentExt, Event, EventCtx},
|
||||
display,
|
||||
geometry::Rect,
|
||||
geometry::{Insets, Rect},
|
||||
};
|
||||
|
||||
pub struct Frame<T, U> {
|
||||
@ -26,14 +26,14 @@ where
|
||||
}
|
||||
|
||||
fn areas(area: Rect) -> (Rect, Rect) {
|
||||
const HEADER_SPACE: i32 = 14;
|
||||
let header_height = theme::FONT_BOLD.line_height() - theme::CONTENT_BORDER;
|
||||
// Same as PageLayout::BUTTON_SPACE.
|
||||
const TITLE_SPACE: i32 = 6;
|
||||
|
||||
let (header_area, content_area) = area.split_top(header_height);
|
||||
let (_space, header_area) = header_area.split_left(theme::CONTENT_BORDER);
|
||||
let (_space, content_area) = content_area.split_top(HEADER_SPACE);
|
||||
let (title_area, content_area) = area.split_top(theme::FONT_BOLD.text_height());
|
||||
let title_area = title_area.inset(Insets::left(theme::CONTENT_BORDER));
|
||||
let content_area = content_area.inset(Insets::top(TITLE_SPACE));
|
||||
|
||||
(header_area, content_area)
|
||||
(title_area, content_area)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub const GREY_LIGHT: Color = Color::rgb(168, 168, 168); // greyish
|
||||
pub const GREY_DARK: Color = Color::rgb(51, 51, 51); // black
|
||||
|
||||
// Commonly used corner radius (i.e. for buttons).
|
||||
pub const RADIUS: u8 = 4;
|
||||
pub const RADIUS: u8 = 2;
|
||||
|
||||
// Size of icons in the UI (i.e. inside buttons).
|
||||
pub const ICON_SIZE: i32 = 16;
|
||||
@ -59,7 +59,7 @@ pub fn button_default() -> ButtonStyleSheet {
|
||||
background_color: BG,
|
||||
border_color: BG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 1,
|
||||
border_width: 0,
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
@ -68,7 +68,7 @@ pub fn button_default() -> ButtonStyleSheet {
|
||||
background_color: BG,
|
||||
border_color: FG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 1,
|
||||
border_width: 0,
|
||||
},
|
||||
disabled: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
@ -77,7 +77,7 @@ pub fn button_default() -> ButtonStyleSheet {
|
||||
background_color: BG,
|
||||
border_color: BG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 1,
|
||||
border_width: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,7 @@ pub fn button_confirm() -> ButtonStyleSheet {
|
||||
background_color: BG,
|
||||
border_color: BG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 1,
|
||||
border_width: 0,
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
@ -100,7 +100,7 @@ pub fn button_confirm() -> ButtonStyleSheet {
|
||||
background_color: BG,
|
||||
border_color: FG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 1,
|
||||
border_width: 0,
|
||||
},
|
||||
disabled: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
@ -109,7 +109,7 @@ pub fn button_confirm() -> ButtonStyleSheet {
|
||||
background_color: BG,
|
||||
border_color: BG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 1,
|
||||
border_width: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user