list editor: refactor event handling

This commit is contained in:
Michael Sippel 2023-08-21 14:12:39 +02:00
parent b40992e001
commit 8b47a19f2a
Signed by: senvas
GPG key ID: F96CF119C34B64A6
4 changed files with 172 additions and 231 deletions

View file

@ -26,10 +26,7 @@ impl ObjCommander for CharEditor {
let cmd_obj = cmd_obj.read().unwrap(); let cmd_obj = cmd_obj.read().unwrap();
let cmd_type = cmd_obj.get_type().clone(); let cmd_type = cmd_obj.get_type().clone();
let char_type = (&self.ctx, "( Char )").into(); if cmd_type == (&self.ctx, "( Char )").into() {
//let _term_event_type = (&ctx, "( TerminalEvent )").into();
if cmd_type == char_type {
if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() { if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
let value = cmd_view.get(); let value = cmd_view.get();
@ -66,9 +63,7 @@ impl CharEditor {
pub fn new_node(ctx0: Arc<RwLock<Context>>) -> NestedNode { pub fn new_node(ctx0: Arc<RwLock<Context>>) -> NestedNode {
let data = SingletonBuffer::new('\0'); let data = SingletonBuffer::new('\0');
let ctx = ctx0.clone(); let ctx = ctx0.clone();
let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() })); let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() }));
NestedNode::new( NestedNode::new(

View file

@ -4,7 +4,7 @@ use {
buffer::{singleton::*} buffer::{singleton::*}
}, },
crate::{ crate::{
editors::list::{ListEditor, ListCursorMode}, editors::list::{ListEditor, ListCursor, ListCursorMode},
type_system::{Context, ReprTree}, type_system::{Context, ReprTree},
tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
commander::{ObjCommander} commander::{ObjCommander}
@ -36,8 +36,29 @@ impl ListCmd {
impl ObjCommander for ListEditor { impl ObjCommander for ListEditor {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let cmd_repr = cmd_obj.read().unwrap(); let cmd_repr = cmd_obj.read().unwrap();
if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = NestedNode>>() {
let node = view.get();
let cur = self.cursor.get();
if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() { if let Some(idx) = cur.idx {
match cur.mode {
ListCursorMode::Select => {
*self.data.get_mut(idx as usize) = Arc::new(RwLock::new(node));
TreeNavResult::Exit
}
ListCursorMode::Insert => {
self.insert(Arc::new(RwLock::new(node)));
self.cursor.set(ListCursor{ idx: Some(idx+1), mode: ListCursorMode::Insert });
TreeNavResult::Continue
}
}
} else {
TreeNavResult::Exit
}
}
else if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() {
let cur = self.cursor.get(); let cur = self.cursor.get();
drop(cmd_repr); drop(cmd_repr);
@ -80,9 +101,30 @@ impl ObjCommander for ListEditor {
} }
} }
_ => { ListCmd::Split => {
self.listlist_split();
TreeNavResult::Continue TreeNavResult::Continue
} }
_ => {
eprintln!("list edit: give cmd to child");
match item.send_cmd_obj(cmd_obj) {
TreeNavResult::Continue => TreeNavResult::Continue,
TreeNavResult::Exit => {
TreeNavResult::Continue
/*
match cmd.get() {
ListCmd::Split => {
},
_ => {
TreeNavResult::Exit
}
}
*/
}
}
}
} }
} else { } else {
TreeNavResult::Exit TreeNavResult::Exit
@ -103,7 +145,11 @@ impl ObjCommander for ListEditor {
TreeNavResult::Continue TreeNavResult::Continue
} }
ListCmd::Split => { ListCmd::Split => {
/*
self.split(self.spill_node);
*/
self.listlist_split(); self.listlist_split();
TreeNavResult::Continue TreeNavResult::Continue
} }
ListCmd::Clear => { ListCmd::Clear => {

View file

@ -354,9 +354,13 @@ impl ListEditor {
if let Some(head_editor) = item.editor.get() { if let Some(head_editor) = item.editor.get() {
eprintln!("listlistsplit:editor = {:?}", Arc::into_raw(head_editor.clone()));
let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap(); let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap();
let mut head = head.write().unwrap(); let mut head = head.write().unwrap();
let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap();
if head.data.len() > 0 { if head.data.len() > 0 {
if cur.tree_addr.len() > 2 { if cur.tree_addr.len() > 2 {
eprintln!("call child head listlist split"); eprintln!("call child head listlist split");
@ -364,35 +368,33 @@ impl ListEditor {
eprintln!("return"); eprintln!("return");
} }
eprintln!("got head"); /*
TODO: replace this by: (does not require ListEditor downcast)
head.send_cmd_obj(ListCmd::Split.into_repr());
tail_node = head.spill_buf.clone();
*/
let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap();
head.split( &mut tail_node ); head.split( &mut tail_node );
eprintln!("made split");
head.goto(TreeCursor::none());
drop(head);
eprintln!("done goto");
tail_node.goto(
TreeCursor {
tree_addr: vec![0],
leaf_mode: if cur.tree_addr.len() > 2 {
ListCursorMode::Select
} else {
ListCursorMode::Insert
}
}
);
self.insert(
Arc::new(RwLock::new(tail_node))
);
eprintln!("made insert");
} }
head.goto(TreeCursor::none());
drop(head);
tail_node.goto(
TreeCursor {
tree_addr: vec![0],
leaf_mode: if cur.tree_addr.len() > 2 {
ListCursorMode::Select
} else {
ListCursorMode::Insert
}
}
);
self.insert(
Arc::new(RwLock::new(tail_node))
);
eprintln!("made insert");
} }
} }
} }

View file

@ -137,224 +137,122 @@ impl PTYListController {
self.depth = depth; self.depth = depth;
} }
/* pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
pub fn handle_node_event(&mut self, c: &NestedNode) -> TreeNavResult { let mut e = self.editor.write().unwrap();
match event {
TerminalEvent::Input(Event::Key(Key::Insert)) => {
e.toggle_leaf_mode();
TreeNavResult::Continue
}
_ => TreeNavResult::Continue
}
} }
pub fn handle_char_event(&mut self, c: &char) -> TreeNavResult { pub fn handle_meta_char(&mut self, c: char, child_close_char: Option<char>) -> TreeNavResult {
eprintln!("handle meta char");
let mut e = self.editor.write().unwrap();
let cur = e.cursor.get();
if Some(c) == self.split_char {
e.listlist_split();
TreeNavResult::Continue
} else if Some(c) == child_close_char {
e.goto(TreeCursor::none());
e.cursor.set(ListCursor {
mode: ListCursorMode::Select,
idx: Some(cur.idx.unwrap_or(0))
});
TreeNavResult::Continue
} else {
TreeNavResult::Exit
}
} }
pub fn handle_term_event(&mut self, e: &TerminalEvent) -> TreeNavResult { pub fn handle_any_event(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let mut e = self.editor.write().unwrap();
} let cur = e.cursor.get();
*/ let ctx = e.ctx.clone();
let ctx = ctx.read().unwrap();
match cur.mode {
ListCursorMode::Insert => {
let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
new_edit.goto(TreeCursor::home());
match new_edit.send_cmd_obj(cmd_obj.clone()) {
TreeNavResult::Continue => {
e.insert(Arc::new(RwLock::new(new_edit)));
TreeNavResult::Continue
}
TreeNavResult::Exit => TreeNavResult::Exit
}
},
ListCursorMode::Select => {
if let Some(mut item) = e.get_item_mut() {
eprintln!("PTYList: forward any cmd to current child item");
let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone());
let child_close_char = item.read().unwrap().close_char.get();
eprintln!("PTYList: returned");
match res {
TreeNavResult::Continue => TreeNavResult::Continue,
TreeNavResult::Exit => {
eprintln!("...returned with exit");
// child editor returned control, probably for meta-char handling..
if cmd_obj.read().unwrap().get_type().clone() == ctx.type_term_from_str("( Char )").unwrap() {
let co = cmd_obj.read().unwrap();
if let Some(cmd_view) = co.get_view::<dyn SingletonView<Item = char>>() {
drop(co);
drop(e);
self.handle_meta_char(cmd_view.get(), child_close_char)
} else {
TreeNavResult::Exit
}
} else {
TreeNavResult::Exit
}
}
}
} else {
// cursor selects non existent item
TreeNavResult::Exit
}
}
}
}
} }
use r3vi::view::singleton::SingletonView; use r3vi::view::singleton::SingletonView;
use crate::commander::ObjCommander; use crate::commander::ObjCommander;
impl ObjCommander for PTYListController { impl ObjCommander for PTYListController {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let mut e = self.editor.write().unwrap(); let mut e = self.editor.write().unwrap();
let cur = e.cursor.get(); let cmd_type = cmd_obj.read().unwrap().get_type().clone();
let cur_depth = e.get_cursor().tree_addr.len();
let ctx0 = e.ctx.clone(); if cmd_type == (&e.ctx, "( ListCmd )").into()
let ctx = e.ctx.clone(); || cmd_type == (&e.ctx, "( NestedNode )").into()
let ctx = ctx.read().unwrap(); {
let co = cmd_obj.read().unwrap();
let cmd_type = co.get_type().clone();
let term_event_type = ctx.type_term_from_str("( TerminalEvent )").unwrap();
let list_cmd_type = ctx.type_term_from_str("( ListCmd )").unwrap();
let nested_node_type = ctx.type_term_from_str("( NestedNode )").unwrap();
let char_type = ctx.type_term_from_str("( Char )").unwrap();
if cmd_type == nested_node_type {
eprintln!("got nested node cmd");
if let Some(node_view) = co.get_view::<dyn SingletonView<Item = NestedNode>>() {
if let Some(idx) = cur.idx {
match cur.mode {
ListCursorMode::Select => {
*e.data.get_mut(idx as usize) = Arc::new(RwLock::new(node_view.get()));
TreeNavResult::Exit
}
ListCursorMode::Insert => {
e.insert(Arc::new(RwLock::new(node_view.get())));
e.cursor.set(ListCursor{ idx: Some(idx+1), mode: ListCursorMode::Insert });
TreeNavResult::Continue
}
}
} else {
TreeNavResult::Exit
}
} else {
TreeNavResult::Continue
}
}
else if cmd_type == list_cmd_type {
drop(co);
e.send_cmd_obj( cmd_obj ) e.send_cmd_obj( cmd_obj )
} }
else if cmd_type == term_event_type { else if cmd_type == (&e.ctx, "( TerminalEvent )").into() {
if let Some(te_view) = co.get_view::<dyn SingletonView<Item = TerminalEvent>>() { let co = cmd_obj.read().unwrap();
drop(co); if let Some(view) = co.get_view::<dyn SingletonView<Item = TerminalEvent>>() {
let event = te_view.get(); drop( co );
drop( e );
match event { self.handle_term_event( &view.get(), cmd_obj )
TerminalEvent::Input(Event::Key(Key::Char('\t')))
| TerminalEvent::Input(Event::Key(Key::Insert)) => {
e.toggle_leaf_mode();
e.set_leaf_mode(ListCursorMode::Select);
TreeNavResult::Continue
}
_ => {
if let Some(idx) = cur.idx {
match cur.mode {
ListCursorMode::Insert => {
match event {
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
e.send_cmd_obj( ListCmd::DeletePxev.into_repr_tree(&ctx0) )
}
TerminalEvent::Input(Event::Key(Key::Delete)) => {
e.send_cmd_obj( ListCmd::DeletePxev.into_repr_tree(&ctx0) )
}
_ => {
let mut node = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
node.goto(TreeCursor::home());
node.send_cmd_obj(cmd_obj);
/*
if e.is_listlist() {
if let Some(new_edit) = node.get_edit::<ListEditor>() {
if new_edit.data.len() == 0 {
remove = true;
}
}
}
if ! remove {
*/
e.insert(Arc::new(RwLock::new(node)));
TreeNavResult::Continue
}
}
},
ListCursorMode::Select => {
if let Some(mut item) = e.get_item().clone() {
if e.is_listlist() {
match event {
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
e.send_cmd_obj( ListCmd::DeletePxev.into_repr_tree(&ctx0) )
}
TerminalEvent::Input(Event::Key(Key::Delete)) => {
e.send_cmd_obj( ListCmd::DeleteNexd.into_repr_tree(&ctx0) )
}
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
if Some(c) == self.split_char {
e.listlist_split();
TreeNavResult::Continue
} else {
item.send_cmd_obj(cmd_obj)
}
}
_ => {
item.send_cmd_obj(cmd_obj)
}
}
} else {
item.send_cmd_obj(cmd_obj)
}
} else {
TreeNavResult::Exit
}
}
}
} else {
TreeNavResult::Exit
}
}
}
} else { } else {
TreeNavResult::Exit TreeNavResult::Exit
} }
} }
else { else {
drop(co); drop( e );
match cur.mode { self.handle_any_event( cmd_obj )
ListCursorMode::Insert => {
let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
new_edit.goto(TreeCursor::home());
match new_edit.send_cmd_obj(cmd_obj.clone()) {
TreeNavResult::Continue => {
e.insert(Arc::new(RwLock::new(new_edit)));
TreeNavResult::Continue
}
TreeNavResult::Exit => {
//eprintln!("listedit: exit from insert mode");
TreeNavResult::Exit
}
}
},
ListCursorMode::Select => {
if let Some(mut item) = e.get_item_mut() {
let mut i = item.write().unwrap();
let res = i.send_cmd_obj(cmd_obj.clone());
let close_char = i.close_char.get();
drop(i);
drop(item);
match res {
TreeNavResult::Continue => {
TreeNavResult::Continue
}
TreeNavResult::Exit => {
if cmd_type == char_type {
let co = cmd_obj.read().unwrap();
if let Some(cmd_view) = co.get_view::<dyn SingletonView<Item = char>>() {
drop(co);
let c = cmd_view.get();
if Some(c) == self.split_char {
e.listlist_split();
TreeNavResult::Continue
} else if Some(c) == close_char {
//eprintln!("listedit: exit from select (close)");
//item.goto(TreeCursor::none());
e.cursor.set(ListCursor {
mode: ListCursorMode::Insert,
idx: Some(cur.idx.unwrap_or(0)+1)
});
TreeNavResult::Continue
} else {
//eprintln!("listedit: exit from select mode");
TreeNavResult::Exit
}
} else {
TreeNavResult::Exit
}
} else {
TreeNavResult::Exit
}
}
}
} else {
TreeNavResult::Exit
}
}
}
} }
} }
} }