index view: replace range() with area()

This commit is contained in:
Michael Sippel 2021-01-16 13:57:06 +01:00
parent f3fa8a7af1
commit 6fe50416b5
Signed by: senvas
GPG key ID: F96CF119C34B64A6
6 changed files with 78 additions and 88 deletions

View file

@ -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<i16>) {
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<Range<Point2<i16>>> {
let src_range = self.src.as_ref()?.range()?;
Some((src_range.start + self.offset) .. (src_range.end + self.offset))
fn area(&self) -> Option<Vec<Point2<i16>>> {
Some(
self.src.as_ref()?
.area()?.into_iter()
.map(|pos| pos + self.offset)
.collect()
)
}
}
impl<V: GridView + ?Sized> Observer<V> for GridOffset<V>
where V::Item: Default {
fn reset(&mut self, view: Option<Arc<V>>) {
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<i16>) {

View file

@ -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<Range<Key>> {
self.src_view.as_ref()?.range()
fn area(&self) -> Option<Vec<Key>> {
self.src_view.as_ref()?.area()
}
}
impl<Key, DstItem, SrcView, F> Observer<SrcView> for MapIndexItem<Key, DstItem, SrcView, F>
where SrcView: IndexView<Key> + ?Sized,
where DstItem: Default,
SrcView: IndexView<Key> + ?Sized,
F: Fn(&SrcView::Item) -> DstItem + Send + Sync
{
fn reset(&mut self, view: Option<Arc<SrcView>>) {
// 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);
}
}

View file

@ -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<Key> : View<Msg = Key> {
fn get(&self, key: &Key) -> Self::Item;
fn range(&self) -> Option<Range<Key>> {
fn area(&self) -> Option<Vec<Key>> {
None
}
}
@ -30,8 +31,8 @@ impl<Key, V: IndexView<Key>> IndexView<Key> for RwLock<V> {
self.read().unwrap().get(key)
}
fn range(&self) -> Option<Range<Key>> {
self.read().unwrap().range()
fn area(&self) -> Option<Vec<Key>> {
self.read().unwrap().area()
}
}
@ -42,8 +43,8 @@ impl<Key, V: IndexView<Key>> IndexView<Key> for Arc<V> {
self.deref().get(key)
}
fn range(&self) -> Option<Range<Key>> {
self.deref().range()
fn area(&self) -> Option<Vec<Key>> {
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<Range<Self::Key>> {
fn area(&self) -> Option<Vec<Self::Key>> {
None
}
}
@ -70,7 +71,8 @@ impl<V: ImplIndexView> IndexView<V::Key> for V {
(self as &V).get(key)
}
fn range(&self) -> Option<Range<V::Key>> {
(self as &V).range()
fn area(&self) -> Option<Vec<V::Key>> {
(self as &V).area()
}
}

View file

@ -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;
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<Range<Point2<i16>>> {
Some(
fn area(&self) -> Option<Vec<Point2<i16>>> {
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())
}
}

View file

@ -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<dyn TerminalView> 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<dyn TerminalView> for CompositeLayer {
pub struct TerminalCompositeView {
idx_count: usize,
layers: HashMap<usize, (Arc<RwLock<CompositeLayer>>, Option<Arc<dyn TerminalView>>)>,
range: Option<Range<Point2<i16>>>,
area: Option<Vec<Point2<i16>>>,
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>
}
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()
if let (
Some(mut new_area),
Some(mut area)
) = (
view.area(),
self.area.as_mut()
) {
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)
)
)
area.append(&mut new_area);
} else {
None
};
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<Range<Point2<i16>>> {
self.range.clone()
fn area(&self) -> Option<Vec<Point2<i16>>> {
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()
}
));

View file

@ -125,10 +125,9 @@ impl Observer<dyn TerminalView> 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);
}