mirror of
				https://github.com/johrpan/musicus.git
				synced 2025-10-26 19:57:25 +01:00 
			
		
		
		
	Make recording screen functional again
This commit is contained in:
		
							parent
							
								
									d5a1de05a7
								
							
						
					
					
						commit
						9e10d47b87
					
				
					 2 changed files with 94 additions and 18 deletions
				
			
		|  | @ -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(§ion.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() | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Elias Projahn
						Elias Projahn