mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 19:57:25 +01:00
Add medium selector
This commit is contained in:
parent
f4254cc431
commit
2d5ce29aae
3 changed files with 195 additions and 1 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use super::medium_editor::MediumEditor;
|
||||
use super::medium_preview::MediumPreview;
|
||||
use crate::navigator::{NavigationHandle, Screen};
|
||||
use crate::selectors::MediumSelector;
|
||||
use crate::widgets::Widget;
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
|
|
@ -144,7 +145,11 @@ impl Screen<Arc<ImportSession>, ()> for ImportScreen {
|
|||
}));
|
||||
|
||||
select_button.connect_clicked(clone!(@weak this => move |_| {
|
||||
debug!("TODO: Show medium selector.");
|
||||
spawn!(@clone this, async move {
|
||||
if let Some(medium) = push!(this.handle, MediumSelector).await {
|
||||
this.select_medium(medium);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
add_button.connect_clicked(clone!(@weak this => move |_| {
|
||||
|
|
|
|||
186
musicus/src/selectors/medium.rs
Normal file
186
musicus/src/selectors/medium.rs
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
use super::selector::Selector;
|
||||
use crate::navigator::{NavigationHandle, Screen};
|
||||
use crate::widgets::Widget;
|
||||
use gettextrs::gettext;
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
use libadwaita::prelude::*;
|
||||
use musicus_backend::db::{Person, Ensemble, Medium};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Either a person or an ensemble to be shown in the list.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PersonOrEnsemble {
|
||||
Person(Person),
|
||||
Ensemble(Ensemble),
|
||||
}
|
||||
|
||||
impl PersonOrEnsemble {
|
||||
/// Get a short textual representation of the item.
|
||||
pub fn get_title(&self) -> String {
|
||||
match self {
|
||||
PersonOrEnsemble::Person(person) => person.name_lf(),
|
||||
PersonOrEnsemble::Ensemble(ensemble) => ensemble.name.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A screen for selecting a medium.
|
||||
pub struct MediumSelector {
|
||||
handle: NavigationHandle<Medium>,
|
||||
selector: Rc<Selector<PersonOrEnsemble>>,
|
||||
}
|
||||
|
||||
impl Screen<(), Medium> for MediumSelector {
|
||||
fn new(_: (), handle: NavigationHandle<Medium>) -> Rc<Self> {
|
||||
// Create UI
|
||||
|
||||
let selector = Selector::<PersonOrEnsemble>::new();
|
||||
selector.set_title(&gettext("Select performer"));
|
||||
|
||||
let this = Rc::new(Self {
|
||||
handle,
|
||||
selector,
|
||||
});
|
||||
|
||||
// Connect signals and callbacks
|
||||
|
||||
this.selector.set_back_cb(clone!(@weak this => move || {
|
||||
this.handle.pop(None);
|
||||
}));
|
||||
|
||||
this.selector.set_load_online(clone!(@weak this => move || {
|
||||
async move {
|
||||
let mut poes = Vec::new();
|
||||
|
||||
let persons = this.handle.backend.db().get_persons().await?;
|
||||
let ensembles = this.handle.backend.db().get_ensembles().await?;
|
||||
|
||||
for person in persons {
|
||||
poes.push(PersonOrEnsemble::Person(person));
|
||||
}
|
||||
|
||||
for ensemble in ensembles {
|
||||
poes.push(PersonOrEnsemble::Ensemble(ensemble));
|
||||
}
|
||||
|
||||
Ok(poes)
|
||||
}
|
||||
}));
|
||||
|
||||
this.selector.set_load_local(clone!(@weak this => move || {
|
||||
async move {
|
||||
let mut poes = Vec::new();
|
||||
|
||||
let persons = this.handle.backend.cl().get_persons().await.unwrap();
|
||||
let ensembles = this.handle.backend.cl().get_ensembles().await.unwrap();
|
||||
|
||||
for person in persons {
|
||||
poes.push(PersonOrEnsemble::Person(person));
|
||||
}
|
||||
|
||||
for ensemble in ensembles {
|
||||
poes.push(PersonOrEnsemble::Ensemble(ensemble));
|
||||
}
|
||||
|
||||
poes
|
||||
}
|
||||
}));
|
||||
|
||||
this.selector.set_make_widget(clone!(@weak this => move |poe| {
|
||||
let row = libadwaita::ActionRow::new();
|
||||
row.set_activatable(true);
|
||||
row.set_title(Some(&poe.get_title()));
|
||||
|
||||
let poe = poe.to_owned();
|
||||
row.connect_activated(clone!(@weak this => move |_| {
|
||||
let poe = poe.clone();
|
||||
spawn!(@clone this, async move {
|
||||
if let Some(medium) = push!(this.handle, MediumSelectorMediumScreen, poe).await {
|
||||
this.handle.pop(Some(medium));
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
row.upcast()
|
||||
}));
|
||||
|
||||
this.selector
|
||||
.set_filter(|search, poe| poe.get_title().to_lowercase().contains(search));
|
||||
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for MediumSelector {
|
||||
fn get_widget(&self) -> gtk::Widget {
|
||||
self.selector.widget.clone().upcast()
|
||||
}
|
||||
}
|
||||
|
||||
/// The actual medium selector that is displayed after the user has selected a person or ensemble.
|
||||
struct MediumSelectorMediumScreen {
|
||||
handle: NavigationHandle<Medium>,
|
||||
poe: PersonOrEnsemble,
|
||||
selector: Rc<Selector<Medium>>,
|
||||
}
|
||||
|
||||
impl Screen<PersonOrEnsemble, Medium> for MediumSelectorMediumScreen {
|
||||
fn new(poe: PersonOrEnsemble, handle: NavigationHandle<Medium>) -> Rc<Self> {
|
||||
let selector = Selector::<Medium>::new();
|
||||
selector.set_title(&gettext("Select medium"));
|
||||
selector.set_subtitle(&poe.get_title());
|
||||
|
||||
let this = Rc::new(Self {
|
||||
handle,
|
||||
poe,
|
||||
selector,
|
||||
});
|
||||
|
||||
this.selector.set_back_cb(clone!(@weak this => move || {
|
||||
this.handle.pop(None);
|
||||
}));
|
||||
|
||||
match this.poe.clone() {
|
||||
PersonOrEnsemble::Person(person) => {
|
||||
// this.selector.set_load_online(clone!(@weak this => move || {
|
||||
// async move { this.handle.backend.cl().get_mediums_for_person(&person.id).await }
|
||||
// }));
|
||||
|
||||
this.selector.set_load_local(clone!(@weak this => move || {
|
||||
let person = person.clone();
|
||||
async move { this.handle.backend.db().get_mediums_for_person(&person.id).await.unwrap() }
|
||||
}));
|
||||
}
|
||||
PersonOrEnsemble::Ensemble(ensemble) => {
|
||||
this.selector.set_load_local(clone!(@weak this => move || {
|
||||
let ensemble = ensemble.clone();
|
||||
async move { this.handle.backend.db().get_mediums_for_ensemble(&ensemble.id).await.unwrap() }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
this.selector.set_make_widget(clone!(@weak this => move |medium| {
|
||||
let row = libadwaita::ActionRow::new();
|
||||
row.set_activatable(true);
|
||||
row.set_title(Some(&medium.name));
|
||||
|
||||
let medium = medium.to_owned();
|
||||
row.connect_activated(clone!(@weak this => move |_| {
|
||||
this.handle.pop(Some(medium.clone()));
|
||||
}));
|
||||
|
||||
row.upcast()
|
||||
}));
|
||||
|
||||
this.selector.set_filter(|search, medium| medium.name.to_lowercase().contains(search));
|
||||
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for MediumSelectorMediumScreen {
|
||||
fn get_widget(&self) -> gtk::Widget {
|
||||
self.selector.widget.clone().upcast()
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,9 @@ pub use ensemble::*;
|
|||
pub mod instrument;
|
||||
pub use instrument::*;
|
||||
|
||||
pub mod medium;
|
||||
pub use medium::*;
|
||||
|
||||
pub mod person;
|
||||
pub use person::*;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue