From 9e10d47b877f77a5840d920f6cfdf897f7103614 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Wed, 3 Feb 2021 16:55:50 +0100 Subject: [PATCH] Make recording screen functional again --- src/screens/recording.rs | 111 ++++++++++++++++++++++++++++++++------- src/widgets/section.rs | 1 + 2 files changed, 94 insertions(+), 18 deletions(-) diff --git a/src/screens/recording.rs b/src/screens/recording.rs index 5e51443..ec532e6 100644 --- a/src/screens/recording.rs +++ b/src/screens/recording.rs @@ -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, - recordings: RefCell>, + list: Rc, + track_sets: RefCell>, + items: RefCell>, } impl Screen for RecordingScreen { @@ -28,21 +40,38 @@ impl Screen 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 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::::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 for RecordingScreen { } } +impl RecordingScreen { + /// Update the track sets variable as well as the user interface. + fn show_track_sets(&self, track_sets: Vec) { + 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() diff --git a/src/widgets/section.rs b/src/widgets/section.rs index ea33777..ed8e7cb 100644 --- a/src/widgets/section.rs +++ b/src/widgets/section.rs @@ -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();