mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47: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_editor::MediumEditor;
|
||||||
use super::medium_preview::MediumPreview;
|
use super::medium_preview::MediumPreview;
|
||||||
use crate::navigator::{NavigationHandle, Screen};
|
use crate::navigator::{NavigationHandle, Screen};
|
||||||
|
use crate::selectors::MediumSelector;
|
||||||
use crate::widgets::Widget;
|
use crate::widgets::Widget;
|
||||||
use glib::clone;
|
use glib::clone;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
@ -144,7 +145,11 @@ impl Screen<Arc<ImportSession>, ()> for ImportScreen {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
select_button.connect_clicked(clone!(@weak this => move |_| {
|
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 |_| {
|
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 mod instrument;
|
||||||
pub use instrument::*;
|
pub use instrument::*;
|
||||||
|
|
||||||
|
pub mod medium;
|
||||||
|
pub use medium::*;
|
||||||
|
|
||||||
pub mod person;
|
pub mod person;
|
||||||
pub use person::*;
|
pub use person::*;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue