From 810dc6a591eb20e4e87be2fb47de446eef731e8b Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Wed, 12 Sep 2018 16:13:41 -0700 Subject: [PATCH] Fix desperate LinearLayout --- src/utils/lines/simple/lines_iterator.rs | 1 - src/views/linear_layout.rs | 18 ++++++++++-------- src/views/stack_view.rs | 6 ++++-- src/views/text_area.rs | 10 ++++++++++ 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/utils/lines/simple/lines_iterator.rs b/src/utils/lines/simple/lines_iterator.rs index 8305739..a90584a 100644 --- a/src/utils/lines/simple/lines_iterator.rs +++ b/src/utils/lines/simple/lines_iterator.rs @@ -63,7 +63,6 @@ impl<'a> Iterator for LinesIterator<'a> { fn next(&mut self) -> Option { let row = self.iter.next()?; - // println!("Got a row: {:?}", row); let start = row.segments.first()?.start; let end = row.segments.last()?.end; diff --git a/src/views/linear_layout.rs b/src/views/linear_layout.rs index e5722e1..e603618 100644 --- a/src/views/linear_layout.rs +++ b/src/views/linear_layout.rs @@ -78,7 +78,7 @@ impl<'a, T: Deref, I: Iterator> Iterator // Save the current offset. let offset = self.offset; - // eprintln!("Available: {}", self.available); + // debug!("Available: {}", self.available); let length = min(self.available, *child.size.get(self.orientation)); @@ -336,16 +336,16 @@ fn try_focus( impl View for LinearLayout { fn draw(&self, printer: &Printer) { // Use pre-computed sizes - // eprintln!("Pre loop!"); + // debug!("Pre loop!"); for (i, item) in ChildIterator::new( self.children.iter(), self.orientation, *printer.size.get(self.orientation), ).enumerate() { - // eprintln!("Printer size: {:?}", printer.size); - // eprintln!("Child size: {:?}", item.child.size); - // eprintln!("Offset: {:?}", item.offset); + // debug!("Printer size: {:?}", printer.size); + // debug!("Child size: {:?}", item.child.size); + // debug!("Offset: {:?}", item.offset); let printer = &printer .offset(self.orientation.make_vec(item.offset, 0)) .cropped(item.child.size) @@ -364,7 +364,7 @@ impl View for LinearLayout { fn layout(&mut self, size: Vec2) { // If we can get away without breaking a sweat, you can bet we will. - // eprintln!("Laying out with {:?}", size); + // debug!("Laying out with {:?}", size); if self.get_cache(size).is_none() { self.required_size(size); } @@ -387,6 +387,7 @@ impl View for LinearLayout { if let Some(size) = self.get_cache(req) { return size; } + debug!("Req: {:?}", req); // First, make a naive scenario: everything will work fine. let ideal_sizes: Vec = self @@ -425,7 +426,7 @@ impl View for LinearLayout { // This is the lowest we'll ever go. It better fit at least. let orientation = self.orientation; - if !desperate.fits_in(req) { + if desperate.get(orientation) > req.get(orientation) { // Just give up... // TODO: hard-cut cap( @@ -447,7 +448,8 @@ impl View for LinearLayout { // This here is how much we're generously offered // (We just checked that req >= desperate, so the subtraction is safe - let mut available = self.orientation.get(&(req - desperate)); + let mut available = + self.orientation.get(&(req.saturating_sub(desperate))); debug!("Available: {:?}", available); // Here, we have to make a compromise between the ideal diff --git a/src/views/stack_view.rs b/src/views/stack_view.rs index f6b155c..8990f7a 100644 --- a/src/views/stack_view.rs +++ b/src/views/stack_view.rs @@ -56,9 +56,11 @@ impl Placement { enum ChildWrapper { // Some views include a shadow around. Shadow(ShadowView>), - // Some include a background. + + // Some include only include a background. Backfilled(Layer), - // Some views don't (fullscreen views mostly) + + // Some views don't even have a background (they'll be transparent). Plain(T), } diff --git a/src/views/text_area.rs b/src/views/text_area.rs index 1dab7c5..30affcc 100644 --- a/src/views/text_area.rs +++ b/src/views/text_area.rs @@ -18,7 +18,10 @@ use {Printer, With, XY}; pub struct TextArea { // TODO: use a smarter data structure (rope?) content: String, + /// Byte offsets within `content` representing text rows + /// + /// Invariant: never empty. rows: Vec, /// When `false`, we don't take any input. @@ -36,6 +39,8 @@ pub struct TextArea { } fn make_rows(text: &str, width: usize) -> Vec { + // We can't make rows with width=0, so force at least width=1. + let width = usize::max(width, 1); LinesIterator::new(text, width).show_spaces().collect() } @@ -142,6 +147,10 @@ impl TextArea { /// Finds the row containing the grapheme at the given offset fn row_at(&self, offset: usize) -> usize { debug!("Offset: {}", offset); + + assert!(!self.rows.is_empty()); + assert!(offset >= self.rows[0].start); + self.rows .iter() .enumerate() @@ -160,6 +169,7 @@ impl TextArea { /// Finds the row containing the cursor fn selected_row(&self) -> usize { + assert!(!self.rows.is_empty(), "Rows should never be empty."); self.row_at(self.cursor) }