//! This example demonstrates how a very simple editor for hexadecimal digits //! can be created with `lib-nested` and the `lib-nested-tty` backend. extern crate cgmath; extern crate nested; extern crate nested_tty; extern crate r3vi; extern crate termion; use { cgmath::Vector2, nested::{ editors::ObjCommander, repr_tree::{Context, ReprTree, ReprTreeExt}, edit_tree::{EditTree} }, nested_tty::{ DisplaySegment, TTYApplication, TerminalCompositor, TerminalStyle, TerminalView, TerminalAtom, TerminalEvent }, r3vi::{ buffer::{singleton::*, vec::*}, view::{port::UpdateTask, list::*} }, std::sync::{Arc, RwLock}, }; #[async_std::main] async fn main() { /* setup context & create Editor-Tree */ let ctx = Arc::new(RwLock::new(Context::new())); nested::editors::char::init_ctx( ctx.clone() ); nested::editors::digit::init_ctx( ctx.clone() ); nested::editors::integer::init_ctx( ctx.clone() ); nested::editors::list::init_ctx( ctx.clone() ); nested_tty::setup_edittree_hook(&ctx); /* structure of Repr-Tree * * === Repr-Tree === * * <Digit 10> * / | \ * / | \ * / | \ * u64 EditTree Char * - Editor \ * - Display EditTree * / | \ - Editor * / | \ - Display * TTY PixelBuf SDF / | \ * / | \ * TTY PixelBuf SDF */ let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") ); /* add initial representation * <Digit 16> ~ Char */ rt_digit.insert_leaf( Context::parse(&ctx, "Char"), nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) ); /* furthermore, setup projections to and from u8 value, * this synchronizes the buffers */ ctx.read().unwrap().apply_morphism( &rt_digit, &laddertypes::MorphismType { src_type: Context::parse(&ctx, "<Digit 16>~Char"), dst_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64") } ); ctx.read().unwrap().apply_morphism( &rt_digit, &laddertypes::MorphismType { src_type: Context::parse(&ctx, "<Digit 16>~Char"), dst_type: Context::parse(&ctx, "<Digit 16>~EditTree") } ); /* setup terminal */ let app = TTYApplication::new({ /* event handler */ let ctx = ctx.clone(); let digit_edittree = rt_digit.edittree( &ctx ); move |ev| { digit_edittree.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); } }); /* setup display view routed to `app.port` */ let compositor = TerminalCompositor::new(app.port.inner()); // add some views to the display compositor { let mut comp = compositor.write().unwrap(); comp.push( nested_tty::make_label("Hello World") .map_item(|p, a| { a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0))) }) .offset(Vector2::new(5,0))); let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); comp.push( nested_tty::make_label(&label_str) .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) .offset(Vector2::new(1,1))); comp.push(rt_digit .edittree( &ctx ).get().read().unwrap() .display_view() .offset(Vector2::new(3,2))); comp.push(rt_digit .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap() .view_u64() .map(|d| nested_tty::make_label(&format!("Digit value={}", d))) .to_grid() .flatten() .offset(Vector2::new(5,3))); } /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); }