Make recording screen functional again

This commit is contained in:
Elias Projahn 2021-02-03 16:55:50 +01:00
parent d5a1de05a7
commit 9e10d47b87
2 changed files with 94 additions and 18 deletions

View file

@ -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(&section.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()

View file

@ -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();