Other crap i added months ago
This commit is contained in:
		
							parent
							
								
									ad89b0c64d
								
							
						
					
					
						commit
						67a948bb66
					
				| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
use egui::{CursorIcon, RichText, Sense, TextBuffer};
 | 
					use egui::{CursorIcon, RichText, Sense, TextBuffer};
 | 
				
			||||||
use xmpd_manifest::store::BaseStore;
 | 
					use xmpd_manifest::store::{BaseStore, StoreExtras};
 | 
				
			||||||
use crate::utils::SearchType;
 | 
					use crate::utils::SearchType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{CompGetter, CompUi};
 | 
					use super::{CompGetter, CompUi};
 | 
				
			||||||
| 
						 | 
					@ -23,12 +23,7 @@ impl CompUi for LeftNav {
 | 
				
			||||||
                ui.vertical(|ui| {
 | 
					                ui.vertical(|ui| {
 | 
				
			||||||
                    let len = state.manifest.store().get_songs().len();
 | 
					                    let len = state.manifest.store().get_songs().len();
 | 
				
			||||||
                    add_playlist_tab(ui, &None, "All Songs", None, len, w);
 | 
					                    add_playlist_tab(ui, &None, "All Songs", None, len, w);
 | 
				
			||||||
                    let mut playlists: Vec<_> = state.manifest.store().get_playlists().into_iter().collect();
 | 
					                    let playlists = state.manifest.store().get_playlists_sorted();
 | 
				
			||||||
                    playlists.sort_by(|a, b| {
 | 
					 | 
				
			||||||
                        let a = a.1.name().to_lowercase();
 | 
					 | 
				
			||||||
                        let b = b.1.name().to_lowercase();
 | 
					 | 
				
			||||||
                        a.cmp(&b)
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                    let search_text = handle_error_ui!(header::Header::get()).search_text.clone();
 | 
					                    let search_text = handle_error_ui!(header::Header::get()).search_text.clone();
 | 
				
			||||||
                    let (qtyp, qtxt) = crate::utils::SearchType::from_str(&search_text);
 | 
					                    let (qtyp, qtxt) = crate::utils::SearchType::from_str(&search_text);
 | 
				
			||||||
                    for (pid, playlist) in playlists.iter() {
 | 
					                    for (pid, playlist) in playlists.iter() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
use egui::{Color32, CursorIcon, ImageSource, RichText, Sense, Vec2};
 | 
					use egui::{Color32, CursorIcon, ImageSource, RichText, Sense, Vec2};
 | 
				
			||||||
use xmpd_cache::DlStatus;
 | 
					use xmpd_cache::DlStatus;
 | 
				
			||||||
use xmpd_manifest::{query, song::Song, store::BaseStore};
 | 
					use xmpd_manifest::{query, song::Song, store::{BaseStore, StoreExtras}};
 | 
				
			||||||
use crate::utils::SearchType;
 | 
					use crate::utils::SearchType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{CompGetter, CompUi};
 | 
					use super::{CompGetter, CompUi};
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ impl CompUi for SongList {
 | 
				
			||||||
            sl.playable_songs = Self::get_playable_songs(&songs)?;
 | 
					            sl.playable_songs = Self::get_playable_songs(&songs)?;
 | 
				
			||||||
            if let Some((sid, _)) = songs.first() {
 | 
					            if let Some((sid, _)) = songs.first() {
 | 
				
			||||||
                if sl.selected_sid == Default::default() {
 | 
					                if sl.selected_sid == Default::default() {
 | 
				
			||||||
                    sl.selected_sid = sid.clone();
 | 
					                    sl.selected_sid = (*sid).clone();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -34,8 +34,8 @@ impl CompUi for SongList {
 | 
				
			||||||
            .show(ui, |ui| {
 | 
					            .show(ui, |ui| {
 | 
				
			||||||
                ui.vertical(|ui| {
 | 
					                ui.vertical(|ui| {
 | 
				
			||||||
                    ui.add_space(3.0);
 | 
					                    ui.add_space(3.0);
 | 
				
			||||||
                    for (sid, song) in disp_songs {
 | 
					                    for sid in disp_songs {
 | 
				
			||||||
                         handle_error_ui!(Self::display_song_tab(ui, state, &sid, &song));
 | 
					                         handle_error_ui!(Self::display_song_tab(ui, state, &sid));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
| 
						 | 
					@ -44,40 +44,19 @@ impl CompUi for SongList {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl SongList {
 | 
					impl SongList {
 | 
				
			||||||
    fn get_and_sort_songs(state: &mut crate::GuiState) -> crate::Result<Vec<(uuid::Uuid, Song)>> {
 | 
					    fn get_and_sort_songs(state: &mut crate::GuiState) -> crate::Result<Vec<(&uuid::Uuid, &Song)>> {
 | 
				
			||||||
        let pid = super::left_nav::LeftNav::get()?.selected_playlist_id.clone();
 | 
					        let pid = super::left_nav::LeftNav::get()?.selected_playlist_id.clone();
 | 
				
			||||||
        match pid {
 | 
					        match pid {
 | 
				
			||||||
            None => {
 | 
					            None => {
 | 
				
			||||||
                let songs = state.manifest.store().get_songs().clone().into_iter();
 | 
					                Ok(state.manifest.store().get_songs_sorted())
 | 
				
			||||||
                let mut songs: Vec<_> = songs.collect();
 | 
					 | 
				
			||||||
                songs.sort_by(|a, b| {
 | 
					 | 
				
			||||||
                    let a = a.1.name().to_lowercase();
 | 
					 | 
				
			||||||
                    let b = b.1.name().to_lowercase();
 | 
					 | 
				
			||||||
                    a.cmp(&b)
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
                Ok(songs)
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Some(pid) => {
 | 
					            Some(pid) => {
 | 
				
			||||||
                let Some(playlist) = state.manifest.store().get_playlist(&pid) else {
 | 
					                Ok(state.manifest.store().get_playlist_songs_sorted(pid).expect("Invalid pid"))
 | 
				
			||||||
                    anyhow::bail!("Couldnt find playlist (corruption?)");
 | 
					 | 
				
			||||||
                };
 | 
					 | 
				
			||||||
                let mut songs = Vec::new();
 | 
					 | 
				
			||||||
                for sid in playlist.songs() {
 | 
					 | 
				
			||||||
                    if let Some(song) = state.manifest.store().get_song(&sid) {
 | 
					 | 
				
			||||||
                        songs.push((sid.clone(), song.clone()));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                songs.sort_by(|a, b| {
 | 
					 | 
				
			||||||
                    let a = a.1.name().to_lowercase();
 | 
					 | 
				
			||||||
                    let b = b.1.name().to_lowercase();
 | 
					 | 
				
			||||||
                    a.cmp(&b)
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
                Ok(songs)
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_songs_to_display(songs: &Vec<(uuid::Uuid, Song)>) -> crate::Result<Vec<(uuid::Uuid, Song)>>{
 | 
					    fn get_songs_to_display<'a>(songs: &'a [(&uuid::Uuid, &Song)]) -> crate::Result<Vec<uuid::Uuid>>{
 | 
				
			||||||
        let mut to_display = Vec::new();
 | 
					        let mut to_display = Vec::new();
 | 
				
			||||||
        let query = {header::Header::get()?.search_text.clone()};
 | 
					        let query = {header::Header::get()?.search_text.clone()};
 | 
				
			||||||
        let (query_type, query_text) = crate::utils::SearchType::from_str(&query);
 | 
					        let (query_type, query_text) = crate::utils::SearchType::from_str(&query);
 | 
				
			||||||
| 
						 | 
					@ -105,15 +84,16 @@ impl SongList {
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if should_display {
 | 
					            if should_display {
 | 
				
			||||||
                to_display.push((sid.clone(), song.clone()));
 | 
					                to_display.push((*sid).clone());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(to_display)
 | 
					        Ok(to_display)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn display_song_tab(ui: &mut egui::Ui, state: &mut crate::GuiState, sid: &uuid::Uuid, song: &Song) -> crate::Result<()> {
 | 
					    fn display_song_tab(ui: &mut egui::Ui, state: &mut crate::GuiState, sid: &uuid::Uuid) -> crate::Result<()> {
 | 
				
			||||||
        let mut clicked = false;
 | 
					        let mut clicked = false;
 | 
				
			||||||
        ui.horizontal(|ui| {
 | 
					        ui.horizontal(|ui| {
 | 
				
			||||||
 | 
					            let song = handle_option!("(internal)", state.manifest.store().get_song(sid));
 | 
				
			||||||
            let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone();
 | 
					            let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone();
 | 
				
			||||||
            // let icon_status = handle_error_ui!(xmpd_cache::Cache::get()).get_cached_icon_status(&sid).clone();
 | 
					            // let icon_status = handle_error_ui!(xmpd_cache::Cache::get()).get_cached_icon_status(&sid).clone();
 | 
				
			||||||
            let img = ui.add(
 | 
					            let img = ui.add(
 | 
				
			||||||
| 
						 | 
					@ -200,7 +180,7 @@ impl SongList {
 | 
				
			||||||
                                .size(16.0);
 | 
					                                .size(16.0);
 | 
				
			||||||
                        ui.add(spinner);
 | 
					                        ui.add(spinner);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Some(DlStatus::Error(e, ..)) => {
 | 
					                    Some(DlStatus::Error(_, _,  e)) => {
 | 
				
			||||||
                        let img = egui::Image::new(crate::data::WARN_ICON)
 | 
					                        let img = egui::Image::new(crate::data::WARN_ICON)
 | 
				
			||||||
                                .tint(Color32::LIGHT_YELLOW)
 | 
					                                .tint(Color32::LIGHT_YELLOW)
 | 
				
			||||||
                                .sense(Sense::hover())
 | 
					                                .sense(Sense::hover())
 | 
				
			||||||
| 
						 | 
					@ -274,12 +254,12 @@ impl SongList {
 | 
				
			||||||
        self.play_song(next, state)?;
 | 
					        self.play_song(next, state)?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn get_playable_songs(songs: &Vec<(uuid::Uuid, Song)>) -> crate::Result<Vec<uuid::Uuid>> {
 | 
					    fn get_playable_songs(songs: &[(&uuid::Uuid, &Song)]) -> crate::Result<Vec<uuid::Uuid>> {
 | 
				
			||||||
        let mut playable_songs = Vec::new();
 | 
					        let mut playable_songs = Vec::new();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for (sid, _) in songs {
 | 
					        for (sid, _) in songs {
 | 
				
			||||||
            if let Some(DlStatus::Done(_)) = xmpd_cache::Cache::get()?.get_cached_song_status(&sid) {
 | 
					            if let Some(DlStatus::Done(_)) = xmpd_cache::Cache::get()?.get_cached_song_status(&sid) {
 | 
				
			||||||
                playable_songs.push(sid.clone());
 | 
					                playable_songs.push((*sid).clone());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(playable_songs)
 | 
					        Ok(playable_songs)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
use std::path::PathBuf;
 | 
					use std::path::PathBuf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use egui::TextBuffer;
 | 
					use egui::{Layout, TextBuffer};
 | 
				
			||||||
use xmpd_manifest::store::{JsonStore, TomlStore};
 | 
					use xmpd_manifest::store::{JsonStore, TomlStore};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::windows::WindowId;
 | 
					use crate::windows::WindowId;
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,10 @@ impl CompUi for TopNav {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					                #[cfg(debug_assertions)]
 | 
				
			||||||
 | 
					                ui.with_layout(Layout::right_to_left(egui::Align::Max), |ui| {
 | 
				
			||||||
 | 
					                    ui.label(format!("ft: {} ms", state.debug_info.last_frame_time.as_millis()));
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
             });
 | 
					             });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        let mut used = false;
 | 
					        let mut used = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,4 @@
 | 
				
			||||||
#![feature(async_closure)]
 | 
					use std::time::{Duration, Instant};
 | 
				
			||||||
 | 
					 | 
				
			||||||
use std::time::Duration;
 | 
					 | 
				
			||||||
use xmpd_manifest::{store::JsonStore, Manifest};
 | 
					use xmpd_manifest::{store::JsonStore, Manifest};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[macro_use]
 | 
					#[macro_use]
 | 
				
			||||||
| 
						 | 
					@ -20,10 +18,19 @@ pub fn start() -> Result<()> {
 | 
				
			||||||
    let options = eframe::NativeOptions::default();
 | 
					    let options = eframe::NativeOptions::default();
 | 
				
			||||||
    let mut state = GuiState::new()?;
 | 
					    let mut state = GuiState::new()?;
 | 
				
			||||||
    let res = eframe::run_simple_native(W_NAME, options, move |ctx, _frame| {
 | 
					    let res = eframe::run_simple_native(W_NAME, options, move |ctx, _frame| {
 | 
				
			||||||
 | 
					        #[cfg(debug_assertions)]
 | 
				
			||||||
 | 
					        let f_start = Instant::now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        egui_extras::install_image_loaders(ctx);
 | 
					        egui_extras::install_image_loaders(ctx);
 | 
				
			||||||
        state.windows.clone().draw_all(ctx, &mut state); 
 | 
					        windows::Windows::draw_all(ctx, &mut state); 
 | 
				
			||||||
        handle_error_ui!(main_window::draw(ctx, &mut state, &cache_rx));
 | 
					        handle_error_ui!(main_window::draw(ctx, &mut state, &cache_rx));
 | 
				
			||||||
        ctx.request_repaint_after(Duration::from_millis(500));
 | 
					        ctx.request_repaint_after(Duration::from_millis(500));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[cfg(debug_assertions)]
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let f_end = Instant::now();
 | 
				
			||||||
 | 
					            state.debug_info.last_frame_time = f_end.duration_since(f_start);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    if let Err(e) = res { // dumb err value by eframe
 | 
					    if let Err(e) = res { // dumb err value by eframe
 | 
				
			||||||
        anyhow::bail!(e.to_string());
 | 
					        anyhow::bail!(e.to_string());
 | 
				
			||||||
| 
						 | 
					@ -31,15 +38,34 @@ pub fn start() -> Result<()> {
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(debug_assertions)]
 | 
				
			||||||
 | 
					#[derive(Debug, Default)]
 | 
				
			||||||
 | 
					pub struct DebugInfo {
 | 
				
			||||||
 | 
					    pub last_frame_time: Duration,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct GuiState {
 | 
					pub struct GuiState {
 | 
				
			||||||
 | 
					    #[cfg(debug_assertions)]
 | 
				
			||||||
 | 
					    pub debug_info: DebugInfo,
 | 
				
			||||||
    pub manifest: Manifest<JsonStore>,
 | 
					    pub manifest: Manifest<JsonStore>,
 | 
				
			||||||
    pub windows: windows::Windows,
 | 
					    pub windows: windows::Windows,
 | 
				
			||||||
    pub player: xmpd_player::Player,
 | 
					    pub player: xmpd_player::Player,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl GuiState {
 | 
					impl GuiState {
 | 
				
			||||||
 | 
					    #[cfg(debug_assertions)]
 | 
				
			||||||
 | 
					    pub fn new() -> Result<Self> {
 | 
				
			||||||
 | 
					        Ok(Self {
 | 
				
			||||||
 | 
					            debug_info: DebugInfo {
 | 
				
			||||||
 | 
					                last_frame_time: Default::default()
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            player: xmpd_player::Player::new(),
 | 
				
			||||||
 | 
					            manifest: Manifest::new(&xmpd_cliargs::CLIARGS.manifest_path())?,
 | 
				
			||||||
 | 
					            windows: windows::Windows::new(),
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(not(debug_assertions))]
 | 
				
			||||||
    pub fn new() -> Result<Self> {
 | 
					    pub fn new() -> Result<Self> {
 | 
				
			||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            player: xmpd_player::Player::new(),
 | 
					            player: xmpd_player::Player::new(),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,13 +30,15 @@ pub fn draw(ctx: &egui::Context, state: &mut GuiState, cache_rx: &Receiver<Messa
 | 
				
			||||||
                ui.horizontal(|ui| {
 | 
					                ui.horizontal(|ui| {
 | 
				
			||||||
                    ui.set_height(main_height);  
 | 
					                    ui.set_height(main_height);  
 | 
				
			||||||
                    ui.vertical(|ui| {
 | 
					                    ui.vertical(|ui| {
 | 
				
			||||||
 | 
					                        ui.set_height(main_height);
 | 
				
			||||||
                        ui.group(|ui| {
 | 
					                        ui.group(|ui| {
 | 
				
			||||||
                            //ui.set_height(main_height * 0.1);
 | 
					                            //ui.set_height(main_height * 0.1);
 | 
				
			||||||
                            ui.set_max_width(left_nav_width);
 | 
					                            ui.set_max_width(left_nav_width);
 | 
				
			||||||
                            handle_error_ui!(crate::components::left_nav::header::Header::draw(ui, state));
 | 
					                            handle_error_ui!(crate::components::left_nav::header::Header::draw(ui, state));
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
 | 
					                        let avail = ui.available_size();
 | 
				
			||||||
                        ui.group(|ui| {
 | 
					                        ui.group(|ui| {
 | 
				
			||||||
                            // ui.set_height(main_height * 0.9);
 | 
					                            ui.set_height(avail.y);
 | 
				
			||||||
                            ui.set_max_width(left_nav_width);
 | 
					                            ui.set_max_width(left_nav_width);
 | 
				
			||||||
                            handle_error_ui!(crate::components::left_nav::LeftNav::draw(ui, state));
 | 
					                            handle_error_ui!(crate::components::left_nav::LeftNav::draw(ui, state));
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,13 @@
 | 
				
			||||||
 | 
					use egui::{RichText, TextEdit};
 | 
				
			||||||
 | 
					use xmpd_cache::DlStatus;
 | 
				
			||||||
 | 
					use xmpd_manifest::store::{BaseStore, StoreExtras};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::Window;
 | 
					use super::Window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Default)]
 | 
					#[derive(Debug, Default)]
 | 
				
			||||||
pub struct AddSongW {
 | 
					pub struct AddSongW {
 | 
				
			||||||
 | 
					    sid: uuid::Uuid,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Window for AddSongW {
 | 
					impl Window for AddSongW {
 | 
				
			||||||
| 
						 | 
					@ -13,8 +17,83 @@ impl Window for AddSongW {
 | 
				
			||||||
    fn default_title() -> &'static str where Self: Sized {
 | 
					    fn default_title() -> &'static str where Self: Sized {
 | 
				
			||||||
        "Add Song to Playlist"
 | 
					        "Add Song to Playlist"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn draw(&mut self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
 | 
					    fn draw(&mut self, ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
 | 
				
			||||||
        ui.label("Hello from other window!");
 | 
					        let theme = xmpd_settings::Settings::get()?.theme.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let songs: Vec<_> = state.manifest.store().get_songs_sorted();
 | 
				
			||||||
 | 
					        if self.sid.is_nil() {
 | 
				
			||||||
 | 
					            if let Some(sid) = songs.first() {
 | 
				
			||||||
 | 
					                self.sid = sid.0.clone();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        let avail = ui.available_size();
 | 
				
			||||||
 | 
					        ui.horizontal(|ui| {
 | 
				
			||||||
 | 
					            ui.vertical(|ui| {
 | 
				
			||||||
 | 
					                ui.group(|ui| {
 | 
				
			||||||
 | 
					                    ui.set_height(avail.y);
 | 
				
			||||||
 | 
					                    let img = egui::Image::new(crate::data::NOTE_ICON)
 | 
				
			||||||
 | 
					                        .tint(theme.accent_color)
 | 
				
			||||||
 | 
					                        .fit_to_exact_size(egui::Vec2::new(64.0, 64.0));
 | 
				
			||||||
 | 
					                    ui.add(img);
 | 
				
			||||||
 | 
					                    let mut name = String::new();
 | 
				
			||||||
 | 
					                    let mut author = String::new();
 | 
				
			||||||
 | 
					                    if let Some(song) = state.manifest.store().get_song(&self.sid) {
 | 
				
			||||||
 | 
					                        name = song.name().to_string();
 | 
				
			||||||
 | 
					                        author = song.author().to_string();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    ui.horizontal(|ui| {
 | 
				
			||||||
 | 
					                        ui.style_mut().spacing.text_edit_width = 150.0;
 | 
				
			||||||
 | 
					                        ui.label("Name:   ");
 | 
				
			||||||
 | 
					                        ui.add_enabled(false, TextEdit::singleline(&mut name));
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    ui.horizontal(|ui| {
 | 
				
			||||||
 | 
					                        ui.style_mut().spacing.text_edit_width = 150.0;
 | 
				
			||||||
 | 
					                        ui.label("Author: ");
 | 
				
			||||||
 | 
					                        ui.add_enabled(false, TextEdit::singleline(&mut author));
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            ui.vertical(|ui| {
 | 
				
			||||||
 | 
					                ui.group(|ui| {
 | 
				
			||||||
 | 
					                    egui::ScrollArea::vertical()
 | 
				
			||||||
 | 
					                        .id_source("song_list_song_add")
 | 
				
			||||||
 | 
					                        .drag_to_scroll(false)
 | 
				
			||||||
 | 
					                        .show(ui, |ui| {
 | 
				
			||||||
 | 
					                            ui.vertical(|ui| {
 | 
				
			||||||
 | 
					                                for (sid, song) in songs {
 | 
				
			||||||
 | 
					                                    ui.group(|ui| {
 | 
				
			||||||
 | 
					                                        let avail = ui.available_size();
 | 
				
			||||||
 | 
					                                        ui.horizontal(|ui| {
 | 
				
			||||||
 | 
					                                            ui.set_width(avail.x);
 | 
				
			||||||
 | 
					                                            let img = egui::Image::new(crate::data::NOTE_ICON)
 | 
				
			||||||
 | 
					                                                .tint(theme.accent_color)
 | 
				
			||||||
 | 
					                                                .fit_to_exact_size(egui::Vec2::new(32.0, 32.0));
 | 
				
			||||||
 | 
					                                            ui.add(img);
 | 
				
			||||||
 | 
					                                            ui.vertical(|ui| {
 | 
				
			||||||
 | 
					                                                let status = {
 | 
				
			||||||
 | 
					                                                    handle_error_ui!(xmpd_cache::Cache::get()).get_cached_song_status(&sid).clone()
 | 
				
			||||||
 | 
					                                                };
 | 
				
			||||||
 | 
					                                                let label = if self.sid == *sid {
 | 
				
			||||||
 | 
					                                                    RichText::new(song.name())
 | 
				
			||||||
 | 
					                                                        .color(theme.accent_color)
 | 
				
			||||||
 | 
					                                                } else if matches!(status, Some(DlStatus::Done(_))) {
 | 
				
			||||||
 | 
					                                                    RichText::new(song.name())
 | 
				
			||||||
 | 
					                                                        .color(theme.text_color)
 | 
				
			||||||
 | 
					                                                } else {
 | 
				
			||||||
 | 
					                                                    RichText::new(song.name())
 | 
				
			||||||
 | 
					                                                        .color(theme.dim_text_color)
 | 
				
			||||||
 | 
					                                                };
 | 
				
			||||||
 | 
					                                                ui.label(label);
 | 
				
			||||||
 | 
					                                            });
 | 
				
			||||||
 | 
					                                        });
 | 
				
			||||||
 | 
					                                    });
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
        Ok(()) 
 | 
					        Ok(()) 
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,13 +67,13 @@ impl Windows {
 | 
				
			||||||
        WINDOWS.lock().unwrap().insert(WT::id(), Box::<WT>::default());
 | 
					        WINDOWS.lock().unwrap().insert(WT::id(), Box::<WT>::default());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn draw_all(&mut self, ctx: &egui::Context, state: &mut GuiState) {
 | 
					    pub fn draw_all(ctx: &egui::Context, state: &mut GuiState) {
 | 
				
			||||||
        let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone();
 | 
					        let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone();
 | 
				
			||||||
        for (win_id, (vp_id, builder)) in &self.windows {
 | 
					        for (win_id, (vp_id, builder)) in state.windows.windows.clone().into_iter() {
 | 
				
			||||||
            if self.is_open(&win_id) {
 | 
					            if state.windows.is_open(&win_id) {
 | 
				
			||||||
                ctx.show_viewport_immediate(vp_id.clone(), builder.clone(), |ctx, _vp_class| {        
 | 
					                ctx.show_viewport_immediate(vp_id.clone(), builder.clone(), |ctx, _vp_class| {        
 | 
				
			||||||
                    ctx.input(|inp| {
 | 
					                    ctx.input(|inp| {
 | 
				
			||||||
                        self.toggle(win_id, !inp.viewport().close_requested());
 | 
					                        state.windows.toggle(&win_id, !inp.viewport().close_requested());
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                    egui::CentralPanel::default()
 | 
					                    egui::CentralPanel::default()
 | 
				
			||||||
                        .frame(
 | 
					                        .frame(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,8 @@ pub struct JsonStore {
 | 
				
			||||||
    playlists: HashMap<Uuid, Playlist>
 | 
					    playlists: HashMap<Uuid, Playlist>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl super::StoreExtras for JsonStore {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl super::BaseStore for JsonStore {
 | 
					impl super::BaseStore for JsonStore {
 | 
				
			||||||
    fn get_default_file_contents() -> &'static str {
 | 
					    fn get_default_file_contents() -> &'static str {
 | 
				
			||||||
        &DEFAULT_TEXT
 | 
					        &DEFAULT_TEXT
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,3 +40,55 @@ pub trait BaseStore {
 | 
				
			||||||
    fn get_original_path(&self) -> &Path;
 | 
					    fn get_original_path(&self) -> &Path;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait StoreExtras: BaseStore {
 | 
				
			||||||
 | 
					    fn get_songs_sorted(&self) -> Vec<(&Uuid, &Song)> {
 | 
				
			||||||
 | 
					        let mut songs: Vec<_> = self.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)
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        songs
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_songs_sorted_cloned(&self) -> Vec<(Uuid, Song)> {
 | 
				
			||||||
 | 
					        let mut songs = Vec::new();
 | 
				
			||||||
 | 
					        for song in self.get_songs_sorted() {
 | 
				
			||||||
 | 
					            songs.push((song.0.clone(), song.1.clone()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        songs
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_playlists_sorted(&self) -> Vec<(&Uuid, &Playlist)> {
 | 
				
			||||||
 | 
					        let mut songs: Vec<_> = self.get_playlists().iter().collect();
 | 
				
			||||||
 | 
					        songs.sort_by(|a, b| {
 | 
				
			||||||
 | 
					            let a = a.1.name().to_lowercase();
 | 
				
			||||||
 | 
					            let b = b.1.name().to_lowercase();
 | 
				
			||||||
 | 
					            a.cmp(&b)
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        songs
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_playlist_songs_sorted(&self, pid: uuid::Uuid) -> Option<Vec<(&Uuid, &Song)>> {
 | 
				
			||||||
 | 
					        let songs_ids: Vec<_> = self.get_playlist(&pid)?.songs().iter().collect();
 | 
				
			||||||
 | 
					        let mut songs = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for sid in songs_ids {
 | 
				
			||||||
 | 
					            songs.push((sid, self.get_song(sid)?));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        songs.sort_by(|a, b| {
 | 
				
			||||||
 | 
					            let a = a.1.name().to_lowercase();
 | 
				
			||||||
 | 
					            let b = b.1.name().to_lowercase();
 | 
				
			||||||
 | 
					            a.cmp(&b)
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        Some(songs)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_playlist_songs_sorted_cloned(&self, pid: uuid::Uuid) -> Option<Vec<(Uuid, Song)>> {
 | 
				
			||||||
 | 
					        let mut songs = Vec::new();
 | 
				
			||||||
 | 
					        for song in self.get_playlist_songs_sorted(pid)? {
 | 
				
			||||||
 | 
					            songs.push((song.0.clone(), song.1.clone()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Some(songs)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,8 @@ pub struct TomlStore {
 | 
				
			||||||
    playlists: HashMap<Uuid, Playlist>
 | 
					    playlists: HashMap<Uuid, Playlist>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl super::StoreExtras for TomlStore {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl super::BaseStore for TomlStore {
 | 
					impl super::BaseStore for TomlStore {
 | 
				
			||||||
    fn get_default_file_contents() -> &'static str {
 | 
					    fn get_default_file_contents() -> &'static str {
 | 
				
			||||||
        &DEFAULT_TEXT
 | 
					        &DEFAULT_TEXT
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user