summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/ui/pane_boundaries_frame.rs
diff options
context:
space:
mode:
authorBrooks Rady <b.j.rady@gmail.com>2021-08-28 17:46:24 +0100
committerGitHub <noreply@github.com>2021-08-28 17:46:24 +0100
commit76a5bc8a05c33fb3f46cff1ce95aa1af694b9927 (patch)
treeaa0c9e4b317d9d01906d11817b3b57f0047d7be8 /zellij-server/src/ui/pane_boundaries_frame.rs
parent1544de266501bb7dbb0b044a04283b4fd5f59c6e (diff)
feat(ui): overhauled resize and layout systems
* refactor(panes): move to parametric pane sizes * Fixed the simpler errors by casting to usize * The least I can do is pass the formatting check... * Move to stable toolchain * Well, it compiles? * And now it doesn't! ;) * Baseline functionality with the new Dimension type * Working POC for percent-based resizing * REVERT THIS COMMIT – DELETES TESTS * Perfected the discrete resize algorithm * Fixed fixed-size panes * Basic bidirectional resize * feat(resize): finalised parametric resize algorithm * Reduce the logging level a bit * Fixed nested layouts using percents * Bug squishing for implicit sizing * Here is a funky (read: rubbish) rounding approach * And now it's gone again! * Improve discretisation algorithm to fix rounding errors * Fix the last layout bug (maybe?) * Mixed explicit and implied percents work now * Let's pretend that didn't happen... * Make things a bit less crashy * Crash slightly more for now (to find bugs) * Manaually splitting of panes works now * Start moving to percent-based resizes * Everything but fullscreen seems to be working * Fix compilatation errors * Culled a massive amount of border code * Why not pause to please rustfmt? * Turns out I was still missing a few tests... * Bringing back even more tests! * Fix tests and pane boarders * Fix the resize system without gaps * Fix content offset * Fixed a bug with pane closing * Add a hack to fix setting of the viewport * Fix toggling between shared borders and frames * fix(tests): make e2e properly use PaneGeom * style(fmt): make rustfmt happy * Revert unintentional rounding of borders * Purge some old borderless stuff * Fix busted tab-bar shrinking * Update E2E tests * Finish implementing fullscreen! * Don't crash anymore? * Fix (almost) all tests * Fix a lack of tab-stops * All tests passing * I really can't be bothered to debug a CI issue * Tie up loose ends * Knock out some lingering FIXMEs * Continue to clean things up * Change some naming and address FIXMEs * Cull more code + FIXMEs * Refactor of the resize system + polish * Only draw frames when absolutely necessary * Fix the tab-bar crash * Fix rendering of boarders on reattach * Fix resizing at small pane sizes * Deduplicate code in the layout system * Update tab-bar WASM * Fixed the pinching of panes during resize * Unexpose needlessly public type * Add back a lost test * Re-add tab tests and get them to compile * All tabs need layouts * Start fixing tests + bug in main * Stabilize the resize algorithm rounding * All tests from main are now passing * Cull more dead code
Diffstat (limited to 'zellij-server/src/ui/pane_boundaries_frame.rs')
-rw-r--r--zellij-server/src/ui/pane_boundaries_frame.rs213
1 files changed, 57 insertions, 156 deletions
diff --git a/zellij-server/src/ui/pane_boundaries_frame.rs b/zellij-server/src/ui/pane_boundaries_frame.rs
index 0ae454d96..d3cd6d5af 100644
--- a/zellij-server/src/ui/pane_boundaries_frame.rs
+++ b/zellij-server/src/ui/pane_boundaries_frame.rs
@@ -1,7 +1,7 @@
use crate::ui::boundaries::boundary_type;
use ansi_term::Colour::{Fixed, RGB};
use ansi_term::Style;
-use zellij_utils::pane_size::PositionAndSize;
+use zellij_utils::pane_size::Viewport;
use zellij_utils::zellij_tile::prelude::PaletteColor;
fn color_string(character: &str, color: Option<PaletteColor>) -> String {
@@ -18,93 +18,15 @@ fn color_string(character: &str, color: Option<PaletteColor>) -> String {
}
}
-pub struct PaneBoundariesFrame {
- pub position_and_size: PositionAndSize,
- base_title: String,
- title: String,
- scroll_position: (usize, usize), // (position, length)
+#[derive(Default, PartialEq)]
+pub struct PaneFrame {
+ pub geom: Viewport,
+ pub title: String,
+ pub scroll_position: (usize, usize), // (position, length)
pub color: Option<PaletteColor>,
- draw_title_only: bool,
- should_render: bool,
}
-impl PaneBoundariesFrame {
- pub fn new(position_and_size: PositionAndSize, title: String) -> Self {
- PaneBoundariesFrame {
- position_and_size,
- color: None,
- base_title: title.clone(),
- title,
- scroll_position: (0, 0),
- draw_title_only: false,
- should_render: true,
- }
- }
- pub fn frame_title_only(mut self) -> Self {
- // TODO: remove this?
- self.draw_title_only = true;
- self.should_render = true;
- self
- }
- pub fn render_only_title(&mut self, should_render_only_title: bool) {
- if should_render_only_title != self.draw_title_only {
- self.should_render = true;
- self.draw_title_only = should_render_only_title;
- }
- }
- pub fn change_pos_and_size(&mut self, position_and_size: PositionAndSize) {
- if position_and_size != self.position_and_size {
- self.position_and_size = position_and_size;
- self.should_render = true;
- }
- }
- pub fn set_color(&mut self, color: Option<PaletteColor>) {
- if color != self.color {
- self.color = color;
- self.should_render = true;
- }
- }
- pub fn update_scroll(&mut self, scroll_position: (usize, usize)) {
- if scroll_position != self.scroll_position {
- self.scroll_position = scroll_position;
- self.should_render = true;
- }
- }
- pub fn update_title(&mut self, title: Option<&String>) {
- match title {
- Some(title) => {
- if title != &self.title {
- self.title = title.clone();
- self.should_render = true;
- }
- }
- None => {
- self.title = self.base_title.clone();
- self.should_render = true;
- }
- }
- }
- pub fn content_position_and_size(&self) -> PositionAndSize {
- if self.draw_title_only {
- self.position_and_size.reduce_top_line()
- } else {
- self.position_and_size.reduce_outer_frame(1)
- }
- }
- pub fn content_offset(&self) -> (usize, usize) {
- // (column_difference, row_difference)
- let content_position_and_size = self.content_position_and_size();
- let column_difference = content_position_and_size
- .x
- .saturating_sub(self.position_and_size.x);
- let row_difference = content_position_and_size
- .y
- .saturating_sub(self.position_and_size.y);
- (column_difference, row_difference)
- }
- pub fn set_should_render(&mut self, should_render: bool) {
- self.should_render = should_render;
- }
+impl PaneFrame {
fn render_title_right_side(&self, max_length: usize) -> Option<String> {
if self.scroll_position.0 > 0 || self.scroll_position.1 > 0 {
let prefix = " SCROLL: ";
@@ -156,17 +78,9 @@ impl PaneBoundariesFrame {
}
}
fn render_title(&self, vte_output: &mut String) {
- let total_title_length = self.position_and_size.cols - 2; // 2 for the left and right corners
- let left_boundary = if self.draw_title_only {
- boundary_type::HORIZONTAL
- } else {
- boundary_type::TOP_LEFT
- };
- let right_boundary = if self.draw_title_only {
- boundary_type::HORIZONTAL
- } else {
- boundary_type::TOP_RIGHT
- };
+ let total_title_length = self.geom.cols.saturating_sub(2); // 2 for the left and right corners
+ let left_boundary = boundary_type::TOP_LEFT;
+ let right_boundary = boundary_type::TOP_RIGHT;
let left_side = self.render_title_left_side(total_title_length);
let right_side = left_side.as_ref().and_then(|left_side| {
let space_left = total_title_length.saturating_sub(left_side.chars().count() + 1); // 1 for a middle separator
@@ -205,73 +119,60 @@ impl PaneBoundariesFrame {
};
vte_output.push_str(&format!(
"\u{1b}[{};{}H\u{1b}[m{}",
- self.position_and_size.y + 1, // +1 because goto is 1 indexed
- self.position_and_size.x + 1, // +1 because goto is 1 indexed
+ self.geom.y + 1, // +1 because goto is 1 indexed
+ self.geom.x + 1, // +1 because goto is 1 indexed
color_string(&title_text, self.color),
)); // goto row/col + boundary character
}
- pub fn render(&mut self) -> Option<String> {
- if !self.should_render {
- return None;
- }
+ pub fn render(&self) -> String {
let mut vte_output = String::new();
- if self.draw_title_only {
- self.render_title(&mut vte_output);
- } else {
- for row in
- self.position_and_size.y..(self.position_and_size.y + self.position_and_size.rows)
- {
- if row == self.position_and_size.y {
- // top row
- self.render_title(&mut vte_output);
- } else if row == self.position_and_size.y + self.position_and_size.rows - 1 {
- // bottom row
- for col in self.position_and_size.x
- ..(self.position_and_size.x + self.position_and_size.cols)
- {
- if col == self.position_and_size.x {
- // bottom left corner
- vte_output.push_str(&format!(
- "\u{1b}[{};{}H\u{1b}[m{}",
- row + 1, // +1 because goto is 1 indexed
- col + 1,
- color_string(boundary_type::BOTTOM_LEFT, self.color),
- )); // goto row/col + boundary character
- } else if col == self.position_and_size.x + self.position_and_size.cols - 1
- {
- // bottom right corner
- vte_output.push_str(&format!(
- "\u{1b}[{};{}H\u{1b}[m{}",
- row + 1, // +1 because goto is 1 indexed
- col + 1,
- color_string(boundary_type::BOTTOM_RIGHT, self.color),
- )); // goto row/col + boundary character
- } else {
- vte_output.push_str(&format!(
- "\u{1b}[{};{}H\u{1b}[m{}",
- row + 1, // +1 because goto is 1 indexed
- col + 1,
- color_string(boundary_type::HORIZONTAL, self.color),
- )); // goto row/col + boundary character
- }
+ for row in self.geom.y..(self.geom.y + self.geom.rows) {
+ if row == self.geom.y {
+ // top row
+ self.render_title(&mut vte_output);
+ } else if row == self.geom.y + self.geom.rows - 1 {
+ // bottom row
+ for col in self.geom.x..(self.geom.x + self.geom.cols) {
+ if col == self.geom.x {
+ // bottom left corner
+ vte_output.push_str(&format!(
+ "\u{1b}[{};{}H\u{1b}[m{}",
+ row + 1, // +1 because goto is 1 indexed
+ col + 1,
+ color_string(boundary_type::BOTTOM_LEFT, self.color),
+ )); // goto row/col + boundary character
+ } else if col == self.geom.x + self.geom.cols - 1 {
+ // bottom right corner
+ vte_output.push_str(&format!(
+ "\u{1b}[{};{}H\u{1b}[m{}",
+ row + 1, // +1 because goto is 1 indexed
+ col + 1,
+ color_string(boundary_type::BOTTOM_RIGHT, self.color),
+ )); // goto row/col + boundary character
+ } else {
+ vte_output.push_str(&format!(
+ "\u{1b}[{};{}H\u{1b}[m{}",
+ row + 1, // +1 because goto is 1 indexed
+ col + 1,
+ color_string(boundary_type::HORIZONTAL, self.color),
+ )); // goto row/col + boundary character
}
- } else {
- vte_output.push_str(&format!(
- "\u{1b}[{};{}H\u{1b}[m{}",
- row + 1, // +1 because goto is 1 indexed
- self.position_and_size.x + 1,
- color_string(boundary_type::VERTICAL, self.color),
- )); // goto row/col + boundary character
- vte_output.push_str(&format!(
- "\u{1b}[{};{}H\u{1b}[m{}",
- row + 1, // +1 because goto is 1 indexed
- self.position_and_size.x + self.position_and_size.cols,
- color_string(boundary_type::VERTICAL, self.color),
- )); // goto row/col + boundary character
}
+ } else {
+ vte_output.push_str(&format!(
+ "\u{1b}[{};{}H\u{1b}[m{}",
+ row + 1, // +1 because goto is 1 indexed
+ self.geom.x + 1,
+ color_string(boundary_type::VERTICAL, self.color),
+ )); // goto row/col + boundary character
+ vte_output.push_str(&format!(
+ "\u{1b}[{};{}H\u{1b}[m{}",
+ row + 1, // +1 because goto is 1 indexed
+ self.geom.x + self.geom.cols,
+ color_string(boundary_type::VERTICAL, self.color),
+ )); // goto row/col + boundary character
}
}
- self.should_render = false;
- Some(vte_output)
+ vte_output
}
}