use projection helper in terminal compositor
This commit is contained in:
parent
4485b3cf13
commit
eb6dc43e53
2 changed files with 191 additions and 155 deletions
118
src/main.rs
118
src/main.rs
|
@ -10,7 +10,7 @@ pub mod terminal;
|
||||||
pub mod projection;
|
pub mod projection;
|
||||||
pub mod string_editor;
|
pub mod string_editor;
|
||||||
pub mod leveled_term_view;
|
pub mod leveled_term_view;
|
||||||
pub mod cell_layout;
|
//pub mod cell_layout;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
async_std::{task},
|
async_std::{task},
|
||||||
|
@ -39,13 +39,69 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
/*
|
||||||
|
struct ListView {
|
||||||
|
opening: OuterViewPort<dyn SequenceView<Item = TerminalAtom>>,
|
||||||
|
closing: OuterViewPort<dyn SequenceView<Item = TerminalAtom>>,
|
||||||
|
delim: OuterViewPort<dyn SequenceView<Item = TerminalAtom>>,
|
||||||
|
|
||||||
|
data: Option<Arc<dyn SequenceView<Item = OuterViewPort<dyn SequenceView<Item = TerminalAtom>>>>>,
|
||||||
|
cast: Arc<RwLock<ObserverBroadcast<>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View for ListView {
|
||||||
|
type Msg = usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SequenceView for ListView {
|
||||||
|
type Item = OuterViewPort<dyn SequenceView<Item = TerminalAtom>>;
|
||||||
|
|
||||||
|
fn get(&self, idx: usize) -> Option<Self::Item> {
|
||||||
|
let len = self.data.len();
|
||||||
|
|
||||||
|
if idx == 0 {
|
||||||
|
Some(self.opening.clone())
|
||||||
|
} else if idx < len*2 {
|
||||||
|
if idx % 2 == 1 {
|
||||||
|
self.data.get(idx / 2)
|
||||||
|
} else {
|
||||||
|
Some(self.delim.clone())
|
||||||
|
}
|
||||||
|
} else if idx == len*2 {
|
||||||
|
Some(self.closing.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Observer<dyn SequenceView<Item = OuterViewPort<dyn SequenceView<Item = TerminalAtom>>>> for ListView {
|
||||||
|
fn reset(&mut self, v: Option<Arc<dyn SequenceView<Item = OuterViewPort<dyn SequenceView<Item = TerminalAtom>>>>>) {
|
||||||
|
self.data = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn notify(&self, idx: usize) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListView {
|
||||||
|
fn new(
|
||||||
|
data: OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn SequenceView<Item = TerminalAtom>>>>,
|
||||||
|
port: InnerViewPort<dyn SequenceView<Item = OuterViewPort<dyn SequenceView<Item = TerminalAtom>>>>
|
||||||
|
) -> Self {
|
||||||
|
let
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let term_port = ViewPort::<dyn TerminalView>::new();
|
let term_port = ViewPort::<dyn TerminalView>::new();
|
||||||
|
|
||||||
let mut compositor = TerminalCompositor::new(term_port.inner());
|
let mut compositor = TerminalCompositor::new(term_port.inner());
|
||||||
compositor.push(ViewPort::<dyn TerminalView>::with_view(Arc::new(ScrambleBackground)).into_outer());
|
//compositor.push(ViewPort::<dyn TerminalView>::with_view(Arc::new(ScrambleBackground)).into_outer());
|
||||||
|
|
||||||
let mut term = Terminal::new(term_port.outer());
|
let mut term = Terminal::new(term_port.outer());
|
||||||
let term_writer = term.get_writer();
|
let term_writer = term.get_writer();
|
||||||
|
@ -60,6 +116,23 @@ async fn main() {
|
||||||
let window_size_port = ViewPort::new();
|
let window_size_port = ViewPort::new();
|
||||||
let mut window_size = SingletonBuffer::new(Vector2::new(0, 0), window_size_port.inner());
|
let mut window_size = SingletonBuffer::new(Vector2::new(0, 0), window_size_port.inner());
|
||||||
|
|
||||||
|
let str_list_port = ViewPort::new();
|
||||||
|
let mut str_list = VecBuffer::<OuterViewPort<dyn SequenceView<Item = TerminalAtom>>>::new(str_list_port.inner());
|
||||||
|
|
||||||
|
compositor.write().unwrap().push(
|
||||||
|
str_list_port.outer()
|
||||||
|
.to_sequence()
|
||||||
|
.flatten()
|
||||||
|
.to_index()
|
||||||
|
.map_key(
|
||||||
|
|idx| Point2::new(*idx as i16, 0 as i16),
|
||||||
|
|pt| if pt.y == 0 { Some(pt.x as usize) } else { None }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
// welcome message
|
||||||
|
task::spawn(async move {
|
||||||
let opening_port = ViewPort::new();
|
let opening_port = ViewPort::new();
|
||||||
let mut opening = VecBuffer::new(opening_port.inner());
|
let mut opening = VecBuffer::new(opening_port.inner());
|
||||||
|
|
||||||
|
@ -80,31 +153,17 @@ async fn main() {
|
||||||
delim.push(TerminalAtom::new(' ', TerminalStyle::fg_color((180, 120, 80))));
|
delim.push(TerminalAtom::new(' ', TerminalStyle::fg_color((180, 120, 80))));
|
||||||
closing.push(TerminalAtom::new(']', TerminalStyle::fg_color((180, 120, 80))));
|
closing.push(TerminalAtom::new(']', TerminalStyle::fg_color((180, 120, 80))));
|
||||||
|
|
||||||
let str_list_port = ViewPort::new();
|
|
||||||
let mut str_list = VecBuffer::<OuterViewPort<dyn SequenceView<Item = TerminalAtom>>>::new(str_list_port.inner());
|
|
||||||
|
|
||||||
str_list.push(opening_port.outer().to_sequence());
|
str_list.push(opening_port.outer().to_sequence());
|
||||||
str_list.push(closing_port.outer().to_sequence());
|
str_list.push(closing_port.outer().to_sequence());
|
||||||
|
|
||||||
compositor.push(
|
|
||||||
str_list_port.outer()
|
|
||||||
.to_sequence()
|
|
||||||
.flatten()
|
|
||||||
.to_index()
|
|
||||||
.map_key(
|
|
||||||
|idx| Point2::new(*idx as i16, 0 as i16),
|
|
||||||
|pt| if pt.y == 0 { Some(pt.x as usize) } else { None }
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
||||||
// welcome message
|
|
||||||
task::sleep(std::time::Duration::from_millis(500)).await;
|
task::sleep(std::time::Duration::from_millis(500)).await;
|
||||||
str_list.insert(1, e1_port.outer().to_sequence());
|
str_list.insert(1, e1_port.outer().to_sequence());
|
||||||
|
|
||||||
for c in "Welcome!".chars() {
|
for c in "Welcome!".chars() {
|
||||||
e1.push(TerminalAtom::new(c, TerminalStyle::fg_color((180, 180, 255))));
|
e1.push(TerminalAtom::new(c, TerminalStyle::fg_color((180, 180, 255))));
|
||||||
task::sleep(std::time::Duration::from_millis(80)).await;
|
task::sleep(std::time::Duration::from_millis(80)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
task::sleep(std::time::Duration::from_millis(500)).await;
|
task::sleep(std::time::Duration::from_millis(500)).await;
|
||||||
str_list.insert(2, delim_port.outer().to_sequence());
|
str_list.insert(2, delim_port.outer().to_sequence());
|
||||||
str_list.insert(3, e2_port.outer().to_sequence());
|
str_list.insert(3, e2_port.outer().to_sequence());
|
||||||
|
@ -132,8 +191,9 @@ async fn main() {
|
||||||
task::sleep(std::time::Duration::from_millis(80)).await;
|
task::sleep(std::time::Duration::from_millis(80)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
for i in 0 .. 10 {
|
for i in 0 .. 10 {
|
||||||
task::sleep(std::time::Duration::from_millis(100)).await;
|
task::sleep(std::time::Duration::from_millis(60)).await;
|
||||||
|
|
||||||
let col = (100+10*i, 55+20*i, 20+ 20*i);
|
let col = (100+10*i, 55+20*i, 20+ 20*i);
|
||||||
*opening.get_mut(0) = TerminalAtom::new('{', TerminalStyle::fg_color(col));
|
*opening.get_mut(0) = TerminalAtom::new('{', TerminalStyle::fg_color(col));
|
||||||
|
@ -141,12 +201,14 @@ async fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0 .. 10 {
|
for i in 0 .. 10 {
|
||||||
task::sleep(std::time::Duration::from_millis(100)).await;
|
task::sleep(std::time::Duration::from_millis(60)).await;
|
||||||
|
|
||||||
let col = (100+10*i, 55+20*i, 20+ 20*i);
|
let col = (100+10*i, 55+20*i, 20+ 20*i);
|
||||||
*opening.get_mut(0) = TerminalAtom::new('<', TerminalStyle::fg_color(col));
|
*opening.get_mut(0) = TerminalAtom::new('<', TerminalStyle::fg_color(col));
|
||||||
*closing.get_mut(0) = TerminalAtom::new('>', TerminalStyle::fg_color(col));
|
*closing.get_mut(0) = TerminalAtom::new('>', TerminalStyle::fg_color(col));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
// string editor 1
|
// string editor 1
|
||||||
|
@ -158,6 +220,22 @@ async fn main() {
|
||||||
let mut editor2 = StringEditor::new();
|
let mut editor2 = StringEditor::new();
|
||||||
let (leveled_edit2_view, leveled_edit2_view_port) = LeveledTermView::new(editor2.insert_view());
|
let (leveled_edit2_view, leveled_edit2_view_port) = LeveledTermView::new(editor2.insert_view());
|
||||||
|
|
||||||
|
compositor.write().unwrap().push(
|
||||||
|
leveled_edit_view_port
|
||||||
|
.map_key(
|
||||||
|
|p| p + Vector2::new(1, 1),
|
||||||
|
|p| Some(p - Vector2::new(1, 1))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
compositor.write().unwrap().push(
|
||||||
|
leveled_edit2_view_port
|
||||||
|
.map_key(
|
||||||
|
|p| p + Vector2::new(1, 2),
|
||||||
|
|p| Some(p - Vector2::new(1, 2))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/*\
|
/*\
|
||||||
<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
|
@ -7,70 +7,67 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
core::{InnerViewPort, OuterViewPort, Observer, ObserverExt, ObserverBroadcast},
|
core::{InnerViewPort, OuterViewPort, Observer, ObserverExt, ObserverBroadcast},
|
||||||
index::{ImplIndexView},
|
index::{ImplIndexView},
|
||||||
terminal::{TerminalAtom, TerminalView}
|
terminal::{TerminalAtom, TerminalView},
|
||||||
|
projection::ProjectionHelper
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompositeLayer {
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
comp: Weak<RwLock<TerminalCompositeView>>,
|
|
||||||
idx: usize
|
pub struct TerminalCompositor {
|
||||||
|
layers: Vec<Arc<dyn TerminalView>>,
|
||||||
|
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
|
||||||
|
proj_helper: ProjectionHelper<Self>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Observer<dyn TerminalView> for CompositeLayer {
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
fn reset(&mut self, view: Option<Arc<dyn TerminalView>>) {
|
|
||||||
let comp = self.comp.upgrade().unwrap();
|
|
||||||
let mut c = comp.write().unwrap();
|
|
||||||
|
|
||||||
let v = &mut c.layers.get_mut(&self.idx).unwrap().1;
|
impl TerminalCompositor {
|
||||||
let old_view = v.clone();
|
pub fn new(
|
||||||
*v = view.clone();
|
port: InnerViewPort<dyn TerminalView>
|
||||||
drop(v);
|
) -> Arc<RwLock<Self>> {
|
||||||
|
let comp = Arc::new(RwLock::new(
|
||||||
if let Some(old_view) = old_view {
|
TerminalCompositor {
|
||||||
if let Some(area) = old_view.area() {
|
layers: Vec::new(),
|
||||||
c.cast.notify_each(area);
|
cast: port.get_broadcast(),
|
||||||
|
proj_helper: ProjectionHelper::new()
|
||||||
}
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
comp.write().unwrap().proj_helper.set_proj(&comp);
|
||||||
|
port.set_view(Some(comp.clone()));
|
||||||
|
|
||||||
|
comp
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(view) = view.as_ref() {
|
pub fn push(&mut self, v: OuterViewPort<dyn TerminalView>) {
|
||||||
if let Some(area) = view.area() {
|
self.layers.push(
|
||||||
c.cast.notify_each(area);
|
self.proj_helper.new_index_arg(
|
||||||
|
v,
|
||||||
|
|s: &mut Self, pos| {
|
||||||
|
s.cast.notify(pos);
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
);
|
||||||
|
|
||||||
fn notify(&self, pos: &Point2<i16>) {
|
|
||||||
self.comp
|
|
||||||
.upgrade().unwrap()
|
|
||||||
.read().unwrap()
|
|
||||||
.cast.notify(pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TerminalCompositeView {
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
idx_count: usize,
|
|
||||||
layers: HashMap<usize, (Arc<RwLock<CompositeLayer>>, Option<Arc<dyn TerminalView>>)>,
|
|
||||||
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ImplIndexView for TerminalCompositeView {
|
impl ImplIndexView for TerminalCompositor {
|
||||||
type Key = Point2<i16>;
|
type Key = Point2<i16>;
|
||||||
type Value = TerminalAtom;
|
type Value = TerminalAtom;
|
||||||
|
|
||||||
fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> {
|
fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> {
|
||||||
let mut atom = None;
|
let mut atom = None;
|
||||||
|
|
||||||
for idx in 0 .. self.idx_count {
|
for layer in self.layers.iter() {
|
||||||
if let Some(l) = self.layers.get(&idx) {
|
match (atom, layer.get(pos)) {
|
||||||
if let Some(view) = l.1.as_ref() {
|
|
||||||
match (atom, view.get(pos)) {
|
|
||||||
(None, next) => atom = next,
|
(None, next) => atom = next,
|
||||||
(Some(last), Some(next)) => atom = Some(next.add_style_back(last.style)),
|
(Some(last), Some(next)) => atom = Some(next.add_style_back(last.style)),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
atom
|
atom
|
||||||
}
|
}
|
||||||
|
@ -78,13 +75,12 @@ impl ImplIndexView for TerminalCompositeView {
|
||||||
fn area(&self) -> Option<Vec<Point2<i16>>> {
|
fn area(&self) -> Option<Vec<Point2<i16>>> {
|
||||||
let mut area = Some(Vec::new());
|
let mut area = Some(Vec::new());
|
||||||
|
|
||||||
for (_, layer) in self.layers.iter() {
|
for layer in self.layers.iter() {
|
||||||
if let Some(view) = layer.1.as_ref() {
|
|
||||||
if let (
|
if let (
|
||||||
Some(mut new_area),
|
Some(mut new_area),
|
||||||
Some(area)
|
Some(area)
|
||||||
) = (
|
) = (
|
||||||
view.area(),
|
layer.area(),
|
||||||
area.as_mut()
|
area.as_mut()
|
||||||
) {
|
) {
|
||||||
area.append(&mut new_area);
|
area.append(&mut new_area);
|
||||||
|
@ -92,46 +88,8 @@ impl ImplIndexView for TerminalCompositeView {
|
||||||
area = None;
|
area = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
area
|
area
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TerminalCompositor {
|
|
||||||
view: Arc<RwLock<TerminalCompositeView>>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TerminalCompositor {
|
|
||||||
pub fn new(
|
|
||||||
port: InnerViewPort<dyn TerminalView>
|
|
||||||
) -> Self {
|
|
||||||
let view = Arc::new(RwLock::new(
|
|
||||||
TerminalCompositeView {
|
|
||||||
idx_count: 0,
|
|
||||||
layers: HashMap::new(),
|
|
||||||
cast: port.get_broadcast()
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
port.set_view(Some(view.clone()));
|
|
||||||
TerminalCompositor{ view }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(&mut self, v: OuterViewPort<dyn TerminalView>) {
|
|
||||||
let mut comp = self.view.write().unwrap();
|
|
||||||
let idx = comp.idx_count;
|
|
||||||
comp.idx_count += 1;
|
|
||||||
|
|
||||||
let layer = Arc::new(RwLock::new(CompositeLayer {
|
|
||||||
comp: Arc::downgrade(&self.view),
|
|
||||||
idx: idx
|
|
||||||
}));
|
|
||||||
|
|
||||||
comp.layers.insert(idx, (layer.clone(), None));
|
|
||||||
drop(comp);
|
|
||||||
|
|
||||||
v.add_observer(layer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue