summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/panes
diff options
context:
space:
mode:
authorhar7an <99636919+har7an@users.noreply.github.com>2022-12-08 12:50:28 +0000
committerGitHub <noreply@github.com>2022-12-08 12:50:28 +0000
commit62eaea15833b34f40270dc1ce8f6d57639dc4bdd (patch)
treeeb06c1f3075ccb5ed6f536d427e14c4fdbdef4e2 /zellij-server/src/panes
parent420c7c319b1c328af9994f758264753c9467aded (diff)
Reimplement resize code (#1990)
* server/floating_panes: Start removing `unwrap`s * server/panes: Remove more `unwrap`s in floating panes code. * utils/data: Unify `Direction` type which was previously present in multiple locations. Also start working on a new Resize Method (type `ResizeStrategy`), to remove code duplication in the resize code. * server: Implement new resize handling with the `ResizeStrategy` type. Add a new action with the ability to invoke it from the CLI. Take care to maintain backwards-compatibility in terms of configuring the new resize mode. * utils/layout: Add conversion for SplitDirection from `data::Direction`. * utils/data: Add impl for `Direction` * server/panes: Rework tiled pane resizing but it's currently still broken in a few regards and misses ability to perform "regular" increase/decrease. * server/panes/tiled_panes: Add debug assertion to catch if the total area of all panes (in percent) is different from 100.0 at some point. * server/panes/tiled/grid: Fix resize bug caused by the fact that neighboring plugin panes previously weren't filtered from resize operations, even though they cannot be resized at all. * utils/data: Add `invert` for `Resize` * utils/data: Add member to `ResizeStrategy` that controls whether we invert resize behavior when increasing size towards a bounadry. This maintains current behavior. * server/screen: Handle new attribute in `ResizeStrategy` * server/panes/resizer: Return `anyhow::Error` * server/panes/tiled: Implement resize increase/decrease without specifying a direction (towards all possible directions). Currently broken in some cases. * server/pane/tiled/grid: Don't return early to preserve resize debug assertions. * server/pane/tiled/grid: Fix resize bug caused by checking for the wrong alignments in some cases. Also refactor the code for looking up aligned panes. * server/panes/tiled/grid: Cleanup code and remove log statements and unused functions. * server/panes/float/grid: Invert resize if the floating pane is hitting a boundary already. * plugins/status-bar: Add hints for new resize * server: Use new resize method * server: Fix tests with new functions and result types. * apply rustfmt * utils: Apply rustfmt * server/panes/floating: Fix resize increase behavior which would previously, upon hitting a boundary, cause the pane to invert the resize operation, which is wrong. Instead, it now does not resize floating panes on an undirected resize "increase" in directions where it hits boundaries. * server/panes/tiled: Use correct resize increments The values for the resize increments were previously wrong, causing many of the tests to fail. * server/panes/tiled: Fix resize checks to correctly consider fixed-size panes. * utils/assets/config: Update default config with new keybindings for resize mode. * server/panes/tiled: Fix resize check * server/panes/tiled: Use shortener for `Direction` type in `change_pane_size` function. * server/panes/tiled: Restore resize behavior for undirected resizes, to the way it was before this PR. * server/panes/floating: Fix resize increment for undirected resizes * utils/data: Fix doctest * utils: Fix test snapshots for tests working with the default config * changelog: Add PR #1990
Diffstat (limited to 'zellij-server/src/panes')
-rw-r--r--zellij-server/src/panes/floating_panes/floating_pane_grid.rs649
-rw-r--r--zellij-server/src/panes/floating_panes/mod.rs513
-rw-r--r--zellij-server/src/panes/tiled_panes/mod.rs98
-rw-r--r--zellij-server/src/panes/tiled_panes/pane_resizer.rs11
-rw-r--r--zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs1854
5 files changed, 1077 insertions, 2048 deletions
diff --git a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
index 83724887f..2245ee16a 100644
--- a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
+++ b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
@@ -2,18 +2,23 @@ use crate::tab::{MIN_TERMINAL_HEIGHT, MIN_TERMINAL_WIDTH};
use crate::{panes::PaneId, tab::Pane};
use std::cmp::Ordering;
use std::collections::HashMap;
+use zellij_utils::data::ResizeStrategy;
+use zellij_utils::errors::prelude::*;
use zellij_utils::pane_size::{Dimension, PaneGeom, Size, Viewport};
use std::cell::RefCell;
use std::rc::Rc;
-const RESIZE_INCREMENT_WIDTH: usize = 5;
-const RESIZE_INCREMENT_HEIGHT: usize = 2;
const MOVE_INCREMENT_HORIZONTAL: usize = 10;
const MOVE_INCREMENT_VERTICAL: usize = 5;
const MAX_PANES: usize = 100;
+// For error reporting
+fn no_pane_id(pane_id: &PaneId) -> String {
+ format!("no floating pane with ID {:?} found", pane_id)
+}
+
pub struct FloatingPaneGrid<'a> {
panes: Rc<RefCell<HashMap<PaneId, &'a mut Box<dyn Pane>>>>,
desired_pane_positions: Rc<RefCell<&'a mut HashMap<PaneId, PaneGeom>>>,
@@ -36,14 +41,17 @@ impl<'a> FloatingPaneGrid<'a> {
viewport,
}
}
- pub fn move_pane_by(&mut self, pane_id: PaneId, x: isize, y: isize) {
+ pub fn move_pane_by(&mut self, pane_id: PaneId, x: isize, y: isize) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} by ({x}, {y})");
+
// true => succeeded to move, false => failed to move
let new_pane_position = {
let mut panes = self.panes.borrow_mut();
let pane = panes
.iter_mut()
.find(|(p_id, _p)| **p_id == pane_id)
- .unwrap()
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?
.1;
let mut new_pane_position = pane.position_and_size();
let min_x = self.viewport.x as isize;
@@ -60,20 +68,39 @@ impl<'a> FloatingPaneGrid<'a> {
new_pane_position.y = new_y as usize;
new_pane_position
};
- self.set_pane_geom(pane_id, new_pane_position);
+ self.set_pane_geom(pane_id, new_pane_position)
+ .with_context(err_context)
}
- fn set_pane_geom(&mut self, pane_id: PaneId, new_pane_geom: PaneGeom) {
+
+ fn set_pane_geom(&mut self, pane_id: PaneId, new_pane_geom: PaneGeom) -> Result<()> {
+ let err_context = || {
+ format!(
+ "failed to set pane {pane_id:?} geometry to {:?}",
+ new_pane_geom
+ )
+ };
+
let mut panes = self.panes.borrow_mut();
let pane = panes
.iter_mut()
.find(|(p_id, _p)| **p_id == pane_id)
- .unwrap()
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?
.1;
pane.set_geom(new_pane_geom);
let mut desired_pane_positions = self.desired_pane_positions.borrow_mut();
desired_pane_positions.insert(pane_id, new_pane_geom);
+ Ok(())
}
- pub fn resize(&mut self, space: Size) {
+
+ pub fn resize(&mut self, space: Size) -> Result<()> {
+ let err_context = || {
+ format!(
+ "failed to resize from {:?} to {:?}",
+ self.display_area, space
+ )
+ };
+
let mut panes = self.panes.borrow_mut();
let desired_pane_positions = self.desired_pane_positions.borrow();
@@ -89,7 +116,15 @@ impl<'a> FloatingPaneGrid<'a> {
for (pane_id, pane) in panes.iter_mut() {
let mut new_pane_geom = pane.current_geom();
- let desired_pane_geom = desired_pane_positions.get(pane_id).unwrap();
+ let desired_pane_geom = desired_pane_positions
+ .get(pane_id)
+ .with_context(|| {
+ format!(
+ "failed to acquire desired pane geometry for pane {:?}",
+ pane_id
+ )
+ })
+ .with_context(err_context)?;
let desired_pane_geom_is_inside_viewport =
pane_geom_is_inside_viewport(&new_viewport, desired_pane_geom);
let pane_is_in_desired_position = new_pane_geom == *desired_pane_geom;
@@ -230,436 +265,340 @@ impl<'a> FloatingPaneGrid<'a> {
pane.set_geom(new_pane_geom);
}
}
+ Ok(())
}
- pub fn move_pane_left(&mut self, pane_id: &PaneId) {
- if let Some(move_by) = self.can_move_pane_left(pane_id, MOVE_INCREMENT_HORIZONTAL) {
- self.move_pane_position_left(pane_id, move_by);
+
+ pub fn move_pane_left(&mut self, pane_id: &PaneId) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} left");
+
+ if let Some(move_by) = self
+ .can_move_pane_left(pane_id, MOVE_INCREMENT_HORIZONTAL)
+ .with_context(err_context)?
+ {
+ self.move_pane_position_left(pane_id, move_by)
+ .with_context(err_context)?;
}
+ Ok(())
}
- pub fn move_pane_right(&mut self, pane_id: &PaneId) {
- if let Some(move_by) = self.can_move_pane_right(pane_id, MOVE_INCREMENT_HORIZONTAL) {
- self.move_pane_position_right(pane_id, move_by);
+
+ pub fn move_pane_right(&mut self, pane_id: &PaneId) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} right");
+
+ if let Some(move_by) = self
+ .can_move_pane_right(pane_id, MOVE_INCREMENT_HORIZONTAL)
+ .with_context(err_context)?
+ {
+ self.move_pane_position_right(pane_id, move_by)
+ .with_context(err_context)?;
}
+ Ok(())
}
- pub fn move_pane_down(&mut self, pane_id: &PaneId) {
- if let Some(move_by) = self.can_move_pane_down(pane_id, MOVE_INCREMENT_VERTICAL) {
- self.move_pane_position_down(pane_id, move_by);
+
+ pub fn move_pane_down(&mut self, pane_id: &PaneId) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} down");
+
+ if let Some(move_by) = self
+ .can_move_pane_down(pane_id, MOVE_INCREMENT_VERTICAL)
+ .with_context(err_context)?
+ {
+ self.move_pane_position_down(pane_id, move_by)
+ .with_context(err_context)?;
}
+ Ok(())
}
- pub fn move_pane_up(&mut self, pane_id: &PaneId) {
- if let Some(move_by) = self.can_move_pane_up(pane_id, MOVE_INCREMENT_VERTICAL) {
- self.move_pane_position_up(pane_id, move_by);
+
+ pub fn move_pane_up(&mut self, pane_id: &PaneId) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} up");
+
+ if let Some(move_by) = self
+ .can_move_pane_up(pane_id, MOVE_INCREMENT_VERTICAL)
+ .with_context(err_context)?
+ {
+ self.move_pane_position_up(pane_id, move_by)
+ .with_context(err_context)?;
}
+ Ok(())
}
- fn can_move_pane_left(&self, pane_id: &PaneId, move_by: usize) -> Option<usize> {
+
+ fn can_move_pane_left(&self, pane_id: &PaneId, move_by: usize) -> Result<Option<usize>> {
+ let err_context = || {
+ format!(
+ "failed to determine if pane {pane_id:?} can be moved left by {move_by} columns"
+ )
+ };
+
let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
+ let pane = panes
+ .get(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let space_until_left_screen_edge = pane.x().saturating_sub(self.viewport.x);
- if space_until_left_screen_edge >= move_by {
+
+ Ok(if space_until_left_screen_edge >= move_by {
Some(move_by)
} else if space_until_left_screen_edge > 0 {
Some(space_until_left_screen_edge)
} else {
None
- }
+ })
}
- fn can_move_pane_right(&self, pane_id: &PaneId, move_by: usize) -> Option<usize> {
+
+ fn can_move_pane_right(&self, pane_id: &PaneId, move_by: usize) -> Result<Option<usize>> {
+ let err_context = || {
+ format!(
+ "failed to determine if pane {pane_id:?} can be moved right by {move_by} columns"
+ )
+ };
+
let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
+ let pane = panes
+ .get(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let space_until_right_screen_edge =
(self.viewport.x + self.viewport.cols).saturating_sub(pane.x() + pane.cols());
- if space_until_right_screen_edge >= move_by {
+
+ Ok(if space_until_right_screen_edge >= move_by {
Some(move_by)
} else if space_until_right_screen_edge > 0 {
Some(space_until_right_screen_edge)
} else {
None
- }
+ })
}
- fn can_move_pane_up(&self, pane_id: &PaneId, move_by: usize) -> Option<usize> {
+
+ fn can_move_pane_up(&self, pane_id: &PaneId, move_by: usize) -> Result<Option<usize>> {
+ let err_context =
+ || format!("failed to determine if pane {pane_id:?} can be moved up by {move_by} rows");
+
let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
+ let pane = panes
+ .get(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let space_until_top_screen_edge = pane.y().saturating_sub(self.viewport.y);
- if space_until_top_screen_edge >= move_by {
+
+ Ok(if space_until_top_screen_edge >= move_by {
Some(move_by)
} else if space_until_top_screen_edge > 0 {
Some(space_until_top_screen_edge)
} else {
None
- }
+ })
}
- fn can_move_pane_down(&self, pane_id: &PaneId, move_by: usize) -> Option<usize> {
+
+ fn can_move_pane_down(&self, pane_id: &PaneId, move_by: usize) -> Result<Option<usize>> {
+ let err_context = || {
+ format!("failed to determine if pane {pane_id:?} can be moved down by {move_by} rows")
+ };
+
let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
+ let pane = panes
+ .get(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let space_until_bottom_screen_edge =
(self.viewport.y + self.viewport.rows).saturating_sub(pane.y() + pane.rows());
- if space_until_bottom_screen_edge >= move_by {
+
+ Ok(if space_until_bottom_screen_edge >= move_by {
Some(move_by)
} else if space_until_bottom_screen_edge > 0 {
Some(space_until_bottom_screen_edge)
} else {
None
- }
+ })
}
- fn move_pane_position_left(&mut self, pane_id: &PaneId, move_by: usize) {
+
+ fn move_pane_position_left(&mut self, pane_id: &PaneId, move_by: usize) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} left by {move_by}");
+
let new_pane_geom = {
let mut panes = self.panes.borrow_mut();
- let pane = panes.get_mut(pane_id).unwrap();
+ let pane = panes
+ .get_mut(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let mut current_geom = pane.position_and_size();
current_geom.x -= move_by;
current_geom
};
- self.set_pane_geom(*pane_id, new_pane_geom);
+ self.set_pane_geom(*pane_id, new_pane_geom)
+ .with_context(err_context)
}
- fn move_pane_position_right(&mut self, pane_id: &PaneId, move_by: usize) {
+
+ fn move_pane_position_right(&mut self, pane_id: &PaneId, move_by: usize) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} right by {move_by}");
+
let new_pane_geom = {
let mut panes = self.panes.borrow_mut();
- let pane = panes.get_mut(pane_id).unwrap();
+ let pane = panes
+ .get_mut(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let mut current_geom = pane.position_and_size();
current_geom.x += move_by;
current_geom
};
- self.set_pane_geom(*pane_id, new_pane_geom);
+ self.set_pane_geom(*pane_id, new_pane_geom)
+ .with_context(err_context)
}
- fn move_pane_position_down(&mut self, pane_id: &PaneId, move_by: usize) {
+
+ fn move_pane_position_down(&mut self, pane_id: &PaneId, move_by: usize) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} down by {move_by}");
+
let new_pane_geom = {
let mut panes = self.panes.borrow_mut();
- let pane = panes.get_mut(pane_id).unwrap();
+ let pane = panes
+ .get_mut(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let mut current_geom = pane.position_and_size();
current_geom.y += move_by;
current_geom
};
- self.set_pane_geom(*pane_id, new_pane_geom);
+ self.set_pane_geom(*pane_id, new_pane_geom)
+ .with_context(err_context)
}
- fn move_pane_position_up(&mut self, pane_id: &PaneId, move_by: usize) {
+
+ fn move_pane_position_up(&mut self, pane_id: &PaneId, move_by: usize) -> Result<()> {
+ let err_context = || format!("failed to move pane {pane_id:?} up by {move_by}");
+
let new_pane_geom = {
let mut panes = self.panes.borrow_mut();
- let pane = panes.get_mut(pane_id).unwrap();
+ let pane = panes
+ .get_mut(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?;
let mut current_geom = pane.position_and_size();
current_geom.y -= move_by;
current_geom
};
- self.set_pane_geom(*pane_id, new_pane_geom);
- }
- pub fn resize_pane_left(&'a mut self, pane_id: &PaneId) {
- if let Some(increase_by) = self.can_increase_pane_size_left(pane_id, RESIZE_INCREMENT_WIDTH)
- {
- self.increase_pane_size_left(pane_id, increase_by);
- } else if let Some(decrease_by) =
- self.can_decrease_pane_size_left(pane_id, RESIZE_INCREMENT_WIDTH)
- {
- self.decrease_pane_size_left(pane_id, decrease_by);
- }
- }
- pub fn resize_pane_right(&mut self, pane_id: &PaneId) {
- if let Some(increase_by) =
- self.can_increase_pane_size_right(pane_id, RESIZE_INCREMENT_WIDTH)
- {
- self.increase_pane_size_right(pane_id, increase_by);
- } else if let Some(decrease_by) =
- self.can_decrease_pane_size_right(pane_id, RESIZE_INCREMENT_WIDTH)
- {
- self.decrease_pane_size_right(pane_id, decrease_by);
- }
- }
- pub fn resize_pane_down(&mut self, pane_id: &PaneId) {
- if let Some(increase_by) =
- self.can_increase_pane_size_down(pane_id, RESIZE_INCREMENT_HEIGHT)
- {
- self.increase_pane_size_down(pane_id, increase_by);
- } else if let Some(decrease_by) =
- self.can_decrease_pane_size_down(pane_id, RESIZE_INCREMENT_HEIGHT)
- {
- self.decrease_pane_size_down(pane_id, decrease_by);
- }
- }
- pub fn resize_pane_up(&mut self, pane_id: &PaneId) {
- if let Some(increase_by) = self.can_increase_pane_size_up(pane_id, RESIZE_INCREMENT_HEIGHT)
- {
- self.increase_pane_size_up(pane_id, increase_by);
- } else if let Some(decrease_by) =
- self.can_decrease_pane_size_up(pane_id, RESIZE_INCREMENT_HEIGHT)
- {
- self.decrease_pane_size_up(pane_id, decrease_by);
- }
- }
- pub fn resize_increase(&mut self, pane_id: &PaneId) {
- if let Some(increase_by) =
- self.can_increase_pane_size_left(pane_id, RESIZE_INCREMENT_WIDTH / 2)
- {
- self.increase_pane_size_left(pane_id, increase_by);
- }
- if let Some(increase_by) =
- self.can_increase_pane_size_right(pane_id, RESIZE_INCREMENT_WIDTH / 2)
- {
- self.increase_pane_size_right(pane_id, increase_by);
- }
- if let Some(increase_by) =
- self.can_increase_pane_size_down(pane_id, RESIZE_INCREMENT_HEIGHT / 2)
- {
- self.increase_pane_size_down(pane_id, increase_by);
- }
- if let Some(increase_by) =
- self.can_increase_pane_size_up(pane_id, RESIZE_INCREMENT_HEIGHT / 2)
- {
- self.increase_pane_size_up(pane_id, increase_by);
- }
+ self.set_pane_geom(*pane_id, new_pane_geom)
+ .with_context(err_context)
}
- pub fn resize_decrease(&mut self, pane_id: &PaneId) {
- if let Some(decrease_by) =
- self.can_decrease_pane_size_left(pane_id, RESIZE_INCREMENT_WIDTH / 2)
- {
- self.decrease_pane_size_left(pane_id, decrease_by);
- }
- if let Some(decrease_by) =
- self.can_decrease_pane_size_right(pane_id, RESIZE_INCREMENT_WIDTH / 2)
- {
- self.decrease_pane_size_right(pane_id, decrease_by);
- }
- if let Some(decrease_by) =
- self.can_decrease_pane_size_down(pane_id, RESIZE_INCREMENT_HEIGHT / 2)
- {
- self.decrease_pane_size_down(pane_id, decrease_by);
- }
- if let Some(decrease_by) =
- self.can_decrease_pane_size_up(pane_id, RESIZE_INCREMENT_HEIGHT / 2)
- {
- self.decrease_pane_size_up(pane_id, decrease_by);
- }
- }
- fn can_increase_pane_size_left(
- &self,
- pane_id: &PaneId,
- max_increase_by: usize,
- ) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let distance_to_left_edge = pane.x().saturating_sub(self.viewport.x);
- if distance_to_left_edge.saturating_sub(max_increase_by) > 0 {
- Some(max_increase_by)
- } else if distance_to_left_edge > 0 {
- Some(distance_to_left_edge)
- } else {
- None
- }
- }
- fn can_decrease_pane_size_left(
- &self,
- pane_id: &PaneId,
- max_decrease_by: usize,
- ) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let space_left_to_decrease = pane.cols().saturating_sub(MIN_TERMINAL_WIDTH);
- if space_left_to_decrease.saturating_sub(max_decrease_by) > 0 {
- Some(max_decrease_by)
- } else if space_left_to_decrease > 0 {
- Some(space_left_to_decrease)
- } else {
- None
- }
- }
- fn can_increase_pane_size_right(
- &self,
- pane_id: &PaneId,
- max_increase_by: usize,
- ) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let distance_to_right_edge =
- (self.viewport.x + self.viewport.cols).saturating_sub(pane.x() + pane.cols());
- if pane.x() + pane.cols() + max_increase_by < self.viewport.cols {
- Some(max_increase_by)
- } else if distance_to_right_edge > 0 {
- Some(distance_to_right_edge)
- } else {
- None
- }
- }
- fn can_decrease_pane_size_right(
- &self,
- pane_id: &PaneId,
- max_decrease_by: usize,
- ) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let space_left_to_decrease = pane.cols().saturating_sub(MIN_TERMINAL_WIDTH);
- let pane_right_edge = pane.x() + pane.cols();
- if space_left_to_decrease.saturating_sub(max_decrease_by) > 0
- && pane.x() + max_decrease_by <= pane_right_edge + MIN_TERMINAL_WIDTH
- {
- Some(max_decrease_by)
- } else if space_left_to_decrease > 0
- && pane.x() + max_decrease_by <= pane_right_edge + MIN_TERMINAL_WIDTH
- {
- Some(space_left_to_decrease)
- } else {
- None
- }
- }
- fn can_increase_pane_size_down(
- &self,
- pane_id: &PaneId,
- max_increase_by: usize,
- ) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let distance_to_bottom_edge =
- (self.viewport.y + self.viewport.rows).saturating_sub(pane.y() + pane.rows());
- if pane.y() + pane.rows() + max_increase_by < self.viewport.rows {
- Some(max_increase_by)
- } else if distance_to_bottom_edge > 0 {
- Some(distance_to_bottom_edge)
- } else {
- None
- }
- }
- fn can_decrease_pane_size_down(
- &self,
+
+ pub fn change_pane_size(
+ &mut self,
pane_id: &PaneId,
- max_decrease_by: usize,
- ) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let space_left_to_decrease = pane.rows().saturating_sub(MIN_TERMINAL_HEIGHT);
- let pane_bottom_edge = pane.y() + pane.rows();
- if space_left_to_decrease.saturating_sub(max_decrease_by) > 0
- && pane.y() + max_decrease_by <= pane_bottom_edge + MIN_TERMINAL_HEIGHT
- {
- Some(max_decrease_by)
- } else if space_left_to_decrease > 0
- && pane.y() + max_decrease_by <= pane_bottom_edge + MIN_TERMINAL_HEIGHT
- {
- Some(space_left_to_decrease)
- } else {
- None
- }
- }
- fn can_increase_pane_size_up(&self, pane_id: &PaneId, max_increase_by: usize) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let distance_to_top_edge = pane.y().saturating_sub(self.viewport.y);
- if distance_to_top_edge.saturating_sub(max_increase_by) > 0 {
- Some(max_increase_by)
- } else if distance_to_top_edge > 0 {
- Some(distance_to_top_edge)
- } else {
- None
- }
- }
- fn can_decrease_pane_size_up(&self, pane_id: &PaneId, max_decrease_by: usize) -> Option<usize> {
- let panes = self.panes.borrow();
- let pane = panes.get(pane_id).unwrap();
- let space_left_to_decrease = pane.rows().saturating_sub(MIN_TERMINAL_HEIGHT);
- if space_left_to_decrease.saturating_sub(max_decrease_by) > 0 {
- Some(max_decrease_by)
- } else if space_left_to_decrease > 0 {
- Some(space_left_to_decrease)
+ strategy: &ResizeStrategy,
+ change_by: (usize, usize), // (x, y)
+ ) -> Result<()> {
+ let err_context = || format!("failed to {strategy} for pane {pane_id:?}");
+
+ let mut geometry = self
+ .panes
+ .borrow()
+ .get(pane_id)
+ .with_context(|| no_pane_id(&pane_id))
+ .with_context(err_context)?
+ .position_and_size();
+
+ let change_by = if strategy.direction.is_none() {
+ (change_by.0 / 2, change_by.1 / 2)
} else {
- None
-