From 55eb59452154bcfcf6f111a934f14f266d8157e2 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 26 Jun 2022 00:49:35 +0200 Subject: [PATCH] product editor: grid layout --- nested/src/index/buffer.rs | 69 +++++++++++++++++++++++++++++++++++- nested/src/make_editor.rs | 63 ++++++++++++++++++++++---------- nested/src/product/editor.rs | 61 ++++++++++++++++--------------- nested/src/product/nav.rs | 32 ++++++++--------- 4 files changed, 160 insertions(+), 65 deletions(-) diff --git a/nested/src/index/buffer.rs b/nested/src/index/buffer.rs index e6e53d1..d5f0851 100644 --- a/nested/src/index/buffer.rs +++ b/nested/src/index/buffer.rs @@ -4,7 +4,7 @@ use { index::{IndexArea, IndexView}, }, std::sync::RwLock, - std::{collections::HashMap, hash::Hash, sync::Arc}, + std::{collections::HashMap, hash::Hash, sync::Arc, ops::{Deref, DerefMut}}, }; pub struct IndexBufferView(Arc>>) @@ -36,6 +36,7 @@ where } } +#[derive(Clone)] pub struct IndexBuffer where Key: Clone + Hash + Eq + Send + Sync + 'static, @@ -68,6 +69,27 @@ where self.port.0.outer() } + pub fn get(&self, key: &Key) -> Option { + self.data.read().unwrap().get(key).cloned() + } + + pub fn get_mut(&mut self, key: &Key) -> MutableIndexAccess { + MutableIndexAccess { + buf: self.clone(), + key: key.clone(), + val: self.get(key) + } + } + + pub fn update(&mut self, key: Key, item: Option) { + if let Some(item) = item { + self.data.write().unwrap().insert(key.clone(), item); + } else { + self.data.write().unwrap().remove(&key); + } + self.port.notify(&IndexArea::Set(vec![key])); + } + pub fn insert(&mut self, key: Key, item: Item) { self.data.write().unwrap().insert(key.clone(), item); self.port.notify(&IndexArea::Set(vec![key])); @@ -87,3 +109,48 @@ where self.port.notify(&IndexArea::Set(vec![key])); } } + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct MutableIndexAccess +where + Key: Clone + Hash + Eq + Send + Sync + 'static, + Item: Clone + Send + Sync + 'static, +{ + buf: IndexBuffer, + key: Key, + val: Option, +} + +impl Deref for MutableIndexAccess +where + Key: Clone + Hash + Eq + Send + Sync + 'static, + Item: Clone + Send + Sync + 'static, +{ + type Target = Option; + + fn deref(&self) -> &Option { + &self.val + } +} + +impl DerefMut for MutableIndexAccess +where + Key: Clone + Hash + Eq + Send + Sync + 'static, + Item: Clone + Send + Sync + 'static, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.val + } +} + +impl Drop for MutableIndexAccess +where + Key: Clone + Hash + Eq + Send + Sync + 'static, + Item: Clone + Send + Sync + 'static, +{ + fn drop(&mut self) { + self.buf.update(self.key.clone(), self.val.clone()); + } +} + diff --git a/nested/src/make_editor.rs b/nested/src/make_editor.rs index ad4a1ed..b489164 100644 --- a/nested/src/make_editor.rs +++ b/nested/src/make_editor.rs @@ -10,7 +10,7 @@ use { product::editor::ProductEditor, char_editor::CharEditor }, - cgmath::Vector2, + cgmath::{Vector2, Point2}, std::sync::{Arc, RwLock}, }; @@ -90,26 +90,46 @@ pub fn make_editor(ctx: Arc>, t: &TypeLadder, depth: usize) -> A } else if t[0] == c.type_term_from_str("( RGB )").unwrap() { Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_t("{ r: ") - .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - .with_t(", g: ") - .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - .with_t(", b: ") - .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - .with_t(" }") + .with_t(Point2::new(0, 0), "{") + .with_t(Point2::new(1, 1), "r: ") + .with_n(Point2::new(2, 1), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) + .with_t(Point2::new(1, 2), "g: ") + .with_n(Point2::new(2, 2), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) + .with_t(Point2::new(1, 3), "b: ") + .with_n(Point2::new(2, 3), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) + .with_t(Point2::new(0, 4), " }") )) as Arc> } else if t[0] == c.type_term_from_str("( Vec3i )").unwrap() { Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_t("{ x: ") - .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) - .with_t(", y: ") - .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) - .with_t(", z: ") - .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) - .with_t(" }") + .with_t(Point2::new(0, 0), "{") + .with_t(Point2::new(1, 1), "x: ") + .with_n(Point2::new(2, 1), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) + .with_t(Point2::new(1, 2), "y: ") + .with_n(Point2::new(2, 2), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) + .with_t(Point2::new(1, 3), "z: ") + .with_n(Point2::new(2, 3), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) + .with_t(Point2::new(0, 4), " }") )) as Arc> + } else if t[0] == c.type_term_from_str("( Json )").unwrap() { + Arc::new(RwLock::new( + PTYListEditor::::new( + Box::new({ + let ctx = ctx.clone(); + move || { + Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) + .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( String )").unwrap() ] ) + .with_t(Point2::new(1, 0), ": ") + .with_n(Point2::new(2, 0), vec![ ctx.read().unwrap().type_term_from_str("( Json )").unwrap() ] ) + )) as Arc> + } + }), + SeqDecorStyle::VerticalSexpr, + depth + ) + )) as Arc> + } else if t[0] == c.type_term_from_str("( List Term )").unwrap() { Arc::new(RwLock::new( PTYListEditor::::new( @@ -126,10 +146,15 @@ pub fn make_editor(ctx: Arc>, t: &TypeLadder, depth: usize) -> A } else { // else: term Arc::new(RwLock::new( - ProductEditor::new(depth, ctx.clone()) - .with_n( vec![ c.type_term_from_str("( List Char )").unwrap() ] ) - .with_n( vec![ c.type_term_from_str("( List Term )").unwrap() ] ) - )) as Arc> + PTYListEditor::new( + Box::new(|| { + Arc::new(RwLock::new(CharEditor::new())) + }), + SeqDecorStyle::DoubleQuote, + depth + ) + )) + } } diff --git a/nested/src/product/editor.rs b/nested/src/product/editor.rs index d3fce6d..d1e75a8 100644 --- a/nested/src/product/editor.rs +++ b/nested/src/product/editor.rs @@ -8,19 +8,21 @@ use { sequence::{SequenceView}, tree_nav::{TreeNav, TerminalTreeEditor, TreeNavResult}, vec::{VecBuffer, MutableVecAccess}, + index::{buffer::{IndexBuffer, MutableIndexAccess}, IndexView}, list::ListCursorMode, product::{segment::ProductEditorSegment}, make_editor::make_editor }, - cgmath::Vector2, + cgmath::{Vector2, Point2}, std::sync::{Arc, RwLock}, termion::event::{Event, Key}, + std::ops::{Deref, DerefMut} }; pub struct ProductEditor { - segments: VecBuffer, - pub(super) n_indices: Vec, - + segments: IndexBuffer, ProductEditorSegment>, + pub(super) n_indices: Vec>, + pub(super) ctx: Arc>, pub(super) cursor: Option, pub(super) depth: usize, @@ -29,7 +31,7 @@ pub struct ProductEditor { impl ProductEditor { pub fn new(depth: usize, ctx: Arc>) -> Self { ProductEditor { - segments: VecBuffer::new(), + segments: IndexBuffer::new(), n_indices: Vec::new(), ctx, cursor: None, @@ -37,53 +39,52 @@ impl ProductEditor { } } - pub fn with_t(mut self, t: &str) -> Self { - self.segments.push(ProductEditorSegment::T(t.to_string(), self.depth)); + pub fn with_t(mut self, pos: Point2, t: &str) -> Self { + self.segments.insert(pos, ProductEditorSegment::T(t.to_string(), self.depth)); self } - pub fn with_n(mut self, n: TypeLadder) -> Self { - let elem_idx = self.segments.len(); - self.segments.push(ProductEditorSegment::N{ + pub fn with_n(mut self, pos: Point2, n: TypeLadder) -> Self { + self.segments.insert(pos, ProductEditorSegment::N{ t: n, editor: None, cur_depth: 0 }); - self.n_indices.push(elem_idx); + self.n_indices.push(pos); self } - pub fn get_editor_element(&self, mut idx: isize) -> Option { + pub fn get_editor_segment(&self, mut idx: isize) -> ProductEditorSegment { idx = crate::modulo(idx, self.n_indices.len() as isize); - if let Some(i) = self.n_indices.get(idx as usize) { - Some(self.segments.get(*i)) + if let Some(pos) = self.n_indices.get(idx as usize) { + self.segments.get(pos).unwrap() } else { - None + unreachable!() } } - pub fn get_editor_element_mut(&mut self, mut idx: isize) -> Option> { + pub fn get_editor_segment_mut(&mut self, mut idx: isize) -> MutableIndexAccess, ProductEditorSegment> { idx = crate::modulo(idx, self.n_indices.len() as isize); - if let Some(i) = self.n_indices.get(idx as usize) { - Some(self.segments.get_mut(*i)) + if let Some(pos) = self.n_indices.get(idx as usize) { + self.segments.get_mut(pos) } else { - None + unreachable!() } } - pub fn get_cur_element(&self) -> Option { - self.get_editor_element(self.cursor?) + pub fn get_cur_segment(&self) -> Option { + Some(self.get_editor_segment(self.cursor?)) } - pub fn get_cur_element_mut(&mut self) -> Option> { - self.get_editor_element_mut(self.cursor?) + pub fn get_cur_segment_mut(&mut self) -> Option, ProductEditorSegment>> { + Some(self.get_editor_segment_mut(self.cursor?)) } pub fn get_editor(&self, idx: isize) -> Option>> { - if let Some(ProductEditorSegment::N{ t: _, editor, cur_depth: _ }) = self.get_editor_element(idx) { + if let ProductEditorSegment::N{ t: _, editor, cur_depth: _ } = self.get_editor_segment(idx) { editor } else { - None + unreachable!() } } @@ -103,14 +104,13 @@ impl TerminalEditor for ProductEditor { let ctx = self.ctx.clone(); self.segments .get_port() - .to_sequence() - .map(move |e: &ProductEditorSegment| { e.get_view(ctx.clone()) }) - .to_grid_horizontal() + .map_item(move |_pos, e: &ProductEditorSegment| { e.get_view(ctx.clone()) }) .flatten() } fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = self.get_cur_element_mut().as_deref_mut() { + if let Some(mut segment) = self.get_cur_segment_mut().as_deref_mut() { + if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = segment.deref_mut() { *cur_depth = self.get_cursor().tree_addr.len(); if let Some(e) = editor.clone() { let mut ce = e.write().unwrap(); @@ -141,6 +141,9 @@ impl TerminalEditor for ProductEditor { *cur_depth = self.get_cursor().tree_addr.len()+1; x } + } else { + unreachable!() + } } else { TerminalEditorResult::Exit } diff --git a/nested/src/product/nav.rs b/nested/src/product/nav.rs index 6e4bf64..f831e8e 100644 --- a/nested/src/product/nav.rs +++ b/nested/src/product/nav.rs @@ -52,8 +52,8 @@ impl TreeNav for ProductEditor { } fn goto(&mut self, mut c: TreeCursor) -> TreeNavResult { - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t: _t, editor, cur_depth } = element.deref_mut() { + if let Some(mut segment) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t: _t, editor, cur_depth }) = segment.deref_mut() { if let Some(e) = editor { let mut e = e.write().unwrap(); e.goto(TreeCursor::none()); @@ -65,8 +65,8 @@ impl TreeNav for ProductEditor { if c.tree_addr.len() > 0 { self.cursor = Some(crate::modulo(c.tree_addr.remove(0), self.n_indices.len() as isize)); - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t: _t, editor, cur_depth } = element.deref_mut() { + if let Some(mut element) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t: _t, editor, cur_depth }) = element.deref_mut() { if let Some(e) = editor { e.write().unwrap().goto(c.clone()); } @@ -89,8 +89,8 @@ impl TreeNav for ProductEditor { if direction.y > 0 { self.cursor = Some(0); - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() { + if let Some(mut element) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() { *cur_depth = 1; } } @@ -106,8 +106,8 @@ impl TreeNav for ProductEditor { 1 => { if direction.y > 0 { // dn - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() { + if let Some(mut element) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() { if let Some(e) = editor { let mut e = e.write().unwrap(); e.goby(direction); @@ -125,8 +125,8 @@ impl TreeNav for ProductEditor { TreeNavResult::Continue } else if direction.y < 0 { // up - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() { + if let Some(mut element) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() { *cur_depth = 0; } } @@ -137,14 +137,14 @@ impl TreeNav for ProductEditor { if (cur.tree_addr[0]+direction.x >= 0) && (cur.tree_addr[0]+direction.x < self.n_indices.len() as isize) { - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() { + if let Some(mut element) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() { *cur_depth = 0; } } self.cursor = Some(cur.tree_addr[0] + direction.x); - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() { + if let Some(mut element) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() { *cur_depth = 1; } } @@ -156,8 +156,8 @@ impl TreeNav for ProductEditor { } } depth => { - if let Some(mut element) = self.get_cur_element_mut() { - if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() { + if let Some(mut element) = self.get_cur_segment_mut() { + if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() { if let Some(e) = editor { let mut ce = e.write().unwrap(); //\\//\\//\\//\\