From 127c43bca0ea63fc26ab927917d3f548ed37f52a Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 15 Aug 2021 02:05:33 +0200 Subject: [PATCH] list editor: add path view add decorate() on OuterViewPort to create a ListDecorator --- nested/src/list/editor.rs | 76 +++++++----- nested/src/list/mod.rs | 2 +- nested/src/list/sexpr.rs | 238 ++++++++++++++++++-------------------- shell/src/main.rs | 95 +-------------- 4 files changed, 165 insertions(+), 246 deletions(-) diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs index ea0c6ae..c4af949 100644 --- a/nested/src/list/editor.rs +++ b/nested/src/list/editor.rs @@ -32,7 +32,7 @@ use { }, string_editor::StringEditor, leveled_term_view::LeveledTermView, - list::SExprView + list::{SExprView, ListDecoration} } }; @@ -59,7 +59,7 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, data_sequence_port: OuterViewPort>>>, make_item_editor: FnMakeItemEditor, level: usize, - pub segment_seq: OuterViewPort>>, + segment_seq: OuterViewPort>, } impl TerminalEditor for ListEditor @@ -67,7 +67,7 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, FnMakeItemEditor: Fn() -> Arc> { fn get_term_view(&self) -> OuterViewPort { - self.segment_seq.horizontal_sexpr_view(0) + self.horizontal_sexpr_view() } fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { @@ -369,6 +369,49 @@ impl ListEditor where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, FnMakeItemEditor: Fn() -> Arc> { + + pub fn get_seg_seq_view(&self) -> OuterViewPort>> { + self.segment_seq + .map( + |segment| match segment { + ListEditorViewSegment::InsertCursor => + make_label("|") + .map_item( + |_pt, atom| + atom.add_style_back(TerminalStyle::fg_color((90,60,200))) + .add_style_back(TerminalStyle::bold(true)) + ), + ListEditorViewSegment::Select(sub_view) => + sub_view.map_item( + |_pt, atom| + atom.add_style_back(TerminalStyle::bg_color((90,60,200))) + ), + ListEditorViewSegment::Edit(sub_view) => + sub_view.map_item( + |_pt, atom| + atom.add_style_back(TerminalStyle::bg_color((0,0,0))) + .add_style_back(TerminalStyle::bold(true)) + ), + ListEditorViewSegment::View(sub_view) => + sub_view.clone() + } + ) + } + + pub fn horizontal_sexpr_view(&self) -> OuterViewPort { + self.get_seg_seq_view().horizontal_sexpr_view(0) + } + pub fn vertical_sexpr_view(&self) -> OuterViewPort { + self.get_seg_seq_view().vertical_sexpr_view(0) + } + + pub fn path_view(&self) -> OuterViewPort { + self.get_seg_seq_view() + .decorate("<", ">", "/", 1) + .to_grid_horizontal() + .flatten() + } + pub fn new(make_item_editor: FnMakeItemEditor) -> Self { let cursor_port = ViewPort::new(); let data_port = ViewPort::new(); @@ -391,32 +434,7 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, cursor, make_item_editor, level: 0, - segment_seq: segment_view_port - .outer() - .map( - |segment| match segment { - ListEditorViewSegment::InsertCursor => - make_label("|") - .map_item( - |_pt, atom| - atom.add_style_back(TerminalStyle::fg_color((90,60,200))) - .add_style_back(TerminalStyle::bold(true)) - ), - ListEditorViewSegment::Select(sub_view) => - sub_view.map_item( - |_pt, atom| - atom.add_style_back(TerminalStyle::bg_color((90,60,200))) - ), - ListEditorViewSegment::Edit(sub_view) => - sub_view.map_item( - |_pt, atom| - atom.add_style_back(TerminalStyle::bg_color((0,0,0))) - .add_style_back(TerminalStyle::bold(true)) - ), - ListEditorViewSegment::View(sub_view) => - sub_view.clone() - } - ) + segment_seq: segment_view_port.outer() } } diff --git a/nested/src/list/mod.rs b/nested/src/list/mod.rs index 0888a48..eaed748 100644 --- a/nested/src/list/mod.rs +++ b/nested/src/list/mod.rs @@ -3,5 +3,5 @@ pub mod editor; pub mod sexpr; pub use editor::ListEditor; -pub use sexpr::SExprView; +pub use sexpr::{SExprView, ListDecoration}; diff --git a/nested/src/list/sexpr.rs b/nested/src/list/sexpr.rs index 9496d5b..810a576 100644 --- a/nested/src/list/sexpr.rs +++ b/nested/src/list/sexpr.rs @@ -1,20 +1,13 @@ use { + crate::{ + core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, + projection::ProjectionHelper, + sequence::SequenceView, + terminal::{make_label, TerminalStyle, TerminalView}, + }, + cgmath::Point2, std::sync::Arc, std::sync::RwLock, - cgmath::{Point2}, - crate::{ - core::{ - View, - ViewPort, - OuterViewPort, - InnerViewPort, - Observer, - ObserverBroadcast - }, - sequence::{SequenceView}, - terminal::{TerminalStyle, TerminalView, make_label}, - projection::ProjectionHelper - } }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -29,7 +22,7 @@ pub struct ListDecorator { item_style: TerminalStyle, cast: Arc>>>>, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper, } impl View for ListDecorator { @@ -41,7 +34,7 @@ impl SequenceView for ListDecorator { fn len(&self) -> Option { let l = self.items.len()?; - Some(if l == 0 { 2 } else { 2*l + 2 }) + Some(if l == 0 { 2 } else { 2 * l + 2 }) } fn get(&self, idx: &usize) -> Option { @@ -49,22 +42,23 @@ impl SequenceView for ListDecorator { let list_style = self.list_style.clone(); let item_style = self.item_style.clone(); let l = self.items.len().unwrap_or(0); - Some( - if *idx == 0 { - self.opening_port.clone() - .map_item(move |_, atom| atom.add_style_back(list_style)) - } else if (l == 0 && *idx == 1) || *idx == 2*l { - self.closing_port.clone() - .map_item(move |_, atom| atom.add_style_back(list_style)) - } else if idx % 2 == 0 { - self.delim_port.clone() - .map_item(move |_, atom| atom.add_style_back(list_style)) - } else { - self.items - .get(&item_idx)? - .map_item(move |_, atom| atom.add_style_back(item_style)) - } - ) + Some(if *idx == 0 { + self.opening_port + .clone() + .map_item(move |_, atom| atom.add_style_back(list_style)) + } else if (l == 0 && *idx == 1) || *idx == 2 * l { + self.closing_port + .clone() + .map_item(move |_, atom| atom.add_style_back(list_style)) + } else if idx % 2 == 0 { + self.delim_port + .clone() + .map_item(move |_, atom| atom.add_style_back(list_style)) + } else { + self.items + .get(&item_idx)? + .map_item(move |_, atom| atom.add_style_back(item_style)) + }) } } @@ -75,51 +69,64 @@ impl ListDecorator { delim: &str, level: usize, items_port: OuterViewPort>>, - out_port: InnerViewPort>> + out_port: InnerViewPort>>, ) -> Arc> { let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone()); - + let li = Arc::new(RwLock::new(ListDecorator { opening_port: make_label(opening), closing_port: make_label(closing), delim_port: make_label(delim), - items: proj_helper.new_sequence_arg( - items_port, - |s: &mut Self, item_idx| { - s.cast.notify( - &(*item_idx * 2 + 1) - ); - s.cast.notify( - &(*item_idx * 2 + 2) - ); - } - ), - list_style: TerminalStyle::fg_color( - match level { - 0 => (200, 120, 10), - 1 => (120, 200, 10), - _ => (255, 255, 255) - } - ), - item_style: TerminalStyle::fg_color( - match level { - _ => (255, 255, 255) - } - ), + items: proj_helper.new_sequence_arg(items_port, |s: &mut Self, item_idx| { + s.cast.notify(&(*item_idx * 2 + 1)); + s.cast.notify(&(*item_idx * 2 + 2)); + }), + list_style: TerminalStyle::fg_color(match level { + 0 => (200, 120, 10), + 1 => (120, 200, 10), + _ => (255, 255, 255), + }), + item_style: TerminalStyle::fg_color(match level { + _ => (255, 255, 255), + }), cast: out_port.get_broadcast(), - proj_helper + proj_helper, })); li.write().unwrap().proj_helper.set_proj(&li); - + out_port.set_view(Some(li.clone())); li } } +pub trait ListDecoration { + fn decorate( + &self, + opening: &str, + closing: &str, + delim: &str, + level: usize, + ) -> OuterViewPort>>; +} + +impl ListDecoration for OuterViewPort>> { + fn decorate( + &self, + opening: &str, + closing: &str, + delim: &str, + level: usize, + ) -> OuterViewPort>> { + let port = ViewPort::new(); + ListDecorator::new(opening, closing, delim, level, self.clone(), port.inner()); + port.into_outer() + } +} + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -use crate::{index::IndexView, grid::GridView}; +use crate::{grid::GridView, index::IndexView}; pub struct VerticalSexprDecorator { opening_port: OuterViewPort, @@ -130,7 +137,7 @@ pub struct VerticalSexprDecorator { item_style: TerminalStyle, cast: Arc>>>>, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper, } impl View for VerticalSexprDecorator { @@ -141,7 +148,9 @@ impl IndexView> for VerticalSexprDecorator { type Item = OuterViewPort; fn area(&self) -> Option>> { - let mut area = (0 .. self.items.len()?).map(|i| Point2::new(1 as i16, i as i16)).collect::>(); + let mut area = (0..self.items.len()?) + .map(|i| Point2::new(1 as i16, i as i16)) + .collect::>(); area.push(Point2::new(0, 0)); area.push(Point2::new(2, self.items.len()? as i16 - 1)); Some(area) @@ -156,28 +165,38 @@ impl IndexView> for VerticalSexprDecorator { match pt.x { 0 => { if pt.y == 0 { - Some(self.opening_port.clone() - .map_item(move |_, atom| atom.add_style_back(list_style))) + Some( + self.opening_port + .clone() + .map_item(move |_, atom| atom.add_style_back(list_style)), + ) } else { None } } 1 => { if item_idx < l { - Some(self.items.get(&item_idx)?.map_item(move |_, atom| atom.add_style_back(item_style))) + Some( + self.items + .get(&item_idx)? + .map_item(move |_, atom| atom.add_style_back(item_style)), + ) } else { None } } 2 => { - if (l == 0 && pt.y == 0) || (item_idx+1 == l) { - Some(self.closing_port.clone() - .map_item(move |_, atom| atom.add_style_back(list_style))) + if (l == 0 && pt.y == 0) || (item_idx + 1 == l) { + Some( + self.closing_port + .clone() + .map_item(move |_, atom| atom.add_style_back(list_style)), + ) } else { None } } - _ => None + _ => None, } } } @@ -188,51 +207,37 @@ impl VerticalSexprDecorator { closing: &str, level: usize, items_port: OuterViewPort>>, - out_port: InnerViewPort>> + out_port: InnerViewPort>>, ) -> Arc> { let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone()); - + let li = Arc::new(RwLock::new(VerticalSexprDecorator { opening_port: make_label(opening), closing_port: make_label(closing), - items: proj_helper.new_sequence_arg( - items_port, - |s: &mut Self, item_idx| { - s.cast.notify( - &Point2::new(1, *item_idx as i16) - ); - s.cast.notify( - &Point2::new(2, *item_idx as i16 - 1) - ); - s.cast.notify( - &Point2::new(2, *item_idx as i16) - ); - } - ), - list_style: TerminalStyle::fg_color( - match level { - 0 => (200, 120, 10), - 1 => (120, 200, 10), - _ => (255, 255, 255) - } - ), - item_style: TerminalStyle::fg_color( - match level { - _ => (255, 255, 255) - } - ), + items: proj_helper.new_sequence_arg(items_port, |s: &mut Self, item_idx| { + s.cast.notify(&Point2::new(1, *item_idx as i16)); + s.cast.notify(&Point2::new(2, *item_idx as i16 - 1)); + s.cast.notify(&Point2::new(2, *item_idx as i16)); + }), + list_style: TerminalStyle::fg_color(match level { + 0 => (200, 120, 10), + 1 => (120, 200, 10), + _ => (255, 255, 255), + }), + item_style: TerminalStyle::fg_color(match level { + _ => (255, 255, 255), + }), cast: out_port.get_broadcast(), - proj_helper + proj_helper, })); li.write().unwrap().proj_helper.set_proj(&li); - + out_port.set_view(Some(li.clone())); li } } - pub trait SExprView { fn horizontal_sexpr_view(&self, level: usize) -> OuterViewPort; fn vertical_bar_view(&self, level: usize) -> OuterViewPort; @@ -242,42 +247,21 @@ pub trait SExprView { impl SExprView for OuterViewPort>> { fn horizontal_sexpr_view(&self, level: usize) -> OuterViewPort { let port = ViewPort::new(); - ListDecorator::new( - "(", ")", " ", - level, - self.clone(), - port.inner() - ); + ListDecorator::new("(", ")", " ", level, self.clone(), port.inner()); - port.into_outer() - .to_grid_horizontal() - .flatten() + port.into_outer().to_grid_horizontal().flatten() } fn vertical_bar_view(&self, level: usize) -> OuterViewPort { let port = ViewPort::new(); - ListDecorator::new( - "Λ", "V", "|", - level, - self.clone(), - port.inner() - ); + ListDecorator::new("Λ", "V", "|", level, self.clone(), port.inner()); - port.into_outer() - .to_grid_vertical() - .flatten() + port.into_outer().to_grid_vertical().flatten() } fn vertical_sexpr_view(&self, level: usize) -> OuterViewPort { let port = ViewPort::new(); - VerticalSexprDecorator::new( - "(", ")", - level, - self.clone(), - port.inner() - ); - port.into_outer() - .flatten() + VerticalSexprDecorator::new("(", ")", level, self.clone(), port.inner()); + port.into_outer().flatten() } } - diff --git a/shell/src/main.rs b/shell/src/main.rs index 544c290..b75a377 100644 --- a/shell/src/main.rs +++ b/shell/src/main.rs @@ -294,95 +294,9 @@ write:: } -/* - - // list views - { - let items_port = ViewPort::new(); - let items = VecBuffer::with_data( - vec![ - arg1_hex_unic_port.clone() - .map(|c| TerminalAtom::from(c)) - .to_index() - .map_key( - |idx| Point2::new(*idx as i16, 0 as i16), - |pt| if pt.y == 0 { Some(pt.x as usize) } else { None } - ), - ed.insert_view() - .map_item( - |_pos, atom| - TerminalAtom::new( - atom.c.unwrap_or(' '), - TerminalStyle::fg_color( - if let Some(c) = atom.c { - if c == '|' { - (200, 200, 90) - } else if c.is_digit(10) { - (0, 200, 0) - } else { - (255, 0, 0) - } - } else { - (0, 0, 0) - } - ).add( - TerminalStyle::bg_color((0,0,0)) - ) - ) - ), - arg1_hex_unic_port.clone() - .map(|c| TerminalAtom::from(c)) - .to_index() - .map_key( - |idx| Point2::new(*idx as i16, 0 as i16), - |pt| if pt.y == 0 { Some(pt.x as usize) } else { None } - ), - ], - items_port.inner() - ); - - let par_items_port = ViewPort::new(); - let par_items = VecBuffer::with_data( - vec![ - items_port.outer().to_sequence().sexpr_view(1), - arg1_hex_unic_port.clone() - .map(|c| TerminalAtom::from(c)) - .to_index() - .map_key( - |idx| Point2::new(*idx as i16, 0 as i16), - |pt| if pt.y == 0 { Some(pt.x as usize) } else { None } - ), - ], - par_items_port.inner() - ); - - compositor.write().unwrap().push( - par_items_port.outer() - .to_sequence() - .sexpr_view(0) - .offset(Vector2::new(45, 5)) - ); - } - - for c in _arg1_vec { - ed.insert(c); - } -*/ - let cur_size_port = ViewPort::new(); let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10), cur_size_port.inner()); -// compositor.write().unwrap() -// .push( - let label_port = cur_size_port.outer() - .map( - |size| make_label(format!("Current Size: {:?}", size).as_str()) - ); -// ); - - //term_port.update(); - //eprintln!("start loop:"); - { // let history_port = ViewPort::new(); // let mut history = VecBuffer::new(history_port.inner()); @@ -411,11 +325,12 @@ write:: let mut te = ListEditor::new(make_sub_editor.clone()); compositor.write().unwrap().push( - te.segment_seq.horizontal_sexpr_view(0).offset(cgmath::Vector2::new(40,y)) + te.path_view() + .offset(cgmath::Vector2::new(40,y)) ); y += 1; - let mut p = te.get_data_port().map(|string_editor| string_editor.read().unwrap().get_data_port()); + let mut p = te.get_data_port().map(|string_editor| string_editor.read().unwrap().get_data_port()); loop { term_port.update(); @@ -494,7 +409,9 @@ write:: compositor.write().unwrap().push(magic.offset(Vector2::new(40, y))); y += 1; compositor.write().unwrap().push( - te.segment_seq.horizontal_sexpr_view(0).offset(cgmath::Vector2::new(40,y)) + te + .horizontal_sexpr_view() + .offset(Vector2::new(40, y)) ); y += 1;