editor: Small tracks editor improvements

This commit is contained in:
Elias Projahn 2025-02-15 09:08:20 +01:00
parent 143876c4de
commit 642d9340e5
3 changed files with 71 additions and 24 deletions

View file

@ -48,8 +48,9 @@ template $MusicusTracksEditor: Adw.NavigationPage {
} }
} }
Gtk.Label { Gtk.Label tracks_label {
label: _("Tracks"); label: _("Tracks");
sensitive: false;
xalign: 0; xalign: 0;
margin-top: 24; margin-top: 24;
@ -61,6 +62,7 @@ template $MusicusTracksEditor: Adw.NavigationPage {
Gtk.ListBox track_list { Gtk.ListBox track_list {
selection-mode: none; selection-mode: none;
margin-top: 12; margin-top: 12;
sensitive: false;
styles [ styles [
"boxed-list" "boxed-list"

View file

@ -43,6 +43,8 @@ mod imp {
#[template_child] #[template_child]
pub select_recording_box: TemplateChild<gtk::Box>, pub select_recording_box: TemplateChild<gtk::Box>,
#[template_child] #[template_child]
pub tracks_label: TemplateChild<gtk::Label>,
#[template_child]
pub track_list: TemplateChild<gtk::ListBox>, pub track_list: TemplateChild<gtk::ListBox>,
#[template_child] #[template_child]
pub save_row: TemplateChild<adw::ButtonRow>, pub save_row: TemplateChild<adw::ButtonRow>,
@ -189,31 +191,58 @@ impl TracksEditor {
.recording_row .recording_row
.set_subtitle(&recording.performers_string()); .set_subtitle(&recording.performers_string());
for track in self // Remove previously added track rows. This is not ideal because the user might be under
// the impression that changing the recording will allow to transfer tracks to it. But:
// What would happen to the old recording's tracks? What would happen with previously
// selected work parts?
for track_row in self.imp().track_rows.borrow_mut().drain(..) {
self.imp().track_list.remove(&track_row);
}
let tracks = self
.library() .library()
.tracks_for_recording(&recording.recording_id) .tracks_for_recording(&recording.recording_id)
.unwrap() .unwrap();
{
self.add_track_row(TracksEditorTrackData { if !tracks.is_empty() {
track_id: Some(track.track_id), self.imp().save_row.set_title(&gettext("Save changes"));
path: PathType::Library(track.path),
works: track.works, for track in tracks {
}); self.add_track_row(
recording.clone(),
TracksEditorTrackData {
track_id: Some(track.track_id),
path: PathType::Library(track.path),
parts: track.works,
},
);
}
} }
self.imp().tracks_label.set_sensitive(true);
self.imp().track_list.set_sensitive(true);
self.imp().recording.replace(Some(recording)); self.imp().recording.replace(Some(recording));
} }
fn add_file(&self, path: PathBuf) { fn add_file(&self, path: PathBuf) {
self.add_track_row(TracksEditorTrackData { if let Some(recording) = &*self.imp().recording.borrow() {
track_id: None, self.add_track_row(
path: PathType::System(path), recording.to_owned(),
works: Vec::new(), TracksEditorTrackData {
}); track_id: None,
path: PathType::System(path),
parts: Vec::new(),
},
);
} else {
log::warn!("Tried to add track row without recording selected");
}
} }
fn add_track_row(&self, track_data: TracksEditorTrackData) { fn add_track_row(&self, recording: Recording, track_data: TracksEditorTrackData) {
let track_row = TracksEditorTrackRow::new(&self.navigation(), &self.library(), track_data); let track_row =
TracksEditorTrackRow::new(&self.navigation(), &self.library(), recording, track_data);
track_row.connect_remove(clone!( track_row.connect_remove(clone!(
#[weak(rename_to = this)] #[weak(rename_to = this)]

View file

@ -1,4 +1,7 @@
use crate::{db::models::Work, library::MusicusLibrary}; use crate::{
db::models::{Recording, Work},
library::MusicusLibrary,
};
use adw::{prelude::*, subclass::prelude::*}; use adw::{prelude::*, subclass::prelude::*};
use formatx::formatx; use formatx::formatx;
@ -23,6 +26,7 @@ mod imp {
#[property(get, construct_only)] #[property(get, construct_only)]
pub library: OnceCell<MusicusLibrary>, pub library: OnceCell<MusicusLibrary>,
pub recording: OnceCell<Recording>,
pub track_data: RefCell<TracksEditorTrackData>, pub track_data: RefCell<TracksEditorTrackData>,
#[template_child] #[template_child]
@ -71,6 +75,7 @@ impl TracksEditorTrackRow {
pub fn new( pub fn new(
navigation: &adw::NavigationView, navigation: &adw::NavigationView,
library: &MusicusLibrary, library: &MusicusLibrary,
recording: Recording,
track_data: TracksEditorTrackData, track_data: TracksEditorTrackData,
) -> Self { ) -> Self {
let obj: Self = glib::Object::builder() let obj: Self = glib::Object::builder()
@ -78,6 +83,8 @@ impl TracksEditorTrackRow {
.property("library", library) .property("library", library)
.build(); .build();
obj.set_activatable(!recording.work.parts.is_empty());
obj.set_subtitle(&match &track_data.path { obj.set_subtitle(&match &track_data.path {
PathType::None => String::new(), PathType::None => String::new(),
PathType::Library(path) => path.to_owned(), PathType::Library(path) => path.to_owned(),
@ -94,8 +101,9 @@ impl TracksEditorTrackRow {
} }
}); });
obj.set_works(&track_data.works); obj.imp().recording.set(recording).unwrap();
obj.imp().track_data.replace(track_data); obj.imp().track_data.replace(track_data);
obj.update_title();
obj obj
} }
@ -122,14 +130,22 @@ impl TracksEditorTrackRow {
self.emit_by_name::<()>("remove", &[]); self.emit_by_name::<()>("remove", &[]);
} }
fn set_works(&self, works: &[Work]) { fn update_title(&self) {
self.set_title( let parts = &self.imp().track_data.borrow().parts;
&works
self.set_title(&if parts.is_empty() {
if self.imp().recording.get().unwrap().work.parts.is_empty() {
gettext("Whole work")
} else {
gettext("Select parts")
}
} else {
parts
.iter() .iter()
.map(|w| w.name.get()) .map(|w| w.name.get())
.collect::<Vec<&str>>() .collect::<Vec<&str>>()
.join(", "), .join(", ")
); });
} }
} }
@ -137,7 +153,7 @@ impl TracksEditorTrackRow {
pub struct TracksEditorTrackData { pub struct TracksEditorTrackData {
pub track_id: Option<String>, pub track_id: Option<String>,
pub path: PathType, pub path: PathType,
pub works: Vec<Work>, pub parts: Vec<Work>,
} }
#[derive(Clone, Default, Debug)] #[derive(Clone, Default, Debug)]