index view: replace range() with area()
This commit is contained in:
parent
f3fa8a7af1
commit
6fe50416b5
6 changed files with 78 additions and 88 deletions
|
@ -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>) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
) {
|
||||
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<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()
|
||||
}
|
||||
));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue