summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2024-01-24 21:45:22 +0100
committerqkzk <qu3nt1n@gmail.com>2024-01-24 21:45:22 +0100
commitc4eae466c106d19118401076ad25d6aee8fbb509 (patch)
treed9ef41a17ec4df07ced5151d001f490b1fd5a10e
parente56fec6d45df7f0cd3171e216b9d64d57fdef810 (diff)
gradient over listing
-rw-r--r--development.md1
-rw-r--r--src/config/colors.rs72
-rw-r--r--src/config/mod.rs2
-rw-r--r--src/io/display.rs43
4 files changed, 100 insertions, 18 deletions
diff --git a/development.md b/development.md
index fc618df..52e5d1f 100644
--- a/development.md
+++ b/development.md
@@ -917,6 +917,7 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
- [x] merge both bulkthing modes. If more files, just create them. Like [oil](https://github.com/stevearc/oil.nvim)
- [x] allow different ports in remote
- [x] sort trash by reversed deletion date
+- [x] gradient over listing
- [ ] ???
## TODO
diff --git a/src/config/colors.rs b/src/config/colors.rs
index 7f56e85..0554e28 100644
--- a/src/config/colors.rs
+++ b/src/config/colors.rs
@@ -43,3 +43,75 @@ pub fn extension_color(extension: &str) -> Color {
hasher.write(extension.as_bytes());
COLORER(hasher.finish() as usize)
}
+
+#[derive(Debug, Clone, Copy)]
+pub struct ColorG {
+ r: u8,
+ g: u8,
+ b: u8,
+}
+
+impl Default for ColorG {
+ fn default() -> Self {
+ Self {
+ r: 255,
+ g: 255,
+ b: 0,
+ }
+ }
+}
+
+impl ColorG {
+ /// Parse a tuikit color into it's rgb values.
+ /// Non parsable colors returns None.
+ pub fn from_tuikit(color: Color) -> Option<Self> {
+ match color {
+ Color::Rgb(r, g, b) => Some(Self { r, g, b }),
+ _ => None,
+ }
+ }
+
+ fn to_tuikit(&self) -> Color {
+ Color::Rgb(self.r, self.g, self.b)
+ }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct Gradient {
+ start: ColorG,
+ end: ColorG,
+ step_ratio: f32,
+ len: usize,
+}
+
+impl Gradient {
+ pub fn new(start: ColorG, end: ColorG, len: usize) -> Self {
+ let step_ratio = 1 as f32 / len as f32;
+ Self {
+ start,
+ end,
+ step_ratio,
+ len,
+ }
+ }
+
+ fn gradient_step(&self, step: usize) -> ColorG {
+ let position = self.step_ratio * step as f32;
+
+ let r = self.start.r as f32 + (self.end.r as f32 - self.start.r as f32) * position;
+ let g = self.start.g as f32 + (self.end.g as f32 - self.start.g as f32) * position;
+ let b = self.start.b as f32 + (self.end.b as f32 - self.start.b as f32) * position;
+
+ ColorG {
+ r: r.round() as u8,
+ g: g.round() as u8,
+ b: b.round() as u8,
+ }
+ }
+
+ pub fn gradient(&self) -> Vec<Color> {
+ (0..self.len)
+ .map(|step| self.gradient_step(step).to_tuikit())
+ .collect()
+ }
+}
diff --git a/src/config/mod.rs b/src/config/mod.rs
index e14762c..9184636 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -2,6 +2,6 @@ mod colors;
mod configuration;
mod keybindings;
-pub use colors::{extension_color, Colorer};
+pub use colors::{extension_color, ColorG, Colorer, Gradient};
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 adf3f5a..e5beea3 100644
--- a/src/io/display.rs
+++ b/src/io/display.rs
@@ -14,7 +14,7 @@ use crate::app::{ClickableLine, ClickableString, FlaggedFooter, FlaggedHeader};
use crate::app::{Header, PreviewHeader};
use crate::common::path_to_string;
use crate::common::ENCRYPTED_DEVICE_BINDS;
-use crate::config::MENU_COLORS;
+use crate::config::{ColorG, Gradient, MENU_COLORS};
use crate::io::read_last_log_line;
use crate::log_info;
use crate::modes::BinaryContent;
@@ -43,11 +43,20 @@ 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(), MENU_COLORS.palette().iter().cycle())
- .map(|((index, line), attr)| (index, line, attr))
+ std::iter::zip(
+ $t.iter().enumerate(),
+ Gradient::new(
+ ColorG::from_tuikit(MENU_COLORS.first).unwrap_or_default(),
+ ColorG::from_tuikit(MENU_COLORS.palette_3).unwrap_or_default(),
+ $t.len(),
+ )
+ .gradient()
+ .iter()
+ .map(|color| color_to_attr(*color)),
+ )
+ .map(|((index, line), attr)| (index, line, attr))
};
}
-
/// Draw every line of the preview
macro_rules! impl_preview {
($text:ident, $tab:ident, $length:ident, $canvas:ident, $line_number_width:ident, $window:ident, $height:ident) => {
@@ -772,7 +781,7 @@ impl<'a> WinSecondary<'a> {
.skip(top)
.take(min(bottom, len))
{
- let attr = self.status.menu.completion.attr(row, attr);
+ let attr = self.status.menu.completion.attr(row, &attr);
Self::draw_content_line(canvas, row + 1 - top, candidate, attr)?;
}
Ok(())
@@ -780,7 +789,7 @@ impl<'a> WinSecondary<'a> {
fn draw_static_lines(lines: &[&str], canvas: &mut dyn Canvas) -> Result<()> {
for (row, line, attr) in enumerated_colored_iter!(lines) {
- Self::draw_content_line(canvas, row, line, *attr)?;
+ Self::draw_content_line(canvas, row, line, attr)?;
}
Ok(())
}
@@ -827,7 +836,7 @@ impl<'a> WinSecondary<'a> {
.skip(top)
.take(min(bottom, len))
{
- let attr = selectable.attr(row, attr);
+ let attr = selectable.attr(row, &attr);
Self::draw_content_line(
canvas,
row + 1 - top,
@@ -842,7 +851,7 @@ impl<'a> WinSecondary<'a> {
let selectable = &self.tab.history;
let content = selectable.content();
for (row, pair, attr) in enumerated_colored_iter!(content) {
- let attr = selectable.attr(row, attr);
+ let attr = selectable.attr(row, &attr);
Self::draw_content_line(
canvas,
row + 1,
@@ -877,7 +886,7 @@ impl<'a> WinSecondary<'a> {
.skip(top)
.take(min(bottom, len))
{
- let attr = trash.attr(row, attr);
+ let attr = trash.attr(row, &attr);
let _ = Self::draw_content_line(canvas, row + 1 - top, &trashinfo.to_string(), attr);
}
}
@@ -886,7 +895,7 @@ impl<'a> WinSecondary<'a> {
let selectable = &self.status.menu.compression;
let content = selectable.content();
for (row, compression_method, attr) in enumerated_colored_iter!(content) {
- let attr = selectable.attr(row, attr);
+ let attr = selectable.attr(row, &attr);
Self::draw_content_line(canvas, row + 1, &compression_method.to_string(), attr)?;
}
Ok(())
@@ -897,7 +906,7 @@ impl<'a> WinSecondary<'a> {
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);
+ let attr = selectable.attr(row, &attr);
Self::draw_content_line(canvas, row + 1, desc, attr)?;
}
Ok(())
@@ -914,7 +923,7 @@ impl<'a> WinSecondary<'a> {
.skip(top)
.take(min(bottom, len))
{
- let attr = self.status.menu.marks.attr(row, attr);
+ let attr = self.status.menu.marks.attr(row, &attr);
Self::draw_content_line(canvas, row + 1 - top, line, attr)?;
}
Ok(())
@@ -936,7 +945,7 @@ impl<'a> WinSecondary<'a> {
.skip(top)
.take(min(bottom, len))
{
- let attr = self.status.menu.tui_applications.attr(row, attr);
+ let attr = self.status.menu.tui_applications.attr(row, &attr);
Self::draw_content_line(canvas, row + 1 - top, command, attr)?;
}
Ok(())
@@ -958,7 +967,7 @@ impl<'a> WinSecondary<'a> {
.skip(top)
.take(min(bottom, len))
{
- let attr = self.status.menu.cli_applications.attr(row, attr);
+ let attr = self.status.menu.cli_applications.attr(row, &attr);
canvas.print_with_attr(
row + 1 + ContentWindow::WINDOW_MARGIN_TOP - top,
4,
@@ -1057,7 +1066,7 @@ impl<'a> WinSecondary<'a> {
canvas,
row + 2,
path.to_str().context("Unreadable filename")?,
- *attr,
+ attr,
)?;
}
Ok(())
@@ -1066,7 +1075,7 @@ impl<'a> WinSecondary<'a> {
fn draw_confirm_bulk(&self, canvas: &mut dyn Canvas) -> Result<()> {
let content = self.status.menu.bulk.format_confirmation();
for (row, line, attr) in enumerated_colored_iter!(content) {
- Self::draw_content_line(canvas, row + 2, line, *attr)?;
+ Self::draw_content_line(canvas, row + 2, line, attr)?;
}
Ok(())
}
@@ -1092,7 +1101,7 @@ impl<'a> WinSecondary<'a> {
fn draw_confirm_non_empty_trash(&self, canvas: &mut dyn Canvas) -> Result<()> {
let content = self.status.menu.trash.content();
for (row, trashinfo, attr) in enumerated_colored_iter!(content) {
- let attr = self.status.menu.trash.attr(row, attr);
+ let attr = self.status.menu.trash.attr(row, &attr);
Self::draw_content_line(canvas, row + 4, &trashinfo.to_string(), attr)?;
}
Ok(())