From 8f329e091d0b2f601a4dfcd51c11b2a87791889e Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 15 Oct 2021 16:38:10 +0200
Subject: [PATCH] use sdf backend in shell

---
 nested/Cargo.toml      |   5 +
 nested/src/lib.rs      |   2 +
 nested/src/sdf/mod.rs  |   4 +
 nested/src/sdf/term.rs | 190 ++++++++++++++++++++++
 sdf_editor/src/main.rs | 154 +-----------------
 shell/Cargo.toml       |   4 +
 shell/src/main.rs      | 349 +++++++++++++++++++++++++++++++++++------
 7 files changed, 507 insertions(+), 201 deletions(-)
 create mode 100644 nested/src/sdf/mod.rs
 create mode 100644 nested/src/sdf/term.rs

diff --git a/nested/Cargo.toml b/nested/Cargo.toml
index 0be90e1..eee3a39 100644
--- a/nested/Cargo.toml
+++ b/nested/Cargo.toml
@@ -16,6 +16,11 @@ serde = { version = "1.0", features = ["derive"] }
 bincode = "1.3.3"
 serde_json = "*"
 
+nako = {git= "https://git.exobiont.de/senvas/nako.git"}
+nako_std = {git= "https://git.exobiont.de/senvas/nako.git"}
+nakorender = {git="https://git.exobiont.de/senvas/nako.git", default-features = false}
+font-kit = "*"
+
 [dependencies.async-std]
 version = "1.9.0"
 features = ["unstable", "attributes"]
diff --git a/nested/src/lib.rs b/nested/src/lib.rs
index 611d921..17b9592 100644
--- a/nested/src/lib.rs
+++ b/nested/src/lib.rs
@@ -18,6 +18,8 @@ pub mod string_editor;
 
 pub mod bimap;
 
+pub mod sdf;
+
 pub fn magic_header() {
     eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
 }
