1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use alloc::{
collections::VecDeque,
string::{String, ToString},
sync::Arc,
};
use embedded_graphics::{
mono_font::{ascii::FONT_10X20, MonoTextStyle},
pixelcolor::Rgb888,
prelude::{Dimensions, Point, Primitive, RgbColor, Size},
primitives::{PrimitiveStyle, Rectangle},
text::{Alignment, Text},
Drawable,
};
use crate::{drivers::GPU_DEVICE, sync::UPIntrFreeCell};
use super::{button::Button, Component, Graphics, Panel};
pub struct Terminal {
inner: UPIntrFreeCell<TerminalInner>,
}
pub struct TerminalInner {
pub text: String,
titel: Option<String>,
graphic: Graphics,
comps: VecDeque<Arc<dyn Component>>,
}
impl Terminal {
pub fn new(
size: Size,
point: Point,
parent: Option<Arc<dyn Component>>,
titel: Option<String>,
text: String,
) -> Self {
Self {
inner: unsafe {
UPIntrFreeCell::new(TerminalInner {
text,
titel,
graphic: Graphics {
size,
point,
drv: GPU_DEVICE.clone(),
},
comps: VecDeque::new(),
})
},
}
}
pub fn repaint(&self, text: String) {
let mut inner = self.inner.exclusive_access();
inner.text += text.as_str();
Text::with_alignment(
inner.text.clone().as_str(),
Point::new(20, 50),
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
Alignment::Left,
)
.draw(&mut inner.graphic);
}
}
impl Component for Terminal {
fn paint(&self) {
let mut inner = self.inner.exclusive_access();
let len = inner.comps.len();
drop(inner);
for i in 0..len {
let mut inner = self.inner.exclusive_access();
let comp = Arc::downgrade(&inner.comps[i]);
drop(inner);
comp.upgrade().unwrap().paint();
}
let mut inner = self.inner.exclusive_access();
let titel = inner.titel.get_or_insert("No Titel".to_string()).clone();
let text = Text::new(
titel.as_str(),
Point::new(20, 20),
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
);
text.draw(&mut inner.graphic);
Text::with_alignment(
inner.text.clone().as_str(),
Point::new(20, 50),
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
Alignment::Left,
)
.draw(&mut inner.graphic);
}
fn add(&self, comp: Arc<dyn Component>) {
let mut inner = self.inner.exclusive_access();
inner.comps.push_back(comp);
}
fn bound(&self) -> (Size, Point) {
let inner = self.inner.exclusive_access();
(inner.graphic.size, inner.graphic.point)
}
}