meli/terminal/screen.rs: draw with x range argument

Instead of providing the horizontal range to draw as x_start and x_end
values, provide a range instead. This is to ensure that when you want to
draw from a bounds/row iterator, which has a col() method that returns
std::ops::Range<usize>, you don't end up drawing from col().start up to
including col().end like I foolishly did.

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/436/head
Manos Pitsidianakis 2 months ago
parent a85b3a089f
commit a9122c6e34
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -614,19 +614,19 @@ impl State {
continue;
}
if let Some((x_start, x_end)) = segment.take() {
self.screen.draw(x_start, x_end, y);
self.screen.draw(x_start..(x_end + 1), y);
}
match segment {
ref mut s @ None => {
*s = Some((x_start, x_end));
None => {
segment = Some((x_start, x_end));
}
ref mut s @ Some(_) if s.unwrap().1 < x_start => {
self.screen.draw(s.unwrap().0, s.unwrap().1, y);
*s = Some((x_start, x_end));
Some((p_x_start, p_x_end)) if p_x_end < x_start => {
self.screen.draw(p_x_start..(p_x_end + 1), y);
segment = Some((x_start, x_end));
}
ref mut s @ Some(_) if s.unwrap().1 < x_end => {
self.screen.draw(s.unwrap().0, s.unwrap().1, y);
*s = Some((s.unwrap().1, x_end));
Some((p_x_start, p_x_end)) if p_x_end < x_end => {
self.screen.draw(p_x_start..(p_x_end + 1), y);
segment = Some((p_x_end, x_end));
}
Some((_, ref mut x)) => {
*x = x_end;
@ -634,7 +634,7 @@ impl State {
}
}
if let Some((x_start, x_end)) = segment {
self.screen.draw(x_start, x_end, y);
self.screen.draw(x_start..(x_end + 1), y);
}
}
@ -652,8 +652,7 @@ impl State {
.grid()
.bounds_iter(self.message_box.cached_area())
{
self.screen
.draw(row.cols().start, row.cols().end, row.row_index());
self.screen.draw(row.cols(), row.row_index());
}
}
}
@ -666,8 +665,7 @@ impl State {
.overlay_grid()
.bounds_iter(self.message_box.cached_area())
{
self.screen
.draw_overlay(row.cols().start, row.cols().end, row.row_index());
self.screen.draw_overlay(row.cols(), row.row_index());
}
}
self.message_box.set_dirty(false);
@ -679,8 +677,7 @@ impl State {
.grid()
.bounds_iter(self.message_box.cached_area())
{
self.screen
.draw(row.cols().start, row.cols().end, row.row_index());
self.screen.draw(row.cols(), row.row_index());
}
}
self.message_box.set_dirty(false);
@ -710,8 +707,7 @@ impl State {
);
}
for row in self.screen.overlay_grid().bounds_iter(overlay_area) {
self.screen
.draw_overlay(row.cols().start, row.cols().end, row.row_index());
self.screen.draw_overlay(row.cols(), row.row_index());
}
}
self.flush();

@ -39,7 +39,8 @@ pub type StateStdout = termion::screen::AlternateScreen<
termion::raw::RawTerminal<BufWriter<Box<dyn Write + 'static>>>,
>;
type DrawHorizontalSegmentFn = fn(&mut CellBuffer, &mut StateStdout, usize, usize, usize) -> ();
type DrawHorizontalSegmentFn =
fn(&mut CellBuffer, &mut StateStdout, std::ops::Range<usize>, usize) -> ();
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
@ -292,25 +293,19 @@ impl Screen<Tty> {
}
#[inline]
pub fn draw(&mut self, x_start: usize, x_end: usize, y: usize) {
pub fn draw(&mut self, xs: std::ops::Range<usize>, y: usize) {
let Some(stdout) = self.display.stdout.as_mut() else {
return;
};
(self.display.draw_horizontal_segment_fn)(&mut self.grid, stdout, x_start, x_end, y);
(self.display.draw_horizontal_segment_fn)(&mut self.grid, stdout, xs, y);
}
#[inline]
pub fn draw_overlay(&mut self, x_start: usize, x_end: usize, y: usize) {
pub fn draw_overlay(&mut self, xs: std::ops::Range<usize>, y: usize) {
let Some(stdout) = self.display.stdout.as_mut() else {
return;
};
(self.display.draw_horizontal_segment_fn)(
&mut self.overlay_grid,
stdout,
x_start,
x_end,
y,
);
(self.display.draw_horizontal_segment_fn)(&mut self.overlay_grid, stdout, xs, y);
}
/// On `SIGWNICH` the `State` redraws itself according to the new
@ -423,21 +418,20 @@ impl Screen<Tty> {
pub fn draw_horizontal_segment(
grid: &mut CellBuffer,
stdout: &mut StateStdout,
x_start: usize,
x_end: usize,
xs: std::ops::Range<usize>,
y: usize,
) {
write!(
stdout,
"{}",
cursor::Goto(x_start as u16 + 1, (y + 1) as u16)
cursor::Goto(xs.start as u16 + 1, (y + 1) as u16)
)
.unwrap();
let mut current_fg = Color::Default;
let mut current_bg = Color::Default;
let mut current_attrs = Attr::DEFAULT;
write!(stdout, "\x1B[m").unwrap();
for x in x_start..=x_end {
for x in xs {
let c = &grid[(x, y)];
if c.attrs() != current_attrs {
c.attrs().write(current_attrs, stdout).unwrap();
@ -463,19 +457,18 @@ impl Screen<Tty> {
pub fn draw_horizontal_segment_no_color(
grid: &mut CellBuffer,
stdout: &mut StateStdout,
x_start: usize,
x_end: usize,
xs: std::ops::Range<usize>,
y: usize,
) {
write!(
stdout,
"{}",
cursor::Goto(x_start as u16 + 1, (y + 1) as u16)
cursor::Goto(xs.start as u16 + 1, (y + 1) as u16)
)
.unwrap();
let mut current_attrs = Attr::DEFAULT;
write!(stdout, "\x1B[m").unwrap();
for x in x_start..=x_end {
for x in xs {
let c = &grid[(x, y)];
if c.attrs() != current_attrs {
c.attrs().write(current_attrs, stdout).unwrap();

Loading…
Cancel
Save