diff --git a/nested/src/sdf/mod.rs b/nested/src/sdf/mod.rs
new file mode 100644
index 0000000..e3a89df
--- /dev/null
+++ b/nested/src/sdf/mod.rs
@@ -0,0 +1,4 @@
+pub mod term;
+
+pub use term::SdfTerm;
+
diff --git a/nested/src/sdf/term.rs b/nested/src/sdf/term.rs
new file mode 100644
index 0000000..29b950c
--- /dev/null
+++ b/nested/src/sdf/term.rs
@@ -0,0 +1,190 @@
+
+use {
+    std::{
+        sync::{Arc, RwLock, Mutex},
+        collections::HashMap
+    },
+    cgmath::{Point2, Vector2},
+    termion::event::{Event, Key},
+    crate::{
+        core::{
+            View,
+            ViewPort,
+            Observer,
+            ObserverExt,
+            OuterViewPort,
+            port::UpdateTask
+        },
+        terminal::{TerminalView}
+    },
+    nako::{
+        stream::{SecondaryStream2d, PrimaryStream2d},
+        glam::{Vec2, Vec3, UVec2, IVec2},
+        operations::{
+            planar::primitives2d::Box2d,
+            volumetric::{Color, Union, Round},
+        },
+    },
+    nakorender::{
+        backend::{Backend, LayerId, LayerId2d, LayerInfo},
+        marp::MarpBackend,
+        winit, camera::Camera2d
+    },
+    nako_std::{
+        text::Character
+    },
+    std::{fs::File, io::Read, mem::needs_drop, path::Path},
+    font_kit::font::Font,
+};
+
+pub struct SdfTerm {
+    src_view: Option<Arc<dyn TerminalView>>,
+    bg_layers: HashMap<Point2<i16>, (bool, LayerId2d)>,
+    fg_layers: HashMap<Point2<i16>, (bool, LayerId2d)>,
+
+    font_height: u32,
+    //font: Mutex<Font>,
+
+    renderer: Arc<Mutex<MarpBackend>>
+}
+
+impl SdfTerm {
+    pub fn new(renderer: Arc<Mutex<MarpBackend>>) -> Self {
+        SdfTerm {
+            src_view: None,
+            bg_layers: HashMap::new(),
+            fg_layers: HashMap::new(),
+            font_height: 30,
+            //font: Mutex::new(Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap()),
+            renderer
+        }
+    }
+
+    pub fn get_order(&self) -> Vec<LayerId> {
+        vec![
+            self.bg_layers.iter(),
+            self.fg_layers.iter()
+        ]
+            .into_iter()
+            .flatten()
+            .filter_map(
+                |(_pt,(active,id))|
+                if *active {
+                    Some((*id).into())
+                } else {
+                    None
+                })
+            .collect::<Vec<_>>()
+    }
+
+    pub fn update(&mut self, pt: &Point2<i16>) {
+        if self.bg_layers.get(pt).is_none() {
+            let id = self.renderer.lock().unwrap().new_layer_2d();
+
+            self.renderer.lock().unwrap().update_camera_2d(
+                id.into(),
+                Camera2d {
+                    extent: Vec2::new(0.5, 1.0),
+                    location: Vec2::new(0.0, 0.0),
+                    rotation: 0.0
+                });
+            self.renderer.lock().unwrap().set_layer_info(
+                id.into(),
+                LayerInfo {
+                    extent: UVec2::new(1 + self.font_height / 2, self.font_height),
+                    location: IVec2::new(pt.x as i32 * self.font_height as i32 / 2, pt.y as i32 * self.font_height as i32)
+                });
+
+            self.bg_layers.insert(*pt, (false, id));
+        }
+        if self.fg_layers.get(pt).is_none() {
+            let id = self.renderer.lock().unwrap().new_layer_2d();
+
+            self.renderer.lock().unwrap().update_camera_2d(
+                id.into(),
+                Camera2d {
+                    extent: Vec2::new(0.5, 1.0),
+                    location: Vec2::new(0.0, 0.0),
+                    rotation: 0.0
+                });
+            self.renderer.lock().unwrap().set_layer_info(
+                id.into(),
+                LayerInfo {
+                    extent: UVec2::new(1 + self.font_height / 2, self.font_height),
+                    location: IVec2::new(pt.x as i32 * self.font_height as i32 / 2, pt.y as i32 * self.font_height as i32)
+                });
+
+            self.fg_layers.insert(*pt, (false, id));
+        }
+
+        if let Some(atom) = self.src_view.get(pt) {
+
+            // background layer
+            if let Some((r,g,b)) = atom.style.bg_color {
+                let mut stream = PrimaryStream2d::new()
+                    .push(
+                        SecondaryStream2d::new(
+                            Union,
+                            Box2d {
+                                extent: Vec2::new(0.6, 1.0)
+                            }
+                        ).push_mod(
+                            Color(
+                                Vec3::new(
+                                    (r as f32 / 255.0).clamp(0.0, 1.0),
+                                    (g as f32 / 255.0).clamp(0.0, 1.0),
+                                    (b as f32 / 255.0).clamp(0.0, 1.0),
+                                )
+                            )
+                        ).build()
+                    );
+
+                self.renderer.lock().unwrap().update_sdf_2d(self.bg_layers.get(pt).unwrap().1, stream.build());
+                self.bg_layers.get_mut(pt).unwrap().0 = true;
+            } else {
+                self.bg_layers.get_mut(pt).unwrap().0 = false;                
+            }
+
+            // foreground layer
+            if let Some(c) = atom.c {
+                let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Light.ttf"),0).unwrap();
+                let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01);
+
+                let (r,g,b) = atom.style.fg_color.unwrap_or((0, 0, 0));
+
+                ch.color = Vec3::new(
+                    (r as f32 / 255.0).clamp(0.0, 1.0),
+                    (g as f32 / 255.0).clamp(0.0, 1.0),
+                    (b as f32 / 255.0).clamp(0.0, 1.0),
+                );
+
+                let mut stream = PrimaryStream2d::new();
+                stream = ch.record_character(stream);
+
+                self.renderer.lock().unwrap().update_sdf_2d(self.fg_layers.get(pt).unwrap().1, stream.build());
+                self.fg_layers.get_mut(pt).unwrap().0 = true;
+            } else {
+                self.fg_layers.get_mut(pt).unwrap().0 = false;                
+            }
+
+        } else {
+            self.bg_layers.get_mut(pt).unwrap().0 = false;
+            self.fg_layers.get_mut(pt).unwrap().0 = false;
+        }
+    }
+}
+
+impl Observer<dyn TerminalView> for SdfTerm {
+    fn reset(&mut self, new_view: Option<Arc<dyn TerminalView>>) {
+        self.src_view = new_view;
+
+        for pt in self.src_view.area().unwrap_or(vec![]) {
+            self.notify(&pt);
+        }
+    }
+
+    fn notify(&mut self, pt: &Point2<i16>) {
+        self.update(pt);
+    }
+}
+
diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs
index 16a2be2..c6bc43f 100644
--- a/sdf_editor/src/main.rs
+++ b/sdf_editor/src/main.rs
@@ -20,7 +20,8 @@ use{
         integer::{PosIntEditor},
         terminal::{Terminal, TerminalAtom, TerminalStyle, TerminalView, TerminalCompositor, TerminalEvent, TerminalEditor},
         list::{ListEditor},
-        tree_nav::{TreeNav}
+        tree_nav::{TreeNav},
+        sdf::SdfTerm
     },
     nako::{
         stream::{SecondaryStream2d, PrimaryStream2d},
@@ -71,157 +72,6 @@ impl Observer<dyn SequenceView<Item = u32>> for ColorCollector {
     }
 }
 
-struct SdfTerm {
-    src_view: Option<Arc<dyn TerminalView>>,
-    bg_layers: HashMap<Point2<i16>, (bool, LayerId2d)>,
-    fg_layers: HashMap<Point2<i16>, (bool, LayerId2d)>,
-
-    font_height: u32,
-    //font: Mutex<Font>,
-
-    renderer: Arc<Mutex<MarpBackend>>
-}
-
-impl SdfTerm {
-    pub fn new(renderer: Arc<Mutex<MarpBackend>>) -> Self {
-        SdfTerm {
-            src_view: None,
-            bg_layers: HashMap::new(),
-            fg_layers: HashMap::new(),
-            font_height: 60,
-            //font: Mutex::new(Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap()),
-            renderer
-        }
-    }
-
-    pub fn get_order(&self) -> Vec<LayerId> {
-        vec![
-            self.bg_layers.iter(),
-            self.fg_layers.iter()
-        ]
-            .into_iter()
-            .flatten()
-            .filter_map(
-                |(_pt,(active,id))|
-                if *active {
-                    Some((*id).into())
-                } else {
-                    None
-                })
-            .collect::<Vec<_>>()
-    }
-
-    pub fn update(&mut self, pt: &Point2<i16>) {
-        if self.bg_layers.get(pt).is_none() {
-            let id = self.renderer.lock().unwrap().new_layer_2d();
-
-            self.renderer.lock().unwrap().update_camera_2d(
-                id.into(),
-                Camera2d {
-                    extent: Vec2::new(0.5, 1.0),
-                    location: Vec2::new(0.0, 0.0),
-                    rotation: 0.0
-                });
-            self.renderer.lock().unwrap().set_layer_info(
-                id.into(),
-                LayerInfo {
-                    extent: UVec2::new(1 + self.font_height / 2, self.font_height),
-                    location: IVec2::new(pt.x as i32 * self.font_height as i32 / 2, pt.y as i32 * self.font_height as i32)
-                });
-
-            self.bg_layers.insert(*pt, (false, id));
-        }
-        if self.fg_layers.get(pt).is_none() {
-            let id = self.renderer.lock().unwrap().new_layer_2d();
-
-            self.renderer.lock().unwrap().update_camera_2d(
-                id.into(),
-                Camera2d {
-                    extent: Vec2::new(0.5, 1.0),
-                    location: Vec2::new(0.0, 0.0),
-                    rotation: 0.0
-                });
-            self.renderer.lock().unwrap().set_layer_info(
-                id.into(),
-                LayerInfo {
-                    extent: UVec2::new(1 + self.font_height / 2, self.font_height),
-                    location: IVec2::new(pt.x as i32 * self.font_height as i32 / 2, pt.y as i32 * self.font_height as i32)
-                });
-
-            self.fg_layers.insert(*pt, (false, id));
-        }
-
-        if let Some(atom) = self.src_view.get(pt) {
-
-            // background layer
-            if let Some((r,g,b)) = atom.style.bg_color {
-                let mut stream = PrimaryStream2d::new()
-                    .push(
-                        SecondaryStream2d::new(
-                            Union,
-                            Box2d {
-                                extent: Vec2::new(0.6, 1.0)
-                            }
-                        ).push_mod(
-                            Color(
-                                Vec3::new(
-                                    (r as f32 / 255.0).clamp(0.0, 1.0),
-                                    (g as f32 / 255.0).clamp(0.0, 1.0),
-                                    (b as f32 / 255.0).clamp(0.0, 1.0),
-                                )
-                            )
-                        ).build()
-                    );
-
-                self.renderer.lock().unwrap().update_sdf_2d(self.bg_layers.get(pt).unwrap().1, stream.build());
-                self.bg_layers.get_mut(pt).unwrap().0 = true;
-            } else {
-                self.bg_layers.get_mut(pt).unwrap().0 = false;                
-            }
-
-            // foreground layer
-            if let Some(c) = atom.c {
-                let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Light.ttf"),0).unwrap();
-                let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01);
-
-                let (r,g,b) = atom.style.fg_color.unwrap_or((0, 0, 0));
-
-                ch.color = Vec3::new(
-                    (r as f32 / 255.0).clamp(0.0, 1.0),
-                    (g as f32 / 255.0).clamp(0.0, 1.0),
-                    (b as f32 / 255.0).clamp(0.0, 1.0),
-                );
-
-                let mut stream = PrimaryStream2d::new();
-                stream = ch.record_character(stream);
-
-                self.renderer.lock().unwrap().update_sdf_2d(self.fg_layers.get(pt).unwrap().1, stream.build());
-                self.fg_layers.get_mut(pt).unwrap().0 = true;
-            } else {
-                self.fg_layers.get_mut(pt).unwrap().0 = false;                
-            }
-
-        } else {
-            self.bg_layers.get_mut(pt).unwrap().0 = false;
-            self.fg_layers.get_mut(pt).unwrap().0 = false;
-        }
-    }
-}
-
-impl Observer<dyn TerminalView> for SdfTerm {
-    fn reset(&mut self, new_view: Option<Arc<dyn TerminalView>>) {
-        self.src_view = new_view;
-
-        for pt in self.src_view.area().unwrap_or(vec![]) {
-            self.notify(&pt);
-        }
-    }
-
-    fn notify(&mut self, pt: &Point2<i16>) {
-        self.update(pt);
-    }
-}
-
 #[async_std::main]
 async fn main() {
     let term_port = ViewPort::new();
diff --git a/shell/Cargo.toml b/shell/Cargo.toml
index d086995..92c140b 100644
--- a/shell/Cargo.toml
+++ b/shell/Cargo.toml
@@ -11,6 +11,10 @@ bincode = "*"
 libc = "0.2.*"
 portable-pty = "0.4.0"
 
+nako = {git= "https://git.exobiont.de/senvas/nako.git"}
+nako_std = {git= "https://git.exobiont.de/senvas/nako.git"}
+nakorender = {git="https://git.exobiont.de/senvas/nako.git", default-features = false}
+
 [dependencies.async-std]
 version = "1.9.0"
 features = ["unstable", "attributes"]
diff --git a/shell/src/main.rs b/shell/src/main.rs
index 004e164..10012ee 100644
--- a/shell/src/main.rs
+++ b/shell/src/main.rs
@@ -7,7 +7,7 @@ mod pty;
 mod ascii_box;
 
 use{
-    std::sync::{Arc, RwLock},
+    std::sync::{Arc, RwLock, Mutex},
     cgmath::{Point2, Vector2},
     termion::event::{Event, Key},
     nested::{
@@ -37,11 +37,27 @@ use{
             TerminalEditor},
         string_editor::{StringEditor},
         tree_nav::{TreeNav, TreeNavResult, TreeCursor, TerminalTreeEditor},
-        list::{SExprView, ListCursorMode, ListEditor, ListEditorStyle}
+        list::{SExprView, ListCursorMode, ListEditor, ListEditorStyle},
+        sdf::SdfTerm
     },
     crate::{
         process::ProcessLauncher
-    }
+    },
+
+    nako::{
+        stream::{SecondaryStream2d, PrimaryStream2d},
+        glam::{Vec2, Vec3, UVec2, IVec2},
+        operations::{
+            planar::primitives2d::Box2d,
+            volumetric::{Color, Union, Round},
+        },
+    },
+    nakorender::{
+        backend::{Backend, LayerId, LayerId2d, LayerInfo},
+        marp::MarpBackend,
+        winit, camera::Camera2d
+    },
+
 };
 
 struct TestView {}
