first steps in reactivating pty-list editor

This commit is contained in:
Michael Sippel 2023-11-29 01:23:41 +01:00
parent 85b614a9bb
commit 25d8acdb72
Signed by: senvas
GPG key ID: F96CF119C34B64A6
12 changed files with 191 additions and 119 deletions

View file

@ -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
*/

View file

@ -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() {

View file

@ -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() )
}

View file

@ -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 {

View file

@ -1,5 +1,5 @@
use {
crate::terminal::TerminalStyle,
crate::atom::TerminalStyle,
};
pub fn bg_style_from_depth(depth: usize) -> TerminalStyle {

View file

@ -0,0 +1,3 @@
pub mod color;

View file

@ -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,14 +170,21 @@ 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
}
}
@ -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 {

View file

@ -0,0 +1,3 @@
pub mod list;

View file

@ -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))))
}
}
}