2020-12-09 17:31:08 +01:00
|
|
|
use {
|
2021-01-06 21:35:46 +01:00
|
|
|
std::{
|
2021-03-30 22:47:05 +02:00
|
|
|
sync::{Arc, Weak},
|
2021-01-16 16:09:16 +01:00
|
|
|
collections::HashMap
|
2021-01-06 21:35:46 +01:00
|
|
|
},
|
2021-03-30 22:47:05 +02:00
|
|
|
std::sync::RwLock,
|
2021-01-06 21:35:46 +01:00
|
|
|
cgmath::Point2,
|
2020-12-09 17:31:08 +01:00
|
|
|
crate::{
|
2021-01-16 16:09:16 +01:00
|
|
|
core::{InnerViewPort, OuterViewPort, Observer, ObserverExt, ObserverBroadcast},
|
2021-01-12 23:09:46 +01:00
|
|
|
index::{ImplIndexView},
|
2021-02-17 18:18:39 +01:00
|
|
|
terminal::{TerminalAtom, TerminalView},
|
|
|
|
projection::ProjectionHelper
|
2020-12-09 17:31:08 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
2020-12-09 17:31:08 +01:00
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
pub struct TerminalCompositor {
|
|
|
|
layers: Vec<Arc<dyn TerminalView>>,
|
|
|
|
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
|
|
|
|
proj_helper: ProjectionHelper<Self>
|
|
|
|
}
|
2021-01-06 21:35:46 +01:00
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
2021-01-06 21:35:46 +01:00
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
impl TerminalCompositor {
|
|
|
|
pub fn new(
|
|
|
|
port: InnerViewPort<dyn TerminalView>
|
|
|
|
) -> Arc<RwLock<Self>> {
|
|
|
|
let comp = Arc::new(RwLock::new(
|
|
|
|
TerminalCompositor {
|
|
|
|
layers: Vec::new(),
|
|
|
|
cast: port.get_broadcast(),
|
|
|
|
proj_helper: ProjectionHelper::new()
|
2021-01-06 21:35:46 +01:00
|
|
|
}
|
2021-02-17 18:18:39 +01:00
|
|
|
));
|
2021-01-06 21:35:46 +01:00
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
comp.write().unwrap().proj_helper.set_proj(&comp);
|
|
|
|
port.set_view(Some(comp.clone()));
|
|
|
|
|
|
|
|
comp
|
2021-01-06 21:35:46 +01:00
|
|
|
}
|
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
pub fn push(&mut self, v: OuterViewPort<dyn TerminalView>) {
|
|
|
|
self.layers.push(
|
|
|
|
self.proj_helper.new_index_arg(
|
|
|
|
v,
|
|
|
|
|s: &mut Self, pos| {
|
|
|
|
s.cast.notify(pos);
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
2021-01-06 21:35:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
2020-12-09 17:31:08 +01:00
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
impl ImplIndexView for TerminalCompositor {
|
2021-01-06 21:35:46 +01:00
|
|
|
type Key = Point2<i16>;
|
2021-01-16 20:19:52 +01:00
|
|
|
type Value = TerminalAtom;
|
2021-01-06 21:35:46 +01:00
|
|
|
|
|
|
|
fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> {
|
|
|
|
let mut atom = None;
|
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
for layer in self.layers.iter() {
|
|
|
|
match (atom, layer.get(pos)) {
|
|
|
|
(None, next) => atom = next,
|
|
|
|
(Some(last), Some(next)) => atom = Some(next.add_style_back(last.style)),
|
|
|
|
_ => {}
|
2020-12-09 17:31:08 +01:00
|
|
|
}
|
|
|
|
}
|
2021-01-06 21:35:46 +01:00
|
|
|
|
|
|
|
atom
|
2020-12-09 17:31:08 +01:00
|
|
|
}
|
|
|
|
|
2021-01-16 13:57:06 +01:00
|
|
|
fn area(&self) -> Option<Vec<Point2<i16>>> {
|
2021-01-16 18:00:56 +01:00
|
|
|
let mut area = Some(Vec::new());
|
|
|
|
|
2021-02-17 18:18:39 +01:00
|
|
|
for layer in self.layers.iter() {
|
|
|
|
if let (
|
|
|
|
Some(mut new_area),
|
|
|
|
Some(area)
|
|
|
|
) = (
|
|
|
|
layer.area(),
|
|
|
|
area.as_mut()
|
|
|
|
) {
|
|
|
|
area.append(&mut new_area);
|
|
|
|
} else {
|
|
|
|
area = None;
|
2021-01-16 18:00:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
area
|
2020-12-09 17:31:08 +01:00
|
|
|
}
|
2021-01-06 21:35:46 +01:00
|
|
|
}
|
|
|
|
|