terminal/cells: return success flag in CellBuffer::resize()

jmap-eventsource
Manos Pitsidianakis 2020-12-01 01:02:48 +02:00
parent 857d4d546f
commit 7db32ff1b3
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 51 additions and 33 deletions

View File

@ -105,7 +105,8 @@ impl ContactManager {
if self.card.external_resource() { if self.card.external_resource() {
self.mode = ViewMode::ReadOnly; self.mode = ViewMode::ReadOnly;
self.content let _ = self
.content
.resize(self.content.size().0, 2, Cell::default()); .resize(self.content.size().0, 2, Cell::default());
write_string_to_grid( write_string_to_grid(
"This contact's origin is external and cannot be edited within meli.", "This contact's origin is external and cannot be edited within meli.",

View File

@ -517,8 +517,14 @@ impl State {
} }
self.cols = termcols.unwrap_or(72) as usize; self.cols = termcols.unwrap_or(72) as usize;
self.rows = termrows.unwrap_or(120) as usize; self.rows = termrows.unwrap_or(120) as usize;
self.grid.resize(self.cols, self.rows, Cell::with_char(' ')); if !self.grid.resize(self.cols, self.rows, Cell::with_char(' ')) {
self.overlay_grid panic!(
"Terminal size too big: ({} cols, {} rows)",
self.cols, self.rows
);
}
let _ = self
.overlay_grid
.resize(self.cols, self.rows, Cell::with_char(' ')); .resize(self.cols, self.rows, Cell::with_char(' '));
self.rcv_event(UIEvent::Resize); self.rcv_event(UIEvent::Resize);

View File

@ -82,6 +82,7 @@ impl fmt::Debug for CellBuffer {
} }
impl CellBuffer { impl CellBuffer {
pub const MAX_SIZE: usize = 300_000;
pub fn area(&self) -> Area { pub fn area(&self) -> Area {
( (
(0, 0), (0, 0),
@ -143,16 +144,11 @@ impl CellBuffer {
/// Resizes `CellBuffer` to the given number of rows and columns, using the given `Cell` as /// Resizes `CellBuffer` to the given number of rows and columns, using the given `Cell` as
/// a blank. /// a blank.
pub fn resize(&mut self, newcols: usize, newrows: usize, blank: Cell) { #[must_use]
pub fn resize(&mut self, newcols: usize, newrows: usize, blank: Cell) -> bool {
let newlen = newcols * newrows; let newlen = newcols * newrows;
if self.buf.len() == newlen { if (self.cols, self.rows) == (newcols, newrows) || newlen >= Self::MAX_SIZE {
self.cols = newcols; return !(newlen >= Self::MAX_SIZE);
self.rows = newrows;
return;
}
if newlen >= 200_000 {
return;
} }
let mut newbuf: Vec<Cell> = Vec::with_capacity(newlen); let mut newbuf: Vec<Cell> = Vec::with_capacity(newlen);
@ -165,6 +161,7 @@ impl CellBuffer {
self.buf = newbuf; self.buf = newbuf;
self.cols = newcols; self.cols = newcols;
self.rows = newrows; self.rows = newrows;
true
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
@ -1086,28 +1083,32 @@ macro_rules! inspect_bounds {
let (upper_left, bottom_right) = $area; let (upper_left, bottom_right) = $area;
if $x > (get_x(bottom_right)) || $x >= get_x(bounds) { if $x > (get_x(bottom_right)) || $x >= get_x(bounds) {
if $grid.growable { if $grid.growable {
$grid.resize( if !$grid.resize(
std::cmp::max($x + 1, $grid.cols), std::cmp::max($x + 1, $grid.cols),
$grid.rows, $grid.rows,
$grid.default_cell, $grid.default_cell,
); ) {
break;
};
} else { } else {
$x = get_x(upper_left); $x = get_x(upper_left);
$y += 1; $y += 1;
if $line_break.is_none() { if let Some(_x) = $line_break {
break; $x = _x;
} else { } else {
$x = $line_break.unwrap(); break;
} }
} }
} }
if $y > (get_y(bottom_right)) || $y >= get_y(bounds) { if $y > (get_y(bottom_right)) || $y >= get_y(bounds) {
if $grid.growable { if $grid.growable {
$grid.resize( if !$grid.resize(
$grid.cols, $grid.cols,
std::cmp::max($y + 1, $grid.rows), std::cmp::max($y + 1, $grid.rows),
$grid.default_cell, $grid.default_cell,
); ) {
break;
};
} else { } else {
return ($x, $y - 1); return ($x, $y - 1);
} }
@ -1126,17 +1127,20 @@ pub fn write_string_to_grid(
// The left-most x coordinate. // The left-most x coordinate.
line_break: Option<usize>, line_break: Option<usize>,
) -> Pos { ) -> Pos {
let bounds = grid.size(); let mut bounds = grid.size();
let upper_left = upper_left!(area); let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area); let bottom_right = bottom_right!(area);
let (mut x, mut y) = upper_left; let (mut x, mut y) = upper_left;
if y == get_y(bounds) || x == get_x(bounds) { if y == get_y(bounds) || x == get_x(bounds) {
if grid.growable { if grid.growable {
grid.resize( if !grid.resize(
std::cmp::max(grid.cols, x + 1), std::cmp::max(grid.cols, x + 2),
std::cmp::max(grid.rows, y + 1), std::cmp::max(grid.rows, y + 2),
grid.default_cell, grid.default_cell,
); ) {
return (x, y);
}
bounds = grid.size();
} else { } else {
return (x, y); return (x, y);
} }
@ -1148,11 +1152,13 @@ pub fn write_string_to_grid(
|| x > get_x(bounds) || x > get_x(bounds)
{ {
if grid.growable { if grid.growable {
grid.resize( if !grid.resize(
std::cmp::max(grid.cols, x + 1), std::cmp::max(grid.cols, x + 2),
std::cmp::max(grid.rows, y + 1), std::cmp::max(grid.rows, y + 2),
grid.default_cell, grid.default_cell,
); ) {
return (x, y);
}
} else { } else {
debug!(" Invalid area with string {} and area {:?}", s, area); debug!(" Invalid area with string {} and area {:?}", s, area);
return (x, y); return (x, y);
@ -1165,12 +1171,12 @@ pub fn write_string_to_grid(
} }
if c == '\n' { if c == '\n' {
y += 1; y += 1;
if line_break.is_none() { if let Some(_x) = line_break {
break; x = _x;
} else {
x = line_break.unwrap();
inspect_bounds!(grid, area, x, y, line_break); inspect_bounds!(grid, area, x, y, line_break);
continue; continue;
} else {
break;
} }
} }
if c == '\t' { if c == '\t' {

View File

@ -108,7 +108,12 @@ impl EmbedGrid {
self.scroll_region.bottom = new_val.1.saturating_sub(1); self.scroll_region.bottom = new_val.1.saturating_sub(1);
self.terminal_size = new_val; self.terminal_size = new_val;
self.grid.resize(new_val.0, new_val.1, Cell::default()); if !self.grid.resize(new_val.0, new_val.1, Cell::default()) {
panic!(
"Terminal size too big: ({} cols, {} rows)",
new_val.0, new_val.1
);
}
self.grid.clear(Cell::default()); self.grid.clear(Cell::default());
self.cursor = (0, 0); self.cursor = (0, 0);
self.wrap_next = false; self.wrap_next = false;