xmpd/xmpd-gui/src/components/song_list/mod.rs

108 lines
4.9 KiB
Rust

use egui::{Color32, RichText, Vec2};
use song_list_nav::SearchType;
use xmpd_manifest::{query::QueryType, song::Song, store::BaseStore};
use super::{CompGetter, CompUi};
pub mod song_list_nav;
#[derive(Debug, Default)]
pub struct SongList {
selected_song_id: uuid::Uuid
}
component_register!(SongList);
impl CompUi for SongList {
fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
egui::ScrollArea::vertical()
.id_source("song_list")
.drag_to_scroll(false)
.show(ui, |ui| {
ui.vertical(|ui| {
ui.add_space(3.0);
let pid = {handle_error_ui!(super::left_nav::LeftNav::get()).selected_playlist_id.clone()};
match pid {
None => {
let mut songs: Vec<_> = state.manifest.store().get_songs().iter().collect();
songs.sort_by(|a, b| {
let a = a.1.name().to_lowercase();
let b = b.1.name().to_lowercase();
a.cmp(&b)
});
for (sid, song) in songs {
let query = {handle_error_ui!(song_list_nav::SongListNav::get()).parse_search()}.clone();
let should_display = match query {
SearchType::Source(s) if !s.is_empty() => format!("{:?}", &song.source_type()).to_lowercase().contains(&s),
SearchType::Author(s) if !s.is_empty() => song.author().to_lowercase().contains(&s),
SearchType::Name(s) if !s.is_empty() => song.name().to_owned().contains(&s),
_ => true
};
if should_display {
display_song_tab(ui, sid, song);
}
}
}
Some(pid) => {
if let Some(playlist) = state.manifest.store().get_playlist(&pid) {
let mut songs = Vec::new();
for sid in playlist.songs() {
if let Some(song) = state.manifest.store().get_song(&sid) {
songs.push((sid, song));
}
}
songs.sort_by(|a, b| {
let a = a.1.name().to_lowercase();
let b = b.1.name().to_lowercase();
a.cmp(&b)
});
let query = {handle_error_ui!(song_list_nav::SongListNav::get()).parse_search()}.clone();
for (sid, song) in songs {
let should_display = match query {
SearchType::Source(ref s) if !s.is_empty() && format!("{:?}", &song.source_type()).to_lowercase().contains(s) => true,
SearchType::Author(ref s) if !s.is_empty() && song.author().to_lowercase().contains(s) => true,
SearchType::Name(ref s) if !s.is_empty() && song.name().to_owned().contains(s) => true,
_ => false
};
if should_display {
display_song_tab(ui, sid, song);
}
}
}
}
}
});
});
Ok(())
}
}
fn display_song_tab(ui: &mut egui::Ui, sid: &uuid::Uuid, song: &Song) {
let rct = ui.horizontal(|ui| {
ui.add(
egui::Image::new(crate::data::NOTE_ICON)
.tint(crate::data::C_ACCENT)
.fit_to_exact_size(Vec2::new(32.0, 32.0))
);
ui.vertical(|ui| {
let selected_song_id = {handle_error_ui!(SongList::get()).selected_song_id};
if selected_song_id == *sid {
ui.label(RichText::new(song.name()).color(crate::data::C_ACCENT));
} else {
ui.label(song.name());
};
ui.monospace(
RichText::new(format!("By {}", song.author()))
.color(crate::data::C_TEXT_DIM)
.size(10.0)
);
});
}).response.rect;
if ui.interact(rct, format!("song_list_{sid:?}").into(), egui::Sense::click()).clicked() {
handle_error_ui!(SongList::get()).selected_song_id = sid.clone();
}
ui.separator();
}