mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47:25 +01:00
editor: Small tracks editor improvements
This commit is contained in:
parent
143876c4de
commit
642d9340e5
3 changed files with 71 additions and 24 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue