diff options
author | a-kenji <aks.kenji@protonmail.com> | 2021-11-15 20:13:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-15 20:13:05 +0100 |
commit | b861baa6a19e7b868e8e3c4d3349a031322f342a (patch) | |
tree | 1def054acd4246c33d1e017df700a49c322efb1c /zellij-server/src/ui | |
parent | 55aef0aeec3f1ba0d075be30cc8210ae3aa42710 (diff) |
First attempt to provide an overlay prompt (#871)
Diffstat (limited to 'zellij-server/src/ui')
-rw-r--r-- | zellij-server/src/ui/mod.rs | 1 | ||||
-rw-r--r-- | zellij-server/src/ui/overlay/mod.rs | 104 | ||||
-rw-r--r-- | zellij-server/src/ui/overlay/prompt.rs | 55 |
3 files changed, 160 insertions, 0 deletions
diff --git a/zellij-server/src/ui/mod.rs b/zellij-server/src/ui/mod.rs index 6ebc46831..08c381836 100644 --- a/zellij-server/src/ui/mod.rs +++ b/zellij-server/src/ui/mod.rs @@ -1,3 +1,4 @@ pub mod boundaries; +pub mod overlay; pub mod pane_boundaries_frame; pub mod pane_resizer; diff --git a/zellij-server/src/ui/overlay/mod.rs b/zellij-server/src/ui/overlay/mod.rs new file mode 100644 index 000000000..3bac1afb5 --- /dev/null +++ b/zellij-server/src/ui/overlay/mod.rs @@ -0,0 +1,104 @@ +//! This module handles the overlay's over the [`Screen`] +//! +//! They consist of: +//! +//! prompt's: +//! +//! notification's: + +pub mod prompt; + +use crate::ServerInstruction; +use zellij_utils::pane_size::Size; + +#[derive(Clone, Debug)] +pub struct Overlay { + pub overlay_type: OverlayType, +} + +pub trait Overlayable { + /// Generates vte_output that can be passed into + /// the `render()` function + fn generate_overlay(&self, size: Size) -> String; +} + +#[derive(Clone, Debug)] +struct Padding { + rows: usize, + cols: usize, +} + +#[derive(Clone, Debug)] +pub enum OverlayType { + Prompt(prompt::Prompt), +} + +impl Overlayable for OverlayType { + fn generate_overlay(&self, size: Size) -> String { + match &self { + OverlayType::Prompt(prompt) => prompt.generate_overlay(size), + } + } +} + +/// Entrypoint from [`Screen`], which holds the context in which +/// the overlays are being rendered. +/// The most recent overlays draw over the previous overlays. +#[derive(Clone, Debug)] +pub struct OverlayWindow { + pub overlay_stack: Vec<Overlay>, +} + +impl Default for OverlayWindow { + fn default() -> Self { + Self { + overlay_stack: vec![], + } + } +} + +impl Overlayable for OverlayWindow { + fn generate_overlay(&self, size: Size) -> String { + let mut output = String::new(); + //let clear_display = "\u{1b}[2J"; + //output.push_str(&clear_display); + for overlay in &self.overlay_stack { + let vte_output = overlay.generate_overlay(size); + output.push_str(&vte_output); + } + output + } +} + +impl Overlay { + pub fn prompt_confirm(self) -> Option<Box<ServerInstruction>> { + match self.overlay_type { + OverlayType::Prompt(p) => p.confirm(), + } + } + pub fn prompt_deny(self) -> Option<Box<ServerInstruction>> { + match self.overlay_type { + OverlayType::Prompt(p) => p.deny(), + } + } +} + +impl Overlayable for Overlay { + fn generate_overlay(&self, size: Size) -> String { + self.overlay_type.generate_overlay(size) + } +} + +impl Overlay { + pub fn new(overlay_type: OverlayType) -> Self { + Self { overlay_type } + } + + fn pad_cols(output: &mut String, cols: usize) { + if let Some(padding) = cols.checked_sub(output.len()) { + for _ in 0..padding { + output.push(' '); + } + } + } +} diff --git a/zellij-server/src/ui/overlay/prompt.rs b/zellij-server/src/ui/overlay/prompt.rs new file mode 100644 index 000000000..f28e3c405 --- /dev/null +++ b/zellij-server/src/ui/overlay/prompt.rs @@ -0,0 +1,55 @@ +use zellij_utils::pane_size::Size; + +use super::{Overlay, OverlayType, Overlayable}; +use crate::{ClientId, ServerInstruction}; + +#[derive(Clone, Debug)] +pub struct Prompt { + pub message: String, + on_confirm: Option<Box<ServerInstruction>>, + on_deny: Option<Box<ServerInstruction>>, +} + +impl Prompt { + pub fn new( + message: String, + on_confirm: Option<Box<ServerInstruction>>, + on_deny: Option<Box<ServerInstruction>>, + ) -> Self { + Self { + message, + on_confirm, + on_deny, + } + } + pub fn confirm(self) -> Option<Box<ServerInstruction>> { + self.on_confirm + } + pub fn deny(self) -> Option<Box<ServerInstruction>> { + self.on_deny + } +} + +impl Overlayable for Prompt { + fn generate_overlay(&self, size: Size) -> String { + let mut output = String::new(); + let rows = size.rows; + let mut vte_output = self.message.clone(); + Overlay::pad_cols(&mut vte_output, size.cols); + for (x, h) in vte_output.chars().enumerate() { + output.push_str(&format!("\u{1b}[{};{}H\u{1b}[48;5;238m{}", rows, x + 1, h,)); + } + output + } +} + +pub fn _generate_quit_prompt(client_id: ClientId) -> Overlay { + let prompt = Prompt::new( + (" Do you want to quit zellij? [Y]es / [N]o").to_string(), + Some(Box::new(ServerInstruction::ClientExit(client_id))), + None, + ); + Overlay { + overlay_type: OverlayType::Prompt(prompt), + } +} |