refactor(core/rust): geometry/display API improvements

[no changelog]
mmilata/tt-pin-keyboard
Martin Milata 2 years ago
parent f2b8822d76
commit b5da6dc911

@ -23,7 +23,7 @@ where
T: Deref<Target = [u8]>,
{
pub fn new(origin: Point, align: Alignment, text: T, style: LabelStyle) -> Self {
let width = display::text_width(&text, style.font);
let width = style.font.text_width(&text);
let height = style.font.line_height();
let area = match align {
// `origin` is the top-left point.

@ -26,7 +26,7 @@ impl Pad {
if self.clear {
self.clear = false;
display::rect(self.area, self.color);
display::rect_fill(self.area, self.color);
}
}
}

@ -397,7 +397,7 @@ impl Span {
// break.
let mut line = Self {
length: 0,
advance: Offset::new(0, text_font.line_height()),
advance: Offset::y(text_font.line_height()),
insert_hyphen_before_line_break: false,
skip_next_chars: 0,
};
@ -447,7 +447,7 @@ impl Span {
// The whole text is fitting.
Self {
length: text.len(),
advance: Offset::new(span_width, 0),
advance: Offset::x(span_width),
insert_hyphen_before_line_break: false,
skip_next_chars: 0,
}

@ -189,7 +189,7 @@ where
match fit {
LayoutFit::Fitting { size, .. } => {
// Text fits, update the bounding box.
let (used, free) = area.hsplit(size.y);
let (used, free) = area.split_top(size.y);
paragraph.set_area(used);
// Continue with next paragraph in remaining space.
area = free;

@ -49,11 +49,19 @@ pub fn fade_backlight(target: i32) {
}
}
pub fn rect(r: Rect, fg_color: Color) {
pub fn rect_fill(r: Rect, fg_color: Color) {
display::bar(r.x0, r.y0, r.width(), r.height(), fg_color.into());
}
pub fn rounded_rect(r: Rect, fg_color: Color, bg_color: Color, radius: u8) {
pub fn rect_stroke(r: Rect, fg_color: Color) {
display::bar(r.x0, r.y0, r.width(), 1, fg_color.into());
display::bar(r.x0, r.y0 + r.height() - 1, r.width(), 1, fg_color.into());
display::bar(r.x0, r.y0, 1, r.height(), fg_color.into());
display::bar(r.x0 + r.width() - 1, r.y0, 1, r.height(), fg_color.into());
}
pub fn rect_fill_rounded(r: Rect, fg_color: Color, bg_color: Color, radius: u8) {
assert!([2, 4, 8, 16].iter().any(|allowed| radius == *allowed));
display::bar_radius(
r.x0,
r.y0,
@ -65,6 +73,22 @@ pub fn rounded_rect(r: Rect, fg_color: Color, bg_color: Color, radius: u8) {
);
}
/// NOTE: Cannot start at odd x-coordinate. In this case icon is shifted 1px
/// left.
pub fn icon_top_left(top_left: Point, data: &[u8], fg_color: Color, bg_color: Color) {
let toif_info = display::toif_info(data).unwrap();
assert!(toif_info.grayscale);
display::icon(
top_left.x,
top_left.y,
toif_info.width.into(),
toif_info.height.into(),
&data[12..], // Skip TOIF header.
fg_color.into(),
bg_color.into(),
);
}
pub fn icon(center: Point, data: &[u8], fg_color: Color, bg_color: Color) {
let toif_info = display::toif_info(data).unwrap();
assert!(toif_info.grayscale);
@ -85,13 +109,13 @@ pub fn icon(center: Point, data: &[u8], fg_color: Color, bg_color: Color) {
}
// Used on T1 only.
pub fn rounded_rect1(r: Rect, fg_color: Color, bg_color: Color) {
pub fn rect_fill_rounded1(r: Rect, fg_color: Color, bg_color: Color) {
display::bar(r.x0, r.y0, r.width(), r.height(), fg_color.into());
let corners = [
r.top_left(),
r.top_right() + Offset::new(-1, 0),
r.bottom_right() + Offset::new(-1, -1),
r.bottom_left() + Offset::new(0, -1),
r.top_right() - Offset::x(1),
r.bottom_right() - Offset::uniform(1),
r.bottom_left() - Offset::y(1),
];
for p in corners.iter() {
display::bar(p.x, p.y, 1, 1, bg_color.into());
@ -156,7 +180,7 @@ pub fn text(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color:
}
pub fn text_center(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color: Color) {
let w = text_width(text, font);
let w = font.text_width(text);
display::text(
baseline.x - w / 2,
baseline.y,
@ -167,10 +191,6 @@ pub fn text_center(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg
);
}
pub fn text_width(text: &[u8], font: Font) -> i32 {
display::text_width(text, font.0)
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Font(i32);
@ -180,7 +200,7 @@ impl Font {
}
pub fn text_width(self, text: &[u8]) -> i32 {
text_width(text, self)
display::text_width(text, self.0)
}
pub fn text_height(self) -> i32 {

@ -22,6 +22,14 @@ impl Offset {
Self::new(0, 0)
}
pub const fn x(x: i32) -> Self {
Self::new(x, 0)
}
pub const fn y(y: i32) -> Self {
Self::new(0, y)
}
pub fn on_axis(axis: Axis, a: i32) -> Self {
match axis {
Axis::Horizontal => Self::new(a, 0),
@ -29,6 +37,13 @@ impl Offset {
}
}
pub fn axis(&self, axis: Axis) -> i32 {
match axis {
Axis::Horizontal => self.x,
Axis::Vertical => self.y,
}
}
pub fn abs(self) -> Self {
Self::new(self.x.abs(), self.y.abs())
}
@ -165,16 +180,20 @@ impl Rect {
self.top_left().center(self.bottom_right())
}
pub fn bottom_center(&self) -> Point {
self.bottom_left().center(self.bottom_right())
}
pub fn contains(&self, point: Point) -> bool {
point.x >= self.x0 && point.x < self.x1 && point.y >= self.y0 && point.y < self.y1
}
pub fn inset(&self, uniform: i32) -> Self {
pub fn inset(&self, insets: Insets) -> Self {
Self {
x0: self.x0 + uniform,
y0: self.y0 + uniform,
x1: self.x1 - uniform,
y1: self.y1 - uniform,
x0: self.x0 + insets.left,
y0: self.y0 + insets.top,
x1: self.x1 - insets.right,
y1: self.y1 - insets.bottom,
}
}
@ -196,53 +215,80 @@ impl Rect {
}
}
pub fn hsplit(self, height: i32) -> (Self, Self) {
let height = if height.is_negative() {
self.height() + height
} else {
height
};
pub fn split_top(self, height: i32) -> (Self, Self) {
let height = height.clamp(0, self.height());
let top = Self {
x0: self.x0,
y0: self.y0,
x1: self.x1,
y1: self.y0 + height,
..self
};
let bottom = Self {
x0: self.x0,
y0: self.y0 + height,
x1: self.x1,
y1: self.y1,
..self
};
(top, bottom)
}
pub fn vsplit(self, width: i32) -> (Self, Self) {
let width = if width.is_negative() {
self.width() + width
} else {
width
};
pub fn split_bottom(self, height: i32) -> (Self, Self) {
self.split_top(self.height() - height)
}
pub fn split_left(self, width: i32) -> (Self, Self) {
let width = width.clamp(0, self.width());
let left = Self {
x0: self.x0,
y0: self.y0,
x1: self.x0 + width,
y1: self.y1,
..self
};
let right = Self {
x0: self.x0 + width,
y0: self.y0,
x1: self.x1,
y1: self.y1,
..self
};
(left, right)
}
pub fn split_right(self, width: i32) -> (Self, Self) {
self.split_left(self.width() - width)
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Insets {
pub top: i32,
pub right: i32,
pub bottom: i32,
pub left: i32,
}
impl Insets {
pub const fn new(top: i32, right: i32, bottom: i32, left: i32) -> Self {
Self {
top,
right,
bottom,
left,
}
}
pub const fn uniform(d: i32) -> Self {
Self::new(d, d, d, d)
}
pub const fn top(d: i32) -> Self {
Self::new(d, 0, 0, 0)
}
pub const fn right(d: i32) -> Self {
Self::new(0, d, 0, 0)
}
pub const fn bottom(d: i32) -> Self {
Self::new(0, 0, d, 0)
}
pub const fn left(d: i32) -> Self {
Self::new(0, 0, 0, d)
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
@ -295,17 +341,50 @@ impl Grid {
}
}
pub fn with_spacing(mut self, spacing: i32) -> Self {
self.spacing = spacing;
self
}
pub fn row_col(&self, row: usize, col: usize) -> Rect {
let cell_width = self.area.width() / self.cols as i32;
let cell_height = self.area.height() / self.rows as i32;
let x = col as i32 * cell_width;
let y = row as i32 * cell_height;
Rect {
x0: self.area.x0 + x,
y0: self.area.y0 + y,
x1: self.area.x0 + x + (cell_width - self.spacing),
y1: self.area.y0 + y + (cell_height - self.spacing),
let ncols = self.cols as i32;
let nrows = self.rows as i32;
let col = (col as i32).min(ncols - 1);
let row = (row as i32).min(nrows - 1);
// Total number of horizontal pixels used for spacing.
let spacing_width = self.spacing * (ncols - 1);
let spacing_height = self.spacing * (nrows - 1);
// Divide what is left by number of cells to obtain width of each cell.
let cell_width = (self.area.width() - spacing_width) / ncols;
let cell_height = (self.area.height() - spacing_height) / nrows;
// Not every area can be fully covered by equal-sized cells and spaces, there
// might be serveral pixels left unused. We'll distribute them by 1px to
// the leftmost cells.
let leftover_width = (self.area.width() - spacing_width) % ncols;
let leftover_height = (self.area.height() - spacing_height) % nrows;
let mut top_left = self.area.top_left()
+ Offset::new(
col * (cell_width + self.spacing),
row * (cell_height + self.spacing),
);
// Some previous cells were 1px wider.
top_left.x += leftover_width.min(col);
top_left.y += leftover_height.min(row);
let mut size = Offset::new(cell_width, cell_height);
// This cell might be 1px wider.
if col < leftover_width {
size.x += 1
}
if row < leftover_height {
size.y += 1
}
Rect::from_top_left_and_size(top_left, size)
}
pub fn cell(&self, index: usize) -> Rect {
@ -357,45 +436,67 @@ impl LinearLayout {
self
}
/// Arranges all `items` by parameters configured in `self` into `area`.
/// Does not change the size of the items (only the position), but it needs
/// to iterate (and ask for the size) twice.
pub fn arrange(&self, area: Rect, items: &mut [impl Dimensions]) {
let item_sum: i32 = items
.iter_mut()
.map(|i| {
let size = i.get_size();
self.axis.main(size.x, size.y)
})
.sum();
let spacing_count = items.len().saturating_sub(1);
fn compute_spacing(&self, area: Rect, count: usize, size_sum: i32) -> (i32, i32) {
let spacing_count = count.saturating_sub(1);
let spacing_sum = spacing_count as i32 * self.spacing;
let naive_size = item_sum + spacing_sum;
let available_space = match self.axis {
Axis::Horizontal => area.width(),
Axis::Vertical => area.height(),
};
let naive_size = size_sum + spacing_sum;
let available_space = area.size().axis(self.axis);
// scale down spacing to fit everything into area
let (total_size, spacing) = if naive_size > available_space {
let scaled_space = (available_space - item_sum) / spacing_count as i32;
let scaled_space = (available_space - size_sum) / spacing_count as i32;
// forbid negative spacing
(available_space, scaled_space.max(0))
} else {
(naive_size, self.spacing)
};
let mut cursor = match self.align {
let init_cursor = match self.align {
Alignment::Start => 0,
Alignment::Center => available_space / 2 - total_size / 2,
Alignment::End => available_space - total_size,
};
(init_cursor, spacing)
}
/// Arranges all `items` by parameters configured in `self` into `area`.
/// Does not change the size of the items (only the position), but it needs
/// to iterate (and ask for the size) twice.
pub fn arrange(&self, area: Rect, items: &mut [impl Dimensions]) {
let item_sum: i32 = items.iter_mut().map(|i| i.get_size().axis(self.axis)).sum();
let (mut cursor, spacing) = self.compute_spacing(area, items.len(), item_sum);
for item in items {
let top_left = area.top_left() + Offset::on_axis(self.axis, cursor);
let size = item.get_size();
item.set_area(Rect::from_top_left_and_size(top_left, size));
cursor += self.axis.main(size.x, size.y);
cursor += size.axis(self.axis);
cursor += spacing;
}
}
/// Arranges number of items of the same size into `area`. The `sink`
/// closure is called `count` times with top left point of each item as
/// argument. Items are centered along the cross axis.
pub fn arrange_uniform(
&self,
area: Rect,
count: usize,
size: Offset,
sink: &mut dyn FnMut(Point),
) {
let item_size = size.axis(self.axis);
let (mut cursor, spacing) = self.compute_spacing(area, count, (count as i32) * item_size);
let cross_coord =
area.size().axis(self.axis.cross()) / 2 - size.axis(self.axis.cross()) / 2;
for _ in 0..count {
let top_left = area.top_left()
+ Offset::on_axis(self.axis, cursor)
+ Offset::on_axis(self.axis.cross(), cross_coord);
sink(top_left);
cursor += item_size;
cursor += spacing;
}
}

@ -94,13 +94,13 @@ impl<T: AsRef<[u8]>> Button<T> {
) -> (Rect, Point) {
let border_width = if styles.normal.border_horiz { 2 } else { 0 };
let content_width = match content {
ButtonContent::Text(text) => display::text_width(text.as_ref(), styles.normal.font) - 1,
ButtonContent::Text(text) => styles.normal.font.text_width(text.as_ref()) - 1,
ButtonContent::Icon(_icon) => todo!(),
};
let button_width = content_width + 2 * border_width;
let area = match pos {
ButtonPos::Left => area.vsplit(button_width).0,
ButtonPos::Right => area.vsplit(-button_width).1,
ButtonPos::Left => area.split_left(button_width).0,
ButtonPos::Right => area.split_right(button_width).1,
};
let start_of_baseline = area.bottom_left() + Offset::new(border_width, -2);
@ -135,9 +135,9 @@ impl<T: AsRef<[u8]>> Component for Button<T> {
ButtonContent::Text(text) => {
let background_color = style.text_color.neg();
if style.border_horiz {
display::rounded_rect1(self.area, background_color, theme::BG);
display::rect_fill_rounded1(self.area, background_color, theme::BG);
} else {
display::rect(self.area, background_color)
display::rect_fill(self.area, background_color)
}
display::text(

@ -39,7 +39,7 @@ impl<T: Component, U: AsRef<[u8]>> Dialog<T, U> {
fn areas(area: Rect) -> (Rect, Rect) {
let button_height = theme::FONT_BOLD.line_height() + 2;
let (content_area, button_area) = area.hsplit(-button_height);
let (content_area, button_area) = area.split_bottom(button_height);
(content_area, button_area)
}
}

@ -25,8 +25,8 @@ impl<T: Component, U: AsRef<[u8]>> Frame<T, U> {
const HEADER_SPACE: i32 = 4;
let header_height = theme::FONT_BOLD.line_height();
let (header_area, content_area) = area.hsplit(header_height);
let (_space, content_area) = content_area.hsplit(HEADER_SPACE);
let (header_area, content_area) = area.split_top(header_height);
let (_space, content_area) = content_area.split_top(HEADER_SPACE);
(header_area, content_area)
}
@ -41,7 +41,7 @@ impl<T: Component, U: AsRef<[u8]>> Component for Frame<T, U> {
fn paint(&mut self) {
display::text(
self.area.bottom_left() + Offset::new(0, -2),
self.area.bottom_left() - Offset::y(2),
self.title.as_ref(),
theme::FONT_BOLD,
theme::FG,

@ -1,7 +1,7 @@
use crate::ui::{
component::{Component, ComponentExt, Event, EventCtx, Never, Pad, PageMsg, Paginate},
display::{self, Color},
geometry::{Offset, Point, Rect},
geometry::{Insets, Offset, Point, Rect},
};
use super::{theme, Button, ButtonMsg, ButtonPos};
@ -63,9 +63,9 @@ where
fn areas(area: Rect) -> (Rect, Rect, Rect) {
let button_height = theme::FONT_BOLD.line_height() + 2;
let (content_area, button_area) = area.hsplit(-button_height);
let (content_area, scrollbar_area) = content_area.vsplit(-ScrollBar::WIDTH);
let (content_area, _) = content_area.hsplit(-1);
let (content_area, button_area) = area.split_bottom(button_height);
let (content_area, scrollbar_area) = content_area.split_right(ScrollBar::WIDTH);
let (content_area, _) = content_area.split_bottom(1);
(content_area, scrollbar_area, button_area)
}
@ -182,8 +182,8 @@ impl ScrollBar {
fn paint_dot(&self, active: bool, top_left: Point) {
let sides = [
Rect::from_top_left_and_size(top_left + Offset::new(1, 0), Offset::new(2, 1)),
Rect::from_top_left_and_size(top_left + Offset::new(0, 1), Offset::new(1, 2)),
Rect::from_top_left_and_size(top_left + Offset::x(1), Offset::new(2, 1)),
Rect::from_top_left_and_size(top_left + Offset::y(1), Offset::new(1, 2)),
Rect::from_top_left_and_size(
top_left + Offset::new(1, Self::DOT_SIZE.y - 1),
Offset::new(2, 1),
@ -194,11 +194,11 @@ impl ScrollBar {
),
];
for side in sides {
display::rect(side, theme::FG)
display::rect_fill(side, theme::FG)
}
if active {
display::rect(
Rect::from_top_left_and_size(top_left, Self::DOT_SIZE).inset(1),
display::rect_fill(
Rect::from_top_left_and_size(top_left, Self::DOT_SIZE).inset(Insets::uniform(1)),
theme::FG,
)
}

@ -2,7 +2,7 @@ use super::{event::TouchEvent, theme};
use crate::ui::{
component::{Component, Event, EventCtx, Map},
display::{self, Color, Font},
geometry::{Grid, Offset, Rect},
geometry::{Grid, Insets, Offset, Rect},
};
pub enum ButtonMsg {
@ -160,14 +160,14 @@ where
if style.border_width > 0 {
// Paint the border and a smaller background on top of it.
display::rounded_rect(
display::rect_fill_rounded(
self.area,
style.border_color,
style.background_color,
style.border_radius,
);
display::rounded_rect(
self.area.inset(style.border_width),
display::rect_fill_rounded(
self.area.inset(Insets::uniform(style.border_width)),
style.button_color,
style.border_color,
style.border_radius,
@ -175,7 +175,7 @@ where
} else {
// We do not need to draw an explicit border in this case, just a
// bigger background.
display::rounded_rect(
display::rect_fill_rounded(
self.area,
style.button_color,
style.background_color,

@ -29,9 +29,9 @@ where
const HEADER_SPACE: i32 = 14;
let header_height = theme::FONT_BOLD.line_height() - theme::CONTENT_BORDER;
let (header_area, content_area) = area.hsplit(header_height);
let (_space, header_area) = header_area.vsplit(theme::CONTENT_BORDER);
let (_space, content_area) = content_area.hsplit(HEADER_SPACE);
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);
(header_area, content_area)
}

@ -3,7 +3,7 @@ use crate::ui::{
base::ComponentExt, paginated::PageMsg, Component, Event, EventCtx, Never, Pad, Paginate,
},
display::{self, Color},
geometry::{Dimensions, Offset, Point, Rect},
geometry::{Dimensions, LinearLayout, Offset, Rect},
};
use super::{theme, Button, Swipe, SwipeDirection};
@ -82,7 +82,7 @@ where
fn paint_hint(&mut self) {
display::text_center(
Point::new(self.pad.area.center().x, self.pad.area.bottom_right().y - 3),
self.pad.area.bottom_center() - Offset::y(3),
b"SWIPE TO CONTINUE",
theme::FONT_BOLD, // FIXME: Figma has this as 14px but bold is 16px
theme::GREY_LIGHT,
@ -180,8 +180,11 @@ pub struct ScrollBar {
}
impl ScrollBar {
const DOT_INTERVAL: i32 = 12;
const ARROW_SPACE: i32 = 23;
const DOT_SIZE: i32 = 6;
/// Edge to edge.
const DOT_INTERVAL: i32 = 6;
/// Edge of last dot to center of arrow icon.
const ARROW_SPACE: i32 = 26;
const ICON_ACTIVE: &'static [u8] = include_res!("model_tt/res/scroll-active.toif");
const ICON_INACTIVE: &'static [u8] = include_res!("model_tt/res/scroll-inactive.toif");
@ -229,40 +232,42 @@ impl Component for ScrollBar {
}
fn paint(&mut self) {
let count = self.page_count as i32;
let interval = {
let available_height = self.area.height();
let naive_height = count * Self::DOT_INTERVAL;
if naive_height > available_height {
available_height / count
let layout = LinearLayout::vertical()
.align_at_center()
.with_spacing(Self::DOT_INTERVAL);
let mut i = 0;
let mut top = None;
let mut display_icon = |top_left| {
let icon = if i == self.active_page {
Self::ICON_ACTIVE
} else {
Self::DOT_INTERVAL
}
Self::ICON_INACTIVE
};
display::icon_top_left(top_left, icon, theme::FG, theme::BG);
i += 1;
top.get_or_insert(top_left.x);
};
let mut dot = Point::new(
self.area.center().x,
self.area.center().y - (count / 2) * interval,
layout.arrange_uniform(
self.area,
self.page_count,
Offset::new(Self::DOT_SIZE, Self::DOT_SIZE),
&mut display_icon,
);
let arrow_distance = self.area.center().x - top.unwrap_or(0) + Self::ARROW_SPACE;
if self.has_previous_page() {
display::icon(
dot - Offset::new(0, Self::ARROW_SPACE),
self.area.center() - Offset::y(arrow_distance),
Self::ICON_UP,
theme::FG,
theme::BG,
);
}
for i in 0..self.page_count {
let icon = if i == self.active_page {
Self::ICON_ACTIVE
} else {
Self::ICON_INACTIVE
};
display::icon(dot, icon, theme::FG, theme::BG);
dot.y += interval;
}
if self.has_next_page() {
display::icon(
dot + Offset::new(0, Self::ARROW_SPACE - interval),
self.area.center() + Offset::y(arrow_distance),
Self::ICON_DOWN,
theme::FG,
theme::BG,
@ -284,13 +289,14 @@ impl PageLayout {
const SCROLLBAR_SPACE: i32 = 10;
pub fn new(area: Rect) -> Self {
let (content, buttons) = area.hsplit(-Button::HEIGHT);
let (content, _space) = content.hsplit(-Self::BUTTON_SPACE);
let (buttons, _space) = buttons.vsplit(-theme::CONTENT_BORDER);
let (_space, content) = content.vsplit(theme::CONTENT_BORDER);
let (content_single_page, _space) = content.vsplit(-theme::CONTENT_BORDER);
let (content, scrollbar) = content.vsplit(-(Self::SCROLLBAR_SPACE + Self::SCROLLBAR_WIDTH));
let (_space, scrollbar) = scrollbar.vsplit(Self::SCROLLBAR_SPACE);
let (content, buttons) = area.split_bottom(Button::<&str>::HEIGHT);
let (content, _space) = content.split_bottom(Self::BUTTON_SPACE);
let (buttons, _space) = buttons.split_right(theme::CONTENT_BORDER);
let (_space, content) = content.split_left(theme::CONTENT_BORDER);
let (content_single_page, _space) = content.split_right(theme::CONTENT_BORDER);
let (content, scrollbar) =
content.split_right(Self::SCROLLBAR_SPACE + Self::SCROLLBAR_WIDTH);
let (_space, scrollbar) = scrollbar.split_left(Self::SCROLLBAR_SPACE);
Self {
content_single_page,

@ -222,7 +222,7 @@ impl Component for PinDots {
fn paint(&mut self) {
// Clear the area with the background color.
display::rect(self.area, self.style.background_color);
display::rect_fill(self.area, self.style.background_color);
// Draw a dot for each PIN digit.
for i in 0..self.digit_count {
@ -231,7 +231,7 @@ impl Component for PinDots {
y: self.area.center().y,
};
let size = Offset::new(Self::DOT, Self::DOT);
display::rounded_rect(
display::rect_fill_rounded(
Rect::from_top_left_and_size(pos, size),
self.style.text_color,
self.style.background_color,

@ -1,7 +1,7 @@
use crate::ui::{
component::{label::LabelStyle, text::layout::DefaultTextTheme},
display::{self, Color, Font},
geometry::Rect,
geometry::{Insets, Rect},
};
use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet};
@ -164,9 +164,5 @@ pub const CONTENT_BORDER: i32 = 5;
/// | 14 |
/// +----------+
pub fn borders() -> Rect {
let (_left_border, area) = display::screen().vsplit(10);
let (area, _right_area) = area.vsplit(-5);
let (_top_border, area) = area.hsplit(13);
let (area, _bottom_border) = area.hsplit(-14);
area
display::screen().inset(Insets::new(13, 5, 14, 10))
}

Loading…
Cancel
Save