feat(plugins): add configurable black background for ui components (#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
This commit is contained in:
parent
fb58c76967
commit
0cd6d5f4e5
15 changed files with 174 additions and 38 deletions
|
|
@ -71,6 +71,7 @@ struct State {
|
|||
ui_size: usize,
|
||||
current_screen: Screen,
|
||||
latest_mode_info: Option<ModeInfo>,
|
||||
colors: Palette,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
|
|
@ -81,6 +82,7 @@ impl Default for State {
|
|||
ui_size: UI_SIZE,
|
||||
current_screen: Screen::default(),
|
||||
latest_mode_info: None,
|
||||
colors: Palette::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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);
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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);
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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() => {
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
@ -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(),
|
||||
|
|
@ -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),
|
||||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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),
|
||||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -135,6 +141,7 @@ impl ZellijPlugin for State {
|
|||
self.tabs.iter().find(|t| t.active),
|
||||
&self.mode_info,
|
||||
self.hide_swap_layout_indication,
|
||||
&background,
|
||||
);
|
||||
|
||||
let output = self
|
||||
|
|
@ -142,10 +149,6 @@ impl ZellijPlugin for State {
|
|||
.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);
|
||||
|
|
|
|||
|
|
@ -164,6 +164,15 @@ fn parse_selected(stringified: &mut String) -> bool {
|
|||
selected
|
||||
}
|
||||
|
||||
fn parse_opaque(stringified: &mut String) -> bool {
|
||||
let mut opaque = false;
|
||||
if stringified.chars().next() == Some('z') {
|
||||
opaque = true;
|
||||
stringified.remove(0);
|
||||
}
|
||||
opaque
|
||||
}
|
||||
|
||||
fn parse_indices(stringified: &mut String) -> Vec<Vec<usize>> {
|
||||
stringified
|
||||
.chars()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use super::{
|
||||
is_too_high, parse_indices, parse_selected, parse_text, stringify_text, Coordinates, Text,
|
||||
is_too_high, parse_indices, parse_opaque, parse_selected, parse_text, stringify_text,
|
||||
Coordinates, Text,
|
||||
};
|
||||
use crate::panes::terminal_character::{AnsiCode, RESET_STYLES};
|
||||
use zellij_utils::data::Style;
|
||||
|
|
@ -40,11 +41,15 @@ pub fn nested_list(
|
|||
.bold(Some(AnsiCode::On))
|
||||
.foreground(Some(style.colors.white.into()))
|
||||
.background(Some(style.colors.bg.into()))
|
||||
} else {
|
||||
} else if line_item.text.opaque {
|
||||
reset_styles_for_item
|
||||
.bold(Some(AnsiCode::On))
|
||||
.foreground(Some(style.colors.white.into()))
|
||||
.background(Some(style.colors.black.into()))
|
||||
} else {
|
||||
reset_styles_for_item
|
||||
.bold(Some(AnsiCode::On))
|
||||
.foreground(Some(style.colors.white.into()))
|
||||
};
|
||||
let (mut text, text_width) = stringify_text(
|
||||
&line_item.text,
|
||||
|
|
@ -69,10 +74,12 @@ pub fn nested_list(
|
|||
RESET_STYLES
|
||||
.foreground(Some(style.colors.white.into()))
|
||||
.background(Some(style.colors.bg.into()))
|
||||
} else {
|
||||
} else if line_item.text.opaque {
|
||||
RESET_STYLES
|
||||
.foreground(Some(style.colors.white.into()))
|
||||
.background(Some(style.colors.black.into()))
|
||||
} else {
|
||||
RESET_STYLES.foreground(Some(style.colors.white.into()))
|
||||
};
|
||||
stringified.push_str(&format!(
|
||||
"{}{}{}{:padding$}{bulletin}{}{text}{}",
|
||||
|
|
@ -89,10 +96,12 @@ pub fn parse_nested_list_items<'a>(
|
|||
.flat_map(|mut stringified| {
|
||||
let indentation_level = parse_indentation_level(&mut stringified);
|
||||
let selected = parse_selected(&mut stringified);
|
||||
let opaque = parse_opaque(&mut stringified);
|
||||
let indices = parse_indices(&mut stringified);
|
||||
let text = parse_text(&mut stringified).map_err(|e| e.to_string())?;
|
||||
let text = Text {
|
||||
text,
|
||||
opaque,
|
||||
selected,
|
||||
indices,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ pub fn table(
|
|||
if cell.selected {
|
||||
reset_styles_for_item.background = None;
|
||||
text_style = text_style.background(Some(style.colors.bg.into()));
|
||||
} else if cell.opaque {
|
||||
reset_styles_for_item.background = None;
|
||||
text_style = text_style.background(Some(style.colors.black.into()));
|
||||
}
|
||||
// here we intentionally don't pass our coordinates even if we have them, because
|
||||
// these cells have already been padded and truncated
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use super::{
|
||||
emphasis_variants_for_ribbon, emphasis_variants_for_selected_ribbon, is_too_wide,
|
||||
parse_indices, parse_selected, Coordinates,
|
||||
parse_indices, parse_opaque, parse_selected, Coordinates,
|
||||
};
|
||||
use crate::panes::terminal_character::{AnsiCode, CharacterStyles, RESET_STYLES};
|
||||
use zellij_utils::{
|
||||
|
|
@ -14,10 +14,12 @@ use zellij_utils::errors::prelude::*;
|
|||
pub fn text(content: Text, style: &Style, component_coordinates: Option<Coordinates>) -> Vec<u8> {
|
||||
let mut text_style = RESET_STYLES
|
||||
.bold(Some(AnsiCode::On))
|
||||
.foreground(Some(style.colors.white.into()))
|
||||
.background(Some(style.colors.black.into()));
|
||||
.foreground(Some(style.colors.white.into()));
|
||||
|
||||
if content.selected {
|
||||
text_style = text_style.background(Some(style.colors.bg.into()));
|
||||
} else if content.opaque {
|
||||
text_style = text_style.background(Some(style.colors.black.into()));
|
||||
}
|
||||
let (text, _text_width) = stringify_text(
|
||||
&content,
|
||||
|
|
@ -100,10 +102,12 @@ pub fn parse_text_params<'a>(params_iter: impl Iterator<Item = &'a mut String>)
|
|||
params_iter
|
||||
.flat_map(|mut stringified| {
|
||||
let selected = parse_selected(&mut stringified);
|
||||
let opaque = parse_opaque(&mut stringified);
|
||||
let indices = parse_indices(&mut stringified);
|
||||
let text = parse_text(&mut stringified).map_err(|e| e.to_string())?;
|
||||
Ok::<Text, String>(Text {
|
||||
text,
|
||||
opaque,
|
||||
selected,
|
||||
indices,
|
||||
})
|
||||
|
|
@ -115,6 +119,7 @@ pub fn parse_text_params<'a>(params_iter: impl Iterator<Item = &'a mut String>)
|
|||
pub struct Text {
|
||||
pub text: String,
|
||||
pub selected: bool,
|
||||
pub opaque: bool,
|
||||
pub indices: Vec<Vec<usize>>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ impl NestedListItem {
|
|||
self.content = self.content.selected();
|
||||
self
|
||||
}
|
||||
pub fn opaque(mut self) -> Self {
|
||||
self.content = self.content.opaque();
|
||||
self
|
||||
}
|
||||
pub fn color_indices(mut self, index_level: usize, indices: Vec<usize>) -> Self {
|
||||
self.content = self.content.color_indices(index_level, indices);
|
||||
self
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use std::ops::RangeBounds;
|
|||
pub struct Text {
|
||||
text: String,
|
||||
selected: bool,
|
||||
opaque: bool,
|
||||
indices: Vec<Vec<usize>>,
|
||||
}
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ impl Text {
|
|||
Text {
|
||||
text: content.to_string(),
|
||||
selected: false,
|
||||
opaque: false,
|
||||
indices: vec![],
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +25,10 @@ impl Text {
|
|||
self.selected = true;
|
||||
self
|
||||
}
|
||||
pub fn opaque(mut self) -> Self {
|
||||
self.opaque = true;
|
||||
self
|
||||
}
|
||||
pub fn color_indices(mut self, index_level: usize, mut indices: Vec<usize>) -> Self {
|
||||
self.pad_indices(index_level);
|
||||
self.indices
|
||||
|
|
@ -75,11 +81,18 @@ impl Text {
|
|||
.join(",")
|
||||
));
|
||||
}
|
||||
if self.selected {
|
||||
format!("x{}{}", indices, text)
|
||||
} else {
|
||||
format!("{}{}", indices, text)
|
||||
|
||||
let mut prefix = "".to_owned();
|
||||
|
||||
if self.opaque {
|
||||
prefix = format!("z{}", prefix);
|
||||
}
|
||||
|
||||
if self.selected {
|
||||
prefix = format!("x{}", prefix);
|
||||
}
|
||||
|
||||
format!("{}{}{}", prefix, indices, text)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue