Add scrollable flag to TextViews

This commit is contained in:
Alexandre Bury 2016-07-16 17:08:17 -07:00
parent 89468d1786
commit 5ee8706582
3 changed files with 46 additions and 7 deletions

View File

@ -17,7 +17,7 @@ fn main() {
.child(TextView::new("Title").h_align(HAlign::Center))
// Box the textview, so it doesn't get too wide.
// A 0 height value means it will be unconstrained.
.child(BoxView::fixed_width(30, TextView::new(text)))
.child(BoxView::fixed_width(30, TextView::new(text).scrollable(false)))
.child(BoxView::fixed_width(30, TextView::new(text)))
.child(BoxView::fixed_width(30, TextView::new(text)))
.child(BoxView::fixed_width(30, TextView::new(text))))

View File

@ -185,8 +185,8 @@ impl SizeCache {
/// * `size` must fit inside `req`.
/// * for each dimension, `constrained = (size == req)`
fn build(size: Vec2, req: Vec2) -> XY<Self> {
XY::new(SizeCache::new(size.x, size.x == req.x),
SizeCache::new(size.y, size.y == req.y))
XY::new(SizeCache::new(size.x, size.x >= req.x),
SizeCache::new(size.y, size.y >= req.y))
}
}

View File

@ -1,4 +1,5 @@
use XY;
use With;
use direction::Direction;
use vec::Vec2;
use view::View;
@ -19,6 +20,9 @@ pub struct TextView {
align: Align,
// If `false`, disable scrolling.
scrollable: bool,
// ScrollBase make many scrolling-related things easier
scrollbase: ScrollBase,
last_size: Option<XY<SizeCache>>,
@ -48,6 +52,7 @@ impl TextView {
TextView {
content: content.to_string(),
rows: Vec::new(),
scrollable: true,
scrollbase: ScrollBase::new(),
align: Align::top_left(),
last_size: None,
@ -55,6 +60,24 @@ impl TextView {
}
}
/// Enable or disable the view's scrolling capabilities.
///
/// When disabled, the view will never attempt to scroll
/// (and will always ask for the full height).
pub fn set_scrollable(&mut self, scrollable: bool) {
self.scrollable = scrollable;
}
/// Enable or disable the view's scrolling capabilities.
///
/// When disabled, the view will never attempt to scroll
/// (and will always ask for the full height).
///
/// Chainable variant.
pub fn scrollable(self, scrollable: bool) -> Self {
self.with(|s| s.set_scrollable(scrollable))
}
/// Sets the horizontal alignment for this view.
pub fn h_align(mut self, h: HAlign) -> Self {
self.align.h = h;
@ -100,7 +123,7 @@ impl TextView {
// Recompute
self.rows = LinesIterator::new(&self.content, size.x).collect();
let mut scrollbar = 0;
if self.rows.len() > size.y {
if self.scrollable && self.rows.len() > size.y {
scrollbar = 2;
// If we're too high, include a scrollbar
self.rows = LinesIterator::new(&self.content,
@ -108,6 +131,7 @@ impl TextView {
.collect();
}
// Desired width, including the scrollbar.
self.width = self.rows
.iter()
.map(|row| row.width)
@ -115,8 +139,15 @@ impl TextView {
.map(|w| w + scrollbar);
// Our resulting size.
let my_size =
size.or_min((self.width.unwrap_or(0), self.rows.len()));
// We can't go lower, width-wise.
let mut my_size = Vec2::new(self.width.unwrap_or(0),
self.rows.len());
if self.scrollable && my_size.y > size.y {
my_size.y = size.y;
}
self.last_size = Some(SizeCache::build(my_size, size));
}
}
@ -237,7 +268,15 @@ impl View for TextView {
fn get_min_size(&mut self, size: Vec2) -> Vec2 {
self.compute_rows(size);
size.or_min((self.width.unwrap_or(0), self.rows.len()))
// This is what we'd like
let mut ideal = Vec2::new(self.width.unwrap_or(0), self.rows.len());
if self.scrollable && ideal.y > size.y {
ideal.y = size.y;
}
ideal
}
fn take_focus(&mut self, _: Direction) -> bool {