lib-nested/examples/tty-04-posint/src/main.rs
2025-03-10 18:19:09 +01:00

188 lines
6.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! In the following example, a <List Char> editor
//! as before is used, but its data is morphed into
//! representing a positional integer which is then
//! projected into different radices and displayed
//! in different views on screen
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, ReprTreeBuilder, ReprTree, ReprTreeExt, ReprLeaf},
edit_tree::{EditTree, TreeNav, TreeCursor}
},
nested_tty::{
DisplaySegment, TTYApplication,
TerminalCompositor, TerminalStyle, TerminalView,
TerminalAtom, TerminalEvent,
edit_tree::cursor_widget::TreeNavExt
},
r3vi::{
buffer::{singleton::*, vec::*},
view::{port::UpdateTask, ViewPort, singleton::*, list::*, sequence::*},
projection::*
},
std::sync::{Arc, RwLock},
};
#[async_std::main]
async fn main() {
/* setup context
*/
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);
/* Create a Representation-Tree of type ``
* with a specific representation-path (big-endian hexadecimal string)
*/
let int_builder = ReprTreeBuilder::new( ctx.clone() )
.require(Context::parse(&ctx,
//" ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>> ~
"<List <Digit 16>> ~ <List Char> ~ EditTree"))
/*
.require(Context::parse(&ctx,
" ~ <PosInt 10 BigEndian> ~ EditTree"))
.require(Context::parse(&ctx,
" ~ <PosInt 8 BigEndian> ~ EditTree"))
.require(Context::parse(&ctx,
" ~ <PosInt 2 BigEndian> ~ EditTree"))
*/
;
let mut rt_int = nested::repr_tree::ReprTree::from_str("3");
rt_int.write().unwrap().set_halo(
/* HALO TYPE (append to top of type ladder) */
Context::parse(&ctx, /*"
~ <PosInt 16 BigEndian>
~ <Seq <Digit 16>>
~ <List <Digit 16>>
*/
" <List <Digit 16>>
~ <List Char>
")
);
rt_int = int_builder.build_from( rt_int )
.expect("cant build initial repr tree");
eprintln!("rt_int = \n{}\n", rt_int.read().unwrap().fmt(&ctx, 0));
/* list of editors
*/
let mut list_editor = nested::editors::list::ListEditor::new(
ctx.clone(),
Context::parse(&ctx, "EditTree"),
ReprTreeBuilder::new(ctx.clone())
);
// add all desired editors to the list
for edit_leaf in int_builder.required_leaves.iter() {
let leaf_rt = rt_int.descend(edit_leaf.clone()).unwrap();
list_editor.data.push(leaf_rt);
}
let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port());
nested_tty::editors::list::PTYListController::for_node(&mut edittree, None, None);
/* cursors are a bit screwed initially so fix them up
* TODO: how to fix this generally?
*/
for edit_leaf in int_builder.required_leaves.iter() {
let leaf_rt = rt_int.descend(edit_leaf.clone()).unwrap();
leaf_rt.edittree(&ctx).get_mut().goto(TreeCursor::none());
}
let first_idx : usize = 0;
int_builder.update( &rt_int, int_builder.required_leaves[first_idx].clone() );
edittree.goto(TreeCursor {
leaf_mode: nested::editors::list::ListCursorMode::Insert,
tree_addr: vec![first_idx as isize, 0]
});
let edittree = Arc::new(RwLock::new(edittree));
/* setup terminal
*/
let app = TTYApplication::new({
/* event handler
*/
let ctx = ctx.clone();
let rt_int = rt_int.clone();
let last_idx = RwLock::new(first_idx);
let int_builder = int_builder.clone();
let edittree = edittree.clone();
move |ev| {
let cur = edittree.read().unwrap().get_cursor();
if cur.tree_addr.len() > 0 {
let mut li = last_idx.write().unwrap();
let ci = cur.tree_addr[0];
if *li != ci as usize {
int_builder.update( &rt_int, int_builder.required_leaves[ci as usize].clone() );
*li = ci as usize;
}
}
edittree.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx));
}
});
/* Setup the compositor to serve as root-view
* by routing it to the `app.port` Viewport,
* so it will be displayed on TTY-output.
*/
let compositor = TerminalCompositor::new(app.port.inner());
/* Now add some views to our compositor
*/
{
let mut comp = compositor.write().unwrap();
let et = edittree.read().unwrap();
comp.push(et.get_cursor_widget());
fn show_edit_tree( ctx: &Arc<RwLock<Context>>, comp: &mut TerminalCompositor, rt: &Arc<RwLock<ReprTree>>, y: i16 )
{
let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend");
let halo_type = rt_edittree.read().unwrap().get_halo_type().clone();
let edittree = rt_edittree.edittree( &ctx );
let box_port = ViewPort::new();
let ascii_box = nested_tty::widgets::ascii_box::AsciiBox::new(
Vector2::new(30, 1),
edittree.get().display_view(),
box_port.inner()
);
comp.push(
box_port.outer()
.offset(Vector2::new(1,y)));
comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) )
.map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
.offset(Vector2::new(1,y)));
}
let mut y = 2;
for t in int_builder.required_leaves.iter() {
show_edit_tree(&ctx, &mut comp, &rt_int.descend(t.clone()).expect(""), y);
y += 4;
}
}
/* write the changes in the view of `term_port` to the terminal
*/
app.show().await.expect("output error!");
}