From 5ee8706582eccce7237c6654b23ac4991ccaa7ea Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Sat, 16 Jul 2016 17:08:17 -0700 Subject: [PATCH] Add `scrollable` flag to TextViews --- examples/linear.rs | 2 +- src/view/mod.rs | 4 ++-- src/view/text_view.rs | 47 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/examples/linear.rs b/examples/linear.rs index ddb0805..63ea903 100644 --- a/examples/linear.rs +++ b/examples/linear.rs @@ -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)))) diff --git a/src/view/mod.rs b/src/view/mod.rs index 8f0b016..753d333 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -185,8 +185,8 @@ impl SizeCache { /// * `size` must fit inside `req`. /// * for each dimension, `constrained = (size == req)` fn build(size: Vec2, req: Vec2) -> XY { - 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)) } } diff --git a/src/view/text_view.rs b/src/view/text_view.rs index 3d7d33b..8a96913 100644 --- a/src/view/text_view.rs +++ b/src/view/text_view.rs @@ -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>, @@ -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 {