mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 11:16:03 +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 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,
|
||||
/// End of the row (excluded)
|
||||
pub end: usize,
|
||||
|
||||
/// Width of the row, in cells.
|
||||
pub width: usize,
|
||||
|
||||
/// Whether or not this text was wrapped onto the next line
|
||||
pub is_wrapped: bool,
|
||||
}
|
||||
|
||||
impl Row {
|
||||
|
@ -149,16 +149,10 @@ where
|
||||
|
||||
// We can know text was wrapped if the stop was optional,
|
||||
// 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();
|
||||
|
||||
// If we had to break a line in two, then at least pretent we're
|
||||
// taking the full width.
|
||||
let width = if text_wrap {
|
||||
self.width
|
||||
} else {
|
||||
chunks.iter().map(|c| c.width).sum()
|
||||
};
|
||||
let width = chunks.iter().map(|c| c.width).sum();
|
||||
|
||||
assert!(width <= self.width);
|
||||
|
||||
@ -170,6 +164,10 @@ where
|
||||
|
||||
// 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>,
|
||||
/// Total width for this row
|
||||
pub width: usize,
|
||||
/// Whether or not this text was wrapped onto the next line
|
||||
pub is_wrapped: bool,
|
||||
}
|
||||
|
||||
impl Row {
|
||||
|
@ -287,6 +287,7 @@ impl TextArea {
|
||||
start: self.content.len(),
|
||||
end: self.content.len(),
|
||||
width: 0,
|
||||
is_wrapped: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -471,12 +472,15 @@ impl View for TextArea {
|
||||
// And y = number of rows
|
||||
debug!("{:?}", self.rows);
|
||||
let scroll_width = if self.rows.len() > constraint.y { 1 } else { 0 };
|
||||
Vec2::new(
|
||||
scroll_width
|
||||
+ 1
|
||||
+ self.rows.iter().map(|r| r.width).max().unwrap_or(1),
|
||||
self.rows.len(),
|
||||
)
|
||||
|
||||
let content_width = if self.rows.iter().any(|row| row.is_wrapped) {
|
||||
// If any row has been wrapped, we want to take the full width.
|
||||
constraint.x.saturating_sub(1 + scroll_width)
|
||||
} 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) {
|
||||
|
@ -357,7 +357,12 @@ impl TextView {
|
||||
LinesIterator::new(content.get_cache().as_ref(), size.x).collect();
|
||||
|
||||
// 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