Make Selection fields private (#154)
All checks were successful
Cargo CI / Build and Test (push) Successful in 1m39s
Cargo CI / Lint (push) Successful in 1m13s
Cargo CI / Build and Test (pull_request) Successful in 1m40s
Cargo CI / Lint (pull_request) Successful in 1m15s

Closes #153

Reviewed-on: #154
This commit is contained in:
Wojciech Kozlowski 2024-03-01 22:31:12 +01:00
parent 42d1edb69c
commit 4dc56f66c6
7 changed files with 140 additions and 110 deletions

View File

@ -113,43 +113,38 @@ mod tests {
fn increment_decrement() { fn increment_decrement() {
let mut browse = AppMachine::browse(inner(music_hoard(COLLECTION.to_owned()))); let mut browse = AppMachine::browse(inner(music_hoard(COLLECTION.to_owned())));
let sel = &browse.inner.selection; let sel = &browse.inner.selection;
assert_eq!(sel.active, Category::Artist); assert_eq!(sel.category(), Category::Artist);
assert_eq!(sel.artist.state.list.selected(), Some(0)); assert_eq!(sel.selected(), Some(0));
browse = browse.increment_selection(Delta::Line).unwrap_browse(); browse = browse.increment_selection(Delta::Line).unwrap_browse();
let sel = &browse.inner.selection; let sel = &browse.inner.selection;
assert_eq!(sel.active, Category::Artist); assert_eq!(sel.category(), Category::Artist);
assert_eq!(sel.artist.state.list.selected(), Some(1)); assert_eq!(sel.selected(), Some(1));
browse = browse.increment_category().unwrap_browse(); browse = browse.increment_category().unwrap_browse();
let sel = &browse.inner.selection; let sel = &browse.inner.selection;
assert_eq!(sel.active, Category::Album); assert_eq!(sel.category(), Category::Album);
assert_eq!(sel.artist.state.list.selected(), Some(1)); assert_eq!(sel.selected(), Some(0));
assert_eq!(sel.artist.album.state.list.selected(), Some(0));
browse = browse.increment_selection(Delta::Line).unwrap_browse(); browse = browse.increment_selection(Delta::Line).unwrap_browse();
let sel = &browse.inner.selection; let sel = &browse.inner.selection;
assert_eq!(sel.active, Category::Album); assert_eq!(sel.category(), Category::Album);
assert_eq!(sel.artist.state.list.selected(), Some(1)); assert_eq!(sel.selected(), Some(1));
assert_eq!(sel.artist.album.state.list.selected(), Some(1));
browse = browse.decrement_selection(Delta::Line).unwrap_browse(); browse = browse.decrement_selection(Delta::Line).unwrap_browse();
let sel = &browse.inner.selection; let sel = &browse.inner.selection;
assert_eq!(sel.active, Category::Album); assert_eq!(sel.category(), Category::Album);
assert_eq!(sel.artist.state.list.selected(), Some(1)); assert_eq!(sel.selected(), Some(0));
assert_eq!(sel.artist.album.state.list.selected(), Some(0));
browse = browse.decrement_category().unwrap_browse(); browse = browse.decrement_category().unwrap_browse();
let sel = &browse.inner.selection; let sel = &browse.inner.selection;
assert_eq!(sel.active, Category::Artist); assert_eq!(sel.category(), Category::Artist);
assert_eq!(sel.artist.state.list.selected(), Some(1)); assert_eq!(sel.selected(), Some(1));
assert_eq!(sel.artist.album.state.list.selected(), Some(0));
browse = browse.decrement_selection(Delta::Line).unwrap_browse(); browse = browse.decrement_selection(Delta::Line).unwrap_browse();
let sel = &browse.inner.selection; let sel = &browse.inner.selection;
assert_eq!(sel.active, Category::Artist); assert_eq!(sel.category(), Category::Artist);
assert_eq!(sel.artist.state.list.selected(), Some(0)); assert_eq!(sel.selected(), Some(0));
assert_eq!(sel.artist.album.state.list.selected(), Some(0));
} }
#[test] #[test]

View File

@ -133,7 +133,7 @@ impl<MH: IMusicHoard> IAppInteractSearchPrivate for AppMachine<MH, AppSearch> {
let search = &self.state.string; let search = &self.state.string;
let sel = &self.inner.selection; let sel = &self.inner.selection;
let result = match sel.active { let result = match sel.category() {
Category::Artist => sel Category::Artist => sel
.state_artist(collection) .state_artist(collection)
.and_then(|state| Self::search_artists(search, next, state)), .and_then(|state| Self::search_artists(search, next, state)),
@ -262,153 +262,156 @@ mod tests {
fn artist_incremental_search() { fn artist_incremental_search() {
// Empty collection. // Empty collection.
let mut search = AppMachine::search(inner(music_hoard(vec![])), orig(None)); let mut search = AppMachine::search(inner(music_hoard(vec![])), orig(None));
assert_eq!(search.inner.selection.artist.state.list.selected(), None); assert_eq!(search.inner.selection.selected(), None);
search.state.string = String::from("album_artist 'a'"); search.state.string = String::from("album_artist 'a'");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), None); assert_eq!(search.inner.selection.selected(), None);
// Basic test, first element. // Basic test, first element.
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from(""); search.state.string = String::from("");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("album_artist "); search.state.string = String::from("album_artist ");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("album_artist 'a'"); search.state.string = String::from("album_artist 'a'");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
// Basic test, non-first element. // Basic test, non-first element.
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("album_artist "); search.state.string = String::from("album_artist ");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("album_artist 'c'"); search.state.string = String::from("album_artist 'c'");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
// Non-lowercase. // Non-lowercase.
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("Album_Artist "); search.state.string = String::from("Album_Artist ");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("Album_Artist 'C'"); search.state.string = String::from("Album_Artist 'C'");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
// Non-ascii. // Non-ascii.
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("album_artist "); search.state.string = String::from("album_artist ");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("album_artist c"); search.state.string = String::from("album_artist c");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
// Non-lowercase, non-ascii. // Non-lowercase, non-ascii.
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("Album_Artist "); search.state.string = String::from("Album_Artist ");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("Album_Artist C"); search.state.string = String::from("Album_Artist C");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
// Stop at name, not sort name. // Stop at name, not sort name.
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("the "); search.state.string = String::from("the ");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
search.state.string = String::from("the album_artist 'c'"); search.state.string = String::from("the album_artist 'c'");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
// Search next with common prefix. // Search next with common prefix.
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.state.string = String::from("album_artist"); search.state.string = String::from("album_artist");
search.incremental_search(false); search.incremental_search(false);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
search.incremental_search(true); search.incremental_search(true);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(1)); assert_eq!(search.inner.selection.selected(), Some(1));
search.incremental_search(true); search.incremental_search(true);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
search.incremental_search(true); search.incremental_search(true);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(3)); assert_eq!(search.inner.selection.selected(), Some(3));
search.incremental_search(true); search.incremental_search(true);
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(3)); assert_eq!(search.inner.selection.selected(), Some(3));
} }
#[test] #[test]
fn album_incremental_search() { fn album_incremental_search() {
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
search.inner.selection.active = Category::Album; search.inner.selection.increment_category();
assert_eq!(search.inner.selection.category(), Category::Album);
let sel = &search.inner.selection; let sel = &search.inner.selection;
assert_eq!(sel.artist.album.state.list.selected(), Some(0)); assert_eq!(sel.selected(), Some(0));
search.state.string = String::from("album_title "); search.state.string = String::from("album_title ");
search.incremental_search(false); search.incremental_search(false);
let sel = &search.inner.selection; let sel = &search.inner.selection;
assert_eq!(sel.artist.album.state.list.selected(), Some(0)); assert_eq!(sel.selected(), Some(0));
let search = search.append_character('a').unwrap_search(); let search = search.append_character('a').unwrap_search();
let search = search.append_character('.').unwrap_search(); let search = search.append_character('.').unwrap_search();
let search = search.append_character('b').unwrap_search(); let search = search.append_character('b').unwrap_search();
let sel = &search.inner.selection; let sel = &search.inner.selection;
assert_eq!(sel.artist.album.state.list.selected(), Some(1)); assert_eq!(sel.selected(), Some(1));
} }
#[test] #[test]
fn track_incremental_search() { fn track_incremental_search() {
let mut search = let mut search =
AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1))); AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(1)));
search.inner.selection.active = Category::Track; search.inner.selection.increment_category();
search.inner.selection.increment_category();
assert_eq!(search.inner.selection.category(), Category::Track);
let sel = &search.inner.selection; let sel = &search.inner.selection;
assert_eq!(sel.artist.album.track.state.list.selected(), Some(0)); assert_eq!(sel.selected(), Some(0));
search.state.string = String::from("track "); search.state.string = String::from("track ");
search.incremental_search(false); search.incremental_search(false);
let sel = &search.inner.selection; let sel = &search.inner.selection;
assert_eq!(sel.artist.album.track.state.list.selected(), Some(0)); assert_eq!(sel.selected(), Some(0));
let search = search.append_character('a').unwrap_search(); let search = search.append_character('a').unwrap_search();
let search = search.append_character('.').unwrap_search(); let search = search.append_character('.').unwrap_search();
@ -417,13 +420,13 @@ mod tests {
let search = search.append_character('2').unwrap_search(); let search = search.append_character('2').unwrap_search();
let sel = &search.inner.selection; let sel = &search.inner.selection;
assert_eq!(sel.artist.album.track.state.list.selected(), Some(1)); assert_eq!(sel.selected(), Some(1));
} }
#[test] #[test]
fn search() { fn search() {
let search = AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(2))); let search = AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(2)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
let search = search.append_character('a').unwrap_search(); let search = search.append_character('a').unwrap_search();
let search = search.append_character('l').unwrap_search(); let search = search.append_character('l').unwrap_search();
@ -438,69 +441,69 @@ mod tests {
let search = search.append_character('s').unwrap_search(); let search = search.append_character('s').unwrap_search();
let search = search.append_character('t').unwrap_search(); let search = search.append_character('t').unwrap_search();
let search = search.append_character(' ').unwrap_search(); let search = search.append_character(' ').unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
let search = search.append_character('\'').unwrap_search(); let search = search.append_character('\'').unwrap_search();
let search = search.append_character('c').unwrap_search(); let search = search.append_character('c').unwrap_search();
let search = search.append_character('\'').unwrap_search(); let search = search.append_character('\'').unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
let search = search.append_character('\'').unwrap_search(); let search = search.append_character('\'').unwrap_search();
let search = search.append_character('b').unwrap_search(); let search = search.append_character('b').unwrap_search();
let search = search.append_character('\'').unwrap_search(); let search = search.append_character('\'').unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(1)); assert_eq!(search.inner.selection.selected(), Some(1));
let app = search.finish_search(); let app = search.finish_search();
let browse = app.unwrap_browse(); let browse = app.unwrap_browse();
assert_eq!(browse.inner.selection.artist.state.list.selected(), Some(1)); assert_eq!(browse.inner.selection.selected(), Some(1));
} }
#[test] #[test]
fn search_next_step_back() { fn search_next_step_back() {
let search = AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(2))); let search = AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(2)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
let search = search.append_character('a').unwrap_search(); let search = search.append_character('a').unwrap_search();
let search = search.search_next().unwrap_search(); let search = search.search_next().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(1)); assert_eq!(search.inner.selection.selected(), Some(1));
let search = search.search_next().unwrap_search(); let search = search.search_next().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
let search = search.search_next().unwrap_search(); let search = search.search_next().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(3)); assert_eq!(search.inner.selection.selected(), Some(3));
let search = search.search_next().unwrap_search(); let search = search.search_next().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(3)); assert_eq!(search.inner.selection.selected(), Some(3));
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(3)); assert_eq!(search.inner.selection.selected(), Some(3));
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(search.inner.selection.selected(), Some(2));
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(1)); assert_eq!(search.inner.selection.selected(), Some(1));
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
} }
#[test] #[test]
fn cancel_search() { fn cancel_search() {
let search = AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(2))); let search = AppMachine::search(inner(music_hoard(COLLECTION.to_owned())), orig(Some(2)));
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(0)); assert_eq!(search.inner.selection.selected(), Some(0));
let search = search.append_character('a').unwrap_search(); let search = search.append_character('a').unwrap_search();
let search = search.append_character('l').unwrap_search(); let search = search.append_character('l').unwrap_search();
@ -518,31 +521,31 @@ mod tests {
let search = search.append_character('\'').unwrap_search(); let search = search.append_character('\'').unwrap_search();
let search = search.append_character('b').unwrap_search(); let search = search.append_character('b').unwrap_search();
let search = search.append_character('\'').unwrap_search(); let search = search.append_character('\'').unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), Some(1)); assert_eq!(search.inner.selection.selected(), Some(1));
let browse = search.cancel_search().unwrap_browse(); let browse = search.cancel_search().unwrap_browse();
assert_eq!(browse.inner.selection.artist.state.list.selected(), Some(2)); assert_eq!(browse.inner.selection.selected(), Some(2));
} }
#[test] #[test]
fn empty_search() { fn empty_search() {
let search = AppMachine::search(inner(music_hoard(vec![])), orig(None)); let search = AppMachine::search(inner(music_hoard(vec![])), orig(None));
assert_eq!(search.inner.selection.artist.state.list.selected(), None); assert_eq!(search.inner.selection.selected(), None);
let search = search.append_character('a').unwrap_search(); let search = search.append_character('a').unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), None); assert_eq!(search.inner.selection.selected(), None);
let search = search.search_next().unwrap_search(); let search = search.search_next().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), None); assert_eq!(search.inner.selection.selected(), None);
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), None); assert_eq!(search.inner.selection.selected(), None);
let search = search.step_back().unwrap_search(); let search = search.step_back().unwrap_search();
assert_eq!(search.inner.selection.artist.state.list.selected(), None); assert_eq!(search.inner.selection.selected(), None);
let browse = search.cancel_search().unwrap_browse(); let browse = search.cancel_search().unwrap_browse();
assert_eq!(browse.inner.selection.artist.state.list.selected(), None); assert_eq!(browse.inner.selection.selected(), None);
} }
#[test] #[test]

