Extend incremental search to albums and tracks #152
@ -109,14 +109,14 @@ impl<MH: IMusicHoard> IAppInteractSearch for AppMachine<MH, AppSearch> {
|
||||
|
||||
trait IAppInteractSearchPrivate {
|
||||
fn incremental_search(&mut self, next: bool);
|
||||
fn search_category<T, P>(
|
||||
state: SelectionState<'_, T>,
|
||||
search_name: &str,
|
||||
next: bool,
|
||||
predicate: P,
|
||||
) -> Option<usize>
|
||||
fn next<P, T>(pred: P, name: &str, next: bool, st: SelectionState<'_, T>) -> Option<usize>
|
||||
where
|
||||
P: FnMut(bool, bool, &str, &T) -> bool;
|
||||
|
||||
fn search_artists(name: &str, next: bool, st: SelectionState<'_, Artist>) -> Option<usize>;
|
||||
fn search_albums(name: &str, next: bool, st: SelectionState<'_, Album>) -> Option<usize>;
|
||||
fn search_tracks(name: &str, next: bool, st: SelectionState<'_, Track>) -> Option<usize>;
|
||||
|
||||
fn predicate_artists(case_sens: bool, char_sens: bool, search: &str, probe: &Artist) -> bool;
|
||||
fn predicate_albums(case_sens: bool, char_sens: bool, search: &str, probe: &Album) -> bool;
|
||||
fn predicate_tracks(case_sens: bool, char_sens: bool, search: &str, probe: &Track) -> bool;
|
||||
@ -132,46 +132,54 @@ impl<MH: IMusicHoard> IAppInteractSearchPrivate for AppMachine<MH, AppSearch> {
|
||||
let collection = self.inner.music_hoard.get_collection();
|
||||
let search = &self.state.string;
|
||||
|
||||
let sel = &mut self.inner.selection;
|
||||
let sel = &self.inner.selection;
|
||||
let result = match sel.active {
|
||||
Category::Artist => sel.state_artist(collection).and_then(|state| {
|
||||
Self::search_category(state, search, next, Self::predicate_artists)
|
||||
}),
|
||||
Category::Album => sel.state_album(collection).and_then(|state| {
|
||||
Self::search_category(state, search, next, Self::predicate_albums)
|
||||
}),
|
||||
Category::Track => sel.state_track(collection).and_then(|state| {
|
||||
Self::search_category(state, search, next, Self::predicate_tracks)
|
||||
}),
|
||||
Category::Artist => sel
|
||||
.state_artist(collection)
|
||||
.and_then(|state| Self::search_artists(search, next, state)),
|
||||
Category::Album => sel
|
||||
.state_album(collection)
|
||||
.and_then(|state| Self::search_albums(search, next, state)),
|
||||
Category::Track => sel
|
||||
.state_track(collection)
|
||||
.and_then(|state| Self::search_tracks(search, next, state)),
|
||||
};
|
||||
|
||||
if result.is_some() {
|
||||
sel.select(collection, result);
|
||||
let collection = self.inner.music_hoard.get_collection();
|
||||
self.inner.selection.select(collection, result);
|
||||
}
|
||||
}
|
||||
|
||||
fn search_category<T, P>(
|
||||
state: SelectionState<'_, T>,
|
||||
search_name: &str,
|
||||
next: bool,
|
||||
mut predicate: P,
|
||||
) -> Option<usize>
|
||||
fn search_artists(name: &str, next: bool, st: SelectionState<'_, Artist>) -> Option<usize> {
|
||||
Self::next(Self::predicate_artists, name, next, st)
|
||||
}
|
||||
|
||||
fn search_albums(name: &str, next: bool, st: SelectionState<'_, Album>) -> Option<usize> {
|
||||
Self::next(Self::predicate_albums, name, next, st)
|
||||
}
|
||||
|
||||
fn search_tracks(name: &str, next: bool, st: SelectionState<'_, Track>) -> Option<usize> {
|
||||
Self::next(Self::predicate_tracks, name, next, st)
|
||||
}
|
||||
|
||||
fn next<P, T>(mut pred: P, name: &str, next: bool, st: SelectionState<'_, T>) -> Option<usize>
|
||||
where
|
||||
P: FnMut(bool, bool, &str, &T) -> bool,
|
||||
{
|
||||
let case_sens = Self::is_case_sensitive(search_name);
|
||||
let char_sens = Self::is_char_sensitive(search_name);
|
||||
let search = Self::normalize_search(search_name, !case_sens, !char_sens);
|
||||
let case_sens = Self::is_case_sensitive(name);
|
||||
let char_sens = Self::is_char_sensitive(name);
|
||||
let search = Self::normalize_search(name, !case_sens, !char_sens);
|
||||
|
||||
let mut index = state.index;
|
||||
if next && ((index + 1) < state.list.len()) {
|
||||
let mut index = st.index;
|
||||
if next && ((index + 1) < st.list.len()) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
let slice = &state.list[index..];
|
||||
let slice = &st.list[index..];
|
||||
slice
|
||||
.iter()
|
||||
.position(|probe| predicate(case_sens, char_sens, &search, probe))
|
||||
.position(|probe| pred(case_sens, char_sens, &search, probe))
|
||||
.map(|slice_index| index + slice_index)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user