summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinzent Steinberg <Vinzent.Steinberg@gmail.com>2019-07-24 14:34:37 +0200
committerVinzent Steinberg <Vinzent.Steinberg@gmail.com>2019-07-24 14:34:37 +0200
commit977e69f9aafc54f9b2ed9ddb2eee5164e30b213c (patch)
treef8f4b0d9ac1b9b3673ca07d3bd901fb243619562
parentf4028baf655e2994459e55d62435de4456fee80f (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.
-rw-r--r--src/interactive/widgets/entries.rs77
-rw-r--r--src/interactive/widgets/footer.rs7
-rw-r--r--src/interactive/widgets/header.rs7
-rw-r--r--src/interactive/widgets/main.rs14
-rw-r--r--src/interactive/widgets/mark.rs38
-rw-r--r--src/interactive/widgets/mod.rs12
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,
+ }
+}