diff --git a/src/keys.rs b/src/keys.rs index ab1ee69..00c82b5 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -1,7 +1,5 @@ use crate::*; -const PAGE_SIZE: usize = 10; - impl Handle for Taggart { fn handle (&mut self, input: &TuiIn) -> Perhaps { let x_min = self.offset; @@ -39,6 +37,22 @@ impl Handle for Taggart { }) => { self.cursor += PAGE_SIZE; }, + Event::Key(KeyEvent { + code: KeyCode::Left, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::NONE, + state: KeyEventState::NONE + }) => { + self.column = self.column.saturating_sub(1); + }, + Event::Key(KeyEvent { + code: KeyCode::Right, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::NONE, + state: KeyEventState::NONE + }) => { + self.column = self.column + 1; + }, _ => {} } if self.cursor < x_min { @@ -50,6 +64,9 @@ impl Handle for Taggart { if self.cursor >= self.paths.len() { self.cursor = self.paths.len().saturating_sub(1) } + if self.column + 1 > COLUMN_COUNT { + self.column = COLUMN_COUNT.saturating_sub(1) + } Ok(None) } } diff --git a/src/main.rs b/src/main.rs index 153b1d9..41cacf0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,12 @@ use std::env::current_dir; mod keys; mod view; -type Usually = std::result::Result>; -type Perhaps = Usually>; +pub(crate) type Usually = std::result::Result>; +pub(crate) type Perhaps = Usually>; + +pub(crate) const PAGE_SIZE: usize = 10; +pub(crate) const COLUMN_COUNT: usize = 5; +pub(crate) const COLUMN_WIDTHS: [u16; COLUMN_COUNT] = [60, 20, 20, 5, 20]; fn cli () -> clap::Command { command!() diff --git a/src/view.rs b/src/view.rs index d388cab..58f98a3 100644 --- a/src/view.rs +++ b/src/view.rs @@ -2,16 +2,25 @@ use crate::*; use tek_tui::ratatui::{style::{Color, Style}, prelude::Stylize}; use pad::PadStr; -fn table_row (label: &str, artist: &str, album: &str, title: &str) -> String { - format!("{label:60} {artist:20} {album:20} {title:20}") + +fn table_row (label: &str, artist: &str, album: &str, track: &str, title: &str) -> String { + let label = label.pad_to_width(COLUMN_WIDTHS[0] as usize); + let artist = artist.pad_to_width(COLUMN_WIDTHS[1] as usize); + let album = album.pad_to_width(COLUMN_WIDTHS[2] as usize); + let track = track.pad_to_width(COLUMN_WIDTHS[3] as usize); + let title = title.pad_to_width(COLUMN_WIDTHS[4] as usize); + format!("{label}│{artist}╎{album}╎{track}╎{title}") +} +fn status_bar (content: impl Content) -> impl Content { + Fixed::y(1, Fill::x(Tui::bold(true, Tui::fg_bg(Color::Rgb(0,0,0), Color::Rgb(255,255,255), content)))) } impl Content for Taggart { fn content (&self) -> impl Render { let sizer = Fill::xy(&self.size); let size = format!("{}x{}", self.size.w(), self.size.h()); - let size_bar = Fill::x(Align::e(Tui::bold(true, Tui::fg_bg(Color::Rgb(0,0,0), Color::Rgb(255,255,255), size)))); - let titlebar = Fill::x(Align::w(Tui::bold(true, Tui::fg_bg(Color::Rgb(0,0,0), Color::Rgb(255,255,255), table_row("FILE", "ARTIST", "ALBUM", "TITLE"))))); + let size_bar = status_bar(Align::e(size)); + let titlebar = status_bar(Align::w(table_row("FILE", "ARTIST", "RELEASE", "TRACK", "TITLE"))); let table = Fill::xy(TreeTable(self)); Bsp::n(size_bar, Bsp::s(titlebar, Bsp::b(sizer, table))) } @@ -22,7 +31,17 @@ struct TreeTable<'a>(&'a Taggart); impl<'a> Content for TreeTable<'a> { fn render (&self, to: &mut TuiOut) { let area = to.area(); - let Taggart { offset, paths, cursor, .. } = self.0; + let Taggart { offset, paths, cursor, column, .. } = self.0; + let mut x = 0; + for (index, width) in COLUMN_WIDTHS.iter().enumerate() { + let w = COLUMN_WIDTHS[index] + 1; + if index == *column { + to.fill_bg([area.x() + x, area.y(), w, area.h()], Color::Rgb(0, 0, 0)); + break + } else { + x += w; + } + } for (i, y) in area.iter_y().enumerate() { let i_offset = i + offset; let selected = *cursor == i_offset; @@ -33,12 +52,14 @@ impl<'a> Content for TreeTable<'a> { let icon = if entry.is_dir {"+"} else {" "}; let name = fragment.display(); let indent = "".pad_to_width((entry.depth - 1) * 2); - let label = table_row(&format!("{cursor} {indent}{icon} {name}"), "", "", ""); + let label = table_row(&format!("{cursor} {indent}{icon} {name}"), "", "", "", ""); to.blit(&label, area.x(), y, if entry.is_dir { None } else { Some(Style::default().bold()) }); if selected { - to.fill_bg([area.x(), y, area.w(), 1], Color::Rgb(0, 0, 0)); + let fill = [area.x(), y, area.w(), 1]; + to.fill_bg(fill, Color::Rgb(48, 48, 48)); + to.fill_fg(fill, Color::Rgb(224, 192, 0)); } } }