Fix desperate LinearLayout

This commit is contained in:
Alexandre Bury 2018-09-12 16:13:41 -07:00
parent be977c705f
commit 810dc6a591
4 changed files with 24 additions and 11 deletions

View File

@ -63,7 +63,6 @@ impl<'a> Iterator for LinesIterator<'a> {
fn next(&mut self) -> Option<Row> {
let row = self.iter.next()?;
// println!("Got a row: {:?}", row);
let start = row.segments.first()?.start;
let end = row.segments.last()?.end;

View File

@ -78,7 +78,7 @@ impl<'a, T: Deref<Target = Child>, I: Iterator<Item = T>> 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<Vec2> = 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

View File

@ -56,9 +56,11 @@ impl Placement {
enum ChildWrapper<T: View> {
// Some views include a shadow around.
Shadow(ShadowView<Layer<T>>),
// Some include a background.
// Some include only include a background.
Backfilled(Layer<T>),
// Some views don't (fullscreen views mostly)
// Some views don't even have a background (they'll be transparent).
Plain(T),
}

View File

@ -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<Row>,
/// When `false`, we don't take any input.
@ -36,6 +39,8 @@ pub struct TextArea {
}
fn make_rows(text: &str, width: usize) -> Vec<Row> {
// 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)
}