mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 19:26:09 +00:00
Fix text alignment when wrapped (#471)
* Fix text alignment when wrapped
This changes the `LinesIterator` to return a `width` that corresponds
with the actual total length of the chunks, rather than returning the
total available width, when a line is wrapped. This effectively reverts
20cb033b8d
(I am not sure why that commit
changed it).
* Add `is_wrapped` flag to `Row`
* Fix TextArea width with wrapped rows
Co-authored-by: Alexandre Bury <alexandre.bury@gmail.com>
This commit is contained in:
parent
d96904a07d
commit
bc49eebeb8
@ -67,8 +67,15 @@ impl<'a> Iterator for LinesIterator<'a> {
|
|||||||
let start = row.segments.first()?.start;
|
let start = row.segments.first()?.start;
|
||||||
let end = row.segments.last()?.end;
|
let end = row.segments.last()?.end;
|
||||||
|
|
||||||
let width = row.width;
|
let spans::Row {
|
||||||
|
width, is_wrapped, ..
|
||||||
|
} = row;
|
||||||
|
|
||||||
Some(Row { start, end, width })
|
Some(Row {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
width,
|
||||||
|
is_wrapped,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,12 @@ pub struct Row {
|
|||||||
pub start: usize,
|
pub start: usize,
|
||||||
/// End of the row (excluded)
|
/// End of the row (excluded)
|
||||||
pub end: usize,
|
pub end: usize,
|
||||||
|
|
||||||
/// Width of the row, in cells.
|
/// Width of the row, in cells.
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
|
|
||||||
|
/// Whether or not this text was wrapped onto the next line
|
||||||
|
pub is_wrapped: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Row {
|
impl Row {
|
||||||
|
@ -149,16 +149,10 @@ where
|
|||||||
|
|
||||||
// We can know text was wrapped if the stop was optional,
|
// We can know text was wrapped if the stop was optional,
|
||||||
// and there's more coming.
|
// and there's more coming.
|
||||||
let text_wrap = !chunks.last().map(|c| c.hard_stop).unwrap_or(true)
|
let is_wrapped = !chunks.last().map(|c| c.hard_stop).unwrap_or(true)
|
||||||
&& self.iter.peek().is_some();
|
&& self.iter.peek().is_some();
|
||||||
|
|
||||||
// If we had to break a line in two, then at least pretent we're
|
let width = chunks.iter().map(|c| c.width).sum();
|
||||||
// taking the full width.
|
|
||||||
let width = if text_wrap {
|
|
||||||
self.width
|
|
||||||
} else {
|
|
||||||
chunks.iter().map(|c| c.width).sum()
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(width <= self.width);
|
assert!(width <= self.width);
|
||||||
|
|
||||||
@ -170,6 +164,10 @@ where
|
|||||||
|
|
||||||
// TODO: merge consecutive segments of the same span
|
// TODO: merge consecutive segments of the same span
|
||||||
|
|
||||||
Some(Row { segments, width })
|
Some(Row {
|
||||||
|
segments,
|
||||||
|
width,
|
||||||
|
is_wrapped,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ pub struct Row {
|
|||||||
pub segments: Vec<Segment>,
|
pub segments: Vec<Segment>,
|
||||||
/// Total width for this row
|
/// Total width for this row
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
|
/// Whether or not this text was wrapped onto the next line
|
||||||
|
pub is_wrapped: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Row {
|
impl Row {
|
||||||
|
@ -287,6 +287,7 @@ impl TextArea {
|
|||||||
start: self.content.len(),
|
start: self.content.len(),
|
||||||
end: self.content.len(),
|
end: self.content.len(),
|
||||||
width: 0,
|
width: 0,
|
||||||
|
is_wrapped: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,12 +472,15 @@ impl View for TextArea {
|
|||||||
// And y = number of rows
|
// And y = number of rows
|
||||||
debug!("{:?}", self.rows);
|
debug!("{:?}", self.rows);
|
||||||
let scroll_width = if self.rows.len() > constraint.y { 1 } else { 0 };
|
let scroll_width = if self.rows.len() > constraint.y { 1 } else { 0 };
|
||||||
Vec2::new(
|
|
||||||
scroll_width
|
let content_width = if self.rows.iter().any(|row| row.is_wrapped) {
|
||||||
+ 1
|
// If any row has been wrapped, we want to take the full width.
|
||||||
+ self.rows.iter().map(|r| r.width).max().unwrap_or(1),
|
constraint.x.saturating_sub(1 + scroll_width)
|
||||||
self.rows.len(),
|
} else {
|
||||||
)
|
self.rows.iter().map(|r| r.width).max().unwrap_or(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
Vec2::new(scroll_width + 1 + content_width, self.rows.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, printer: &Printer) {
|
fn draw(&self, printer: &Printer) {
|
||||||
|
@ -357,7 +357,12 @@ impl TextView {
|
|||||||
LinesIterator::new(content.get_cache().as_ref(), size.x).collect();
|
LinesIterator::new(content.get_cache().as_ref(), size.x).collect();
|
||||||
|
|
||||||
// Desired width
|
// Desired width
|
||||||
self.width = self.rows.iter().map(|row| row.width).max();
|
self.width = if self.rows.iter().any(|row| row.is_wrapped) {
|
||||||
|
// If any rows are wrapped, then require the full width.
|
||||||
|
Some(size.x)
|
||||||
|
} else {
|
||||||
|
self.rows.iter().map(|row| row.width).max()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user