aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlukeflo2024-11-29 10:46:13 +0100
committerlukeflo2024-11-29 10:46:13 +0100
commitc4d82e66bdd253cf97fd0a04c251b29e82edc92b (patch)
treec9e678182460a4bc7b98452ddcf7373063ac76f0
parent93fc2222b008bc7dd8eaafcafa341c6aed440d6e (diff)
downloadbibiman-c4d82e66bdd253cf97fd0a04c251b29e82edc92b.tar.gz
bibiman-c4d82e66bdd253cf97fd0a04c251b29e82edc92b.zip
implemented light color scheme
-rw-r--r--.gitignore3
-rw-r--r--src/cliargs.rs15
-rw-r--r--src/tui/colors.rs45
-rw-r--r--src/tui/ui.rs179
4 files changed, 166 insertions, 76 deletions
diff --git a/.gitignore b/.gitignore
index 62cc0c7..8bac1c1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
# no backup files
**/*.bak
-# no gif's
+# no gif's and images
**/*.tape
res/*.gif
+res/*.png
diff --git a/src/cliargs.rs b/src/cliargs.rs
index d6c27c4..5f83eb3 100644
--- a/src/cliargs.rs
+++ b/src/cliargs.rs
@@ -43,7 +43,10 @@ impl CLIArgs {
match arg {
Short('h') | Long("help") => args.helparg = true,
Short('v') | Long("version") => args.versionarg = true,
- Long("light-theme") => AppColors::light_colors(&mut args.colors),
+ Long("light-terminal") => {
+ args.colors.light_colors();
+ args.colors.toggle_color_scheme()
+ }
// Value(pos_arg) => parse_files(&mut args, pos_arg),
Value(pos_arg) => args.pos_args.push(pos_arg.into()),
_ => return Err(arg.unexpected()),
@@ -98,14 +101,18 @@ pub fn help_func() -> String {
{} {}
USAGE:
- bibiman [FLAGS] [file]
+ bibiman [FLAGS] [files/dirs]
POSITIONAL ARGS:
<file> Path to .bib file
+ <dir> Path to directory containing .bib files
+
+ Both can be passed multiple times
FLAGS:
- -h, --help Show this help and exit
- -v, --version Show the version and exit",
+ -h, --help Show this help and exit
+ -v, --version Show the version and exit
+ --light-terminal Enable color mode for light terminal background",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION"),
);
diff --git a/src/tui/colors.rs b/src/tui/colors.rs
index 206ac92..3ea6e86 100644
--- a/src/tui/colors.rs
+++ b/src/tui/colors.rs
@@ -16,6 +16,12 @@
/////
#[derive(Debug, Clone)]
+pub enum AppColorScheme {
+ Light,
+ Dark,
+}
+
+#[derive(Debug, Clone)]
pub struct AppColors {
pub main_text_color: u8,
pub highlight_text_color: u8,
@@ -24,6 +30,10 @@ pub struct AppColors {
pub info_color: u8,
pub confirm_color: u8,
pub warn_color: u8,
+ pub bar_bg_color: u8,
+ pub popup_bg_color: u8,
+ pub selected_row_bg_color: u8,
+ pub color_scheme: AppColorScheme,
}
impl Default for AppColors {
@@ -36,14 +46,18 @@ impl Default for AppColors {
info_color: 99,
confirm_color: 47,
warn_color: 124,
+ bar_bg_color: 235,
+ popup_bg_color: 234,
+ selected_row_bg_color: 237,
+ color_scheme: AppColorScheme::Dark,
}
}
}
impl AppColors {
- pub fn new() -> Self {
- Self::default()
- }
+ // pub fn new() -> Self {
+ // Self::default()
+ // }
pub fn main_text_color(&mut self, index: u8) {
self.main_text_color = index
@@ -73,12 +87,35 @@ impl AppColors {
self.warn_color = index
}
+ pub fn bar_bg_color(&mut self, index: u8) {
+ self.bar_bg_color = index
+ }
+
+ pub fn popup_bg_color(&mut self, index: u8) {
+ self.popup_bg_color = index
+ }
+
+ pub fn selected_row_bg_color(&mut self, index: u8) {
+ self.selected_row_bg_color = index
+ }
+
+ pub fn toggle_color_scheme(&mut self) {
+ match self.color_scheme {
+ AppColorScheme::Light => self.color_scheme = AppColorScheme::Dark,
+ AppColorScheme::Dark => self.color_scheme = AppColorScheme::Light,
+ }
+ }
+
/// Activates the default color scheme for light background terminals
pub fn light_colors(&mut self) {
self.main_text_color(235);
self.highlight_text_color(232);
self.entry_color(23);
self.keyword_color(58);
- self.info_color(57)
+ self.info_color(57);
+ self.bar_bg_color(144);
+ self.popup_bg_color(187);
+ self.confirm_color(22);
+ self.selected_row_bg_color(107)
}
}
diff --git a/src/tui/ui.rs b/src/tui/ui.rs
index c9ee3ba..cca87ce 100644
--- a/src/tui/ui.rs
+++ b/src/tui/ui.rs
@@ -17,6 +17,7 @@
use std::path::PathBuf;
+use super::colors::AppColorScheme;
use super::popup::PopupArea;
use crate::bibiman::entries::EntryTableColumn;
use crate::bibiman::{CurrentArea, FormerArea};
@@ -38,29 +39,50 @@ use ratatui::{
};
use walkdir::WalkDir;
-// Background colors
-static HEADER_FOOTER_BG: Color = Color::Indexed(235);
-static POPUP_BG: Color = Color::Indexed(234);
-
// Symbols
static SORTED_ENTRIES: &str = "▼";
static SORTED_ENTRIES_REVERSED: &str = "▲";
static SCROLLBAR_UPPER_CORNER: Option<&str> = Some("┓");
static SCROLLBAR_LOWER_CORNER: Option<&str> = Some("┛");
-pub const fn color_list(list_item: i32, sel_item: i32, highlight: u8, max_diff: i32) -> Color {
- if list_item == sel_item {
- Color::Indexed(highlight)
- } else if (list_item - sel_item) > max_diff
- || (sel_item - list_item) > max_diff
- || -(list_item - sel_item) > max_diff
- || -(sel_item - list_item) > max_diff
- {
- Color::Indexed(highlight - max_diff as u8)
- } else if list_item < sel_item {
- Color::Indexed(highlight - (sel_item - list_item) as u8)
- } else {
- Color::Indexed(highlight - (list_item - sel_item) as u8)
+pub fn color_list(
+ args: &CLIArgs,
+ list_item: i32,
+ sel_item: i32,
+ highlight: u8,
+ max_diff: i32,
+) -> Color {
+ match args.colors.color_scheme {
+ AppColorScheme::Dark => {
+ if list_item == sel_item {
+ Color::Indexed(highlight)
+ } else if (list_item - sel_item) > max_diff
+ || (sel_item - list_item) > max_diff
+ || -(list_item - sel_item) > max_diff
+ || -(sel_item - list_item) > max_diff
+ {
+ Color::Indexed(highlight - max_diff as u8)
+ } else if list_item < sel_item {
+ Color::Indexed(highlight - (sel_item - list_item) as u8)
+ } else {
+ Color::Indexed(highlight - (list_item - sel_item) as u8)
+ }
+ }
+ AppColorScheme::Light => {
+ if list_item == sel_item {
+ Color::Indexed(highlight)
+ } else if (list_item - sel_item) > max_diff
+ || (sel_item - list_item) > max_diff
+ || -(list_item - sel_item) > max_diff
+ || -(sel_item - list_item) > max_diff
+ {
+ Color::Indexed(highlight + max_diff as u8)
+ } else if list_item < sel_item {
+ Color::Indexed(highlight + (sel_item - list_item) as u8)
+ } else {
+ Color::Indexed(highlight + (list_item - sel_item) as u8)
+ }
+ }
}
}
@@ -129,7 +151,7 @@ pub fn render_popup(app: &mut App, args: &CLIArgs, frame: &mut Frame) {
.style(
Style::new()
.fg(Color::Indexed(args.colors.main_text_color))
- .bg(POPUP_BG),
+ .bg(Color::Indexed(args.colors.popup_bg_color)),
)
.border_set(symbols::border::THICK)
.border_style(Style::new().fg(Color::Indexed(args.colors.entry_color)));
@@ -172,7 +194,7 @@ pub fn render_popup(app: &mut App, args: &CLIArgs, frame: &mut Frame) {
.style(
Style::new()
.fg(Color::Indexed(args.colors.main_text_color))
- .bg(POPUP_BG),
+ .bg(Color::Indexed(args.colors.popup_bg_color)),
);
let content = Paragraph::new(app.bibiman.popup_area.popup_message.clone())
@@ -203,7 +225,7 @@ pub fn render_popup(app: &mut App, args: &CLIArgs, frame: &mut Frame) {
.style(
Style::new()
.fg(Color::Indexed(args.colors.main_text_color))
- .bg(POPUP_BG),
+ .bg(Color::Indexed(args.colors.popup_bg_color)),
);
let content = Paragraph::new(app.bibiman.popup_area.popup_message.clone())
@@ -237,7 +259,7 @@ pub fn render_popup(app: &mut App, args: &CLIArgs, frame: &mut Frame) {
.style(
Style::new()
.fg(Color::Indexed(args.colors.main_text_color))
- .bg(POPUP_BG),
+ .bg(Color::Indexed(args.colors.popup_bg_color)),
)
.border_set(symbols::border::THICK)
.border_style(Style::new().fg(Color::Indexed(args.colors.keyword_color)));
@@ -281,7 +303,7 @@ pub fn render_footer(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect: Rec
let block = Block::new()
.padding(Padding::horizontal(1))
- .bg(HEADER_FOOTER_BG);
+ .bg(Color::Indexed(args.colors.bar_bg_color));
let search_string = Paragraph::new(Line::from(vec![
Span::styled(
@@ -291,14 +313,17 @@ pub fn render_footer(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect: Rec
.fg(Color::Indexed(args.colors.entry_color))
.add_modifier(Modifier::BOLD)
} else if let Some(FormerArea::TagArea) = app.bibiman.former_area {
- Style::new().fg(Color::Indexed(args.colors.highlight_text_color))
+ Style::new()
+ .fg(Color::Indexed(args.colors.keyword_color))
+ .add_modifier(Modifier::BOLD)
} else {
Style::new()
.fg(Color::Indexed(args.colors.highlight_text_color))
.add_modifier(Modifier::BOLD)
},
),
- Span::raw(app.bibiman.search_struct.search_string.clone()),
+ Span::raw(app.bibiman.search_struct.search_string.clone())
+ .fg(Color::Indexed(args.colors.highlight_text_color)),
]))
.block(block);
@@ -339,29 +364,45 @@ pub fn render_file_info(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
let file_info = if args.pos_args.len() == 1 && args.pos_args.first().unwrap().is_file() {
Line::from(vec![
- Span::raw("File: ").bold(),
- Span::raw(args.pos_args[0].file_name().unwrap().to_string_lossy()).bold(),
+ Span::raw("File: ")
+ .fg(Color::Indexed(args.colors.main_text_color))
+ .bold(),
+ Span::raw(args.pos_args[0].file_name().unwrap().to_string_lossy())
+ .fg(Color::Indexed(args.colors.main_text_color))
+ .bold(),
])
- .bg(HEADER_FOOTER_BG)
+ .bg(Color::Indexed(args.colors.bar_bg_color))
} else if args.pos_args.len() == 1 && args.pos_args.first().unwrap().is_dir() {
Line::from(vec![
- Span::raw("Directory: ").bold(),
- Span::raw(args.pos_args[0].file_name().unwrap().to_string_lossy()).bold(),
- Span::raw("/*.bib").bold(),
+ Span::raw("Directory: ")
+ .bold()
+ .fg(Color::Indexed(args.colors.main_text_color)),
+ Span::raw(args.pos_args[0].file_name().unwrap().to_string_lossy())
+ .fg(Color::Indexed(args.colors.main_text_color))
+ .bold(),
+ Span::raw("/*.bib")
+ .fg(Color::Indexed(args.colors.main_text_color))
+ .bold(),
])
- .bg(HEADER_FOOTER_BG)
+ .bg(Color::Indexed(args.colors.bar_bg_color))
} else {
Line::from(vec![
- Span::raw("Multiple files (").bold(),
- Span::raw(count_files(&args.files).to_string()).bold(),
- Span::raw(")"),
+ Span::raw("Multiple files (")
+ .fg(Color::Indexed(args.colors.main_text_color))
+ .bold(),
+ Span::raw(count_files(&args.files).to_string())
+ .fg(Color::Indexed(args.colors.main_text_color))
+ .bold(),
+ Span::raw(")")
+ .fg(Color::Indexed(args.colors.main_text_color))
+ .bold(),
])
- .bg(HEADER_FOOTER_BG)
+ .bg(Color::Indexed(args.colors.bar_bg_color))
};
let cur_keywords = Line::from(if !app.bibiman.tag_list.selected_keywords.is_empty() {
vec![
- Span::raw("Selected keywords: "),
+ Span::raw("Selected keywords: ").fg(Color::Indexed(args.colors.main_text_color)),
// Show all keywords in correct order if list is filtered
// successively by multiple keywords
Span::raw(app.bibiman.tag_list.selected_keywords.join(" → "))
@@ -371,7 +412,7 @@ pub fn render_file_info(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
} else {
vec![Span::raw(" ")]
})
- .bg(HEADER_FOOTER_BG);
+ .bg(Color::Indexed(args.colors.bar_bg_color));
// .render(keyword_area, buf);
let item_count = Line::from(
@@ -407,16 +448,18 @@ pub fn render_file_info(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
.to_string()
},
)
+ .fg(Color::Indexed(args.colors.main_text_color))
.bold(),
- Span::raw("/"),
- Span::raw(app.bibiman.entry_table.entry_table_items.len().to_string()),
+ Span::raw("/").fg(Color::Indexed(args.colors.main_text_color)),
+ Span::raw(app.bibiman.entry_table.entry_table_items.len().to_string())
+ .fg(Color::Indexed(args.colors.main_text_color)),
]
} else {
vec![Span::raw("No entries")]
},
)
.right_aligned()
- .bg(HEADER_FOOTER_BG);
+ .bg(Color::Indexed(args.colors.bar_bg_color));
frame.render_widget(file_info, file_area);
frame.render_widget(cur_keywords, keyword_area);
frame.render_widget(item_count, count_area);
@@ -467,7 +510,7 @@ pub fn render_entrytable(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
let header_style = Style::default()
.bold()
.fg(Color::Indexed(args.colors.main_text_color))
- .bg(HEADER_FOOTER_BG);
+ .bg(Color::Indexed(args.colors.bar_bg_color));
let header = Row::new(vec![
Cell::from(
@@ -490,9 +533,9 @@ pub fn render_entrytable(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
if let EntryTableColumn::Authors =
app.bibiman.entry_table.entry_table_selected_column
{
- Color::Indexed(237)
+ Color::Indexed(args.colors.selected_row_bg_color)
} else {
- HEADER_FOOTER_BG
+ Color::Indexed(args.colors.bar_bg_color)
},
),
),
@@ -514,9 +557,9 @@ pub fn render_entrytable(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
.bg(
if let EntryTableColumn::Title = app.bibiman.entry_table.entry_table_selected_column
{
- Color::Indexed(237)
+ Color::Indexed(args.colors.selected_row_bg_color)
} else {
- HEADER_FOOTER_BG
+ Color::Indexed(args.colors.bar_bg_color)
},
),
),
@@ -538,9 +581,9 @@ pub fn render_entrytable(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
.bg(
if let EntryTableColumn::Year = app.bibiman.entry_table.entry_table_selected_column
{
- Color::Indexed(237)
+ Color::Indexed(args.colors.selected_row_bg_color)
} else {
- HEADER_FOOTER_BG
+ Color::Indexed(args.colors.bar_bg_color)
},
),
),
@@ -564,9 +607,9 @@ pub fn render_entrytable(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
if let EntryTableColumn::Pubtype =
app.bibiman.entry_table.entry_table_selected_column
{
- Color::Indexed(237)
+ Color::Indexed(args.colors.selected_row_bg_color)
} else {
- HEADER_FOOTER_BG
+ Color::Indexed(args.colors.bar_bg_color)
},
),
),
@@ -588,6 +631,7 @@ pub fn render_entrytable(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect:
.collect::<Row>()
.style(
Style::new().fg(color_list(
+ args,
i as i32,
app.bibiman
.entry_table
@@ -727,25 +771,27 @@ pub fn render_selected_item(app: &mut App, args: &CLIArgs, frame: &mut Frame, re
let mut content = vec![Span::styled("Keywords: ", style_value)];
for k in kw {
// Add half block highlighted in bg color to enlarge block
- content.push(Span::raw("▐").fg(HEADER_FOOTER_BG));
+ content.push(Span::raw("▐").fg(Color::Indexed(args.colors.bar_bg_color)));
content.push(Span::styled(
k,
- Style::default().bg(HEADER_FOOTER_BG).fg(
- // Highlight selected keyword green
- if app
- .bibiman
- .tag_list
- .selected_keywords
- .iter()
- .any(|e| e == k)
- {
- Color::Green
- } else {
- Color::Indexed(args.colors.main_text_color)
- },
- ),
+ Style::default()
+ .bg(Color::Indexed(args.colors.bar_bg_color))
+ .fg(
+ // Highlight selected keyword green
+ if app
+ .bibiman
+ .tag_list
+ .selected_keywords
+ .iter()
+ .any(|e| e == k)
+ {
+ Color::Green
+ } else {
+ Color::Indexed(args.colors.main_text_color)
+ },
+ ),
));
- content.push(Span::raw("▌").fg(HEADER_FOOTER_BG));
+ content.push(Span::raw("▌").fg(Color::Indexed(args.colors.bar_bg_color)));
}
lines.push(Line::from(content))
}
@@ -895,6 +941,7 @@ pub fn render_taglist(app: &mut App, args: &CLIArgs, frame: &mut Frame, rect: Re
ListItem::from(keyword.to_owned()).style(Style::new().fg(
if app.bibiman.tag_list.tag_list_state.selected().is_some() {
color_list(
+ args,
i as i32,
app.bibiman.tag_list.tag_list_state.selected().unwrap() as i32,
args.colors.highlight_text_color,
@@ -961,8 +1008,6 @@ fn render_cursor(app: &mut App, frame: &mut Frame, area: Rect, x_offset: u16) {
/// helper function to create a centered rect using up certain percentage of the available rect `r`
fn popup_area(area: Rect, percent_x: u16, percent_y: u16) -> Rect {
- // let vertical = Layout::vertical([Constraint::Percentage(percent_y)]).flex(Flex::Center);
- // let horizontal = Layout::horizontal([Constraint::Percentage(percent_x)]).flex(Flex::Center);
let vertical = Layout::vertical([Constraint::Length(percent_y)]).flex(Flex::Center);
let horizontal = Layout::horizontal([Constraint::Length(percent_x)]).flex(Flex::Center);
let [area] = vertical.areas(area);