summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/ui
diff options
context:
space:
mode:
authora-kenji <aks.kenji@protonmail.com>2021-11-15 20:13:05 +0100
committerGitHub <noreply@github.com>2021-11-15 20:13:05 +0100
commitb861baa6a19e7b868e8e3c4d3349a031322f342a (patch)
tree1def054acd4246c33d1e017df700a49c322efb1c /zellij-server/src/ui
parent55aef0aeec3f1ba0d075be30cc8210ae3aa42710 (diff)
First attempt to provide an overlay prompt (#871)
Diffstat (limited to 'zellij-server/src/ui')
-rw-r--r--zellij-server/src/ui/mod.rs1
-rw-r--r--zellij-server/src/ui/overlay/mod.rs104
-rw-r--r--zellij-server/src/ui/overlay/prompt.rs55
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),
+ }
+}