use egui::RichText; use xmpd_manifest::store::BaseStore; use super::{CompGetter, CompUi}; #[derive(Debug, Default)] pub struct LeftNav { pub selected_playlist_id: Option, } component_register!(LeftNav); impl CompUi for LeftNav { fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> { let w = ui.available_width(); egui::ScrollArea::vertical() .id_source("left_nav") .drag_to_scroll(false) .show(ui, |ui| { ui.vertical(|ui| { let len = state.manifest.store().get_songs().len(); add_playlist_tab(ui, &None, "All Songs", None, len, w); let mut playlists: Vec<_> = state.manifest.store().get_playlists().into_iter().collect(); playlists.sort_by(|a, b| { let a = a.1.name().to_lowercase(); let b = b.1.name().to_lowercase(); a.cmp(&b) }); for (pid, playlist) in playlists.iter() { add_playlist_tab(ui, &Some(**pid), playlist.name(), Some(playlist.author()), playlist.songs().len(), w ); } }); }); Ok(()) } } fn add_playlist_tab(ui: &mut egui::Ui, pid: &Option, title: &str, author: Option<&str>, song_count: usize, width: f32) { let wdg_rect = ui.horizontal(|ui| { ui.set_width(width); ui.add_space(5.0); ui.add( egui::Image::new(crate::data::NOTE_ICON) .tint(crate::data::C_ACCENT) .fit_to_exact_size(egui::Vec2::new(32.0, 32.0)) ); ui.vertical(|ui| { { if handle_error_ui!(LeftNav::get()).selected_playlist_id == *pid { ui.label( RichText::new(title) .size(10.0) .color(crate::data::C_ACCENT) ); } else { ui.label( RichText::new(title) .size(10.0) ); } } if let Some(author) = author { ui.monospace( RichText::new(format!("By {author}")) .color(crate::data::C_TEXT_DIM) .size(8.0) ); } ui.monospace( RichText::new(format!("{song_count} songs")) .color(crate::data::C_TEXT_DIM) .size(8.0) ); }); }).response.rect; if ui.interact(wdg_rect, format!("left_nav_playlist_{pid:?}").into(), egui::Sense::click()).clicked() { handle_error_ui!(LeftNav::get()).selected_playlist_id = pid.clone(); } ui.separator(); }