From 2922c17a86f8d40312e2a68c3501e8b5352609b2 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Tue, 23 Mar 2021 18:06:42 +0100 Subject: [PATCH] Add medium preview screen --- musicus/res/ui/medium_preview.ui | 51 +++++++++++++ musicus/src/import/import_screen.rs | 5 +- musicus/src/import/medium_preview.rs | 103 +++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 musicus/res/ui/medium_preview.ui create mode 100644 musicus/src/import/medium_preview.rs diff --git a/musicus/res/ui/medium_preview.ui b/musicus/res/ui/medium_preview.ui new file mode 100644 index 0000000..f6c3ed2 --- /dev/null +++ b/musicus/res/ui/medium_preview.ui @@ -0,0 +1,51 @@ + + + + + + vertical + + + false + false + + + Preview + + + + + go-previous-symbolic + + + + + + + True + + + + + 6 + 6 + 6 + vertical + + + start + 12 + 6 + + + + + + + + + + + + + diff --git a/musicus/src/import/import_screen.rs b/musicus/src/import/import_screen.rs index 1b7ae4a..78e9c33 100644 --- a/musicus/src/import/import_screen.rs +++ b/musicus/src/import/import_screen.rs @@ -78,7 +78,10 @@ impl ImportScreen { .build(); row.connect_activated(clone!(@weak this => move |_| { - debug!("Medium selected: {}", medium.name); + let medium = medium.clone(); + spawn!(@clone this, async move { + push!(this.handle, MediumPreview, (this.session.clone(), medium.clone())).await; + }); })); this.matching_list.append(&row); diff --git a/musicus/src/import/medium_preview.rs b/musicus/src/import/medium_preview.rs new file mode 100644 index 0000000..6323204 --- /dev/null +++ b/musicus/src/import/medium_preview.rs @@ -0,0 +1,103 @@ +use super::medium_editor::MediumEditor; +use crate::navigator::{NavigationHandle, Screen}; +use crate::widgets::Widget; +use gettextrs::gettext; +use glib::clone; +use gtk::prelude::*; +use gtk_macros::get_widget; +use libadwaita::prelude::*; +use log::debug; +use musicus_backend::db::Medium; +use musicus_backend::import::ImportSession; +use std::rc::Rc; +use std::sync::Arc; + +/// A dialog for presenting the selected medium when importing music. +pub struct MediumPreview { + handle: NavigationHandle<()>, + session: Arc, + widget: gtk::Box, +} + +impl Screen<(Arc, Medium), ()> for MediumPreview { + /// Create a new medium preview screen. + fn new((session, medium): (Arc, Medium), handle: NavigationHandle<()>) -> Rc { + // Create UI + + let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/medium_preview.ui"); + + get_widget!(builder, gtk::Box, widget); + get_widget!(builder, gtk::Button, back_button); + get_widget!(builder, gtk::Box, medium_box); + get_widget!(builder, gtk::Label, name_label); + + let this = Rc::new(Self { + handle, + session, + widget, + }); + + // Connect signals and callbacks + + back_button.connect_clicked(clone!(@weak this => move |_| { + this.handle.pop(None); + })); + + // Populate the widget + + name_label.set_text(&medium.name); + + for track_set in medium.tracks { + let recording = &track_set.recording; + + let frame = gtk::FrameBuilder::new() + .margin_bottom(12) + .build(); + + let list = gtk::ListBoxBuilder::new() + .selection_mode(gtk::SelectionMode::None) + .build(); + + let header = libadwaita::ActionRowBuilder::new() + .activatable(false) + .title(&recording.work.get_title()) + .subtitle(&recording.get_performers()) + .build(); + + list.append(&header); + + for track in track_set.tracks { + let mut parts = Vec::::new(); + for part in &track.work_parts { + parts.push(track_set.recording.work.parts[*part].title.clone()); + } + + let title = if parts.is_empty() { + gettext("Unknown") + } else { + parts.join(", ") + }; + + let row = libadwaita::ActionRowBuilder::new() + .activatable(false) + .title(&title) + .subtitle(&track.path) + .margin_start(12) + .build(); + + list.append(&row); + } + + frame.set_child(Some(&list)); + medium_box.append(&frame); + } + + this + } +} + +impl Widget for MediumPreview { + fn get_widget(&self) -> gtk::Widget { + self.widget.clone().upcast() + } +}