diff options
author | Vinzent Steinberg <Vinzent.Steinberg@gmail.com> | 2019-07-24 14:34:37 +0200 |
---|---|---|
committer | Vinzent Steinberg <Vinzent.Steinberg@gmail.com> | 2019-07-24 14:34:37 +0200 |
commit | 977e69f9aafc54f9b2ed9ddb2eee5164e30b213c (patch) | |
tree | f8f4b0d9ac1b9b3673ca07d3bd901fb243619562 /src/interactive | |
parent | f4028baf655e2994459e55d62435de4456fee80f (diff) |
Fix color scheme for light terminals
This is done by making sure that we never have a background that is
black or white combined with a foreground that uses the terminal's
default and vice versa.
Because we cannot access the default terminal colors, we have to rely on
inverted colors and bold text for highlighting.
Also, the mark pane was improved to be more consistent with the entries
pane. Ideally, we would use the same color as in the entries pane, but
this is currently not possible, because the mark pane does not know
whether a path is a directory or not.
Fixes #13.
Diffstat (limited to 'src/interactive')
-rw-r--r-- | src/interactive/widgets/entries.rs | 77 | ||||
-rw-r--r-- | src/interactive/widgets/footer.rs | 7 | ||||
-rw-r--r-- | src/interactive/widgets/header.rs | 7 | ||||
-rw-r--r-- | src/interactive/widgets/main.rs | 14 | ||||
-rw-r--r-- | src/interactive/widgets/mark.rs | 38 | ||||
-rw-r--r-- | src/interactive/widgets/mod.rs | 12 |
6 files changed, 64 insertions, 91 deletions
diff --git a/src/interactive/widgets/entries.rs b/src/interactive/widgets/entries.rs index ed2c001..b4274f2 100644 --- a/src/interactive/widgets/entries.rs +++ b/src/interactive/widgets/entries.rs @@ -1,7 +1,7 @@ use crate::interactive::{ path_of, widgets::{ - EntryMarkMap, COLOR_BYTESIZE_SELECTED, COLOR_MARKED, COLOR_MARKED_DARK, COLOR_MARKED_DARKER, + get_name_color, EntryMarkMap, }, DisplayOptions, EntryDataBundle, }; @@ -11,7 +11,7 @@ use std::{borrow::Borrow, path::Path}; use tui::{ buffer::Buffer, layout::Rect, - style::{Color, Style}, + style::{Color, Style, Modifier}, widgets::{Block, Borders, Text}, }; use tui_react::{fill_background_to_right, List, ListProps}; @@ -97,28 +97,18 @@ impl Entries { is_dir, exists, }| { - let (is_selected, style) = match selected { - Some(idx) if *idx == *node_idx => ( - true, - Style { - fg: Color::Black, - bg: if *is_focussed { - Color::White - } else { - Color::DarkGray - }, - ..Default::default() - }, - ), - _ => ( - false, - Style { - fg: Color::White, - bg: Color::Reset, - ..Default::default() - }, - ), + let mut style = Style::default(); + let is_selected = if let Some(idx) = selected { + *idx == *node_idx + } else { + false }; + if is_selected { + style.modifier.insert(Modifier::REVERSED); + } + if *is_focussed & is_selected { + style.modifier.insert(Modifier::BOLD); + } let bytes = Text::Styled( format!( @@ -128,11 +118,7 @@ impl Entries { ) .into(), Style { - fg: match (is_selected, *is_focussed) { - (true, true) => COLOR_BYTESIZE_SELECTED, - (true, false) => Color::Black, - _ => Color::Green, - }, + fg: Color::Green, ..style }, ); @@ -142,14 +128,7 @@ impl Entries { display.byte_vis.display(w.size as f32 / total as f32) ) .into(), - Style { - fg: match (is_selected, *is_focussed) { - (true, true) => COLOR_MARKED_DARK, - (true, false) => COLOR_MARKED_DARKER, - _ => style.fg, - }, - ..style - }, + style, ); let name = Text::Styled( @@ -162,24 +141,16 @@ impl Entries { area.width, ) .into(), - Style { - fg: match ( - !is_dir, - exists, - marked.map(|m| m.contains_key(node_idx)).unwrap_or(false), - ) { - (true, true, false) if !is_selected => Color::DarkGray, - (true, true, false) => style.fg, - (false, true, false) => style.fg, - - (true, true, true) => COLOR_MARKED_DARK, - (false, true, true) => COLOR_MARKED, - + { + let is_marked = marked.map(|m| m.contains_key(node_idx)).unwrap_or(false); + let fg = if !exists { // non-existing - always red! - (_, false, _) => Color::Red, - }, - ..style - }, + Color::Red + } else { + get_name_color(style.fg, !is_dir, is_marked) + }; + Style { fg, ..style } + } ); vec![bytes, percentage, name] }, diff --git a/src/interactive/widgets/footer.rs b/src/interactive/widgets/footer.rs index 03b2d3a..16c4965 100644 --- a/src/interactive/widgets/footer.rs +++ b/src/interactive/widgets/footer.rs @@ -26,8 +26,6 @@ impl Footer { message, } = props.borrow(); - let bg_color = Color::White; - let text_color = Color::Black; let lines = [ Text::Raw( format!( @@ -46,7 +44,7 @@ impl Footer { m.into(), Style { fg: Color::Red, - bg: bg_color, + bg: Color::Reset, modifier: Modifier::BOLD | Modifier::RAPID_BLINK, }, ) @@ -54,8 +52,7 @@ impl Footer { ]; Paragraph::new(lines.iter().filter_map(|x| x.as_ref())) .style(Style { - fg: text_color, - bg: bg_color, + modifier: Modifier::REVERSED, ..Default::default() }) .draw(area, buf); diff --git a/src/interactive/widgets/header.rs b/src/interactive/widgets/header.rs index 2cacb02..fca6f8f 100644 --- a/src/interactive/widgets/header.rs +++ b/src/interactive/widgets/header.rs @@ -9,12 +9,12 @@ pub struct Header; impl Header { pub fn render(&self, bg_color: Color, area: Rect, buf: &mut Buffer) { - let text_color = Color::Black; - let standard = Style { - fg: text_color, + let standard = Style{ + fg: Color::Black, bg: bg_color, ..Default::default() }; + assert_ne!(standard.bg, standard.fg); let modified = |text: &'static str, modifier| { Text::Styled( text.into(), @@ -43,7 +43,6 @@ impl Header { ]; Paragraph::new(lines.iter()) .style(Style { - fg: text_color, bg: bg_color, ..Default::default() }) diff --git a/src/interactive/widgets/main.rs b/src/interactive/widgets/main.rs index c1c16ad..abd13dd 100644 --- a/src/interactive/widgets/main.rs +++ b/src/interactive/widgets/main.rs @@ -1,7 +1,7 @@ use crate::interactive::{ widgets::{ Entries, EntriesProps, Footer, FooterProps, Header, HelpPane, HelpPaneProps, MarkPane, - MarkPaneProps, COLOR_MARKED_LIGHT, + MarkPaneProps, COLOR_MARKED, }, AppState, DisplayOptions, FocussedPane, }; @@ -54,14 +54,14 @@ impl MainWindow { bg: Color::Reset, modifier: Modifier::empty(), }; - let white = Style { - fg: Color::White, + let bold = Style { + modifier: Modifier::BOLD, ..grey }; match state.focussed { - Main => (white, grey, grey), - Help => (grey, white, grey), - Mark => (grey, grey, white), + Main => (bold, grey, grey), + Help => (grey, bold, grey), + Mark => (grey, grey, bold), } }; @@ -76,7 +76,7 @@ impl MainWindow { let marked = self.mark_pane.as_ref().map(|p| p.marked()); let bg_color = match (marked.map_or(true, |m| m.is_empty()), state.focussed) { (false, FocussedPane::Mark) => Color::LightRed, - (false, _) => COLOR_MARKED_LIGHT, + (false, _) => COLOR_MARKED, (_, _) => Color::White, }; Header.render(bg_color, header_area, buf); diff --git a/src/interactive/widgets/mark.rs b/src/interactive/widgets/mark.rs index cbd34a6..49a4128 100644 --- a/src/interactive/widgets/mark.rs +++ b/src/interactive/widgets/mark.rs @@ -1,6 +1,6 @@ use crate::interactive::{ fit_string_graphemes_with_ellipsis, path_of, - widgets::{COLOR_BYTESIZE_SELECTED, COLOR_MARKED_LIGHT}, + widgets::get_name_color, CursorDirection, }; use dua::{ @@ -219,17 +219,21 @@ impl MarkPane { format.display(marked.iter().map(|(_k, v)| v.size).sum::<u64>()) ); let selected = self.selected; + let has_focus = self.has_focus; let entries = marked.values().sorted_by_key(|v| &v.index).enumerate().map( |(idx, v): (usize, &EntryMark)| { - let (default_style, is_selected) = match selected { - Some(selected) if idx == selected => ( + let default_style = match selected { + Some(selected) if idx == selected => { + let mut modifier = Modifier::REVERSED; + if has_focus { + modifier.insert(Modifier::BOLD); + } Style { - bg: Color::White, + modifier, ..Default::default() - }, - true, - ), - _ => (Style::default(), false), + } + }, + _ => Style::default(), }; let (path, path_len) = { let path = format!( @@ -254,14 +258,11 @@ impl MarkPane { _ => (path, num_path_graphemes), } }; + let fg_path = get_name_color(Color::Reset, false, true); // TODO: determine whether directory let path = Text::Styled( path.into(), Style { - fg: if is_selected { - Color::Black - } else { - COLOR_MARKED_LIGHT - }, + fg: fg_path, ..default_style }, ); @@ -273,11 +274,7 @@ impl MarkPane { ) .into(), Style { - fg: if is_selected { - COLOR_BYTESIZE_SELECTED - } else { - Color::Green - }, + fg: Color::Green, ..default_style }, ); @@ -290,7 +287,10 @@ impl MarkPane { .saturating_sub(format.total_width()) ) .into(), - default_style, + Style { + fg: fg_path, + ..default_style + }, ); vec![path, spacer, bytes] }, diff --git a/src/interactive/widgets/mod.rs b/src/interactive/widgets/mod.rs index ee6f34c..b9c72f5 100644 --- a/src/interactive/widgets/mod.rs +++ b/src/interactive/widgets/mod.rs @@ -14,8 +14,14 @@ pub use mark::*; use tui::style::Color; -pub const COLOR_BYTESIZE_SELECTED: Color = Color::DarkGray; pub const COLOR_MARKED: Color = Color::Yellow; -pub const COLOR_MARKED_LIGHT: Color = Color::LightYellow; pub const COLOR_MARKED_DARK: Color = Color::Rgb(176, 126, 0); -pub const COLOR_MARKED_DARKER: Color = Color::Rgb(106, 66, 0); + +fn get_name_color(fg: Color, is_file: bool, is_marked: bool) -> Color { + match (is_file, is_marked) { + (true, false) => Color::DarkGray, + (true, true) => COLOR_MARKED_DARK, + (false, true) => COLOR_MARKED, + _ => fg, + } +} |