mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47:25 +01:00
editor: Add album editor
This commit is contained in:
parent
c4162fd98a
commit
a16dc446d6
8 changed files with 638 additions and 116 deletions
|
|
@ -10,7 +10,7 @@ use gtk::glib::{self, Boxed};
|
|||
use super::{schema::*, tables, TranslatedString};
|
||||
|
||||
// Re-exports for tables that don't need additional information.
|
||||
pub use tables::{Album, Instrument, Person, Role};
|
||||
pub use tables::{Instrument, Person, Role};
|
||||
|
||||
#[derive(Boxed, Clone, Debug)]
|
||||
#[boxed_type(name = "MusicusWork")]
|
||||
|
|
@ -68,6 +68,14 @@ pub struct Track {
|
|||
pub works: Vec<Work>,
|
||||
}
|
||||
|
||||
#[derive(Boxed, Clone, Debug)]
|
||||
#[boxed_type(name = "MusicusAlbum")]
|
||||
pub struct Album {
|
||||
pub album_id: String,
|
||||
pub name: TranslatedString,
|
||||
pub recordings: Vec<Recording>,
|
||||
}
|
||||
|
||||
impl Eq for Person {}
|
||||
impl PartialEq for Person {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
|
|
@ -268,6 +276,13 @@ impl Recording {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for Recording {}
|
||||
impl PartialEq for Recording {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.recording_id == other.recording_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Recording {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}; {}", self.work, self.performers_string())
|
||||
|
|
@ -360,9 +375,35 @@ impl Track {
|
|||
}
|
||||
}
|
||||
|
||||
impl Album {
|
||||
pub fn from_table(data: tables::Album, connection: &mut SqliteConnection) -> Result<Self> {
|
||||
let recordings: Vec<Recording> = recordings::table
|
||||
.inner_join(album_recordings::table)
|
||||
.order(album_recordings::sequence_number)
|
||||
.filter(album_recordings::album_id.eq(&data.album_id))
|
||||
.select(tables::Recording::as_select())
|
||||
.load(connection)?
|
||||
.into_iter()
|
||||
.map(|r| Recording::from_table(r, connection))
|
||||
.collect::<Result<Vec<Recording>>>()?;
|
||||
|
||||
Ok(Self {
|
||||
album_id: data.album_id,
|
||||
name: data.name,
|
||||
recordings,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Album {}
|
||||
impl PartialEq for Album {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.album_id == other.album_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Album {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
208
src/editor/album_editor.rs
Normal file
208
src/editor/album_editor.rs
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
use crate::{
|
||||
db::models::{Album, Recording},
|
||||
editor::{
|
||||
recording_editor::MusicusRecordingEditor,
|
||||
recording_selector_popover::RecordingSelectorPopover,
|
||||
translation_editor::MusicusTranslationEditor,
|
||||
},
|
||||
library::MusicusLibrary,
|
||||
};
|
||||
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gettextrs::gettext;
|
||||
use gtk::glib::{
|
||||
clone, Properties,
|
||||
{self, subclass::Signal},
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use std::cell::{OnceCell, RefCell};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, gtk::CompositeTemplate, Properties)]
|
||||
#[properties(wrapper_type = super::AlbumEditor)]
|
||||
#[template(file = "data/ui/album_editor.blp")]
|
||||
pub struct AlbumEditor {
|
||||
#[property(get, construct_only)]
|
||||
pub navigation: OnceCell<adw::NavigationView>,
|
||||
#[property(get, construct_only)]
|
||||
pub library: OnceCell<MusicusLibrary>,
|
||||
|
||||
pub album_id: OnceCell<String>,
|
||||
pub recordings: RefCell<Vec<Recording>>,
|
||||
|
||||
pub recordings_popover: OnceCell<RecordingSelectorPopover>,
|
||||
|
||||
#[template_child]
|
||||
pub name_editor: TemplateChild<MusicusTranslationEditor>,
|
||||
#[template_child]
|
||||
pub recordings_list: TemplateChild<gtk::ListBox>,
|
||||
#[template_child]
|
||||
pub select_recording_box: TemplateChild<gtk::Box>,
|
||||
#[template_child]
|
||||
pub save_row: TemplateChild<adw::ButtonRow>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for AlbumEditor {
|
||||
const NAME: &'static str = "MusicusAlbumEditor";
|
||||
type Type = super::AlbumEditor;
|
||||
type ParentType = adw::NavigationPage;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
MusicusTranslationEditor::static_type();
|
||||
klass.bind_template();
|
||||
klass.bind_template_instance_callbacks();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for AlbumEditor {
|
||||
fn signals() -> &'static [Signal] {
|
||||
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
|
||||
vec![Signal::builder("created")
|
||||
.param_types([Album::static_type()])
|
||||
.build()]
|
||||
});
|
||||
|
||||
SIGNALS.as_ref()
|
||||
}
|
||||
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
let recordings_popover = RecordingSelectorPopover::new(self.library.get().unwrap());
|
||||
|
||||
let obj = self.obj().clone();
|
||||
recordings_popover.connect_selected(move |_, recording| {
|
||||
obj.add_recording(recording);
|
||||
});
|
||||
|
||||
let obj = self.obj().clone();
|
||||
recordings_popover.connect_create(move |_| {
|
||||
let editor = MusicusRecordingEditor::new(&obj.navigation(), &obj.library(), None);
|
||||
|
||||
editor.connect_created(clone!(
|
||||
#[weak]
|
||||
obj,
|
||||
move |_, recording| {
|
||||
obj.add_recording(recording);
|
||||
}
|
||||
));
|
||||
|
||||
obj.navigation().push(&editor);
|
||||
});
|
||||
|
||||
self.select_recording_box.append(&recordings_popover);
|
||||
self.recordings_popover.set(recordings_popover).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for AlbumEditor {}
|
||||
impl NavigationPageImpl for AlbumEditor {}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AlbumEditor(ObjectSubclass<imp::AlbumEditor>)
|
||||
@extends gtk::Widget, adw::NavigationPage;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl AlbumEditor {
|
||||
pub fn new(
|
||||
navigation: &adw::NavigationView,
|
||||
library: &MusicusLibrary,
|
||||
album: Option<&Album>,
|
||||
) -> Self {
|
||||
let obj: Self = glib::Object::builder()
|
||||
.property("navigation", navigation)
|
||||
.property("library", library)
|
||||
.build();
|
||||
|
||||
if let Some(album) = album {
|
||||
obj.imp().save_row.set_title(&gettext("Save changes"));
|
||||
obj.imp().album_id.set(album.album_id.clone()).unwrap();
|
||||
obj.imp().name_editor.set_translation(&album.name);
|
||||
|
||||
for recording in &album.recordings {
|
||||
obj.add_recording(recording.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
obj
|
||||
}
|
||||
|
||||
pub fn connect_created<F: Fn(&Self, Album) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.connect_local("created", true, move |values| {
|
||||
let obj = values[0].get::<Self>().unwrap();
|
||||
let album = values[1].get::<Album>().unwrap();
|
||||
f(&obj, album);
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn select_recording(&self) {
|
||||
self.imp().recordings_popover.get().unwrap().popup();
|
||||
}
|
||||
|
||||
fn add_recording(&self, recording: Recording) {
|
||||
let row = adw::ActionRow::builder()
|
||||
.title(recording.work.to_string())
|
||||
.subtitle(recording.performers_string())
|
||||
.build();
|
||||
|
||||
let remove_button = gtk::Button::builder()
|
||||
.icon_name("user-trash-symbolic")
|
||||
.valign(gtk::Align::Center)
|
||||
.css_classes(["flat"])
|
||||
.build();
|
||||
|
||||
remove_button.connect_clicked(clone!(
|
||||
#[weak(rename_to = this)]
|
||||
self,
|
||||
#[weak]
|
||||
row,
|
||||
#[strong]
|
||||
recording,
|
||||
move |_| {
|
||||
this.imp().recordings_list.remove(&row);
|
||||
this.imp()
|
||||
.recordings
|
||||
.borrow_mut()
|
||||
.retain(|r| *r != recording);
|
||||
}
|
||||
));
|
||||
|
||||
row.add_suffix(&remove_button);
|
||||
|
||||
self.imp()
|
||||
.recordings_list
|
||||
.insert(&row, self.imp().recordings.borrow().len() as i32);
|
||||
|
||||
self.imp().recordings.borrow_mut().push(recording);
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn save(&self) {
|
||||
let library = self.imp().library.get().unwrap();
|
||||
|
||||
let name = self.imp().name_editor.translation();
|
||||
let recordings = self.imp().recordings.borrow().clone();
|
||||
|
||||
if let Some(album_id) = self.imp().album_id.get() {
|
||||
library.update_album(album_id, name, recordings).unwrap();
|
||||
} else {
|
||||
let album = library.create_album(name, recordings).unwrap();
|
||||
self.emit_by_name::<()>("created", &[&album]);
|
||||
}
|
||||
|
||||
self.imp().navigation.get().unwrap().pop();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
pub mod activatable_row;
|
||||
pub mod album_editor;
|
||||
pub mod ensemble_editor;
|
||||
pub mod ensemble_selector_popover;
|
||||
pub mod instrument_editor;
|
||||
|
|
|
|||
109
src/library.rs
109
src/library.rs
|
|
@ -131,10 +131,13 @@ impl MusicusLibrary {
|
|||
.map(|w| Work::from_table(w, connection))
|
||||
.collect::<Result<Vec<Work>>>()?;
|
||||
|
||||
let albums: Vec<Album> = albums::table
|
||||
let albums = albums::table
|
||||
.filter(albums::name.like(&search))
|
||||
.limit(9)
|
||||
.load(connection)?;
|
||||
.load::<tables::Album>(connection)?
|
||||
.into_iter()
|
||||
.map(|a| Album::from_table(a, connection))
|
||||
.collect::<Result<Vec<Album>>>()?;
|
||||
|
||||
LibraryResults {
|
||||
composers,
|
||||
|
|
@ -259,7 +262,10 @@ impl MusicusLibrary {
|
|||
)
|
||||
.select(albums::all_columns)
|
||||
.distinct()
|
||||
.load(connection)?;
|
||||
.load::<tables::Album>(connection)?
|
||||
.into_iter()
|
||||
.map(|a| Album::from_table(a, connection))
|
||||
.collect::<Result<Vec<Album>>>()?;
|
||||
|
||||
LibraryResults {
|
||||
composers,
|
||||
|
|
@ -320,7 +326,10 @@ impl MusicusLibrary {
|
|||
)
|
||||
.select(albums::all_columns)
|
||||
.distinct()
|
||||
.load(connection)?;
|
||||
.load::<tables::Album>(connection)?
|
||||
.into_iter()
|
||||
.map(|a| Album::from_table(a, connection))
|
||||
.collect::<Result<Vec<Album>>>()?;
|
||||
|
||||
LibraryResults {
|
||||
composers,
|
||||
|
|
@ -691,7 +700,11 @@ impl MusicusLibrary {
|
|||
let mut binding = self.imp().connection.borrow_mut();
|
||||
let connection = &mut *binding.as_mut().unwrap();
|
||||
|
||||
let albums = albums::table.load::<Album>(connection)?;
|
||||
let albums = albums::table
|
||||
.load::<tables::Album>(connection)?
|
||||
.into_iter()
|
||||
.map(|a| Album::from_table(a, connection))
|
||||
.collect::<Result<Vec<Album>>>()?;
|
||||
|
||||
Ok(albums)
|
||||
}
|
||||
|
|
@ -1234,8 +1247,92 @@ impl MusicusLibrary {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn create_album(
|
||||
&self,
|
||||
name: TranslatedString,
|
||||
recordings: Vec<Recording>,
|
||||
) -> Result<Album> {
|
||||
let mut binding = self.imp().connection.borrow_mut();
|
||||
let connection = &mut *binding.as_mut().unwrap();
|
||||
|
||||
let album_id = db::generate_id();
|
||||
let now = Local::now().naive_local();
|
||||
|
||||
let album_data = tables::Album {
|
||||
album_id: album_id.clone(),
|
||||
name,
|
||||
created_at: now,
|
||||
edited_at: now,
|
||||
last_used_at: now,
|
||||
last_played_at: None,
|
||||
};
|
||||
|
||||
diesel::insert_into(albums::table)
|
||||
.values(&album_data)
|
||||
.execute(connection)?;
|
||||
|
||||
for (index, recording) in recordings.into_iter().enumerate() {
|
||||
let album_recording_data = tables::AlbumRecording {
|
||||
album_id: album_id.clone(),
|
||||
recording_id: recording.recording_id,
|
||||
sequence_number: index as i32,
|
||||
};
|
||||
|
||||
diesel::insert_into(album_recordings::table)
|
||||
.values(&album_recording_data)
|
||||
.execute(connection)?;
|
||||
}
|
||||
|
||||
let album = Album::from_table(album_data, connection)?;
|
||||
|
||||
self.changed();
|
||||
|
||||
Ok(album)
|
||||
}
|
||||
|
||||
pub fn update_album(
|
||||
&self,
|
||||
album_id: &str,
|
||||
name: TranslatedString,
|
||||
recordings: Vec<Recording>,
|
||||
) -> Result<()> {
|
||||
let mut binding = self.imp().connection.borrow_mut();
|
||||
let connection = &mut *binding.as_mut().unwrap();
|
||||
|
||||
let now = Local::now().naive_local();
|
||||
|
||||
diesel::update(albums::table)
|
||||
.filter(albums::album_id.eq(album_id))
|
||||
.set((
|
||||
albums::name.eq(name),
|
||||
albums::edited_at.eq(now),
|
||||
albums::last_used_at.eq(now),
|
||||
))
|
||||
.execute(connection)?;
|
||||
|
||||
diesel::delete(album_recordings::table)
|
||||
.filter(album_recordings::album_id.eq(album_id))
|
||||
.execute(connection)?;
|
||||
|
||||
for (index, recording) in recordings.into_iter().enumerate() {
|
||||
let album_recording_data = tables::AlbumRecording {
|
||||
album_id: album_id.to_owned(),
|
||||
recording_id: recording.recording_id,
|
||||
sequence_number: index as i32,
|
||||
};
|
||||
|
||||
diesel::insert_into(album_recordings::table)
|
||||
.values(&album_recording_data)
|
||||
.execute(connection)?;
|
||||
}
|
||||
|
||||
self.changed();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Import a track into the music library.
|
||||
// TODO: Support mediums, think about albums.
|
||||
// TODO: Support mediums.
|
||||
pub fn import_track(
|
||||
&self,
|
||||
path: impl AsRef<Path>,
|
||||
|
|
|
|||
145
src/library_manager/albums_page.rs
Normal file
145
src/library_manager/albums_page.rs
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
use crate::{db::models::Album, editor::album_editor::AlbumEditor, library::MusicusLibrary};
|
||||
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gettextrs::gettext;
|
||||
use gtk::glib::{self, clone};
|
||||
|
||||
use std::cell::{OnceCell, RefCell};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||
#[template(file = "data/ui/library_manager_albums_page.blp")]
|
||||
pub struct AlbumsPage {
|
||||
pub navigation: OnceCell<adw::NavigationView>,
|
||||
pub library: OnceCell<MusicusLibrary>,
|
||||
pub albums: RefCell<Vec<Album>>,
|
||||
pub albums_filtered: RefCell<Vec<Album>>,
|
||||
|
||||
#[template_child]
|
||||
pub search_entry: TemplateChild<gtk::SearchEntry>,
|
||||
#[template_child]
|
||||
pub list: TemplateChild<gtk::ListBox>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for AlbumsPage {
|
||||
const NAME: &'static str = "MusicusLibraryManagerAlbumsPage";
|
||||
type Type = super::AlbumsPage;
|
||||
type ParentType = adw::NavigationPage;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
klass.bind_template_instance_callbacks();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for AlbumsPage {}
|
||||
impl WidgetImpl for AlbumsPage {}
|
||||
|
||||
impl NavigationPageImpl for AlbumsPage {
|
||||
fn showing(&self) {
|
||||
self.parent_showing();
|
||||
self.obj().update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AlbumsPage(ObjectSubclass<imp::AlbumsPage>)
|
||||
@extends gtk::Widget, adw::NavigationPage;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl AlbumsPage {
|
||||
pub fn new(navigation: &adw::NavigationView, library: &MusicusLibrary) -> Self {
|
||||
let obj: Self = glib::Object::new();
|
||||
let imp = obj.imp();
|
||||
|
||||
imp.navigation.set(navigation.to_owned()).unwrap();
|
||||
imp.library.set(library.to_owned()).unwrap();
|
||||
|
||||
obj
|
||||
}
|
||||
|
||||
fn update(&self) {
|
||||
let albums = self.imp().library.get().unwrap().all_albums().unwrap();
|
||||
self.imp().albums.replace(albums);
|
||||
self.search_changed();
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn search_changed(&self) {
|
||||
let albums_filtered = self
|
||||
.imp()
|
||||
.albums
|
||||
.borrow()
|
||||
.iter()
|
||||
.filter(|a| {
|
||||
a.name
|
||||
.get()
|
||||
.contains(&self.imp().search_entry.text().to_string())
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<Album>>();
|
||||
|
||||
self.imp().list.remove_all();
|
||||
|
||||
for album in albums_filtered {
|
||||
let row = adw::ActionRow::builder()
|
||||
.title(album.name.get())
|
||||
.activatable(true)
|
||||
.build();
|
||||
|
||||
row.connect_activated(clone!(
|
||||
#[weak(rename_to = obj)]
|
||||
self,
|
||||
#[strong]
|
||||
album,
|
||||
move |_| {
|
||||
obj.imp().navigation.get().unwrap().push(&AlbumEditor::new(
|
||||
&obj.imp().navigation.get().unwrap(),
|
||||
&obj.imp().library.get().unwrap(),
|
||||
Some(&album),
|
||||
));
|
||||
}
|
||||
));
|
||||
|
||||
let delete_button = gtk::Button::builder()
|
||||
.icon_name("user-trash-symbolic")
|
||||
.tooltip_text(gettext("Delete album"))
|
||||
.valign(gtk::Align::Center)
|
||||
.css_classes(["flat"])
|
||||
.build();
|
||||
|
||||
// TODO:
|
||||
// delete_button.connect_clicked(clone!(
|
||||
// #[weak(rename_to = obj)]
|
||||
// self,
|
||||
// #[strong]
|
||||
// album,
|
||||
// move |_| {
|
||||
// obj.imp().library.delete_album(&album.album_id).unwrap();
|
||||
// }
|
||||
// ));
|
||||
|
||||
row.add_suffix(&delete_button);
|
||||
|
||||
self.imp().list.append(&row);
|
||||
}
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn create(&self) {
|
||||
self.imp().navigation.get().unwrap().push(&AlbumEditor::new(
|
||||
&self.imp().navigation.get().unwrap(),
|
||||
&self.imp().library.get().unwrap(),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
pub mod albums_page;
|
||||
|
||||
use crate::{
|
||||
db::{
|
||||
models::{Album, Ensemble, Instrument, Person, Recording, Role, Track, Work},
|
||||
|
|
@ -8,6 +10,7 @@ use crate::{
|
|||
};
|
||||
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use albums_page::AlbumsPage;
|
||||
use gettextrs::gettext;
|
||||
use gtk::glib;
|
||||
|
||||
|
|
@ -103,7 +106,7 @@ impl LibraryManager {
|
|||
}
|
||||
|
||||
#[template_callback]
|
||||
async fn open_library(&self, _: &adw::ActionRow) {
|
||||
async fn open_library(&self) {
|
||||
let dialog = gtk::FileDialog::builder()
|
||||
.title(gettext("Select music library folder"))
|
||||
.modal(true)
|
||||
|
|
@ -127,37 +130,41 @@ impl LibraryManager {
|
|||
}
|
||||
|
||||
#[template_callback]
|
||||
fn import_archive(&self, _: &adw::ButtonRow) {}
|
||||
fn import_archive(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn export_archive(&self, _: &adw::ButtonRow) {}
|
||||
fn export_archive(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_persons(&self, _: &adw::ActionRow) {}
|
||||
fn show_persons(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_roles(&self, _: &adw::ActionRow) {}
|
||||
fn show_roles(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_instruments(&self, _: &adw::ActionRow) {}
|
||||
fn show_instruments(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_works(&self, _: &adw::ActionRow) {}
|
||||
fn show_works(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_ensembles(&self, _: &adw::ActionRow) {}
|
||||
fn show_ensembles(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_recordings(&self, _: &adw::ActionRow) {}
|
||||
fn show_recordings(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_tracks(&self, _: &adw::ActionRow) {}
|
||||
fn show_tracks(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_mediums(&self, _: &adw::ActionRow) {}
|
||||
fn show_mediums(&self) {}
|
||||
|
||||
#[template_callback]
|
||||
fn show_albums(&self, _: &adw::ActionRow) {}
|
||||
fn show_albums(&self) {
|
||||
let navigation = self.imp().navigation.get().unwrap();
|
||||
let library = self.imp().library.get().unwrap();
|
||||
navigation.push(&AlbumsPage::new(navigation, library));
|
||||
}
|
||||
|
||||
// TODO: Make this async.
|
||||
fn update(&self) {
|
||||
|
|
@ -217,101 +224,4 @@ impl LibraryManager {
|
|||
.set_label(&albums.len().to_string());
|
||||
self.imp().albums.replace(albums);
|
||||
}
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_person(&self) {
|
||||
// self.imp()
|
||||
// .navigation
|
||||
// .get()
|
||||
// .unwrap()
|
||||
// .push(&MusicusPersonEditor::new(
|
||||
// &self.imp().navigation.get().unwrap(),
|
||||
// &self.imp().library.get().unwrap(),
|
||||
// None,
|
||||
// ));
|
||||
// }
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_role(&self) {
|
||||
// self.imp()
|
||||
// .navigation
|
||||
// .get()
|
||||
// .unwrap()
|
||||
// .push(&MusicusRoleEditor::new(
|
||||
// &self.imp().navigation.get().unwrap(),
|
||||
// &self.imp().library.get().unwrap(),
|
||||
// None,
|
||||
// ));
|
||||
// }
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_instrument(&self) {
|
||||
// self.imp()
|
||||
// .navigation
|
||||
// .get()
|
||||
// .unwrap()
|
||||
// .push(&MusicusInstrumentEditor::new(
|
||||
// &self.imp().navigation.get().unwrap(),
|
||||
// &self.imp().library.get().unwrap(),
|
||||
// None,
|
||||
// ));
|
||||
// }
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_work(&self) {
|
||||
// self.imp()
|
||||
// .navigation
|
||||
// .get()
|
||||
// .unwrap()
|
||||
// .push(&MusicusWorkEditor::new(
|
||||
// &self.imp().navigation.get().unwrap(),
|
||||
// &self.imp().library.get().unwrap(),
|
||||
// None,
|
||||
// ));
|
||||
// }
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_ensemble(&self) {
|
||||
// self.imp()
|
||||
// .navigation
|
||||
// .get()
|
||||
// .unwrap()
|
||||
// .push(&MusicusEnsembleEditor::new(
|
||||
// &self.imp().navigation.get().unwrap(),
|
||||
// &self.imp().library.get().unwrap(),
|
||||
// None,
|
||||
// ));
|
||||
// }
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_recording(&self) {
|
||||
// self.imp()
|
||||
// .navigation
|
||||
// .get()
|
||||
// .unwrap()
|
||||
// .push(&MusicusRecordingEditor::new(
|
||||
// &self.imp().navigation.get().unwrap(),
|
||||
// &self.imp().library.get().unwrap(),
|
||||
// None,
|
||||
// ));
|
||||
// }
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_medium(&self) {
|
||||
// todo!("Medium import");
|
||||
// }
|
||||
|
||||
// #[template_callback]
|
||||
// fn add_album(&self) {
|
||||
// todo!("Album editor");
|
||||
// // self.imp()
|
||||
// // .navigation
|
||||
// // .get()
|
||||
// // .unwrap()
|
||||
// // .push(&MusicusAlbumEditor::new(
|
||||
// // &self.imp().navigation.get().unwrap(),
|
||||
// // &self.imp().library.get().unwrap(),
|
||||
// // None,
|
||||
// // ));
|
||||
// }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue