first steps in reactivating pty-list editor
This commit is contained in:
parent
85b614a9bb
commit
25d8acdb72
12 changed files with 191 additions and 119 deletions
|
@ -7,7 +7,7 @@ extern crate termion;
|
|||
use {
|
||||
cgmath::Vector2,
|
||||
nested::{
|
||||
edit_tree::NestedNode,
|
||||
edit_tree::{NestedNode, TreeCursor, TreeNav},
|
||||
repr_tree::{Context, ReprTree},
|
||||
},
|
||||
nested_tty::{
|
||||
|
@ -17,7 +17,8 @@ use {
|
|||
},
|
||||
r3vi::{
|
||||
buffer::singleton::*,
|
||||
view::{port::UpdateTask, singleton::*, ViewPort},
|
||||
view::{port::UpdateTask, singleton::*, sequence::*, ViewPort},
|
||||
projection::decorate_sequence::*
|
||||
},
|
||||
std::sync::{Arc, Mutex, RwLock},
|
||||
termion::event::{Event, Key},
|
||||
|
@ -26,48 +27,134 @@ use {
|
|||
fn node_make_char_view(
|
||||
node: NestedNode
|
||||
) -> NestedNode {
|
||||
let char_view = node.data
|
||||
.read()
|
||||
.unwrap()
|
||||
.get_port::<dyn SingletonView<Item = char>>()
|
||||
.expect("unable to get Char-view")
|
||||
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
||||
.to_grid();
|
||||
node.display
|
||||
.write().unwrap()
|
||||
.insert_branch(ReprTree::new_leaf(
|
||||
Context::parse(&node.ctx, "TerminalView"),
|
||||
node.data
|
||||
.read()
|
||||
.unwrap()
|
||||
.get_port::<dyn SingletonView<Item = char>>()
|
||||
.expect("unable to get Char-view")
|
||||
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
||||
.to_grid()
|
||||
.into(),
|
||||
));
|
||||
|
||||
let mut display_rt = ReprTree::new(Context::parse(&node.ctx, "Display"));
|
||||
node
|
||||
}
|
||||
|
||||
display_rt.insert_branch(ReprTree::new_leaf(
|
||||
Context::parse(&node.ctx, "TerminalView"),
|
||||
char_view.into(),
|
||||
));
|
||||
fn node_make_list_view(
|
||||
mut node: NestedNode
|
||||
) -> NestedNode {
|
||||
eprintln!("add list display type");
|
||||
node.display
|
||||
.write().unwrap()
|
||||
.insert_branch(ReprTree::new_leaf(
|
||||
Context::parse(&node.ctx, "TerminalView"),
|
||||
|
||||
node.set_view(
|
||||
Arc::new(RwLock::new(display_rt))
|
||||
)
|
||||
node.data
|
||||
.read()
|
||||
.unwrap()
|
||||
.get_port::< dyn SequenceView<Item = NestedNode> >()
|
||||
.expect("unable to get Seq-view")
|
||||
.map(move |char_node| node_make_view(char_node.clone()).display_view() )
|
||||
.wrap(nested_tty::make_label("("), nested_tty::make_label(")"))
|
||||
.to_grid_horizontal()
|
||||
.flatten()
|
||||
.into()
|
||||
));
|
||||
|
||||
// nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") );
|
||||
nested_tty::editors::list::PTYListController::for_node( &mut node, None, None );
|
||||
|
||||
node
|
||||
}
|
||||
|
||||
fn node_make_view(
|
||||
node: NestedNode
|
||||
) -> NestedNode {
|
||||
if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") {
|
||||
node_make_char_view( node )
|
||||
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") {
|
||||
node_make_list_view( node )
|
||||
// node
|
||||
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") {
|
||||
node_make_list_view( node )
|
||||
} else {
|
||||
eprintln!("couldnt add view");
|
||||
node
|
||||
}
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
let app = TTYApplication::new( |ev| { /* event handler */ } );
|
||||
|
||||
/* setup context & create Editor-Tree
|
||||
*/
|
||||
let ctx = Arc::new(RwLock::new(Context::default()));
|
||||
|
||||
let mut node = Context::make_node(
|
||||
|
||||
/* Create a Char-Node with editor & view
|
||||
*/
|
||||
let mut n1 = Context::make_node(
|
||||
&ctx,
|
||||
// node type
|
||||
Context::parse(&ctx, "Char"),
|
||||
// depth
|
||||
SingletonBuffer::new(0).get_port(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// set abstract data
|
||||
node.data = ReprTree::from_char(&ctx, 'Λ');
|
||||
).unwrap();
|
||||
|
||||
// add a display view to the node
|
||||
node = node_make_char_view( node );
|
||||
n1 = node_make_view( n1 );
|
||||
|
||||
/* Create a <List Char>-Node with editor & view
|
||||
*/
|
||||
let mut node2 = Context::make_node(
|
||||
&ctx,
|
||||
// node type
|
||||
Context::parse(&ctx, "<List Char>"),
|
||||
// depth
|
||||
SingletonBuffer::new(0).get_port(),
|
||||
).unwrap();
|
||||
|
||||
// add a display view to the node
|
||||
node2 = node_make_view( node2 );
|
||||
|
||||
/* setup terminal
|
||||
*/
|
||||
let app = TTYApplication::new({
|
||||
/* event handler
|
||||
*/
|
||||
|
||||
let ctx = ctx.clone();
|
||||
let mut node = n1.clone();
|
||||
node.goto(TreeCursor::home());
|
||||
|
||||
|
||||
let node2 = node2.clone();
|
||||
move |ev| {
|
||||
|
||||
if let Some(cmd) =node2.cmd.get() {
|
||||
cmd.write().unwrap().send_cmd_obj(
|
||||
ReprTree::new_leaf(
|
||||
Context::parse(&ctx, "TerminalEvent"),
|
||||
SingletonBuffer::new(ev.clone()).get_port().into()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
match ev {
|
||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||
if let Some(cmd) = node.cmd.get() {
|
||||
cmd.write().unwrap().send_cmd_obj(
|
||||
ReprTree::from_char(&ctx, c)
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* setup display view routed to `app.port`
|
||||
*/
|
||||
|
@ -82,17 +169,21 @@ async fn main() {
|
|||
.offset(Vector2::new(5, 0)),
|
||||
);
|
||||
|
||||
|
||||
let label = ctx.read().unwrap().type_term_to_str( &n1.get_type() );
|
||||
compositor.write().unwrap()
|
||||
.push(nested_tty::make_label("Char").offset(Vector2::new(0, 2)));
|
||||
.push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2)));
|
||||
|
||||
compositor.write().unwrap()
|
||||
.push(node.display_view().offset(Vector2::new(15, 2)));
|
||||
.push(n1.display_view().offset(Vector2::new(15, 2)));
|
||||
|
||||
|
||||
let label2 = ctx.read().unwrap().type_term_to_str( &node2.get_type() );
|
||||
compositor.write().unwrap()
|
||||
.push(nested_tty::make_label( &label2 ).offset(Vector2::new(0, 3)));
|
||||
|
||||
compositor.write().unwrap()
|
||||
.push(nested_tty::make_label("<List Char>").offset(Vector2::new(0, 3)));
|
||||
|
||||
compositor.write().unwrap()
|
||||
.push(nested_tty::make_label("---").offset(Vector2::new(15, 3)));
|
||||
.push(node2.display_view().offset(Vector2::new(15, 3)));
|
||||
|
||||
/* write the changes in the view of `term_port` to the terminal
|
||||
*/
|
||||
|
|
|
@ -73,7 +73,7 @@ pub struct NestedNode {
|
|||
pub data: Arc<RwLock<ReprTree>>,
|
||||
|
||||
/// display view
|
||||
pub view: Option< Arc<RwLock<ReprTree>> >,
|
||||
pub display: Arc<RwLock<ReprTree>>,
|
||||
|
||||
/// diagnostics
|
||||
pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >,
|
||||
|
@ -103,16 +103,17 @@ pub struct NestedNode {
|
|||
impl NestedNode {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self {
|
||||
NestedNode {
|
||||
ctx,
|
||||
data,
|
||||
view: None,
|
||||
display: Arc::new(RwLock::new(ReprTree::new(Context::parse(&ctx, "Display")))),
|
||||
diag: None,
|
||||
depth,
|
||||
editor: SingletonBuffer::new(None),
|
||||
spillbuf: Arc::new(RwLock::new(Vec::new())),
|
||||
cmd: SingletonBuffer::new(None),
|
||||
close_char: SingletonBuffer::new(None),
|
||||
tree_nav: SingletonBuffer::new(None)
|
||||
tree_nav: SingletonBuffer::new(None),
|
||||
|
||||
ctx
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,20 +130,7 @@ impl NestedNode {
|
|||
),
|
||||
SingletonBuffer::new(0).get_port()
|
||||
)
|
||||
/*
|
||||
.set_view(buf.get_port()
|
||||
.map(|c| TerminalAtom::from(c))
|
||||
.to_index()
|
||||
.map_key(
|
||||
|_x| {
|
||||
Point2::new(0, 0)
|
||||
},
|
||||
|p| {
|
||||
if *p == Point2::new(0,0) { Some(()) } else { None }
|
||||
})
|
||||
)
|
||||
*/
|
||||
.set_editor(Arc::new(RwLock::new(buf)))
|
||||
// .set_editor(Arc::new(RwLock::new(buf)))
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,11 +151,6 @@ impl NestedNode {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn set_view(mut self, view: Arc<RwLock<ReprTree>>) -> Self {
|
||||
self.view = Some(view);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
|
||||
self.cmd.set(Some(cmd));
|
||||
self
|
||||
|
@ -189,10 +172,6 @@ impl NestedNode {
|
|||
self.diag.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
||||
pub fn get_view(&self) -> Option< Arc<RwLock<ReprTree>> > {
|
||||
self.view.clone()
|
||||
}
|
||||
|
||||
pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>>
|
||||
where V::Msg: Clone {
|
||||
let ctx = self.ctx.clone();
|
||||
|
@ -245,29 +224,6 @@ impl TreeType for NestedNode {
|
|||
}
|
||||
*/
|
||||
|
||||
/* TODO: remove that at some point
|
||||
*/
|
||||
/*
|
||||
impl TerminalEditor for NestedNode {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.get_view()
|
||||
}
|
||||
|
||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
let buf = SingletonBuffer::new(event.clone());
|
||||
|
||||
if let Some(cmd) = self.cmd.get() {
|
||||
cmd.write().unwrap().send_cmd_obj(
|
||||
ReprTree::new_leaf(
|
||||
self.ctx.read().unwrap().type_term_from_str("TerminalEvent").unwrap(),
|
||||
AnyOuterViewPort::from(buf.get_port())
|
||||
));
|
||||
}
|
||||
|
||||
TerminalEditorResult::Continue
|
||||
}
|
||||
}
|
||||
*/
|
||||
impl TreeNav for NestedNode {
|
||||
fn get_cursor(&self) -> TreeCursor {
|
||||
if let Some(tn) = self.tree_nav.get() {
|
||||
|
|
|
@ -82,13 +82,6 @@ impl CharEditor {
|
|||
),
|
||||
depth
|
||||
)
|
||||
/* todo: move to lib-nested-term
|
||||
.set_view(data
|
||||
.get_port()
|
||||
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
||||
.to_grid()
|
||||
)
|
||||
*/
|
||||
.set_cmd( editor.clone() )
|
||||
.set_editor( editor.clone() )
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use {
|
|||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub struct ListEditor {
|
||||
pub(super) cursor: SingletonBuffer<ListCursor>,
|
||||
pub cursor: SingletonBuffer<ListCursor>,
|
||||
|
||||
// todo: (?) remove RwLock<..> around NestedNode ??
|
||||
pub data: VecBuffer< Arc<RwLock<NestedNode>> >,
|
||||
|
@ -27,10 +27,10 @@ pub struct ListEditor {
|
|||
|
||||
depth: OuterViewPort<dyn SingletonView<Item = usize>>,
|
||||
|
||||
pub(crate) ctx: Arc<RwLock<Context>>,
|
||||
pub ctx: Arc<RwLock<Context>>,
|
||||
|
||||
/// item type
|
||||
pub(super) typ: TypeTerm,
|
||||
pub typ: TypeTerm,
|
||||
}
|
||||
|
||||
impl ListEditor {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use {
|
||||
crate::terminal::TerminalStyle,
|
||||
crate::atom::TerminalStyle,
|
||||
};
|
||||
|
||||
pub fn bg_style_from_depth(depth: usize) -> TerminalStyle {
|
3
lib-nested-tty/src/edit_tree/mod.rs
Normal file
3
lib-nested-tty/src/edit_tree/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
pub mod color;
|
||||
|
|
@ -4,23 +4,24 @@ use {
|
|||
projection::decorate_sequence::*,
|
||||
},
|
||||
nested::{
|
||||
type_system::{Context, ReprTree},
|
||||
repr_tree::{Context, ReprTree},
|
||||
editors::list::*,
|
||||
tree::{TreeCursor, TreeNav, TreeNavResult},
|
||||
tree::NestedNode,
|
||||
PtySegment
|
||||
edit_tree::{TreeCursor, TreeNav, TreeNavResult, NestedNode},
|
||||
},
|
||||
crate::{
|
||||
TerminalEvent, TerminalView, make_label
|
||||
}
|
||||
DisplaySegment,
|
||||
TerminalStyle,
|
||||
TerminalEvent, TerminalView, make_label,
|
||||
edit_tree::color::{bg_style_from_depth, fg_style_from_depth}
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
termion::event::{Event, Key}
|
||||
};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
impl PtySegment for ListSegment {
|
||||
fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
impl DisplaySegment for ListSegment {
|
||||
fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
match self {
|
||||
ListSegment::InsertCursor => {
|
||||
make_label("|")
|
||||
|
@ -32,7 +33,7 @@ impl PtySegment for ListSegment {
|
|||
ListSegment::Item{ editor, cur_dist } => {
|
||||
let e = editor.clone();
|
||||
let cur_dist = *cur_dist;
|
||||
editor.get_view().map_item(move |_pt, atom| {
|
||||
editor.display_view().map_item(move |_pt, atom| {
|
||||
let c = e.get_cursor();
|
||||
let cur_depth = c.tree_addr.len();
|
||||
let select =
|
||||
|
@ -71,7 +72,7 @@ impl PTYListStyle {
|
|||
editor.get_data_port()
|
||||
);
|
||||
let se = seg_seq.read().unwrap();
|
||||
se.get_view().map(move |segment| segment.pty_view())
|
||||
se.get_view().map(move |segment| segment.display_view())
|
||||
}
|
||||
|
||||
pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> {
|
||||
|
@ -83,7 +84,7 @@ impl PTYListStyle {
|
|||
|
||||
seg_seq
|
||||
.get_view()
|
||||
.map(move |segment| segment.pty_view())
|
||||
.map(move |segment| segment.display_view())
|
||||
.separate(make_label(&self.style.1))
|
||||
.wrap(make_label(&self.style.0), make_label(&self.style.2))
|
||||
.to_grid_horizontal()
|
||||
|
@ -91,12 +92,15 @@ impl PTYListStyle {
|
|||
}
|
||||
|
||||
pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) {
|
||||
node.view = Some(
|
||||
Self::new(style)
|
||||
.pty_view(
|
||||
&node.get_edit::<ListEditor>().unwrap().read().unwrap()
|
||||
)
|
||||
);
|
||||
node.display
|
||||
.write().unwrap()
|
||||
.insert_branch(ReprTree::new_leaf(
|
||||
Context::parse(&node.ctx, "TerminalView"),
|
||||
Self::new(style)
|
||||
.pty_view(
|
||||
&node.get_edit::<ListEditor>().unwrap().read().unwrap()
|
||||
).into()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,15 +170,22 @@ impl PTYListController {
|
|||
self.editor.read().unwrap().get_item()
|
||||
}
|
||||
|
||||
pub fn handle_term_event(&mut self, event: &TerminalEvent, _cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
||||
pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
||||
let mut e = self.editor.write().unwrap();
|
||||
match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
||||
e.toggle_leaf_mode();
|
||||
TreeNavResult::Continue
|
||||
}
|
||||
_ => TreeNavResult::Continue
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||
let ctx = e.ctx.clone();
|
||||
drop(e);
|
||||
self.handle_any_event(
|
||||
ReprTree::from_char(&ctx, *c)
|
||||
)
|
||||
}
|
||||
_ => TreeNavResult::Continue
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_meta_char(&mut self, c: char, child_close_char: Option<char>) -> TreeNavResult {
|
||||
|
@ -201,6 +212,7 @@ impl PTYListController {
|
|||
}
|
||||
|
||||
pub fn handle_any_event(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
||||
eprintln!("ANY EVENT");
|
||||
let mut e = self.editor.write().unwrap();
|
||||
let cur = e.cursor.get();
|
||||
let ctx = e.ctx.clone();
|
||||
|
@ -255,7 +267,7 @@ impl PTYListController {
|
|||
}
|
||||
|
||||
use r3vi::view::singleton::SingletonView;
|
||||
use crate::commander::ObjCommander;
|
||||
use nested::editors::ObjCommander;
|
||||
|
||||
impl ObjCommander for PTYListController {
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
||||
|
|
3
lib-nested-tty/src/editors/mod.rs
Normal file
3
lib-nested-tty/src/editors/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
pub mod list;
|
||||
|
|
@ -11,7 +11,8 @@ pub mod ansi_parser;
|
|||
pub mod terminal;
|
||||
pub mod tty_application;
|
||||
|
||||
//pub mod edit_tree;
|
||||
pub mod editors;
|
||||
pub mod edit_tree;
|
||||
//pub mod widgets;
|
||||
|
||||
// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\
|
||||
|
@ -43,11 +44,24 @@ use std::sync::{Arc, RwLock};
|
|||
|
||||
impl DisplaySegment for nested::edit_tree::NestedNode {
|
||||
fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.view.as_ref().unwrap()
|
||||
if let Some( tv_repr ) = self.display
|
||||
.read().unwrap()
|
||||
.descend( Context::parse(&self.ctx, "TerminalView") ).expect("terminal backend not supported by view")
|
||||
.read().unwrap()
|
||||
.get_port::<dyn TerminalView>().unwrap()
|
||||
.descend( Context::parse(&self.ctx, "TerminalView") )
|
||||
{
|
||||
if let Some(port) =
|
||||
tv_repr
|
||||
.read().unwrap()
|
||||
.get_port::<dyn TerminalView>() {
|
||||
port
|
||||
}
|
||||
|
||||
else {
|
||||
make_label("no TerminalView port found")
|
||||
}
|
||||
} else {
|
||||
make_label("TTY Display not supported")
|
||||
.map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((220, 30, 30))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue