diff --git a/musicus/src/import/medium_editor.rs b/musicus/src/import/medium_editor.rs index e69de29..85b8a8d 100644 --- a/musicus/src/import/medium_editor.rs +++ b/musicus/src/import/medium_editor.rs @@ -0,0 +1,75 @@ +use super::disc_source::DiscSource; +use crate::backend::Backend; +// use crate::editors::{TrackSetEditor, TrackSource}; +use crate::widgets::{Navigator, NavigatorScreen}; +use crate::widgets::new_list::List; +use glib::clone; +use gtk::prelude::*; +use gtk_macros::get_widget; +use std::cell::RefCell; +use std::rc::Rc; + +/// A dialog for editing metadata while importing music into the music library. +pub struct MediumEditor { + backend: Rc, + source: DiscSource, + widget: gtk::Box, + navigator: RefCell>>, +} + +impl MediumEditor { + /// Create a new medium editor. + pub fn new(backend: Rc, source: DiscSource) -> Rc { + // Create UI + + let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/medium_editor.ui"); + + get_widget!(builder, gtk::Box, widget); + get_widget!(builder, gtk::Button, back_button); + get_widget!(builder, gtk::Button, add_button); + get_widget!(builder, gtk::Frame, frame); + + let list = List::new("No recordings added."); + frame.add(&list.widget); + + let this = Rc::new(Self { + backend, + source, + widget, + navigator: RefCell::new(None), + }); + + // Connect signals and callbacks + + back_button.connect_clicked(clone!(@strong this => move |_| { + let navigator = this.navigator.borrow().clone(); + if let Some(navigator) = navigator { + navigator.pop(); + } + })); + + add_button.connect_clicked(clone!(@strong this => move |_| { + let navigator = this.navigator.borrow().clone(); + if let Some(navigator) = navigator { + // let editor = TrackSetEditor::new(this.backend.clone(), this.source.clone()); + // navigator.push(editor); + } + })); + + this + } +} + +impl NavigatorScreen for MediumEditor { + fn attach_navigator(&self, navigator: Rc) { + self.navigator.replace(Some(navigator)); + } + + fn get_widget(&self) -> gtk::Widget { + self.widget.clone().upcast() + } + + fn detach_navigator(&self) { + self.navigator.replace(None); + } +} diff --git a/musicus/src/import/source_selector.rs b/musicus/src/import/source_selector.rs index 0743096..121bc34 100644 --- a/musicus/src/import/source_selector.rs +++ b/musicus/src/import/source_selector.rs @@ -1,3 +1,4 @@ +use super::medium_editor::MediumEditor; use super::disc_source::DiscSource; use crate::backend::Backend; use crate::widgets::{Navigator, NavigatorScreen}; @@ -55,7 +56,13 @@ impl SourceSelector { context.spawn_local(async move { match DiscSource::load().await { Ok(disc) => { - println!("{:?}", disc); + let navigator = clone.navigator.borrow().clone(); + if let Some(navigator) = navigator { + let editor = MediumEditor::new(clone.backend.clone(), disc); + navigator.push(editor); + } + + clone.info_bar.set_revealed(false); clone.stack.set_visible_child_name("start"); } Err(_) => { diff --git a/musicus/src/widgets/mod.rs b/musicus/src/widgets/mod.rs index 9e59253..089a3ec 100644 --- a/musicus/src/widgets/mod.rs +++ b/musicus/src/widgets/mod.rs @@ -7,6 +7,8 @@ pub use navigator::*; pub mod navigator_window; pub use navigator_window::*; +pub mod new_list; + pub mod player_bar; pub use player_bar::*; diff --git a/musicus/src/widgets/new_list.rs b/musicus/src/widgets/new_list.rs new file mode 100644 index 0000000..98261e6 --- /dev/null +++ b/musicus/src/widgets/new_list.rs @@ -0,0 +1,50 @@ +use gtk::prelude::*; +use std::cell::RefCell; + +/// A simple list of widgets. +pub struct List { + pub widget: gtk::ListBox, + make_widget: RefCell gtk::Widget>>>, +} + +impl List { + /// Create a new list. The list will be empty. + pub fn new(placeholder_text: &str) -> Self { + let placeholder_label = gtk::Label::new(Some(placeholder_text)); + placeholder_label.set_margin_top(6); + placeholder_label.set_margin_bottom(6); + placeholder_label.set_margin_start(6); + placeholder_label.set_margin_end(6); + placeholder_label.show(); + + let widget = gtk::ListBox::new(); + widget.set_selection_mode(gtk::SelectionMode::None); + widget.set_placeholder(Some(&placeholder_label)); + widget.show(); + + Self { + widget, + make_widget: RefCell::new(None), + } + } + + /// Set the closure to be called to construct widgets for the items. + pub fn set_make_widget gtk::Widget + 'static>(&self, make_widget: F) { + self.make_widget.replace(Some(Box::new(make_widget))); + } + + /// Call the make_widget function for each item. This will automatically + /// show all children by indices 0..length. + pub fn update(&self, length: usize) { + for child in self.widget.get_children() { + self.widget.remove(&child); + } + + if let Some(make_widget) = &*self.make_widget.borrow() { + for index in 0..length { + let row = make_widget(index); + self.widget.insert(&row, -1); + } + } + } +}