@@ -67,55 +83,289 @@ async fn main() {
     let term_port = ViewPort::new();
     let compositor = TerminalCompositor::new(term_port.inner());
 
-    let mut term = Terminal::new(term_port.outer());
-    let term_writer = term.get_writer();
+    //let mut term = Terminal::new(term_port.outer());
+    //let term_writer = term.get_writer();
 
+    let event_loop = nakorender::winit::event_loop::EventLoop::new();
+    let window = nakorender::winit::window::Window::new(&event_loop).unwrap();
+    let mut renderer = Arc::new(Mutex::new(nakorender::marp::MarpBackend::new(&window, &event_loop)));
+    let mut sdf_term = Arc::new(RwLock::new(SdfTerm::new(renderer.clone())));
+    term_port.outer().add_observer(sdf_term.clone());
+
+    let table_port = ViewPort::<dyn nested::grid::GridView<Item = OuterViewPort<dyn TerminalView>>>::new();
+    let mut table_buf = nested::index::buffer::IndexBuffer::new(table_port.inner());
+
+    let magic = make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>")
+        .map_item(
+            |pos, atom|
+            atom.add_style_back(
+                TerminalStyle::fg_color(
+                    (5,
+                     ((80+(pos.x*30)%100) as u8),
+                     (55+(pos.x*15)%180) as u8)
+                )
+            )
+        );
+
+    let cur_size_port = ViewPort::new();
+    let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10), cur_size_port.inner());
+
+    let status_chars_port = ViewPort::new();
+    let mut status_chars = VecBuffer::new(status_chars_port.inner());
+
+    let mut process_list_editor = ListEditor::new(
+        Box::new(|| {
+            Arc::new(RwLock::new(
+                ProcessLauncher::new()
+            ))
+        }),
+        ListEditorStyle::VerticalSexpr
+    );
+
+    table_buf.insert_iter(vec![
+        (Point2::new(0, 0), magic.clone()),
+        (Point2::new(0, 1), status_chars_port.outer().to_sequence().to_grid_horizontal()),
+        (Point2::new(0, 2), magic.clone()),
+        (Point2::new(0, 3), process_list_editor.get_term_view())
+    ]);
+
+    //compositor.write().unwrap().push(monstera::make_monstera());
+    compositor.write().unwrap().push(table_port.outer().flatten());//.offset(Vector2::new(40, 2)));
+
+    process_list_editor.goto(TreeCursor {
+        leaf_mode: ListCursorMode::Insert,
+        tree_addr: vec![ 0 ]
+    });
+
+    event_loop.run(move |event, _target, control_flow|{
+        //Set to polling for now, might be overwritten
+        //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderer.lock().unwrap()s don't work that hard
+        //if nothing changes. So should be okay for a alpha style programm.
+        *control_flow = winit::event_loop::ControlFlow::Poll;
+
+        //now check if a rerender was requested, or if we worked on all
+        //events on that batch
+        term_port.update();
+        renderer.lock().unwrap().set_layer_order(
+            vec![
+                //vec![ color_layer_id.into() ].into_iter(),
+                sdf_term.read().unwrap().get_order().into_iter()
+            ]
+                .into_iter()
+                .flatten()
+                .collect::<Vec<_>>()
+                .as_slice()
+        );
+
+        match event{
+            winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::Resized(newsize)} => {
+                
+            }
+            winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::KeyboardInput{ device_id, input, is_synthetic }} => {
+                if input.state == winit::event::ElementState::Pressed {
+                    if let Some(kc) = input.virtual_keycode {
+                        match kc {
+                            winit::event::VirtualKeyCode::Space => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(' '))));
+                            }
+                            winit::event::VirtualKeyCode::Return => {
+                                process_list_editor.get_item().unwrap().write().unwrap().launch_pty2()
+                            }
+                            winit::event::VirtualKeyCode::Key0 |
+                            winit::event::VirtualKeyCode::Numpad0 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('0'))));
+                            }
+                            winit::event::VirtualKeyCode::Key1 |
+                            winit::event::VirtualKeyCode::Numpad1 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('1'))));
+                            }
+                            winit::event::VirtualKeyCode::Key2 |
+                            winit::event::VirtualKeyCode::Numpad2 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('2'))));
+                            }
+                            winit::event::VirtualKeyCode::Key3 |
+                            winit::event::VirtualKeyCode::Numpad3 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('3'))));
+                            }
+                            winit::event::VirtualKeyCode::Key4 |
+                            winit::event::VirtualKeyCode::Numpad4 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('4'))));
+                            }
+                            winit::event::VirtualKeyCode::Key5 |
+                            winit::event::VirtualKeyCode::Numpad5 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('5'))));
+                            }
+                            winit::event::VirtualKeyCode::Key6 |
+                            winit::event::VirtualKeyCode::Numpad6 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('6'))));
+                            }
+                            winit::event::VirtualKeyCode::Key7 |
+                            winit::event::VirtualKeyCode::Numpad7 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('7'))));
+                            }
+                            winit::event::VirtualKeyCode::Key8 |
+                            winit::event::VirtualKeyCode::Numpad8 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('8'))));
+                            }
+                            winit::event::VirtualKeyCode::Key9 |
+                            winit::event::VirtualKeyCode::Numpad9 => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('9'))));
+                            }
+                            winit::event::VirtualKeyCode::A => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('a'))));
+                            }
+                            winit::event::VirtualKeyCode::B => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('b'))));
+                            }
+                            winit::event::VirtualKeyCode::C => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('c'))));
+                            }
+                            winit::event::VirtualKeyCode::D => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('d'))));
+                            }
+                            winit::event::VirtualKeyCode::E => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('e'))));
+                            }
+                            winit::event::VirtualKeyCode::F => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('f'))));
+                            }
+                            winit::event::VirtualKeyCode::G => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('g'))));
+                            }
+                            winit::event::VirtualKeyCode::H => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('h'))));
+                            }
+                            winit::event::VirtualKeyCode::I => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('i'))));
+                            }
+                            winit::event::VirtualKeyCode::J => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('j'))));
+                            }
+                            winit::event::VirtualKeyCode::K => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('k'))));
+                            }
+                            winit::event::VirtualKeyCode::L => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('l'))));
+                            }
+                            winit::event::VirtualKeyCode::M => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('m'))));
+                            }
+                            winit::event::VirtualKeyCode::N => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('n'))));
+                            }
+                            winit::event::VirtualKeyCode::O => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('o'))));
+                            }
+                            winit::event::VirtualKeyCode::P => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('p'))));
+                            }
+                            winit::event::VirtualKeyCode::Q => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('q'))));
+                            }
+                            winit::event::VirtualKeyCode::R => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('r'))));
+                            }
+                            winit::event::VirtualKeyCode::S => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('s'))));
+                            }
+                            winit::event::VirtualKeyCode::T => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('t'))));
+                            }
+                            winit::event::VirtualKeyCode::U => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('u'))));
+                            }
+                            winit::event::VirtualKeyCode::V => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('v'))));
+                            }
+                            winit::event::VirtualKeyCode::W => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('w'))));
+                            }
+                            winit::event::VirtualKeyCode::X => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('x'))));
+                            }
+                            winit::event::VirtualKeyCode::Y => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('y'))));
+                            }
+                            winit::event::VirtualKeyCode::Z => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('z'))));
+                            }
+                            winit::event::VirtualKeyCode::Tab => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Insert)));
+                            }
+                            winit::event::VirtualKeyCode::Delete => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Delete)));
+                            }
+                            winit::event::VirtualKeyCode::Back => {
+                                process_list_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Backspace)));
+                            }
+                            winit::event::VirtualKeyCode::Left => {
+                                process_list_editor.pxev();
+                            }
+                            winit::event::VirtualKeyCode::Right => {
+                                process_list_editor.nexd();
+                            }
+                            winit::event::VirtualKeyCode::Up => {
+                                process_list_editor.up();
+                            }
+                            winit::event::VirtualKeyCode::Down => {
+                                process_list_editor.dn();
+                                process_list_editor.goto_home();
+                            }
+                            winit::event::VirtualKeyCode::Home => {
+                                process_list_editor.goto_home();
+                            }
+                            winit::event::VirtualKeyCode::End => {
+                                process_list_editor.goto_end();
+                            }
+                            _ => {
+                            }
+                        }
+                    }
+                }
+            }
+            winit::event::Event::MainEventsCleared => {
+                window.request_redraw();
+            }
+            winit::event::Event::RedrawRequested(_) => {
+                //term_port.update();
+                renderer.lock().unwrap().render(&window);
+            }
+            _ => {},
+        }
+
+        status_chars.clear();
+        let cur = process_list_editor.get_cursor();
+
+        if cur.tree_addr.len() > 0 {
+            status_chars.push(TerminalAtom::new('@', TerminalStyle::fg_color((120, 80, 80)).add(TerminalStyle::bold(true))));
+            for x in cur.tree_addr {
+                for c in format!("{}", x).chars() {
+                    status_chars.push(TerminalAtom::new(c, TerminalStyle::fg_color((0, 100, 20))));
+                }
+                status_chars.push(TerminalAtom::new('.', TerminalStyle::fg_color((120, 80, 80))));
+            }
+
+            status_chars.push(TerminalAtom::new(':', TerminalStyle::fg_color((120, 80, 80)).add(TerminalStyle::bold(true))));
+            for c in
+                match cur.leaf_mode {
+                    ListCursorMode::Insert => "INSERT",
+                    ListCursorMode::Select => "SELECT",
+                    ListCursorMode::Modify => "MODIFY"
+                }.chars()
+            {
+                status_chars.push(TerminalAtom::new(c, TerminalStyle::fg_color((200, 200, 20))));
+            }
+            status_chars.push(TerminalAtom::new(':', TerminalStyle::fg_color((120, 80, 80)).add(TerminalStyle::bold(true))));
+        } else {
+            for c in "Press <DN> to enter".chars() {
+                status_chars.push(TerminalAtom::new(c, TerminalStyle::fg_color((200, 200, 20))));
+            }
+        }
+        
+    });
+/*
     async_std::task::spawn(
         async move {
-            let table_port = ViewPort::<dyn nested::grid::GridView<Item = OuterViewPort<dyn TerminalView>>>::new();
-            let mut table_buf = nested::index::buffer::IndexBuffer::new(table_port.inner());
-
-            let magic = make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>")
-                .map_item(
-                    |pos, atom|
-                    atom.add_style_back(
-                        TerminalStyle::fg_color(
-                            (5,
-                             ((80+(pos.x*30)%100) as u8),
-                             (55+(pos.x*15)%180) as u8)
-                        )
-                    )
-                );
-
-            let cur_size_port = ViewPort::new();
-            let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10), cur_size_port.inner());
-
-            let status_chars_port = ViewPort::new();
-            let mut status_chars = VecBuffer::new(status_chars_port.inner());
-
-            let mut process_list_editor = ListEditor::new(
-                Box::new(|| {
-                    Arc::new(RwLock::new(
-                        ProcessLauncher::new()
-                    ))
-                }),
-                ListEditorStyle::VerticalSexpr
-            );
-
-            table_buf.insert_iter(vec![
-                (Point2::new(0, 0), magic.clone()),
-                (Point2::new(0, 1), status_chars_port.outer().to_sequence().to_grid_horizontal()),
-                (Point2::new(0, 2), magic.clone()),
-                (Point2::new(0, 3), process_list_editor.get_term_view())
-            ]);
-
-            compositor.write().unwrap().push(monstera::make_monstera());
-            compositor.write().unwrap().push(table_port.outer().flatten().offset(Vector2::new(40, 2)));
-
-            process_list_editor.goto(TreeCursor {
-                leaf_mode: ListCursorMode::Insert,
-                tree_addr: vec![ 0 ]
-            });
 
             let tp = term_port.clone();
             async_std::task::spawn(
@@ -222,5 +472,6 @@ async fn main() {
     );
 
     term_writer.show().await.expect("output error!");
+*/
 }