Modularised components, moved everythign there
This commit is contained in:
		
							parent
							
								
									2cde24e7a8
								
							
						
					
					
						commit
						f26fd97809
					
				
							
								
								
									
										57
									
								
								src/ui/gui/components/context_menu.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/ui/gui/components/context_menu.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
use egui::{Color32, RichText};
 | 
			
		||||
use crate::{manifest::song::Song, ui::gui::windows::{song_edit::GuiSongEditor, WindowIndex}};
 | 
			
		||||
 | 
			
		||||
pub struct ContextMenu;
 | 
			
		||||
 | 
			
		||||
// NOTE: This should be a component but theres no easy way to do that, so we just make it folow the
 | 
			
		||||
// trait manually, ish, more like a convention
 | 
			
		||||
impl /* ComponentUi for */ ContextMenu {
 | 
			
		||||
    pub fn ui(gui: &mut crate::ui::gui::Gui, ui: &mut egui::Ui, pname: &String, sname: &String, song: &Song) {
 | 
			
		||||
        if ui.button("Edit").clicked() {
 | 
			
		||||
            let w = gui.windows.get_window::<GuiSongEditor>(WindowIndex::SongEdit);
 | 
			
		||||
            w.set_active_song(pname, sname, song.get_url_str());
 | 
			
		||||
            gui.windows.open(WindowIndex::SongEdit, true);
 | 
			
		||||
            ui.close_menu()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ui.button("Download").clicked() {
 | 
			
		||||
            if let Err(e) = gui.downloader.download_song_nb(&gui.cfg, pname, sname, song, gui.manifest.get_format()) {
 | 
			
		||||
                log::error!("{e}");
 | 
			
		||||
                gui.throw_error(format!("Failed to download song {sname}: {e}"));
 | 
			
		||||
            }
 | 
			
		||||
            ui.close_menu()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ui.button("Open Source").clicked() {
 | 
			
		||||
            if let Err(e) = open::that(song.get_url_str()) {
 | 
			
		||||
                log::error!("{e}");
 | 
			
		||||
                gui.throw_error(format!("Failed to open song source: {e}"));
 | 
			
		||||
            }
 | 
			
		||||
            ui.close_menu()
 | 
			
		||||
        }
 | 
			
		||||
        if ui.button("Play").clicked() {
 | 
			
		||||
            let p = crate::util::get_song_path(pname, sname, gui.manifest.get_format());
 | 
			
		||||
            
 | 
			
		||||
            if !p.exists() {
 | 
			
		||||
               gui.throw_error(format!("Song does not exist on disk")); 
 | 
			
		||||
            } else if let Err(e) = open::that(p) {
 | 
			
		||||
                log::error!("{e}");
 | 
			
		||||
                gui.throw_error(format!("Failed to play song: {e}"));
 | 
			
		||||
            }
 | 
			
		||||
            ui.close_menu()
 | 
			
		||||
        }
 | 
			
		||||
        if ui.button("Delete from disk").clicked() {
 | 
			
		||||
            let p = crate::util::get_song_path(pname, sname, gui.manifest.get_format());
 | 
			
		||||
            if p.exists() {
 | 
			
		||||
                if let Err(e) = std::fs::remove_file(p) {
 | 
			
		||||
                    gui.throw_error(format!("Failed to delete file: {e}"));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            ui.close_menu();
 | 
			
		||||
        }
 | 
			
		||||
        if ui.button(RichText::new("Delete").color(Color32::RED)).clicked() {
 | 
			
		||||
            gui.throw_error("TODO");
 | 
			
		||||
            ui.close_menu()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
use super::Gui;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub mod nav;
 | 
			
		||||
pub mod song_list;
 | 
			
		||||
pub mod context_menu;
 | 
			
		||||
 | 
			
		||||
pub trait Component {
 | 
			
		||||
    fn ui(gui: &mut Gui, ctx: &egui::Context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait ComponentUi {
 | 
			
		||||
    fn ui(gui: &mut Gui, ui: &mut egui::Ui);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,13 @@
 | 
			
		|||
use super::{windows::WindowIndex, Gui};
 | 
			
		||||
use crate::ui::gui::{windows::WindowIndex, Gui};
 | 
			
		||||
 | 
			
		||||
impl Gui {
 | 
			
		||||
use super::Component;
 | 
			
		||||
 | 
			
		||||
    pub fn draw_nav(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub struct NavBar;
 | 
			
		||||
 | 
			
		||||
impl Component for NavBar {
 | 
			
		||||
    fn ui(gui: &mut Gui, ctx: &egui::Context) {
 | 
			
		||||
        egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
 | 
			
		||||
            // The top panel is often a good place for a menu bar:
 | 
			
		||||
            egui::menu::bar(ui, |ui| {
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +16,7 @@ impl Gui {
 | 
			
		|||
                        ctx.open_url(egui::OpenUrl::new_tab("https://git.mcorangehq.xyz/XOR64/music"));
 | 
			
		||||
                    }
 | 
			
		||||
                    if ui.button("Save").clicked() {
 | 
			
		||||
                        if let Err(e) =  self.manifest.save(None) {
 | 
			
		||||
                        if let Err(e) =  gui.manifest.save(None) {
 | 
			
		||||
                            log::error!("Failed to save manifest: {e}");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -22,19 +27,19 @@ impl Gui {
 | 
			
		|||
 | 
			
		||||
                ui.menu_button("Song", |ui| {
 | 
			
		||||
                    if ui.button("Add New").clicked() {
 | 
			
		||||
                        self.windows.open(WindowIndex::SongNew, true);
 | 
			
		||||
                        gui.windows.open(WindowIndex::SongNew, true);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                ui.menu_button("Playlist", |ui| {
 | 
			
		||||
                    if ui.button("Import").clicked() {
 | 
			
		||||
                        self.windows.open(WindowIndex::ImportPlaylist, true);
 | 
			
		||||
                        gui.windows.open(WindowIndex::ImportPlaylist, true);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                ui.menu_button("Downloader", |ui| {
 | 
			
		||||
                    if ui.button("Download All").clicked() {
 | 
			
		||||
                        if let Err(e) = self.downloader.download_all_nb(&self.manifest, &self.cfg) {
 | 
			
		||||
                        if let Err(e) = gui.downloader.download_all_nb(&gui.manifest, &gui.cfg) {
 | 
			
		||||
                            log::error!("Err: {e}");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -42,21 +47,22 @@ impl Gui {
 | 
			
		|||
                ui.add_space(16.0);
 | 
			
		||||
                ui.with_layout(egui::Layout::bottom_up(egui::Align::RIGHT), |ui| {
 | 
			
		||||
                    ui.horizontal(|ui| {
 | 
			
		||||
                        if self.downloader.get_songs_left_nb() > 0 {
 | 
			
		||||
                            self.downloading = true;
 | 
			
		||||
                            ui.label(format!("Downloading: {}/{}", self.downloader.get_songs_left_nb(), self.downloader.get_initial_song_count_nb()));
 | 
			
		||||
                        } else if self.downloading {
 | 
			
		||||
                        if gui.downloader.get_songs_left_nb() > 0 {
 | 
			
		||||
                            gui.downloading = true;
 | 
			
		||||
                            ui.label(format!("Downloading: {}/{}", gui.downloader.get_songs_left_nb(), gui.downloader.get_initial_song_count_nb()));
 | 
			
		||||
                        } else if gui.downloading {
 | 
			
		||||
                            let _ = notify_rust::Notification::new()
 | 
			
		||||
                                .summary("Done downloading")
 | 
			
		||||
                                .body("Your music has been downloaded")
 | 
			
		||||
                                .show();
 | 
			
		||||
                            self.downloading = false;
 | 
			
		||||
                            gui.downloading = false;
 | 
			
		||||
                        }
 | 
			
		||||
                        let _ = self.downloader.download_all_nb_poll(&self.cfg);
 | 
			
		||||
                        let _ = gui.downloader.download_all_nb_poll(&gui.cfg);
 | 
			
		||||
                        egui::widgets::global_dark_light_mode_buttons(ui);
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    } 
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								src/ui/gui/components/song_list.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/ui/gui/components/song_list.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
use egui::{Color32, RichText};
 | 
			
		||||
use egui_extras::{Column, TableBuilder};
 | 
			
		||||
 | 
			
		||||
use crate::manifest::song::SongType;
 | 
			
		||||
 | 
			
		||||
use super::{context_menu::ContextMenu, ComponentUi};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub struct SongList;
 | 
			
		||||
 | 
			
		||||
impl ComponentUi for SongList {
 | 
			
		||||
    fn ui(gui: &mut crate::ui::gui::Gui, ui: &mut egui::Ui) {
 | 
			
		||||
        let fltr_by;
 | 
			
		||||
        let filter_clean;
 | 
			
		||||
        if gui.filter.starts_with("playlist:") {
 | 
			
		||||
            fltr_by = "playlist";
 | 
			
		||||
            filter_clean = gui.filter.strip_prefix("playlist:").unwrap_or("").to_string().to_lowercase();
 | 
			
		||||
        } else if gui.filter.starts_with("source:") {
 | 
			
		||||
            fltr_by = "source";
 | 
			
		||||
            filter_clean = gui.filter.strip_prefix("source:").unwrap_or("").to_string().to_lowercase();
 | 
			
		||||
        } else if gui.filter.starts_with("url:") {
 | 
			
		||||
            fltr_by = "url";
 | 
			
		||||
            filter_clean = gui.filter.strip_prefix("url:").unwrap_or("").to_string();
 | 
			
		||||
        } else {
 | 
			
		||||
            fltr_by = "";
 | 
			
		||||
            filter_clean = gui.filter.clone();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ui.vertical(|ui| {
 | 
			
		||||
            ui.horizontal(|ui| {
 | 
			
		||||
                ui.colored_label(Color32::from_hex("#4444aa").unwrap(), "Filter: ");
 | 
			
		||||
                ui.text_edit_singleline(&mut gui.filter);
 | 
			
		||||
            });  
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        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::auto())
 | 
			
		||||
                //.column(
 | 
			
		||||
                //    Column::remainder()
 | 
			
		||||
                //        .at_least(40.0)
 | 
			
		||||
                //        .clip(true)
 | 
			
		||||
                //        .resizable(true),
 | 
			
		||||
                //)
 | 
			
		||||
                .column(Column::auto())
 | 
			
		||||
                .column(Column::remainder())
 | 
			
		||||
                //.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
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            table.header(20.0, |mut header| {
 | 
			
		||||
                // header.col(|_|{});
 | 
			
		||||
                header.col(|ui| {
 | 
			
		||||
                    ui.strong("Playlist");
 | 
			
		||||
                }); 
 | 
			
		||||
                header.col(|ui| { 
 | 
			
		||||
                    ui.strong("Source");
 | 
			
		||||
                });
 | 
			
		||||
                header.col(|ui| {
 | 
			
		||||
                    ui.strong("Name");
 | 
			
		||||
                });
 | 
			
		||||
            }).body(|mut body| {
 | 
			
		||||
                for (pname, sname, s) in songs {    
 | 
			
		||||
                    if fltr_by == "playlist" && !filter_clean.is_empty() {
 | 
			
		||||
                        if !pname.to_lowercase().contains(&filter_clean) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if fltr_by == "type" && !filter_clean.is_empty(){
 | 
			
		||||
                        if !s.get_type().to_string().to_lowercase().contains(&filter_clean) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if fltr_by == "url" && !filter_clean.is_empty(){
 | 
			
		||||
                        if !s.get_url_str().contains(&filter_clean) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if !filter_clean.is_empty() {
 | 
			
		||||
                        if !sname.to_lowercase().contains(&filter_clean) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    body.row(18.0, |mut row| {
 | 
			
		||||
                         
 | 
			
		||||
                        row.col(|ui| {
 | 
			
		||||
                            ui.label(pname.clone())
 | 
			
		||||
                                .context_menu(|ui| ContextMenu::ui(gui, ui, &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| ContextMenu::ui(gui, ui, &pname, &sname, &s));
 | 
			
		||||
                        });
 | 
			
		||||
                        row.col(|ui| {
 | 
			
		||||
                            ui.hyperlink_to(sname.clone(), s.get_url_str())
 | 
			
		||||
                                .context_menu(|ui| ContextMenu::ui(gui, ui, &pname, &sname, &s));
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                        row.response()
 | 
			
		||||
                            .context_menu(|ui| ContextMenu::ui(gui, ui, &pname, &sname, &s));
 | 
			
		||||
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +1,9 @@
 | 
			
		|||
mod nav_bar;
 | 
			
		||||
mod windows;
 | 
			
		||||
mod components;
 | 
			
		||||
 | 
			
		||||
use egui::{Color32, RichText};
 | 
			
		||||
use egui_extras::{Column, TableBuilder};
 | 
			
		||||
use components::{Component, ComponentUi};
 | 
			
		||||
use windows::{State, WindowIndex, WindowManager};
 | 
			
		||||
 | 
			
		||||
use crate::{config::ConfigWrapper, downloader::Downloader, manifest::{song::{Song, SongType}, Manifest}};
 | 
			
		||||
use crate::{config::ConfigWrapper, downloader::Downloader, manifest::Manifest};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +58,8 @@ impl Gui {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl eframe::App for Gui {
 | 
			
		||||
    fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
 | 
			
		||||
        self.draw_nav(ctx, frame);
 | 
			
		||||
    fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
 | 
			
		||||
        components::nav::NavBar::ui(self, ctx);
 | 
			
		||||
        {
 | 
			
		||||
            let mut state = State {
 | 
			
		||||
                cfg: self.cfg.clone(),
 | 
			
		||||
| 
						 | 
				
			
			@ -78,173 +75,9 @@ impl eframe::App for Gui {
 | 
			
		|||
        egui::CentralPanel::default().show(ctx, |ui| {
 | 
			
		||||
            // The central panel the region left after adding TopPanel's and SidePanel's
 | 
			
		||||
            //ui.heading(format!("Songs ({})", self.manifest.get_song_count()));
 | 
			
		||||
            
 | 
			
		||||
            let fltr_by;
 | 
			
		||||
            let filter_clean;
 | 
			
		||||
            if self.filter.starts_with("playlist:") {
 | 
			
		||||
                fltr_by = "playlist";
 | 
			
		||||
                filter_clean = self.filter.strip_prefix("playlist:").unwrap_or("").to_string().to_lowercase();
 | 
			
		||||
            } else if self.filter.starts_with("source:") {
 | 
			
		||||
                fltr_by = "source";
 | 
			
		||||
                filter_clean = self.filter.strip_prefix("source:").unwrap_or("").to_string().to_lowercase();
 | 
			
		||||
            } else if self.filter.starts_with("url:") {
 | 
			
		||||
                fltr_by = "url";
 | 
			
		||||
                filter_clean = self.filter.strip_prefix("url:").unwrap_or("").to_string();
 | 
			
		||||
            } else {
 | 
			
		||||
                fltr_by = "";
 | 
			
		||||
                filter_clean = self.filter.clone();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ui.vertical(|ui| {
 | 
			
		||||
                ui.horizontal(|ui| {
 | 
			
		||||
                    ui.colored_label(Color32::from_hex("#4444aa").unwrap(), "Filter: ");
 | 
			
		||||
                    ui.text_edit_singleline(&mut self.filter);
 | 
			
		||||
                });  
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
            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::auto())
 | 
			
		||||
                    //.column(
 | 
			
		||||
                    //    Column::remainder()
 | 
			
		||||
                    //        .at_least(40.0)
 | 
			
		||||
                    //        .clip(true)
 | 
			
		||||
                    //        .resizable(true),
 | 
			
		||||
                    //)
 | 
			
		||||
                    .column(Column::auto())
 | 
			
		||||
                    .column(Column::remainder())
 | 
			
		||||
                    //.column(Column::remainder())
 | 
			
		||||
                    .min_scrolled_height(0.0)
 | 
			
		||||
                    .max_scroll_height(available_height)
 | 
			
		||||
                    .sense(egui::Sense::click());
 | 
			
		||||
                
 | 
			
		||||
                let playlists = self.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
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                table.header(20.0, |mut header| {
 | 
			
		||||
                    // header.col(|_|{});
 | 
			
		||||
                    header.col(|ui| {
 | 
			
		||||
                        ui.strong("Playlist");
 | 
			
		||||
                    }); 
 | 
			
		||||
                    header.col(|ui| { 
 | 
			
		||||
                        ui.strong("Source");
 | 
			
		||||
                    });
 | 
			
		||||
                    header.col(|ui| {
 | 
			
		||||
                        ui.strong("Name");
 | 
			
		||||
                    });
 | 
			
		||||
                }).body(|mut body| {
 | 
			
		||||
                    for (pname, sname, s) in songs {    
 | 
			
		||||
                        if fltr_by == "playlist" && !filter_clean.is_empty() {
 | 
			
		||||
                            if !pname.to_lowercase().contains(&filter_clean) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                        } else if fltr_by == "type" && !filter_clean.is_empty(){
 | 
			
		||||
                            if !s.get_type().to_string().to_lowercase().contains(&filter_clean) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                        } else if fltr_by == "url" && !filter_clean.is_empty(){
 | 
			
		||||
                            if !s.get_url_str().contains(&filter_clean) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                        } else if !filter_clean.is_empty() {
 | 
			
		||||
                            if !sname.to_lowercase().contains(&filter_clean) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        body.row(18.0, |mut row| {
 | 
			
		||||
                             
 | 
			
		||||
                            row.col(|ui| {
 | 
			
		||||
                                ui.label(pname.clone())
 | 
			
		||||
                                    .context_menu(|ui| context_menu(self, ui, &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(self, ui, &pname, &sname, &s));
 | 
			
		||||
                            });
 | 
			
		||||
                            row.col(|ui| {
 | 
			
		||||
                                ui.hyperlink_to(sname.clone(), s.get_url_str())
 | 
			
		||||
                                    .context_menu(|ui| context_menu(self, ui, &pname, &sname, &s));
 | 
			
		||||
                            });
 | 
			
		||||
 | 
			
		||||
                            row.response()
 | 
			
		||||
                                .context_menu(|ui| context_menu(self, ui, &pname, &sname, &s));
 | 
			
		||||
 | 
			
		||||
                            fn context_menu(this: &mut Gui, ui: &mut egui::Ui, pname: &String, sname: &String, song: &Song) {
 | 
			
		||||
                                if ui.button("Edit").clicked() {
 | 
			
		||||
                                    let w = this.windows.get_window::<windows::song_edit::GuiSongEditor>(WindowIndex::SongEdit);
 | 
			
		||||
                                    w.set_active_song(pname, sname, song.get_url_str());
 | 
			
		||||
                                    this.windows.open(WindowIndex::SongEdit, true);
 | 
			
		||||
                                    ui.close_menu()
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if ui.button("Download").clicked() {
 | 
			
		||||
                                    if let Err(e) = this.downloader.download_song_nb(&this.cfg, pname, sname, song, this.manifest.get_format()) {
 | 
			
		||||
                                        log::error!("{e}");
 | 
			
		||||
                                        this.throw_error(format!("Failed to download song {sname}: {e}"));
 | 
			
		||||
                                    }
 | 
			
		||||
                                    ui.close_menu()
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if ui.button("Open Source").clicked() {
 | 
			
		||||
                                    if let Err(e) = open::that(song.get_url_str()) {
 | 
			
		||||
                                        log::error!("{e}");
 | 
			
		||||
                                        this.throw_error(format!("Failed to open song source: {e}"));
 | 
			
		||||
                                    }
 | 
			
		||||
                                    ui.close_menu()
 | 
			
		||||
                                }
 | 
			
		||||
                                if ui.button("Play").clicked() {
 | 
			
		||||
                                    let p = crate::util::get_song_path(pname, sname, this.manifest.get_format());
 | 
			
		||||
                                    
 | 
			
		||||
                                    if !p.exists() {
 | 
			
		||||
                                       this.throw_error(format!("Song does not exist on disk")); 
 | 
			
		||||
                                    } else if let Err(e) = open::that(p) {
 | 
			
		||||
                                        log::error!("{e}");
 | 
			
		||||
                                        this.throw_error(format!("Failed to play song: {e}"));
 | 
			
		||||
                                    }
 | 
			
		||||
                                    ui.close_menu()
 | 
			
		||||
                                }
 | 
			
		||||
                                if ui.button("Delete from disk").clicked() {
 | 
			
		||||
                                    let p = crate::util::get_song_path(pname, sname, this.manifest.get_format());
 | 
			
		||||
                                    if p.exists() {
 | 
			
		||||
                                        if let Err(e) = std::fs::remove_file(p) {
 | 
			
		||||
                                            this.throw_error(format!("Failed to delete file: {e}"));
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    ui.close_menu();
 | 
			
		||||
                                }
 | 
			
		||||
                                if ui.button(RichText::new("Delete").color(Color32::RED)).clicked() {
 | 
			
		||||
                                    this.throw_error("TODO");
 | 
			
		||||
                                    ui.close_menu()
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        })
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
            components::song_list::SongList::ui(self, ui);
 | 
			
		||||
            ui.separator();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| {
 | 
			
		||||
                egui::warn_if_debug_build(ui);
 | 
			
		||||
            });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user