diff --git a/src/tui/ui.rs b/src/tui/ui.rs index cfef7b3..24a1037 100644 --- a/src/tui/ui.rs +++ b/src/tui/ui.rs @@ -1,6 +1,6 @@ use musichoard::{ collection::{Collection, CollectionManager}, - Album, AlbumId, Artist, Track, TrackFormat, + Album, Artist, Track, TrackFormat, }; use ratatui::{ backend::Backend, @@ -37,10 +37,6 @@ impl TrackSelection { TrackSelection { selection } } - fn selection(&mut self) -> &mut ListState { - &mut self.selection - } - fn increment(&mut self, tracks: &[Track]) { if let Some(index) = self.selection.selected() { if let Some(result) = index.checked_add(1) { @@ -74,14 +70,6 @@ impl AlbumSelection { AlbumSelection { selection, track } } - fn selection(&mut self) -> &mut ListState { - &mut self.selection - } - - fn track_selection(&mut self) -> &mut ListState { - self.track.selection() - } - fn increment(&mut self, albums: &[Album]) { if let Some(index) = self.selection.selected() { if let Some(result) = index.checked_add(1) { @@ -129,18 +117,6 @@ impl ArtistSelection { ArtistSelection { selection, album } } - fn selection(&mut self) -> &mut ListState { - &mut self.selection - } - - fn album_selection(&mut self) -> &mut ListState { - self.album.selection() - } - - fn track_selection(&mut self) -> &mut ListState { - self.album.track_selection() - } - fn increment(&mut self, artists: &[Artist]) { if let Some(index) = self.selection.selected() { if let Some(result) = index.checked_add(1) { @@ -206,18 +182,6 @@ impl Selection { } } - fn artist_selection(&mut self) -> &mut ListState { - self.artist.selection() - } - - fn album_selection(&mut self) -> &mut ListState { - self.artist.album_selection() - } - - fn track_selection(&mut self) -> &mut ListState { - self.artist.track_selection() - } - fn increment_category(&mut self) { self.active = match self.active { Category::Artist => Category::Album, @@ -283,11 +247,13 @@ pub struct MhUi { struct ArtistArea { list: Rect, + album: AlbumArea, } struct AlbumArea { list: Rect, info: Rect, + track: TrackArea, } struct TrackArea { @@ -295,32 +261,18 @@ struct TrackArea { info: Rect, } -struct FrameAreas { - artists: ArtistArea, - albums: AlbumArea, - tracks: TrackArea, -} - -struct SelectionList<'a> { - list: List<'a>, - state: &'a mut ListState, -} - struct ArtistState<'a> { - list: SelectionList<'a>, - active: bool, + list: List<'a>, } struct AlbumState<'a> { - list: SelectionList<'a>, + list: List<'a>, info: Paragraph<'a>, - active: bool, } struct TrackState<'a> { - list: SelectionList<'a>, + list: List<'a>, info: Paragraph<'a>, - active: bool, } impl MhUi { @@ -334,7 +286,7 @@ impl MhUi { }) } - fn construct_areas(frame: Rect) -> FrameAreas { + fn construct_areas(frame: Rect) -> ArtistArea { let width_one_third = frame.width / 3; let height_one_third = frame.height / 3; @@ -378,21 +330,20 @@ impl MhUi { height: panel_height_bottom, }; - FrameAreas { - artists: ArtistArea { list: artist_list }, - albums: AlbumArea { + ArtistArea { + list: artist_list, + album: AlbumArea { list: album_list, info: album_info, - }, - tracks: TrackArea { - list: track_list, - info: track_info, + track: TrackArea { + list: track_list, + info: track_info, + }, }, } } - fn construct_artist_state(&mut self) -> ArtistState { - let artists = self.collection_manager.get_collection(); + fn construct_artist_state(artists: &[Artist]) -> ArtistState { let list = List::new( artists .iter() @@ -400,69 +351,31 @@ impl MhUi { .collect::>(), ); - let active = self.selection.active == Category::Artist; - let state = self.selection.artist_selection(); - - ArtistState { - list: SelectionList { list, state }, - active, - } + ArtistState { list } } - fn construct_album_state(&mut self) -> AlbumState { - let albums: Vec<&AlbumId> = - if let Some(artist_index) = self.selection.artist.selection.selected() { - self.collection_manager.get_collection()[artist_index] - .albums - .iter() - .map(|a| &a.id) - .collect() - } else { - vec![] - }; - + fn construct_album_state(albums: &[Album], selected: Option) -> AlbumState { let list = List::new( albums .iter() - .map(|id| ListItem::new(id.title.as_str())) + .map(|a| ListItem::new(a.id.title.as_str())) .collect::>(), ); - let active = self.selection.active == Category::Album; - let state = self.selection.album_selection(); - - let album = state.selected().map(|i| albums[i]); + let album = selected.map(|i| &albums[i]); let info = Paragraph::new(format!( "Title: {}\n\ Year: {}", - album.map(|a| a.title.as_str()).unwrap_or(""), + album.map(|a| a.id.title.as_str()).unwrap_or(""), album - .map(|a| a.year.to_string()) + .map(|a| a.id.year.to_string()) .unwrap_or_else(|| "".to_string()), )); - AlbumState { - list: SelectionList { list, state }, - info, - active, - } + AlbumState { list, info } } - fn construct_track_state(&mut self) -> TrackState { - let tracks: Vec<&Track> = - if let Some(artist_index) = self.selection.artist.selection.selected() { - if let Some(album_index) = self.selection.artist.album.selection.selected() { - self.collection_manager.get_collection()[artist_index].albums[album_index] - .tracks - .iter() - .collect() - } else { - vec![] - } - } else { - vec![] - }; - + fn construct_track_state(tracks: &[Track], selected: Option) -> TrackState { let list = List::new( tracks .iter() @@ -470,10 +383,7 @@ impl MhUi { .collect::>(), ); - let active = self.selection.active == Category::Track; - let state = self.selection.track_selection(); - - let track = state.selected().map(|i| tracks[i]); + let track = selected.map(|i| &tracks[i]); let info = Paragraph::new(format!( "Track: {}\n\ Title: {}\n\ @@ -494,11 +404,7 @@ impl MhUi { .unwrap_or(""), )); - TrackState { - list: SelectionList { list, state }, - info, - active, - } + TrackState { list, info } } fn style(_active: bool) -> Style { @@ -528,19 +434,19 @@ impl MhUi { fn render_list_widget( title: &str, - mut list: SelectionList, + list: List, + list_state: &mut ListState, active: bool, area: Rect, frame: &mut Frame<'_, B>, ) { frame.render_stateful_widget( - list.list - .highlight_style(Self::highlight_style(active)) + list.highlight_style(Self::highlight_style(active)) .highlight_symbol(">> ") .style(Self::style(active)) .block(Self::block(title, active)), area, - &mut list.state, + list_state, ); } @@ -559,21 +465,98 @@ impl MhUi { ); } - fn render_artist_column(&mut self, area: ArtistArea, frame: &mut Frame<'_, B>) { - let state = self.construct_artist_state(); - Self::render_list_widget("Artists", state.list, state.active, area.list, frame); + fn render_artist_column( + artists: &[Artist], + category: Category, + selection: &mut ArtistSelection, + area: ArtistArea, + frame: &mut Frame<'_, B>, + ) { + let state = Self::construct_artist_state(artists); + Self::render_list_widget( + "Artists", + state.list, + &mut selection.selection, + category == Category::Artist, + area.list, + frame, + ); + + let empty_vec: Vec = vec![]; + Self::render_album_column( + if let Some(artist_index) = selection.selection.selected() { + &artists[artist_index].albums + } else { + &empty_vec + }, + category, + &mut selection.album, + area.album, + frame, + ); } - fn render_album_column(&mut self, area: AlbumArea, frame: &mut Frame<'_, B>) { - let state = self.construct_album_state(); - Self::render_list_widget("Albums", state.list, state.active, area.list, frame); - Self::render_info_widget("Album info", state.info, state.active, area.info, frame); + fn render_album_column( + albums: &[Album], + category: Category, + selection: &mut AlbumSelection, + area: AlbumArea, + frame: &mut Frame<'_, B>, + ) { + let state = Self::construct_album_state(albums, selection.selection.selected()); + Self::render_list_widget( + "Albums", + state.list, + &mut selection.selection, + category == Category::Album, + area.list, + frame, + ); + Self::render_info_widget( + "Album info", + state.info, + category == Category::Album, + area.info, + frame, + ); + + let empty_vec: Vec = vec![]; + Self::render_track_column( + if let Some(album_index) = selection.selection.selected() { + &albums[album_index].tracks + } else { + &empty_vec + }, + category, + &mut selection.track, + area.track, + frame, + ); } - fn render_track_column(&mut self, area: TrackArea, frame: &mut Frame<'_, B>) { - let state = self.construct_track_state(); - Self::render_list_widget("Tracks", state.list, state.active, area.list, frame); - Self::render_info_widget("Track info", state.info, state.active, area.info, frame); + fn render_track_column( + tracks: &[Track], + category: Category, + selection: &mut TrackSelection, + area: TrackArea, + frame: &mut Frame<'_, B>, + ) { + let state = Self::construct_track_state(tracks, selection.selection.selected()); + Self::render_list_widget( + "Tracks", + state.list, + &mut selection.selection, + category == Category::Track, + area.list, + frame, + ); + Self::render_info_widget( + "Track info", + state.info, + category == Category::Track, + area.info, + frame, + ); } } @@ -620,9 +603,13 @@ impl Ui for MhUi { fn render(&mut self, frame: &mut Frame<'_, B>) { let areas = Self::construct_areas(frame.size()); - self.render_artist_column(areas.artists, frame); - self.render_album_column(areas.albums, frame); - self.render_track_column(areas.tracks, frame); + Self::render_artist_column( + self.collection_manager.get_collection(), + self.selection.active, + &mut self.selection.artist, + areas, + frame, + ); } }