summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2024-01-09 19:39:47 +0100
committerqkzk <qu3nt1n@gmail.com>2024-01-09 19:39:47 +0100
commitd9a1bc06817aa25ccb9b6379b4f2f50436a64719 (patch)
tree0c8bd15fab22746f15b5b3c777a9ae9d2c64136b
parentccad56446815deffd9e6e38dba7c650f42139414 (diff)
configurable menu colors
-rw-r--r--config_files/fm/config.yaml16
-rw-r--r--development.md3
-rw-r--r--src/config/configuration.rs66
-rw-r--r--src/config/mod.rs2
-rw-r--r--src/io/display.rs108
-rw-r--r--src/io/mod.rs2
6 files changed, 144 insertions, 53 deletions
diff --git a/config_files/fm/config.yaml b/config_files/fm/config.yaml
index 7a094e5..0f41ead 100644
--- a/config_files/fm/config.yaml
+++ b/config_files/fm/config.yaml
@@ -28,6 +28,22 @@ colors:
symlink: magenta
broken: light_magenta
+# Colors for menus, headers, footers etc.
+menu_colors:
+ # first color
+ first: rgb(45, 250, 209)
+ # second color
+ second: rgb(230, 189, 87)
+ # selected tab border
+ selected_border: rgb(45, 250, 209)
+ # non selected tab border
+ inert_border: rgb(120, 120, 120)
+ # palette of 4 elements, used in menus (second window) and header
+ palette_1: rgb(45, 250, 209)
+ palette_2: rgb(230, 189, 87)
+ palette_3: rgb(230, 167, 255)
+ palette_4: rgb(59, 204, 255)
+
# keybindings
#
# You can bind any key to any action.
diff --git a/development.md b/development.md
index 3d9f497..1d6a3bd 100644
--- a/development.md
+++ b/development.md
@@ -737,6 +737,7 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
Custom and simple search (filename containing input).
Jump to the file with <return>
ATM both "edit::jump" and "display::flagged" show the same content. The former may be removed soon.
+- Configurable menu colors. Every color used on screen is now configurable like file colors.
#### Changelog
@@ -842,6 +843,7 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
- [x] Move back & leave_mode history should use the same status method
- [x] toggling tree selects the current file if possible
- [x] FIX: next_sibling doesn't wrap
+- [x] configurable menu colors
- [ ] pre release
- [x] Fix last missing items
- [x] check installation (remove config, cargo build)
@@ -851,7 +853,6 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
## Version 0.1.26
-- [ ] configurable menu colors
- [ ] display all specific binds for every mode with a key ?
- [ ] merge sort & regex, display nb of matches, completion + flag on the fly
- [ ] display number of matches while searching
diff --git a/src/config/configuration.rs b/src/config/configuration.rs
index ac2f61c..93699ff 100644
--- a/src/config/configuration.rs
+++ b/src/config/configuration.rs
@@ -3,12 +3,13 @@ use std::{fs::File, path};
use anyhow::Result;
use clap::Parser;
use serde_yaml;
-use tuikit::attr::Color;
+use tuikit::attr::{Attr, Color};
use crate::common::{is_program_in_path, DEFAULT_TERMINAL_FLAG};
use crate::common::{CONFIG_PATH, DEFAULT_TERMINAL_APPLICATION};
use crate::config::Bindings;
use crate::config::Colorer;
+use crate::io::color_to_attr;
/// Holds every configurable aspect of the application.
/// All attributes are hardcoded then updated from optional values
@@ -253,3 +254,66 @@ lazy_static::lazy_static! {
pub static ref START_FOLDER: std::path::PathBuf =
std::fs::canonicalize(crate::io::Args::parse().path).unwrap_or_default();
}
+
+pub struct MenuColors {
+ pub first: Color,
+ pub second: Color,
+ pub selected_border: Color,
+ pub inert_border: Color,
+ pub palette_1: Color,
+ pub palette_2: Color,
+ pub palette_3: Color,
+ pub palette_4: Color,
+}
+
+impl Default for MenuColors {
+ fn default() -> Self {
+ Self {
+ first: Color::Rgb(45, 250, 209),
+ second: Color::Rgb(230, 189, 87),
+ selected_border: Color::Rgb(45, 250, 209),
+ inert_border: Color::Rgb(248, 248, 248),
+ palette_1: Color::Rgb(45, 250, 209),
+ palette_2: Color::Rgb(230, 189, 87),
+ palette_3: Color::Rgb(230, 167, 255),
+ palette_4: Color::Rgb(59, 204, 255),
+ }
+ }
+}
+
+impl MenuColors {
+ pub fn update(mut self) -> Self {
+ if let Ok(file) = File::open(path::Path::new(
+ &shellexpand::tilde(CONFIG_PATH).to_string(),
+ )) {
+ if let Ok(yaml) =
+ serde_yaml::from_reader::<std::fs::File, serde_yaml::value::Value>(file)
+ {
+ let menu_colors = &yaml["menu_colors"];
+ update_attribute!(self.first, menu_colors, "first");
+ update_attribute!(self.second, menu_colors, "second");
+ update_attribute!(self.selected_border, menu_colors, "selected_border");
+ update_attribute!(self.inert_border, menu_colors, "inert_border");
+ update_attribute!(self.palette_1, menu_colors, "palette_1");
+ update_attribute!(self.palette_2, menu_colors, "palette_2");
+ update_attribute!(self.palette_3, menu_colors, "palette_3");
+ update_attribute!(self.palette_4, menu_colors, "palette_4");
+ }
+ }
+ self
+ }
+
+ #[inline]
+ pub const fn palette(&self) -> [Attr; 4] {
+ [
+ color_to_attr(self.palette_1),
+ color_to_attr(self.palette_2),
+ color_to_attr(self.palette_3),
+ color_to_attr(self.palette_4),
+ ]
+ }
+}
+
+lazy_static::lazy_static! {
+ pub static ref MENU_COLORS: MenuColors = MenuColors::default().update();
+}
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 3db1dc7..e14762c 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -3,5 +3,5 @@ mod configuration;
mod keybindings;
pub use colors::{extension_color, Colorer};
-pub use configuration::{load_config, Config, COLORER, COLORS, START_FOLDER};
+pub use configuration::{load_config, Config, COLORER, COLORS, MENU_COLORS, START_FOLDER};
pub use keybindings::{Bindings, REFRESH_EVENT, REFRESH_KEY};
diff --git a/src/io/display.rs b/src/io/display.rs
index e47456a..a2063df 100644
--- a/src/io/display.rs
+++ b/src/io/display.rs
@@ -17,6 +17,7 @@ use crate::common::{
ENCRYPTED_DEVICE_BINDS, HELP_FIRST_SENTENCE, HELP_SECOND_SENTENCE, LOG_FIRST_SENTENCE,
LOG_SECOND_SENTENCE,
};
+use crate::config::MENU_COLORS;
use crate::io::read_last_log_line;
use crate::log_info;
use crate::modes::BinaryContent;
@@ -46,7 +47,7 @@ use crate::modes::{parse_input_mode, SecondLine};
/// Iter over the content, returning a triplet of `(index, line, attr)`.
macro_rules! enumerated_colored_iter {
($t:ident) => {
- std::iter::zip($t.iter().enumerate(), ATTR_MENU_ELEMS.iter().cycle())
+ std::iter::zip($t.iter().enumerate(), MENU_COLORS.palette().iter().cycle())
.map(|((index, line), attr)| (index, line, attr))
};
}
@@ -67,30 +68,6 @@ macro_rules! impl_preview {
/// At least 120 chars width to display 2 tabs.
pub const MIN_WIDTH_FOR_DUAL_PANE: usize = 120;
-const ATTR_FIRST_LINE: [Attr; 4] = [
- color_to_attr(Color::Rgb(45, 250, 209)),
- color_to_attr(Color::Rgb(230, 189, 87)),
- color_to_attr(Color::Rgb(230, 167, 255)),
- color_to_attr(Color::Rgb(59, 204, 255)),
-];
-
-const ATTR_MENU_ELEMS: [Attr; 10] = [
- color_to_attr(Color::Rgb(236, 250, 250)),
- color_to_attr(Color::Rgb(221, 242, 209)),
- color_to_attr(Color::Rgb(205, 235, 197)),
- color_to_attr(Color::Rgb(190, 227, 186)),
- color_to_attr(Color::Rgb(174, 220, 174)),
- color_to_attr(Color::Rgb(159, 212, 163)),
- color_to_attr(Color::Rgb(174, 220, 174)),
- color_to_attr(Color::Rgb(190, 227, 186)),
- color_to_attr(Color::Rgb(205, 235, 197)),
- color_to_attr(Color::Rgb(221, 242, 209)),
-];
-
-const ATTR_FIRST: Attr = color_to_attr(Color::Rgb(45, 250, 209));
-const ATTR_SECOND: Attr = color_to_attr(Color::Rgb(230, 189, 87));
-const ATTR_INERT: Attr = color_to_attr(Color::Rgb(248, 248, 248));
-
enum TabPosition {
Left,
Right,
@@ -272,7 +249,7 @@ impl<'a> WinMain<'a> {
) -> Result<()> {
if self.status.menu.flagged.contains(path) {
attr.effect |= Effect::BOLD;
- canvas.print_with_attr(row, 0, "█", ATTR_SECOND)?;
+ canvas.print_with_attr(row, 0, "█", color_to_attr(MENU_COLORS.second))?;
}
Ok(())
}
@@ -365,7 +342,7 @@ impl<'a> WinMain<'a> {
row_position_in_canvas,
0,
&line_number_to_print.to_string(),
- ATTR_FIRST,
+ color_to_attr(MENU_COLORS.first),
)?)
}
@@ -459,7 +436,7 @@ impl<'a> WinMain<'a> {
row,
0,
&format_line_nr_hex(i + 1 + window.top, line_number_width_hex),
- ATTR_FIRST,
+ color_to_attr(MENU_COLORS.first),
)?;
line.print_bytes(canvas, row, line_number_width_hex + 1);
line.print_ascii(canvas, row, line_number_width_hex + 43);
@@ -731,7 +708,12 @@ struct LogLine;
impl Draw for LogLine {
fn draw(&self, canvas: &mut dyn Canvas) -> DrawResult<()> {
let height = canvas.height()?;
- canvas.print_with_attr(height - 2, 4, &read_last_log_line(), ATTR_SECOND)?;
+ canvas.print_with_attr(
+ height - 2,
+ 4,
+ &read_last_log_line(),
+ color_to_attr(MENU_COLORS.second),
+ )?;
Ok(())
}
}
@@ -757,7 +739,7 @@ impl<'a> Draw for WinMainFooter<'a> {
DisplayMode::Flagged => FlaggedFooter::new(self.status)?.strings().to_owned(),
_ => Footer::new(self.status, self.tab)?.strings().to_owned(),
};
- let mut attr = ATTR_FIRST;
+ let mut attr = color_to_attr(MENU_COLORS.first);
if self.is_selected {
attr.effect |= Effect::REVERSE;
};
@@ -813,15 +795,20 @@ impl<'a> WinSecondary<'a> {
let mut col = 11;
for (text, is_valid) in &mode_parsed {
let attr = if *is_valid {
- Attr::from(Color::YELLOW)
+ color_to_attr(MENU_COLORS.first)
} else {
- Attr::from(Color::RED)
+ color_to_attr(MENU_COLORS.second)
};
col += 1 + canvas.print_with_attr(1, col, text, attr)?;
}
}
edit => {
- canvas.print_with_attr(1, 2, edit.second_line(), ATTR_SECOND)?;
+ canvas.print_with_attr(
+ 1,
+ 2,
+ edit.second_line(),
+ color_to_attr(MENU_COLORS.second),
+ )?;
}
}
Ok(())
@@ -947,7 +934,12 @@ impl<'a> WinSecondary<'a> {
}
fn draw_trash_content(&self, canvas: &mut dyn Canvas, trash: &Trash) {
- let _ = canvas.print_with_attr(1, 2, &self.status.menu.trash.help, ATTR_SECOND);
+ let _ = canvas.print_with_attr(
+ 1,
+ 2,
+ &self.status.menu.trash.help,
+ color_to_attr(MENU_COLORS.second),
+ );
let content = trash.content();
let (top, bottom) = (self.status.menu.window.top, self.status.menu.window.bottom);
let len = content.len();
@@ -972,7 +964,7 @@ impl<'a> WinSecondary<'a> {
fn draw_context(&self, canvas: &mut dyn Canvas) -> Result<()> {
let selectable = &self.status.menu.context;
- canvas.print_with_attr(1, 2, "Pick an action.", ATTR_SECOND)?;
+ canvas.print_with_attr(1, 2, "Pick an action.", color_to_attr(MENU_COLORS.second))?;
let content = selectable.content();
for (row, desc, attr) in enumerated_colored_iter!(content) {
let attr = selectable.attr(row, attr);
@@ -983,7 +975,7 @@ impl<'a> WinSecondary<'a> {
fn draw_marks(&self, canvas: &mut dyn Canvas, mark_action: MarkAction) -> Result<()> {
canvas.print(1, 2, mark_action.second_line())?;
- canvas.print_with_attr(2, 4, "mark path", ATTR_SECOND)?;
+ canvas.print_with_attr(2, 4, "mark path", color_to_attr(MENU_COLORS.second))?;
let content = self.status.menu.marks.as_strings();
let (top, bottom) = (self.status.menu.window.top, self.status.menu.window.bottom);
@@ -1000,7 +992,12 @@ impl<'a> WinSecondary<'a> {
// TODO: refactor both methods below with common trait selectable
fn draw_shell_menu(&self, canvas: &mut dyn Canvas) -> Result<()> {
- canvas.print_with_attr(1, 2, self.tab.edit_mode.second_line(), ATTR_SECOND)?;
+ canvas.print_with_attr(
+ 1,
+ 2,
+ self.tab.edit_mode.second_line(),
+ color_to_attr(MENU_COLORS.second),
+ )?;
let content = &self.status.menu.tui_applications.content;
let (top, bottom) = (self.status.menu.window.top, self.status.menu.window.bottom);
@@ -1016,7 +1013,7 @@ impl<'a> WinSecondary<'a> {
}
fn draw_cli_applications(&self, canvas: &mut dyn Canvas) -> Result<()> {
- canvas.print_with_attr(1, 2, "pick a command", ATTR_SECOND)?;
+ canvas.print_with_attr(1, 2, "pick a command", color_to_attr(MENU_COLORS.second))?;
let content = &self.status.menu.cli_applications.content;
let desc_size = self.status.menu.cli_applications.desc_size;
@@ -1060,7 +1057,12 @@ impl<'a> WinSecondary<'a> {
where
T: MountRepr,
{
- canvas.print_with_attr(1, 2, ENCRYPTED_DEVICE_BINDS, ATTR_SECOND)?;
+ canvas.print_with_attr(
+ 1,
+ 2,
+ ENCRYPTED_DEVICE_BINDS,
+ color_to_attr(MENU_COLORS.second),
+ )?;
let (top, bottom) = (self.status.menu.window.top, self.status.menu.window.bottom);
let len = selectable.len();
for (i, device) in selectable
@@ -1103,7 +1105,7 @@ impl<'a> WinSecondary<'a> {
canvas,
0,
&confirmed_mode.confirmation_string(&dest),
- ATTR_SECOND,
+ color_to_attr(MENU_COLORS.second),
)?;
match confirmed_mode {
NeedConfirmation::EmptyTrash => self.draw_confirm_empty_trash(canvas)?,
@@ -1144,7 +1146,12 @@ impl<'a> WinSecondary<'a> {
}
fn draw_trash_is_empty(&self, canvas: &mut dyn Canvas) {
- let _ = Self::draw_content_line(canvas, 0, "Trash is empty", ATTR_SECOND);
+ let _ = Self::draw_content_line(
+ canvas,
+ 0,
+ "Trash is empty",
+ color_to_attr(MENU_COLORS.second),
+ );
}
fn draw_confirm_non_empty_trash(&self, canvas: &mut dyn Canvas) -> Result<()> {
@@ -1196,9 +1203,6 @@ pub struct Display {
}
impl Display {
- const SELECTED_BORDER: Attr = ATTR_FIRST;
- const INERT_BORDER: Attr = ATTR_INERT;
-
/// Returns a new `Display` instance from a `tuikit::term::Term` object.
pub fn new(term: Arc<Term>) -> Self {
log_info!("starting display...");
@@ -1296,9 +1300,15 @@ impl Display {
fn borders(&self, status: &Status) -> (Attr, Attr) {
if status.index == 0 {
- (Self::SELECTED_BORDER, Self::INERT_BORDER)
+ (
+ color_to_attr(MENU_COLORS.selected_border),
+ color_to_attr(MENU_COLORS.inert_border),
+ )
} else {
- (Self::INERT_BORDER, Self::SELECTED_BORDER)
+ (
+ color_to_attr(MENU_COLORS.inert_border),
+ color_to_attr(MENU_COLORS.selected_border),
+ )
}
}
@@ -1353,7 +1363,7 @@ impl Display {
let win = self.vertical_split(
&win_main_left,
&win_second_left,
- Self::SELECTED_BORDER,
+ color_to_attr(MENU_COLORS.selected_border),
percent_left,
)?;
Ok(self.term.draw(&win)?)
@@ -1364,7 +1374,7 @@ fn format_line_nr_hex(line_nr: usize, width: usize) -> String {
format!("{line_nr:0width$x}")
}
-const fn color_to_attr(color: Color) -> Attr {
+pub const fn color_to_attr(color: Color) -> Attr {
Attr {
fg: color,
bg: Color::Default,
@@ -1380,7 +1390,7 @@ fn draw_colored_strings(
effect_reverse: bool,
) -> Result<()> {
let mut col = 1;
- for (text, attr) in std::iter::zip(strings.iter(), ATTR_FIRST_LINE.iter().cycle()) {
+ for (text, attr) in std::iter::zip(strings.iter(), MENU_COLORS.palette().iter().cycle()) {
let mut attr = *attr;
if effect_reverse {
attr.effect |= Effect::REVERSE;
diff --git a/src/io/mod.rs b/src/io/mod.rs
index 3581388..6fd0d3f 100644
--- a/src/io/mod.rs
+++ b/src/io/mod.rs
@@ -7,7 +7,7 @@ mod opener;
pub use args::Args;
pub use commands::*;
-pub use display::{Display, Height, MIN_WIDTH_FOR_DUAL_PANE};
+pub use display::{color_to_attr, Display, Height, MIN_WIDTH_FOR_DUAL_PANE};
pub use git::{git, git_root};
pub use log::{read_last_log_line, read_log, set_loggers, write_log_info_once, write_log_line};
pub use opener::*;