zellij/zellij-utils/src/pane_size.rs
Aram Drevekenin 821e7cbc5a
feat(ui): add floating panes (#1066)
* basic functionality

* close and reopen scratch terminal working

* embed/float and resize whole tab for floating and static floating panes

* move focus working

* fix focus change in floating panes

* move pane with mouse

* floating z indices

* tests and better resize algorithm

* starting to work on performance

* some performance experimentations

* new render engine

* reverse painters algorithm for floating panes

* fix frame buffering

* improve ux situation

* handle multiple new panes on screen without overlap

* adjust keybindings

* adjust key hints

* fix multiuser frame ui

* fix various floating/multiuser bugs

* remove stuff

* wide characters under floating panes

* fix wide character frame override

* fix non-frame boundaries interactions with floating panes

* fix selection character width

* fix title frame wide char overflow

* fix existing tests

* add tests

* refactor output out of tab

* refactor floating panes out of tab

* refactor tab

* moar refactoring

* refactorings and bring back terminal window title setting

* add frame vte output

* remove more unused stuff

* remove even more unused stuff

* you know the drill

* refactor floating panes and remove more stuffs

* refactor pane grids

* remove unused output caching

* refactor output

* remove unused stuff

* rustfmt

* some formatting

* rustfmt

* reduce clippy to normal

* remove comment

* remove unused

* fix closign pane

* fix tests
2022-02-18 21:10:06 +01:00

146 lines
3.3 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::position::Position;
/// Contains the position and size of a [`Pane`], or more generally of any terminal, measured
/// in character rows and columns.
#[derive(Clone, Copy, Default, PartialEq, Debug, Serialize, Deserialize, Eq)]
pub struct PaneGeom {
pub x: usize,
pub y: usize,
pub rows: Dimension,
pub cols: Dimension,
}
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct Viewport {
pub x: usize,
pub y: usize,
pub rows: usize,
pub cols: usize,
}
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct Offset {
pub top: usize,
pub bottom: usize,
pub right: usize,
pub left: usize,
}
#[derive(Clone, Copy, Default, PartialEq, Debug, Serialize, Deserialize)]
pub struct Size {
pub rows: usize,
pub cols: usize,
}
#[derive(Eq, Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
pub struct Dimension {
pub constraint: Constraint,
inner: usize,
}
impl Default for Dimension {
fn default() -> Self {
Self::percent(100.0)
}
}
impl Dimension {
pub fn fixed(size: usize) -> Dimension {
Self {
constraint: Constraint::Fixed(size),
inner: 1,
}
}
pub fn percent(percent: f64) -> Dimension {
Self {
constraint: Constraint::Percent(percent),
inner: 1,
}
}
pub fn as_usize(&self) -> usize {
self.inner
}
pub fn as_percent(&self) -> Option<f64> {
if let Constraint::Percent(p) = self.constraint {
Some(p)
} else {
None
}
}
pub fn set_inner(&mut self, inner: usize) {
self.inner = inner;
}
pub fn is_fixed(&self) -> bool {
matches!(self.constraint, Constraint::Fixed(_))
}
}
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
pub enum Constraint {
/// Constrains the dimension to a fixed, integer number of rows / columns
Fixed(usize),
/// Constrains the dimension to a flexible percent size of the total screen
Percent(f64),
}
impl Eq for Constraint {}
impl PaneGeom {
pub fn contains(&self, point: &Position) -> bool {
let col = point.column.0 as usize;
let row = point.line.0 as usize;
self.x <= col
&& col < self.x + self.cols.as_usize()
&& self.y <= row
&& row < self.y + self.rows.as_usize()
}
}
impl Offset {
pub fn frame(size: usize) -> Self {
Self {
top: size,
bottom: size,
right: size,
left: size,
}
}
// FIXME: This should be top and left, not bottom and right, but `boundaries.rs` would need
// some changing
pub fn shift(bottom: usize, right: usize) -> Self {
Self {
bottom,
right,
..Default::default()
}
}
}
impl From<PaneGeom> for Viewport {
fn from(pane: PaneGeom) -> Self {
Self {
x: pane.x,
y: pane.y,
rows: pane.rows.as_usize(),
cols: pane.cols.as_usize(),
}
}
}
impl From<Size> for Viewport {
fn from(size: Size) -> Self {
Self {
rows: size.rows,
cols: size.cols,
..Default::default()
}
}
}