225 lines
6.4 KiB
Rust
225 lines
6.4 KiB
Rust
use {
|
|
std::{sync::{Arc, RwLock}, any::Any},
|
|
cgmath::{Vector2, Point2},
|
|
r3vi::{
|
|
view::{View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*},
|
|
buffer::{singleton::*, vec::*}
|
|
},
|
|
laddertypes::{TypeTerm},
|
|
crate::{
|
|
repr_tree::{ReprTree, ReprTreeArc, Context},
|
|
edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}},
|
|
editors::{list::{ListCursorMode}, ObjCommander}
|
|
}
|
|
};
|
|
|
|
#[derive(Clone)]
|
|
pub struct EdittreeDisplay {
|
|
/// display view
|
|
pub view: Arc<RwLock<ReprTree>>,
|
|
|
|
/// diagnostics
|
|
pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >,
|
|
|
|
/// depth
|
|
pub depth: OuterViewPort<dyn SingletonView<Item = usize>>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct EdittreeControl {
|
|
/// abstract editor
|
|
pub editor: SingletonBuffer<
|
|
Option< Arc<dyn Any + Send + Sync> >
|
|
>,
|
|
|
|
pub spillbuf: Arc<RwLock< Vec< ReprTreeArc > >>,
|
|
|
|
/// commander & navigation
|
|
pub cmd: SingletonBuffer<
|
|
Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> >
|
|
>, /// abstract data view
|
|
|
|
pub close_char: SingletonBuffer< Option< char > >,
|
|
|
|
// could be replaced by cmd when TreeNav -CmdObjects are used
|
|
pub tree_nav: SingletonBuffer<
|
|
Option< Arc<RwLock<dyn TreeNav + Send + Sync>> >
|
|
>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct EditTree {
|
|
/// context
|
|
pub ctx: Arc<RwLock<Context>>,
|
|
|
|
/// viewports for terminal display
|
|
pub disp: EdittreeDisplay,
|
|
|
|
/// editor & commander objects
|
|
pub ctrl: EdittreeControl
|
|
}
|
|
|
|
impl EditTree {
|
|
pub fn new(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self {
|
|
EditTree {
|
|
disp: EdittreeDisplay {
|
|
view: ReprTree::new_arc(Context::parse(&ctx, "Display")),
|
|
diag: None,
|
|
depth,
|
|
},
|
|
ctrl: EdittreeControl {
|
|
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),
|
|
},
|
|
ctx
|
|
}
|
|
}
|
|
|
|
pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
|
|
self.ctrl.editor.set(Some(editor));
|
|
self
|
|
}
|
|
|
|
pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
|
|
self.ctrl.cmd.set(Some(cmd));
|
|
self
|
|
}
|
|
|
|
pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
|
|
self.ctrl.tree_nav.set(Some(nav));
|
|
self
|
|
}
|
|
|
|
pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
|
|
self.disp.diag = Some(diag);
|
|
self
|
|
}
|
|
|
|
//\\//\\
|
|
|
|
pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
|
self.disp.diag.clone().unwrap_or(ViewPort::new().into_outer())
|
|
}
|
|
|
|
pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
|
|
if let Some(edit) = self.ctrl.editor.get() {
|
|
if let Ok(edit) = edit.downcast::<RwLock<T>>() {
|
|
Some(edit)
|
|
} else {
|
|
None
|
|
}
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
impl TreeType for NestedNode {
|
|
fn get_type(&self, addr: &TreeAddr) -> TypeLadder {
|
|
if let Some(editor) = self.editor {
|
|
editor.read().unwrap().get_type(addr)
|
|
} else {
|
|
vec![]
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
impl TreeNav for EditTree {
|
|
fn get_cursor(&self) -> TreeCursor {
|
|
if let Some(tn) = self.ctrl.tree_nav.get() {
|
|
tn.read().unwrap().get_cursor()
|
|
} else {
|
|
TreeCursor::default()
|
|
}
|
|
}
|
|
|
|
fn get_addr_view(&self) -> OuterViewPort<dyn SequenceView<Item = isize>> {
|
|
if let Some(tn) = self.ctrl.tree_nav.get() {
|
|
tn.read().unwrap().get_addr_view()
|
|
} else {
|
|
OuterViewPort::default()
|
|
}
|
|
}
|
|
|
|
fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> {
|
|
if let Some(tn) = self.ctrl.tree_nav.get() {
|
|
tn.read().unwrap().get_mode_view()
|
|
} else {
|
|
OuterViewPort::default()
|
|
}
|
|
}
|
|
|
|
fn get_cursor_warp(&self) -> TreeCursor {
|
|
if let Some(tn) = self.ctrl.tree_nav.get() {
|
|
tn.read().unwrap().get_cursor_warp()
|
|
} else {
|
|
TreeCursor::default()
|
|
}
|
|
}
|
|
|
|
fn get_height(&self, op: &TreeHeightOp) -> usize {
|
|
if let Some(tn) = self.ctrl.tree_nav.get() {
|
|
tn.read().unwrap().get_height( op )
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
|
|
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
|
|
if let Some(tn) = self.ctrl.tree_nav.get() {
|
|
tn.write().unwrap().goby(direction)
|
|
} else {
|
|
TreeNavResult::Exit
|
|
}
|
|
}
|
|
|
|
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
|
|
if let Some(tn) = self.ctrl.tree_nav.get() {
|
|
tn.write().unwrap().goto(new_cursor)
|
|
} else {
|
|
TreeNavResult::Exit
|
|
}
|
|
}
|
|
}
|
|
|
|
use crate::edit_tree::nav::TreeNavCmd;
|
|
|
|
impl ObjCommander for EditTree {
|
|
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
|
|
|
if cmd_obj.read().unwrap().get_type() == &Context::parse(&self.ctx, "TreeNavCmd") {
|
|
if let Some(cmd) = cmd_obj.read().unwrap().get_view::<dyn SingletonView<Item = TreeNavCmd>>() {
|
|
match cmd.get() {
|
|
TreeNavCmd::pxev => self.pxev(),
|
|
TreeNavCmd::nexd => self.nexd(),
|
|
TreeNavCmd::qpxev => self.qpxev(),
|
|
TreeNavCmd::qnexd => self.qnexd(),
|
|
|
|
TreeNavCmd::up => self.up(),
|
|
TreeNavCmd::dn => self.dn(),
|
|
|
|
_ => TreeNavResult::Continue
|
|
}
|
|
} else {
|
|
TreeNavResult::Exit
|
|
}
|
|
} else if let Some(cmd) = self.ctrl.cmd.get() {
|
|
// todo: filter out tree-nav cmds and send them to tree_nav
|
|
cmd.write().unwrap().send_cmd_obj(cmd_obj)
|
|
} else {
|
|
TreeNavResult::Exit
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl Diagnostics for EditTree {
|
|
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
|
self.get_diag()
|
|
}
|
|
}
|