zellij/default-plugins/session-manager/src/ui/welcome_screen.rs
Aram Drevekenin 6b20a958f4
feat(sessions): welcome screen (#3112)
* prototype - can send layout name for new session from session-manager

* feat(sessions): ui for selecting layout for new session in the session-manager

* fix: send available layouts to plugins

* make tests compile

* fix tests

* improve ui

* fix: respect built-in layouts

* ui for built-in layouts

* some cleanups

* style(fmt): rustfmt

* welcome screen ui

* fix: make sure layout config is not shared between sessions

* allow disconnecting other users from current session and killing other sessions

* fix: respect default layout

* add welcome screen layout

* tests(plugins): new api methods

* fix(session-manager): do not quit welcome screen on esc and break

* fix(plugins): adjust permissions

* style(fmt): rustfmt

* style(fmt): fix warnings
2024-02-06 14:26:14 +01:00

168 lines
15 KiB
Rust
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

static BANNER: &str = "
██╗ ██╗██╗ ███████╗██████╗ ██████╗ ███╗ ███╗ ███████╗███████╗██╗ ██╗ ██╗ ██╗██╗
██║ ██║██║ ██╔════╝██╔══██╗██╔═══██╗████╗ ████║ ╚══███╔╝██╔════╝██║ ██║ ██║ ██║██║
███████║██║ █████╗ ██████╔╝██║ ██║██╔████╔██║ ███╔╝ █████╗ ██║ ██║ ██║ ██║██║
██╔══██║██║ ██╔══╝ ██╔══██╗██║ ██║██║╚██╔╝██║ ███╔╝ ██╔══╝ ██║ ██║ ██║██ ██║╚═╝
██║ ██║██║ ██║ ██║ ██║╚██████╔╝██║ ╚═╝ ██║ ███████╗███████╗███████╗███████╗██║╚█████╔╝██╗
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚══════╝╚═╝ ╚════╝ ╚═╝
";
static SMALL_BANNER: &str = "
██╗ ██╗██╗ ██╗
██║ ██║██║ ██║
███████║██║ ██║
██╔══██║██║ ╚═╝
██║ ██║██║ ██╗
╚═╝ ╚═╝╚═╝ ╚═╝
";
static MEDIUM_BANNER: &str = "
██╗ ██╗██╗ ████████╗██╗ ██╗███████╗██████╗ ███████╗ ██╗
██║ ██║██║ ╚══██╔══╝██║ ██║██╔════╝██╔══██╗██╔════╝ ██║
███████║██║ ██║ ███████║█████╗ ██████╔╝█████╗ ██║
██╔══██║██║ ██║ ██╔══██║██╔══╝ ██╔══██╗██╔══╝ ╚═╝
██║ ██║██║ ██║ ██║ ██║███████╗██║ ██║███████╗ ██╗
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝
";
pub fn render_banner(x: usize, y: usize, rows: usize, cols: usize) {
if rows >= 8 {
if cols > 100 {
println!("\u{1b}[{}H", y + rows.saturating_sub(8) / 2);
for line in BANNER.lines() {
println!("\u{1b}[{}C{}", x.saturating_sub(1), line);
}
} else if cols > 63 {
println!("\u{1b}[{}H", y + rows.saturating_sub(8) / 2);
let x = (cols.saturating_sub(63) as f64 / 2.0) as usize;
for line in MEDIUM_BANNER.lines() {
println!("\u{1b}[{}C{}", x, line);
}
} else {
println!("\u{1b}[{}H", y + rows.saturating_sub(8) / 2);
let x = (cols.saturating_sub(18) as f64 / 2.0) as usize;
for line in SMALL_BANNER.lines() {
println!("\u{1b}[{}C{}", x, line);
}
}
} else if rows > 2 {
println!(
"\u{1b}[{};{}H\u{1b}[1mHi from Zellij!",
(y + rows / 2) + 1,
(x + cols.saturating_sub(15) / 2).saturating_sub(1)
);
}
}
pub fn render_welcome_boundaries(rows: usize, cols: usize) {
let width_of_main_menu = std::cmp::min(cols, 101);
let has_room_for_logos = cols.saturating_sub(width_of_main_menu) > 100;
let left_boundary_x = (cols.saturating_sub(width_of_main_menu) as f64 / 2.0).floor() as usize;
let right_boundary_x = left_boundary_x + width_of_main_menu;
let y_starting_point = rows.saturating_sub(15) / 2;
let middle_row =
(y_starting_point + rows.saturating_sub(y_starting_point) / 2).saturating_sub(1);
for i in y_starting_point..rows {
if i == middle_row {
if has_room_for_logos {
print!("\u{1b}[{};{}H┤", i + 1, left_boundary_x + 1);
print!(
"\u{1b}[m\u{1b}[{};{}H├\u{1b}[K",
i + 1,
right_boundary_x + 1
);
print!("\u{1b}[{};{}H", i + 1, left_boundary_x.saturating_sub(9));
for _ in 0..10 {
print!("");
}
print!("\u{1b}[{};{}H", i + 1, right_boundary_x + 2);
for _ in 0..10 {
print!("");
}
} else {
print!("\u{1b}[{};{}H│", i + 1, left_boundary_x + 1);
print!(
"\u{1b}[m\u{1b}[{};{}H│\u{1b}[K",
i + 1,
right_boundary_x + 1
);
}
} else {
if i == y_starting_point {
print!("\u{1b}[{};{}H┌", i + 1, left_boundary_x + 1);
print!(
"\u{1b}[m\u{1b}[{};{}H┐\u{1b}[K",
i + 1,
right_boundary_x + 1
);
} else if i == rows.saturating_sub(1) {
print!("\u{1b}[{};{}H└", i + 1, left_boundary_x + 1);
print!(
"\u{1b}[m\u{1b}[{};{}H┘\u{1b}[K",
i + 1,
right_boundary_x + 1
);
} else {
print!("\u{1b}[{};{}H│", i + 1, left_boundary_x + 1);
print!(
"\u{1b}[m\u{1b}[{};{}H│\u{1b}[K",
i + 1,
right_boundary_x + 1
); // this includes some
// ANSI magic to delete
// everything after this
// boundary in order to
// fix some rendering
// bugs in the legacy
// components of this
// plugin
}
}
}
if rows.saturating_sub(y_starting_point) > 25 && has_room_for_logos {
for (i, line) in LOGO.lines().enumerate() {
print!(
"\u{1b}[{};{}H{}",
middle_row.saturating_sub(12) + i,
0,
line
);
}
for (i, line) in LOGO.lines().enumerate() {
print!(
"\u{1b}[{};{}H{}",
middle_row.saturating_sub(12) + i,
cols.saturating_sub(47),
line
);
}
}
}
static LOGO: &str = r#" 

 _y$ y@g_
 ya@@@@L4@@@@gy_
 u@@@@@@F "@@@@@@@@y_
 _a@@, @@@P~` __ ~T@@@@@@@@g
 _yg@@@@@$ "~ _yg@@@@gy `~PR@F~_yggy_
 y$@@@@@@PF _y$@@@@@@@@@@gy_ 4@@@@@@@y_
 g@@@@@F~ _yg@@@@@@@@@@@@@@@@@@g_ ~F@@@@@@
 $@@@F yg@@@@@@@@@@@@@@@@@@@@@@@@gy 9@@F"
 $@@@$ 4@@@@@@~@@@@@@@@@@@@@@@@@@@@@ "_yg$
 $@@@$ 4@@@@@ ~@@@@@@@@@@@@@@@@@@@ g@@@@
 $@@@$ 4@@@@@@y ~@@@@@@@@@@@@@@@@@ $@@@F
 $@@@$ 4@@@@@@@@y ~@@@@@@@@@@@@@@@ `~_y_
 $@@@$ 4@@@@@@@P` _g@@@@@@@@@@@@@@@ y@@@@
 $@@@$ 4@@@@@P` _y@@@@@@@@@@@@@@@@@ 4@@@@
 $@@@$ 4@@@@$_ y@@@@@ $@@@@ 4@@@@
 $@@@$ 4@@@@@@g@@@@@@@@@@@@@@@@@@@@@ ~@@@
 $@@P 7R@@@@@@@@@@@@@@@@@@@@@@@@P~ _@g_7@
 ~~_yg@gy_ ~5@@@@@@@@@@@@@@@@@@F~ _yg@@@@y
 R@@@@@@@ ~~@@@@@@@@@@@P~` ya@@@@@@@@F
 ~5@@@@ 4@gy `~4@@@@F~ y@@@@@@@P~`
 `~P 4@@@@gy_ `` _yr a@@@@@F~
 5@@@@@@@gg@@~_g@@@~`
 ~~@@@@@@@^y@F~
 `~4@F ~

 "#;