TreeNav trait
adapt ListEditor and StringEditor
This commit is contained in:
parent
127c43bca0
commit
603034a065
5 changed files with 393 additions and 208 deletions
|
@ -12,6 +12,8 @@ pub mod terminal;
|
||||||
pub mod integer;
|
pub mod integer;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
|
|
||||||
|
pub mod tree_nav;
|
||||||
|
|
||||||
pub mod string_editor;
|
pub mod string_editor;
|
||||||
pub mod leveled_term_view;
|
pub mod leveled_term_view;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ use {
|
||||||
Context
|
Context
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor},
|
||||||
projection::ProjectionHelper,
|
projection::ProjectionHelper,
|
||||||
singleton::{SingletonView, SingletonBuffer},
|
singleton::{SingletonView, SingletonBuffer},
|
||||||
sequence::{SequenceView},
|
sequence::{SequenceView},
|
||||||
|
@ -62,8 +63,221 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
||||||
segment_seq: OuterViewPort<dyn SequenceView<Item = ListEditorViewSegment>>,
|
segment_seq: OuterViewPort<dyn SequenceView<Item = ListEditorViewSegment>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<SubEditor, FnMakeItemEditor> TreeNav for ListEditor<SubEditor, FnMakeItemEditor>
|
||||||
|
where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
|
FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
|
||||||
|
{
|
||||||
|
fn up(&mut self) -> TreeNavResult {
|
||||||
|
match self.cursor.get() {
|
||||||
|
ListEditorCursor::Edit(idx) => {
|
||||||
|
let ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
match cur_edit.up() {
|
||||||
|
TreeNavResult::Exit => {
|
||||||
|
self.cursor.set(ListEditorCursor::Select(idx));
|
||||||
|
}
|
||||||
|
TreeNavResult::Continue => {}
|
||||||
|
}
|
||||||
|
TreeNavResult::Continue
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto(&mut self, tree_addr: Vec<usize>) -> TreeNavResult {
|
||||||
|
if tree_addr.len() == 1 {
|
||||||
|
if tree_addr[0] < self.data.len() {
|
||||||
|
match self.cursor.get() {
|
||||||
|
ListEditorCursor::None |
|
||||||
|
ListEditorCursor::Select(_) => {
|
||||||
|
self.cursor.set(ListEditorCursor::Select(tree_addr[0]));
|
||||||
|
}
|
||||||
|
ListEditorCursor::Insert(_) => {
|
||||||
|
self.cursor.set(ListEditorCursor::Insert(tree_addr[0]));
|
||||||
|
}
|
||||||
|
ListEditorCursor::Edit(_) => {
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(tree_addr[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
} else if tree_addr.len() > 0 {
|
||||||
|
if tree_addr[0] < self.data.len() {
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(tree_addr[0]));
|
||||||
|
|
||||||
|
let ce = self.data.get_mut(tree_addr[0]);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
cur_edit.goto(tree_addr[1..].iter().cloned().collect());
|
||||||
|
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto_end(&mut self) -> TreeNavResult {
|
||||||
|
match self.cursor.get() {
|
||||||
|
ListEditorCursor::None |
|
||||||
|
ListEditorCursor::Insert(_) |
|
||||||
|
ListEditorCursor::Select(_) =>
|
||||||
|
self.goto(vec![ self.data.len()-1 ]),
|
||||||
|
ListEditorCursor::Edit(idx) => {
|
||||||
|
let ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
match cur_edit.goto_end() {
|
||||||
|
TreeNavResult::Continue => TreeNavResult::Continue,
|
||||||
|
TreeNavResult::Exit => {
|
||||||
|
if idx+1 < self.data.len() {
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
||||||
|
self.data.get_mut(idx+1).write().unwrap().goto_end();
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto_home(&mut self) -> TreeNavResult {
|
||||||
|
match self.cursor.get() {
|
||||||
|
ListEditorCursor::None |
|
||||||
|
ListEditorCursor::Insert(_) |
|
||||||
|
ListEditorCursor::Select(_) => self.goto(vec![ 0 ]),
|
||||||
|
ListEditorCursor::Edit(idx) => {
|
||||||
|
let ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
match cur_edit.goto_home() {
|
||||||
|
TreeNavResult::Continue => TreeNavResult::Continue,
|
||||||
|
TreeNavResult::Exit => {
|
||||||
|
if idx > 0 {
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(idx-1));
|
||||||
|
self.data.get_mut(idx-1).write().unwrap().goto_home();
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.up();
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dn(&mut self) -> TreeNavResult {
|
||||||
|
match self.cursor.get() {
|
||||||
|
ListEditorCursor::Select(idx) => {
|
||||||
|
self.data.get_mut(idx).write().unwrap().goto_home();
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(idx));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
TreeNavResult::Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pxev(&mut self) -> TreeNavResult {
|
||||||
|
match self.cursor.get() {
|
||||||
|
ListEditorCursor::None => TreeNavResult::Exit,
|
||||||
|
ListEditorCursor::Insert(idx) => {
|
||||||
|
if idx > 0 {
|
||||||
|
self.cursor.set(ListEditorCursor::Insert(idx-1));
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListEditorCursor::Select(idx) => {
|
||||||
|
if idx > 0 {
|
||||||
|
self.cursor.set(ListEditorCursor::Select(idx-1));
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListEditorCursor::Edit(idx) => {
|
||||||
|
let ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
match cur_edit.pxev() {
|
||||||
|
TreeNavResult::Exit => {
|
||||||
|
if idx > 0 {
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(idx-1));
|
||||||
|
self.data.get_mut(idx-1).write().unwrap().goto_end();
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TreeNavResult::Continue => TreeNavResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nexd(&mut self) -> TreeNavResult {
|
||||||
|
match self.cursor.get() {
|
||||||
|
ListEditorCursor::None => TreeNavResult::Exit,
|
||||||
|
ListEditorCursor::Insert(idx) => {
|
||||||
|
if idx < self.data.len() {
|
||||||
|
self.cursor.set(ListEditorCursor::Insert(idx+1));
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListEditorCursor::Select(idx) => {
|
||||||
|
if idx+1 < self.data.len() {
|
||||||
|
self.cursor.set(ListEditorCursor::Select(idx + 1));
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListEditorCursor::Edit(idx) => {
|
||||||
|
let ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
match cur_edit.nexd() {
|
||||||
|
TreeNavResult::Exit => {
|
||||||
|
if idx+1 < self.data.len() {
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
||||||
|
self.data.get_mut(idx+1).write().unwrap().goto_home();
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {//if idx+1 == self.data.len() {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TreeNavResult::Continue => TreeNavResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<SubEditor, FnMakeItemEditor> TerminalEditor for ListEditor<SubEditor, FnMakeItemEditor>
|
impl<SubEditor, FnMakeItemEditor> TerminalEditor for ListEditor<SubEditor, FnMakeItemEditor>
|
||||||
where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
|
FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
|
||||||
{
|
{
|
||||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
|
@ -72,144 +286,51 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
match self.cursor.get() {
|
match self.cursor.get() {
|
||||||
ListEditorCursor::None => {
|
|
||||||
|
|
||||||
}
|
|
||||||
ListEditorCursor::Insert(idx) => {
|
ListEditorCursor::Insert(idx) => {
|
||||||
|
self.data.insert(idx, (self.make_item_editor)());
|
||||||
|
|
||||||
|
let mut ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
cur_edit.goto_home();
|
||||||
|
self.cursor.set(ListEditorCursor::Edit(idx));
|
||||||
|
cur_edit.handle_terminal_event(event);
|
||||||
|
}
|
||||||
|
ListEditorCursor::Edit(idx) => {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
TerminalEvent::Input(Event::Key(Key::Char(' '))) => {
|
||||||
self.cursor.set(ListEditorCursor::Select(idx));
|
// split..
|
||||||
}
|
self.data.insert(idx+1, (self.make_item_editor)());
|
||||||
TerminalEvent::Input(Event::Key(Key::Left)) => {
|
self.data.get_mut(idx).write().unwrap().goto_end();
|
||||||
if idx > 0 {
|
self.data.get_mut(idx+1).write().unwrap().goto_home();
|
||||||
self.cursor.set(ListEditorCursor::Insert(idx-1));
|
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Right)) => {
|
|
||||||
if idx < self.data.len() {
|
|
||||||
self.cursor.set(ListEditorCursor::Insert(idx+1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
event => {
|
event => {
|
||||||
self.data.insert(idx, (self.make_item_editor)());
|
let mut ce = self.data.get_mut(idx);
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx));
|
let mut cur_edit = ce.write().unwrap();
|
||||||
self.data.get_mut(idx).write().unwrap().handle_terminal_event(event);
|
|
||||||
|
cur_edit.handle_terminal_event(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListEditorCursor::Select(idx) => {
|
ListEditorCursor::Select(idx) => {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
||||||
self.cursor.set(ListEditorCursor::Insert(idx));
|
|
||||||
}
|
}
|
||||||
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||||
self.data.remove(idx);
|
self.data.remove(idx);
|
||||||
|
|
||||||
if self.data.len() == 0 {
|
if self.data.len() == 0 {
|
||||||
self.cursor.set(ListEditorCursor::Insert(0));
|
self.cursor.set(ListEditorCursor::Insert(0));
|
||||||
} else if idx == self.data.len() && idx > 0 {
|
} else if idx == self.data.len() {
|
||||||
self.cursor.set(ListEditorCursor::Select(idx-1))
|
self.cursor.set(ListEditorCursor::Select(idx-1));
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Home)) => {
|
|
||||||
if self.data.len() > 0 {
|
|
||||||
self.cursor.set(ListEditorCursor::Select(0))
|
|
||||||
} else {
|
|
||||||
self.cursor.set(ListEditorCursor::Insert(0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::End)) => {
|
|
||||||
if self.data.len() > 0 {
|
|
||||||
self.cursor.set(ListEditorCursor::Select(self.data.len() - 1))
|
|
||||||
} else {
|
|
||||||
self.cursor.set(ListEditorCursor::Insert(0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Left)) => {
|
|
||||||
if idx > 0 {
|
|
||||||
self.cursor.set(ListEditorCursor::Select(idx - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Right)) => {
|
|
||||||
if idx+1 < self.data.len() {
|
|
||||||
self.cursor.set(ListEditorCursor::Select(idx + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event => {
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx));
|
|
||||||
self.data.get_mut(idx).write().unwrap().handle_terminal_event(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ListEditorCursor::Edit(idx) => {
|
|
||||||
match event {
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\t'))) => {
|
|
||||||
if idx > 0 {
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx-1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
|
||||||
if idx+1 < self.data.len() {
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(' '))) => {
|
|
||||||
// split..
|
|
||||||
self.data.insert(idx+1, (self.make_item_editor)());
|
|
||||||
self.data.get_mut(idx).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::End)));
|
|
||||||
self.data.get_mut(idx+1).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
|
||||||
}
|
|
||||||
event => {
|
|
||||||
let ce = self.data.get_mut(idx);
|
|
||||||
let mut cur_edit = ce.write().unwrap();
|
|
||||||
match cur_edit.handle_terminal_event(event) {
|
|
||||||
TerminalEditorResult::Exit => {
|
|
||||||
match event {
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Up)) => {
|
|
||||||
self.cursor.set(ListEditorCursor::Select(idx));
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Home)) => {
|
|
||||||
if idx > 0 {
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx-1));
|
|
||||||
self.data.get_mut(idx-1).write().unwrap().handle_terminal_event(event);
|
|
||||||
} else {
|
|
||||||
cur_edit.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Backspace)) | // -> join
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Left)) => {
|
|
||||||
if idx > 0 {
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx-1));
|
|
||||||
self.data.get_mut(idx-1).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::End)));
|
|
||||||
} else {
|
|
||||||
cur_edit.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::End)) => {
|
|
||||||
if idx+1 < self.data.len() {
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
|
||||||
self.data.get_mut(idx+1).write().unwrap().handle_terminal_event(event);
|
|
||||||
} else if idx+1 == self.data.len() {
|
|
||||||
cur_edit.handle_terminal_event(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Delete)) |
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Right)) => {
|
|
||||||
if idx+1 < self.data.len() {
|
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
|
||||||
self.data.get_mut(idx+1).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
|
|
||||||
} else if idx+1 == self.data.len() {
|
|
||||||
cur_edit.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::End)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TerminalEditorResult::Continue => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_=>{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalEditorResult::Continue
|
TerminalEditorResult::Continue
|
||||||
|
@ -404,10 +525,15 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
||||||
pub fn vertical_sexpr_view(&self) -> OuterViewPort<dyn TerminalView> {
|
pub fn vertical_sexpr_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.get_seg_seq_view().vertical_sexpr_view(0)
|
self.get_seg_seq_view().vertical_sexpr_view(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path_view(&self) -> OuterViewPort<dyn TerminalView> {
|
pub fn path_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.get_seg_seq_view()
|
self.get_seg_seq_view()
|
||||||
.decorate("<", ">", "/", 1)
|
.decorate("<", ">", "/", 0)
|
||||||
|
.to_grid_horizontal()
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
pub fn string_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
|
self.get_seg_seq_view()
|
||||||
|
.decorate("\"", "\"", "", 1)
|
||||||
.to_grid_horizontal()
|
.to_grid_horizontal()
|
||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ use {
|
||||||
core::{ViewPort, OuterViewPort},
|
core::{ViewPort, OuterViewPort},
|
||||||
singleton::{SingletonView, SingletonBuffer},
|
singleton::{SingletonView, SingletonBuffer},
|
||||||
vec::VecBuffer,
|
vec::VecBuffer,
|
||||||
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}
|
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
|
||||||
|
tree_nav::{TreeNav, TreeNavResult}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,56 +54,89 @@ impl StringEditor {
|
||||||
self.cursor_port.outer()
|
self.cursor_port.outer()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn goto(&mut self, new_pos: usize) -> TerminalEditorResult {
|
pub fn insert(&mut self, c: char) -> TreeNavResult {
|
||||||
if new_pos <= self.data.len() {
|
|
||||||
self.cursor.set(Some(new_pos));
|
|
||||||
TerminalEditorResult::Continue
|
|
||||||
} else {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TerminalEditorResult::Exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn goto_end(&mut self) -> TerminalEditorResult {
|
|
||||||
self.goto(self.data.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev(&mut self) -> TerminalEditorResult {
|
|
||||||
let cur = self.cursor.get().unwrap_or(usize::MAX);
|
|
||||||
if cur > 0 {
|
|
||||||
self.cursor.set(Some(cur - 1));
|
|
||||||
TerminalEditorResult::Continue
|
|
||||||
} else {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TerminalEditorResult::Exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next(&mut self) -> TerminalEditorResult {
|
|
||||||
self.goto(self.cursor.get().unwrap_or(0) + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert(&mut self, c: char) -> TerminalEditorResult {
|
|
||||||
self.data.insert(self.cursor.get().unwrap_or(0), c);
|
self.data.insert(self.cursor.get().unwrap_or(0), c);
|
||||||
self.next()
|
self.nexd()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_prev(&mut self) -> TerminalEditorResult {
|
pub fn delete_prev(&mut self) -> TreeNavResult {
|
||||||
let cur = self.cursor.get().unwrap_or(0);
|
let cur = self.cursor.get().unwrap_or(0);
|
||||||
if cur <= self.data.len() && cur > 0 {
|
if cur <= self.data.len() && cur > 0 {
|
||||||
self.data.remove(cur-1);
|
self.data.remove(cur-1);
|
||||||
}
|
}
|
||||||
self.prev()
|
self.pxev()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&mut self) -> TerminalEditorResult {
|
pub fn delete(&mut self) -> TreeNavResult {
|
||||||
let cur = self.cursor.get().unwrap_or(0);
|
let cur = self.cursor.get().unwrap_or(0);
|
||||||
if cur < self.data.len() {
|
if cur < self.data.len() {
|
||||||
self.data.remove(cur);
|
self.data.remove(cur);
|
||||||
TerminalEditorResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
self.cursor.set(None);
|
self.cursor.set(None);
|
||||||
TerminalEditorResult::Exit
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TreeNav for StringEditor {
|
||||||
|
fn goto(&mut self, tree_pos: Vec<usize>) -> TreeNavResult {
|
||||||
|
if tree_pos.len() == 1 {
|
||||||
|
let new_pos = tree_pos[0];
|
||||||
|
if new_pos <= self.data.len() {
|
||||||
|
self.cursor.set(Some(new_pos));
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
self.cursor.set(None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.cursor.set(None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pxev(&mut self) -> TreeNavResult {
|
||||||
|
let cur = self.cursor.get().unwrap_or(usize::MAX);
|
||||||
|
if cur > 0 {
|
||||||
|
self.cursor.set(Some(cur - 1));
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else {
|
||||||
|
self.cursor.set(None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nexd(&mut self) -> TreeNavResult {
|
||||||
|
self.goto(vec![ self.cursor.get().unwrap_or(0) + 1 ])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto_end(&mut self) -> TreeNavResult {
|
||||||
|
if self.cursor.get() == Some(self.data.len()) {
|
||||||
|
self.up()
|
||||||
|
} else {
|
||||||
|
self.goto(vec![ self.data.len() ])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto_home(&mut self) -> TreeNavResult {
|
||||||
|
if self.cursor.get() == Some(0) {
|
||||||
|
self.up()
|
||||||
|
} else {
|
||||||
|
self.goto(vec![ 0 ])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn up(&mut self) -> TreeNavResult {
|
||||||
|
self.cursor.set(None);
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dn(&mut self) -> TreeNavResult {
|
||||||
|
if self.cursor.get() == Some(0) {
|
||||||
|
self.up()
|
||||||
|
} else {
|
||||||
|
self.goto(vec![0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,33 +148,19 @@ impl TerminalEditor for StringEditor {
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Left)) => self.prev(),
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Right)) => self.next(),
|
|
||||||
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Up)) => {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TerminalEditorResult::Exit
|
|
||||||
}
|
|
||||||
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Down)) |
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Home)) =>
|
|
||||||
if self.cursor.get() == Some(0) {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TerminalEditorResult::Exit
|
|
||||||
} else {
|
|
||||||
self.goto(0)
|
|
||||||
},
|
|
||||||
TerminalEvent::Input(Event::Key(Key::End)) =>
|
|
||||||
if self.cursor.get() == Some(self.data.len()) {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TerminalEditorResult::Exit
|
|
||||||
} else {
|
|
||||||
self.goto_end()
|
|
||||||
},
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Continue,
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Continue,
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => self.insert(*c),
|
TerminalEvent::Input(Event::Key(Key::Char(c))) => match self.insert(*c) {
|
||||||
TerminalEvent::Input(Event::Key(Key::Delete)) => self.delete(),
|
TreeNavResult::Exit => TerminalEditorResult::Exit,
|
||||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => self.delete_prev(),
|
TreeNavResult::Continue => TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Delete)) => match self.delete() {
|
||||||
|
TreeNavResult::Exit => TerminalEditorResult::Exit,
|
||||||
|
TreeNavResult::Continue => TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Backspace)) => match self.delete_prev() {
|
||||||
|
TreeNavResult::Exit => TerminalEditorResult::Exit,
|
||||||
|
TreeNavResult::Continue => TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
_ => TerminalEditorResult::Continue
|
_ => TerminalEditorResult::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
41
nested/src/tree_nav.rs
Normal file
41
nested/src/tree_nav.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
pub enum TreeNavResult {
|
||||||
|
Continue,
|
||||||
|
Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TreeNav {
|
||||||
|
fn up(&mut self) -> TreeNavResult {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dn(&mut self) -> TreeNavResult {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pxev(&mut self) -> TreeNavResult {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nexd(&mut self) -> TreeNavResult {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto_home(&mut self) -> TreeNavResult {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto_end(&mut self) -> TreeNavResult {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto(&mut self, tree_addr: Vec<usize>) -> TreeNavResult {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::terminal::{TerminalView, TerminalEditor};
|
||||||
|
|
||||||
|
pub trait TerminalTreeEditor = TerminalEditor + TreeNav;
|
||||||
|
|
|
@ -28,6 +28,7 @@ use{
|
||||||
TerminalView,
|
TerminalView,
|
||||||
TerminalEditor},
|
TerminalEditor},
|
||||||
string_editor::StringEditor,
|
string_editor::StringEditor,
|
||||||
|
tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor},
|
||||||
list::{SExprView, ListEditor}
|
list::{SExprView, ListEditor}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -297,25 +298,8 @@ write::
|
||||||
let cur_size_port = ViewPort::new();
|
let cur_size_port = ViewPort::new();
|
||||||
let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10), cur_size_port.inner());
|
let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10), cur_size_port.inner());
|
||||||
|
|
||||||
{
|
|
||||||
// let history_port = ViewPort::new();
|
|
||||||
// let mut history = VecBuffer::new(history_port.inner());
|
|
||||||
/*
|
|
||||||
compositor.write().unwrap().push(
|
|
||||||
history_port.into_outer()
|
|
||||||
.to_sequence()
|
|
||||||
.map(
|
|
||||||
|
|
|
||||||
)
|
|
||||||
.to_grid_vertical()
|
|
||||||
.flatten()
|
|
||||||
.offset(Vector2::new(45, 5))
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
let mut y = 5;
|
let mut y = 5;
|
||||||
|
|
||||||
|
|
||||||
// TypeEditor
|
// TypeEditor
|
||||||
|
|
||||||
let make_sub_editor = || {
|
let make_sub_editor = || {
|
||||||
|
@ -346,6 +330,22 @@ write::
|
||||||
TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) |
|
TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) |
|
||||||
TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) |
|
TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) |
|
||||||
TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
|
TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
|
||||||
|
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Left)) => {
|
||||||
|
if te.pxev() == TreeNavResult::Exit {
|
||||||
|
te.goto_home();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Right)) => {
|
||||||
|
if te.nexd() == TreeNavResult::Exit {
|
||||||
|
te.goto_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Up)) => { te.up(); }
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Down)) => { te.dn(); }
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Home)) => { te.goto_home(); }
|
||||||
|
TerminalEvent::Input(Event::Key(Key::End)) => { te.goto_end(); }
|
||||||
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||||
let mut strings = Vec::new();
|
let mut strings = Vec::new();
|
||||||
|
|
||||||
|
@ -398,12 +398,8 @@ write::
|
||||||
y+=1;
|
y+=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
te.handle_terminal_event(
|
te.up();
|
||||||
&TerminalEvent::Input(Event::Key(Key::Up))
|
te.goto_home();
|
||||||
);
|
|
||||||
te.handle_terminal_event(
|
|
||||||
&TerminalEvent::Input(Event::Key(Key::Home))
|
|
||||||
);
|
|
||||||
te = ListEditor::new(make_sub_editor.clone());
|
te = ListEditor::new(make_sub_editor.clone());
|
||||||
|
|
||||||
compositor.write().unwrap().push(magic.offset(Vector2::new(40, y)));
|
compositor.write().unwrap().push(magic.offset(Vector2::new(40, y)));
|
||||||
|
|
Loading…
Reference in a new issue