aboutsummaryrefslogtreecommitdiff
path: root/src/grid.rs
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2016-06-29 10:21:02 -0700
committerJoe Wilm <joe@jwilm.com>2016-06-29 10:21:02 -0700
commit22789f35c7ab90a5ada70fdca25ca1c626eb1ca5 (patch)
tree4588f58a30b542a09fedc143f8ed710115440923 /src/grid.rs
parent69ed81d2495c6eb548c44e73c0e9ed359d3820f0 (diff)
downloadalacritty-22789f35c7ab90a5ada70fdca25ca1c626eb1ca5.tar.gz
alacritty-22789f35c7ab90a5ada70fdca25ca1c626eb1ca5.zip
Implement terminal resizing
The resize event is received from glutin on the update thread, but the renderer needs to be informed as well for updating the viewport and projection matrix. This is achieved with an mpsc::channel. To support resizing, the grid now offers methods for growing and shrinking, and there are several implementations available for clear_region based on different Range* types. Core resize logic is all in Term::resize. It attempts to keep as much context as possible when shinking the window. When growing, it's basically just adding rows.
Diffstat (limited to 'src/grid.rs')
-rw-r--r--src/grid.rs88
1 files changed, 83 insertions, 5 deletions
diff --git a/src/grid.rs b/src/grid.rs
index 42dcf210..3ce0a036 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -1,6 +1,7 @@
//! Functions for computing properties of the terminal grid
use std::ops::{Index, IndexMut, Deref, DerefMut, Range, RangeTo, RangeFrom};
+use std::cmp::Ordering;
use std::slice::{Iter, IterMut};
use util::Rotate;
@@ -104,12 +105,55 @@ impl Grid {
self.clear_region(region);
}
- pub fn clear_region(&mut self, region: Range<usize>) {
- for row in self.raw[region].iter_mut() {
- for cell in row.iter_mut() {
- cell.reset();
- }
+ pub fn resize(&mut self, rows: usize, cols: usize) {
+ // Check that there's actually work to do and return early if not
+ if rows == self.rows && cols == self.cols {
+ return;
+ }
+
+ match self.rows.cmp(&rows) {
+ Ordering::Less => self.grow_rows(rows),
+ Ordering::Greater => self.shrink_rows(rows),
+ Ordering::Equal => (),
+ }
+
+ match self.cols.cmp(&cols) {
+ Ordering::Less => self.grow_cols(cols),
+ Ordering::Greater => self.shrink_cols(cols),
+ Ordering::Equal => (),
+ }
+ }
+
+ fn grow_rows(&mut self, rows: usize) {
+ for _ in self.num_rows()..rows {
+ self.raw.push(Row::new(self.cols));
+ }
+
+ self.rows = rows;
+ }
+
+ fn shrink_rows(&mut self, rows: usize) {
+ while self.raw.len() != rows {
+ self.raw.pop();
}
+
+ self.rows = rows;
+ }
+
+ fn grow_cols(&mut self, cols: usize) {
+ for row in self.rows_mut() {
+ row.grow(cols);
+ }
+
+ self.cols = cols;
+ }
+
+ fn shrink_cols(&mut self, cols: usize) {
+ for row in self.rows_mut() {
+ row.shrink(cols);
+ }
+
+ self.cols = cols;
}
}
@@ -154,6 +198,18 @@ impl Row {
Row(vec![Cell::new(' '); columns])
}
+ pub fn grow(&mut self, cols: usize) {
+ while self.len() != cols {
+ self.push(Cell::new(' '));
+ }
+ }
+
+ pub fn shrink(&mut self, cols: usize) {
+ while self.len() != cols {
+ self.pop();
+ }
+ }
+
pub fn cells(&self) -> Iter<Cell> {
self.0.iter()
}
@@ -221,3 +277,25 @@ impl IndexMut<RangeTo<usize>> for Row {
&mut self.0[index]
}
}
+
+pub trait ClearRegion<T> {
+ fn clear_region(&mut self, region: T);
+}
+
+macro_rules! clear_region_impl {
+ ($range:ty) => {
+ impl ClearRegion<$range> for Grid {
+ fn clear_region(&mut self, region: $range) {
+ for row in self.raw[region].iter_mut() {
+ for cell in row.iter_mut() {
+ cell.reset();
+ }
+ }
+ }
+ }
+ }
+}
+
+clear_region_impl!(Range<usize>);
+clear_region_impl!(RangeTo<usize>);
+clear_region_impl!(RangeFrom<usize>);