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::backend::Backend;
use crate::database::Recording; use crate::database::{Recording, TrackSet};
use crate::editors::RecordingEditor; use crate::editors::RecordingEditor;
use crate::navigator::{NavigatorWindow, NavigationHandle, Screen}; use crate::navigator::{NavigatorWindow, NavigationHandle, Screen};
use crate::player::PlaylistItem;
use crate::widgets; use crate::widgets;
use crate::widgets::{List, Section, Widget}; use crate::widgets::{List, Section, Widget};
use gettextrs::gettext; use gettextrs::gettext;
@ -11,13 +12,24 @@ use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; 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. /// A screen for showing a recording.
pub struct RecordingScreen { pub struct RecordingScreen {
handle: NavigationHandle<()>, handle: NavigationHandle<()>,
recording: Recording, recording: Recording,
widget: widgets::Screen, widget: widgets::Screen,
track_list: Rc<List>, list: Rc<List>,
recordings: RefCell<Vec<Recording>>, track_sets: RefCell<Vec<TrackSet>>,
items: RefCell<Vec<ListItem>>,
} }
impl Screen<Recording, ()> for RecordingScreen { impl Screen<Recording, ()> for RecordingScreen {
@ -28,21 +40,38 @@ impl Screen<Recording, ()> for RecordingScreen {
widget.set_title(&recording.work.get_title()); widget.set_title(&recording.work.get_title());
widget.set_subtitle(&recording.get_performers()); 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 { let this = Rc::new(Self {
handle, handle,
recording, recording,
widget, widget,
track_list, list,
recordings: RefCell::new(Vec::new()), 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.widget.set_back_cb(clone!(@weak this => move || {
this.handle.pop(None); this.handle.pop(None);
})); }));
this.widget.add_action(&gettext("Edit recording"), clone!(@weak this => move || { this.widget.add_action(&gettext("Edit recording"), clone!(@weak this => move || {
spawn!(@clone this, async move { spawn!(@clone this, async move {
let window = NavigatorWindow::new(this.handle.backend.clone()); 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.list.set_make_widget_cb(clone!(@weak this => move |index| {
this.track_list.invalidate_filter(); 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. let mut title_parts = Vec::<String>::new();
// this.track_list.set_make_widget_cb(clone!(@strong this => move |index| { 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| { let title = if title_parts.is_empty() {
// TODO: Implement. gettext("Unknown")
// search.is_empty() || text.to_lowercase().contains(&search) } else {
true 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. // Load the content asynchronously.
spawn!(@clone this, async move { 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(); 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 { impl Widget for RecordingScreen {
fn get_widget(&self) -> gtk::Widget { fn get_widget(&self) -> gtk::Widget {
self.widget.widget.clone().upcast() self.widget.widget.clone().upcast()

View file

@ -50,6 +50,7 @@ impl Section {
let button = gtk::ButtonBuilder::new() let button = gtk::ButtonBuilder::new()
.has_frame(false) .has_frame(false)
.valign(gtk::Align::Center) .valign(gtk::Align::Center)
.margin_top(12)
.icon_name(icon_name) .icon_name(icon_name)
.build(); .build();