Skip to content

Commit

Permalink
feat(plugins): add configurable black background for ui components (z…
Browse files Browse the repository at this point in the history
…ellij-org#3681)

* feat(plugins): add transparent background for text and nested_list

* chore: fix formatting issue

* feat: invert flag behaviour

* feat: implement bg_black handling for table cells

* fix: order of selected and bg_black in protocol

* chore: rename from bg_black to opaque

* fix: explicit selected, if opaque and selected for text

* chore: fix formatting issues

* feat: opaque tab-bar

* feat: opaque session-manager bars

* feat: opaque ribbon in plugin manager

* feat: opaque one-line ui

* feat: opaque tab-bar in configuration plugin
  • Loading branch information
dj95 authored and imsnif committed Dec 31, 2024
1 parent 2faf8ec commit 0a501b0
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 37 deletions.
5 changes: 4 additions & 1 deletion default-plugins/configuration/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct State {
ui_size: usize,
current_screen: Screen,
latest_mode_info: Option<ModeInfo>,
colors: Palette,
}

impl Default for State {
Expand All @@ -81,6 +82,7 @@ impl Default for State {
ui_size: UI_SIZE,
current_screen: Screen::default(),
latest_mode_info: None,
colors: Palette::default(),
}
}
}
Expand Down Expand Up @@ -114,6 +116,7 @@ impl ZellijPlugin for State {
let mut should_render = false;
match event {
Event::ModeUpdate(mode_info) => {
self.colors = mode_info.style.colors;
if self.latest_mode_info.as_ref().and_then(|l| l.base_mode) != mode_info.base_mode {
// reset ui state
self.current_screen.reset_state(self.is_setup_wizard);
Expand Down Expand Up @@ -168,7 +171,7 @@ impl ZellijPlugin for State {
fn render(&mut self, rows: usize, cols: usize) {
let notification = self.notification.clone();
if self.is_in_main_screen() {
top_tab_menu(cols, &self.current_screen);
top_tab_menu(cols, &self.current_screen, &self.colors);
}
match &mut self.current_screen {
Screen::RebindLeaders(rebind_leaders_screen) => {
Expand Down
13 changes: 11 additions & 2 deletions default-plugins/configuration/src/ui_components.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
use crate::{Screen, WIDTH_BREAKPOINTS};
use zellij_tile::prelude::*;

pub fn top_tab_menu(cols: usize, current_screen: &Screen) {
pub fn top_tab_menu(cols: usize, current_screen: &Screen, colors: &Palette) {
let background = match colors.theme_hue {
ThemeHue::Dark => colors.black,
ThemeHue::Light => colors.white,
};
let bg_color = match background {
PaletteColor::Rgb((r, g, b)) => format!("\u{1b}[48;2;{};{};{}m\u{1b}[0K", r, g, b),
PaletteColor::EightBit(color) => format!("\u{1b}[48;5;{}m\u{1b}[0K", color),
};
let first_ribbon_text_long = "Rebind leader keys";
let second_ribbon_text_long = "Change mode behavior";
let first_ribbon_text_short = "Rebind keys";
Expand All @@ -25,8 +33,9 @@ pub fn top_tab_menu(cols: usize, current_screen: &Screen) {
if second_ribbon_is_selected {
second_ribbon = second_ribbon.selected();
}
let switch_key = Text::new("<TAB>").color_range(3, ..);
let switch_key = Text::new("<TAB>").color_range(3, ..).opaque();
print_text_with_coordinates(switch_key, 0, 0, None, None);
print!("\u{1b}[{};{}H{}", 0, starting_positions.0 - 1, bg_color);
print_ribbon_with_coordinates(first_ribbon, starting_positions.0, 0, None, None);
print_ribbon_with_coordinates(second_ribbon, starting_positions.1, 0, None, None);
}
Expand Down
32 changes: 30 additions & 2 deletions default-plugins/plugin-manager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct NewPluginScreen {
selected_config_index: Option<usize>,
request_ids: Vec<String>,
load_in_background: bool,
colors: Palette,
}

impl Default for NewPluginScreen {
Expand All @@ -49,11 +50,19 @@ impl Default for NewPluginScreen {
selected_config_index: None,
request_ids: vec![],
load_in_background: true,
colors: Palette::default(),
}
}
}

impl NewPluginScreen {
pub fn new(colors: Palette) -> Self {
Self {
colors,
..Default::default()
}
}

pub fn render(&self, rows: usize, cols: usize) {
self.render_title(cols);
self.render_url_field(cols);
Expand Down Expand Up @@ -246,12 +255,26 @@ impl NewPluginScreen {
fn render_background_toggle(&self, y_coordinates: usize) {
let key_shortcuts_text = format!("Ctrl l");
print_text_with_coordinates(
Text::new(&key_shortcuts_text).color_range(3, ..),
Text::new(&key_shortcuts_text).color_range(3, ..).opaque(),
0,
y_coordinates,
None,
None,
);
let background = match self.colors.theme_hue {
ThemeHue::Dark => self.colors.black,
ThemeHue::Light => self.colors.white,
};
let bg_color = match background {
PaletteColor::Rgb((r, g, b)) => format!("\u{1b}[48;2;{};{};{}m\u{1b}[0K", r, g, b),
PaletteColor::EightBit(color) => format!("\u{1b}[48;5;{}m\u{1b}[0K", color),
};
println!(
"\u{1b}[{};{}H{}",
y_coordinates + 1,
key_shortcuts_text.chars().count() + 1,
bg_color
);
let load_in_background_text = format!("Load in Background");
let load_in_foreground_text = format!("Load in Foreground");
let (load_in_background_ribbon, load_in_foreground_ribbon) = if self.load_in_background {
Expand Down Expand Up @@ -473,6 +496,7 @@ struct State {
plugin_id_to_tab_position: HashMap<u32, usize>,
search_term: String,
new_plugin_screen: Option<NewPluginScreen>,
colors: Palette,
}

register_plugin!(State);
Expand Down Expand Up @@ -524,6 +548,10 @@ impl ZellijPlugin for State {
fn update(&mut self, event: Event) -> bool {
let mut should_render = false;
match event {
Event::ModeUpdate(mode_info) => {
self.colors = mode_info.style.colors;
should_render = true;
},
Event::SessionUpdate(live_sessions, _dead_sessions) => {
for session in live_sessions {
if session.is_current_session {
Expand Down Expand Up @@ -994,7 +1022,7 @@ impl State {
self.reload_selected();
},
BareKey::Char('a') if key.has_modifiers(&[KeyModifier::Ctrl]) => {
self.new_plugin_screen = Some(Default::default());
self.new_plugin_screen = Some(NewPluginScreen::new(self.colors));
should_render = true;
},
BareKey::Delete if key.has_no_modifiers() => {
Expand Down
13 changes: 12 additions & 1 deletion default-plugins/session-manager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,21 @@ impl ZellijPlugin for State {
fn render(&mut self, rows: usize, cols: usize) {
let (x, y, width, height) = self.main_menu_size(rows, cols);

let background = match self.colors.palette.theme_hue {
ThemeHue::Dark => self.colors.palette.black,
ThemeHue::Light => self.colors.palette.white,
};

if self.is_welcome_screen {
render_banner(x, 0, rows.saturating_sub(height), width);
}
render_screen_toggle(self.active_screen, x, y, width.saturating_sub(2));
render_screen_toggle(
self.active_screen,
x,
y,
width.saturating_sub(2),
&background,
);

match self.active_screen {
ActiveScreen::NewSession => {
Expand Down
25 changes: 22 additions & 3 deletions default-plugins/session-manager/src/ui/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,10 +507,22 @@ pub fn minimize_lines(
pub fn render_prompt(search_term: &str, colors: Colors, x: usize, y: usize) {
let prompt = colors.green(&format!("Search:"));
let search_term = colors.bold(&format!("{}_", search_term));
println!("\u{1b}[{};{}H{} {}\n", y + 1, x, prompt, search_term);
println!(
"\u{1b}[{};{}H\u{1b}[0m{} {}\n",
y + 1,
x,
prompt,
search_term
);
}

pub fn render_screen_toggle(active_screen: ActiveScreen, x: usize, y: usize, max_cols: usize) {
pub fn render_screen_toggle(
active_screen: ActiveScreen,
x: usize,
y: usize,
max_cols: usize,
background: &PaletteColor,
) {
let key_indication_text = "<TAB>";
let (new_session_text, running_sessions_text, exited_sessions_text) = if max_cols > 66 {
("New Session", "Attach to Session", "Resurrect Session")
Expand All @@ -520,10 +532,12 @@ pub fn render_screen_toggle(active_screen: ActiveScreen, x: usize, y: usize, max
let key_indication_len = key_indication_text.chars().count() + 1;
let first_ribbon_length = new_session_text.chars().count() + 4;
let second_ribbon_length = running_sessions_text.chars().count() + 4;
let third_ribbon_length = exited_sessions_text.chars().count() + 4;
let key_indication_x = x;
let first_ribbon_x = key_indication_x + key_indication_len;
let second_ribbon_x = first_ribbon_x + first_ribbon_length;
let third_ribbon_x = second_ribbon_x + second_ribbon_length;
let reset_x = third_ribbon_x + third_ribbon_length + 1;
let mut new_session_text = Text::new(new_session_text);
let mut running_sessions_text = Text::new(running_sessions_text);
let mut exited_sessions_text = Text::new(exited_sessions_text);
Expand All @@ -538,13 +552,18 @@ pub fn render_screen_toggle(active_screen: ActiveScreen, x: usize, y: usize, max
exited_sessions_text = exited_sessions_text.selected();
},
}
let bg_color = match background {
PaletteColor::Rgb((r, g, b)) => format!("\u{1b}[48;2;{};{};{}m\u{1b}[0K", r, g, b),
PaletteColor::EightBit(color) => format!("\u{1b}[48;5;{}m\u{1b}[0K", color),
};
print_text_with_coordinates(
Text::new(key_indication_text).color_range(3, ..),
Text::new(key_indication_text).color_range(3, ..).opaque(),
key_indication_x,
y,
None,
None,
);
println!("\u{1b}[{};{}H{}", y + 1, first_ribbon_x, bg_color);
print_ribbon_with_coordinates(new_session_text, first_ribbon_x, y, None, None);
print_ribbon_with_coordinates(running_sessions_text, second_ribbon_x, y, None, None);
print_ribbon_with_coordinates(exited_sessions_text, third_ribbon_x, y, None, None);
Expand Down
19 changes: 12 additions & 7 deletions default-plugins/status-bar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,19 @@ impl ZellijPlugin for State {
""
};

let background = match self.mode_info.style.colors.theme_hue {
ThemeHue::Dark => self.mode_info.style.colors.black,
ThemeHue::Light => self.mode_info.style.colors.white,
};

if rows == 1 && !self.classic_ui {
let fill_bg = match background {
PaletteColor::Rgb((r, g, b)) => format!("\u{1b}[48;2;{};{};{}m\u{1b}[0K", r, g, b),
PaletteColor::EightBit(color) => format!("\u{1b}[48;5;{}m\u{1b}[0K", color),
};
let active_tab = self.tabs.iter().find(|t| t.active);
print!(
"{}",
"{}{}",
one_line_ui(
&self.mode_info,
active_tab,
Expand All @@ -265,7 +274,8 @@ impl ZellijPlugin for State {
self.base_mode_is_locked,
self.text_copy_destination,
self.display_system_clipboard_failure,
)
),
fill_bg,
);
return;
}
Expand All @@ -274,11 +284,6 @@ impl ZellijPlugin for State {
let first_line = first_line(&self.mode_info, active_tab, cols, separator);
let second_line = self.second_line(cols);

let background = match self.mode_info.style.colors.theme_hue {
ThemeHue::Dark => self.mode_info.style.colors.black,
ThemeHue::Light => self.mode_info.style.colors.white,
};

// [48;5;238m is white background, [0K is so that it fills the rest of the line
// [m is background reset, [0K is so that it clears the rest of the line
match background {
Expand Down
13 changes: 8 additions & 5 deletions default-plugins/status-bar/src/one_line_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ fn render_common_modifiers(
line_part_to_render.part = format!(
"{}{}{}",
line_part_to_render.part,
serialize_text(&Text::new(&prefix_text)),
serialize_text(&Text::new(&prefix_text).opaque()),
suffix_separator
);
line_part_to_render.len += prefix_text.chars().count() + separator.chars().count();
Expand Down Expand Up @@ -908,7 +908,7 @@ fn secondary_keybinds(help: &ModeInfo, tab_info: Option<&TabInfo>, max_len: usiz
}

fn text_as_line_part_with_emphasis(text: String, emphases_index: usize) -> LinePart {
let part = serialize_text(&Text::new(&text).color_range(emphases_index, ..));
let part = serialize_text(&Text::new(&text).color_range(emphases_index, ..).opaque());
LinePart {
part,
len: text.width(),
Expand Down Expand Up @@ -1445,9 +1445,11 @@ fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<usize
if no_common_modifier || key.len() == 1 {
let key_string_text = format!(" {} ", key.join(key_separator));
let text = if let Some(color_index) = color_index {
Text::new(&key_string_text).color_range(color_index, ..)
} else {
Text::new(&key_string_text)
.color_range(color_index, ..)
.opaque()
} else {
Text::new(&key_string_text).opaque()
};
LinePart {
part: serialize_text(&text),
Expand All @@ -1464,8 +1466,9 @@ fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<usize
modifier_str.width() + 3
..modifier_str.width() + 3 + key_string_without_modifier.width(),
)
.opaque()
} else {
Text::new(&key_string_text)
Text::new(&key_string_text).opaque()
};
LinePart {
part: serialize_text(&text),
Expand Down
18 changes: 15 additions & 3 deletions default-plugins/tab-bar/src/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ pub fn tab_line(
tab_info: Option<&TabInfo>,
mode_info: &ModeInfo,
hide_swap_layout_indicator: bool,
background: &PaletteColor,
) -> Vec<LinePart> {
let mut tabs_after_active = all_tabs.split_off(active_tab_index);
let mut tabs_before_active = all_tabs;
Expand Down Expand Up @@ -278,6 +279,14 @@ pub fn tab_line(
capabilities,
);
prefix.append(&mut tabs_to_render);
prefix.append(&mut vec![LinePart {
part: match background {
PaletteColor::Rgb((r, g, b)) => format!("\u{1b}[48;2;{};{};{}m\u{1b}[0K", r, g, b),
PaletteColor::EightBit(color) => format!("\u{1b}[48;5;{}m\u{1b}[0K", color),
},
len: 0,
tab_index: None,
}]);

if let Some(mut swap_layout_indicator) = swap_layout_indicator.take() {
let remaining_space = cols
Expand Down Expand Up @@ -382,9 +391,11 @@ pub fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<u
if no_common_modifier || key.len() == 1 {
let key_string_text = format!(" {} ", key.join(key_separator));
let text = if let Some(color_index) = color_index {
Text::new(&key_string_text).color_range(color_index, ..)
} else {
Text::new(&key_string_text)
.color_range(color_index, ..)
.opaque()
} else {
Text::new(&key_string_text).opaque()
};
LinePart {
part: serialize_text(&text),
Expand All @@ -402,8 +413,9 @@ pub fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<u
modifier_str.width() + 3
..modifier_str.width() + 3 + key_string_without_modifier.width(),
)
.opaque()
} else {
Text::new(&key_string_text)
Text::new(&key_string_text).opaque()
};
LinePart {
part: serialize_text(&text),
Expand Down
11 changes: 7 additions & 4 deletions default-plugins/tab-bar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ impl ZellijPlugin for State {
is_alternate_tab = !is_alternate_tab;
all_tabs.push(tab);
}

let background = match self.mode_info.style.colors.theme_hue {
ThemeHue::Dark => self.mode_info.style.colors.black,
ThemeHue::Light => self.mode_info.style.colors.white,
};

self.tab_line = tab_line(
self.mode_info.session_name.as_deref(),
all_tabs,
Expand All @@ -135,17 +141,14 @@ impl ZellijPlugin for State {
self.tabs.iter().find(|t| t.active),
&self.mode_info,
self.hide_swap_layout_indication,
&background,
);

let output = self
.tab_line
.iter()
.fold(String::new(), |output, part| output + &part.part);

let background = match self.mode_info.style.colors.theme_hue {
ThemeHue::Dark => self.mode_info.style.colors.black,
ThemeHue::Light => self.mode_info.style.colors.white,
};
match background {
PaletteColor::Rgb((r, g, b)) => {
print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", output, r, g, b);
Expand Down
Loading

0 comments on commit 0a501b0

Please sign in to comment.