use egui::Color32; use egui_extras::{Column, TableBuilder}; use crate::{manifest::song::SongType, ui::gui::windows::{self, WindowIndex}}; use super::{search_bar::SearchType, ComponentContextMenu, ComponentUi}; mod context_menu; #[derive(Debug, Default)] pub struct SongList; impl ComponentUi for SongList { fn ui(gui: &mut crate::ui::gui::Gui, ui: &mut egui::Ui) { ui.vertical(|ui| { { use crate::ui::gui::components::ComponentUiMut; let mut search = gui.search.clone(); search.ui(gui, ui); gui.search = search; } ui.vertical(|ui| { let available_height = ui.available_height(); let table = TableBuilder::new(ui) .striped(true) .cell_layout(egui::Layout::left_to_right(egui::Align::Center)) .resizable(true) .column(Column::auto()) .column(Column::remainder()) .min_scrolled_height(0.0) .max_scroll_height(available_height) .sense(egui::Sense::click()); let playlists = gui.manifest.get_playlists().clone(); let songs = { let mut songs = Vec::new(); for (pname, p) in playlists { for (sname, s) in p { songs.push((pname.clone(), sname, s)); } } songs.sort_by_key(|song| song.1.to_lowercase()); songs }; table.header(20.0, |mut header| { header.col(|ui| { ui.strong("Source"); }); header.col(|ui| { ui.strong("Name"); }); }).body(|mut body| { for (pname, sname, s) in songs { if pname != gui.current_playlist { continue; } match gui.search.get_search() { (SearchType::Generic, filter) if !filter.is_empty() => { if !pname.to_lowercase().contains(&filter) { continue; } } (SearchType::Song, filter) if !filter.is_empty() => { if !sname.to_lowercase().contains(&filter) { continue; } } (SearchType::Source, filter) if !filter.is_empty() => { if !s.get_type().to_string().to_lowercase().contains(&filter) { continue; } } (SearchType::Url, filter) if !filter.is_empty() => { if !s.get_url_str().contains(&filter) { continue; } } (SearchType::Source, _) => (), (SearchType::Song, _) => (), (SearchType::Generic, _) => (), (SearchType::Url, _) => (), } body.row(18.0, |mut row| { let song_info = context_menu::SongInfo::new(&pname, &sname, &s); row.col(|ui| { let color = match s.get_type() { SongType::Youtube => Color32::from_hex("#FF0000").unwrap(), SongType::Spotify => Color32::from_hex("#1db954").unwrap(), SongType::Soundcloud => Color32::from_hex("#F26F23").unwrap() }; ui.colored_label(color, s.get_type().to_string()) .context_menu(|ui| context_menu::ContextMenu::ui(gui, ui, &song_info)); }); row.col(|ui| { ui.hyperlink_to(sname.clone(), s.get_url_str()) .context_menu(|ui| context_menu::ContextMenu::ui(gui, ui, &song_info)); }); row.response() .context_menu(|ui| context_menu::ContextMenu::ui(gui, ui, &song_info)); }); } }); }); }); check_if_needs_delete(gui); } } fn check_if_needs_delete(gui: &mut crate::ui::gui::Gui) { // Check for items that need to be deleted let (id, resp, data) = gui.windows.get_window::(WindowIndex::Confirm).get_response(); match (id.as_str(), resp) { ("song_list_song_manifest_delete", Some(true)) => { gui.manifest.remove_song(&data[0], &data[1]); let _ = gui.manifest.save(None); gui.windows.get_window::(WindowIndex::Confirm).reset(); } ("song_list_song_manifest_delete", Some(false)) => { log::debug!("FALSE"); gui.windows.get_window::(WindowIndex::Confirm).reset(); } _ => () } }