diff --git a/default-plugins/compact-bar/src/line.rs b/default-plugins/compact-bar/src/line.rs index fa5fd3e932..5e531772d4 100644 --- a/default-plugins/compact-bar/src/line.rs +++ b/default-plugins/compact-bar/src/line.rs @@ -16,7 +16,7 @@ fn populate_tabs_in_tab_line( tabs_after_active: &mut Vec, tabs_to_render: &mut Vec, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) { let mut middle_size = get_current_title_len(tabs_to_render); @@ -107,7 +107,7 @@ fn populate_tabs_in_tab_line( fn left_more_message( tab_count_to_the_left: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -122,13 +122,14 @@ fn left_more_message( // 238 // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + let (text_color, sep_color) = ( + palette.ribbon_unselected.base, + palette.text_unselected.background, + ); + let plus_ribbon_bg = palette.text_selected.emphasis_1; + let left_separator = style!(sep_color, plus_ribbon_bg).paint(separator); + let more_styled_text = style!(text_color, plus_ribbon_bg).bold().paint(more_text); + let right_separator = style!(plus_ribbon_bg, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -140,7 +141,7 @@ fn left_more_message( fn right_more_message( tab_count_to_the_right: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -154,13 +155,15 @@ fn right_more_message( }; // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + + let (text_color, sep_color) = ( + palette.ribbon_unselected.base, + palette.text_unselected.background, + ); + let plus_ribbon_bg = palette.text_selected.emphasis_1; + let left_separator = style!(sep_color, plus_ribbon_bg).paint(separator); + let more_styled_text = style!(text_color, plus_ribbon_bg).bold().paint(more_text); + let right_separator = style!(plus_ribbon_bg, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -173,24 +176,17 @@ fn right_more_message( fn tab_line_prefix( session_name: Option<&str>, mode: InputMode, - palette: Palette, + palette: Styling, cols: usize, ) -> Vec { let prefix_text = " Zellij ".to_string(); let prefix_text_len = prefix_text.chars().count(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; - let bg_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, - }; - - let locked_mode_color = palette.magenta; - let normal_mode_color = palette.green; - let other_modes_color = palette.orange; + let text_color = palette.text_unselected.base; + let bg_color = palette.text_unselected.background; + let locked_mode_color = palette.text_unselected.emphasis_4; + let normal_mode_color = palette.text_unselected.emphasis_3; + let other_modes_color = palette.text_unselected.emphasis_1; let prefix_styled_text = style!(text_color, bg_color).bold().paint(prefix_text); let mut parts = vec![LinePart { @@ -201,10 +197,6 @@ fn tab_line_prefix( if let Some(name) = session_name { let name_part = format!("({})", name); let name_part_len = name_part.width(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; let name_part_styled_text = style!(text_color, bg_color).bold().paint(name_part); if cols.saturating_sub(prefix_text_len) >= name_part_len { parts.push(LinePart { @@ -253,7 +245,7 @@ pub fn tab_line( mut all_tabs: Vec, active_tab_index: usize, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, hide_session_name: bool, mode: InputMode, @@ -293,6 +285,7 @@ pub fn tab_line( let current_title_len = get_current_title_len(&prefix); if current_title_len < cols { let mut remaining_space = cols - current_title_len; + let remaining_bg = palette.text_unselected.background; if let Some(swap_layout_status) = swap_layout_status( remaining_space, active_swap_layout_name, @@ -304,7 +297,7 @@ pub fn tab_line( remaining_space -= swap_layout_status.len; let mut buffer = String::new(); for _ in 0..remaining_space { - buffer.push_str(&style!(palette.black, palette.black).paint(" ").to_string()); + buffer.push_str(&style!(remaining_bg, remaining_bg).paint(" ").to_string()); } prefix.push(LinePart { part: buffer, @@ -323,7 +316,7 @@ fn swap_layout_status( swap_layout_name: &Option, is_swap_layout_damaged: bool, input_mode: InputMode, - palette: &Palette, + palette: &Styling, separator: &str, ) -> Option { match swap_layout_name { @@ -331,31 +324,28 @@ fn swap_layout_status( let mut swap_layout_name = format!(" {} ", swap_layout_name); swap_layout_name.make_ascii_uppercase(); let swap_layout_name_len = swap_layout_name.len() + 3; + let bg = palette.text_unselected.background; + let fg = palette.ribbon_unselected.background; + let green = palette.ribbon_selected.background; let (prefix_separator, swap_layout_name, suffix_separator) = if input_mode == InputMode::Locked { ( - style!(palette.black, palette.fg).paint(separator), - style!(palette.black, palette.fg) - .italic() - .paint(&swap_layout_name), - style!(palette.fg, palette.black).paint(separator), + style!(bg, fg).paint(separator), + style!(bg, fg).italic().paint(&swap_layout_name), + style!(fg, bg).paint(separator), ) } else if is_swap_layout_damaged { ( - style!(palette.black, palette.fg).paint(separator), - style!(palette.black, palette.fg) - .bold() - .paint(&swap_layout_name), - style!(palette.fg, palette.black).paint(separator), + style!(bg, fg).paint(separator), + style!(bg, fg).bold().paint(&swap_layout_name), + style!(fg, bg).paint(separator), ) } else { ( - style!(palette.black, palette.green).paint(separator), - style!(palette.black, palette.green) - .bold() - .paint(&swap_layout_name), - style!(palette.green, palette.black).paint(separator), + style!(bg, green).paint(separator), + style!(bg, green).bold().paint(&swap_layout_name), + style!(green, bg).paint(separator), ) }; let swap_layout_indicator = format!( diff --git a/default-plugins/compact-bar/src/main.rs b/default-plugins/compact-bar/src/main.rs index a7a19bd019..567dc187ed 100644 --- a/default-plugins/compact-bar/src/main.rs +++ b/default-plugins/compact-bar/src/main.rs @@ -131,10 +131,7 @@ impl ZellijPlugin for State { .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, - }; + let background = self.mode_info.style.colors.text_unselected.background; match background { PaletteColor::Rgb((r, g, b)) => { print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", output, r, g, b); diff --git a/default-plugins/compact-bar/src/tab.rs b/default-plugins/compact-bar/src/tab.rs index ec711cc9e7..68609b23ec 100644 --- a/default-plugins/compact-bar/src/tab.rs +++ b/default-plugins/compact-bar/src/tab.rs @@ -4,12 +4,12 @@ use unicode_width::UnicodeWidthStr; use zellij_tile::prelude::*; use zellij_tile_utils::style; -fn cursors(focused_clients: &[ClientId], palette: Palette) -> (Vec, usize) { +fn cursors(focused_clients: &[ClientId], colors: MultiplayerColors) -> (Vec, usize) { // cursor section, text length let mut len = 0; let mut cursors = vec![]; for client_id in focused_clients.iter() { - if let Some(color) = client_id_to_colors(*client_id, palette) { + if let Some(color) = client_id_to_colors(*client_id, colors) { cursors.push(style!(color.1, color.0).paint(" ")); len += 1; } @@ -21,37 +21,40 @@ pub fn render_tab( text: String, tab: &TabInfo, is_alternate_tab: bool, - palette: Palette, + palette: Styling, separator: &str, ) -> LinePart { let focused_clients = tab.other_focused_clients.as_slice(); let separator_width = separator.width(); - let alternate_tab_color = match palette.theme_hue { - // TODO: only do this if we don't have the arrow capabilities - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, + let alternate_tab_color = if is_alternate_tab { + palette.ribbon_unselected.emphasis_1 + } else { + palette.ribbon_unselected.background }; let background_color = if tab.active { - palette.green + palette.ribbon_selected.background } else if is_alternate_tab { alternate_tab_color } else { - palette.fg + palette.ribbon_unselected.background }; - let foreground_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, + let foreground_color = if tab.active { + palette.ribbon_selected.base + } else { + palette.ribbon_unselected.base }; - let left_separator = style!(foreground_color, background_color).paint(separator); + let separator_fill_color = palette.text_unselected.background; + let left_separator = style!(separator_fill_color, background_color).paint(separator); let mut tab_text_len = text.width() + (separator_width * 2) + 2; // + 2 for padding let tab_styled_text = style!(foreground_color, background_color) .bold() .paint(format!(" {} ", text)); - let right_separator = style!(background_color, foreground_color).paint(separator); + let right_separator = style!(background_color, separator_fill_color).paint(separator); let tab_styled_text = if !focused_clients.is_empty() { - let (cursor_section, extra_length) = cursors(focused_clients, palette); + let (cursor_section, extra_length) = + cursors(focused_clients, palette.multiplayer_user_colors); tab_text_len += extra_length; let mut s = String::new(); let cursor_beginning = style!(foreground_color, background_color) @@ -85,7 +88,7 @@ pub fn tab_style( mut tabname: String, tab: &TabInfo, mut is_alternate_tab: bool, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) -> LinePart { let separator = tab_separator(capabilities); diff --git a/default-plugins/configuration/src/main.rs b/default-plugins/configuration/src/main.rs index afc08bf533..6a9c6fc97e 100644 --- a/default-plugins/configuration/src/main.rs +++ b/default-plugins/configuration/src/main.rs @@ -71,7 +71,7 @@ struct State { ui_size: usize, current_screen: Screen, latest_mode_info: Option, - colors: Palette, + colors: Styling, } impl Default for State { @@ -82,7 +82,7 @@ impl Default for State { ui_size: UI_SIZE, current_screen: Screen::default(), latest_mode_info: None, - colors: Palette::default(), + colors: Palette::default().into(), } } } diff --git a/default-plugins/configuration/src/ui_components.rs b/default-plugins/configuration/src/ui_components.rs index 4ccccf9c84..7440fc56a9 100644 --- a/default-plugins/configuration/src/ui_components.rs +++ b/default-plugins/configuration/src/ui_components.rs @@ -1,11 +1,8 @@ use crate::{Screen, WIDTH_BREAKPOINTS}; use zellij_tile::prelude::*; -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, - }; +pub fn top_tab_menu(cols: usize, current_screen: &Screen, colors: &Styling) { + let background = colors.text_unselected.background; 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), diff --git a/default-plugins/plugin-manager/src/main.rs b/default-plugins/plugin-manager/src/main.rs index 22b215ef33..c148a7bac6 100644 --- a/default-plugins/plugin-manager/src/main.rs +++ b/default-plugins/plugin-manager/src/main.rs @@ -34,7 +34,7 @@ pub struct NewPluginScreen { selected_config_index: Option, request_ids: Vec, load_in_background: bool, - colors: Palette, + colors: Styling, } impl Default for NewPluginScreen { @@ -50,13 +50,13 @@ impl Default for NewPluginScreen { selected_config_index: None, request_ids: vec![], load_in_background: false, - colors: Palette::default(), + colors: Palette::default().into(), } } } impl NewPluginScreen { - pub fn new(colors: Palette) -> Self { + pub fn new(colors: Styling) -> Self { Self { colors, ..Default::default() @@ -261,10 +261,7 @@ impl NewPluginScreen { None, None, ); - let background = match self.colors.theme_hue { - ThemeHue::Dark => self.colors.black, - ThemeHue::Light => self.colors.white, - }; + let background = self.colors.text_unselected.background; 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), @@ -496,7 +493,7 @@ struct State { plugin_id_to_tab_position: HashMap, search_term: String, new_plugin_screen: Option, - colors: Palette, + colors: Styling, } register_plugin!(State); diff --git a/default-plugins/session-manager/src/main.rs b/default-plugins/session-manager/src/main.rs index 8dd6da87f6..ba6ef55d92 100644 --- a/default-plugins/session-manager/src/main.rs +++ b/default-plugins/session-manager/src/main.rs @@ -122,10 +122,7 @@ 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, - }; + let background = self.colors.palette.text_unselected.background; if self.is_welcome_screen { render_banner(x, 0, rows.saturating_sub(height), width); diff --git a/default-plugins/session-manager/src/ui/components.rs b/default-plugins/session-manager/src/ui/components.rs index 03c4d3283c..d03d31dfb4 100644 --- a/default-plugins/session-manager/src/ui/components.rs +++ b/default-plugins/session-manager/src/ui/components.rs @@ -83,9 +83,14 @@ impl ListItem { let mut remaining_cols = max_cols; for span in session_name { span.render( - indices - .clone() - .map(|i| (SpanStyle::ForegroundBold(self.colors.palette.magenta), i)), + indices.clone().map(|i| { + ( + SpanStyle::ForegroundBold( + self.colors.palette.text_unselected.emphasis_4, + ), + i, + ) + }), &mut line_to_render, &mut remaining_cols, ); @@ -102,9 +107,14 @@ impl ListItem { let mut remaining_cols = max_cols; for span in tab_name { span.render( - indices - .clone() - .map(|i| (SpanStyle::ForegroundBold(self.colors.palette.magenta), i)), + indices.clone().map(|i| { + ( + SpanStyle::ForegroundBold( + self.colors.palette.text_unselected.emphasis_4, + ), + i, + ) + }), &mut line_to_render, &mut remaining_cols, ); @@ -116,9 +126,14 @@ impl ListItem { let mut remaining_cols = max_cols; for span in pane_name { span.render( - indices - .clone() - .map(|i| (SpanStyle::ForegroundBold(self.colors.palette.magenta), i)), + indices.clone().map(|i| { + ( + SpanStyle::ForegroundBold( + self.colors.palette.text_unselected.emphasis_4, + ), + i, + ) + }), &mut line_to_render, &mut remaining_cols, ); @@ -297,11 +312,11 @@ impl LineToRender { pub fn make_selected_as_search(&mut self, add_arrows: bool) { self.is_selected = true; let arrows = if add_arrows { - self.colors.magenta(" <↓↑> ") + self.colors.shortcuts(" <↓↑> ") } else { " ".to_owned() }; - match self.colors.palette.bg { + match self.colors.palette.list_selected.background { PaletteColor::EightBit(byte) => { self.line = format!( "\u{1b}[48;5;{byte}m\u{1b}[K\u{1b}[48;5;{byte}m{arrows}{}", @@ -319,11 +334,11 @@ impl LineToRender { pub fn make_selected(&mut self, add_arrows: bool) { self.is_selected = true; let arrows = if add_arrows { - self.colors.magenta("<←↓↑→>") + self.colors.shortcuts("<←↓↑→>") } else { " ".to_owned() }; - match self.colors.palette.bg { + match self.colors.palette.list_selected.background { PaletteColor::EightBit(byte) => { self.line = format!( "\u{1b}[48;5;{byte}m\u{1b}[K\u{1b}[48;5;{byte}m{arrows}{}", @@ -343,7 +358,7 @@ impl LineToRender { let more = if self.truncated_result_count > 0 { self.colors - .red(&format!(" [+{}]", self.truncated_result_count)) + .exit_code_error(&format!(" [+{}]", self.truncated_result_count)) } else { String::new() }; @@ -368,12 +383,12 @@ pub fn build_session_ui_line(session_ui_info: &SessionUiInfo, colors: Colors) -> .iter() .fold(0, |acc, tab| acc + tab.panes.len()); let tab_count = format!("{}", tab_count_text); - let tab_count_styled = colors.cyan(&tab_count); + let tab_count_styled = colors.tab_count(&tab_count); let total_pane_count = format!("{}", total_pane_count_text); - let total_pane_count_styled = colors.green(&total_pane_count); + let total_pane_count_styled = colors.pane_count_search_prompt(&total_pane_count); let session_name = &session_ui_info.name; let connected_users = format!("{}", session_ui_info.connected_users); - let connected_users_styled = colors.orange(&connected_users); + let connected_users_styled = colors.connected_users(&connected_users); let session_bullet_span = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![StringAndLength::new( format!(" > "), @@ -381,7 +396,7 @@ pub fn build_session_ui_line(session_ui_info: &SessionUiInfo, colors: Colors) -> )])); let session_name_span = UiSpan::TruncatableUiSpan(TruncatableUiSpan::new( session_name.clone(), - SpanStyle::ForegroundBold(colors.palette.orange), + SpanStyle::ForegroundBold(colors.palette.text_unselected.emphasis_1), )); let tab_and_pane_count = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![ StringAndLength::new( @@ -409,9 +424,9 @@ pub fn build_session_ui_line(session_ui_info: &SessionUiInfo, colors: Colors) -> ui_spans.push(connected_users_count); if session_ui_info.is_current_session { let current_session_indication = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![ - StringAndLength::new(colors.orange(&format!(" ")), 18), - StringAndLength::new(colors.orange(&format!(" ")), 10), - StringAndLength::new(colors.orange(&format!(" ")), 4), + StringAndLength::new(colors.connected_users(&format!(" ")), 18), + StringAndLength::new(colors.connected_users(&format!(" ")), 10), + StringAndLength::new(colors.connected_users(&format!(" ")), 4), ])); ui_spans.push(current_session_indication); } @@ -423,7 +438,7 @@ pub fn build_tab_ui_line(tab_ui_info: &TabUiInfo, colors: Colors) -> Vec let tab_name = &tab_ui_info.name; let pane_count_text = tab_ui_info.panes.len(); let pane_count = format!("{}", pane_count_text); - let pane_count_styled = colors.green(&pane_count); + let pane_count_styled = colors.pane_count_search_prompt(&pane_count); let tab_bullet_span = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![StringAndLength::new( format!(" - "), @@ -431,7 +446,7 @@ pub fn build_tab_ui_line(tab_ui_info: &TabUiInfo, colors: Colors) -> Vec )])); let tab_name_span = UiSpan::TruncatableUiSpan(TruncatableUiSpan::new( tab_name.clone(), - SpanStyle::ForegroundBold(colors.palette.cyan), + SpanStyle::ForegroundBold(colors.palette.text_unselected.emphasis_2), )); let connected_users_count_span = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![ StringAndLength::new( @@ -455,9 +470,9 @@ pub fn build_pane_ui_line(pane_ui_info: &PaneUiInfo, colors: Colors) -> Vec= folder_prompt.width() @@ -598,8 +613,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({} {}, {} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(folder_prompt), - colors.orange(&new_session_folder), + colors.session_name_prompt(folder_prompt), + colors.pane_count_search_prompt(&new_session_folder), change_folder_shortcut, to_change, reset_folder_shortcut, @@ -617,8 +632,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({} {}, {} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), - colors.orange(&new_session_folder), + colors.session_name_prompt(short_folder_prompt), + colors.pane_count_search_prompt(&new_session_folder), change_folder_shortcut, to_change, reset_folder_shortcut, @@ -634,8 +649,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({}/{})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), - colors.orange(&new_session_folder), + colors.session_name_prompt(short_folder_prompt), + colors.pane_count_search_prompt(&new_session_folder), change_folder_shortcut, reset_folder_shortcut, ); @@ -652,8 +667,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({}/{})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), - colors.orange(&truncated_path), + colors.session_name_prompt(short_folder_prompt), + colors.pane_count_search_prompt(&truncated_path), change_folder_shortcut, reset_folder_shortcut, ); @@ -663,7 +678,7 @@ fn render_new_session_folder_prompt( let folder_prompt = "New session folder:"; let short_folder_prompt = "Folder:"; let change_folder_shortcut_text = ""; - let change_folder_shortcut = colors.magenta(change_folder_shortcut_text); + let change_folder_shortcut = colors.shortcuts(change_folder_shortcut_text); let to_set = "to set"; if max_cols @@ -672,7 +687,7 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} ({} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(folder_prompt), + colors.session_name_prompt(folder_prompt), change_folder_shortcut, to_set, ); @@ -685,7 +700,7 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} ({} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), + colors.session_name_prompt(short_folder_prompt), change_folder_shortcut, to_set, ); @@ -693,7 +708,7 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {}", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), + colors.session_name_prompt(short_folder_prompt), change_folder_shortcut, ); } @@ -709,7 +724,7 @@ pub fn render_new_session_block( x: usize, y: usize, ) { - let enter = colors.magenta(""); + let enter = colors.shortcuts(""); if new_session_info.entering_new_session_name() { let prompt = "New session name:"; let long_instruction = "when done, blank for random"; @@ -720,8 +735,8 @@ pub fn render_new_session_block( println!( "\u{1b}[m{}{} {}_ ({} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(prompt), - colors.orange(&new_session_name), + colors.session_name_prompt(prompt), + colors.pane_count_search_prompt(&new_session_name), enter, long_instruction, ); @@ -746,8 +761,8 @@ pub fn render_new_session_block( println!( "\u{1b}[m{}{} {}_ {}", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(prompt), - colors.orange(&new_session_name), + colors.session_name_prompt(prompt), + colors.pane_count_search_prompt(&new_session_name), enter, ); } @@ -759,23 +774,23 @@ pub fn render_new_session_block( }; let prompt = "New session name:"; let long_instruction = "to correct"; - let esc = colors.magenta(""); + let esc = colors.shortcuts(""); if max_cols_of_new_session_block > prompt.width() + long_instruction.width() + new_session_name.width() + 15 { println!( "\u{1b}[m{}{}: {} ({} to correct)", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green("New session name"), - colors.orange(new_session_name), + colors.session_name_prompt("New session name"), + colors.pane_count_search_prompt(new_session_name), esc, ); } else { println!( "\u{1b}[m{}{}: {} {}", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green("New session name"), - colors.orange(new_session_name), + colors.session_name_prompt("New session name"), + colors.pane_count_search_prompt(new_session_name), esc, ); } @@ -919,13 +934,13 @@ pub fn render_controls_line( } }, ActiveScreen::AttachToSession => { - let rename = colors.magenta(""); + let rename = colors.shortcuts(""); let rename_text = colors.bold("Rename"); - let disconnect = colors.magenta(""); + let disconnect = colors.shortcuts(""); let disconnect_text = colors.bold("Disconnect others"); - let kill = colors.magenta(""); + let kill = colors.shortcuts(""); let kill_text = colors.bold("Kill"); - let kill_all = colors.magenta(""); + let kill_all = colors.shortcuts(""); let kill_all_text = colors.bold("Kill all"); if max_cols > 90 { @@ -937,13 +952,13 @@ pub fn render_controls_line( } }, ActiveScreen::ResurrectSession => { - let arrows = colors.magenta("<↓↑>"); + let arrows = colors.shortcuts("<↓↑>"); let navigate = colors.bold("Navigate"); - let enter = colors.magenta(""); + let enter = colors.shortcuts(""); let select = colors.bold("Resurrect"); - let del = colors.magenta(""); + let del = colors.shortcuts(""); let del_text = colors.bold("Delete"); - let del_all = colors.magenta(""); + let del_all = colors.shortcuts(""); let del_all_text = colors.bold("Delete all"); if max_cols > 83 { @@ -959,10 +974,10 @@ pub fn render_controls_line( #[derive(Debug, Default, Clone, Copy)] pub struct Colors { - pub palette: Palette, + pub palette: Styling, } impl Colors { - pub fn new(palette: Palette) -> Self { + pub fn new(palette: Styling) -> Self { Colors { palette } } pub fn bold(&self, text: &str) -> String { @@ -979,24 +994,29 @@ impl Colors { }, } } - pub fn orange(&self, text: &str) -> String { - self.color(&self.palette.orange, text) + + pub fn session_name_prompt(&self, text: &str) -> String { + self.color(&self.palette.exit_code_success.base, text) + } + + pub fn connected_users(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_3, text) } - pub fn green(&self, text: &str) -> String { - self.color(&self.palette.green, text) + pub fn pane_count_search_prompt(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_3, text) } - pub fn red(&self, text: &str) -> String { - self.color(&self.palette.red, text) + pub fn exit_code_error(&self, text: &str) -> String { + self.color(&self.palette.exit_code_error.base, text) } - pub fn cyan(&self, text: &str) -> String { - self.color(&self.palette.cyan, text) + pub fn tab_count(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_2, text) } - pub fn magenta(&self, text: &str) -> String { - self.color(&self.palette.magenta, text) + pub fn shortcuts(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_4, text) } } diff --git a/default-plugins/status-bar/src/first_line.rs b/default-plugins/status-bar/src/first_line.rs index 9fd3b7d912..a67ef10b19 100644 --- a/default-plugins/status-bar/src/first_line.rs +++ b/default-plugins/status-bar/src/first_line.rs @@ -344,14 +344,17 @@ fn key_indicators( line_part } -fn swap_layout_keycode(mode_info: &ModeInfo, palette: &Palette) -> LinePart { +fn swap_layout_keycode(mode_info: &ModeInfo) -> LinePart { let mode_keybinds = mode_info.get_mode_keybinds(); let prev_next_keys = action_key_group( &mode_keybinds, &[&[Action::PreviousSwapLayout], &[Action::NextSwapLayout]], ); - let prev_next_keys_indicator = - style_key_with_modifier(&prev_next_keys, palette, Some(palette.black)); + let prev_next_keys_indicator = style_key_with_modifier( + &prev_next_keys, + &mode_info.style.colors, + Some(mode_info.style.colors.text_unselected.background), + ); let keycode = ANSIStrings(&prev_next_keys_indicator); let len = unstyled_len(&keycode); let part = keycode.to_string(); @@ -364,14 +367,13 @@ fn swap_layout_status( is_swap_layout_damaged: bool, mode_info: &ModeInfo, colored_elements: ColoredElements, - palette: &Palette, separator: &str, ) -> Option { match swap_layout_name { Some(swap_layout_name) => { let mut swap_layout_name = format!(" {} ", swap_layout_name); swap_layout_name.make_ascii_uppercase(); - let keycode = swap_layout_keycode(mode_info, palette); + let keycode = swap_layout_keycode(mode_info); let swap_layout_name_len = swap_layout_name.len() + 3; // 2 for the arrow separators, one for the screen end buffer // macro_rules! style_swap_layout_indicator { @@ -701,7 +703,6 @@ pub fn first_line( tab_info.is_swap_layout_dirty, help, colored_elements, - &help.style.colors, separator, ) { remaining_space -= swap_layout_status.len; @@ -730,7 +731,7 @@ mod tests { use super::*; fn colored_elements() -> ColoredElements { - let palette = Palette::default(); + let palette = Styling::default(); color_elements(palette, false) } diff --git a/default-plugins/status-bar/src/main.rs b/default-plugins/status-bar/src/main.rs index 8b35650cdd..79f7d70d0d 100644 --- a/default-plugins/status-bar/src/main.rs +++ b/default-plugins/status-bar/src/main.rs @@ -87,96 +87,105 @@ pub struct SegmentStyle { // we need different colors from palette for the default theme // plus here we can add new sources in the future, like Theme // that can be defined in the config perhaps -fn color_elements(palette: Palette, different_color_alternates: bool) -> ColoredElements { - let background = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, - }; - let foreground = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; +fn color_elements(palette: Styling, different_color_alternates: bool) -> ColoredElements { + let background = palette.text_unselected.background; + let foreground = palette.text_unselected.base; let alternate_background_color = if different_color_alternates { - match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - } + palette.ribbon_unselected.base } else { - palette.fg + palette.ribbon_unselected.background }; - match palette.source { - PaletteSource::Default => ColoredElements { - selected: SegmentStyle { - prefix_separator: style!(background, palette.green), - char_left_separator: style!(background, palette.green).bold(), - char_shortcut: style!(palette.red, palette.green).bold(), - char_right_separator: style!(background, palette.green).bold(), - styled_text: style!(background, palette.green).bold(), - suffix_separator: style!(palette.green, background).bold(), - }, - unselected: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).bold(), - char_shortcut: style!(palette.red, palette.fg).bold(), - char_right_separator: style!(background, palette.fg).bold(), - styled_text: style!(background, palette.fg).bold(), - suffix_separator: style!(palette.fg, background), - }, - unselected_alternate: SegmentStyle { - prefix_separator: style!(background, alternate_background_color), - char_left_separator: style!(background, alternate_background_color).bold(), - char_shortcut: style!(palette.red, alternate_background_color).bold(), - char_right_separator: style!(background, alternate_background_color).bold(), - styled_text: style!(background, alternate_background_color).bold(), - suffix_separator: style!(alternate_background_color, background), - }, - disabled: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).dimmed().italic(), - char_shortcut: style!(background, palette.fg).dimmed().italic(), - char_right_separator: style!(background, palette.fg).dimmed().italic(), - styled_text: style!(background, palette.fg).dimmed().italic(), - suffix_separator: style!(palette.fg, background), - }, - superkey_prefix: style!(foreground, background).bold(), - superkey_suffix_separator: style!(background, background), + ColoredElements { + selected: SegmentStyle { + prefix_separator: style!(background, palette.ribbon_selected.background), + char_left_separator: style!( + palette.ribbon_selected.base, + palette.ribbon_selected.background + ) + .bold(), + char_shortcut: style!( + palette.ribbon_selected.emphasis_1, + palette.ribbon_selected.background + ) + .bold(), + char_right_separator: style!( + palette.ribbon_selected.base, + palette.ribbon_selected.background + ) + .bold(), + styled_text: style!( + palette.ribbon_selected.base, + palette.ribbon_selected.background + ) + .bold(), + suffix_separator: style!(palette.ribbon_selected.background, background).bold(), }, - PaletteSource::Xresources => ColoredElements { - selected: SegmentStyle { - prefix_separator: style!(background, palette.green), - char_left_separator: style!(palette.fg, palette.green).bold(), - char_shortcut: style!(palette.red, palette.green).bold(), - char_right_separator: style!(palette.fg, palette.green).bold(), - styled_text: style!(background, palette.green).bold(), - suffix_separator: style!(palette.green, background).bold(), - }, - unselected: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).bold(), - char_shortcut: style!(palette.red, palette.fg).bold(), - char_right_separator: style!(background, palette.fg).bold(), - styled_text: style!(background, palette.fg).bold(), - suffix_separator: style!(palette.fg, background), - }, - unselected_alternate: SegmentStyle { - prefix_separator: style!(background, alternate_background_color), - char_left_separator: style!(background, alternate_background_color).bold(), - char_shortcut: style!(palette.red, alternate_background_color).bold(), - char_right_separator: style!(background, alternate_background_color).bold(), - styled_text: style!(background, alternate_background_color).bold(), - suffix_separator: style!(alternate_background_color, background), - }, - disabled: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).dimmed(), - char_shortcut: style!(background, palette.fg).dimmed(), - char_right_separator: style!(background, palette.fg).dimmed(), - styled_text: style!(background, palette.fg).dimmed(), - suffix_separator: style!(palette.fg, background), - }, - superkey_prefix: style!(background, palette.fg).bold(), - superkey_suffix_separator: style!(palette.fg, background), + unselected: SegmentStyle { + prefix_separator: style!(background, palette.ribbon_unselected.background), + char_left_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .bold(), + char_shortcut: style!( + palette.ribbon_unselected.emphasis_1, + palette.ribbon_unselected.background + ) + .bold(), + char_right_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .bold(), + styled_text: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .bold(), + suffix_separator: style!(palette.ribbon_unselected.background, background).bold(), }, + unselected_alternate: SegmentStyle { + prefix_separator: style!(background, alternate_background_color), + char_left_separator: style!(background, alternate_background_color).bold(), + char_shortcut: style!( + palette.ribbon_unselected.emphasis_1, + alternate_background_color + ) + .bold(), + char_right_separator: style!(background, alternate_background_color).bold(), + styled_text: style!(palette.ribbon_unselected.base, alternate_background_color).bold(), + suffix_separator: style!(alternate_background_color, background).bold(), + }, + disabled: SegmentStyle { + prefix_separator: style!(background, palette.ribbon_unselected.background), + char_left_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + char_shortcut: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + char_right_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + styled_text: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + suffix_separator: style!(palette.ribbon_unselected.background, background), + }, + superkey_prefix: style!(foreground, background).bold(), + superkey_suffix_separator: style!(background, background), } } @@ -253,10 +262,7 @@ 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, - }; + let background = self.mode_info.style.colors.text_unselected.background; if rows == 1 && !self.classic_ui { let fill_bg = match background { @@ -280,6 +286,7 @@ impl ZellijPlugin for State { return; } + //TODO: Switch to UI components here let active_tab = self.tabs.iter().find(|t| t.active); let first_line = first_line(&self.mode_info, active_tab, cols, separator); let second_line = self.second_line(cols); @@ -432,19 +439,16 @@ pub fn action_key_group( /// type. pub fn style_key_with_modifier( keyvec: &[KeyWithModifier], - palette: &Palette, + palette: &Styling, background: Option, ) -> Vec> { if keyvec.is_empty() { return vec![]; } - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); - let green_color = palette_match!(palette.green); - let orange_color = palette_match!(palette.orange); + let text_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let mut ret = vec![]; let common_modifiers = get_common_modifiers(keyvec.iter().collect()); @@ -706,7 +710,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('b')), KeyWithModifier::new(BareKey::Char('c')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -722,7 +726,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('k')), KeyWithModifier::new(BareKey::Char('l')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -738,7 +742,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Up), KeyWithModifier::new(BareKey::Right), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -752,7 +756,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Left), KeyWithModifier::new(BareKey::Right), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -766,7 +770,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Down), KeyWithModifier::new(BareKey::Up), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -782,7 +786,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('c')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Char('d')).with_ctrl_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -798,7 +802,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('c')).with_alt_modifier(), KeyWithModifier::new(BareKey::Char('d')).with_alt_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -814,7 +818,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Up).with_alt_modifier(), KeyWithModifier::new(BareKey::Right).with_alt_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -829,7 +833,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('b')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Char('c')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -852,7 +856,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Tab), KeyWithModifier::new(BareKey::Esc), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -870,7 +874,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char(' ')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Tab).with_ctrl_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -885,7 +889,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char(' ')).with_alt_modifier(), KeyWithModifier::new(BareKey::Tab).with_alt_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); diff --git a/default-plugins/status-bar/src/one_line_ui.rs b/default-plugins/status-bar/src/one_line_ui.rs index 777e97d27e..a4d3403907 100644 --- a/default-plugins/status-bar/src/one_line_ui.rs +++ b/default-plugins/status-bar/src/one_line_ui.rs @@ -1064,8 +1064,8 @@ fn add_keygroup_separator(help: &ModeInfo, max_len: usize) -> Option { let mut ret = LinePart::default(); - let separator_color = palette_match!(palette.orange); - let bg_color = palette_match!(palette.black); + let separator_color = palette_match!(palette.text_unselected.emphasis_1); + let bg_color = palette_match!(palette.ribbon_selected.base); let mut bits: Vec = vec![]; let mode_help_text = match help.mode { InputMode::RenamePane => Some("RENAMING PANE"), diff --git a/default-plugins/status-bar/src/second_line.rs b/default-plugins/status-bar/src/second_line.rs index fa2be639b0..c92e522504 100644 --- a/default-plugins/status-bar/src/second_line.rs +++ b/default-plugins/status-bar/src/second_line.rs @@ -17,16 +17,13 @@ fn full_length_shortcut( is_first_shortcut: bool, key: Vec, action: &str, - palette: Palette, + palette: Styling, ) -> LinePart { if key.is_empty() { return LinePart::default(); } - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); + let text_color = palette_match!(palette.text_unselected.base); let separator = if is_first_shortcut { " " } else { " / " }; let mut bits: Vec = vec![Style::new().fg(text_color).paint(separator)]; @@ -45,13 +42,10 @@ fn full_length_shortcut( } } -fn locked_interface_indication(palette: Palette) -> LinePart { +fn locked_interface_indication(palette: Styling) -> LinePart { let locked_text = " -- INTERFACE LOCKED -- "; let locked_text_len = locked_text.chars().count(); - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); + let text_color = palette_match!(palette.text_unselected.base); let locked_styled_text = Style::new().fg(text_color).bold().paint(locked_text); LinePart { part: locked_styled_text.to_string(), @@ -354,8 +348,8 @@ pub fn keybinds(help: &ModeInfo, tip_name: &str, max_width: usize) -> LinePart { best_effort_shortcut_list(help, tip_body.short, max_width) } -pub fn text_copied_hint(palette: &Palette, copy_destination: CopyDestination) -> LinePart { - let green_color = palette_match!(palette.green); +pub fn text_copied_hint(palette: &Styling, copy_destination: CopyDestination) -> LinePart { + let green_color = palette_match!(palette.text_unselected.emphasis_3); let hint = match copy_destination { CopyDestination::Command => "Text piped to external command", #[cfg(not(target_os = "macos"))] @@ -370,22 +364,19 @@ pub fn text_copied_hint(palette: &Palette, copy_destination: CopyDestination) -> } } -pub fn system_clipboard_error(palette: &Palette) -> LinePart { +pub fn system_clipboard_error(palette: &Styling) -> LinePart { let hint = " Error using the system clipboard."; - let red_color = palette_match!(palette.red); + let red_color = palette_match!(palette.text_unselected.emphasis_4); LinePart { part: Style::new().fg(red_color).bold().paint(hint).to_string(), len: hint.len(), } } -pub fn fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) -> LinePart { - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); - let green_color = palette_match!(palette.green); - let orange_color = palette_match!(palette.orange); +pub fn fullscreen_panes_to_hide(palette: &Styling, panes_to_hide: usize) -> LinePart { + let text_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let shortcut_left_separator = Style::new().fg(text_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(text_color).bold().paint("): "); let fullscreen = "FULLSCREEN"; @@ -414,18 +405,9 @@ pub fn fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) -> Line pub fn floating_panes_are_visible(mode_info: &ModeInfo) -> LinePart { let palette = mode_info.style.colors; let km = &mode_info.get_mode_keybinds(); - let white_color = match palette.white { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; - let green_color = match palette.green { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; - let orange_color = match palette.orange { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; + let white_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let shortcut_left_separator = Style::new().fg(white_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(white_color).bold().paint("): "); let floating_panes = "FLOATING PANES VISIBLE"; @@ -477,13 +459,10 @@ pub fn floating_panes_are_visible(mode_info: &ModeInfo) -> LinePart { } } -pub fn locked_fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) -> LinePart { - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); - let green_color = palette_match!(palette.green); - let orange_color = palette_match!(palette.orange); +pub fn locked_fullscreen_panes_to_hide(palette: &Styling, panes_to_hide: usize) -> LinePart { + let text_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let locked_text = " -- INTERFACE LOCKED -- "; let shortcut_left_separator = Style::new().fg(text_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(text_color).bold().paint("): "); @@ -512,15 +491,9 @@ pub fn locked_fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) } } -pub fn locked_floating_panes_are_visible(palette: &Palette) -> LinePart { - let white_color = match palette.white { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; - let orange_color = match palette.orange { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; +pub fn locked_floating_panes_are_visible(palette: &Styling) -> LinePart { + let white_color = palette_match!(palette.text_unselected.base); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let shortcut_left_separator = Style::new().fg(white_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(white_color).bold().paint(")"); let locked_text = " -- INTERFACE LOCKED -- "; @@ -566,7 +539,7 @@ mod tests { #[test] fn full_length_shortcut_with_key() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a'))]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -577,7 +550,7 @@ mod tests { #[test] fn full_length_shortcut_with_key_first_element() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a'))]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(true, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -589,7 +562,7 @@ mod tests { // When there is no binding, we print no shortcut either fn full_length_shortcut_without_key() { let keyvec = vec![]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -600,7 +573,7 @@ mod tests { #[test] fn full_length_shortcut_with_key_unprintable_1() { let keyvec = vec![KeyWithModifier::new(BareKey::Enter)]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -611,7 +584,7 @@ mod tests { #[test] fn full_length_shortcut_with_key_unprintable_2() { let keyvec = vec![KeyWithModifier::new(BareKey::Backspace)]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -622,7 +595,7 @@ mod tests { #[test] fn full_length_shortcut_with_ctrl_key() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a')).with_ctrl_modifier()]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -633,7 +606,7 @@ mod tests { #[test] fn full_length_shortcut_with_alt_key() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a')).with_alt_modifier()]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -648,7 +621,7 @@ mod tests { KeyWithModifier::new(BareKey::Char('b')), KeyWithModifier::new(BareKey::Char('c')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -663,7 +636,7 @@ mod tests { KeyWithModifier::new(BareKey::Char('b')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Enter), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -678,7 +651,7 @@ mod tests { KeyWithModifier::new(BareKey::Char('b')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Char('c')).with_ctrl_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); diff --git a/default-plugins/status-bar/src/tip/data/compact_layout.rs b/default-plugins/status-bar/src/tip/data/compact_layout.rs index 77dec8a60f..f7ee7335a3 100644 --- a/default-plugins/status-bar/src/tip/data/compact_layout.rs +++ b/default-plugins/status-bar/src/tip/data/compact_layout.rs @@ -25,7 +25,7 @@ macro_rules! strings { pub fn compact_layout_full(help: &ModeInfo) -> LinePart { // Tip: UI taking up too much space? Start Zellij with // zellij -l compact or remove pane frames with Ctrl +

+ - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -43,7 +43,7 @@ pub fn compact_layout_full(help: &ModeInfo) -> LinePart { pub fn compact_layout_medium(help: &ModeInfo) -> LinePart { // Tip: To save screen space, start Zellij with // zellij -l compact or remove pane frames with Ctrl +

+ - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -61,7 +61,7 @@ pub fn compact_layout_medium(help: &ModeInfo) -> LinePart { pub fn compact_layout_short(help: &ModeInfo) -> LinePart { // Save screen space, start Zellij with // zellij -l compact or remove pane frames with Ctrl +

+ - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Save screen space, start with: "), diff --git a/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs b/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs index ebd944b779..a8c18ad65e 100644 --- a/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs +++ b/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs @@ -24,7 +24,7 @@ macro_rules! strings { pub fn edit_scrollbuffer_full(help: &ModeInfo) -> LinePart { // Tip: Search through the scrollbuffer using your default $EDITOR with // Ctrl + + - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -39,7 +39,7 @@ pub fn edit_scrollbuffer_full(help: &ModeInfo) -> LinePart { pub fn edit_scrollbuffer_medium(help: &ModeInfo) -> LinePart { // Tip: Search the scrollbuffer using your $EDITOR with // Ctrl + + - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -54,7 +54,7 @@ pub fn edit_scrollbuffer_medium(help: &ModeInfo) -> LinePart { pub fn edit_scrollbuffer_short(help: &ModeInfo) -> LinePart { // Search using $EDITOR with // Ctrl + + - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Search using "), diff --git a/default-plugins/status-bar/src/tip/data/move_tabs.rs b/default-plugins/status-bar/src/tip/data/move_tabs.rs index 6ad119e49c..690686a1e4 100644 --- a/default-plugins/status-bar/src/tip/data/move_tabs.rs +++ b/default-plugins/status-bar/src/tip/data/move_tabs.rs @@ -25,7 +25,7 @@ macro_rules! strings { pub fn move_tabs_full(help: &ModeInfo) -> LinePart { // Tip: Wrong order of tabs? You can move them to left and right with: // Alt + i (left) and Alt + o (right) - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); let bits = vec![ Style::new().paint(" Tip: "), @@ -41,7 +41,7 @@ pub fn move_tabs_full(help: &ModeInfo) -> LinePart { pub fn move_tabs_medium(help: &ModeInfo) -> LinePart { // Tip: You can move tabs to left and right with: // Alt + i (left) and Alt + o (right) - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); let bits = vec![ Style::new().paint(" Tip: "), @@ -56,7 +56,7 @@ pub fn move_tabs_medium(help: &ModeInfo) -> LinePart { pub fn move_tabs_short(help: &ModeInfo) -> LinePart { // Move tabs with: Alt + i (left) and Alt + o (right) - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); let bits = vec![ Style::new().paint(" Move tabs with: "), diff --git a/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs b/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs index 7daabeb6dd..69c9057f7a 100644 --- a/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs +++ b/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs @@ -23,8 +23,8 @@ macro_rules! strings { pub fn mouse_click_to_terminal_full(help: &ModeInfo) -> LinePart { // Tip: SHIFT + bypasses Zellij and sends the mouse click directly to the terminal - let green_color = palette_match!(help.style.colors.green); - let orange_color = palette_match!(help.style.colors.orange); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), @@ -37,8 +37,8 @@ pub fn mouse_click_to_terminal_full(help: &ModeInfo) -> LinePart { pub fn mouse_click_to_terminal_medium(help: &ModeInfo) -> LinePart { // Tip: SHIFT + sends the click directly to the terminal - let green_color = palette_match!(help.style.colors.green); - let orange_color = palette_match!(help.style.colors.orange); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), Style::new().fg(orange_color).bold().paint("Shift"), @@ -50,8 +50,8 @@ pub fn mouse_click_to_terminal_medium(help: &ModeInfo) -> LinePart { pub fn mouse_click_to_terminal_short(help: &ModeInfo) -> LinePart { // Tip: SHIFT + => sends click to terminal. - let green_color = palette_match!(help.style.colors.green); - let orange_color = palette_match!(help.style.colors.orange); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), diff --git a/default-plugins/status-bar/src/tip/data/use_mouse.rs b/default-plugins/status-bar/src/tip/data/use_mouse.rs index 4bbfbf948d..da4fa57bba 100644 --- a/default-plugins/status-bar/src/tip/data/use_mouse.rs +++ b/default-plugins/status-bar/src/tip/data/use_mouse.rs @@ -24,7 +24,7 @@ macro_rules! strings { pub fn use_mouse_full(help: &ModeInfo) -> LinePart { // Tip: Use the mouse to switch pane focus, scroll through the pane // scrollbuffer, switch or scroll through tabs - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); strings!(&[ Style::new().paint(" Tip: "), @@ -36,7 +36,7 @@ pub fn use_mouse_full(help: &ModeInfo) -> LinePart { pub fn use_mouse_medium(help: &ModeInfo) -> LinePart { // Tip: Use the mouse to switch panes/tabs or scroll through the pane // scrollbuffer - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); strings!(&[ Style::new().paint(" Tip: "), @@ -47,7 +47,7 @@ pub fn use_mouse_medium(help: &ModeInfo) -> LinePart { pub fn use_mouse_short(help: &ModeInfo) -> LinePart { // Tip: Use the mouse to switch panes/tabs or scroll - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); strings!(&[ Style::new().fg(green_color).bold().paint(" Use the mouse"), diff --git a/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs b/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs index 3dd7b6d853..62eb0ad205 100644 --- a/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs +++ b/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs @@ -23,7 +23,7 @@ macro_rules! strings { pub fn zellij_setup_check_full(help: &ModeInfo) -> LinePart { // Tip: Having issues with Zellij? Try running "zellij setup --check" - let orange_color = palette_match!(help.style.colors.orange); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), @@ -37,7 +37,7 @@ pub fn zellij_setup_check_full(help: &ModeInfo) -> LinePart { pub fn zellij_setup_check_medium(help: &ModeInfo) -> LinePart { // Tip: Run "zellij setup --check" to find issues - let orange_color = palette_match!(help.style.colors.orange); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), @@ -52,7 +52,7 @@ pub fn zellij_setup_check_medium(help: &ModeInfo) -> LinePart { pub fn zellij_setup_check_short(help: &ModeInfo) -> LinePart { // Run "zellij setup --check" to find issues - let orange_color = palette_match!(help.style.colors.orange); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Run "), diff --git a/default-plugins/tab-bar/src/line.rs b/default-plugins/tab-bar/src/line.rs index d9f82698be..7f564a3dbe 100644 --- a/default-plugins/tab-bar/src/line.rs +++ b/default-plugins/tab-bar/src/line.rs @@ -17,7 +17,7 @@ fn populate_tabs_in_tab_line( tabs_after_active: &mut Vec, tabs_to_render: &mut Vec, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) { let mut middle_size = get_current_title_len(tabs_to_render); @@ -109,7 +109,7 @@ fn populate_tabs_in_tab_line( fn left_more_message( tab_count_to_the_left: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -124,13 +124,15 @@ fn left_more_message( // 238 // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + let (text_color, sep_color) = ( + palette.ribbon_unselected.base, + palette.text_unselected.background, + ); + let left_separator = style!(sep_color, palette.ribbon_unselected.background).paint(separator); + let more_styled_text = style!(text_color, palette.ribbon_unselected.background) + .bold() + .paint(more_text); + let right_separator = style!(palette.ribbon_unselected.background, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -142,7 +144,7 @@ fn left_more_message( fn right_more_message( tab_count_to_the_right: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -156,13 +158,15 @@ fn right_more_message( }; // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + let (text_color, sep_color) = ( + palette.ribbon_unselected.base, + palette.text_unselected.background, + ); + let left_separator = style!(sep_color, palette.ribbon_unselected.background).paint(separator); + let more_styled_text = style!(text_color, palette.ribbon_unselected.background) + .bold() + .paint(more_text); + let right_separator = style!(palette.ribbon_unselected.background, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -172,18 +176,12 @@ fn right_more_message( } } -fn tab_line_prefix(session_name: Option<&str>, palette: Palette, cols: usize) -> Vec { +fn tab_line_prefix(session_name: Option<&str>, palette: Styling, cols: usize) -> Vec { let prefix_text = " Zellij ".to_string(); let prefix_text_len = prefix_text.chars().count(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; - let bg_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, - }; + let text_color = palette.text_unselected.base; + let bg_color = palette.text_unselected.background; let prefix_styled_text = style!(text_color, bg_color).bold().paint(prefix_text); let mut parts = vec![LinePart { part: prefix_styled_text.to_string(), @@ -193,10 +191,7 @@ fn tab_line_prefix(session_name: Option<&str>, palette: Palette, cols: usize) -> if let Some(name) = session_name { let name_part = format!("({}) ", name); let name_part_len = name_part.width(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; + let text_color = palette.text_unselected.base; let name_part_styled_text = style!(text_color, bg_color).bold().paint(name_part); if cols.saturating_sub(prefix_text_len) >= name_part_len { parts.push(LinePart { @@ -222,7 +217,7 @@ pub fn tab_line( mut all_tabs: Vec, active_tab_index: usize, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, hide_session_name: bool, tab_info: Option<&TabInfo>, @@ -290,7 +285,14 @@ pub fn tab_line( let mut padding = String::new(); let mut padding_len = 0; for _ in 0..remaining_space { - padding.push_str(" "); + padding.push_str( + &style!( + palette.text_unselected.background, + palette.text_unselected.background + ) + .paint(" ") + .to_string(), + ); padding_len += 1; } swap_layout_indicator.part = format!("{}{}", padding, swap_layout_indicator.part); diff --git a/default-plugins/tab-bar/src/main.rs b/default-plugins/tab-bar/src/main.rs index f38c245b7f..c841971587 100644 --- a/default-plugins/tab-bar/src/main.rs +++ b/default-plugins/tab-bar/src/main.rs @@ -125,10 +125,7 @@ impl ZellijPlugin for State { 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, - }; + let background = self.mode_info.style.colors.text_unselected.background; self.tab_line = tab_line( self.mode_info.session_name.as_deref(), diff --git a/default-plugins/tab-bar/src/tab.rs b/default-plugins/tab-bar/src/tab.rs index 0c66d25af3..194b99bb41 100644 --- a/default-plugins/tab-bar/src/tab.rs +++ b/default-plugins/tab-bar/src/tab.rs @@ -4,12 +4,15 @@ use unicode_width::UnicodeWidthStr; use zellij_tile::prelude::*; use zellij_tile_utils::style; -fn cursors(focused_clients: &[ClientId], palette: Palette) -> (Vec, usize) { +fn cursors( + focused_clients: &[ClientId], + multiplayer_colors: MultiplayerColors, +) -> (Vec, usize) { // cursor section, text length let mut len = 0; let mut cursors = vec![]; for client_id in focused_clients.iter() { - if let Some(color) = client_id_to_colors(*client_id, palette) { + if let Some(color) = client_id_to_colors(*client_id, multiplayer_colors) { cursors.push(style!(color.1, color.0).paint(" ")); len += 1; } @@ -21,36 +24,41 @@ pub fn render_tab( text: String, tab: &TabInfo, is_alternate_tab: bool, - palette: Palette, + palette: Styling, separator: &str, ) -> LinePart { let focused_clients = tab.other_focused_clients.as_slice(); let separator_width = separator.width(); - let alternate_tab_color = match palette.theme_hue { - // TODO: only do this if we don't have the arrow capabilities - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, + + let alternate_tab_color = if is_alternate_tab { + palette.text_unselected.background + } else { + palette.ribbon_unselected.background }; let background_color = if tab.active { - palette.green + palette.ribbon_selected.background } else if is_alternate_tab { alternate_tab_color } else { - palette.fg + palette.ribbon_unselected.background }; - let foreground_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, + let foreground_color = if tab.active { + palette.ribbon_selected.base + } else { + palette.ribbon_unselected.base }; - let left_separator = style!(foreground_color, background_color).paint(separator); + + let separator_fill_color = palette.text_unselected.background; + let left_separator = style!(separator_fill_color, background_color).paint(separator); let mut tab_text_len = text.width() + (separator_width * 2) + 2; // +2 for padding let tab_styled_text = style!(foreground_color, background_color) .bold() .paint(format!(" {} ", text)); - let right_separator = style!(background_color, foreground_color).paint(separator); + let right_separator = style!(background_color, separator_fill_color).paint(separator); let tab_styled_text = if !focused_clients.is_empty() { - let (cursor_section, extra_length) = cursors(focused_clients, palette); + let (cursor_section, extra_length) = + cursors(focused_clients, palette.multiplayer_user_colors); tab_text_len += extra_length + 2; // 2 for cursor_beginning and cursor_end let mut s = String::new(); let cursor_beginning = style!(foreground_color, background_color) @@ -84,7 +92,7 @@ pub fn tab_style( mut tabname: String, tab: &TabInfo, mut is_alternate_tab: bool, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) -> LinePart { let separator = tab_separator(capabilities); diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 8738650e71..0d7b313b3c 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -216,7 +216,7 @@ pub fn start_client( let palette = config .theme_config(config_options.theme.as_ref()) - .unwrap_or_else(|| os_input.load_palette()); + .unwrap_or_else(|| os_input.load_palette().into()); let full_screen_ws = os_input.get_terminal_size_using_fd(0); let client_attributes = ClientAttributes { @@ -616,7 +616,7 @@ pub fn start_server_detached( let palette = config .theme_config(config_options.theme.as_ref()) - .unwrap_or_else(|| os_input.load_palette()); + .unwrap_or_else(|| os_input.load_palette().into()); let client_attributes = ClientAttributes { size: Size { rows: 50, cols: 50 }, // just so size is not 0, it doesn't matter because we diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index a4daf6f9d6..c87d754704 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -353,7 +353,7 @@ impl SessionMetaData { .unwrap_or_else(Default::default), theme: new_config .theme_config(new_config.options.theme.as_ref()) - .unwrap_or_else(|| default_palette()), + .unwrap_or_else(|| default_palette().into()), simplified_ui: new_config.options.simplified_ui.unwrap_or(false), default_shell: new_config.options.default_shell, pane_frames: new_config.options.pane_frames.unwrap_or(true), diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs index d0ce41e8b9..8573e1f3a4 100644 --- a/zellij-server/src/panes/floating_panes/mod.rs +++ b/zellij-server/src/panes/floating_panes/mod.rs @@ -22,7 +22,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::rc::Rc; use std::time::Instant; use zellij_utils::{ - data::{ModeInfo, Palette, Style}, + data::{ModeInfo, Style, Styling}, errors::prelude::*, input::command::RunCommand, input::layout::{FloatingPaneLayout, Run, RunPluginOrAlias}, @@ -1028,7 +1028,7 @@ impl FloatingPanes { }, } } - pub fn update_pane_themes(&mut self, theme: Palette) { + pub fn update_pane_themes(&mut self, theme: Styling) { self.style.colors = theme; for pane in self.panes.values_mut() { pane.update_theme(theme); diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs index 0cc7ba2cec..9afa86f15c 100644 --- a/zellij-server/src/panes/grid.rs +++ b/zellij-server/src/panes/grid.rs @@ -16,7 +16,7 @@ use std::{ use zellij_utils::{ consts::{DEFAULT_SCROLL_BUFFER_SIZE, SCROLL_BUFFER_SIZE}, - data::{Palette, PaletteColor}, + data::{Palette, PaletteColor, Styling}, pane_size::SizeInPixels, position::Position, vte, @@ -1093,14 +1093,19 @@ impl Grid { .selection .contains_row(character_chunk.y.saturating_sub(content_y)) { - let background_color = match style.colors.bg { + let background_color = match style.colors.text_selected.background { PaletteColor::Rgb(rgb) => AnsiCode::RgbCode(rgb), PaletteColor::EightBit(col) => AnsiCode::ColorIndex(col), }; + let foreground_color = match style.colors.text_selected.base { + PaletteColor::Rgb(rgb) => AnsiCode::RgbCode(rgb), + PaletteColor::EightBit(col) => AnsiCode::ColorIndex(col), + }; + character_chunk.add_selection_and_colors( self.selection, background_color, - None, + Some(foreground_color), content_x, content_y, ); @@ -1109,9 +1114,15 @@ impl Grid { if res.contains_row(character_chunk.y.saturating_sub(content_y)) { let (select_background_palette, select_foreground_palette) = if Some(res) == self.search_results.active.as_ref() { - (style.colors.orange, style.colors.black) + ( + style.colors.text_unselected.emphasis_1, + style.colors.text_unselected.background, + ) } else { - (style.colors.green, style.colors.black) + ( + style.colors.text_unselected.emphasis_3, + style.colors.text_unselected.background, + ) }; let background_color = match select_background_palette { PaletteColor::Rgb(rgb) => AnsiCode::RgbCode(rgb), @@ -2164,7 +2175,7 @@ impl Grid { pub fn unlock_renders(&mut self) { self.lock_renders = false; } - pub fn update_theme(&mut self, theme: Palette) { + pub fn update_theme(&mut self, theme: Styling) { self.style.colors = theme.clone(); } pub fn update_arrow_fonts(&mut self, should_support_arrow_fonts: bool) { diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs index 7bc2a9724c..241930786d 100644 --- a/zellij-server/src/panes/plugin_pane.rs +++ b/zellij-server/src/panes/plugin_pane.rs @@ -25,7 +25,7 @@ use zellij_utils::pane_size::{Offset, SizeInPixels}; use zellij_utils::position::Position; use zellij_utils::{ channels::SenderWithContext, - data::{Event, InputMode, Mouse, Palette, PaletteColor, Style}, + data::{Event, InputMode, Mouse, Palette, PaletteColor, Style, Styling}, errors::prelude::*, input::layout::Run, pane_size::PaneGeom, @@ -623,7 +623,7 @@ impl Pane for PluginPane { .unwrap(); } fn add_red_pane_frame_color_override(&mut self, error_text: Option) { - self.pane_frame_color_override = Some((self.style.colors.red, error_text)); + self.pane_frame_color_override = Some((self.style.colors.exit_code_error.base, error_text)); } fn clear_pane_frame_color_override(&mut self) { self.pane_frame_color_override = None; @@ -681,7 +681,7 @@ impl Pane for PluginPane { self.pane_name = String::from_utf8_lossy(&buf).to_string(); self.set_should_render(true); } - fn update_theme(&mut self, theme: Palette) { + fn update_theme(&mut self, theme: Styling) { self.style.colors = theme.clone(); for grid in self.grids.values_mut() { grid.update_theme(theme.clone()); @@ -743,10 +743,10 @@ impl PluginPane { } } fn display_request_permission_message(&self, plugin_permission: &PluginPermission) -> String { - let bold_white = style!(self.style.colors.white).bold(); - let cyan = style!(self.style.colors.cyan).bold(); - let orange = style!(self.style.colors.orange).bold(); - let green = style!(self.style.colors.green).bold(); + let bold_white = style!(self.style.colors.text_unselected.base).bold(); + let cyan = style!(self.style.colors.text_unselected.emphasis_2).bold(); + let orange = style!(self.style.colors.text_unselected.emphasis_1).bold(); + let green = style!(self.style.colors.text_unselected.emphasis_3).bold(); let mut messages = String::new(); let permissions: BTreeSet = diff --git a/zellij-server/src/panes/terminal_character.rs b/zellij-server/src/panes/terminal_character.rs index 3bdc6559fd..c95dbc9617 100644 --- a/zellij-server/src/panes/terminal_character.rs +++ b/zellij-server/src/panes/terminal_character.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use unicode_width::UnicodeWidthChar; use unicode_width::UnicodeWidthStr; +use zellij_utils::data::StyleDeclaration; use zellij_utils::input::command::RunCommand; use zellij_utils::{ data::{PaletteColor, Style}, @@ -762,6 +763,12 @@ impl Display for CharacterStyles { } } +impl From for CharacterStyles { + fn from(declaration: StyleDeclaration) -> Self { + RESET_STYLES.foreground(Some(declaration.base.into())) + } +} + #[derive(Clone, Copy, Debug, PartialEq)] pub enum LinkAnchor { Start(u16), @@ -977,7 +984,9 @@ pub fn render_first_run_banner( Some(run_command) => { let bold_text = RESET_STYLES.bold(Some(AnsiCode::On)); let command_color_text = RESET_STYLES - .foreground(Some(AnsiCode::from(style.colors.green))) + .foreground(Some(AnsiCode::from( + style.colors.text_unselected.emphasis_3, + ))) .bold(Some(AnsiCode::On)); let waiting_to_run_text = "Waiting to run: "; let command_text = run_command.to_string(); @@ -1002,7 +1011,9 @@ pub fn render_first_run_banner( let ctrl_c_bare_text = "Ctrl-c"; let controls_bare_text_fourth_part = "> exit"; let controls_color = RESET_STYLES - .foreground(Some(AnsiCode::from(style.colors.orange))) + .foreground(Some(AnsiCode::from( + style.colors.text_unselected.emphasis_1, + ))) .bold(Some(AnsiCode::On)); let controls_line_length = controls_bare_text_first_part.len() + enter_bare_text.len() @@ -1054,7 +1065,9 @@ pub fn render_first_run_banner( let ctrl_c_bare_text = "Ctrl-c"; let controls_bare_text_fourth_part = "> exit"; let controls_color = RESET_STYLES - .foreground(Some(AnsiCode::from(style.colors.orange))) + .foreground(Some(AnsiCode::from( + style.colors.text_unselected.emphasis_1, + ))) .bold(Some(AnsiCode::On)); let controls_line_length = controls_bare_text_first_part.len() + enter_bare_text.len() diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs index fe1a96ae4f..5e80927da0 100644 --- a/zellij-server/src/panes/terminal_pane.rs +++ b/zellij-server/src/panes/terminal_pane.rs @@ -18,7 +18,7 @@ use zellij_utils::pane_size::Offset; use zellij_utils::{ data::{ BareKey, InputMode, KeyWithModifier, Palette, PaletteColor, PaneId as ZellijUtilsPaneId, - Style, + Style, Styling, }, errors::prelude::*, input::layout::Run, @@ -727,7 +727,7 @@ impl Pane for TerminalPane { self.set_should_render(true); } fn add_red_pane_frame_color_override(&mut self, error_text: Option) { - self.pane_frame_color_override = Some((self.style.colors.red, error_text)); + self.pane_frame_color_override = Some((self.style.colors.exit_code_error.base, error_text)); } fn clear_pane_frame_color_override(&mut self) { self.pane_frame_color_override = None; @@ -794,7 +794,7 @@ impl Pane for TerminalPane { run_command.clone() }) } - fn update_theme(&mut self, theme: Palette) { + fn update_theme(&mut self, theme: Styling) { self.style.colors = theme.clone(); self.grid.update_theme(theme); if self.banner.is_some() { diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs index 0223a79ecb..37c90c4a93 100644 --- a/zellij-server/src/panes/tiled_panes/mod.rs +++ b/zellij-server/src/panes/tiled_panes/mod.rs @@ -18,7 +18,7 @@ use crate::{ }; use stacked_panes::StackedPanes; use zellij_utils::{ - data::{Direction, ModeInfo, Palette, PaneInfo, ResizeStrategy, Style}, + data::{Direction, ModeInfo, Palette, PaneInfo, ResizeStrategy, Style, Styling}, errors::prelude::*, input::{ command::RunCommand, @@ -1806,7 +1806,7 @@ impl TiledPanes { } pane_infos } - pub fn update_pane_themes(&mut self, theme: Palette) { + pub fn update_pane_themes(&mut self, theme: Styling) { self.style.colors = theme; for pane in self.panes.values_mut() { pane.update_theme(theme); diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__ribbon_ui_component.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__ribbon_ui_component.snap index 0fc9c80809..d06338841c 100644 --- a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__ribbon_ui_component.snap +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__ribbon_ui_component.snap @@ -1,9 +1,8 @@ --- source: zellij-server/src/panes/./unit/grid_tests.rs -assertion_line: 2921 expression: "format!(\"{:?}\", grid)" --- -00 (C):  RESIZE  +00 (C):  [1m<[38;5;9mn[39;38;5;0m> RESIZE  01 (C): 02 (C): 03 (C): @@ -43,5 +42,4 @@ expression: "format!(\"{:?}\", grid)" 37 (C): 38 (C): 39 (C): -40 (C): - +40 (C): diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__table_ui_component.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__table_ui_component.snap index 9424207699..50e40db7e9 100644 --- a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__table_ui_component.snap +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__table_ui_component.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/panes/./unit/grid_tests.rs -assertion_line: 3102 expression: "format!(\"{:?}\", grid)" --- 00 (C): title1 title2 title3 title4 title5 @@ -9,7 +8,7 @@ expression: "format!(\"{:?}\", grid)" 03 (C): 3lksdjflksdjf lkjdsflksjdf lkjsd😳lkfjsfd lkjsdlkjfd lkjdslkjsdf 04 (C): 4lksdjflks222djf lk😳222jdsflksjdf lk222jsdlkfjsfd lkwwwjsdlkjfd lkjdslkjsdf 05 (C): 5lksdjflksdjf lkjdsflksjdf lkjsdlkfjsfd lksdjflksjfdlkjsdlkjfd lkjdrrrrslkjsdf -06 (C): 6lksdjflk😳sdjf l😳kjdsflksjdf lkjsdlkfjsfd lkjsdlkjfd lwwkwkjdslkjsdf +06 (C): [36m6lksdjflk😳sdjf [46ml😳kjdsflksjdf lkjsdlkfjsfd lkjsdlkjfd lwwkwkjdslkjsdf 07 (C): 08 (C): 09 (C): @@ -43,5 +42,4 @@ expression: "format!(\"{:?}\", grid)" 37 (C): 38 (C): 39 (C): -40 (C): - +40 (C): diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 82c1a341cb..874afaee87 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -9,7 +9,8 @@ use std::time::Duration; use log::{debug, warn}; use zellij_utils::data::{ - Direction, KeyWithModifier, PaneManifest, PluginPermission, Resize, ResizeStrategy, SessionInfo, + Direction, KeyWithModifier, PaneManifest, PluginPermission, Resize, ResizeStrategy, + SessionInfo, Styling, }; use zellij_utils::errors::prelude::*; use zellij_utils::input::command::RunCommand; @@ -364,7 +365,7 @@ pub enum ScreenInstruction { client_id: ClientId, keybinds: Keybinds, default_mode: InputMode, - theme: Palette, + theme: Styling, simplified_ui: bool, default_shell: Option, pane_frames: bool, @@ -2439,7 +2440,7 @@ impl Screen { &mut self, new_keybinds: Keybinds, new_default_mode: InputMode, - theme: Palette, + theme: Styling, simplified_ui: bool, default_shell: Option, pane_frames: bool, diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index de5bba6515..9c20496e38 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -48,7 +48,9 @@ use std::{ str, }; use zellij_utils::{ - data::{Event, FloatingPaneCoordinates, InputMode, ModeInfo, Palette, PaletteColor, Style}, + data::{ + Event, FloatingPaneCoordinates, InputMode, ModeInfo, Palette, PaletteColor, Style, Styling, + }, input::{ command::TerminalAction, layout::{ @@ -200,7 +202,7 @@ pub(crate) struct TabData { pub name: String, pub active: bool, pub mode_info: ModeInfo, - pub colors: Palette, + pub colors: Styling, } // FIXME: Use a struct that has a pane_type enum, to reduce all of the duplication @@ -497,7 +499,7 @@ pub trait Pane { fn rerun(&mut self) -> Option { None } // only relevant to terminal panes - fn update_theme(&mut self, _theme: Palette) {} + fn update_theme(&mut self, _theme: Styling) {} fn update_arrow_fonts(&mut self, _should_support_arrow_fonts: bool) {} fn update_rounded_corners(&mut self, _rounded_corners: bool) {} fn set_should_be_suppressed(&mut self, _should_be_suppressed: bool) {} @@ -4363,7 +4365,7 @@ impl Tab { } Ok(()) } - pub fn update_theme(&mut self, theme: Palette) { + pub fn update_theme(&mut self, theme: Styling) { self.style.colors = theme; self.floating_panes.update_pane_themes(theme); self.tiled_panes.update_pane_themes(theme); diff --git a/zellij-server/src/ui/components/mod.rs b/zellij-server/src/ui/components/mod.rs index 260e2c2a60..db4094eb16 100644 --- a/zellij-server/src/ui/components/mod.rs +++ b/zellij-server/src/ui/components/mod.rs @@ -10,7 +10,7 @@ use zellij_utils::{data::Style, lazy_static::lazy_static, regex::Regex, vte}; use component_coordinates::{is_too_high, is_too_wide, Coordinates}; use nested_list::{nested_list, parse_nested_list_items}; -use ribbon::{emphasis_variants_for_ribbon, emphasis_variants_for_selected_ribbon, ribbon}; +use ribbon::ribbon; use table::table; use text::{parse_text, parse_text_params, stringify_text, text, Text}; @@ -87,7 +87,6 @@ impl<'a> UiComponentParser<'a> { columns, rows, stringified_params, - Some(self.style.colors.green), &self.style, component_coordinates, ); diff --git a/zellij-server/src/ui/components/nested_list.rs b/zellij-server/src/ui/components/nested_list.rs index 4d32141441..c2aa286034 100644 --- a/zellij-server/src/ui/components/nested_list.rs +++ b/zellij-server/src/ui/components/nested_list.rs @@ -2,7 +2,7 @@ use super::{ is_too_high, parse_indices, parse_opaque, parse_selected, parse_text, stringify_text, Coordinates, Text, }; -use crate::panes::terminal_character::{AnsiCode, RESET_STYLES}; +use crate::panes::terminal_character::{AnsiCode, CharacterStyles, RESET_STYLES}; use zellij_utils::data::Style; use unicode_width::UnicodeWidthChar; @@ -27,37 +27,29 @@ pub fn nested_list( if is_too_high(line_index + 1, &coordinates) { break; } - let mut reset_styles_for_item = RESET_STYLES; - reset_styles_for_item.background = None; - reset_styles_for_item.foreground = None; + let style_declaration = if line_item.text.selected { + style.colors.list_selected + } else { + style.colors.list_unselected + }; let padding = line_item.indentation_level * 2 + 1; let bulletin = if line_item.indentation_level % 2 == 0 { "> " } else { "- " }; - let text_style = if line_item.text.selected { - reset_styles_for_item - .bold(Some(AnsiCode::On)) - .foreground(Some(style.colors.white.into())) - .background(Some(style.colors.bg.into())) - } 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())) + let text_style = if line_item.text.opaque || line_item.text.selected { + CharacterStyles::from(style_declaration) + .background(Some(style_declaration.background.into())) } else { - reset_styles_for_item - .bold(Some(AnsiCode::On)) - .foreground(Some(style.colors.white.into())) + CharacterStyles::from(style_declaration) }; let (mut text, text_width) = stringify_text( &line_item.text, Some(padding + bulletin.len()), &coordinates, - style, - text_style, - line_item.text.selected, + &style_declaration, + text_style.bold(Some(AnsiCode::On)), ); text = pad_line(text, max_width, padding, text_width); let go_to_row_instruction = coordinates @@ -70,20 +62,13 @@ pub fn nested_list( "".to_owned() } }); - let line_style = if line_item.text.selected { - RESET_STYLES - .foreground(Some(style.colors.white.into())) - .background(Some(style.colors.bg.into())) - } 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}{}", - go_to_row_instruction, line_style, reset_styles_for_item, " ", text_style, RESET_STYLES + "{}{}{:padding$}{bulletin}{}{text}{}", + go_to_row_instruction, + text_style, + " ", + text_style.bold(Some(AnsiCode::On)), + RESET_STYLES )); } stringified.as_bytes().to_vec() diff --git a/zellij-server/src/ui/components/ribbon.rs b/zellij-server/src/ui/components/ribbon.rs index 7f0f781592..b1b9901ce8 100644 --- a/zellij-server/src/ui/components/ribbon.rs +++ b/zellij-server/src/ui/components/ribbon.rs @@ -1,6 +1,5 @@ -use super::{is_too_wide, Coordinates, Text}; +use super::{text::stringify_text, Coordinates, Text}; use crate::panes::terminal_character::{AnsiCode, CharacterStyles, RESET_STYLES}; -use unicode_width::UnicodeWidthChar; use zellij_utils::data::{PaletteColor, Style}; static ARROW_SEPARATOR: &str = ""; @@ -12,21 +11,24 @@ pub fn ribbon( component_coordinates: Option, ) -> Vec { let colors = style.colors; - let (first_arrow_styles, text_style, last_arrow_styles) = if content.selected { - ( - character_style(colors.black, colors.green), - character_style(colors.black, colors.green), - character_style(colors.green, colors.black), - ) + let background = colors.text_unselected.background; + let declaration = if content.selected { + colors.ribbon_selected } else { - ( - character_style(colors.black, colors.fg), - character_style(colors.black, colors.fg), - character_style(colors.fg, colors.black), - ) + colors.ribbon_unselected }; - let (text, _text_width) = - stringify_ribbon_text(&content, &component_coordinates, style, text_style); + let (first_arrow_styles, text_style, last_arrow_styles) = ( + character_style(background, declaration.background), + character_style(declaration.base, declaration.background), + character_style(declaration.background, background), + ); + let (text, _text_width) = stringify_text( + &content, + None, + &component_coordinates, + &declaration, + text_style, + ); let mut stringified = component_coordinates .map(|c| c.to_string()) .unwrap_or_else(|| String::new()); @@ -45,68 +47,6 @@ pub fn ribbon( stringified.as_bytes().to_vec() } -pub fn emphasis_variants_for_ribbon(style: &Style) -> [PaletteColor; 4] { - [ - style.colors.red, - style.colors.white, - style.colors.blue, - style.colors.magenta, - ] -} - -pub fn emphasis_variants_for_selected_ribbon(style: &Style) -> [PaletteColor; 4] { - [ - style.colors.red, - style.colors.orange, - style.colors.magenta, - style.colors.blue, - ] -} - -fn stringify_ribbon_text( - text: &Text, - coordinates: &Option, - style: &Style, - text_style: CharacterStyles, -) -> (String, usize) { - let mut stringified = String::new(); - let mut text_width = 0; - for (i, character) in text.text.chars().enumerate() { - let character_width = character.width().unwrap_or(0); - if is_too_wide(character_width, text_width, &coordinates) { - break; - } - if !text.indices.is_empty() { - let character_with_styling = - color_ribbon_index_character(character, i, &text, style, text_style); - stringified.push_str(&character_with_styling); - } else { - stringified.push(character); - } - text_width += character_width; - } - (stringified, text_width) -} - -fn color_ribbon_index_character( - character: char, - index: usize, - text: &Text, - style: &Style, - base_style: CharacterStyles, -) -> String { - let character_style = if text.selected { - text.style_of_index_for_selected_ribbon(index, style) - .map(|foreground_style| base_style.foreground(Some(foreground_style.into()))) - .unwrap_or(base_style) - } else { - text.style_of_index_for_ribbon(index, style) - .map(|foreground_style| base_style.foreground(Some(foreground_style.into()))) - .unwrap_or(base_style) - }; - format!("{}{}{}", character_style, character, base_style) -} - fn character_style(foreground: PaletteColor, background: PaletteColor) -> CharacterStyles { RESET_STYLES .foreground(Some(foreground.into())) diff --git a/zellij-server/src/ui/components/table.rs b/zellij-server/src/ui/components/table.rs index cdb664556b..8d3b45e413 100644 --- a/zellij-server/src/ui/components/table.rs +++ b/zellij-server/src/ui/components/table.rs @@ -1,16 +1,12 @@ use super::{is_too_high, is_too_wide, stringify_text, Coordinates, Text}; use crate::panes::terminal_character::{AnsiCode, RESET_STYLES}; use std::collections::BTreeMap; -use zellij_utils::{ - data::{PaletteColor, Style}, - shared::ansi_len, -}; +use zellij_utils::{data::Style, shared::ansi_len}; pub fn table( columns: usize, _rows: usize, contents: Vec, - title_color: Option, style: &Style, coordinates: Option, ) -> Vec { @@ -18,34 +14,41 @@ pub fn table( // we first arrange the data by columns so that we can pad them by the widest one let stringified_columns = stringify_table_columns(contents, columns); let stringified_rows = stringify_table_rows(stringified_columns, &coordinates); - let title_styles = RESET_STYLES - .foreground(title_color.map(|t| t.into())) - .bold(Some(AnsiCode::On)); - let cell_styles = RESET_STYLES.bold(Some(AnsiCode::On)); for (row_index, (_, row)) in stringified_rows.into_iter().enumerate() { let is_title_row = row_index == 0; if is_too_high(row_index + 1, &coordinates) { break; } for cell in row { - let mut reset_styles_for_item = RESET_STYLES; - let mut text_style = if is_title_row { - title_styles + let (reset_styles_for_item, declaration) = if is_title_row { + (RESET_STYLES.background(None), style.colors.table_title) } else { - cell_styles + if cell.selected { + ( + RESET_STYLES + .background(Some(style.colors.table_cell_selected.background.into())), + style.colors.table_cell_selected, + ) + } else { + ( + RESET_STYLES.background(None), + style.colors.table_cell_unselected, + ) + } }; - 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 - let (text, _text_width) = - stringify_text(&cell, None, &None, style, text_style, cell.selected); - stringified.push_str(&format!("{}{}{} ", text_style, text, reset_styles_for_item)); + let (text, _text_width) = stringify_text( + &cell, + None, + &None, + &declaration, + reset_styles_for_item.bold(Some(AnsiCode::On)), + ); + stringified.push_str(&format!( + "{}{} {}", + reset_styles_for_item, text, RESET_STYLES + )); } let next_row_instruction = coordinates .as_ref() diff --git a/zellij-server/src/ui/components/text.rs b/zellij-server/src/ui/components/text.rs index 2173f72f4c..56a99f6aec 100644 --- a/zellij-server/src/ui/components/text.rs +++ b/zellij-server/src/ui/components/text.rs @@ -1,10 +1,7 @@ -use super::{ - emphasis_variants_for_ribbon, emphasis_variants_for_selected_ribbon, is_too_wide, - parse_indices, parse_opaque, parse_selected, Coordinates, -}; -use crate::panes::terminal_character::{AnsiCode, CharacterStyles, RESET_STYLES}; +use super::{is_too_wide, parse_indices, parse_opaque, parse_selected, Coordinates}; +use crate::panes::{terminal_character::CharacterStyles, AnsiCode}; use zellij_utils::{ - data::{PaletteColor, Style}, + data::{PaletteColor, Style, StyleDeclaration}, shared::ansi_len, }; @@ -12,28 +9,28 @@ use unicode_width::UnicodeWidthChar; use zellij_utils::errors::prelude::*; pub fn text(content: Text, style: &Style, component_coordinates: Option) -> Vec { - let mut text_style = RESET_STYLES - .bold(Some(AnsiCode::On)) - .foreground(Some(style.colors.white.into())); + let declaration = if content.selected { + style.colors.text_selected + } else { + style.colors.text_unselected + }; + + let base_text_style = CharacterStyles::from(declaration).bold(Some(AnsiCode::On)); - 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, None, &component_coordinates, - style, - text_style, - content.selected, + &declaration, + base_text_style, ); match component_coordinates { - Some(component_coordinates) => format!("{}{}{}", component_coordinates, text_style, text) - .as_bytes() - .to_vec(), - None => format!("{}{}", text_style, text).as_bytes().to_vec(), + Some(component_coordinates) => { + format!("{}{}{}", component_coordinates, base_text_style, text) + .as_bytes() + .to_vec() + }, + None => format!("{}{}", base_text_style, text).as_bytes().to_vec(), } } @@ -41,12 +38,16 @@ pub fn stringify_text( text: &Text, left_padding: Option, coordinates: &Option, - style: &Style, - text_style: CharacterStyles, - is_selected: bool, + style: &StyleDeclaration, + component_text_style: CharacterStyles, ) -> (String, usize) { let mut text_width = 0; let mut stringified = String::new(); + let base_text_style = if text.opaque || text.selected { + component_text_style.background(Some(style.background.into())) + } else { + component_text_style + }; for (i, character) in text.text.chars().enumerate() { let character_width = character.width().unwrap_or(0); if is_too_wide( @@ -57,16 +58,12 @@ pub fn stringify_text( break; } text_width += character_width; - if !text.indices.is_empty() { - let character_with_styling = - color_index_character(character, i, &text, style, text_style, is_selected); - stringified.push_str(&character_with_styling); - } else { - stringified.push(character); - } + let character_with_styling = + color_index_character(character, i, &text, style, base_text_style); + stringified.push_str(&character_with_styling); } let coordinates_width = coordinates.as_ref().and_then(|c| c.width); - match (coordinates_width, text_style.background) { + match (coordinates_width, base_text_style.background) { (Some(coordinates_width), Some(_background_style)) => { let text_width_with_left_padding = text_width + left_padding.unwrap_or(0); let background_padding_length = @@ -91,32 +88,16 @@ pub fn color_index_character( character: char, index: usize, text: &Text, - style: &Style, + declaration: &StyleDeclaration, base_text_style: CharacterStyles, - is_selected: bool, ) -> String { let character_style = text - .style_of_index(index, style) - .map(|foreground_style| { - let mut character_style = base_text_style.foreground(Some(foreground_style.into())); - if is_selected { - character_style = character_style.background(Some(style.colors.bg.into())); - }; - character_style - }) + .style_of_index(index, declaration) + .map(|foreground_style| base_text_style.foreground(Some(foreground_style.into()))) .unwrap_or(base_text_style); format!("{}{}{}", character_style, character, base_text_style) } -pub fn emphasis_variants(style: &Style) -> [PaletteColor; 4] { - [ - style.colors.orange, - style.colors.cyan, - style.colors.green, - style.colors.magenta, - ] -} - pub fn parse_text_params<'a>(params_iter: impl Iterator) -> Vec { params_iter .flat_map(|mut stringified| { @@ -148,38 +129,14 @@ impl Text { self.text.push(' '); } } - pub fn style_of_index(&self, index: usize, style: &Style) -> Option { - let index_variant_styles = emphasis_variants(style); - for i in (0..=3).rev() { - // we do this in reverse to give precedence to the last applied - // style - if let Some(indices) = self.indices.get(i) { - if indices.contains(&index) { - return Some(index_variant_styles[i]); - } - } - } - None - } - pub fn style_of_index_for_ribbon(&self, index: usize, style: &Style) -> Option { - let index_variant_styles = emphasis_variants_for_ribbon(style); - for i in (0..=3).rev() { - // we do this in reverse to give precedence to the last applied - // style - if let Some(indices) = self.indices.get(i) { - if indices.contains(&index) { - return Some(index_variant_styles[i]); - } - } - } - None - } - pub fn style_of_index_for_selected_ribbon( - &self, - index: usize, - style: &Style, - ) -> Option { - let index_variant_styles = emphasis_variants_for_selected_ribbon(style); + + pub fn style_of_index(&self, index: usize, style: &StyleDeclaration) -> Option { + let index_variant_styles = [ + style.emphasis_1, + style.emphasis_2, + style.emphasis_3, + style.emphasis_4, + ]; for i in (0..=3).rev() { // we do this in reverse to give precedence to the last applied // style @@ -189,7 +146,7 @@ impl Text { } } } - None + Some(style.base) } } diff --git a/zellij-server/src/ui/loading_indication.rs b/zellij-server/src/ui/loading_indication.rs index 1c77d03983..a9c55bf9ff 100644 --- a/zellij-server/src/ui/loading_indication.rs +++ b/zellij-server/src/ui/loading_indication.rs @@ -1,7 +1,7 @@ use std::fmt::{Display, Error, Formatter}; use zellij_utils::{ - data::{Palette, PaletteColor}, + data::{PaletteColor, Styling}, errors::prelude::*, }; @@ -24,7 +24,7 @@ pub struct LoadingIndication { error: Option, animation_offset: usize, plugin_name: String, - terminal_emulator_colors: Option, + terminal_emulator_colors: Option, override_previous_error: bool, } @@ -39,7 +39,7 @@ impl LoadingIndication { pub fn set_name(&mut self, plugin_name: String) { self.plugin_name = plugin_name; } - pub fn with_colors(mut self, terminal_emulator_colors: Palette) -> Self { + pub fn with_colors(mut self, terminal_emulator_colors: Styling) -> Self { self.terminal_emulator_colors = Some(terminal_emulator_colors); self } @@ -142,19 +142,27 @@ macro_rules! style { impl Display for LoadingIndication { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { let cyan = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.cyan).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_success.emphasis_1).bold() + }, None => ansi_term::Style::new(), }; let green = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.green).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_success.base).bold() + }, None => ansi_term::Style::new(), }; let yellow = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.yellow).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_error.emphasis_1).bold() + }, None => ansi_term::Style::new(), }; let red = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.red).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_error.base).bold() + }, None => ansi_term::Style::new(), }; let bold = ansi_term::Style::new().bold().italic(); diff --git a/zellij-server/src/ui/pane_boundaries_frame.rs b/zellij-server/src/ui/pane_boundaries_frame.rs index c3884fbf7c..7587936167 100644 --- a/zellij-server/src/ui/pane_boundaries_frame.rs +++ b/zellij-server/src/ui/pane_boundaries_frame.rs @@ -127,7 +127,7 @@ impl PaneFrame { self.color = Some(color); } fn client_cursor(&self, client_id: ClientId) -> Vec { - let color = client_id_to_colors(client_id, self.style.colors); + let color = client_id_to_colors(client_id, self.style.colors.multiplayer_user_colors); background_color(" ", color.map(|c| c.0)) } fn get_corner(&self, corner: &'static str) -> &'static str { @@ -847,9 +847,9 @@ impl PaneFrame { let exited_text = "EXIT CODE: "; let exit_code_text = format!("{}", exit_code); let exit_code_color = if exit_code == 0 { - self.style.colors.green + self.style.colors.exit_code_success.base } else { - self.style.colors.red + self.style.colors.exit_code_error.base }; let right_bracket = " ] "; first_part.append(&mut foreground_color(left_bracket, self.color)); @@ -875,7 +875,7 @@ impl PaneFrame { first_part.append(&mut foreground_color(left_bracket, self.color)); first_part.append(&mut foreground_color( exited_text, - Some(self.style.colors.red), + Some(self.style.colors.exit_code_error.base), )); first_part.append(&mut foreground_color(right_bracket, self.color)); ( @@ -910,7 +910,7 @@ impl PaneFrame { second_part.append(&mut foreground_color(left_enter_bracket, self.color)); second_part.append(&mut foreground_color( enter_text, - Some(self.style.colors.orange), + Some(self.style.colors.text_unselected.emphasis_4), )); second_part.append(&mut foreground_color(right_enter_bracket, self.color)); second_part.append(&mut foreground_color(enter_tip, self.color)); @@ -918,7 +918,7 @@ impl PaneFrame { second_part.append(&mut foreground_color(left_esc_bracket, self.color)); second_part.append(&mut foreground_color( esc_text, - Some(self.style.colors.orange), + Some(self.style.colors.text_unselected.emphasis_4), )); second_part.append(&mut foreground_color(right_esc_bracket, self.color)); second_part.append(&mut foreground_color(esc_tip, self.color)); @@ -926,7 +926,7 @@ impl PaneFrame { second_part.append(&mut foreground_color(left_break_bracket, self.color)); second_part.append(&mut foreground_color( break_text, - Some(self.style.colors.orange), + Some(self.style.colors.text_unselected.emphasis_4), )); second_part.append(&mut foreground_color(right_break_bracket, self.color)); second_part.append(&mut foreground_color(break_tip, self.color)); diff --git a/zellij-server/src/ui/pane_contents_and_ui.rs b/zellij-server/src/ui/pane_contents_and_ui.rs index b2ed6383c4..f3091bea1d 100644 --- a/zellij-server/src/ui/pane_contents_and_ui.rs +++ b/zellij-server/src/ui/pane_contents_and_ui.rs @@ -5,9 +5,7 @@ use crate::ui::boundaries::Boundaries; use crate::ui::pane_boundaries_frame::FrameParams; use crate::ClientId; use std::collections::HashMap; -use zellij_utils::data::{ - client_id_to_colors, single_client_color, InputMode, PaletteColor, Style, -}; +use zellij_utils::data::{client_id_to_colors, InputMode, PaletteColor, Style}; use zellij_utils::errors::prelude::*; pub struct PaneContentsAndUi<'a> { pane: &'a mut Box, @@ -139,7 +137,10 @@ impl<'a> PaneContentsAndUi<'a> { .with_context(|| { format!("failed to render fake cursor if needed for client {client_id}") })?; - if let Some(colors) = client_id_to_colors(*fake_cursor_client_id, self.style.colors) { + if let Some(colors) = client_id_to_colors( + *fake_cursor_client_id, + self.style.colors.multiplayer_user_colors, + ) { let cursor_is_visible = self .pane .cursor_coordinates() @@ -276,14 +277,16 @@ impl<'a> PaneContentsAndUi<'a> { match mode { InputMode::Normal | InputMode::Locked => { if session_is_mirrored || !self.multiple_users_exist_in_session { - let colors = single_client_color(self.style.colors); // mirrored sessions only have one focused color - Some(colors.0) + Some(self.style.colors.frame_selected.base) } else { - let colors = client_id_to_colors(client_id, self.style.colors); + let colors = client_id_to_colors( + client_id, + self.style.colors.multiplayer_user_colors, + ); colors.map(|colors| colors.0) } }, - _ => Some(self.style.colors.orange), + _ => Some(self.style.colors.frame_highlight.base), } } else { None diff --git a/zellij-utils/assets/prost/api.style.rs b/zellij-utils/assets/prost/api.style.rs index cd768c3908..62080a5f97 100644 --- a/zellij-utils/assets/prost/api.style.rs +++ b/zellij-utils/assets/prost/api.style.rs @@ -1,12 +1,15 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Style { + #[deprecated] #[prost(message, optional, tag = "1")] pub palette: ::core::option::Option, #[prost(bool, tag = "2")] pub rounded_corners: bool, #[prost(bool, tag = "3")] pub hide_session_name: bool, + #[prost(message, optional, tag = "4")] + pub styling: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -77,6 +80,40 @@ pub struct RgbColorPayload { #[prost(uint32, tag = "3")] pub blue: u32, } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Styling { + #[prost(message, repeated, tag = "1")] + pub text_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub text_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub ribbon_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub ribbon_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "5")] + pub table_title: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "6")] + pub table_cell_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "7")] + pub table_cell_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "8")] + pub list_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "9")] + pub list_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "10")] + pub frame_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "11")] + pub frame_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "12")] + pub frame_highlight: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "13")] + pub exit_code_success: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "14")] + pub exit_code_error: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "15")] + pub multiplayer_user_colors: ::prost::alloc::vec::Vec, +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ColorType { diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs index 1f3adf305e..0155031b80 100644 --- a/zellij-utils/src/data.rs +++ b/zellij-utils/src/data.rs @@ -2,6 +2,7 @@ use crate::input::actions::Action; use crate::input::config::ConversionError; use crate::input::keybinds::Keybinds; use crate::input::layout::{RunPlugin, SplitSize}; +use crate::shared::colors as default_colors; use clap::ArgEnum; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; @@ -22,20 +23,21 @@ pub type ClientId = u16; // TODO: merge with crate type? pub fn client_id_to_colors( client_id: ClientId, - colors: Palette, + colors: MultiplayerColors, ) -> Option<(PaletteColor, PaletteColor)> { // (primary color, secondary color) + let black = PaletteColor::EightBit(default_colors::BLACK); match client_id { - 1 => Some((colors.magenta, colors.black)), - 2 => Some((colors.blue, colors.black)), - 3 => Some((colors.purple, colors.black)), - 4 => Some((colors.yellow, colors.black)), - 5 => Some((colors.cyan, colors.black)), - 6 => Some((colors.gold, colors.black)), - 7 => Some((colors.red, colors.black)), - 8 => Some((colors.silver, colors.black)), - 9 => Some((colors.pink, colors.black)), - 10 => Some((colors.brown, colors.black)), + 1 => Some((colors.player_1, black)), + 2 => Some((colors.player_2, black)), + 3 => Some((colors.player_3, black)), + 4 => Some((colors.player_4, black)), + 5 => Some((colors.player_5, black)), + 6 => Some((colors.player_6, black)), + 7 => Some((colors.player_7, black)), + 8 => Some((colors.player_8, black)), + 9 => Some((colors.player_9, black)), + 10 => Some((colors.player_10, black)), _ => None, } } @@ -1132,11 +1134,348 @@ pub struct Palette { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize)] pub struct Style { - pub colors: Palette, + pub colors: Styling, pub rounded_corners: bool, pub hide_session_name: bool, } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct Styling { + pub text_unselected: StyleDeclaration, + pub text_selected: StyleDeclaration, + pub ribbon_unselected: StyleDeclaration, + pub ribbon_selected: StyleDeclaration, + pub table_title: StyleDeclaration, + pub table_cell_unselected: StyleDeclaration, + pub table_cell_selected: StyleDeclaration, + pub list_unselected: StyleDeclaration, + pub list_selected: StyleDeclaration, + pub frame_unselected: StyleDeclaration, + pub frame_selected: StyleDeclaration, + pub frame_highlight: StyleDeclaration, + pub exit_code_success: StyleDeclaration, + pub exit_code_error: StyleDeclaration, + pub multiplayer_user_colors: MultiplayerColors, +} + +#[derive(Debug, Copy, Default, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct StyleDeclaration { + pub base: PaletteColor, + pub background: PaletteColor, + pub emphasis_1: PaletteColor, + pub emphasis_2: PaletteColor, + pub emphasis_3: PaletteColor, + pub emphasis_4: PaletteColor, +} + +#[derive(Debug, Copy, Default, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct MultiplayerColors { + pub player_1: PaletteColor, + pub player_2: PaletteColor, + pub player_3: PaletteColor, + pub player_4: PaletteColor, + pub player_5: PaletteColor, + pub player_6: PaletteColor, + pub player_7: PaletteColor, + pub player_8: PaletteColor, + pub player_9: PaletteColor, + pub player_10: PaletteColor, +} + +pub const DEFAULT_STYLES: Styling = Styling { + text_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + text_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + ribbon_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BLACK), + emphasis_1: PaletteColor::EightBit(default_colors::RED), + emphasis_2: PaletteColor::EightBit(default_colors::WHITE), + emphasis_3: PaletteColor::EightBit(default_colors::BLUE), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + ribbon_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BLACK), + emphasis_1: PaletteColor::EightBit(default_colors::RED), + emphasis_2: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_3: PaletteColor::EightBit(default_colors::MAGENTA), + emphasis_4: PaletteColor::EightBit(default_colors::BLUE), + background: PaletteColor::EightBit(default_colors::GREEN), + }, + exit_code_success: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::CYAN), + emphasis_2: PaletteColor::EightBit(default_colors::BLACK), + emphasis_3: PaletteColor::EightBit(default_colors::MAGENTA), + emphasis_4: PaletteColor::EightBit(default_colors::BLUE), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + exit_code_error: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::RED), + emphasis_1: PaletteColor::EightBit(default_colors::YELLOW), + emphasis_2: PaletteColor::EightBit(default_colors::GOLD), + emphasis_3: PaletteColor::EightBit(default_colors::SILVER), + emphasis_4: PaletteColor::EightBit(default_colors::PURPLE), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + frame_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_1: PaletteColor::EightBit(default_colors::PINK), + emphasis_2: PaletteColor::EightBit(default_colors::GRAY), + emphasis_3: PaletteColor::EightBit(default_colors::BROWN), + emphasis_4: PaletteColor::EightBit(default_colors::BLACK), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + frame_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::MAGENTA), + emphasis_4: PaletteColor::EightBit(default_colors::BROWN), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + frame_highlight: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::GREEN), + emphasis_2: PaletteColor::EightBit(default_colors::GREEN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::GREEN), + background: PaletteColor::EightBit(default_colors::GREEN), + }, + table_title: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + table_cell_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + table_cell_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::RED), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + list_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + list_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::RED), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + multiplayer_user_colors: MultiplayerColors { + player_1: PaletteColor::EightBit(default_colors::MAGENTA), + player_2: PaletteColor::EightBit(default_colors::BLUE), + player_3: PaletteColor::EightBit(default_colors::PURPLE), + player_4: PaletteColor::EightBit(default_colors::YELLOW), + player_5: PaletteColor::EightBit(default_colors::CYAN), + player_6: PaletteColor::EightBit(default_colors::GOLD), + player_7: PaletteColor::EightBit(default_colors::RED), + player_8: PaletteColor::EightBit(default_colors::SILVER), + player_9: PaletteColor::EightBit(default_colors::PINK), + player_10: PaletteColor::EightBit(default_colors::BROWN), + }, +}; + +impl Default for Styling { + fn default() -> Self { + DEFAULT_STYLES + } +} + +impl From for Palette { + fn from(styling: Styling) -> Self { + Palette { + theme_hue: ThemeHue::Dark, + source: PaletteSource::Default, + fg: styling.ribbon_unselected.background, + bg: styling.text_unselected.background, + red: styling.exit_code_error.base, + green: styling.text_unselected.emphasis_3, + yellow: styling.exit_code_error.emphasis_1, + blue: styling.ribbon_unselected.emphasis_3, + magenta: styling.text_unselected.emphasis_4, + orange: styling.text_unselected.emphasis_1, + cyan: styling.text_unselected.emphasis_2, + black: styling.ribbon_unselected.base, + white: styling.ribbon_unselected.emphasis_2, + gray: styling.list_unselected.background, + purple: styling.multiplayer_user_colors.player_3, + gold: styling.multiplayer_user_colors.player_6, + silver: styling.multiplayer_user_colors.player_8, + pink: styling.multiplayer_user_colors.player_9, + brown: styling.multiplayer_user_colors.player_10, + } + } +} + +impl From for Styling { + fn from(palette: Palette) -> Self { + let (fg, bg) = match palette.theme_hue { + ThemeHue::Light => (palette.black, palette.white), + ThemeHue::Dark => (palette.white, palette.black), + }; + Styling { + text_unselected: StyleDeclaration { + base: fg, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: bg, + }, + text_selected: StyleDeclaration { + base: fg, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: palette.bg, + }, + ribbon_unselected: StyleDeclaration { + base: palette.black, + emphasis_1: palette.red, + emphasis_2: palette.white, + emphasis_3: palette.blue, + emphasis_4: palette.magenta, + background: palette.fg, + }, + ribbon_selected: StyleDeclaration { + base: palette.black, + emphasis_1: palette.red, + emphasis_2: palette.orange, + emphasis_3: palette.magenta, + emphasis_4: palette.blue, + background: palette.green, + }, + exit_code_success: StyleDeclaration { + base: palette.green, + emphasis_1: palette.cyan, + emphasis_2: palette.black, + emphasis_3: palette.magenta, + emphasis_4: palette.blue, + background: Default::default(), + }, + exit_code_error: StyleDeclaration { + base: palette.red, + emphasis_1: palette.yellow, + emphasis_2: palette.gold, + emphasis_3: palette.silver, + emphasis_4: palette.purple, + background: Default::default(), + }, + frame_unselected: StyleDeclaration { + base: palette.orange, + emphasis_1: palette.pink, + emphasis_2: palette.gray, + emphasis_3: palette.brown, + emphasis_4: palette.black, + background: Default::default(), + }, + frame_selected: StyleDeclaration { + base: palette.green, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.magenta, + emphasis_4: palette.brown, + background: Default::default(), + }, + frame_highlight: StyleDeclaration { + base: palette.green, + emphasis_1: palette.green, + emphasis_2: palette.green, + emphasis_3: palette.green, + emphasis_4: palette.green, + background: Default::default(), + }, + table_title: StyleDeclaration { + base: palette.green, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.red, + emphasis_4: palette.magenta, + background: palette.gray, + }, + table_cell_unselected: StyleDeclaration { + base: palette.fg, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: palette.black, + }, + table_cell_selected: StyleDeclaration { + base: palette.green, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.red, + emphasis_4: palette.magenta, + background: palette.bg, + }, + list_unselected: StyleDeclaration { + base: palette.white, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: palette.bg, + }, + list_selected: StyleDeclaration { + base: palette.white, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: palette.bg, + }, + multiplayer_user_colors: MultiplayerColors { + player_1: palette.magenta, + player_2: palette.blue, + player_3: palette.purple, + player_4: palette.yellow, + player_5: palette.cyan, + player_6: palette.gold, + player_7: palette.red, + player_8: palette.silver, + player_9: palette.pink, + player_10: palette.brown, + }, + } + } +} + // FIXME: Poor devs hashtable since HashTable can't derive `Default`... pub type KeybindsVec = Vec<(InputMode, Vec<(KeyWithModifier, Vec)>)>; @@ -1170,8 +1509,8 @@ impl ModeInfo { pub fn update_default_mode(&mut self, new_default_mode: InputMode) { self.base_mode = Some(new_default_mode); } - pub fn update_theme(&mut self, theme: Palette) { - self.style.colors = theme; + pub fn update_theme(&mut self, theme: Styling) { + self.style.colors = theme.into(); } pub fn update_rounded_corners(&mut self, rounded_corners: bool) { self.style.rounded_corners = rounded_corners; diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs index 8075ea0da1..6a26ea5402 100644 --- a/zellij-utils/src/input/config.rs +++ b/zellij-utils/src/input/config.rs @@ -1,4 +1,4 @@ -use crate::data::Palette; +use crate::data::Styling; use miette::{Diagnostic, LabeledSpan, NamedSource, SourceCode}; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -166,7 +166,7 @@ impl TryFrom<&CliArgs> for Config { } impl Config { - pub fn theme_config(&self, theme_name: Option<&String>) -> Option { + pub fn theme_config(&self, theme_name: Option<&String>) -> Option { match &theme_name { Some(theme_name) => self.themes.get_theme(theme_name).map(|theme| theme.palette), None => self.themes.get_theme("default").map(|theme| theme.palette), @@ -407,8 +407,8 @@ impl Config { #[cfg(test)] mod config_test { use super::*; - use crate::data::{InputMode, Palette, PaletteColor}; - use crate::input::layout::RunPlugin; + use crate::data::{InputMode, Palette, PaletteColor, PluginTag, StyleDeclaration, Styling}; + use crate::input::layout::{RunPlugin, RunPluginLocation}; use crate::input::options::{Clipboard, OnForceClose}; use crate::input::theme::{FrameConfig, Theme, Themes, UiConfig}; use std::collections::{BTreeMap, HashMap}; @@ -630,7 +630,8 @@ mod config_test { black: PaletteColor::Rgb((0, 0, 0)), white: PaletteColor::Rgb((255, 255, 255)), ..Default::default() - }, + } + .into(), sourced_from_external_file: false, }, ); @@ -688,7 +689,8 @@ mod config_test { black: PaletteColor::Rgb((0, 0, 0)), white: PaletteColor::Rgb((255, 255, 255)), ..Default::default() - }, + } + .into(), sourced_from_external_file: false, }, ); @@ -708,7 +710,8 @@ mod config_test { white: PaletteColor::Rgb((229, 233, 240)), orange: PaletteColor::Rgb((208, 135, 112)), ..Default::default() - }, + } + .into(), sourced_from_external_file: false, }, ); @@ -753,7 +756,8 @@ mod config_test { black: PaletteColor::EightBit(1), white: PaletteColor::EightBit(255), ..Default::default() - }, + } + .into(), sourced_from_external_file: false, }, ); @@ -761,6 +765,304 @@ mod config_test { assert_eq!(config.themes, expected_themes, "Theme defined in config"); } + #[test] + fn can_define_style_for_theme_with_hex() { + let config_contents = r##" + themes { + named_theme { + text_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + text_selected { + base "#16161D" + emphasis_1 "#16161D" + emphasis_2 "#16161D" + emphasis_3 "#16161D" + emphasis_4 "#16161D" + background "#9CABCA" + } + ribbon_unselected { + base "#DCD7BA" + emphasis_1 "#7FB4CA" + emphasis_2 "#A3D4D5" + emphasis_3 "#7AA89F" + emphasis_4 "#DCD819" + background "#252535" + } + ribbon_selected { + base "#16161D" + emphasis_1 "#181820" + emphasis_2 "#1A1A22" + emphasis_3 "#2A2A37" + emphasis_4 "#363646" + background "#76946A" + } + table_title { + base "#DCD7BA" + emphasis_1 "#7FB4CA" + emphasis_2 "#A3D4D5" + emphasis_3 "#7AA89F" + emphasis_4 "#DCD819" + background "#252535" + } + table_cell_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + table_cell_selected { + base "#16161D" + emphasis_1 "#181820" + emphasis_2 "#1A1A22" + emphasis_3 "#2A2A37" + emphasis_4 "#363646" + background "#76946A" + } + list_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + list_selected { + base "#16161D" + emphasis_1 "#181820" + emphasis_2 "#1A1A22" + emphasis_3 "#2A2A37" + emphasis_4 "#363646" + background "#76946A" + } + frame_unselected { + base "#DCD8DD" + emphasis_1 "#7FB4CA" + emphasis_2 "#A3D4D5" + emphasis_3 "#7AA89F" + emphasis_4 "#DCD819" + } + frame_selected { + base "#76946A" + emphasis_1 "#C34043" + emphasis_2 "#C8C093" + emphasis_3 "#ACD7CD" + emphasis_4 "#DCD819" + } + exit_code_success { + base "#76946A" + emphasis_1 "#76946A" + emphasis_2 "#76946A" + emphasis_3 "#76946A" + emphasis_4 "#76946A" + } + exit_code_error { + base "#C34043" + emphasis_1 "#C34043" + emphasis_2 "#C34043" + emphasis_3 "#C34043" + emphasis_4 "#C34043" + } + } + } + "##; + + let config = Config::from_kdl(config_contents, None).unwrap(); + let mut expected_themes = HashMap::new(); + expected_themes.insert( + "named_theme".into(), + Theme { + sourced_from_external_file: false, + palette: Styling { + text_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + text_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((22, 22, 29)), + emphasis_2: PaletteColor::Rgb((22, 22, 29)), + emphasis_3: PaletteColor::Rgb((22, 22, 29)), + emphasis_4: PaletteColor::Rgb((22, 22, 29)), + background: PaletteColor::Rgb((156, 171, 202)), + }, + ribbon_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((127, 180, 202)), + emphasis_2: PaletteColor::Rgb((163, 212, 213)), + emphasis_3: PaletteColor::Rgb((122, 168, 159)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + background: PaletteColor::Rgb((37, 37, 53)), + }, + ribbon_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((24, 24, 32)), + emphasis_2: PaletteColor::Rgb((26, 26, 34)), + emphasis_3: PaletteColor::Rgb((42, 42, 55)), + emphasis_4: PaletteColor::Rgb((54, 54, 70)), + background: PaletteColor::Rgb((118, 148, 106)), + }, + table_title: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((127, 180, 202)), + emphasis_2: PaletteColor::Rgb((163, 212, 213)), + emphasis_3: PaletteColor::Rgb((122, 168, 159)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + background: PaletteColor::Rgb((37, 37, 53)), + }, + table_cell_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + table_cell_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((24, 24, 32)), + emphasis_2: PaletteColor::Rgb((26, 26, 34)), + emphasis_3: PaletteColor::Rgb((42, 42, 55)), + emphasis_4: PaletteColor::Rgb((54, 54, 70)), + background: PaletteColor::Rgb((118, 148, 106)), + }, + list_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + list_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((24, 24, 32)), + emphasis_2: PaletteColor::Rgb((26, 26, 34)), + emphasis_3: PaletteColor::Rgb((42, 42, 55)), + emphasis_4: PaletteColor::Rgb((54, 54, 70)), + background: PaletteColor::Rgb((118, 148, 106)), + }, + frame_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 216, 221)), + emphasis_1: PaletteColor::Rgb((127, 180, 202)), + emphasis_2: PaletteColor::Rgb((163, 212, 213)), + emphasis_3: PaletteColor::Rgb((122, 168, 159)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + ..Default::default() + }, + frame_selected: StyleDeclaration { + base: PaletteColor::Rgb((118, 148, 106)), + emphasis_1: PaletteColor::Rgb((195, 64, 67)), + emphasis_2: PaletteColor::Rgb((200, 192, 147)), + emphasis_3: PaletteColor::Rgb((172, 215, 205)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + ..Default::default() + }, + exit_code_success: StyleDeclaration { + base: PaletteColor::Rgb((118, 148, 106)), + emphasis_1: PaletteColor::Rgb((118, 148, 106)), + emphasis_2: PaletteColor::Rgb((118, 148, 106)), + emphasis_3: PaletteColor::Rgb((118, 148, 106)), + emphasis_4: PaletteColor::Rgb((118, 148, 106)), + ..Default::default() + }, + exit_code_error: StyleDeclaration { + base: PaletteColor::Rgb((195, 64, 67)), + emphasis_1: PaletteColor::Rgb((195, 64, 67)), + emphasis_2: PaletteColor::Rgb((195, 64, 67)), + emphasis_3: PaletteColor::Rgb((195, 64, 67)), + emphasis_4: PaletteColor::Rgb((195, 64, 67)), + ..Default::default() + }, + ..Default::default() + }, + }, + ); + let expected_themes = Themes::from_data(expected_themes); + assert_eq!(config.themes, expected_themes, "Theme defined in config") + } + + #[test] + fn omitting_required_style_errors() { + let config_contents = r##" + themes { + named_theme { + text_unselected { + base "#DCD7BA" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + } + } + "##; + + let config = Config::from_kdl(config_contents, None); + assert!(config.is_err()); + if let Err(ConfigError::KdlError(KdlError { + error_message, + src: _, + offset: _, + len: _, + help_message: _, + })) = config + { + assert_eq!(error_message, "Missing theme color: emphasis_1") + } + } + + #[test] + fn partial_declaration_of_styles_defaults_omitted() { + let config_contents = r##" + themes { + named_theme { + text_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + } + } + "##; + + let config = Config::from_kdl(config_contents, None).unwrap(); + let mut expected_themes = HashMap::new(); + expected_themes.insert( + "named_theme".into(), + Theme { + sourced_from_external_file: false, + palette: Styling { + text_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + ..Default::default() + }, + }, + ); + let expected_themes = Themes::from_data(expected_themes); + assert_eq!(config.themes, expected_themes, "Theme defined in config") + } + #[test] fn can_define_plugin_configuration_in_configfile() { let config_contents = r#" diff --git a/zellij-utils/src/input/theme.rs b/zellij-utils/src/input/theme.rs index a7f212f0d7..b4fbc630e1 100644 --- a/zellij-utils/src/input/theme.rs +++ b/zellij-utils/src/input/theme.rs @@ -7,7 +7,7 @@ use std::{ fmt, }; -use crate::data::Palette; +use crate::data::Styling; #[derive(Debug, Default, Clone, Copy, PartialEq, Deserialize, Serialize)] pub struct UiConfig { @@ -74,9 +74,9 @@ impl Themes { #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub struct Theme { - #[serde(flatten)] - pub palette: Palette, pub sourced_from_external_file: bool, + #[serde(flatten)] + pub palette: Styling, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap index 957ddf0469..fce85af14b 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap @@ -1,109 +1,627 @@ --- source: zellij-utils/src/input/./unit/theme_test.rs -assertion_line: 15 expression: "format!(\"{:#?}\", theme)" --- { "dracula": Theme { - palette: Palette { - source: Default, - theme_hue: Dark, - fg: Rgb( - ( - 248, - 248, - 242, - ), - ), - bg: Rgb( - ( - 40, - 42, - 54, - ), - ), - black: Rgb( - ( - 0, - 0, - 0, - ), - ), - red: Rgb( - ( - 255, - 85, - 85, - ), - ), - green: Rgb( - ( - 80, - 250, - 123, - ), - ), - yellow: Rgb( - ( - 241, - 250, - 140, - ), - ), - blue: Rgb( - ( - 98, - 114, - 164, - ), - ), - magenta: Rgb( - ( - 255, - 121, - 198, - ), - ), - cyan: Rgb( - ( - 139, - 233, - 253, - ), - ), - white: Rgb( - ( - 255, - 255, - 255, - ), - ), - orange: Rgb( - ( - 255, - 184, - 108, - ), - ), - gray: EightBit( - 0, - ), - purple: EightBit( - 0, - ), - gold: EightBit( - 0, - ), - silver: EightBit( - 0, - ), - pink: EightBit( - 0, - ), - brown: EightBit( - 0, - ), - }, sourced_from_external_file: true, + palette: Styling { + text_unselected: StyleDeclaration { + base: Rgb( + ( + 255, + 255, + 255, + ), + ), + background: Rgb( + ( + 0, + 0, + 0, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + text_selected: StyleDeclaration { + base: Rgb( + ( + 255, + 255, + 255, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + ribbon_unselected: StyleDeclaration { + base: Rgb( + ( + 0, + 0, + 0, + ), + ), + background: Rgb( + ( + 248, + 248, + 242, + ), + ), + emphasis_1: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_2: Rgb( + ( + 255, + 255, + 255, + ), + ), + emphasis_3: Rgb( + ( + 98, + 114, + 164, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + ribbon_selected: StyleDeclaration { + base: Rgb( + ( + 0, + 0, + 0, + ), + ), + background: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_1: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_2: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_3: Rgb( + ( + 255, + 121, + 198, + ), + ), + emphasis_4: Rgb( + ( + 98, + 114, + 164, + ), + ), + }, + table_title: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + table_cell_unselected: StyleDeclaration { + base: Rgb( + ( + 248, + 248, + 242, + ), + ), + background: Rgb( + ( + 0, + 0, + 0, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + table_cell_selected: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + list_unselected: StyleDeclaration { + base: Rgb( + ( + 248, + 248, + 242, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + list_selected: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + frame_unselected: StyleDeclaration { + base: Rgb( + ( + 255, + 184, + 108, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: EightBit( + 0, + ), + emphasis_2: EightBit( + 0, + ), + emphasis_3: EightBit( + 0, + ), + emphasis_4: Rgb( + ( + 0, + 0, + 0, + ), + ), + }, + frame_selected: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 121, + 198, + ), + ), + emphasis_4: EightBit( + 0, + ), + }, + frame_highlight: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_2: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 80, + 250, + 123, + ), + ), + }, + exit_code_success: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_2: Rgb( + ( + 0, + 0, + 0, + ), + ), + emphasis_3: Rgb( + ( + 255, + 121, + 198, + ), + ), + emphasis_4: Rgb( + ( + 98, + 114, + 164, + ), + ), + }, + exit_code_error: StyleDeclaration { + base: Rgb( + ( + 255, + 85, + 85, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 241, + 250, + 140, + ), + ), + emphasis_2: EightBit( + 0, + ), + emphasis_3: EightBit( + 0, + ), + emphasis_4: EightBit( + 0, + ), + }, + multiplayer_user_colors: MultiplayerColors { + player_1: Rgb( + ( + 255, + 121, + 198, + ), + ), + player_2: Rgb( + ( + 98, + 114, + 164, + ), + ), + player_3: EightBit( + 0, + ), + player_4: Rgb( + ( + 241, + 250, + 140, + ), + ), + player_5: Rgb( + ( + 139, + 233, + 253, + ), + ), + player_6: EightBit( + 0, + ), + player_7: Rgb( + ( + 255, + 85, + 85, + ), + ), + player_8: EightBit( + 0, + ), + player_9: EightBit( + 0, + ), + player_10: EightBit( + 0, + ), + }, + }, }, } diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs index 37f36fd8a5..9861451ff5 100644 --- a/zellij-utils/src/kdl/mod.rs +++ b/zellij-utils/src/kdl/mod.rs @@ -1,7 +1,8 @@ mod kdl_layout_parser; use crate::data::{ - BareKey, Direction, FloatingPaneCoordinates, InputMode, KeyWithModifier, LayoutInfo, Palette, - PaletteColor, PaneInfo, PaneManifest, PermissionType, Resize, SessionInfo, TabInfo, + BareKey, Direction, FloatingPaneCoordinates, InputMode, KeyWithModifier, LayoutInfo, + MultiplayerColors, Palette, PaletteColor, PaneInfo, PaneManifest, PermissionType, Resize, + SessionInfo, StyleDeclaration, Styling, TabInfo, DEFAULT_STYLES, }; use crate::envs::EnvironmentVariables; use crate::home::{find_default_config_dir, get_layout_dir}; @@ -1241,6 +1242,41 @@ impl PaletteColor { } } +impl StyleDeclaration { + pub fn to_kdl(&self, declaration_name: &str) -> KdlNode { + let mut node = KdlNode::new(declaration_name); + let mut doc = KdlDocument::new(); + + doc.nodes_mut().push(self.base.to_kdl("base")); + doc.nodes_mut().push(self.background.to_kdl("background")); + doc.nodes_mut().push(self.emphasis_1.to_kdl("emphasis_1")); + doc.nodes_mut().push(self.emphasis_2.to_kdl("emphasis_2")); + doc.nodes_mut().push(self.emphasis_3.to_kdl("emphasis_3")); + doc.nodes_mut().push(self.emphasis_4.to_kdl("emphasis_4")); + node.set_children(doc); + node + } +} + +impl MultiplayerColors { + pub fn to_kdl(&self) -> KdlNode { + let mut node = KdlNode::new("multiplayer_user_colors"); + let mut doc = KdlDocument::new(); + doc.nodes_mut().push(self.player_1.to_kdl("player_1")); + doc.nodes_mut().push(self.player_2.to_kdl("player_2")); + doc.nodes_mut().push(self.player_3.to_kdl("player_3")); + doc.nodes_mut().push(self.player_4.to_kdl("player_4")); + doc.nodes_mut().push(self.player_5.to_kdl("player_5")); + doc.nodes_mut().push(self.player_6.to_kdl("player_6")); + doc.nodes_mut().push(self.player_7.to_kdl("player_7")); + doc.nodes_mut().push(self.player_8.to_kdl("player_8")); + doc.nodes_mut().push(self.player_9.to_kdl("player_9")); + doc.nodes_mut().push(self.player_10.to_kdl("player_10")); + node.set_children(doc); + node + } +} + impl TryFrom<(&KdlNode, &Options)> for Action { type Error = ConfigError; fn try_from((kdl_action, config_options): (&KdlNode, &Options)) -> Result { @@ -2051,6 +2087,20 @@ macro_rules! kdl_child_with_name { }}; } +#[macro_export] +macro_rules! kdl_child_with_name_or_error { + ( $kdl_node:expr, $name:expr) => {{ + $kdl_node + .children() + .and_then(|children| children.nodes().iter().find(|c| c.name().value() == $name)) + .ok_or(ConfigError::new_kdl_error( + format!("Missing node {}", $name).into(), + $kdl_node.span().offset(), + $kdl_node.span().len(), + )) + }}; +} + #[macro_export] macro_rules! kdl_get_string_property_or_child_value_with_error { ( $kdl_node:expr, $name:expr ) => { @@ -3896,6 +3946,67 @@ impl UiConfig { } impl Themes { + fn style_declaration_from_node( + style_node: &KdlNode, + style_descriptor: &str, + default: StyleDeclaration, + ) -> Result { + let descriptor_node = kdl_child_with_name!(style_node, style_descriptor); + + match descriptor_node { + Some(descriptor) => { + let colors = kdl_children_or_error!( + descriptor, + format!("Missing colors for {}", style_descriptor) + ); + Ok(StyleDeclaration { + base: PaletteColor::try_from(("base", colors))?, + background: PaletteColor::try_from(("background", colors)).unwrap_or_default(), + emphasis_1: PaletteColor::try_from(("emphasis_1", colors))?, + emphasis_2: PaletteColor::try_from(("emphasis_2", colors))?, + emphasis_3: PaletteColor::try_from(("emphasis_3", colors))?, + emphasis_4: PaletteColor::try_from(("emphasis_4", colors))?, + }) + }, + None => Ok(default), + } + } + + fn multiplayer_colors(style_node: &KdlNode) -> Result { + let descriptor_node = kdl_child_with_name!(style_node, "multiplayer_user_colors"); + match descriptor_node { + Some(descriptor) => { + let colors = kdl_children_or_error!( + descriptor, + format!("Missing colors for {}", "multiplayer_user_colors") + ); + Ok(MultiplayerColors { + player_1: PaletteColor::try_from(("player_1", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_1), + player_2: PaletteColor::try_from(("player_2", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_2), + player_3: PaletteColor::try_from(("player_3", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_3), + player_4: PaletteColor::try_from(("player_4", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_4), + player_5: PaletteColor::try_from(("player_5", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_5), + player_6: PaletteColor::try_from(("player_6", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_6), + player_7: PaletteColor::try_from(("player_7", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_7), + player_8: PaletteColor::try_from(("player_8", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_8), + player_9: PaletteColor::try_from(("player_9", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_9), + player_10: PaletteColor::try_from(("player_10", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_10), + }) + }, + None => Ok(DEFAULT_STYLES.multiplayer_user_colors), + } + } + pub fn from_kdl( themes_from_kdl: &KdlNode, sourced_from_external_file: bool, @@ -3904,8 +4015,17 @@ impl Themes { for theme_config in kdl_children_nodes_or_error!(themes_from_kdl, "no themes found") { let theme_name = kdl_name!(theme_config); let theme_colors = kdl_children_or_error!(theme_config, "empty theme"); - let theme = Theme { - palette: Palette { + let palette_color_names = HashSet::from([ + "fg", "bg", "red", "green", "blue", "yellow", "magenta", "orange", "cyan", "black", + "white", + ]); + let theme = if theme_colors + .nodes() + .iter() + .all(|n| palette_color_names.contains(n.name().value())) + { + // Older palette based theme definition + let palette = Palette { fg: PaletteColor::try_from(("fg", theme_colors))?, bg: PaletteColor::try_from(("bg", theme_colors))?, red: PaletteColor::try_from(("red", theme_colors))?, @@ -3918,8 +4038,92 @@ impl Themes { black: PaletteColor::try_from(("black", theme_colors))?, white: PaletteColor::try_from(("white", theme_colors))?, ..Default::default() - }, - sourced_from_external_file, + }; + Theme { + palette: palette.into(), + sourced_from_external_file, + } + } else { + // Newer theme definition with named styles + let s = Styling { + text_unselected: Themes::style_declaration_from_node( + theme_config, + "text_unselected", + DEFAULT_STYLES.text_unselected, + )?, + text_selected: Themes::style_declaration_from_node( + theme_config, + "text_selected", + DEFAULT_STYLES.text_selected, + )?, + ribbon_unselected: Themes::style_declaration_from_node( + theme_config, + "ribbon_unselected", + DEFAULT_STYLES.ribbon_unselected, + )?, + ribbon_selected: Themes::style_declaration_from_node( + theme_config, + "ribbon_selected", + DEFAULT_STYLES.ribbon_selected, + )?, + table_title: Themes::style_declaration_from_node( + theme_config, + "table_title", + DEFAULT_STYLES.table_title, + )?, + table_cell_unselected: Themes::style_declaration_from_node( + theme_config, + "table_cell_unselected", + DEFAULT_STYLES.table_cell_unselected, + )?, + table_cell_selected: Themes::style_declaration_from_node( + theme_config, + "table_cell_selected", + DEFAULT_STYLES.table_cell_selected, + )?, + list_unselected: Themes::style_declaration_from_node( + theme_config, + "list_unselected", + DEFAULT_STYLES.list_unselected, + )?, + list_selected: Themes::style_declaration_from_node( + theme_config, + "list_selected", + DEFAULT_STYLES.list_selected, + )?, + frame_unselected: Themes::style_declaration_from_node( + theme_config, + "frame_unselected", + DEFAULT_STYLES.frame_unselected, + )?, + frame_selected: Themes::style_declaration_from_node( + theme_config, + "frame_selected", + DEFAULT_STYLES.frame_selected, + )?, + frame_highlight: Themes::style_declaration_from_node( + theme_config, + "frame_highlight", + DEFAULT_STYLES.frame_highlight, + )?, + exit_code_success: Themes::style_declaration_from_node( + theme_config, + "exit_code_success", + DEFAULT_STYLES.exit_code_success, + )?, + exit_code_error: Themes::style_declaration_from_node( + theme_config, + "exit_code_error", + DEFAULT_STYLES.exit_code_error, + )?, + multiplayer_user_colors: Themes::multiplayer_colors(theme_config) + .unwrap_or_default(), + }; + + Theme { + palette: s, + sourced_from_external_file, + } }; themes.insert(theme_name.into(), theme); } @@ -3985,37 +4189,55 @@ impl Themes { let mut current_theme_node_children = KdlDocument::new(); current_theme_node_children .nodes_mut() - .push(theme.palette.fg.to_kdl("fg")); + .push(theme.palette.text_unselected.to_kdl("text_unselected")); current_theme_node_children .nodes_mut() - .push(theme.palette.bg.to_kdl("bg")); + .push(theme.palette.text_selected.to_kdl("text_selected")); current_theme_node_children .nodes_mut() - .push(theme.palette.red.to_kdl("red")); + .push(theme.palette.ribbon_selected.to_kdl("ribbon_selected")); current_theme_node_children .nodes_mut() - .push(theme.palette.green.to_kdl("green")); + .push(theme.palette.ribbon_unselected.to_kdl("ribbon_unselected")); current_theme_node_children .nodes_mut() - .push(theme.palette.yellow.to_kdl("yellow")); + .push(theme.palette.table_title.to_kdl("table_title")); + current_theme_node_children.nodes_mut().push( + theme + .palette + .table_cell_selected + .to_kdl("table_cell_selected"), + ); + current_theme_node_children.nodes_mut().push( + theme + .palette + .table_cell_unselected + .to_kdl("table_cell_unselected"), + ); current_theme_node_children .nodes_mut() - .push(theme.palette.blue.to_kdl("blue")); + .push(theme.palette.list_selected.to_kdl("list_selected")); current_theme_node_children .nodes_mut() - .push(theme.palette.magenta.to_kdl("magenta")); + .push(theme.palette.list_unselected.to_kdl("list_unselected")); current_theme_node_children .nodes_mut() - .push(theme.palette.orange.to_kdl("orange")); + .push(theme.palette.frame_selected.to_kdl("frame_selected")); current_theme_node_children .nodes_mut() - .push(theme.palette.cyan.to_kdl("cyan")); + .push(theme.palette.frame_unselected.to_kdl("frame_unselected")); current_theme_node_children .nodes_mut() - .push(theme.palette.black.to_kdl("black")); + .push(theme.palette.frame_highlight.to_kdl("frame_highlight")); current_theme_node_children .nodes_mut() - .push(theme.palette.white.to_kdl("white")); + .push(theme.palette.exit_code_success.to_kdl("exit_code_success")); + current_theme_node_children + .nodes_mut() + .push(theme.palette.exit_code_error.to_kdl("exit_code_error")); + current_theme_node_children + .nodes_mut() + .push(theme.palette.multiplayer_user_colors.to_kdl()); current_theme_node.set_children(current_theme_node_children); themes.nodes_mut().push(current_theme_node); } @@ -5093,7 +5315,7 @@ fn themes_to_string() { .unwrap(); assert_eq!( deserialized, deserialized_from_serialized, - "Deserialized serialized config equals original config" + "Deserialized serialized config equals original config", ); insta::assert_snapshot!(serialized.to_string()); } diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string.snap index 7bbc19cd15..50cbbe4512 100644 --- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string.snap +++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string.snap @@ -1,20 +1,132 @@ --- source: zellij-utils/src/kdl/mod.rs -assertion_line: 3697 expression: serialized.to_string() --- themes { dracula { - fg 248 248 242 - bg 40 42 54 - red 255 85 85 - green 80 250 123 - yellow 241 250 140 - blue 98 114 164 - magenta 255 121 198 - orange 255 184 108 - cyan 139 233 253 - black 0 0 0 - white 255 255 255 + text_unselected { + base 255 255 255 + background 0 0 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + text_selected { + base 255 255 255 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + ribbon_selected { + base 0 0 0 + background 80 250 123 + emphasis_1 255 85 85 + emphasis_2 255 184 108 + emphasis_3 255 121 198 + emphasis_4 98 114 164 + } + ribbon_unselected { + base 0 0 0 + background 248 248 242 + emphasis_1 255 85 85 + emphasis_2 255 255 255 + emphasis_3 98 114 164 + emphasis_4 255 121 198 + } + table_title { + base 80 250 123 + background 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 85 85 + emphasis_4 255 121 198 + } + table_cell_selected { + base 80 250 123 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 85 85 + emphasis_4 255 121 198 + } + table_cell_unselected { + base 248 248 242 + background 0 0 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + list_selected { + base 80 250 123 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 85 85 + emphasis_4 255 121 198 + } + list_unselected { + base 248 248 242 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + frame_selected { + base 80 250 123 + background 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 121 198 + emphasis_4 0 + } + frame_unselected { + base 255 184 108 + background 0 + emphasis_1 0 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 0 0 + } + frame_highlight { + base 80 250 123 + background 0 + emphasis_1 80 250 123 + emphasis_2 80 250 123 + emphasis_3 80 250 123 + emphasis_4 80 250 123 + } + exit_code_success { + base 80 250 123 + background 0 + emphasis_1 139 233 253 + emphasis_2 0 0 0 + emphasis_3 255 121 198 + emphasis_4 98 114 164 + } + exit_code_error { + base 255 85 85 + background 0 + emphasis_1 241 250 140 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 + } + multiplayer_user_colors { + player_1 255 121 198 + player_2 98 114 164 + player_3 0 + player_4 241 250 140 + player_5 139 233 253 + player_6 0 + player_7 255 85 85 + player_8 0 + player_9 0 + player_10 0 + } } } diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_combined_definitions.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_combined_definitions.snap index 3498af78e3..5a7a809f6e 100644 --- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_combined_definitions.snap +++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_combined_definitions.snap @@ -1,20 +1,132 @@ --- source: zellij-utils/src/kdl/mod.rs -assertion_line: 3775 expression: serialized.to_string() --- themes { default { - fg 1 - bg 10 - red 30 - green 40 - yellow 50 - blue 60 - magenta 70 - orange 208 135 112 - cyan 80 - black 20 - white 255 255 255 + text_unselected { + base 255 255 255 + background 20 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + text_selected { + base 255 255 255 + background 10 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + ribbon_selected { + base 20 + background 40 + emphasis_1 30 + emphasis_2 208 135 112 + emphasis_3 70 + emphasis_4 60 + } + ribbon_unselected { + base 20 + background 1 + emphasis_1 30 + emphasis_2 255 255 255 + emphasis_3 60 + emphasis_4 70 + } + table_title { + base 40 + background 0 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 30 + emphasis_4 70 + } + table_cell_selected { + base 40 + background 10 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 30 + emphasis_4 70 + } + table_cell_unselected { + base 1 + background 20 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + list_selected { + base 40 + background 10 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 30 + emphasis_4 70 + } + list_unselected { + base 1 + background 10 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + frame_selected { + base 40 + background 0 + emphasis_1 208 135 112 + emphasis_2 80 + emphasis_3 70 + emphasis_4 0 + } + frame_unselected { + base 208 135 112 + background 0 + emphasis_1 0 + emphasis_2 0 + emphasis_3 0 + emphasis_4 20 + } + frame_highlight { + base 40 + background 0 + emphasis_1 40 + emphasis_2 40 + emphasis_3 40 + emphasis_4 40 + } + exit_code_success { + base 40 + background 0 + emphasis_1 80 + emphasis_2 20 + emphasis_3 70 + emphasis_4 60 + } + exit_code_error { + base 30 + background 0 + emphasis_1 50 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 + } + multiplayer_user_colors { + player_1 70 + player_2 60 + player_3 0 + player_4 50 + player_5 80 + player_6 0 + player_7 30 + player_8 0 + player_9 0 + player_10 0 + } } } diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_eight_bit_definitions.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_eight_bit_definitions.snap index 5406cbb8cc..319ea61722 100644 --- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_eight_bit_definitions.snap +++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_eight_bit_definitions.snap @@ -1,20 +1,132 @@ --- source: zellij-utils/src/kdl/mod.rs -assertion_line: 3749 expression: serialized.to_string() --- themes { default { - fg 1 - bg 10 - red 30 - green 40 - yellow 50 - blue 60 - magenta 70 - orange 254 - cyan 80 - black 20 - white 90 + text_unselected { + base 90 + background 20 + emphasis_1 254 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + text_selected { + base 90 + background 10 + emphasis_1 254 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + ribbon_selected { + base 20 + background 40 + emphasis_1 30 + emphasis_2 254 + emphasis_3 70 + emphasis_4 60 + } + ribbon_unselected { + base 20 + background 1 + emphasis_1 30 + emphasis_2 90 + emphasis_3 60 + emphasis_4 70 + } + table_title { + base 40 + background 0 + emphasis_1 254 + emphasis_2 80 + emphasis_3 30 + emphasis_4 70 + } + table_cell_selected { + base 40 + background 10 + emphasis_1 254 + emphasis_2 80 + emphasis_3 30 + emphasis_4 70 + } + table_cell_unselected { + base 1 + background 20 + emphasis_1 254 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + list_selected { + base 40 + background 10 + emphasis_1 254 + emphasis_2 80 + emphasis_3 30 + emphasis_4 70 + } + list_unselected { + base 1 + background 10 + emphasis_1 254 + emphasis_2 80 + emphasis_3 40 + emphasis_4 70 + } + frame_selected { + base 40 + background 0 + emphasis_1 254 + emphasis_2 80 + emphasis_3 70 + emphasis_4 0 + } + frame_unselected { + base 254 + background 0 + emphasis_1 0 + emphasis_2 0 + emphasis_3 0 + emphasis_4 20 + } + frame_highlight { + base 40 + background 0 + emphasis_1 40 + emphasis_2 40 + emphasis_3 40 + emphasis_4 40 + } + exit_code_success { + base 40 + background 0 + emphasis_1 80 + emphasis_2 20 + emphasis_3 70 + emphasis_4 60 + } + exit_code_error { + base 30 + background 0 + emphasis_1 50 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 + } + multiplayer_user_colors { + player_1 70 + player_2 60 + player_3 0 + player_4 50 + player_5 80 + player_6 0 + player_7 30 + player_8 0 + player_9 0 + player_10 0 + } } } diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_hex_definitions.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_hex_definitions.snap index 3cbf559a25..04d39257b7 100644 --- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_hex_definitions.snap +++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_hex_definitions.snap @@ -1,20 +1,132 @@ --- source: zellij-utils/src/kdl/mod.rs -assertion_line: 3723 expression: serialized.to_string() --- themes { nord { - fg 216 222 233 - bg 46 52 64 - red 191 97 106 - green 163 190 140 - yellow 235 203 139 - blue 129 161 193 - magenta 180 142 173 - orange 208 135 112 - cyan 136 192 208 - black 59 66 82 - white 229 233 240 + text_unselected { + base 229 233 240 + background 59 66 82 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + text_selected { + base 229 233 240 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + ribbon_selected { + base 59 66 82 + background 163 190 140 + emphasis_1 191 97 106 + emphasis_2 208 135 112 + emphasis_3 180 142 173 + emphasis_4 129 161 193 + } + ribbon_unselected { + base 59 66 82 + background 216 222 233 + emphasis_1 191 97 106 + emphasis_2 229 233 240 + emphasis_3 129 161 193 + emphasis_4 180 142 173 + } + table_title { + base 163 190 140 + background 0 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 191 97 106 + emphasis_4 180 142 173 + } + table_cell_selected { + base 163 190 140 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 191 97 106 + emphasis_4 180 142 173 + } + table_cell_unselected { + base 216 222 233 + background 59 66 82 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + list_selected { + base 163 190 140 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 191 97 106 + emphasis_4 180 142 173 + } + list_unselected { + base 216 222 233 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + frame_selected { + base 163 190 140 + background 0 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 180 142 173 + emphasis_4 0 + } + frame_unselected { + base 208 135 112 + background 0 + emphasis_1 0 + emphasis_2 0 + emphasis_3 0 + emphasis_4 59 66 82 + } + frame_highlight { + base 163 190 140 + background 0 + emphasis_1 163 190 140 + emphasis_2 163 190 140 + emphasis_3 163 190 140 + emphasis_4 163 190 140 + } + exit_code_success { + base 163 190 140 + background 0 + emphasis_1 136 192 208 + emphasis_2 59 66 82 + emphasis_3 180 142 173 + emphasis_4 129 161 193 + } + exit_code_error { + base 191 97 106 + background 0 + emphasis_1 235 203 139 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 + } + multiplayer_user_colors { + player_1 180 142 173 + player_2 129 161 193 + player_3 0 + player_4 235 203 139 + player_5 136 192 208 + player_6 0 + player_7 191 97 106 + player_8 0 + player_9 0 + player_10 0 + } } } diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_multiple_theme_definitions.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_multiple_theme_definitions.snap index f8d7d38b4a..0eead928f9 100644 --- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_multiple_theme_definitions.snap +++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__themes_to_string_with_multiple_theme_definitions.snap @@ -1,33 +1,258 @@ --- source: zellij-utils/src/kdl/mod.rs -assertion_line: 4821 expression: serialized.to_string() --- themes { dracula { - fg 248 248 242 - bg 40 42 54 - red 255 85 85 - green 80 250 123 - yellow 241 250 140 - blue 98 114 164 - magenta 255 121 198 - orange 255 184 108 - cyan 139 233 253 - black 0 0 0 - white 255 255 255 + text_unselected { + base 255 255 255 + background 0 0 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + text_selected { + base 255 255 255 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + ribbon_selected { + base 0 0 0 + background 80 250 123 + emphasis_1 255 85 85 + emphasis_2 255 184 108 + emphasis_3 255 121 198 + emphasis_4 98 114 164 + } + ribbon_unselected { + base 0 0 0 + background 248 248 242 + emphasis_1 255 85 85 + emphasis_2 255 255 255 + emphasis_3 98 114 164 + emphasis_4 255 121 198 + } + table_title { + base 80 250 123 + background 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 85 85 + emphasis_4 255 121 198 + } + table_cell_selected { + base 80 250 123 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 85 85 + emphasis_4 255 121 198 + } + table_cell_unselected { + base 248 248 242 + background 0 0 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + list_selected { + base 80 250 123 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 85 85 + emphasis_4 255 121 198 + } + list_unselected { + base 248 248 242 + background 40 42 54 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 80 250 123 + emphasis_4 255 121 198 + } + frame_selected { + base 80 250 123 + background 0 + emphasis_1 255 184 108 + emphasis_2 139 233 253 + emphasis_3 255 121 198 + emphasis_4 0 + } + frame_unselected { + base 255 184 108 + background 0 + emphasis_1 0 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 0 0 + } + frame_highlight { + base 80 250 123 + background 0 + emphasis_1 80 250 123 + emphasis_2 80 250 123 + emphasis_3 80 250 123 + emphasis_4 80 250 123 + } + exit_code_success { + base 80 250 123 + background 0 + emphasis_1 139 233 253 + emphasis_2 0 0 0 + emphasis_3 255 121 198 + emphasis_4 98 114 164 + } + exit_code_error { + base 255 85 85 + background 0 + emphasis_1 241 250 140 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 + } + multiplayer_user_colors { + player_1 255 121 198 + player_2 98 114 164 + player_3 0 + player_4 241 250 140 + player_5 139 233 253 + player_6 0 + player_7 255 85 85 + player_8 0 + player_9 0 + player_10 0 + } } nord { - fg 216 222 233 - bg 46 52 64 - red 191 97 106 - green 163 190 140 - yellow 235 203 139 - blue 129 161 193 - magenta 180 142 173 - orange 208 135 112 - cyan 136 192 208 - black 59 66 82 - white 229 233 240 + text_unselected { + base 229 233 240 + background 59 66 82 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + text_selected { + base 229 233 240 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + ribbon_selected { + base 59 66 82 + background 163 190 140 + emphasis_1 191 97 106 + emphasis_2 208 135 112 + emphasis_3 180 142 173 + emphasis_4 129 161 193 + } + ribbon_unselected { + base 59 66 82 + background 216 222 233 + emphasis_1 191 97 106 + emphasis_2 229 233 240 + emphasis_3 129 161 193 + emphasis_4 180 142 173 + } + table_title { + base 163 190 140 + background 0 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 191 97 106 + emphasis_4 180 142 173 + } + table_cell_selected { + base 163 190 140 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 191 97 106 + emphasis_4 180 142 173 + } + table_cell_unselected { + base 216 222 233 + background 59 66 82 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + list_selected { + base 163 190 140 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 191 97 106 + emphasis_4 180 142 173 + } + list_unselected { + base 216 222 233 + background 46 52 64 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 163 190 140 + emphasis_4 180 142 173 + } + frame_selected { + base 163 190 140 + background 0 + emphasis_1 208 135 112 + emphasis_2 136 192 208 + emphasis_3 180 142 173 + emphasis_4 0 + } + frame_unselected { + base 208 135 112 + background 0 + emphasis_1 0 + emphasis_2 0 + emphasis_3 0 + emphasis_4 59 66 82 + } + frame_highlight { + base 163 190 140 + background 0 + emphasis_1 163 190 140 + emphasis_2 163 190 140 + emphasis_3 163 190 140 + emphasis_4 163 190 140 + } + exit_code_success { + base 163 190 140 + background 0 + emphasis_1 136 192 208 + emphasis_2 59 66 82 + emphasis_3 180 142 173 + emphasis_4 129 161 193 + } + exit_code_error { + base 191 97 106 + background 0 + emphasis_1 235 203 139 + emphasis_2 0 + emphasis_3 0 + emphasis_4 0 + } + multiplayer_user_colors { + player_1 180 142 173 + player_2 129 161 193 + player_3 0 + player_4 235 203 139 + player_5 136 192 208 + player_6 0 + player_7 191 97 106 + player_8 0 + player_9 0 + player_10 0 + } } } diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs index b1ab0e8e24..b5561ea4d5 100644 --- a/zellij-utils/src/plugin_api/event.rs +++ b/zellij-utils/src/plugin_api/event.rs @@ -1426,7 +1426,9 @@ fn serialize_mode_update_event_with_non_default_values() { silver: PaletteColor::EightBit(2), pink: PaletteColor::EightBit(2), brown: PaletteColor::Rgb((222, 221, 220)), - }, + } + .into(), + // TODO: replace default rounded_corners: true, hide_session_name: false, }, diff --git a/zellij-utils/src/plugin_api/style.proto b/zellij-utils/src/plugin_api/style.proto index f4f3b75889..cfea362e52 100644 --- a/zellij-utils/src/plugin_api/style.proto +++ b/zellij-utils/src/plugin_api/style.proto @@ -3,9 +3,10 @@ syntax = "proto3"; package api.style; message Style { - Palette palette = 1; + Palette palette = 1 [deprecated = true]; bool rounded_corners = 2; bool hide_session_name = 3; + Styling styling = 4; } message Palette { @@ -52,3 +53,21 @@ enum ThemeHue { Dark = 0; Light = 1; } + +message Styling { + repeated Color text_unselected = 1; + repeated Color text_selected = 2; + repeated Color ribbon_unselected = 3; + repeated Color ribbon_selected =4; + repeated Color table_title = 5; + repeated Color table_cell_unselected = 6; + repeated Color table_cell_selected = 7; + repeated Color list_unselected = 8; + repeated Color list_selected = 9; + repeated Color frame_unselected = 10; + repeated Color frame_selected = 11; + repeated Color frame_highlight = 12; + repeated Color exit_code_success = 13; + repeated Color exit_code_error = 14; + repeated Color multiplayer_user_colors = 15; +} diff --git a/zellij-utils/src/plugin_api/style.rs b/zellij-utils/src/plugin_api/style.rs index 1e3ba677f6..2b30ec15f2 100644 --- a/zellij-utils/src/plugin_api/style.rs +++ b/zellij-utils/src/plugin_api/style.rs @@ -1,9 +1,11 @@ use super::generated_api::api::style::{ color::Payload as ProtobufColorPayload, Color as ProtobufColor, ColorType as ProtobufColorType, Palette as ProtobufPalette, RgbColorPayload as ProtobufRgbColorPayload, Style as ProtobufStyle, - ThemeHue as ProtobufThemeHue, + Styling as ProtobufStyling, ThemeHue as ProtobufThemeHue, +}; +use crate::data::{ + MultiplayerColors, Palette, PaletteColor, Style, StyleDeclaration, Styling, ThemeHue, }; -use crate::data::{Palette, PaletteColor, Style, ThemeHue}; use crate::errors::prelude::*; use std::convert::TryFrom; @@ -11,11 +13,12 @@ use std::convert::TryFrom; impl TryFrom for Style { type Error = &'static str; fn try_from(protobuf_style: ProtobufStyle) -> Result { + let s = protobuf_style + .styling + .ok_or("malformed style payload")? + .try_into()?; Ok(Style { - colors: protobuf_style - .palette - .ok_or("malformed style payload")? - .try_into()?, + colors: s, rounded_corners: protobuf_style.rounded_corners, hide_session_name: protobuf_style.hide_session_name, }) @@ -25,10 +28,156 @@ impl TryFrom for Style { impl TryFrom