From 2ebf2c6cefa44a1f357f49289c93f26fb0c95f57 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 23 Mar 2025 22:05:54 +0200 Subject: [PATCH] add year column --- src/model/column.rs | 73 +++++++++++++------------------------------ src/model/entry.rs | 6 ++++ src/model/metadata.rs | 19 +++++++++-- src/view.rs | 2 +- src/view/table.rs | 8 +++-- 5 files changed, 52 insertions(+), 56 deletions(-) diff --git a/src/model/column.rs b/src/model/column.rs index 28383d1..fc105f2 100644 --- a/src/model/column.rs +++ b/src/model/column.rs @@ -30,60 +30,31 @@ impl ColumnOption>, fn(&mut [T], usize, &str)> { } } +macro_rules! setter { + ($method:ident) => { + |entries: &mut [Entry], index: usize, value: &str|{ + if let Some(entries) = paths_under(entries, index) { + for entry in entries.iter() { + entry.write().unwrap().$method(&value); + } + } else if let Some(entry) = entries.get_mut(index) { + entry.$method(&value) + } + } + } +} + impl Default for ColumnsOption>, fn(&mut [Entry], usize, &str)> { fn default () -> Self { Self(vec![ - - Column::new(&"HASH", 8, |entry: &Entry|entry.hash()), - - Column::new(&"SIZE", 8, |entry: &Entry|entry.size()), - - Column::new(&"FILE", 80, |entry: &Entry|entry.name()), - - Column::new(&"ARTIST", 30, |entry: &Entry|entry.artist()) - .setter(|entries: &mut [Entry], index: usize, value: &str|{ - if let Some(entries) = paths_under(entries, index) { - for entry in entries.iter() { - entry.write().unwrap().set_artist(&value); - } - } else if let Some(entry) = entries.get_mut(index) { - entry.set_artist(&value) - } - }), - - Column::new(&"RELEASE", 30, |entry: &Entry|entry.album()) - .setter(|entries: &mut [Entry], index: usize, value: &str|{ - if let Some(entries) = paths_under(entries, index) { - for entry in entries.iter() { - entry.write().unwrap().set_album(&value); - } - } else if let Some(entry) = entries.get_mut(index) { - entry.set_album(&value) - } - }), - - Column::new(&"TRACK", 5, |entry: &Entry|entry.track()) - .setter(|entries: &mut [Entry], index: usize, value: &str|{ - if let Some(entries) = paths_under(entries, index) { - for entry in entries.iter() { - entry.write().unwrap().set_track(&value); - } - } else if let Some(entry) = entries.get_mut(index) { - entry.set_track(&value) - } - }), - - Column::new(&"TITLE", 80, |entry: &Entry|entry.title()) - .setter(|entries: &mut [Entry], index: usize, value: &str|{ - if let Some(entries) = paths_under(entries, index) { - for entry in entries.iter() { - entry.write().unwrap().set_title(&value); - } - } else if let Some(entry) = entries.get_mut(index) { - entry.set_title(&value) - } - }), - + Column::new(&"HASH", 8, |entry: &Entry|entry.hash()), + Column::new(&"SIZE", 8, |entry: &Entry|entry.size()), + Column::new(&"FILE", 80, |entry: &Entry|entry.name()), + Column::new(&"ARTIST", 30, |entry: &Entry|entry.artist()).setter(setter!(set_artist)), + Column::new(&"YEAR", 5, |entry: &Entry|entry.year()).setter(setter!(set_year)), + Column::new(&"RELEASE", 30, |entry: &Entry|entry.album()).setter(setter!(set_album)), + Column::new(&"TRACK", 5, |entry: &Entry|entry.track()).setter(setter!(set_track)), + Column::new(&"TITLE", 80, |entry: &Entry|entry.title()).setter(setter!(set_title)), ]) } } diff --git a/src/model/entry.rs b/src/model/entry.rs index 974d6cd..3c04021 100644 --- a/src/model/entry.rs +++ b/src/model/entry.rs @@ -56,6 +56,9 @@ impl Entry { pub fn artist (&self) -> Option> { self.info.read().unwrap().artist() } + pub fn year (&self) -> Option> { + self.info.read().unwrap().year() + } pub fn album (&self) -> Option> { self.info.read().unwrap().album() } @@ -68,6 +71,9 @@ impl Entry { pub fn set_artist (&self, value: &impl AsRef ) { self.info.write().unwrap().set_artist(value) } + pub fn set_year (&self, value: &impl AsRef ) { + self.info.write().unwrap().set_year(value) + } pub fn set_album (&self, value: &impl AsRef ) { self.info.write().unwrap().set_album(value) } diff --git a/src/model/metadata.rs b/src/model/metadata.rs index cae2ee3..3d7e409 100644 --- a/src/model/metadata.rs +++ b/src/model/metadata.rs @@ -135,6 +135,12 @@ impl Metadata { _ => None } } + pub fn year (&self) -> Option> { + match self { + Metadata::Music { year, .. } => year.map(|t|format!("{t}").into()).clone(), + _ => None + } + } pub fn album (&self) -> Option> { match self { Metadata::Music { album, .. } => album.clone(), @@ -159,6 +165,16 @@ impl Metadata { _ => {} } } + pub fn set_year (&mut self, value: &impl AsRef ) { + match self { + Metadata::Music { year, .. } => { + if let Ok(value) = value.as_ref().trim().parse::() { + *year = Some(value) + } + }, + _ => {} + } + } pub fn set_album (&mut self, value: &impl AsRef ) { match self { Metadata::Music { album, .. } => *album = Some(value.as_ref().into()), @@ -171,9 +187,8 @@ impl Metadata { _ => {} } } - pub fn set_track (&mut self, value: &impl AsRef ) { + pub fn set_track (&mut self, value: &impl AsRef) { match self { - Metadata::Directory { .. } => todo!("set track for whole directory"), Metadata::Music { track, .. } => { if let Ok(value) = value.as_ref().trim().parse::() { *track = Some(value) diff --git a/src/view.rs b/src/view.rs index ae4080c..29479bc 100644 --- a/src/view.rs +++ b/src/view.rs @@ -26,7 +26,7 @@ impl Content for Taggart { } else { Bsp::e( Tui::bg(Self::BG_BROWSE, Tui::fg(Self::FG_BROWSE, " BROWSE ")), - " Q: exit, Arrows: select, Enter: edit" + " Q: exit, Arrows: select, Space: open, Enter: edit" ) }))), Fill::x(Align::e(size)), diff --git a/src/view/table.rs b/src/view/table.rs index 5237284..537aff3 100644 --- a/src/view/table.rs +++ b/src/view/table.rs @@ -18,6 +18,7 @@ impl<'a> TreeTable<'a> { pub(crate) const FG_ROW: Color = Color::Rgb(0, 0, 0); pub(crate) const BG_ROW: Color = Color::Rgb(192, 128, 0); pub(crate) const BG_CELL: Color = Color::Rgb(224, 192, 0); + pub(crate) const FG_CELL: Color = Color::Rgb(255, 255, 255); pub(crate) const BG_EDIT: Color = Color::Rgb(48, 96, 0); pub(crate) const FG_EDIT: Color = Color::Rgb(255, 255, 255); fn rows (&self, to: &mut TuiOut, area: [u16;4], active_x: u16, active_w: u16) { @@ -54,7 +55,7 @@ impl<'a> TreeTable<'a> { let fill = [xa + x0, y, w, 1]; to.fill_bg(fill, Self::BG_CELL); } - fn row_data (&self, to: &mut TuiOut, entry: &Entry, row: usize, x: &mut u16) { + fn row_data (&self, to: &mut TuiOut, entry: &Entry, cursor: usize, x: &mut u16) { let y = to.area().y(); for (column_index, Column { width, @@ -64,7 +65,7 @@ impl<'a> TreeTable<'a> { to.area[0] = *x; if let Some((edit_index, value)) = self.0.editing.as_ref() && self.0.column == column_index - && self.0.cursor == row + && self.0.cursor == cursor { to.fill_bg([*x, y, *width as u16, 1], Self::BG_EDIT); to.fill_fg([*x, y, *width as u16, 1], Self::FG_EDIT); @@ -72,6 +73,9 @@ impl<'a> TreeTable<'a> { Content::render(&TrimStringRef(*width as u16, &value), to); } else if let Some(value) = getter(entry) { Content::render(&TrimStringRef(*width as u16, &value), to); + if self.0.cursor != cursor { + to.fill_fg([*x, y, *width as u16, 1], Self::FG_CELL); + } } *x += *width as u16 + 1; to.blit(&"│", *x - 1, y, None);