From 47a35f22b7a0c1e68468524891c9ed5264c22e32 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 6 Jan 2024 17:04:15 +0100
Subject: [PATCH] some work on repr tree example

---
 examples/tty-02-node/src/main.rs              | 214 +++++++++---------
 lib-nested-core/src/editors/char/mod.rs       |  11 +-
 lib-nested-core/src/editors/integer/editor.rs |  44 ++--
 lib-nested-core/src/editors/mod.rs            |   3 +-
 lib-nested-core/src/repr_tree/mod.rs          |  11 +-
 lib-nested-tty/src/editors/mod.rs             |  38 +++-
 6 files changed, 170 insertions(+), 151 deletions(-)

diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs
index d041723..53f82bb 100644
--- a/examples/tty-02-node/src/main.rs
+++ b/examples/tty-02-node/src/main.rs
@@ -14,6 +14,7 @@ use {
     nested_tty::{
         DisplaySegment, TTYApplication,
         TerminalCompositor, TerminalStyle, TerminalView,
+        TerminalAtom
     },
     r3vi::{
         buffer::{singleton::*, vec::*},
@@ -21,112 +22,126 @@ use {
     std::sync::{Arc, RwLock},
 };
 
-/*
-struct ParseDigit { radix: u32 }
-impl Morphism for ParseDigit {
-    fn new(
-        ctx: &Arc<RwLock<Context>>
-    ) -> Self {
-        
-    }
-
-    fn setup_projection(&self, repr_tree: Arc<RwLock<ReprTree>>) {
-        if let Some( char_view ) = repr_tree.get_out(Context::parse(&ctx, "Char~")) {
-            
-        }
-    }
-}
-
-get_morphism( ) -> Morphism {
-    
-}
-*/
 #[async_std::main]
 async fn main() {
     /* setup context & create Editor-Tree
      */
     let ctx = Arc::new(RwLock::new(Context::new()));
 
-    /* Create a Char-Node with editor & view
+    /* structure of Repr-Tree
+     *
+     *   === Repr-Tree ===
+     *
+     *        <Digit 10>
+     *         /   |     \
+     *        /    |        \
+     *       /     |          \
+     *     u32  [ EditTree ]  Char
+     *           - Editor         \
+     *           - Display      [ EditTree ]
+     *         /     |    \      - Editor
+     *        /      |     \     - Display
+     *      TTY  PixelBuf  SDF  /    |     \
+     *                         /     |      \
+     *                       TTY  PixelBuf  SDF
+     */
+    let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 10>") );
+    let port_char = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = char>>::new();
+    let port_u32 = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = u32>>::new();
+    let port_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = NestedNode>>::new();
+    let port_char_edit = r3vi::view::ViewPort::<dyn r3vi::view::singleton::SingletonView<Item = NestedNode>>::new();
+
+    rt_digit.write().unwrap()
+        .insert_leaf(
+            vec![ Context::parse(&ctx, "Char") ].into_iter(),
+            port_char.outer().into()
+        );
+
+    rt_digit.write().unwrap()
+        .insert_leaf(
+            vec![ Context::parse(&ctx, "Char"), Context::parse(&ctx, "EditTree") ].into_iter(),
+            port_char_edit.outer().into()
+        );
+
+    rt_digit.write().unwrap()
+        .insert_leaf(
+            vec![ Context::parse(&ctx, "EditTree") ].into_iter(),
+            port_edit.outer().into()
+        );
+
+    rt_digit.write().unwrap()
+        .insert_leaf(
+            vec![ Context::parse(&ctx, "u32") ].into_iter(),
+            port_u32.outer().into()
+        );
+
+    /* setup projections between representations
      */
 
-    let mut char_obj = ReprTree::make_leaf(
-        Context::parse(&ctx, "Char"),
-        SingletonBuffer::new('X').get_port().into()
-    );
+    // created by  Char  ==>  Char~EditTree
+    let mut edittree_char =
+        nested::editors::char::CharEditor::new_edit_tree(
+            ctx.clone(),
+            r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
+        );
+
+    node_edit_char = nested_tty::editors::edittree_make_char_view( edittree_char );
+    let mut edit_char = node_edit_char.get_edit::< nested::editors::char::CharEditor >().unwrap();
+    port_char.attach_to( edit_char.read().unwrap().get_port() );
+
+    let buf_edit_char = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_char.clone() );
+    port_char_edit.attach_to( buf_edit_char.get_port() );
+
+
+
+    // created by   <Digit 10>   ==>  <Digit 10>~EditTree
+    let mut node_edit_digit =
+        nested::editors::integer::DigitEditor::new(
+            ctx.clone(),
+            16
+        ).into_node(
+            r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
+        );
+
+    node_edit_digit = nested_tty::editors::edittree_make_digit_view( node_edit_digit );
+    let mut edit_digit = node_edit_digit.get_edit::< nested::editors::integer::DigitEditor >().unwrap();
+
+    // created by   <Digit 10> ==> <Digit 10>~U32
+    port_u32.attach_to(  port_char.outer().map(|c| c.to_digit(16).unwrap_or(0)) );
+ //    port_u32.attach_to( edit_digit.read().unwrap().get_data_port().map(|d| d.unwrap_or(0)) );
+
+    let port_proj_u32_to_char = port_u32.outer().map(|val| char::from_digit(val, 16).unwrap_or('?') );
+    
+    let buf_edit_digit = r3vi::buffer::singleton::SingletonBuffer::new( node_edit_digit );
+    port_edit.attach_to( buf_edit_digit.get_port() );
+
 /*
-    char_obj.insert_branch(
-        Context::parse(&ctx, "EditTree"),
-        SingletonBuffer::new(
-            NestedNode::new()
+    ctx.write().unwrap()
+        .morphisms
+        .add_morphism(
+            MorphismType {
+                src_type: Context::parse(&ctx, "Char"),
+                dst_type: Context::parse(&ctx, "Char~EditTree")
+            },
+
+            |rt, _σ| {
+                rt.write().unwrap()
+                    .insert_branch(
+                        Context::parse(&ctx, "")
+                    );
+            }
         )
-    );
-
-    let mut vec_obj = ReprTree::make_leaf(
-        Context::parse(&ctx, "<Vec Char>"),
-        VecBuffer::new(vec!['a', 'b', 'c']).get_port().into()
-    );
-
-    let mut char_edit = Context::new_edit_tree(
-        &ctx,
-        // node type
-        Context::parse(&ctx, "Char"),
-        // depth
-        SingletonBuffer::new(0).get_port(),
-    )
-    .unwrap();
 */
-    // add a display view to the node
-    //node1 = nested_tty::editors::node_make_tty_view(node1);
 
-    /* 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 = nested_tty::editors::node_make_tty_view(node2);
-
-    /* Create a <List Char>-Node with editor & view
-     */
-/*
-    let mut node3 = Context::make_node(
-        &ctx,
-        // node type
-        Context::parse(&ctx, "<List <List Char>>"),
-        // depth
-        SingletonBuffer::new(0).get_port(),
-    )
-    .unwrap();
-*/
-    // add a display view to the node
-    //node3 = nested_tty::editors::node_make_tty_view(node3);
- 
     /* setup terminal
      */
     let app = TTYApplication::new({
         /* event handler
          */
-
         let ctx = ctx.clone();
- //       let node1 = node1.clone();
-//        let node2 = node2.clone();
-//        let node3 = node3.clone();
+        let node1 = buf_edit_digit.clone();
         move |ev| {
-//            let mut node1 = node1.clone();
-//            let mut node2 = node2.clone();
-//            let mut node3 = node3.clone();
-//            node1.send_cmd_obj(ev.to_repr_tree(&ctx));
-//            node2.send_cmd_obj(ev.to_repr_tree(&ctx));
-//            node3.send_cmd_obj(ev.to_repr_tree(&ctx));
+            node1.get().send_cmd_obj(ev.to_repr_tree(&ctx));
         }
     });
 
@@ -142,6 +157,7 @@ async fn main() {
             })
             .offset(Vector2::new(5, 0)),
     );
+    compositor.write().unwrap().push( buf_edit_digit.get().display_view().offset(Vector2::new(0,2)) );
 
 /*    let label = ctx.read().unwrap().type_term_to_str(&node1.get_type());
     compositor
@@ -153,30 +169,6 @@ async fn main() {
         .write()
         .unwrap()
         .push(node1.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(node2.display_view().offset(Vector2::new(15, 3)));
-
-
-    let label3 = ctx.read().unwrap().type_term_to_str(&node3.get_type());
-    compositor
-        .write()
-        .unwrap()
-        .push(nested_tty::make_label(&label3).offset(Vector2::new(0, 4)));
-
-    compositor
-        .write()
-        .unwrap()
-        .push(node3.display_view().offset(Vector2::new(25, 4)));
 */
     /* write the changes in the view of `term_port` to the terminal
      */
diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs
index 40ea021..12614f1 100644
--- a/lib-nested-core/src/editors/char/mod.rs
+++ b/lib-nested-core/src/editors/char/mod.rs
@@ -71,19 +71,16 @@ impl CharEditor {
         self.get_port().get_view().unwrap().get()
     }
 
-    pub fn new_node(ctx0: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode {
+    pub fn new_edit_tree(
+        ctx0: Arc<RwLock<Context>>,
+        depth: OuterViewPort<dyn SingletonView<Item = usize>>
+    ) -> NestedNode {
         let data = SingletonBuffer::new('\0');
         let ctx = ctx0.clone();
         let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() }));
 
         NestedNode::new(
             ctx0.clone(),
-            /*
-            ReprTree::new_leaf(
-                ctx0.read().unwrap().type_term_from_str("Char").unwrap(),
-                data.get_port().into()
-            ),
-            */
             depth
         )
             .set_cmd( editor.clone() )
diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs
index 91d068d..e37f495 100644
--- a/lib-nested-core/src/editors/integer/editor.rs
+++ b/lib-nested-core/src/editors/integer/editor.rs
@@ -49,9 +49,7 @@ impl ObjCommander for DigitEditor {
                     /* in case the character c is not in the range of digit-chars,
                        add a message to the diagnostics view
                      */
-
 /*
-
                     let message = IndexBuffer::from_iter(vec![
                         (Point2::new(1, 0), make_label("invalid digit '")),
                         (Point2::new(2, 0), make_label(&format!("{}", c))
@@ -61,7 +59,7 @@ impl ObjCommander for DigitEditor {
 
                     self.msg.push(crate::diagnostics::make_error(message.get_port().flatten()));
 */
-                    
+
                     self.data.set(Some(c));
                 } else {
                     self.data.set(Some(c));
@@ -89,34 +87,33 @@ impl DigitEditor {
         let ed = editor.write().unwrap();
         let r = ed.radix;
 
-        NestedNode::new(ed.ctx.clone(), /*data,*/ depth)
+        NestedNode::new(ed.ctx.clone(), depth)
+            .set_editor(editor.clone())
             .set_cmd(editor.clone())
-            /*
-            .set_view(
-                ed.data
-                    .get_port()
-                    .map(move |c| {
-                        TerminalAtom::new(
-                            c.unwrap_or('?'),
-                            if c.unwrap_or('?').to_digit(r).is_some() {
-                                TerminalStyle::fg_color((90, 160, 90))
-                            } else {
-                                //TerminalStyle::bg_color((90, 10, 10))
-                                TerminalStyle::fg_color((200, 40, 40))
-                            },
-                        )
-                    })
-                    .to_grid()
-            )
             .set_diag(
                 ed.msg.get_port().to_sequence()
             )
+    }
+
+    pub fn attach_to(&mut self, source: OuterViewPort<dyn SingletonView<Item = u32>>) {
+        /*
+        source.add_observer(
+            Arc::new(NotifyFnObserver::new(|_msg| {
+                self.data.set( source.get() )
+            }))
+        );
         */
     }
 
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> {
         let radix = self.radix;
-        self.data.get_port().map(move |c| c?.to_digit(radix))
+        self.data.get_port().map(move |c|
+            if let Some(d) = c.unwrap_or('?').to_digit(radix) {
+                Ok(d)
+            } else {
+                Err(c.unwrap_or('?'))
+            }
+        )
     }
 
     pub fn get_type(&self) -> TypeTerm {
@@ -134,7 +131,6 @@ impl DigitEditor {
     }
 }
 
-
 pub struct PosIntEditor {
     radix: u32,
     digits: NestedNode,
diff --git a/lib-nested-core/src/editors/mod.rs b/lib-nested-core/src/editors/mod.rs
index eebac4e..3a720c3 100644
--- a/lib-nested-core/src/editors/mod.rs
+++ b/lib-nested-core/src/editors/mod.rs
@@ -4,7 +4,7 @@ pub mod list;
 //pub mod sum;
 
 pub mod char;
-//pub mod integer;
+pub mod integer;
 //pub mod typeterm;
 
 
@@ -24,3 +24,4 @@ pub trait ObjCommander {
     fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult;
 }
 
+
diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs
index dc6e7d9..bd62527 100644
--- a/lib-nested-core/src/repr_tree/mod.rs
+++ b/lib-nested-core/src/repr_tree/mod.rs
@@ -7,7 +7,7 @@ pub use {
 };
 
 use {
-    r3vi::view::{AnyOuterViewPort, OuterViewPort, View},
+    r3vi::view::{AnyOuterViewPort, OuterViewPort, View, singleton::*},
     laddertypes::{TypeTerm},
     std::{
         collections::HashMap,
@@ -99,7 +99,14 @@ impl ReprTree {
 
     //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
-    
+
+    pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
+        self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available")
+    }
+
+    pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> {
+        self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available")
+    }
 
     pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
     where
diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs
index 3d2a7b4..4839841 100644
--- a/lib-nested-tty/src/editors/mod.rs
+++ b/lib-nested-tty/src/editors/mod.rs
@@ -13,22 +13,22 @@ use {
     crate::{
         make_label,
         DisplaySegment,
-        atom::TerminalAtom
+        atom::{TerminalAtom, TerminalStyle}
     }
 };
-/*
-pub fn node_make_char_view(
+
+pub fn edittree_make_char_view(
     node: NestedNode
 ) -> NestedNode {
     node.disp.view
         .write().unwrap()
         .insert_branch(ReprTree::new_leaf(
             Context::parse(&node.ctx, "TerminalView"),
-            node.data
+            node.get_edit::< nested::editors::char::CharEditor >()
+                .unwrap()
                 .read()
                 .unwrap()
-                .get_port::<dyn SingletonView<Item = char>>()
-                .expect("unable to get Char-view")
+                .get_port()
                 .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
                 .to_grid()
                 .into(),
@@ -37,6 +37,32 @@ pub fn node_make_char_view(
     node
 }
 
+pub fn edittree_make_digit_view(
+    node: NestedNode
+) -> NestedNode {
+    node.disp.view
+        .write().unwrap()
+        .insert_branch(ReprTree::new_leaf(
+            Context::parse(&node.ctx, "TerminalView"),
+            node.get_edit::< nested::editors::integer::DigitEditor >()
+                .unwrap()
+                .read()
+                .unwrap()
+                .get_data_port()
+                .map(move |digit|
+                    match digit {
+                        Ok(digit) => TerminalAtom::new( char::from_digit(digit, 16).unwrap_or('?'), TerminalStyle::fg_color((220, 220, 0)) ),
+                        Err(c) => TerminalAtom::new( c, TerminalStyle::fg_color((220, 0, 0)) )
+                    }
+                )
+                .to_grid()
+                .into(),
+        ));
+
+    node
+}
+
+/*
 pub fn node_make_seq_view(
     mut node: NestedNode
 ) -> NestedNode {