Implement TextArea::important_area

This commit is contained in:
Alexandre Bury 2018-03-22 14:00:18 -07:00
parent 1ad515e5f0
commit a989fd5f80
2 changed files with 44 additions and 7 deletions

View File

@ -597,16 +597,28 @@ impl View for LinearLayout {
} }
fn important_area(&self, _: Vec2) -> Rect { fn important_area(&self, _: Vec2) -> Rect {
if self.children.is_empty() {
// Return dummy area if we are empty.
return Rect::from((0, 0));
}
// Pick the focused item, with its offset
let item = {
let mut iterator = ChildIterator::new( let mut iterator = ChildIterator::new(
self.children.iter(), self.children.iter(),
self.orientation, self.orientation,
usize::max_value(), usize::max_value(),
); );
let item = iterator.nth(self.focus).unwrap(); iterator.nth(self.focus).unwrap()
};
let rect = item.child.view.important_area(item.child.size); // Make a vector offset from the scalar value
let offset = self.orientation.make_vec(item.offset, 0); let offset = self.orientation.make_vec(item.offset, 0);
// And ask the child its own area.
let rect = item.child.view.important_area(item.child.size);
// Add `offset` to the rect.
rect + offset rect + offset
} }
} }

View File

@ -1,6 +1,7 @@
use {Printer, With, XY}; use {Printer, With, XY};
use direction::Direction; use direction::Direction;
use event::{Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Event, EventResult, Key, MouseButton, MouseEvent};
use rect::Rect;
use std::cmp::min; use std::cmp::min;
use theme::{ColorStyle, Effect}; use theme::{ColorStyle, Effect};
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
@ -133,6 +134,10 @@ impl TextArea {
self.row_at(self.cursor) self.row_at(self.cursor)
} }
fn selected_col(&self) -> usize {
self.col_at(self.cursor)
}
fn page_up(&mut self) { fn page_up(&mut self) {
for _ in 0..5 { for _ in 0..5 {
self.move_up(); self.move_up();
@ -593,4 +598,24 @@ impl View for TextArea {
self.last_size = size; self.last_size = size;
self.compute_rows(size); self.compute_rows(size);
} }
fn important_area(&self, _: Vec2) -> Rect {
// The important area is a single character
let char_width = if self.cursor >= self.content.len() {
// If we're are the end of the content, it'll be a space
1
} else {
// Otherwise it's the selected grapheme
self.content[self.cursor..]
.graphemes(true)
.next()
.unwrap()
.width()
};
Rect::from_size(
(self.selected_col(), self.selected_row()),
(char_width, 1),
)
}
} }