use egui::{CursorIcon, RichText, Sense, TextBuffer}; use xmpd_manifest::store::{BaseStore, StoreExtras}; use crate::utils::SearchType; use super::{CompGetter, CompUi}; pub mod header; #[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 playlists = state.manifest.store().get_playlists_sorted(); let search_text = handle_error_ui!(header::Header::get()).search_text.clone(); let (qtyp, qtxt) = crate::utils::SearchType::from_str(&search_text); for (pid, playlist) in playlists.iter() { match qtyp { _ if qtxt.is_empty() => (), SearchType::Normal if playlist.name().to_lowercase().contains(&qtxt) => (), SearchType::Author if playlist.author().to_lowercase().contains(&qtxt) => (), _ => continue } 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) { if pid.is_some() { ui.separator(); } let theme = &handle_error_ui!(xmpd_settings::Settings::get()).theme; 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(theme.accent_color) .sense(Sense::click()) .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(theme.accent_color) ); } else { ui.label( RichText::new(title) .color(theme.text_color) .size(10.0) ); } } if let Some(author) = author { ui.monospace( RichText::new(format!("By {author}")) .color(theme.dim_text_color) .size(8.0) ); } ui.monospace( RichText::new(format!("{song_count} songs")) .color(theme.dim_text_color) .size(8.0) ); }); }).response.rect; let blob = ui.interact(wdg_rect, format!("left_nav_playlist_{pid:?}").into(), egui::Sense::click()); if blob.clicked() { handle_error_ui!(LeftNav::get()).selected_playlist_id = pid.clone(); } if blob.hovered() { ui.output_mut(|o| o.cursor_icon = CursorIcon::PointingHand); } }