View File

@ -96,6 +96,14 @@ impl AlbumSelection {
selected.and_then(|index| self.track.selection_state(&albums[index].tracks)) selected.and_then(|index| self.track.selection_state(&albums[index].tracks))
} }
pub fn widget_state(&mut self) -> &mut WidgetState {
&mut self.state
}
pub fn widget_state_track(&mut self) -> &mut WidgetState {
self.track.widget_state()
}
pub fn reset(&mut self, albums: &[Album]) { pub fn reset(&mut self, albums: &[Album]) {
if self.state.list.selected() != Some(0) { if self.state.list.selected() != Some(0) {
self.reinitialise(albums, None); self.reinitialise(albums, None);

View File

@ -113,6 +113,18 @@ impl ArtistSelection {
selected.and_then(|index| self.album.state_tracks(&artists[index].albums)) selected.and_then(|index| self.album.state_tracks(&artists[index].albums))
} }
pub fn widget_state(&mut self) -> &mut WidgetState {
&mut self.state
}
pub fn widget_state_album(&mut self) -> &mut WidgetState {
self.album.widget_state()
}
pub fn widget_state_track(&mut self) -> &mut WidgetState {
self.album.widget_state_track()
}
pub fn reset(&mut self, artists: &[Artist]) { pub fn reset(&mut self, artists: &[Artist]) {
if self.state.list.selected() != Some(0) { if self.state.list.selected() != Some(0) {
self.reinitialise(artists, None); self.reinitialise(artists, None);

View File

@ -14,6 +14,16 @@ pub enum Category {
Track, Track,
} }
pub struct Selection {
active: Category,
artist: ArtistSelection,
}
pub struct SelectionState<'a, T> {
pub list: &'a [T],
pub index: usize,
}
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct WidgetState { pub struct WidgetState {
pub list: ListState, pub list: ListState,
@ -26,16 +36,6 @@ impl PartialEq for WidgetState {
} }
} }
pub struct Selection {
pub active: Category,
pub artist: ArtistSelection,
}
pub struct SelectionState<'a, T> {
pub list: &'a [T],
pub index: usize,
}
pub enum Delta { pub enum Delta {
Line, Line,
Page, Page,
@ -104,6 +104,10 @@ impl Selection {
self.artist.select_track(artists, index); self.artist.select_track(artists, index);
} }
pub fn category(&self) -> Category {
self.active
}
pub fn selected(&self) -> Option<usize> { pub fn selected(&self) -> Option<usize> {
match self.active { match self.active {
Category::Artist => self.selected_artist(), Category::Artist => self.selected_artist(),
@ -136,6 +140,18 @@ impl Selection {
self.artist.state_track(coll) self.artist.state_track(coll)
} }
pub fn widget_state_artist(&mut self) -> &mut WidgetState {
self.artist.widget_state()
}
pub fn widget_state_album(&mut self) -> &mut WidgetState {
self.artist.widget_state_album()
}
pub fn widget_state_track(&mut self) -> &mut WidgetState {
self.artist.widget_state_track()
}
pub fn reset(&mut self, collection: &Collection) { pub fn reset(&mut self, collection: &Collection) {
match self.active { match self.active {
Category::Artist => self.reset_artist(collection), Category::Artist => self.reset_artist(collection),

View File

@ -60,6 +60,10 @@ impl TrackSelection {
selected.map(|index| SelectionState { list, index }) selected.map(|index| SelectionState { list, index })
} }
pub fn widget_state(&mut self) -> &mut WidgetState {
&mut self.state
}
pub fn reset(&mut self, tracks: &[Track]) { pub fn reset(&mut self, tracks: &[Track]) {
if self.state.list.selected() != Some(0) { if self.state.list.selected() != Some(0) {
self.reinitialise(tracks, None); self.reinitialise(tracks, None);

View File

@ -590,46 +590,39 @@ impl Ui {
state: &AppPublicState, state: &AppPublicState,
frame: &mut Frame, frame: &mut Frame,
) { ) {
let active = selection.active; let active = selection.category();
let areas = FrameArea::new(frame.size()); let areas = FrameArea::new(frame.size());
let artist_selection = &mut selection.artist;
let artist_state = ArtistState::new( let artist_state = ArtistState::new(
active == Category::Artist, active == Category::Artist,
artists, artists,
&mut artist_selection.state, selection.widget_state_artist(),
); );
Self::render_artist_column(artist_state, areas.artist, frame); Self::render_artist_column(artist_state, areas.artist, frame);
let no_albums: Vec<Album> = vec![]; let no_albums: Vec<Album> = vec![];
let albums = artist_selection let albums = selection
.state .state_album(artists)
.list .map(|st| st.list)
.selected()
.map(|i| &artists[i].albums)
.unwrap_or_else(|| &no_albums); .unwrap_or_else(|| &no_albums);
let album_selection = &mut artist_selection.album;
let album_state = AlbumState::new( let album_state = AlbumState::new(
active == Category::Album, active == Category::Album,
albums, albums,
&mut album_selection.state, selection.widget_state_album(),
); );
Self::render_album_column(album_state, areas.album, frame); Self::render_album_column(album_state, areas.album, frame);
let no_tracks: Vec<Track> = vec![]; let no_tracks: Vec<Track> = vec![];
let tracks = album_selection let tracks = selection
.state .state_track(artists)
.list .map(|st| st.list)
.selected()
.map(|i| &albums[i].tracks)
.unwrap_or_else(|| &no_tracks); .unwrap_or_else(|| &no_tracks);
let track_selection = &mut album_selection.track;
let track_state = TrackState::new( let track_state = TrackState::new(
active == Category::Track, active == Category::Track,
tracks, tracks,
&mut track_selection.state, selection.widget_state_track(),
); );
Self::render_track_column(track_state, areas.track, frame); Self::render_track_column(track_state, areas.track, frame);
@ -640,8 +633,7 @@ impl Ui {
fn render_info_overlay(artists: &Collection, selection: &mut Selection, frame: &mut Frame) { fn render_info_overlay(artists: &Collection, selection: &mut Selection, frame: &mut Frame) {
let area = OverlayBuilder::default().build(frame.size()); let area = OverlayBuilder::default().build(frame.size());
let artist_selection = &mut selection.artist; let artist_overlay = ArtistOverlay::new(artists, &selection.widget_state_artist().list);
let artist_overlay = ArtistOverlay::new(artists, &artist_selection.state.list);
Self::render_overlay_widget("Artist", artist_overlay.properties, area, false, frame); Self::render_overlay_widget("Artist", artist_overlay.properties, area, false, frame);
} }