mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-18 11:21:11 +00:00
feat(core/ui): vertical alignment for FormattedText
[no changelog]
This commit is contained in:
parent
f481590bb7
commit
312f6899c7
@ -2,7 +2,7 @@ use crate::{
|
||||
strutil::StringType,
|
||||
ui::{
|
||||
component::{Component, Event, EventCtx, Never, Paginate},
|
||||
geometry::Rect,
|
||||
geometry::{Alignment, Offset, Rect},
|
||||
},
|
||||
};
|
||||
|
||||
@ -14,19 +14,42 @@ use super::{
|
||||
#[derive(Clone)]
|
||||
pub struct FormattedText<T: StringType + Clone> {
|
||||
op_layout: OpTextLayout<T>,
|
||||
vertical: Alignment,
|
||||
char_offset: usize,
|
||||
y_offset: i16,
|
||||
}
|
||||
|
||||
impl<T: StringType + Clone> FormattedText<T> {
|
||||
pub fn new(op_layout: OpTextLayout<T>) -> Self {
|
||||
Self {
|
||||
op_layout,
|
||||
vertical: Alignment::Start,
|
||||
char_offset: 0,
|
||||
y_offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vertically_aligned(mut self, align: Alignment) -> Self {
|
||||
self.vertical = align;
|
||||
self
|
||||
}
|
||||
|
||||
fn layout_content(&mut self, sink: &mut dyn LayoutSink) -> LayoutFit {
|
||||
self.op_layout.layout_content(self.char_offset, sink)
|
||||
self.op_layout
|
||||
.layout_ops(self.char_offset, Offset::y(self.y_offset), sink)
|
||||
}
|
||||
|
||||
fn align_vertically(&mut self, content_height: i16) {
|
||||
let bounds_height = self.op_layout.layout.bounds.height();
|
||||
if content_height >= bounds_height {
|
||||
self.y_offset = 0;
|
||||
return;
|
||||
}
|
||||
self.y_offset = match self.vertical {
|
||||
Alignment::Start => 0,
|
||||
Alignment::Center => (bounds_height - content_height) / 2,
|
||||
Alignment::End => bounds_height - content_height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,8 +96,8 @@ impl<T: StringType + Clone> Paginate for FormattedText<T> {
|
||||
|
||||
// Looping through the content until we arrive at
|
||||
// the wanted page.
|
||||
let mut fit = self.layout_content(&mut TextNoOp);
|
||||
while active_page < to_page {
|
||||
let fit = self.layout_content(&mut TextNoOp);
|
||||
match fit {
|
||||
LayoutFit::Fitting { .. } => {
|
||||
break; // TODO: We should consider if there's more content
|
||||
@ -86,9 +109,11 @@ impl<T: StringType + Clone> Paginate for FormattedText<T> {
|
||||
active_page += 1;
|
||||
char_offset += processed_chars;
|
||||
self.char_offset = char_offset;
|
||||
fit = self.layout_content(&mut TextNoOp);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.align_vertically(fit.height());
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,6 +122,8 @@ impl<T: StringType + Clone> Component for FormattedText<T> {
|
||||
|
||||
fn place(&mut self, bounds: Rect) -> Rect {
|
||||
self.op_layout.place(bounds);
|
||||
let height = self.layout_content(&mut TextNoOp).height();
|
||||
self.align_vertically(height);
|
||||
bounds
|
||||
}
|
||||
|
||||
|
@ -46,14 +46,19 @@ impl<'a, T: StringType + Clone + 'a> OpTextLayout<T> {
|
||||
|
||||
/// Send the layout's content into a sink.
|
||||
pub fn layout_content(&mut self, skip_bytes: usize, sink: &mut dyn LayoutSink) -> LayoutFit {
|
||||
self.layout_ops(skip_bytes, sink)
|
||||
self.layout_ops(skip_bytes, Offset::zero(), sink)
|
||||
}
|
||||
|
||||
/// Perform some operations defined on `Op` for a list of those `Op`s
|
||||
/// - e.g. changing the color, changing the font or rendering the text.
|
||||
fn layout_ops(&mut self, skip_bytes: usize, sink: &mut dyn LayoutSink) -> LayoutFit {
|
||||
pub fn layout_ops(
|
||||
&mut self,
|
||||
skip_bytes: usize,
|
||||
offset: Offset,
|
||||
sink: &mut dyn LayoutSink,
|
||||
) -> LayoutFit {
|
||||
// TODO: make sure it is called when we have the current font (not sooner)
|
||||
let mut cursor = &mut self.layout.initial_cursor();
|
||||
let mut cursor = &mut (self.layout.initial_cursor() + offset);
|
||||
let init_cursor = *cursor;
|
||||
let mut total_processed_chars = 0;
|
||||
|
||||
@ -219,6 +224,10 @@ impl<T: StringType + Clone> OpTextLayout<T> {
|
||||
pub fn text_bold(self, text: T) -> Self {
|
||||
self.font(Font::BOLD).text(text)
|
||||
}
|
||||
|
||||
pub fn text_demibold(self, text: T) -> Self {
|
||||
self.font(Font::DEMIBOLD).text(text)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
Loading…
Reference in New Issue
Block a user