client: library: 'more' menu split up into two columns

This commit is contained in:
Mark 2023-10-04 19:53:58 +02:00
parent 6bab2bc075
commit 59ae8c06b0
2 changed files with 58 additions and 105 deletions

View File

@ -385,6 +385,10 @@ impl GuiElemCfg {
self.drag_target = true; self.drag_target = true;
self self
} }
pub fn force_redraw(mut self) -> Self {
self.redraw = true;
self
}
pub fn disabled(mut self) -> Self { pub fn disabled(mut self) -> Self {
self.enabled = false; self.enabled = false;
self self

View File

@ -8,7 +8,6 @@ use std::{
}, },
}; };
use clap::builder::StringValueParser;
use musicdb_lib::data::{ use musicdb_lib::data::{
album::Album, album::Album,
artist::Artist, artist::Artist,
@ -69,7 +68,6 @@ pub struct LibraryBrowser {
filter_songs: Rc<Mutex<Filter>>, filter_songs: Rc<Mutex<Filter>>,
filter_albums: Rc<Mutex<Filter>>, filter_albums: Rc<Mutex<Filter>>,
filter_artists: Rc<Mutex<Filter>>, filter_artists: Rc<Mutex<Filter>>,
do_something_sender: mpsc::Sender<Box<dyn FnOnce(&mut Self)>>,
do_something_receiver: mpsc::Receiver<Box<dyn FnOnce(&mut Self)>>, do_something_receiver: mpsc::Receiver<Box<dyn FnOnce(&mut Self)>>,
} }
impl Clone for LibraryBrowser { impl Clone for LibraryBrowser {
@ -269,7 +267,6 @@ impl LibraryBrowser {
filter_songs, filter_songs,
filter_albums, filter_albums,
filter_artists, filter_artists,
do_something_sender,
do_something_receiver, do_something_receiver,
} }
} }
@ -1169,17 +1166,10 @@ impl FilterPanel {
let ssc1 = Rc::clone(&search_settings_changed); let ssc1 = Rc::clone(&search_settings_changed);
let ssc2 = Rc::clone(&search_settings_changed); let ssc2 = Rc::clone(&search_settings_changed);
let ssc3 = Rc::clone(&search_settings_changed); let ssc3 = Rc::clone(&search_settings_changed);
let ssc4 = Rc::clone(&search_settings_changed);
let ssc5 = Rc::clone(&search_settings_changed);
let ssc6 = Rc::clone(&search_settings_changed);
let ssc7 = Rc::clone(&search_settings_changed);
let sel3 = selected.clone(); let sel3 = selected.clone();
let sel4 = selected.clone(); const VSPLIT: f32 = 0.4;
let sel5 = selected.clone();
let sel6 = selected.clone();
let sel7 = selected.clone();
let tab_main = GuiElem::new(ScrollBox::new( let tab_main = GuiElem::new(ScrollBox::new(
GuiElemCfg::default(), GuiElemCfg::at(Rectangle::from_tuples((0.0, 0.0), (VSPLIT, 1.0))),
crate::gui_base::ScrollBoxSizeUnit::Pixels, crate::gui_base::ScrollBoxSizeUnit::Pixels,
vec![ vec![
( (
@ -1315,7 +1305,7 @@ impl FilterPanel {
))], ))],
)), )),
GuiElem::new(Button::new( GuiElem::new(Button::new(
GuiElemCfg::at(Rectangle::from_tuples((0.55, 0.0), (0.65, 1.0))), GuiElemCfg::at(Rectangle::from_tuples((0.55, 0.0), (0.75, 1.0))),
{ {
let dss = do_something_sender.clone(); let dss = do_something_sender.clone();
move |_| { move |_| {
@ -1347,7 +1337,7 @@ impl FilterPanel {
))], ))],
)), )),
GuiElem::new(Button::new( GuiElem::new(Button::new(
GuiElemCfg::at(Rectangle::from_tuples((0.7, 0.0), (0.8, 1.0))), GuiElemCfg::at(Rectangle::from_tuples((0.8, 0.0), (1.0, 1.0))),
{ {
let dss = do_something_sender.clone(); let dss = do_something_sender.clone();
move |_| { move |_| {
@ -1356,8 +1346,11 @@ impl FilterPanel {
.store(true, std::sync::atomic::Ordering::Relaxed); .store(true, std::sync::atomic::Ordering::Relaxed);
let mut sel = s.selected.0.lock().unwrap(); let mut sel = s.selected.0.lock().unwrap();
for (_, _, albums, _) in &s.library_filtered { for (_, _, albums, _) in &s.library_filtered {
for (id, _, _) in albums { for (id, album, _) in albums {
sel.1.insert(*id); sel.1.insert(*id);
for (s, _) in album {
sel.2.insert(*s);
}
} }
} }
})) }))
@ -1373,31 +1366,6 @@ impl FilterPanel {
Vec2::new(0.5, 0.5), Vec2::new(0.5, 0.5),
))], ))],
)), )),
GuiElem::new(Button::new(
GuiElemCfg::at(Rectangle::from_tuples((0.85, 0.0), (0.95, 1.0))),
{
let dss = do_something_sender.clone();
move |_| {
dss.send(Box::new(|s| {
s.search_settings_changed
.store(true, std::sync::atomic::Ordering::Relaxed);
let mut sel = s.selected.0.lock().unwrap();
for (id, _, _, _) in &s.library_filtered {
sel.0.insert(*id);
}
}))
.unwrap();
vec![]
}
},
vec![GuiElem::new(Label::new(
GuiElemCfg::default(),
"artists".to_owned(),
Color::GRAY,
None,
Vec2::new(0.5, 0.5),
))],
)),
], ],
)), )),
1.0, 1.0,
@ -1405,17 +1373,17 @@ impl FilterPanel {
], ],
)); ));
let tab_filters_songs = GuiElem::new(ScrollBox::new( let tab_filters_songs = GuiElem::new(ScrollBox::new(
GuiElemCfg::default().disabled(), GuiElemCfg::at(Rectangle::from_tuples((VSPLIT, 0.0), (1.0, 1.0))),
crate::gui_base::ScrollBoxSizeUnit::Pixels, crate::gui_base::ScrollBoxSizeUnit::Pixels,
vec![], vec![],
)); ));
let tab_filters_albums = GuiElem::new(ScrollBox::new( let tab_filters_albums = GuiElem::new(ScrollBox::new(
GuiElemCfg::default().disabled(), GuiElemCfg::at(Rectangle::from_tuples((VSPLIT, 0.0), (1.0, 1.0))).disabled(),
crate::gui_base::ScrollBoxSizeUnit::Pixels, crate::gui_base::ScrollBoxSizeUnit::Pixels,
vec![], vec![],
)); ));
let tab_filters_artists = GuiElem::new(ScrollBox::new( let tab_filters_artists = GuiElem::new(ScrollBox::new(
GuiElemCfg::default().disabled(), GuiElemCfg::at(Rectangle::from_tuples((VSPLIT, 0.0), (1.0, 1.0))).disabled(),
crate::gui_base::ScrollBoxSizeUnit::Pixels, crate::gui_base::ScrollBoxSizeUnit::Pixels,
vec![], vec![],
)); ));
@ -1428,18 +1396,12 @@ impl FilterPanel {
config: GuiElemCfg::default().disabled(), config: GuiElemCfg::default().disabled(),
children: vec![ children: vec![
GuiElem::new(Panel::new( GuiElem::new(Panel::new(
GuiElemCfg::at(Rectangle::from_tuples((0.0, 0.0), (1.0, HEIGHT))), GuiElemCfg::at(Rectangle::from_tuples((VSPLIT, 0.0), (1.0, HEIGHT))),
vec![ vec![
GuiElem::new(Button::new( GuiElem::new(Button::new(
GuiElemCfg::at(Rectangle::from_tuples((0.0, 0.0), (0.33, 1.0))), GuiElemCfg::at(Rectangle::from_tuples((0.0, 0.0), (0.33, 1.0))),
move |_| { move |_| {
let v = if set_tab_1.load(std::sync::atomic::Ordering::Relaxed) != 1 set_tab_1.store(0, std::sync::atomic::Ordering::Relaxed);
{
1
} else {
0
};
set_tab_1.store(v, std::sync::atomic::Ordering::Relaxed);
vec![] vec![]
}, },
vec![GuiElem::new(Label::new( vec![GuiElem::new(Label::new(
@ -1453,13 +1415,7 @@ impl FilterPanel {
GuiElem::new(Button::new( GuiElem::new(Button::new(
GuiElemCfg::at(Rectangle::from_tuples((0.33, 0.0), (0.67, 1.0))), GuiElemCfg::at(Rectangle::from_tuples((0.33, 0.0), (0.67, 1.0))),
move |_| { move |_| {
let v = if set_tab_2.load(std::sync::atomic::Ordering::Relaxed) != 2 set_tab_2.store(1, std::sync::atomic::Ordering::Relaxed);
{
2
} else {
0
};
set_tab_2.store(v, std::sync::atomic::Ordering::Relaxed);
vec![] vec![]
}, },
vec![GuiElem::new(Label::new( vec![GuiElem::new(Label::new(
@ -1473,13 +1429,7 @@ impl FilterPanel {
GuiElem::new(Button::new( GuiElem::new(Button::new(
GuiElemCfg::at(Rectangle::from_tuples((0.67, 0.0), (1.0, 1.0))), GuiElemCfg::at(Rectangle::from_tuples((0.67, 0.0), (1.0, 1.0))),
move |_| { move |_| {
let v = if set_tab_3.load(std::sync::atomic::Ordering::Relaxed) != 3 set_tab_3.store(2, std::sync::atomic::Ordering::Relaxed);
{
3
} else {
0
};
set_tab_3.store(v, std::sync::atomic::Ordering::Relaxed);
vec![] vec![]
}, },
vec![GuiElem::new(Label::new( vec![GuiElem::new(Label::new(
@ -1494,13 +1444,9 @@ impl FilterPanel {
)), )),
GuiElem::new(Panel::new( GuiElem::new(Panel::new(
GuiElemCfg::at(Rectangle::from_tuples((0.0, HEIGHT), (1.0, 1.0))), GuiElemCfg::at(Rectangle::from_tuples((0.0, HEIGHT), (1.0, 1.0))),
vec![ vec![tab_filters_songs, tab_filters_albums, tab_filters_artists],
tab_main,
tab_filters_songs,
tab_filters_albums,
tab_filters_artists,
],
)), )),
tab_main,
], ],
line_height: 0.0, line_height: 0.0,
search_settings_changed, search_settings_changed,
@ -1788,6 +1734,10 @@ impl GuiElemTrait for FilterPanel {
fn draw(&mut self, info: &mut DrawInfo, _g: &mut speedy2d::Graphics2D) { fn draw(&mut self, info: &mut DrawInfo, _g: &mut speedy2d::Graphics2D) {
// set line height // set line height
if info.line_height != self.line_height { if info.line_height != self.line_height {
let sb = self.children[2].try_as_mut::<ScrollBox>().unwrap();
for (_, h) in &mut sb.children {
*h = info.line_height;
}
for c in &mut self.children[1].inner.children() { for c in &mut self.children[1].inner.children() {
if let Some(sb) = c.try_as_mut::<ScrollBox>() { if let Some(sb) = c.try_as_mut::<ScrollBox>() {
for (_, h) in &mut sb.children { for (_, h) in &mut sb.children {
@ -1800,7 +1750,9 @@ impl GuiElemTrait for FilterPanel {
// maybe switch tabs // maybe switch tabs
let mut new_tab = self.new_tab.load(std::sync::atomic::Ordering::Relaxed); let mut new_tab = self.new_tab.load(std::sync::atomic::Ordering::Relaxed);
let mut load_tab = false; let mut load_tab = false;
if new_tab != self.tab { if new_tab != usize::MAX {
self.new_tab
.store(usize::MAX, std::sync::atomic::Ordering::Relaxed);
load_tab = true; load_tab = true;
if new_tab == usize::MAX { if new_tab == usize::MAX {
self.new_tab self.new_tab
@ -1823,41 +1775,37 @@ impl GuiElemTrait for FilterPanel {
.inner .inner
.config_mut() .config_mut()
.enabled = true; .enabled = true;
if self.tab > 0 { *self.children[0]
*self.children[0] .inner
.inner .children()
.children() .nth(self.tab)
.nth(self.tab - 1) .unwrap()
.unwrap() .try_as_mut::<Button>()
.try_as_mut::<Button>() .unwrap()
.unwrap() .children[0]
.children[0] .try_as_mut::<Label>()
.try_as_mut::<Label>() .unwrap()
.unwrap() .content
.content .color() = Color::GRAY;
.color() = Color::GRAY; *self.children[0]
} .inner
if new_tab > 0 { .children()
*self.children[0] .nth(new_tab)
.inner .unwrap()
.children() .try_as_mut::<Button>()
.nth(new_tab - 1) .unwrap()
.unwrap() .children[0]
.try_as_mut::<Button>() .try_as_mut::<Label>()
.unwrap() .unwrap()
.children[0] .content
.try_as_mut::<Label>() .color() = Color::WHITE;
.unwrap()
.content
.color() = Color::WHITE;
}
self.tab = new_tab; self.tab = new_tab;
} }
} }
// load tab // load tab
if load_tab { if load_tab {
match new_tab { match new_tab {
1 | 2 | 3 => { 0 | 1 | 2 => {
let sb = self.children[1] let sb = self.children[1]
.inner .inner
.children() .children()
@ -1866,18 +1814,19 @@ impl GuiElemTrait for FilterPanel {
.try_as_mut::<ScrollBox>() .try_as_mut::<ScrollBox>()
.unwrap(); .unwrap();
let ssc = Rc::clone(&self.search_settings_changed); let ssc = Rc::clone(&self.search_settings_changed);
let my_tab = new_tab;
let ntab = Rc::clone(&self.new_tab); let ntab = Rc::clone(&self.new_tab);
sb.children = Self::build_filter( sb.children = Self::build_filter(
match new_tab { match new_tab {
1 => &self.filter_songs, 0 => &self.filter_songs,
2 => &self.filter_albums, 1 => &self.filter_albums,
3 => &self.filter_artists, 2 => &self.filter_artists,
_ => unreachable!(), _ => unreachable!(),
}, },
info.line_height, info.line_height,
&Rc::new(move |update_ui| { &Rc::new(move |update_ui| {
if update_ui { if update_ui {
ntab.store(usize::MAX, std::sync::atomic::Ordering::Relaxed); ntab.store(my_tab, std::sync::atomic::Ordering::Relaxed);
} }
ssc.store(true, std::sync::atomic::Ordering::Relaxed); ssc.store(true, std::sync::atomic::Ordering::Relaxed);
}), }),