Remade the window adding machanism, added playlist add window
This commit is contained in:
		
							parent
							
								
									86cf5542be
								
							
						
					
					
						commit
						c2c18154b3
					
				
							
								
								
									
										41
									
								
								xmpd-gui/src/components/left_nav/header.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								xmpd-gui/src/components/left_nav/header.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
use uuid::Uuid;
 | 
			
		||||
use crate::{components::{CompGetter, CompUi}, windows::WindowId};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
pub struct Header {
 | 
			
		||||
    pub search_text: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
component_register!(Header);
 | 
			
		||||
 | 
			
		||||
impl CompUi for Header {
 | 
			
		||||
    fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        let theme = xmpd_settings::Settings::get()?.theme.clone();
 | 
			
		||||
 | 
			
		||||
        ui.vertical(|ui| {
 | 
			
		||||
            ui.horizontal(|ui| {
 | 
			
		||||
                let search_icon = egui::Image::new(crate::data::SEARCH_ICON)
 | 
			
		||||
                    .fit_to_exact_size(egui::Vec2::new(16.0, 16.0))
 | 
			
		||||
                    .tint(theme.accent_color);
 | 
			
		||||
                ui.add(search_icon);
 | 
			
		||||
                {
 | 
			
		||||
                    ui.text_edit_singleline(&mut handle_error_ui!(Header::get()).search_text);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            //ui.with_layout(egui::Layout::top_down(egui::Align::), add_contents)
 | 
			
		||||
            ui.with_layout(egui::Layout::right_to_left(egui::Align::Min), |ui| {
 | 
			
		||||
                let add_song = ui.add(
 | 
			
		||||
                    egui::Image::new(crate::data::PLUS_ICON)
 | 
			
		||||
                        .tint(theme.accent_color)
 | 
			
		||||
                        .sense(egui::Sense::click())
 | 
			
		||||
                        .fit_to_exact_size(egui::Vec2::new(16.0, 16.0))
 | 
			
		||||
                );
 | 
			
		||||
                if add_song.clicked() {
 | 
			
		||||
                    state.windows.toggle(&WindowId::NewPlaylist, true);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        Ok(()) 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
use egui::{CursorIcon, RichText, Sense};
 | 
			
		||||
use egui::{CursorIcon, RichText, Sense, TextBuffer};
 | 
			
		||||
use xmpd_manifest::store::BaseStore;
 | 
			
		||||
use crate::utils::SearchType;
 | 
			
		||||
 | 
			
		||||
use super::{CompGetter, CompUi};
 | 
			
		||||
 | 
			
		||||
pub mod header;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
pub struct LeftNav {
 | 
			
		||||
    pub selected_playlist_id: Option<uuid::Uuid>,
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +29,15 @@ impl CompUi for LeftNav {
 | 
			
		|||
                        let b = b.1.name().to_lowercase();
 | 
			
		||||
                        a.cmp(&b)
 | 
			
		||||
                    });
 | 
			
		||||
                    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(),
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +54,9 @@ impl CompUi for LeftNav {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn add_playlist_tab(ui: &mut egui::Ui, pid: &Option<uuid::Uuid>, 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +105,6 @@ fn add_playlist_tab(ui: &mut egui::Ui, pid: &Option<uuid::Uuid>, title: &str, au
 | 
			
		|||
    if blob.hovered() {
 | 
			
		||||
        ui.output_mut(|o| o.cursor_icon = CursorIcon::PointingHand);
 | 
			
		||||
    }
 | 
			
		||||
    ui.separator();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2,25 +2,20 @@ use uuid::Uuid;
 | 
			
		|||
use xmpd_cache::DlStatus;
 | 
			
		||||
use xmpd_manifest::{song::Song, store::BaseStore};
 | 
			
		||||
 | 
			
		||||
use crate::components::{left_nav::LeftNav, toast::ToastType, CompGetter, CompUi};
 | 
			
		||||
use crate::{components::{left_nav::LeftNav, toast::ToastType, CompGetter, CompUi}, windows::WindowId};
 | 
			
		||||
 | 
			
		||||
use super::SongList;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub enum SearchType {
 | 
			
		||||
    Name(String),
 | 
			
		||||
    Author(String),
 | 
			
		||||
    Source(String),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
pub struct SongListNav {
 | 
			
		||||
    text: String,
 | 
			
		||||
pub struct Header {
 | 
			
		||||
    pub search_text: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
component_register!(SongListNav);
 | 
			
		||||
component_register!(Header);
 | 
			
		||||
 | 
			
		||||
impl CompUi for SongListNav {
 | 
			
		||||
impl CompUi for Header {
 | 
			
		||||
    fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        let theme = xmpd_settings::Settings::get()?.theme.clone();
 | 
			
		||||
        let pid = {LeftNav::get()?.selected_playlist_id.clone()};
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +26,7 @@ impl CompUi for SongListNav {
 | 
			
		|||
                .tint(theme.accent_color);
 | 
			
		||||
            ui.add(search_icon);
 | 
			
		||||
            {
 | 
			
		||||
                ui.text_edit_singleline(&mut handle_error_ui!(SongListNav::get()).text);
 | 
			
		||||
                ui.text_edit_singleline(&mut handle_error_ui!(Header::get()).search_text);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ui.with_layout(egui::Layout::right_to_left(egui::Align::RIGHT), |ui| {
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +67,7 @@ impl CompUi for SongListNav {
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
                if add_song.clicked() {
 | 
			
		||||
                    todo!()
 | 
			
		||||
                    state.windows.toggle(&WindowId::AddSongToPl, true);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -80,16 +75,8 @@ impl CompUi for SongListNav {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl SongListNav {
 | 
			
		||||
    pub fn parse_search(&self) -> SearchType {
 | 
			
		||||
        match &self.text {
 | 
			
		||||
            i @ _ if i.starts_with("source:") => 
 | 
			
		||||
                SearchType::Source(i.strip_prefix("source:").unwrap_or("").to_string().to_lowercase()),
 | 
			
		||||
            i @ _ if i.starts_with("author:") => 
 | 
			
		||||
                SearchType::Author(i.strip_prefix("author:").unwrap_or("").to_string().to_lowercase()),
 | 
			
		||||
            i @ _ => SearchType::Name(i.to_string().to_lowercase())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
impl Header {
 | 
			
		||||
    
 | 
			
		||||
    fn get_songs_to_download(songs: &Vec<uuid::Uuid>) -> crate::Result<Vec<uuid::Uuid>> {
 | 
			
		||||
        let mut songs2 = Vec::new();
 | 
			
		||||
        
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +1,11 @@
 | 
			
		|||
use std::borrow::Cow;
 | 
			
		||||
 | 
			
		||||
use egui::{Color32, CursorIcon, ImageSource, RichText, Sense, Vec2};
 | 
			
		||||
use song_list_nav::SearchType;
 | 
			
		||||
use xmpd_cache::DlStatus;
 | 
			
		||||
use xmpd_manifest::{song::Song, store::BaseStore};
 | 
			
		||||
use xmpd_manifest::{query, song::Song, store::BaseStore};
 | 
			
		||||
use crate::utils::SearchType;
 | 
			
		||||
 | 
			
		||||
use super::{CompGetter, CompUi};
 | 
			
		||||
 | 
			
		||||
pub mod song_list_nav;
 | 
			
		||||
pub mod header;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
pub struct SongList {
 | 
			
		||||
| 
						 | 
				
			
			@ -80,27 +79,28 @@ impl SongList {
 | 
			
		|||
 | 
			
		||||
    fn get_songs_to_display(songs: &Vec<(uuid::Uuid, Song)>) -> crate::Result<Vec<(uuid::Uuid, Song)>>{
 | 
			
		||||
        let mut to_display = Vec::new();
 | 
			
		||||
        let query = {song_list_nav::SongListNav::get()?.parse_search()}.clone();
 | 
			
		||||
        let query = {header::Header::get()?.search_text.clone()};
 | 
			
		||||
        let (query_type, query_text) = crate::utils::SearchType::from_str(&query);
 | 
			
		||||
        for (sid, song) in songs {
 | 
			
		||||
            let should_display = match &query {
 | 
			
		||||
                SearchType::Name(s) | 
 | 
			
		||||
                SearchType::Author(s) |
 | 
			
		||||
                SearchType::Source(s) if s.is_empty() => true,
 | 
			
		||||
            let should_display = match &query_type {
 | 
			
		||||
                SearchType::Normal | 
 | 
			
		||||
                SearchType::Author |
 | 
			
		||||
                SearchType::Source if query_text.is_empty() => true,
 | 
			
		||||
 | 
			
		||||
                SearchType::Source(s) => {
 | 
			
		||||
                SearchType::Source => {
 | 
			
		||||
                    song.source_type().to_string()
 | 
			
		||||
                        .to_lowercase()
 | 
			
		||||
                        .contains(s)
 | 
			
		||||
                        .contains(&query_text)
 | 
			
		||||
                },
 | 
			
		||||
                SearchType::Author(s) => {
 | 
			
		||||
                SearchType::Author => {
 | 
			
		||||
                    song.author()
 | 
			
		||||
                        .to_lowercase()
 | 
			
		||||
                        .contains(s)
 | 
			
		||||
                        .contains(&query_text)
 | 
			
		||||
                },
 | 
			
		||||
                SearchType::Name(s) => {
 | 
			
		||||
                SearchType::Normal => {
 | 
			
		||||
                    song.name()
 | 
			
		||||
                        .to_lowercase()
 | 
			
		||||
                        .contains(s)
 | 
			
		||||
                        .contains(&query_text)
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,15 +29,22 @@ pub fn draw(ctx: &egui::Context, state: &mut GuiState, cache_rx: &Receiver<Messa
 | 
			
		|||
                let song_list_width = avail.x - left_nav_width - 35.0;
 | 
			
		||||
                ui.horizontal(|ui| {
 | 
			
		||||
                    ui.set_height(main_height);  
 | 
			
		||||
                    ui.group(|ui| {
 | 
			
		||||
                        ui.set_height(main_height);
 | 
			
		||||
                        ui.set_max_width(left_nav_width);
 | 
			
		||||
                        handle_error_ui!(crate::components::left_nav::LeftNav::draw(ui, state));
 | 
			
		||||
                    ui.vertical(|ui| {
 | 
			
		||||
                        ui.group(|ui| {
 | 
			
		||||
                            //ui.set_height(main_height * 0.1);
 | 
			
		||||
                            ui.set_max_width(left_nav_width);
 | 
			
		||||
                            handle_error_ui!(crate::components::left_nav::header::Header::draw(ui, state));
 | 
			
		||||
                        });
 | 
			
		||||
                        ui.group(|ui| {
 | 
			
		||||
                            // ui.set_height(main_height * 0.9);
 | 
			
		||||
                            ui.set_max_width(left_nav_width);
 | 
			
		||||
                            handle_error_ui!(crate::components::left_nav::LeftNav::draw(ui, state));
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
                    ui.vertical(|ui| {
 | 
			
		||||
                        ui.group(|ui| {
 | 
			
		||||
                            ui.set_width(song_list_width);
 | 
			
		||||
                            handle_error_ui!(crate::components::song_list::song_list_nav::SongListNav::draw(ui, state));
 | 
			
		||||
                            handle_error_ui!(crate::components::song_list::header::Header::draw(ui, state));
 | 
			
		||||
                        });
 | 
			
		||||
                        ui.group(|ui| {
 | 
			
		||||
                            ui.set_width(song_list_width);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,23 @@
 | 
			
		|||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub enum SearchType {
 | 
			
		||||
    Normal,
 | 
			
		||||
    Author,
 | 
			
		||||
    Source,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl SearchType {
 | 
			
		||||
    pub fn from_str(s: &str) -> (Self, String) {
 | 
			
		||||
        match s {
 | 
			
		||||
            i @ _ if i.starts_with("source:") => 
 | 
			
		||||
                (Self::Source, i.strip_prefix("source:").unwrap_or("").to_string().to_lowercase()),
 | 
			
		||||
            i @ _ if i.starts_with("author:") => 
 | 
			
		||||
                (Self::Author, i.strip_prefix("author:").unwrap_or("").to_string().to_lowercase()),
 | 
			
		||||
            i @ _ => (Self::Normal, i.to_string().to_lowercase())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn super_separator(ui: &mut egui::Ui, color: egui::Color32, width: f32, height: f32) {
 | 
			
		||||
    egui::Frame::none()
 | 
			
		||||
        .fill(color)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								xmpd-gui/src/windows/add_song.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								xmpd-gui/src/windows/add_song.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
use super::Window;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
pub struct AddSongW {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Window for AddSongW {
 | 
			
		||||
    fn id() -> super::WindowId where Self: Sized {
 | 
			
		||||
        super::WindowId::AddSongToPl
 | 
			
		||||
    }
 | 
			
		||||
    fn default_title() -> &'static str where Self: Sized {
 | 
			
		||||
        "Add Song to Playlist"
 | 
			
		||||
    }
 | 
			
		||||
    fn draw(&mut self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        ui.label("Hello from other window!");
 | 
			
		||||
        Ok(()) 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +13,12 @@ pub struct DebugW {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl Window for DebugW {
 | 
			
		||||
    fn id() -> super::WindowId where Self: Sized {
 | 
			
		||||
        super::WindowId::Debug
 | 
			
		||||
    }
 | 
			
		||||
    fn default_title() -> &'static str where Self: Sized {
 | 
			
		||||
        "DEBUG WINDOW"
 | 
			
		||||
    }
 | 
			
		||||
    fn draw(&mut self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        ui.group(|ui| {
 | 
			
		||||
            ui.vertical(|ui| {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,12 @@ pub struct ErrorW {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl Window for ErrorW {
 | 
			
		||||
    fn id() -> super::WindowId where Self: Sized {
 | 
			
		||||
        super::WindowId::Error
 | 
			
		||||
    }
 | 
			
		||||
    fn default_title() -> &'static str where Self: Sized {
 | 
			
		||||
        "Error!"
 | 
			
		||||
    }
 | 
			
		||||
    fn draw(&mut self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        ui.label("Hello from other window!");
 | 
			
		||||
        Ok(()) 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,15 +6,22 @@ use crate::GuiState;
 | 
			
		|||
mod debug;
 | 
			
		||||
mod error;
 | 
			
		||||
mod settings;
 | 
			
		||||
mod add_song;
 | 
			
		||||
mod new_song;
 | 
			
		||||
mod new_playlist;
 | 
			
		||||
 | 
			
		||||
lazy_static::lazy_static!(
 | 
			
		||||
    static ref WINDOWS: Arc<Mutex<HashMap<WindowId, Box<dyn Window>>>> = Arc::new(Mutex::new(HashMap::new()));
 | 
			
		||||
    static ref OPEN_WINDOWS: Arc<Mutex<HashSet<WindowId>>> = Arc::new(Mutex::new(HashSet::new()));
 | 
			
		||||
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
pub trait Window: std::fmt::Debug + Send {
 | 
			
		||||
    fn draw(&mut self, ui: &mut egui::Ui, state: &mut GuiState) -> crate::Result<()>;
 | 
			
		||||
    fn id() -> WindowId where Self: Sized;
 | 
			
		||||
    fn default_title() -> &'static str where Self: Sized;
 | 
			
		||||
    fn close(&self) where Self: Sized{
 | 
			
		||||
        OPEN_WINDOWS.lock().unwrap().remove(&Self::id());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Hash, PartialEq, PartialOrd, Ord, Eq)]
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +29,10 @@ pub enum WindowId {
 | 
			
		|||
    Settings,
 | 
			
		||||
    Error,
 | 
			
		||||
    #[cfg(debug_assertions)]
 | 
			
		||||
    Debug
 | 
			
		||||
    Debug,
 | 
			
		||||
    NewPlaylist,
 | 
			
		||||
    NewSong,
 | 
			
		||||
    AddSongToPl,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
| 
						 | 
				
			
			@ -40,18 +50,21 @@ impl Windows {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn add_all_windows(&mut self) {
 | 
			
		||||
        self.add_new_window(WindowId::Error, "Error!", Box::<error::ErrorW>::default());
 | 
			
		||||
        self.add_new_window(WindowId::Settings, "Settings", Box::<settings::SettingsW>::default());
 | 
			
		||||
        #[cfg(debug_assertions)]
 | 
			
		||||
        self.add_new_window(WindowId::Debug, "Debug", Box::<debug::DebugW>::default());
 | 
			
		||||
        self.add_new_window::<debug::DebugW>();
 | 
			
		||||
        self.add_new_window::<error::ErrorW>();
 | 
			
		||||
        self.add_new_window::<settings::SettingsW>();
 | 
			
		||||
        self.add_new_window::<add_song::AddSongW>();
 | 
			
		||||
        self.add_new_window::<new_song::NewSongW>();
 | 
			
		||||
        self.add_new_window::<new_playlist::NewPlaylistW>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn add_new_window(&mut self, id: WindowId, title: &str, cb: Box<dyn Window>) {
 | 
			
		||||
    pub fn add_new_window<WT: Window + Default + 'static>(&mut self) {
 | 
			
		||||
        let builder = ViewportBuilder::default()
 | 
			
		||||
            .with_window_type(egui::X11WindowType::Dialog)
 | 
			
		||||
            .with_title(title);
 | 
			
		||||
        self.windows.insert(id.clone(), (ViewportId::from_hash_of(id.clone()), builder));
 | 
			
		||||
        WINDOWS.lock().unwrap().insert(id, cb);
 | 
			
		||||
            .with_title(WT::default_title());
 | 
			
		||||
        self.windows.insert(WT::id(), (ViewportId::from_hash_of(WT::id()), builder));
 | 
			
		||||
        WINDOWS.lock().unwrap().insert(WT::id(), Box::<WT>::default());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn draw_all(&mut self, ctx: &egui::Context, state: &mut GuiState) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										102
									
								
								xmpd-gui/src/windows/new_playlist.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								xmpd-gui/src/windows/new_playlist.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,102 @@
 | 
			
		|||
use std::str::FromStr;
 | 
			
		||||
 | 
			
		||||
use egui::{Sense, Vec2};
 | 
			
		||||
use xmpd_manifest::{playlist::{self, Playlist}, store::BaseStore};
 | 
			
		||||
 | 
			
		||||
use super::{Window, WindowId};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct NewPlaylistW {
 | 
			
		||||
    name: String,
 | 
			
		||||
    author: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for NewPlaylistW {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            name: String::from("New Playlist"),
 | 
			
		||||
            author: String::from("Unknown"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Window for NewPlaylistW {
 | 
			
		||||
    fn id() -> WindowId where Self: Sized {
 | 
			
		||||
        WindowId::NewPlaylist
 | 
			
		||||
    }
 | 
			
		||||
    fn default_title() -> &'static str where Self: Sized {
 | 
			
		||||
        "New Playlist"
 | 
			
		||||
    }
 | 
			
		||||
    fn draw(&mut self, ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        let theme = xmpd_settings::Settings::get()?.theme.clone();
 | 
			
		||||
        let img_size = 64.0;
 | 
			
		||||
        let img_spacing = 10.0;
 | 
			
		||||
        ui.vertical(|ui| {
 | 
			
		||||
            ui.horizontal(|ui| {
 | 
			
		||||
                let mut rect = egui::Rect::ZERO;
 | 
			
		||||
                rect.set_width(img_size);
 | 
			
		||||
                rect.set_height(img_size);
 | 
			
		||||
                rect.set_top(img_spacing);
 | 
			
		||||
                rect.set_left(img_spacing);
 | 
			
		||||
                let rect_int = ui.interact(rect, "new_playlist_w".into(), Sense::click());
 | 
			
		||||
                if rect_int.hovered() {
 | 
			
		||||
                    ui.allocate_ui_at_rect(rect, |ui| {
 | 
			
		||||
                        ui.group(|ui| {
 | 
			
		||||
                            let img = egui::Image::new(crate::data::PLUS_ICON)
 | 
			
		||||
                                .tint(theme.accent_color)
 | 
			
		||||
                                .fit_to_exact_size(Vec2::new(img_size, img_size));
 | 
			
		||||
                                //.paint_at(ui, rect);
 | 
			
		||||
                            ui.add(img);
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
   
 | 
			
		||||
                } else {
 | 
			
		||||
                    ui.allocate_ui_at_rect(rect, |ui| {
 | 
			
		||||
                        ui.group(|ui| {
 | 
			
		||||
                            let img = egui::Image::new(crate::data::NOTE_ICON)
 | 
			
		||||
                                .tint(theme.accent_color)
 | 
			
		||||
                                .fit_to_exact_size(Vec2::new(img_size, img_size));
 | 
			
		||||
                                //.paint_at(ui, rect);
 | 
			
		||||
                            ui.add(img);
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                if rect_int.clicked() {
 | 
			
		||||
                    // TODO: Add a way to add custom icons
 | 
			
		||||
                }
 | 
			
		||||
                ui.vertical(|ui| {
 | 
			
		||||
                    ui.add_space(img_spacing);
 | 
			
		||||
                    ui.horizontal(|ui| { 
 | 
			
		||||
                        ui.label("Name:   ");
 | 
			
		||||
                        ui.text_edit_singleline(&mut self.name);
 | 
			
		||||
                    });
 | 
			
		||||
                    ui.horizontal(|ui| { 
 | 
			
		||||
                        ui.label("Author: ");
 | 
			
		||||
                        ui.text_edit_singleline(&mut self.author);
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
            ui.with_layout(egui::Layout::bottom_up(egui::Align::Max), |ui| {
 | 
			
		||||
                ui.add_space(3.0);
 | 
			
		||||
                ui.horizontal(|ui| {
 | 
			
		||||
                    ui.add_space(3.0);
 | 
			
		||||
                    if ui.button("Cancel").clicked() {
 | 
			
		||||
                        self.author = String::from("New Playlist");
 | 
			
		||||
                        self.name = String::from("Unknown");
 | 
			
		||||
                        state.windows.toggle(&WindowId::NewPlaylist, false);
 | 
			
		||||
                    }
 | 
			
		||||
                    if ui.button("Add").clicked() {
 | 
			
		||||
                        let mut playlist = Playlist::default();
 | 
			
		||||
                        playlist.set_name(&self.name);
 | 
			
		||||
                        playlist.set_author(&self.author);
 | 
			
		||||
                        let playlists = state.manifest.store_mut().get_playlists_mut();
 | 
			
		||||
                        playlists.insert(uuid::Uuid::new_v4(), playlist);
 | 
			
		||||
                        state.windows.toggle(&WindowId::NewPlaylist, false);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        Ok(()) 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								xmpd-gui/src/windows/new_song.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								xmpd-gui/src/windows/new_song.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
use super::Window;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
pub struct NewSongW {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Window for NewSongW {
 | 
			
		||||
    fn id() -> super::WindowId where Self: Sized {
 | 
			
		||||
        super::WindowId::NewSong
 | 
			
		||||
    }
 | 
			
		||||
    fn default_title() -> &'static str where Self: Sized {
 | 
			
		||||
        "New Song"
 | 
			
		||||
    }
 | 
			
		||||
    fn draw(&mut self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        ui.label("Hello from other window!");
 | 
			
		||||
        Ok(()) 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +25,12 @@ impl Default for SettingsW {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
impl Window for SettingsW {
 | 
			
		||||
    fn id() -> super::WindowId where Self: Sized {
 | 
			
		||||
        super::WindowId::Settings
 | 
			
		||||
    }
 | 
			
		||||
    fn default_title() -> &'static str where Self: Sized {
 | 
			
		||||
        "Settings"
 | 
			
		||||
    }
 | 
			
		||||
    #[allow(irrefutable_let_patterns)]
 | 
			
		||||
    fn draw(&mut self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
 | 
			
		||||
        ui.group(|ui| {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user