mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 19:57:25 +01:00
Make recording screen functional again
This commit is contained in:
parent
d5a1de05a7
commit
9e10d47b87
2 changed files with 94 additions and 18 deletions
|
|
@ -1,7 +1,8 @@
|
|||
use crate::backend::Backend;
|
||||
use crate::database::Recording;
|
||||
use crate::database::{Recording, TrackSet};
|
||||
use crate::editors::RecordingEditor;
|
||||
use crate::navigator::{NavigatorWindow, NavigationHandle, Screen};
|
||||
use crate::player::PlaylistItem;
|
||||
use crate::widgets;
|
||||
use crate::widgets::{List, Section, Widget};
|
||||
use gettextrs::gettext;
|
||||
|
|
@ -11,13 +12,24 @@ use libadwaita::prelude::*;
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Representation of one entry within the track list.
|
||||
enum ListItem {
|
||||
/// A track row. This hold an index to the track set and an index to the
|
||||
/// track within the track set.
|
||||
Track(usize, usize),
|
||||
|
||||
/// A separator intended for use between track sets.
|
||||
Separator,
|
||||
}
|
||||
|
||||
/// A screen for showing a recording.
|
||||
pub struct RecordingScreen {
|
||||
handle: NavigationHandle<()>,
|
||||
recording: Recording,
|
||||
widget: widgets::Screen,
|
||||
track_list: Rc<List>,
|
||||
recordings: RefCell<Vec<Recording>>,
|
||||
list: Rc<List>,
|
||||
track_sets: RefCell<Vec<TrackSet>>,
|
||||
items: RefCell<Vec<ListItem>>,
|
||||
}
|
||||
|
||||
impl Screen<Recording, ()> for RecordingScreen {
|
||||
|
|
@ -28,21 +40,38 @@ impl Screen<Recording, ()> for RecordingScreen {
|
|||
widget.set_title(&recording.work.get_title());
|
||||
widget.set_subtitle(&recording.get_performers());
|
||||
|
||||
let track_list = List::new();
|
||||
let list = List::new();
|
||||
let section = Section::new(&gettext("Tracks"), &list.widget);
|
||||
widget.add_content(§ion.widget);
|
||||
|
||||
let this = Rc::new(Self {
|
||||
handle,
|
||||
recording,
|
||||
widget,
|
||||
track_list,
|
||||
recordings: RefCell::new(Vec::new()),
|
||||
list,
|
||||
track_sets: RefCell::new(Vec::new()),
|
||||
items: RefCell::new(Vec::new()),
|
||||
});
|
||||
|
||||
section.add_action("media-playback-start-symbolic", clone!(@weak this => move || {
|
||||
if let Some(player) = this.handle.backend.get_player() {
|
||||
if let Some(track_set) = this.track_sets.borrow().get(0).cloned() {
|
||||
let indices = (0..track_set.tracks.len()).collect();
|
||||
|
||||
let playlist_item = PlaylistItem {
|
||||
track_set,
|
||||
indices,
|
||||
};
|
||||
|
||||
player.add_item(playlist_item).unwrap();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
this.widget.set_back_cb(clone!(@weak this => move || {
|
||||
this.handle.pop(None);
|
||||
}));
|
||||
|
||||
|
||||
this.widget.add_action(&gettext("Edit recording"), clone!(@weak this => move || {
|
||||
spawn!(@clone this, async move {
|
||||
let window = NavigatorWindow::new(this.handle.backend.clone());
|
||||
|
|
@ -57,25 +86,46 @@ impl Screen<Recording, ()> for RecordingScreen {
|
|||
});
|
||||
}));
|
||||
|
||||
this.widget.set_search_cb(clone!(@weak this => move || {
|
||||
this.track_list.invalidate_filter();
|
||||
}));
|
||||
this.list.set_make_widget_cb(clone!(@weak this => move |index| {
|
||||
match this.items.borrow()[index] {
|
||||
ListItem::Track(track_set_index, track_index) => {
|
||||
let track_set = &this.track_sets.borrow()[track_set_index];
|
||||
let track = &track_set.tracks[track_index];
|
||||
|
||||
// TODO: Implement.
|
||||
// this.track_list.set_make_widget_cb(clone!(@strong this => move |index| {
|
||||
// }));
|
||||
let mut title_parts = Vec::<String>::new();
|
||||
for part in &track.work_parts {
|
||||
title_parts.push(this.recording.work.parts[*part].title.clone());
|
||||
}
|
||||
|
||||
this.track_list.set_filter_cb(clone!(@weak this => move |index| {
|
||||
// TODO: Implement.
|
||||
// search.is_empty() || text.to_lowercase().contains(&search)
|
||||
true
|
||||
let title = if title_parts.is_empty() {
|
||||
gettext("Unknown")
|
||||
} else {
|
||||
title_parts.join(", ")
|
||||
};
|
||||
|
||||
let row = libadwaita::ActionRow::new();
|
||||
row.set_title(Some(&title));
|
||||
|
||||
row.upcast()
|
||||
}
|
||||
ListItem::Separator => {
|
||||
let separator = gtk::Separator::new(gtk::Orientation::Horizontal);
|
||||
separator.upcast()
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// Load the content asynchronously.
|
||||
|
||||
spawn!(@clone this, async move {
|
||||
// TODO: Implement.
|
||||
let track_sets = this.handle
|
||||
.backend
|
||||
.db()
|
||||
.get_track_sets(&this.recording.id)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
this.show_track_sets(track_sets);
|
||||
this.widget.ready();
|
||||
});
|
||||
|
||||
|
|
@ -83,6 +133,31 @@ impl Screen<Recording, ()> for RecordingScreen {
|
|||
}
|
||||
}
|
||||
|
||||
impl RecordingScreen {
|
||||
/// Update the track sets variable as well as the user interface.
|
||||
fn show_track_sets(&self, track_sets: Vec<TrackSet>) {
|
||||
let mut first = true;
|
||||
let mut items = Vec::new();
|
||||
|
||||
for (track_set_index, track_set) in track_sets.iter().enumerate() {
|
||||
if !first {
|
||||
items.push(ListItem::Separator);
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
for (track_index, _) in track_set.tracks.iter().enumerate() {
|
||||
items.push(ListItem::Track(track_set_index, track_index));
|
||||
}
|
||||
}
|
||||
|
||||
let length = items.len();
|
||||
self.items.replace(items);
|
||||
self.track_sets.replace(track_sets);
|
||||
self.list.update(length);
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for RecordingScreen {
|
||||
fn get_widget(&self) -> gtk::Widget {
|
||||
self.widget.widget.clone().upcast()
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ impl Section {
|
|||
let button = gtk::ButtonBuilder::new()
|
||||
.has_frame(false)
|
||||
.valign(gtk::Align::Center)
|
||||
.margin_top(12)
|
||||
.icon_name(icon_name)
|
||||
.build();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue