From 6fe50416b5c1a441352ce54624dde0bb5136c2e1 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sat, 16 Jan 2021 13:57:06 +0100 Subject: [PATCH] index view: replace range() with area() --- src/grid/offset.rs | 36 ++++++++++----------- src/index/map_item.rs | 17 +++++++--- src/index/mod.rs | 22 +++++++------ src/string_editor.rs | 20 ++++++------ src/terminal/compositor.rs | 64 +++++++++++++++----------------------- src/terminal/terminal.rs | 7 ++--- 6 files changed, 78 insertions(+), 88 deletions(-) diff --git a/src/grid/offset.rs b/src/grid/offset.rs index fb70308..3119284 100644 --- a/src/grid/offset.rs +++ b/src/grid/offset.rs @@ -1,7 +1,7 @@ use { std::{ sync::{Arc, RwLock}, - ops::Range + boxed::Box }, cgmath::{Point2, Vector2}, crate::{ @@ -40,16 +40,12 @@ where V::Item: Default { } pub fn set_offset(&mut self, new_offset: Vector2) { - let old_range = self.range(); + let old_area = self.area(); self.offset = new_offset; - let new_range = self.range(); + let new_area = self.area(); - if let Some(old_range) = old_range { - self.cast.notify_each(GridWindowIterator::from(old_range)); - } - if let Some(new_range) = new_range { - self.cast.notify_each(GridWindowIterator::from(new_range)); - } + if let Some(area) = old_area { self.cast.notify_each(area); } + if let Some(area) = new_area { self.cast.notify_each(area); } } } @@ -69,25 +65,25 @@ where V::Item: Default { } } - fn range(&self) -> Option>> { - let src_range = self.src.as_ref()?.range()?; - Some((src_range.start + self.offset) .. (src_range.end + self.offset)) + fn area(&self) -> Option>> { + Some( + self.src.as_ref()? + .area()?.into_iter() + .map(|pos| pos + self.offset) + .collect() + ) } } impl Observer for GridOffset where V::Item: Default { fn reset(&mut self, view: Option>) { - let old_range = self.range(); + let old_area = self.area(); self.src = view; - let new_range = self.range(); + let new_area = self.area(); - if let Some(old_range) = old_range { - self.cast.notify_each(GridWindowIterator::from(old_range)); - } - if let Some(new_range) = new_range { - self.cast.notify_each(GridWindowIterator::from(new_range)); - } + if let Some(area) = old_area { self.cast.notify_each(area); } + if let Some(area) = new_area { self.cast.notify_each(area); } } fn notify(&self, msg: &Point2) { diff --git a/src/index/map_item.rs b/src/index/map_item.rs index c9bdbb0..0a3e874 100644 --- a/src/index/map_item.rs +++ b/src/index/map_item.rs @@ -1,12 +1,13 @@ pub use { std::{ sync::{Arc, RwLock}, - ops::Range + boxed::Box }, crate::{ core::{ View, Observer, + ObserverExt, ObserverBroadcast, ViewPort, InnerViewPort, @@ -85,21 +86,27 @@ where DstItem: Default, } } - fn range(&self) -> Option> { - self.src_view.as_ref()?.range() + fn area(&self) -> Option> { + self.src_view.as_ref()?.area() } } impl Observer for MapIndexItem -where SrcView: IndexView + ?Sized, +where DstItem: Default, + SrcView: IndexView + ?Sized, F: Fn(&SrcView::Item) -> DstItem + Send + Sync { fn reset(&mut self, view: Option>) { - // todo: notify on reset ?? + let old_area = self.area(); self.src_view = view; + let new_area = self.area(); + + if let Some(area) = old_area { self.cast.notify_each(area); } + if let Some(area) = new_area { self.cast.notify_each(area); } } fn notify(&self, msg: &Key) { self.cast.notify(msg); } } + diff --git a/src/index/mod.rs b/src/index/mod.rs index bd02c47..97958be 100644 --- a/src/index/mod.rs +++ b/src/index/mod.rs @@ -1,10 +1,11 @@ pub mod map_item; +pub mod map_key; use { std::{ sync::{Arc, RwLock}, - ops::{Deref, Range} + ops::Deref, }, crate::core::View }; @@ -16,7 +17,7 @@ pub trait IndexView : View { fn get(&self, key: &Key) -> Self::Item; - fn range(&self) -> Option> { + fn area(&self) -> Option> { None } } @@ -30,8 +31,8 @@ impl> IndexView for RwLock { self.read().unwrap().get(key) } - fn range(&self) -> Option> { - self.read().unwrap().range() + fn area(&self) -> Option> { + self.read().unwrap().area() } } @@ -41,9 +42,9 @@ impl> IndexView for Arc { fn get(&self, key: &Key) -> Self::Item { self.deref().get(key) } - - fn range(&self) -> Option> { - self.deref().range() + + fn area(&self) -> Option> { + self.deref().area() } } @@ -54,7 +55,7 @@ pub trait ImplIndexView : Send + Sync { type Value; fn get(&self, key: &Self::Key) -> Self::Value; - fn range(&self) -> Option> { + fn area(&self) -> Option> { None } } @@ -70,7 +71,8 @@ impl IndexView for V { (self as &V).get(key) } - fn range(&self) -> Option> { - (self as &V).range() + fn area(&self) -> Option> { + (self as &V).area() } } + diff --git a/src/string_editor.rs b/src/string_editor.rs index 85db477..b8b5fd4 100644 --- a/src/string_editor.rs +++ b/src/string_editor.rs @@ -1,6 +1,7 @@ + use { std::{ - ops::Range, + boxed::Box, sync::{Arc, RwLock}, }, cgmath::Point2, @@ -16,7 +17,7 @@ use { }, sequence::SequenceView, index::{ImplIndexView}, - grid::{GridView}, + grid::{GridView, GridWindowIterator}, terminal::{TerminalAtom, TerminalStyle, TerminalView}, //vec_buffer::VecBuffer } @@ -37,19 +38,19 @@ impl ImplIndexView for StringEditorState { let data = self.data.read().unwrap(); if pos.y == 0 { - if pos.x < data.len() as i16 + 3 { - let i = pos.x as usize; + let i = pos.x as usize; + if i < data.len() + 3 { return Some( if i == 0 { TerminalAtom::new('"', TerminalStyle::fg_color((180,200,130))) } else if i-1 == self.cursor { - TerminalAtom::new('|', TerminalStyle::fg_color((180,200,130)).add(TerminalStyle::bold(true))) + TerminalAtom::new('|', TerminalStyle::fg_color((180,200,130)).add(TerminalStyle::bold(false))) } else if i-1 == data.len()+1 { TerminalAtom::new('"', TerminalStyle::fg_color((180,200,130))) } else { TerminalAtom::new( data.get(i as usize - if i <= self.cursor { 1 } else { 2 }).unwrap().clone(), - TerminalStyle::fg_color((80,150,80)) + TerminalStyle::fg_color((80,150,80)).add(TerminalStyle::bold(true)) ) } ) @@ -59,11 +60,10 @@ impl ImplIndexView for StringEditorState { None } - fn range(&self) -> Option>> { - Some( + fn area(&self) -> Option>> { + Some(GridWindowIterator::from( Point2::new(0, 0) - .. Point2::new(self.data.read().unwrap().len() as i16 + 3, 1) - ) + .. Point2::new(self.data.read().unwrap().len() as i16 + 3, 1)).collect()) } } diff --git a/src/terminal/compositor.rs b/src/terminal/compositor.rs index 8e92cfe..95045da 100644 --- a/src/terminal/compositor.rs +++ b/src/terminal/compositor.rs @@ -2,7 +2,7 @@ use { std::{ sync::{Arc, Weak, RwLock}, collections::HashMap, - ops::Range, + boxed::Box, cmp::{min, max} }, cgmath::Point2, @@ -29,14 +29,14 @@ impl Observer for CompositeLayer { c.layers.get_mut(&self.idx).unwrap().1 = view.clone(); if let Some(old_view) = old_view { - if let Some(range) = old_view.range() { - c.cast.notify_each(GridWindowIterator::from(range)); + if let Some(area) = old_view.area() { + c.cast.notify_each(area); } } if let Some(view) = view.as_ref() { - if let Some(range) = view.range() { - c.cast.notify_each(GridWindowIterator::from(range)); + if let Some(area) = view.area() { + c.cast.notify_each(area); } } } @@ -55,42 +55,27 @@ impl Observer for CompositeLayer { pub struct TerminalCompositeView { idx_count: usize, layers: HashMap>, Option>)>, - range: Option>>, + area: Option>>, cast: Arc>> } impl TerminalCompositeView { fn update_range(&mut self) { - if self.layers.len() == 0 { - self.range = Some(Point2::new(0, 0) .. Point2::new(0, 0)) - } else { - self.range = None; + self.area = Some(Vec::new()); - for (idx, layer) in self.layers.iter() { - self.range = - if let ( - Some(new_range), - Some(old_range) - ) = ( - if let Some(view) = layer.1.as_ref() { - view.range().clone() - } else { - None - }, - self.range.as_ref() - ) { - Some( - Point2::new( - min(old_range.start.x, new_range.start.x), - min(old_range.start.y, new_range.start.y) - ) .. Point2::new( - max(old_range.end.x, new_range.end.x), - max(old_range.end.y, new_range.end.y) - ) - ) - } else { - None - }; + for (idx, layer) in self.layers.iter() { + if let Some(view) = layer.1.as_ref() { + if let ( + Some(mut new_area), + Some(mut area) + ) = ( + view.area(), + self.area.as_mut() + ) { + area.append(&mut new_area); + } else { + self.area = None; + } } } } @@ -106,6 +91,7 @@ impl ImplIndexView for TerminalCompositeView { for idx in 0 .. self.idx_count { if let Some(l) = self.layers.get(&idx) { if let Some(view) = l.1.as_ref() { + /* if let Some(range) = view.range() { if pos.x < range.start.x || pos.x >= range.end.x || @@ -114,7 +100,7 @@ impl ImplIndexView for TerminalCompositeView { continue; } } - + */ match (atom, view.get(pos)) { (None, next) => atom = next, (Some(last), Some(next)) => atom = Some(next.add_style_back(last.style)), @@ -127,8 +113,8 @@ impl ImplIndexView for TerminalCompositeView { atom } - fn range(&self) -> Option>> { - self.range.clone() + fn area(&self) -> Option>> { + self.area.clone() } } @@ -145,7 +131,7 @@ impl TerminalCompositor { TerminalCompositeView { idx_count: 0, layers: HashMap::new(), - range: Some(Point2::new(0, 0) .. Point2::new(0, 0)), + area: Some(Vec::new()), cast: port.get_broadcast() } )); diff --git a/src/terminal/terminal.rs b/src/terminal/terminal.rs index c3b763f..d01689a 100644 --- a/src/terminal/terminal.rs +++ b/src/terminal/terminal.rs @@ -125,10 +125,9 @@ impl Observer for TermOutObserver { let (w, h) = termion::terminal_size().unwrap(); if let Some(view) = view { - for pos in GridWindowIterator::from( - view.range().unwrap_or( - Point2::new(0, 0) .. Point2::new(w as i16, h as i16) - ) + for pos in view.area().unwrap_or( + GridWindowIterator::from( + Point2::new(0, 0) .. Point2::new(w as i16, h as i16)).collect() ) { self.dirty_pos_tx.send(pos); }