From a3d966df115acba02233e428e48f629295cd9416 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sat, 28 Aug 2021 17:01:31 +0200 Subject: [PATCH] fix some bugs and add help to demo --- nested/src/grid/flatten.rs | 19 +++--- nested/src/list/editor.rs | 84 +++++++++++++++++++-------- nested/src/string_editor.rs | 32 ++++++++++- shell/src/main.rs | 111 +++++++++++++++++++++++------------- 4 files changed, 173 insertions(+), 73 deletions(-) diff --git a/nested/src/grid/flatten.rs b/nested/src/grid/flatten.rs index 9792f7c..92c2dc2 100644 --- a/nested/src/grid/flatten.rs +++ b/nested/src/grid/flatten.rs @@ -115,11 +115,10 @@ where Item: 'static } } ); -/* + if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { chunk.view = view; } else { -*/ self.chunks.insert( chunk_idx, Chunk { @@ -128,9 +127,7 @@ where Item: 'static view } ); - /* } - */ chunk_port.0.update(); self.update_all_offsets(); @@ -162,20 +159,24 @@ where Item: 'static let mut col_widths = vec![0 as i16; (top_range.end.x) as usize]; let mut row_heights = vec![0 as i16; (top_range.end.y) as usize]; + for chunk_idx in GridWindowIterator::from(self.top.range()) { + if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { + let lim = chunk.view.range().end; + col_widths[chunk_idx.x as usize] = std::cmp::max(col_widths[chunk_idx.x as usize], lim.x); + row_heights[chunk_idx.y as usize] = std::cmp::max(row_heights[chunk_idx.y as usize], lim.y); + } + } + for chunk_idx in GridWindowIterator::from(self.top.range()) { if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { let old_offset = chunk.offset; let old_limit = chunk.limit; + chunk.limit = chunk.view.range().end; chunk.offset = Vector2::new( (0 .. chunk_idx.x as usize).map(|x| col_widths[x]).sum(), (0 .. chunk_idx.y as usize).map(|y| row_heights[y]).sum() ); - chunk.limit = chunk.view.range().end; - - col_widths[chunk_idx.x as usize] = std::cmp::max(col_widths[chunk_idx.x as usize], chunk.limit.x); - row_heights[chunk_idx.y as usize] = std::cmp::max(row_heights[chunk_idx.y as usize], chunk.limit.y); - if old_offset != chunk.offset { dirty_idx.extend( GridWindowIterator::from( diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs index 9723b77..d04b754 100644 --- a/nested/src/list/editor.rs +++ b/nested/src/list/editor.rs @@ -137,6 +137,17 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, fn goto_end(&mut self) -> TreeNavResult { let mut cur = self.cursor.get(); let i = cur.idx.unwrap_or(0); + + if self.data.len() == 0 && cur.idx.is_none() { + self.cursor.set( + ListCursor { + mode: ListCursorMode::Insert, + idx: Some(0) + } + ); + return TreeNavResult::Continue; + } + if i < self.data.len() { match cur.mode { ListCursorMode::Insert => { @@ -150,6 +161,16 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } } ListCursorMode::Select => { + if self.data.len() == 0 && cur.idx.is_none() { + self.cursor.set( + ListCursor { + mode: ListCursorMode::Insert, + idx: Some(0) + } + ); + return TreeNavResult::Continue; + } + if i+1 < self.data.len() || cur.idx.is_none() { cur.idx = Some(self.data.len()-1); self.cursor.set(cur); @@ -170,24 +191,25 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } TreeNavResult::Exit => { drop(cur_edit); + self.up(); - if let Some(i) = cur.idx { - if i+1 < self.data.len() { - self.nexd(); - self.set_leaf_mode(cur_mode); - - for x in 1 .. depth { - self.dn(); - self.goto_home(); - } + if i+1 < self.data.len() { + self.set_mode(ListCursorMode::Select); + self.nexd(); + for x in 1 .. depth { self.dn(); - self.goto_end(); - - return TreeNavResult::Continue; + self.goto_home(); } + + self.set_leaf_mode(cur_mode); + self.dn(); + self.goto_end(); + + return TreeNavResult::Continue; } + TreeNavResult::Exit } } @@ -201,13 +223,23 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, fn goto_home(&mut self) -> TreeNavResult { let cur = self.cursor.get(); + if self.data.len() == 0 && cur.idx.is_none() { + self.cursor.set( + ListCursor { + mode: ListCursorMode::Insert, + idx: Some(0) + } + ); + return TreeNavResult::Continue; + } + match cur.mode { ListCursorMode::Insert | ListCursorMode::Select => { if cur.idx != Some(0) { self.cursor.set( ListCursor { - mode: cur.mode, + mode: if self.data.len() == 0 { ListCursorMode::Insert } else { cur.mode }, idx: Some(0) } ); @@ -226,9 +258,10 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, match cur_edit.goto_home() { TreeNavResult::Exit => { drop(cur_edit); - self.up(); if let Some(i) = cur.idx { + self.up(); + if i > 0 { self.set_mode(ListCursorMode::Select); self.pxev(); @@ -331,6 +364,7 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, self.up(); if i > 0 { + self.set_mode(ListCursorMode::Select); self.pxev(); for x in 1 .. depth { @@ -341,7 +375,6 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, self.set_leaf_mode(cur_mode); self.dn(); self.goto_end(); - TreeNavResult::Continue } else { TreeNavResult::Exit @@ -391,17 +424,21 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, TreeNavResult::Exit => { drop(cur_edit); drop(ce); - self.up(); + self.up(); if i+1 < self.data.len() { + + self.set_mode(ListCursorMode::Select); self.nexd(); - for x in 0 .. depth { + for x in 1 .. depth { self.dn(); self.goto_home(); } self.set_leaf_mode(cur_mode); + self.dn(); + self.goto_home(); TreeNavResult::Continue } else { TreeNavResult::Exit @@ -565,7 +602,7 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, .map_item( |_pt, atom| atom.add_style_back(TerminalStyle::fg_color((90,60,200))) - .add_style_back(TerminalStyle::bg_color((0,0,0))) + //.add_style_back(TerminalStyle::bg_color((0,0,0))) .add_style_back(TerminalStyle::bold(true)) ), ListEditorViewSegment::Select(sub_view) => @@ -574,11 +611,11 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, atom.add_style_front(TerminalStyle::bg_color((90,60,200))) ), ListEditorViewSegment::Modify(sub_view) => { - sub_view.map_item( + sub_view.clone()/*.map_item( |_pt, atom| - atom.add_style_back(TerminalStyle::bg_color((0,0,0))) - .add_style_back(TerminalStyle::bold(true)) - ) + atom//.add_style_back(TerminalStyle::bg_color((0,0,0))) + //.add_style_back(TerminalStyle::bold(true)) + )*/ }, ListEditorViewSegment::View(sub_view) => sub_view.clone() @@ -684,7 +721,7 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, }); } } - + fn set_mode(&mut self, mode: ListCursorMode) { let mut cur = self.cursor.get(); @@ -699,6 +736,7 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, } cur.mode = mode; + self.cursor.set(cur); } } diff --git a/nested/src/string_editor.rs b/nested/src/string_editor.rs index db7a44d..477e375 100644 --- a/nested/src/string_editor.rs +++ b/nested/src/string_editor.rs @@ -5,7 +5,7 @@ use { core::{ViewPort, OuterViewPort}, singleton::{SingletonView, SingletonBuffer}, vec::VecBuffer, - terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}, + terminal::{TerminalView, TerminalStyle, TerminalEvent, TerminalEditor, TerminalEditorResult}, tree_nav::{TreeNav, TreeNavResult} } }; @@ -40,6 +40,10 @@ impl TerminalEditor for CharEditor { } else { "".to_string() }) + .map_item( + |_idx, atom| + atom.add_style_back(TerminalStyle::fg_color((120, 200, 10))) + ) } fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { @@ -60,4 +64,30 @@ impl TerminalEditor for CharEditor { } } +/* +pub struct ArgListEditor { + +} +impl TreeNav for ArgListEditor { + +} + +impl TerminalEditor for ArgListEditor { + fn get_term_view(&self) -> OuterViewPort { + + } + + fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { + match event { + TerminalEvent::Input(Event::Key(Key::Char(' '))) => { + // list.get_arg() + // split + } + _ => { + + } + } + } +} +*/ diff --git a/shell/src/main.rs b/shell/src/main.rs index b775078..e595bd8 100644 --- a/shell/src/main.rs +++ b/shell/src/main.rs @@ -89,45 +89,36 @@ write:: async_std::task::spawn( async move { + let table_port = ViewPort::>>::new(); + let mut table_buf = nested::index::buffer::IndexBuffer::new(table_port.inner()); - let magic = make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>") - .map_item( - |pos, atom| - atom.add_style_back( - TerminalStyle::fg_color( - (5, - ((80+(pos.x*30)%100) as u8), - (55+(pos.x*15)%180) as u8) - ) + let magic = make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>") + .map_item( + |pos, atom| + atom.add_style_back( + TerminalStyle::fg_color( + (5, + ((80+(pos.x*30)%100) as u8), + (55+(pos.x*15)%180) as u8) ) - ); - - { - compositor.write().unwrap().push(magic.offset(Vector2::new(40, 4))); - //compositor.write().unwrap().push(magic.offset(Vector2::new(40, 20))); - - //let monstera_port = monstera::make_monstera(); - //compositor.write().unwrap().push(monstera_port.clone()); - //compositor.write().unwrap().push(monstera_port.offset(Vector2::new(83,0))); - - } + ) + ); let cur_size_port = ViewPort::new(); let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10), cur_size_port.inner()); - let mut y = 5; - // TypeEditor - let make_char_editor = || { - std::sync::Arc::new(std::sync::RwLock::new(DigitEditor::new(16))) + std::sync::Arc::new(std::sync::RwLock::new(CharEditor::new())) + }; + let make_subsub_editor = move || { + std::sync::Arc::new(std::sync::RwLock::new(ListEditor::new(make_char_editor.clone(), ListEditorStyle::String))) }; - let make_sub_editor = move || { - std::sync::Arc::new(std::sync::RwLock::new(ListEditor::new(make_char_editor.clone(), ListEditorStyle::Hex))) + std::sync::Arc::new(std::sync::RwLock::new(ListEditor::new(make_subsub_editor.clone(), ListEditorStyle::HorizontalSexpr))) }; - let mut te = ListEditor::new(make_sub_editor.clone(), ListEditorStyle::Clist); + let mut te = ListEditor::new(make_sub_editor.clone(), ListEditorStyle::VerticalSexpr); te.goto( TreeCursor { @@ -136,24 +127,63 @@ write:: } ); - compositor.write().unwrap().push( - te.get_term_view() - .offset(cgmath::Vector2::new(40,y)) - ); - y += 1; - let mut p = te.get_data_port().map(|sub_editor| sub_editor.read().unwrap().get_data_port()); let status_chars_port = ViewPort::new(); let mut status_chars = VecBuffer::new(status_chars_port.inner()); - compositor.write().unwrap().push( - status_chars_port.outer() - .to_sequence() - .to_grid_horizontal() - .offset(cgmath::Vector2::new(40, 2)) - ); + let help_port = ViewPort::>>::new(); + let mut help_buf = nested::index::buffer::IndexBuffer::, OuterViewPort>::new(help_port.inner()); + let table_style = TerminalStyle::fg_color((120, 100, 80)); + let desc_style = TerminalStyle::italic(true); + help_buf.insert_iter(vec![ + (Point2::new(0, 0), make_label("CTRL+{c,d,g}").map_item(|_idx, atom| atom.add_style_back(TerminalStyle::bold(true)))), + (Point2::new(1, 0), make_label(" | ").map_item(move |_idx, atom| atom.add_style_back(table_style))), + (Point2::new(2, 0), make_label("quit").map_item(move |_idx, atom| atom.add_style_back(desc_style))), + + (Point2::new(0, 1), make_label("↞ ← ↑ ↓ → ↠").map_item(|_idx, atom| atom.add_style_back(TerminalStyle::bold(true)))), + (Point2::new(1, 1), make_label(" | ").map_item(move |_idx, atom| atom.add_style_back(table_style))), + (Point2::new(2, 1), make_label("move cursor").map_item(move |_idx, atom| atom.add_style_back(desc_style))), + + (Point2::new(0, 3), make_label(" (Select)").map_item(|_idx, atom| atom.add_style_back(TerminalStyle::bold(true)))), + (Point2::new(1, 3), make_label(" | ").map_item(move |_idx, atom| atom.add_style_back(table_style))), + (Point2::new(2, 3), make_label("delete item at cursor position").map_item(move |_idx, atom| atom.add_style_back(desc_style))), + + (Point2::new(0, 4), make_label(" (Insert)").map_item(|_idx, atom| atom.add_style_back(TerminalStyle::bold(true)))), + (Point2::new(1, 4), make_label(" | ").map_item(move |_idx, atom| atom.add_style_back(table_style))), + (Point2::new(2, 4), make_label("delete item right to cursor").map_item(move |_idx, atom| atom.add_style_back(desc_style))), + + (Point2::new(0, 5), make_label(" (Insert)").map_item(|_idx, atom| atom.add_style_back(TerminalStyle::bold(true)))), + (Point2::new(1, 5), make_label(" | ").map_item(move |_idx, atom| atom.add_style_back(table_style))), + (Point2::new(2, 5), make_label("delete item left to cursor").map_item(move |_idx, atom| atom.add_style_back(desc_style))), + + (Point2::new(0, 6), make_label("").map_item(|_idx, atom| atom.add_style_back(TerminalStyle::bold(true)))), + (Point2::new(1, 6), make_label(" | ").map_item(move |_idx, atom| atom.add_style_back(table_style))), + (Point2::new(2, 6), make_label("toggle cursor mode (insert / select)").map_item(move |_idx, atom| atom.add_style_back(desc_style))), + ]); + + let help_head = make_label("─────────────────────┬─────────────────────").map_item(move |_idx, atom| atom.add_style_back(table_style)); + + table_buf.insert_iter(vec![ + (Point2::new(0, 0), magic.clone()), + (Point2::new(0, 2), status_chars_port.outer().to_sequence().to_grid_horizontal()), + (Point2::new(0, 3), te.get_term_view()), + (Point2::new(0, 4), make_label(" ")), + (Point2::new(0, 5), help_head), + (Point2::new(0, 6), help_port.outer().flatten()), + (Point2::new(0, 7), magic.clone()), + ]); + + compositor.write().unwrap().push(monstera::make_monstera()); + compositor.write().unwrap().push(table_port.outer().flatten().offset(Vector2::new(40, 2))); + +/* + te.get_data_port() + .map( + |item_editor| item_editor.read().unwrap().get_data_port() + ) +*/ loop { term_port.update(); match term.next_event().await { @@ -180,9 +210,10 @@ write:: } } TerminalEvent::Input(Event::Key(Key::Up)) => { te.up(); } - TerminalEvent::Input(Event::Key(Key::Down)) => { te.dn(); } + TerminalEvent::Input(Event::Key(Key::Down)) => { te.dn(); te.goto_home(); } TerminalEvent::Input(Event::Key(Key::Home)) => { if te.goto_home() == TreeNavResult::Exit { + te.goto_home(); } }