mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 14:58:09 +00:00
fix(core/ui/rust): painting of overlapping Maybe<T> components
[no changelog]
This commit is contained in:
parent
168389a7b3
commit
c257a8a687
@ -4,7 +4,11 @@ use heapless::Vec;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
ui::{component::Map, geometry::Rect},
|
ui::{
|
||||||
|
component::{maybe::PaintOverlapping, Map},
|
||||||
|
display::Color,
|
||||||
|
geometry::Rect,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "buttons")]
|
#[cfg(feature = "buttons")]
|
||||||
@ -136,6 +140,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PaintOverlapping for Child<T>
|
||||||
|
where
|
||||||
|
T: PaintOverlapping,
|
||||||
|
{
|
||||||
|
fn cleared_area(&self) -> Option<(Rect, Color)> {
|
||||||
|
self.component.cleared_area()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint_overlapping(&mut self) {
|
||||||
|
if self.marked_for_paint {
|
||||||
|
self.marked_for_paint = false;
|
||||||
|
self.component.paint_overlapping()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ui_debug")]
|
#[cfg(feature = "ui_debug")]
|
||||||
impl<T> crate::trace::Trace for Child<T>
|
impl<T> crate::trace::Trace for Child<T>
|
||||||
where
|
where
|
||||||
@ -167,6 +187,11 @@ where
|
|||||||
self.0.paint();
|
self.0.paint();
|
||||||
self.1.paint();
|
self.1.paint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
|
||||||
|
self.0.bounds(sink);
|
||||||
|
self.1.bounds(sink);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ui_debug")]
|
#[cfg(feature = "ui_debug")]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
component::{Component, ComponentExt, Event, EventCtx, Pad},
|
component::{Component, ComponentExt, Event, EventCtx, Pad},
|
||||||
display::Color,
|
display::{self, Color},
|
||||||
geometry::Rect,
|
geometry::Rect,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,3 +98,48 @@ where
|
|||||||
self.inner.bounds(sink);
|
self.inner.bounds(sink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait PaintOverlapping {
|
||||||
|
/// Return area that would be cleared during regular paint, along with
|
||||||
|
/// background color, or None if clearing isn't requested.
|
||||||
|
fn cleared_area(&self) -> Option<(Rect, Color)>;
|
||||||
|
|
||||||
|
/// Paint the component but do not clear background beforehand.
|
||||||
|
fn paint_overlapping(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaintOverlapping for Maybe<T>
|
||||||
|
where
|
||||||
|
T: Component,
|
||||||
|
{
|
||||||
|
fn cleared_area(&self) -> Option<(Rect, Color)> {
|
||||||
|
self.pad.will_paint()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint_overlapping(&mut self) {
|
||||||
|
self.pad.cancel_clear();
|
||||||
|
self.paint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Paint multiple Maybe<T> components, correctly handling clearing of
|
||||||
|
/// background in the case the areas overlap, i.e. clear the combined area first
|
||||||
|
/// and then paint over it.
|
||||||
|
pub fn paint_overlapping(components: &mut [&mut dyn PaintOverlapping]) {
|
||||||
|
let mut area = Rect::zero();
|
||||||
|
let mut color = Color::rgb(0, 0, 0);
|
||||||
|
for component in components.iter() {
|
||||||
|
if let Some((clear_area, clear_color)) = component.cleared_area() {
|
||||||
|
area = area.union(clear_area);
|
||||||
|
color = clear_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if area != Rect::zero() {
|
||||||
|
display::rect_fill(area, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
for component in components.iter_mut() {
|
||||||
|
component.paint_overlapping()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -26,6 +26,18 @@ impl Pad {
|
|||||||
self.clear = true;
|
self.clear = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cancel_clear(&mut self) {
|
||||||
|
self.clear = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn will_paint(&self) -> Option<(Rect, Color)> {
|
||||||
|
if self.clear {
|
||||||
|
Some((self.area, self.color))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn paint(&mut self) {
|
pub fn paint(&mut self) {
|
||||||
if self.clear {
|
if self.clear {
|
||||||
self.clear = false;
|
self.clear = false;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
|
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
component::{Child, Component, Event, EventCtx, Label, Maybe},
|
component::{maybe::paint_overlapping, Child, Component, Event, EventCtx, Label, Maybe},
|
||||||
geometry::{Alignment, Grid, Rect},
|
geometry::{Alignment, Grid, Rect},
|
||||||
model_tt::{
|
model_tt::{
|
||||||
component::{Button, ButtonMsg},
|
component::{Button, ButtonMsg},
|
||||||
@ -139,9 +139,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&mut self) {
|
fn paint(&mut self) {
|
||||||
self.prompt.paint();
|
paint_overlapping(&mut [&mut self.prompt, &mut self.input, &mut self.back]);
|
||||||
self.input.paint();
|
|
||||||
self.back.paint();
|
|
||||||
for btn in &mut self.keys {
|
for btn in &mut self.keys {
|
||||||
btn.paint();
|
btn.paint();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user