modified: src/main_screen.rs

modified:   src/playlist_icon.rs
This commit is contained in:
Michael Wain 2025-02-11 17:32:15 +03:00
parent ded8897ece
commit 8c3d87133d
2 changed files with 51 additions and 36 deletions

View File

@ -261,7 +261,7 @@ impl MainScreen {
for (i, row) in rows.iter().enumerate() {
let cols = Layout::default()
.direction(Direction::Horizontal)
.constraints(vec![Constraint::Length(16); 2]) // Three columns
.constraints(vec![Constraint::Percentage(33); 3]) // Three columns
.split(*row);
for (j, col) in cols.iter().enumerate() {
@ -270,13 +270,19 @@ impl MainScreen {
let p = &v[index];
/*let url_cl = p.thumbnail_url.clone();
let s = url_cl.lines().map(Line::from).collect::<Vec<Line>>();
let s = url_cl.lines().map(Line::from).collect::<Vec<Line>>();*/
let paragraph = Paragraph::new(s)
let paragraph = Paragraph::new(Line::from(p.name.clone()))
.block(Block::default().borders(Borders::ALL))
.style(Style::default());*/
.style(Style::default());
frame.render_widget(p.thumbnail.clone(), *col);
let pl = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Percentage(70), Constraint::Percentage(30)])
.split(*col);
frame.render_widget(p.thumbnail.clone(), pl[0]);
frame.render_widget(paragraph, pl[1]);
}
}
}

View File

@ -1,34 +1,30 @@
use std::collections::HashSet;
use color_eyre::owo_colors::OwoColorize;
use image::{DynamicImage, GenericImageView};
use ratatui::{
buffer::Buffer,
layout::Rect,
style::{Color, Style, Stylize},
widgets::Widget,
};
use image::DynamicImage;
use ratatui::{buffer::Buffer, layout::Rect, style::Color, widgets::Widget};
#[derive(Default, Clone)]
pub struct PlaylistIcon {
colors: [[u8; 3]; 8],
colors: Vec<[u8; 3]>,
}
impl PlaylistIcon {
pub fn new(img: DynamicImage) -> Self {
let pixels = img
.resize_exact(8, 8, image::imageops::FilterType::Nearest)
.to_rgb8()
.pixels()
.map(|p| p.0)
.collect::<HashSet<[u8; 3]>>()
let img_rgb = img.to_rgb8();
let pixels = img_rgb.as_raw();
let r = color_thief::get_palette(pixels, color_thief::ColorFormat::Rgb, 10, 4)
.unwrap()
.iter()
.copied()
.map(|c| [c.r, c.g, c.b])
.collect::<Vec<[u8; 3]>>();
Self {
colors: pixels[..8].try_into().unwrap(),
}
Self { colors: r }
}
fn lerp(a: &[u8; 3], b: &[u8; 3], n: f32) -> [u8; 3] {
let r = (b[0] as f32 - a[0] as f32) * n + b[0] as f32;
let g = (b[1] as f32 - a[1] as f32) * n + b[1] as f32;
let b = (b[2] as f32 - a[2] as f32) * n + b[2] as f32;
[r as u8, g as u8, b as u8]
}
}
@ -36,17 +32,30 @@ impl Widget for PlaylistIcon {
fn render(self, area: Rect, buf: &mut Buffer) {
let mut i = 0;
for x in area.left()..area.right() {
for y in area.top()..area.bottom() {
let color = self.colors[i];
buf.set_string(
x,
y,
"",
Style::default().fg(Color::Rgb(color[0], color[1], color[2])),
);
i = if i >= self.colors.len() - 1 { 0 } else { i + 1 };
let start = self.colors.first().unwrap_or(&[255u8, 255u8, 255u8]);
let end = &[0u8, 0u8, 0u8];
let mut c = *start;
for y in area.top()..area.bottom() {
for x in area.left()..area.right() {
let n = (((area.bottom() - y).pow(2) + (area.right() - x).pow(2)) as f32).sqrt();
c = PlaylistIcon::lerp(start, end, n);
buf[(x, y)]
.set_char(' ')
.set_bg(Color::Rgb(c[0], c[1], c[2]))
.set_fg(Color::Rgb(c[0], c[1], c[2]));
}
i = match self.colors.len() {
0 => 0,
_ => {
if i >= self.colors.len() - 1 {
0
} else {
i + 1
}
}
};
}
}
}