use musicdb_lib::data::{database::Database, AlbumId, ArtistId, SongId}; use regex::{Regex, RegexBuilder}; use speedy2d::{ color::Color, dimen::Vec2, shape::Rectangle, window::{MouseButton, VirtualKeyCode}, }; use crate::{ gui::{Dragging, DrawInfo, GuiAction, GuiElem, GuiElemCfg, GuiElemTrait}, gui_base::ScrollBox, gui_text::{Label, TextField}, gui_wrappers::WithFocusHotkey, }; /* This is responsible for showing the library, with Regex search and drag-n-drop. */ #[derive(Clone)] pub struct LibraryBrowser { config: GuiElemCfg, pub children: Vec, search_artist: String, search_artist_regex: Option, search_album: String, search_album_regex: Option, search_song: String, search_song_regex: Option, } fn search_regex_new(pat: &str) -> Result { RegexBuilder::new(pat) .unicode(true) .case_insensitive(true) .build() } impl LibraryBrowser { pub fn new(config: GuiElemCfg) -> Self { let search_artist = TextField::new( GuiElemCfg::at(Rectangle::from_tuples((0.01, 0.01), (0.45, 0.05))), "artist".to_string(), Color::GRAY, Color::WHITE, ); let search_album = TextField::new( GuiElemCfg::at(Rectangle::from_tuples((0.55, 0.01), (0.99, 0.05))), "album".to_string(), Color::GRAY, Color::WHITE, ); let search_song = WithFocusHotkey::new_ctrl( VirtualKeyCode::F, TextField::new( GuiElemCfg::at(Rectangle::from_tuples((0.01, 0.06), (0.99, 0.1))), "song".to_string(), Color::GRAY, Color::WHITE, ), ); let library_scroll_box = ScrollBox::new( GuiElemCfg::at(Rectangle::from_tuples((0.0, 0.1), (1.0, 1.0))), crate::gui_base::ScrollBoxSizeUnit::Pixels, vec![], ); Self { config, children: vec![ GuiElem::new(search_artist), GuiElem::new(search_album), GuiElem::new(search_song), GuiElem::new(library_scroll_box), ], search_artist: String::new(), search_artist_regex: None, search_album: String::new(), search_album_regex: None, search_song: String::new(), search_song_regex: None, } } } impl GuiElemTrait for LibraryBrowser { fn config(&self) -> &GuiElemCfg { &self.config } fn config_mut(&mut self) -> &mut GuiElemCfg { &mut self.config } fn children(&mut self) -> Box + '_> { Box::new(self.children.iter_mut()) } fn any(&self) -> &dyn std::any::Any { self } fn any_mut(&mut self) -> &mut dyn std::any::Any { self } fn clone_gui(&self) -> Box { Box::new(self.clone()) } fn draw(&mut self, info: &mut DrawInfo, _g: &mut speedy2d::Graphics2D) { let mut search_changed = false; { let v = &mut self.children[0].try_as_mut::().unwrap().children[0] .try_as_mut::