diff options
author | Brooks Rady <b.j.rady@gmail.com> | 2021-08-28 17:46:24 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-28 17:46:24 +0100 |
commit | 76a5bc8a05c33fb3f46cff1ce95aa1af694b9927 (patch) | |
tree | aa0c9e4b317d9d01906d11817b3b57f0047d7be8 /zellij-server/src/ui/pane_boundaries_frame.rs | |
parent | 1544de266501bb7dbb0b044a04283b4fd5f59c6e (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.rs | 213 |
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 } } |