mirror of
				https://github.com/johrpan/musicus.git
				synced 2025-10-26 11:47:25 +01:00 
			
		
		
		
	Update dependencies, adapt code, fix warnings
This commit is contained in:
		
							parent
							
								
									75d4e82cf8
								
							
						
					
					
						commit
						835d4f0d42
					
				
					 44 changed files with 595 additions and 541 deletions
				
			
		
							
								
								
									
										677
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										677
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -6,10 +6,10 @@ edition = "2021" | ||||||
| [dependencies] | [dependencies] | ||||||
| chrono = "0.4" | chrono = "0.4" | ||||||
| fragile = "2" | fragile = "2" | ||||||
| gio = "0.16" | gio = "0.17" | ||||||
| glib = "0.16" | glib = "0.17" | ||||||
| gstreamer = "0.19" | gstreamer = "0.20" | ||||||
| gstreamer-player = "0.19" | gstreamer-player = "0.20" | ||||||
| log = { version = "0.4", features = ["std"] } | log = { version = "0.4", features = ["std"] } | ||||||
| musicus_database = { version = "0.1.0", path = "../database" } | musicus_database = { version = "0.1.0", path = "../database" } | ||||||
| musicus_import = { version = "0.1.0", path = "../import" } | musicus_import = { version = "0.1.0", path = "../import" } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,9 @@ | ||||||
| use chrono::{Local, DateTime}; | use chrono::{DateTime, Local}; | ||||||
| use log::{Level, LevelFilter, Log, Metadata, Record}; | use log::{Level, LevelFilter, Log, Metadata, Record}; | ||||||
| use std::{fmt::Display, sync::{Arc, Mutex}}; | use std::{ | ||||||
|  |     fmt::Display, | ||||||
|  |     sync::{Arc, Mutex}, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| /// Register the custom logger. This will panic if called more than once.
 | /// Register the custom logger. This will panic if called more than once.
 | ||||||
| pub fn register() -> Arc<Logger> { | pub fn register() -> Arc<Logger> { | ||||||
|  | @ -72,6 +75,10 @@ impl<'a> From<&Record<'a>> for LogMessage { | ||||||
| 
 | 
 | ||||||
| impl Display for LogMessage { | impl Display for LogMessage { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         write!(f, "{} {} ({}): {}", self.time, self.module, self.level, self.message) |         write!( | ||||||
|  |             f, | ||||||
|  |             "{} {} ({}): {}", | ||||||
|  |             self.time, self.module, self.level, self.message | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| use crate::{Backend, Error, Result}; | use crate::{Backend, Error, Result}; | ||||||
| use db::Track; | use db::Track; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | use gstreamer_player::PlayerVideoRenderer; | ||||||
| use musicus_database as db; | use musicus_database as db; | ||||||
| use std::cell::{Cell, RefCell}; | use std::cell::{Cell, RefCell}; | ||||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||||
|  | @ -32,10 +33,7 @@ pub struct Player { | ||||||
| impl Player { | impl Player { | ||||||
|     pub fn new(music_library_path: PathBuf) -> Rc<Self> { |     pub fn new(music_library_path: PathBuf) -> Rc<Self> { | ||||||
|         let dispatcher = gstreamer_player::PlayerGMainContextSignalDispatcher::new(None); |         let dispatcher = gstreamer_player::PlayerGMainContextSignalDispatcher::new(None); | ||||||
|         let player = gstreamer_player::Player::new( |         let player = gstreamer_player::Player::new(None::<PlayerVideoRenderer>, Some(dispatcher)); | ||||||
|             gstreamer_player::PlayerVideoRenderer::NONE, |  | ||||||
|             Some(&dispatcher), |  | ||||||
|         ); |  | ||||||
|         let mut config = player.config(); |         let mut config = player.config(); | ||||||
|         config.set_position_update_interval(250); |         config.set_position_update_interval(250); | ||||||
|         player.set_config(config).unwrap(); |         player.set_config(config).unwrap(); | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ use chrono::Utc; | ||||||
| use diesel::prelude::*; | use diesel::prelude::*; | ||||||
| use log::info; | use log::info; | ||||||
| 
 | 
 | ||||||
| use crate::{Result, schema::ensembles, defer_foreign_keys}; | use crate::{defer_foreign_keys, schema::ensembles, Result}; | ||||||
| 
 | 
 | ||||||
| /// An ensemble that takes part in recordings.
 | /// An ensemble that takes part in recordings.
 | ||||||
| #[derive(Insertable, Queryable, PartialEq, Eq, Hash, Debug, Clone)] | #[derive(Insertable, Queryable, PartialEq, Eq, Hash, Debug, Clone)] | ||||||
|  |  | ||||||
|  | @ -82,7 +82,7 @@ impl Track { | ||||||
| 
 | 
 | ||||||
| /// Table data for a [`Medium`].
 | /// Table data for a [`Medium`].
 | ||||||
| #[derive(Insertable, Queryable, Debug, Clone)] | #[derive(Insertable, Queryable, Debug, Clone)] | ||||||
| #[table_name = "mediums"] | #[diesel(table_name = mediums)] | ||||||
| struct MediumRow { | struct MediumRow { | ||||||
|     pub id: String, |     pub id: String, | ||||||
|     pub name: String, |     pub name: String, | ||||||
|  | @ -93,7 +93,7 @@ struct MediumRow { | ||||||
| 
 | 
 | ||||||
| /// Table data for a [`Track`].
 | /// Table data for a [`Track`].
 | ||||||
| #[derive(Insertable, Queryable, QueryableByName, Debug, Clone)] | #[derive(Insertable, Queryable, QueryableByName, Debug, Clone)] | ||||||
| #[table_name = "tracks"] | #[diesel(table_name = tracks)] | ||||||
| struct TrackRow { | struct TrackRow { | ||||||
|     pub id: String, |     pub id: String, | ||||||
|     pub medium: Option<String>, |     pub medium: Option<String>, | ||||||
|  |  | ||||||
|  | @ -97,7 +97,7 @@ impl PersonOrEnsemble { | ||||||
| 
 | 
 | ||||||
| /// Database table data for a recording.
 | /// Database table data for a recording.
 | ||||||
| #[derive(Insertable, Queryable, QueryableByName, Debug, Clone)] | #[derive(Insertable, Queryable, QueryableByName, Debug, Clone)] | ||||||
| #[table_name = "recordings"] | #[diesel(table_name = recordings)] | ||||||
| struct RecordingRow { | struct RecordingRow { | ||||||
|     pub id: String, |     pub id: String, | ||||||
|     pub work: String, |     pub work: String, | ||||||
|  | @ -120,7 +120,7 @@ impl From<Recording> for RecordingRow { | ||||||
| 
 | 
 | ||||||
| /// Database table data for a performance.
 | /// Database table data for a performance.
 | ||||||
| #[derive(Insertable, Queryable, Debug, Clone)] | #[derive(Insertable, Queryable, Debug, Clone)] | ||||||
| #[table_name = "performances"] | #[diesel(table_name = performances)] | ||||||
| struct PerformanceRow { | struct PerformanceRow { | ||||||
|     pub id: i64, |     pub id: i64, | ||||||
|     pub recording: String, |     pub recording: String, | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ use crate::{ | ||||||
| 
 | 
 | ||||||
| /// Table row data for a work.
 | /// Table row data for a work.
 | ||||||
| #[derive(Insertable, Queryable, Debug, Clone)] | #[derive(Insertable, Queryable, Debug, Clone)] | ||||||
| #[table_name = "works"] | #[diesel(table_name = works)] | ||||||
| struct WorkRow { | struct WorkRow { | ||||||
|     pub id: String, |     pub id: String, | ||||||
|     pub composer: String, |     pub composer: String, | ||||||
|  | @ -33,7 +33,7 @@ impl From<Work> for WorkRow { | ||||||
| 
 | 
 | ||||||
| /// Definition that a work uses an instrument.
 | /// Definition that a work uses an instrument.
 | ||||||
| #[derive(Insertable, Queryable, Debug, Clone)] | #[derive(Insertable, Queryable, Debug, Clone)] | ||||||
| #[table_name = "instrumentations"] | #[diesel(table_name = instrumentations)] | ||||||
| struct InstrumentationRow { | struct InstrumentationRow { | ||||||
|     pub id: i64, |     pub id: i64, | ||||||
|     pub work: String, |     pub work: String, | ||||||
|  | @ -42,7 +42,7 @@ struct InstrumentationRow { | ||||||
| 
 | 
 | ||||||
| /// Table row data for a work part.
 | /// Table row data for a work part.
 | ||||||
| #[derive(Insertable, Queryable, Debug, Clone)] | #[derive(Insertable, Queryable, Debug, Clone)] | ||||||
| #[table_name = "work_parts"] | #[diesel(table_name = work_parts)] | ||||||
| struct WorkPartRow { | struct WorkPartRow { | ||||||
|     pub id: i64, |     pub id: i64, | ||||||
|     pub work: String, |     pub work: String, | ||||||
|  |  | ||||||
|  | @ -4,10 +4,10 @@ version = "0.1.0" | ||||||
| edition = "2021" | edition = "2021" | ||||||
| 
 | 
 | ||||||
| [dependencies] | [dependencies] | ||||||
| base64 = "0.13" | base64 = "0.21" | ||||||
| glib = "0.16" | glib = "0.17" | ||||||
| gstreamer = "0.19" | gstreamer = "0.20" | ||||||
| gstreamer-pbutils = "0.19" | gstreamer-pbutils = "0.20" | ||||||
| log = "0.4" | log = "0.4" | ||||||
| once_cell = "1" | once_cell = "1" | ||||||
| rand = "0.8" | rand = "0.8" | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| use crate::error::{Error, Result}; | use crate::error::{Error, Result}; | ||||||
| use crate::session::{ImportSession, ImportTrack, State}; | use crate::session::{ImportSession, ImportTrack, State}; | ||||||
|  | use base64::Engine; | ||||||
| use gstreamer::prelude::*; | use gstreamer::prelude::*; | ||||||
| use gstreamer::tags::{Duration, TrackNumber}; | use gstreamer::tags::{Duration, TrackNumber}; | ||||||
| use gstreamer::{ClockTime, ElementFactory, MessageType, MessageView, TocEntryType}; | use gstreamer::{ClockTime, ElementFactory, MessageType, MessageView, TocEntryType}; | ||||||
|  | @ -108,7 +109,7 @@ pub(super) fn new() -> Result<ImportSession> { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     let source_id = base64::encode_config(hasher.finalize(), base64::URL_SAFE); |     let source_id = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(hasher.finalize()); | ||||||
| 
 | 
 | ||||||
|     info!("Successfully loaded audio CD with {} tracks.", tracks.len()); |     info!("Successfully loaded audio CD with {} tracks.", tracks.len()); | ||||||
|     info!("Source ID: {}", source_id); |     info!("Source ID: {}", source_id); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| use crate::error::{Error, Result}; | use crate::error::{Error, Result}; | ||||||
| use crate::session::{ImportSession, ImportTrack, State}; | use crate::session::{ImportSession, ImportTrack, State}; | ||||||
|  | use base64::Engine; | ||||||
| use gstreamer::ClockTime; | use gstreamer::ClockTime; | ||||||
| use gstreamer_pbutils::Discoverer; | use gstreamer_pbutils::Discoverer; | ||||||
| use log::{info, warn}; | use log::{info, warn}; | ||||||
|  | @ -64,7 +65,7 @@ pub(super) fn new(path: PathBuf) -> Result<ImportSession> { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     let source_id = base64::encode_config(hasher.finalize(), base64::URL_SAFE); |     let source_id = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(hasher.finalize()); | ||||||
| 
 | 
 | ||||||
|     info!("Source ID: {}", source_id); |     info!("Source ID: {}", source_id); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,13 +5,13 @@ edition = "2021" | ||||||
| 
 | 
 | ||||||
| [dependencies] | [dependencies] | ||||||
| anyhow = "1" | anyhow = "1" | ||||||
| adw = { package = "libadwaita", version = "0.2", features = ["v1_2"] } | adw = { package = "libadwaita", version = "0.3", features = ["v1_2"] } | ||||||
| futures-channel = "0.3" | futures-channel = "0.3" | ||||||
| gettext-rs = { version = "0.7", features = ["gettext-system"] } | gettext-rs = { version = "0.7", features = ["gettext-system"] } | ||||||
| gio = "0.16" | gio = "0.17" | ||||||
| glib = "0.16" | glib = "0.17" | ||||||
| gstreamer = "0.19" | gstreamer = "0.20" | ||||||
| gtk = { package = "gtk4", version = "0.5" } | gtk = { package = "gtk4", version = "0.6" } | ||||||
| gtk-macros = "0.3" | gtk-macros = "0.3" | ||||||
| log = "0.4" | log = "0.4" | ||||||
| musicus_backend = { version = "0.1.0", path = "../backend" } | musicus_backend = { version = "0.1.0", path = "../backend" } | ||||||
|  |  | ||||||
|  | @ -2,8 +2,8 @@ use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::{Editor, Section, Widget}; | use crate::widgets::{Editor, Section, Widget}; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use gtk::{builders::ListBoxBuilder, glib::clone, prelude::*}; | use gtk::{glib::clone, prelude::*}; | ||||||
| use musicus_backend::db::{generate_id, Ensemble, self}; | use musicus_backend::db::{self, generate_id, Ensemble}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
| /// A dialog for creating or editing a ensemble.
 | /// A dialog for creating or editing a ensemble.
 | ||||||
|  | @ -23,12 +23,12 @@ impl Screen<Option<Ensemble>, Ensemble> for EnsembleEditor { | ||||||
|         let editor = Editor::new(); |         let editor = Editor::new(); | ||||||
|         editor.set_title("Ensemble"); |         editor.set_title("Ensemble"); | ||||||
| 
 | 
 | ||||||
|         let list = ListBoxBuilder::new() |         let list = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let name = adw::EntryRow::builder().title(&gettext("Name")).build(); |         let name = adw::EntryRow::builder().title(gettext("Name")).build(); | ||||||
|         list.append(&name); |         list.append(&name); | ||||||
| 
 | 
 | ||||||
|         let section = Section::new(&gettext("General"), &list); |         let section = Section::new(&gettext("General"), &list); | ||||||
|  | @ -88,7 +88,10 @@ impl EnsembleEditor { | ||||||
| 
 | 
 | ||||||
|         let ensemble = Ensemble::new(self.id.clone(), name.to_string()); |         let ensemble = Ensemble::new(self.id.clone(), name.to_string()); | ||||||
| 
 | 
 | ||||||
|         db::update_ensemble(&mut self.handle.backend.db().lock().unwrap(), ensemble.clone())?; |         db::update_ensemble( | ||||||
|  |             &mut self.handle.backend.db().lock().unwrap(), | ||||||
|  |             ensemble.clone(), | ||||||
|  |         )?; | ||||||
|         self.handle.backend.library_changed(); |         self.handle.backend.library_changed(); | ||||||
| 
 | 
 | ||||||
|         Ok(ensemble) |         Ok(ensemble) | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::{Editor, Section, Widget}; | use crate::widgets::{Editor, Section, Widget}; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use gtk::{builders::ListBoxBuilder, glib::clone, prelude::*}; | use gtk::{glib::clone, prelude::*}; | ||||||
| use musicus_backend::db::{self, generate_id, Instrument}; | use musicus_backend::db::{self, generate_id, Instrument}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
|  | @ -23,12 +23,12 @@ impl Screen<Option<Instrument>, Instrument> for InstrumentEditor { | ||||||
|         let editor = Editor::new(); |         let editor = Editor::new(); | ||||||
|         editor.set_title("Instrument/Role"); |         editor.set_title("Instrument/Role"); | ||||||
| 
 | 
 | ||||||
|         let list = ListBoxBuilder::new() |         let list = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let name = adw::EntryRow::builder().title(&gettext("Name")).build(); |         let name = adw::EntryRow::builder().title(gettext("Name")).build(); | ||||||
|         list.append(&name); |         list.append(&name); | ||||||
| 
 | 
 | ||||||
|         let section = Section::new(&gettext("General"), &list); |         let section = Section::new(&gettext("General"), &list); | ||||||
|  |  | ||||||
|  | @ -3,8 +3,8 @@ use crate::selectors::{EnsembleSelector, InstrumentSelector, PersonSelector}; | ||||||
| use crate::widgets::{ButtonRow, Editor, Section, Widget}; | use crate::widgets::{ButtonRow, Editor, Section, Widget}; | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use gtk::builders::ButtonBuilder; | 
 | ||||||
| use gtk::{builders::ListBoxBuilder, glib::clone}; | use gtk::glib::clone; | ||||||
| use log::error; | use log::error; | ||||||
| use musicus_backend::db::{Ensemble, Instrument, Performance, Person, PersonOrEnsemble}; | use musicus_backend::db::{Ensemble, Instrument, Performance, Person, PersonOrEnsemble}; | ||||||
| use std::cell::RefCell; | use std::cell::RefCell; | ||||||
|  | @ -30,7 +30,7 @@ impl Screen<Option<Performance>, Performance> for PerformanceEditor { | ||||||
|         editor.set_title("Performance"); |         editor.set_title("Performance"); | ||||||
|         editor.set_may_save(false); |         editor.set_may_save(false); | ||||||
| 
 | 
 | ||||||
|         let performer_list = ListBoxBuilder::new() |         let performer_list = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
|  | @ -46,12 +46,12 @@ impl Screen<Option<Performance>, Performance> for PerformanceEditor { | ||||||
|             "Select either a person or an ensemble as a performer.", |             "Select either a person or an ensemble as a performer.", | ||||||
|         )); |         )); | ||||||
| 
 | 
 | ||||||
|         let role_list = ListBoxBuilder::new() |         let role_list = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let reset_role_button = ButtonBuilder::new() |         let reset_role_button = gtk::Button::builder() | ||||||
|             .icon_name("user-trash-symbolic") |             .icon_name("user-trash-symbolic") | ||||||
|             .valign(gtk::Align::Center) |             .valign(gtk::Align::Center) | ||||||
|             .visible(false) |             .visible(false) | ||||||
|  |  | ||||||
|  | @ -3,8 +3,8 @@ use crate::widgets::{Editor, Section, Widget}; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::{builders::ListBoxBuilder, prelude::*}; | use gtk::prelude::*; | ||||||
| use musicus_backend::db::{generate_id, Person, self}; | use musicus_backend::db::{self, generate_id, Person}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
| /// A dialog for creating or editing a person.
 | /// A dialog for creating or editing a person.
 | ||||||
|  | @ -25,18 +25,16 @@ impl Screen<Option<Person>, Person> for PersonEditor { | ||||||
|         let editor = Editor::new(); |         let editor = Editor::new(); | ||||||
|         editor.set_title("Person"); |         editor.set_title("Person"); | ||||||
| 
 | 
 | ||||||
|         let list = ListBoxBuilder::new() |         let list = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let first_name = adw::EntryRow::builder() |         let first_name = adw::EntryRow::builder() | ||||||
|             .title(&gettext("First name")) |             .title(gettext("First name")) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let last_name = adw::EntryRow::builder() |         let last_name = adw::EntryRow::builder().title(gettext("Last name")).build(); | ||||||
|             .title(&gettext("Last name")) |  | ||||||
|             .build(); |  | ||||||
| 
 | 
 | ||||||
|         list.append(&first_name); |         list.append(&first_name); | ||||||
|         list.append(&last_name); |         list.append(&last_name); | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ use super::performance::PerformanceEditor; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::selectors::WorkSelector; | use crate::selectors::WorkSelector; | ||||||
| use crate::widgets::{List, Widget}; | use crate::widgets::{List, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
|  | @ -129,10 +129,10 @@ impl Screen<Option<Recording>, Recording> for RecordingEditor { | ||||||
|                 }); |                 }); | ||||||
|             })); |             })); | ||||||
| 
 | 
 | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .focusable(false) |                 .focusable(false) | ||||||
|                 .activatable_widget(&edit_button) |                 .activatable_widget(&edit_button) | ||||||
|                 .title(&performance.get_title()) |                 .title(performance.get_title()) | ||||||
|                 .build(); |                 .build(); | ||||||
| 
 | 
 | ||||||
|             row.add_suffix(&delete_button); |             row.add_suffix(&delete_button); | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ use super::work_part::WorkPartEditor; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::selectors::{InstrumentSelector, PersonSelector}; | use crate::selectors::{InstrumentSelector, PersonSelector}; | ||||||
| use crate::widgets::{List, Widget}; | use crate::widgets::{List, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
|  | @ -125,7 +125,7 @@ impl Screen<Option<Work>, Work> for WorkEditor { | ||||||
|                     this.instrument_list.update(length); |                     this.instrument_list.update(length); | ||||||
|                 })); |                 })); | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .title(&instrument.name) |                     .title(&instrument.name) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|  | @ -184,7 +184,7 @@ impl Screen<Option<Work>, Work> for WorkEditor { | ||||||
|                     }); |                     }); | ||||||
|                 })); |                 })); | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .focusable(false) |                     .focusable(false) | ||||||
|                     .title(&part.title) |                     .title(&part.title) | ||||||
|                     .activatable_widget(&edit_button) |                     .activatable_widget(&edit_button) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ use super::medium_preview::MediumPreview; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::selectors::MediumSelector; | use crate::selectors::MediumSelector; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk_macros::get_widget; | use gtk_macros::get_widget; | ||||||
|  | @ -68,10 +68,10 @@ impl ImportScreen { | ||||||
|         let this = self; |         let this = self; | ||||||
| 
 | 
 | ||||||
|         for medium in mediums { |         for medium in mediums { | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .activatable(true) |                 .activatable(true) | ||||||
|                 .title(&medium.name) |                 .title(&medium.name) | ||||||
|                 .subtitle(&format!("{} Tracks", medium.tracks.len())) |                 .subtitle(format!("{} Tracks", medium.tracks.len())) | ||||||
|                 .build(); |                 .build(); | ||||||
| 
 | 
 | ||||||
|             row.connect_activated(clone!(@weak this =>  move |_| { |             row.connect_activated(clone!(@weak this =>  move |_| { | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| use super::track_set_editor::{TrackData, TrackSetData, TrackSetEditor}; | use super::track_set_editor::{TrackData, TrackSetData, TrackSetEditor}; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::{List, Widget}; | use crate::widgets::{List, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -109,10 +109,10 @@ impl Screen<(Arc<ImportSession>, Option<Medium>), Medium> for MediumEditor { | ||||||
|                 edit_button.set_valign(gtk::Align::Center); |                 edit_button.set_valign(gtk::Align::Center); | ||||||
|                 edit_button.set_child(Some(&edit_image)); |                 edit_button.set_child(Some(&edit_image)); | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .focusable(false) |                     .focusable(false) | ||||||
|                     .title(&title) |                     .title(title) | ||||||
|                     .subtitle(&subtitle) |                     .subtitle(subtitle) | ||||||
|                     .activatable_widget(&edit_button) |                     .activatable_widget(&edit_button) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,11 +1,11 @@ | ||||||
| use super::medium_editor::MediumEditor; | use super::medium_editor::MediumEditor; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use anyhow::{anyhow, Result}; | use anyhow::{anyhow, Result}; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::builders::{FrameBuilder, ListBoxBuilder}; | 
 | ||||||
| use gtk::prelude::*; | use gtk::prelude::*; | ||||||
| use gtk_macros::get_widget; | use gtk_macros::get_widget; | ||||||
| use musicus_backend::db::{self, Medium}; | use musicus_backend::db::{self, Medium}; | ||||||
|  | @ -141,16 +141,16 @@ impl MediumPreview { | ||||||
|             if track.recording.id != last_recording_id { |             if track.recording.id != last_recording_id { | ||||||
|                 last_recording_id = &track.recording.id; |                 last_recording_id = &track.recording.id; | ||||||
| 
 | 
 | ||||||
|                 let list = ListBoxBuilder::new() |                 let list = gtk::ListBox::builder() | ||||||
|                     .selection_mode(gtk::SelectionMode::None) |                     .selection_mode(gtk::SelectionMode::None) | ||||||
|                     .margin_bottom(12) |                     .margin_bottom(12) | ||||||
|                     .css_classes(vec![String::from("boxed-list")]) |                     .css_classes(vec![String::from("boxed-list")]) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 let header = ActionRowBuilder::new() |                 let header = adw::ActionRow::builder() | ||||||
|                     .activatable(false) |                     .activatable(false) | ||||||
|                     .title(&track.recording.work.get_title()) |                     .title(track.recording.work.get_title()) | ||||||
|                     .subtitle(&track.recording.get_performers()) |                     .subtitle(track.recording.get_performers()) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 list.append(&header); |                 list.append(&header); | ||||||
|  | @ -174,9 +174,9 @@ impl MediumPreview { | ||||||
|                     parts.join(", ") |                     parts.join(", ") | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(false) |                     .activatable(false) | ||||||
|                     .title(&title) |                     .title(title) | ||||||
|                     .subtitle(&import_tracks[track.source_index].name) |                     .subtitle(&import_tracks[track.source_index].name) | ||||||
|                     .margin_start(12) |                     .margin_start(12) | ||||||
|                     .build(); |                     .build(); | ||||||
|  | @ -186,7 +186,7 @@ impl MediumPreview { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if let Some(list) = &last_list { |         if let Some(list) = &last_list { | ||||||
|             let frame = FrameBuilder::new().margin_bottom(12).build(); |             let frame = gtk::Frame::builder().margin_bottom(12).build(); | ||||||
| 
 | 
 | ||||||
|             frame.set_child(Some(list)); |             frame.set_child(Some(list)); | ||||||
|             self.medium_box.append(&frame); |             self.medium_box.append(&frame); | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::builders::ListBoxBuilder; | 
 | ||||||
| use gtk_macros::get_widget; | use gtk_macros::get_widget; | ||||||
| use musicus_backend::db::Recording; | use musicus_backend::db::Recording; | ||||||
| use std::cell::RefCell; | use std::cell::RefCell; | ||||||
|  | @ -31,7 +31,7 @@ impl Screen<(Recording, Vec<usize>), Vec<usize>> for TrackEditor { | ||||||
|         get_widget!(builder, gtk::Button, select_button); |         get_widget!(builder, gtk::Button, select_button); | ||||||
|         get_widget!(builder, adw::Clamp, clamp); |         get_widget!(builder, adw::Clamp, clamp); | ||||||
| 
 | 
 | ||||||
|         let parts_list = ListBoxBuilder::new() |         let parts_list = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
|  | @ -68,7 +68,7 @@ impl Screen<(Recording, Vec<usize>), Vec<usize>> for TrackEditor { | ||||||
|                 } |                 } | ||||||
|             })); |             })); | ||||||
| 
 | 
 | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .focusable(false) |                 .focusable(false) | ||||||
|                 .title(&part.title) |                 .title(&part.title) | ||||||
|                 .activatable_widget(&check) |                 .activatable_widget(&check) | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::builders::ListBoxBuilder; | 
 | ||||||
| use gtk_macros::get_widget; | use gtk_macros::get_widget; | ||||||
| use musicus_backend::import::ImportSession; | use musicus_backend::import::ImportSession; | ||||||
| use std::cell::RefCell; | use std::cell::RefCell; | ||||||
|  | @ -31,7 +31,7 @@ impl Screen<Arc<ImportSession>, Vec<usize>> for TrackSelector { | ||||||
|         get_widget!(builder, gtk::Button, select_button); |         get_widget!(builder, gtk::Button, select_button); | ||||||
|         get_widget!(builder, adw::Clamp, clamp); |         get_widget!(builder, adw::Clamp, clamp); | ||||||
| 
 | 
 | ||||||
|         let track_list = ListBoxBuilder::new() |         let track_list = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
|  | @ -78,7 +78,7 @@ impl Screen<Arc<ImportSession>, Vec<usize>> for TrackSelector { | ||||||
|                 } |                 } | ||||||
|             })); |             })); | ||||||
| 
 | 
 | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .focusable(false) |                 .focusable(false) | ||||||
|                 .title(&track.name) |                 .title(&track.name) | ||||||
|                 .activatable_widget(&check) |                 .activatable_widget(&check) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ use super::track_selector::TrackSelector; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::selectors::RecordingSelector; | use crate::selectors::RecordingSelector; | ||||||
| use crate::widgets::{List, Widget}; | use crate::widgets::{List, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -145,9 +145,9 @@ impl Screen<Arc<ImportSession>, TrackSetData> for TrackSetEditor { | ||||||
|             edit_button.set_valign(gtk::Align::Center); |             edit_button.set_valign(gtk::Align::Center); | ||||||
|             edit_button.set_child(Some(&edit_image)); |             edit_button.set_child(Some(&edit_image)); | ||||||
| 
 | 
 | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .focusable(false) |                 .focusable(false) | ||||||
|                 .title(&title) |                 .title(title) | ||||||
|                 .subtitle(track_name) |                 .subtitle(track_name) | ||||||
|                 .activatable_widget(&edit_button) |                 .activatable_widget(&edit_button) | ||||||
|                 .build(); |                 .build(); | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ use crate::widgets::Widget; | ||||||
| use futures_channel::oneshot; | use futures_channel::oneshot; | ||||||
| use futures_channel::oneshot::{Receiver, Sender}; | use futures_channel::oneshot::{Receiver, Sender}; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::builders::StackBuilder; | 
 | ||||||
| use gtk::prelude::*; | use gtk::prelude::*; | ||||||
| use musicus_backend::Backend; | use musicus_backend::Backend; | ||||||
| use std::cell::{Cell, RefCell}; | use std::cell::{Cell, RefCell}; | ||||||
|  | @ -97,7 +97,7 @@ impl Navigator { | ||||||
|         W: IsA<gtk::Window>, |         W: IsA<gtk::Window>, | ||||||
|         E: IsA<gtk::Widget>, |         E: IsA<gtk::Widget>, | ||||||
|     { |     { | ||||||
|         let widget = StackBuilder::new() |         let widget = gtk::Stack::builder() | ||||||
|             .hhomogeneous(false) |             .hhomogeneous(false) | ||||||
|             .vhomogeneous(false) |             .vhomogeneous(false) | ||||||
|             .interpolate_size(true) |             .interpolate_size(true) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ use crate::editors::EnsembleEditor; | ||||||
| use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | ||||||
| use crate::widgets; | use crate::widgets; | ||||||
| use crate::widgets::{List, Section, Widget}; | use crate::widgets::{List, Section, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -75,10 +75,10 @@ impl Screen<Ensemble, ()> for EnsembleScreen { | ||||||
|             clone!(@weak this => @default-panic,  move |index| { |             clone!(@weak this => @default-panic,  move |index| { | ||||||
|                 let recording = &this.recordings.borrow()[index]; |                 let recording = &this.recordings.borrow()[index]; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&recording.work.get_title()) |                     .title(recording.work.get_title()) | ||||||
|                     .subtitle(&recording.get_performers()) |                     .subtitle(recording.get_performers()) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 let recording = recording.to_owned(); |                 let recording = recording.to_owned(); | ||||||
|  | @ -105,7 +105,7 @@ impl Screen<Ensemble, ()> for EnsembleScreen { | ||||||
|             .set_make_widget_cb(clone!(@weak this => @default-panic,  move |index| { |             .set_make_widget_cb(clone!(@weak this => @default-panic,  move |index| { | ||||||
|                 let medium = &this.mediums.borrow()[index]; |                 let medium = &this.mediums.borrow()[index]; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&medium.name) |                     .title(&medium.name) | ||||||
|                     .build(); |                     .build(); | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ use crate::import::SourceSelector; | ||||||
| use crate::navigator::{NavigationHandle, Navigator, NavigatorWindow, Screen}; | use crate::navigator::{NavigationHandle, Navigator, NavigatorWindow, Screen}; | ||||||
| use crate::preferences::Preferences; | use crate::preferences::Preferences; | ||||||
| use crate::widgets::{List, PlayerBar, Widget}; | use crate::widgets::{List, PlayerBar, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -102,9 +102,9 @@ impl Screen<(), ()> for MainScreen { | ||||||
|             .set_make_widget_cb(clone!(@weak this =>  @default-panic, move |index| { |             .set_make_widget_cb(clone!(@weak this =>  @default-panic, move |index| { | ||||||
|                 let poe = &this.poes.borrow()[index]; |                 let poe = &this.poes.borrow()[index]; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&poe.get_title()) |                     .title(poe.get_title()) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 let poe = poe.to_owned(); |                 let poe = poe.to_owned(); | ||||||
|  | @ -207,13 +207,13 @@ impl MainScreen { | ||||||
| 
 | 
 | ||||||
|         copy_button.connect_clicked(clone!(@weak logger, @weak toast_overlay => move |widget| { |         copy_button.connect_clicked(clone!(@weak logger, @weak toast_overlay => move |widget| { | ||||||
|             widget.clipboard().set_text(&logger.messages().into_iter().map(|m| m.to_string()).collect::<Vec<String>>().join("\n")); |             widget.clipboard().set_text(&logger.messages().into_iter().map(|m| m.to_string()).collect::<Vec<String>>().join("\n")); | ||||||
|             toast_overlay.add_toast(&adw::Toast::builder().title(&gettext("Copied to clipboard")).build()); |             toast_overlay.add_toast(adw::Toast::builder().title(gettext("Copied to clipboard")).build()); | ||||||
|         })); |         })); | ||||||
| 
 | 
 | ||||||
|         let header = adw::HeaderBar::builder() |         let header = adw::HeaderBar::builder() | ||||||
|             .title_widget( |             .title_widget( | ||||||
|                 &adw::WindowTitle::builder() |                 &adw::WindowTitle::builder() | ||||||
|                     .title(&gettext("Debug log")) |                     .title(gettext("Debug log")) | ||||||
|                     .build(), |                     .build(), | ||||||
|             ) |             ) | ||||||
|             .build(); |             .build(); | ||||||
|  | @ -227,7 +227,7 @@ impl MainScreen { | ||||||
|         for message in logger.messages() { |         for message in logger.messages() { | ||||||
|             log_list.append( |             log_list.append( | ||||||
|                 &adw::ActionRow::builder() |                 &adw::ActionRow::builder() | ||||||
|                     .title(&format!( |                     .title(format!( | ||||||
|                         "<b>{}</b> {} <i>{}</i>", |                         "<b>{}</b> {} <i>{}</i>", | ||||||
|                         message.level, |                         message.level, | ||||||
|                         message.time.format("%Y-%m-%d %H:%M:%S"), |                         message.time.format("%Y-%m-%d %H:%M:%S"), | ||||||
|  | @ -255,7 +255,7 @@ impl MainScreen { | ||||||
|         adw::Window::builder() |         adw::Window::builder() | ||||||
|             .transient_for(&self.handle.window) |             .transient_for(&self.handle.window) | ||||||
|             .modal(true) |             .modal(true) | ||||||
|             .title(&gettext("Debug log")) |             .title(gettext("Debug log")) | ||||||
|             .default_width(640) |             .default_width(640) | ||||||
|             .default_height(480) |             .default_height(480) | ||||||
|             .content(&toast_overlay) |             .content(&toast_overlay) | ||||||
|  | @ -269,10 +269,10 @@ impl MainScreen { | ||||||
|             .transient_for(&self.handle.window) |             .transient_for(&self.handle.window) | ||||||
|             .modal(true) |             .modal(true) | ||||||
|             .application_icon("de.johrpan.musicus") |             .application_icon("de.johrpan.musicus") | ||||||
|             .application_name(&gettext("Musicus")) |             .application_name(gettext("Musicus")) | ||||||
|             .developer_name("Elias Projahn") |             .developer_name("Elias Projahn") | ||||||
|             .version(config::VERSION) |             .version(config::VERSION) | ||||||
|             .comments(&gettext("The classical music player and organizer.")) |             .comments(gettext("The classical music player and organizer.")) | ||||||
|             .website("https://code.johrpan.de/johrpan/musicus") |             .website("https://code.johrpan.de/johrpan/musicus") | ||||||
|             .developers(vec![String::from("Elias Projahn <elias@johrpan.de>")]) |             .developers(vec![String::from("Elias Projahn <elias@johrpan.de>")]) | ||||||
|             .copyright("© 2022 Elias Projahn") |             .copyright("© 2022 Elias Projahn") | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets; | use crate::widgets; | ||||||
| use crate::widgets::{List, Section, Widget}; | use crate::widgets::{List, Section, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -75,10 +75,10 @@ impl Screen<Medium, ()> for MediumScreen { | ||||||
|                     parts.join(", ") |                     parts.join(", ") | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .margin_start(12) |                     .margin_start(12) | ||||||
|                     .selectable(false) |                     .selectable(false) | ||||||
|                     .title(&title) |                     .title(title) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 row.upcast() |                 row.upcast() | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ use crate::editors::PersonEditor; | ||||||
| use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | ||||||
| use crate::widgets; | use crate::widgets; | ||||||
| use crate::widgets::{List, Section, Widget}; | use crate::widgets::{List, Section, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -81,7 +81,7 @@ impl Screen<Person, ()> for PersonScreen { | ||||||
|             .set_make_widget_cb(clone!(@weak this =>  @default-panic, move |index| { |             .set_make_widget_cb(clone!(@weak this =>  @default-panic, move |index| { | ||||||
|                 let work = &this.works.borrow()[index]; |                 let work = &this.works.borrow()[index]; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&work.title) |                     .title(&work.title) | ||||||
|                     .build(); |                     .build(); | ||||||
|  | @ -109,10 +109,10 @@ impl Screen<Person, ()> for PersonScreen { | ||||||
|             clone!(@weak this =>  @default-panic, move |index| { |             clone!(@weak this =>  @default-panic, move |index| { | ||||||
|                 let recording = &this.recordings.borrow()[index]; |                 let recording = &this.recordings.borrow()[index]; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&recording.work.get_title()) |                     .title(recording.work.get_title()) | ||||||
|                     .subtitle(&recording.get_performers()) |                     .subtitle(recording.get_performers()) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 let recording = recording.to_owned(); |                 let recording = recording.to_owned(); | ||||||
|  | @ -139,7 +139,7 @@ impl Screen<Person, ()> for PersonScreen { | ||||||
|             .set_make_widget_cb(clone!(@weak this => @default-panic,  move |index| { |             .set_make_widget_cb(clone!(@weak this => @default-panic,  move |index| { | ||||||
|                 let medium = &this.mediums.borrow()[index]; |                 let medium = &this.mediums.borrow()[index]; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&medium.name) |                     .title(&medium.name) | ||||||
|                     .build(); |                     .build(); | ||||||
|  |  | ||||||
|  | @ -65,7 +65,7 @@ impl Screen<(), ()> for PlayerScreen { | ||||||
|         content.append(&list.widget); |         content.append(&list.widget); | ||||||
| 
 | 
 | ||||||
|         let event_controller = gtk::EventControllerLegacy::new(); |         let event_controller = gtk::EventControllerLegacy::new(); | ||||||
|         position_scale.add_controller(&event_controller); |         position_scale.add_controller(event_controller.clone()); | ||||||
| 
 | 
 | ||||||
|         let this = Rc::new(Self { |         let this = Rc::new(Self { | ||||||
|             handle, |             handle, | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ use crate::editors::RecordingEditor; | ||||||
| use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | ||||||
| use crate::widgets; | use crate::widgets; | ||||||
| use crate::widgets::{List, Section, Widget}; | use crate::widgets::{List, Section, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -85,8 +85,8 @@ impl Screen<Recording, ()> for RecordingScreen { | ||||||
|                     title_parts.join(", ") |                     title_parts.join(", ") | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .title(&title) |                     .title(title) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 row.upcast() |                 row.upcast() | ||||||
|  |  | ||||||
|  | @ -1,9 +1,7 @@ | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::{HeaderBarBuilder, StatusPageBuilder}; |  | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::builders::{BoxBuilder, ButtonBuilder}; |  | ||||||
| use gtk::prelude::*; | use gtk::prelude::*; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
|  | @ -17,23 +15,23 @@ pub struct WelcomeScreen { | ||||||
| 
 | 
 | ||||||
| impl Screen<(), ()> for WelcomeScreen { | impl Screen<(), ()> for WelcomeScreen { | ||||||
|     fn new(_: (), handle: NavigationHandle<()>) -> Rc<Self> { |     fn new(_: (), handle: NavigationHandle<()>) -> Rc<Self> { | ||||||
|         let widget = BoxBuilder::new() |         let widget = gtk::Box::builder() | ||||||
|             .orientation(gtk::Orientation::Vertical) |             .orientation(gtk::Orientation::Vertical) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let header = HeaderBarBuilder::new() |         let header = gtk::HeaderBar::builder() | ||||||
|             .title_widget(&adw::WindowTitle::new("Musicus", "")) |             .title_widget(&adw::WindowTitle::new("Musicus", "")) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let button = ButtonBuilder::new() |         let button = gtk::Button::builder() | ||||||
|             .halign(gtk::Align::Center) |             .halign(gtk::Align::Center) | ||||||
|             .label(&gettext("Select folder")) |             .label(gettext("Select folder")) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let welcome = StatusPageBuilder::new() |         let welcome = adw::StatusPage::builder() | ||||||
|             .icon_name("folder-music-symbolic") |             .icon_name("folder-music-symbolic") | ||||||
|             .title(&gettext("Welcome to Musicus!")) |             .title(gettext("Welcome to Musicus!")) | ||||||
|             .description(&gettext( |             .description(gettext( | ||||||
|                 "Get startet by selecting the folder containing your music \ |                 "Get startet by selecting the folder containing your music \ | ||||||
|                 files! Musicus will create a new database there or open one that already exists.",
 |                 files! Musicus will create a new database there or open one that already exists.",
 | ||||||
|             )) |             )) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ use crate::editors::WorkEditor; | ||||||
| use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | use crate::navigator::{NavigationHandle, NavigatorWindow, Screen}; | ||||||
| use crate::widgets; | use crate::widgets; | ||||||
| use crate::widgets::{List, Section, Widget}; | use crate::widgets::{List, Section, Widget}; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -70,10 +70,10 @@ impl Screen<Work, ()> for WorkScreen { | ||||||
|             clone!(@weak this =>  @default-panic, move |index| { |             clone!(@weak this =>  @default-panic, move |index| { | ||||||
|                 let recording = &this.recordings.borrow()[index]; |                 let recording = &this.recordings.borrow()[index]; | ||||||
| 
 | 
 | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&recording.work.get_title()) |                     .title(recording.work.get_title()) | ||||||
|                     .subtitle(&recording.get_performers()) |                     .subtitle(recording.get_performers()) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 let recording = recording.to_owned(); |                 let recording = recording.to_owned(); | ||||||
|  |  | ||||||
|  | @ -2,12 +2,12 @@ use super::selector::Selector; | ||||||
| use crate::editors::EnsembleEditor; | use crate::editors::EnsembleEditor; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use log::warn; | use log::warn; | ||||||
| use musicus_backend::db::{Ensemble, self}; | use musicus_backend::db::{self, Ensemble}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
| /// A screen for selecting a ensemble.
 | /// A screen for selecting a ensemble.
 | ||||||
|  | @ -42,7 +42,7 @@ impl Screen<(), Ensemble> for EnsembleSelector { | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector | ||||||
|             .set_make_widget(clone!(@weak this => @default-panic,  move |ensemble| { |             .set_make_widget(clone!(@weak this => @default-panic,  move |ensemble| { | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&ensemble.name) |                     .title(&ensemble.name) | ||||||
|                     .build(); |                     .build(); | ||||||
|  | @ -63,8 +63,9 @@ impl Screen<(), Ensemble> for EnsembleSelector { | ||||||
|         this.selector |         this.selector | ||||||
|             .set_filter(|search, ensemble| ensemble.name.to_lowercase().contains(search)); |             .set_filter(|search, ensemble| ensemble.name.to_lowercase().contains(search)); | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector.set_items( | ||||||
|             .set_items(db::get_recent_ensembles(&mut this.handle.backend.db().lock().unwrap(), ).unwrap()); |             db::get_recent_ensembles(&mut this.handle.backend.db().lock().unwrap()).unwrap(), | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         this |         this | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -2,12 +2,12 @@ use super::selector::Selector; | ||||||
| use crate::editors::InstrumentEditor; | use crate::editors::InstrumentEditor; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use log::warn; | use log::warn; | ||||||
| use musicus_backend::db::{Instrument, self}; | use musicus_backend::db::{self, Instrument}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
| /// A screen for selecting a instrument.
 | /// A screen for selecting a instrument.
 | ||||||
|  | @ -42,7 +42,7 @@ impl Screen<(), Instrument> for InstrumentSelector { | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector | ||||||
|             .set_make_widget(clone!(@weak this =>  @default-panic, move |instrument| { |             .set_make_widget(clone!(@weak this =>  @default-panic, move |instrument| { | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&instrument.name) |                     .title(&instrument.name) | ||||||
|                     .build(); |                     .build(); | ||||||
|  | @ -63,8 +63,9 @@ impl Screen<(), Instrument> for InstrumentSelector { | ||||||
|         this.selector |         this.selector | ||||||
|             .set_filter(|search, instrument| instrument.name.to_lowercase().contains(search)); |             .set_filter(|search, instrument| instrument.name.to_lowercase().contains(search)); | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector.set_items( | ||||||
|             .set_items(db::get_recent_instruments(&mut this.handle.backend.db().lock().unwrap(), ).unwrap()); |             db::get_recent_instruments(&mut this.handle.backend.db().lock().unwrap()).unwrap(), | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         this |         this | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| use super::selector::Selector; | use super::selector::Selector; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -31,9 +31,9 @@ impl Screen<(), Medium> for MediumSelector { | ||||||
|         })); |         })); | ||||||
| 
 | 
 | ||||||
|         this.selector.set_make_widget(clone!(@weak this =>  @default-panic, move |poe| { |         this.selector.set_make_widget(clone!(@weak this =>  @default-panic, move |poe| { | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .activatable(true) |                 .activatable(true) | ||||||
|                 .title(&poe.get_title()) |                 .title(poe.get_title()) | ||||||
|                 .build(); |                 .build(); | ||||||
| 
 | 
 | ||||||
|             let poe = poe.to_owned(); |             let poe = poe.to_owned(); | ||||||
|  | @ -106,7 +106,7 @@ impl Screen<PersonOrEnsemble, Medium> for MediumSelectorMediumScreen { | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector | ||||||
|             .set_make_widget(clone!(@weak this =>  @default-panic, move |medium| { |             .set_make_widget(clone!(@weak this =>  @default-panic, move |medium| { | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&medium.name) |                     .title(&medium.name) | ||||||
|                     .build(); |                     .build(); | ||||||
|  |  | ||||||
|  | @ -2,12 +2,12 @@ use super::selector::Selector; | ||||||
| use crate::editors::PersonEditor; | use crate::editors::PersonEditor; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use log::warn; | use log::warn; | ||||||
| use musicus_backend::db::{Person, self}; | use musicus_backend::db::{self, Person}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
| /// A screen for selecting a person.
 | /// A screen for selecting a person.
 | ||||||
|  | @ -42,9 +42,9 @@ impl Screen<(), Person> for PersonSelector { | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector | ||||||
|             .set_make_widget(clone!(@weak this =>  @default-panic, move |person| { |             .set_make_widget(clone!(@weak this =>  @default-panic, move |person| { | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&person.name_lf()) |                     .title(person.name_lf()) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 let person = person.to_owned(); |                 let person = person.to_owned(); | ||||||
|  | @ -63,8 +63,9 @@ impl Screen<(), Person> for PersonSelector { | ||||||
|         this.selector |         this.selector | ||||||
|             .set_filter(|search, person| person.name_fl().to_lowercase().contains(search)); |             .set_filter(|search, person| person.name_fl().to_lowercase().contains(search)); | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector.set_items( | ||||||
|             .set_items(db::get_recent_persons(&mut this.handle.backend.db().lock().unwrap(), ).unwrap()); |             db::get_recent_persons(&mut this.handle.backend.db().lock().unwrap()).unwrap(), | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         this |         this | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ use super::selector::Selector; | ||||||
| use crate::editors::{PersonEditor, RecordingEditor, WorkEditor}; | use crate::editors::{PersonEditor, RecordingEditor, WorkEditor}; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
|  | @ -53,9 +53,9 @@ impl Screen<(), Recording> for RecordingSelector { | ||||||
|         })); |         })); | ||||||
| 
 | 
 | ||||||
|         this.selector.set_make_widget(clone!(@weak this =>  @default-panic, move |person| { |         this.selector.set_make_widget(clone!(@weak this =>  @default-panic, move |person| { | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .activatable(true) |                 .activatable(true) | ||||||
|                 .title(&person.name_lf()) |                 .title(person.name_lf()) | ||||||
|                 .build(); |                 .build(); | ||||||
| 
 | 
 | ||||||
|             let person = person.to_owned(); |             let person = person.to_owned(); | ||||||
|  | @ -129,7 +129,7 @@ impl Screen<Person, Work> for RecordingSelectorWorkScreen { | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector | ||||||
|             .set_make_widget(clone!(@weak this =>  @default-panic, move |work| { |             .set_make_widget(clone!(@weak this =>  @default-panic, move |work| { | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&work.title) |                     .title(&work.title) | ||||||
|                     .build(); |                     .build(); | ||||||
|  | @ -197,9 +197,9 @@ impl Screen<Work, Recording> for RecordingSelectorRecordingScreen { | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector | ||||||
|             .set_make_widget(clone!(@weak this =>  @default-panic, move |recording| { |             .set_make_widget(clone!(@weak this =>  @default-panic, move |recording| { | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&recording.get_performers()) |                     .title(recording.get_performers()) | ||||||
|                     .build(); |                     .build(); | ||||||
| 
 | 
 | ||||||
|                 let recording = recording.to_owned(); |                 let recording = recording.to_owned(); | ||||||
|  |  | ||||||
|  | @ -2,12 +2,12 @@ use super::selector::Selector; | ||||||
| use crate::editors::{PersonEditor, WorkEditor}; | use crate::editors::{PersonEditor, WorkEditor}; | ||||||
| use crate::navigator::{NavigationHandle, Screen}; | use crate::navigator::{NavigationHandle, Screen}; | ||||||
| use crate::widgets::Widget; | use crate::widgets::Widget; | ||||||
| use adw::builders::ActionRowBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use gettextrs::gettext; | use gettextrs::gettext; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use log::warn; | use log::warn; | ||||||
| use musicus_backend::db::{Person, Work, self}; | use musicus_backend::db::{self, Person, Work}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
| /// A screen for selecting a work.
 | /// A screen for selecting a work.
 | ||||||
|  | @ -47,9 +47,9 @@ impl Screen<(), Work> for WorkSelector { | ||||||
|         })); |         })); | ||||||
| 
 | 
 | ||||||
|         this.selector.set_make_widget(clone!(@weak this =>  @default-panic, move |person| { |         this.selector.set_make_widget(clone!(@weak this =>  @default-panic, move |person| { | ||||||
|             let row = ActionRowBuilder::new() |             let row = adw::ActionRow::builder() | ||||||
|                 .activatable(true) |                 .activatable(true) | ||||||
|                 .title(&person.name_lf()) |                 .title(person.name_lf()) | ||||||
|                 .build(); |                 .build(); | ||||||
| 
 | 
 | ||||||
|             let person = person.to_owned(); |             let person = person.to_owned(); | ||||||
|  | @ -71,8 +71,9 @@ impl Screen<(), Work> for WorkSelector { | ||||||
|         this.selector |         this.selector | ||||||
|             .set_filter(|search, person| person.name_fl().to_lowercase().contains(search)); |             .set_filter(|search, person| person.name_fl().to_lowercase().contains(search)); | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector.set_items( | ||||||
|             .set_items(db::get_recent_persons(&mut this.handle.backend.db().lock().unwrap()).unwrap()); |             db::get_recent_persons(&mut this.handle.backend.db().lock().unwrap()).unwrap(), | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         this |         this | ||||||
|     } |     } | ||||||
|  | @ -118,7 +119,7 @@ impl Screen<Person, Work> for WorkSelectorWorkScreen { | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector | ||||||
|             .set_make_widget(clone!(@weak this =>  @default-panic, move |work| { |             .set_make_widget(clone!(@weak this =>  @default-panic, move |work| { | ||||||
|                 let row = ActionRowBuilder::new() |                 let row = adw::ActionRow::builder() | ||||||
|                     .activatable(true) |                     .activatable(true) | ||||||
|                     .title(&work.title) |                     .title(&work.title) | ||||||
|                     .build(); |                     .build(); | ||||||
|  | @ -138,8 +139,13 @@ impl Screen<Person, Work> for WorkSelectorWorkScreen { | ||||||
|         this.selector |         this.selector | ||||||
|             .set_filter(|search, work| work.title.to_lowercase().contains(search)); |             .set_filter(|search, work| work.title.to_lowercase().contains(search)); | ||||||
| 
 | 
 | ||||||
|         this.selector |         this.selector.set_items( | ||||||
|             .set_items(db::get_works(&mut this.handle.backend.db().lock().unwrap(), &this.person.id).unwrap()); |             db::get_works( | ||||||
|  |                 &mut this.handle.backend.db().lock().unwrap(), | ||||||
|  |                 &this.person.id, | ||||||
|  |             ) | ||||||
|  |             .unwrap(), | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         this |         this | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| use super::Widget; | use super::Widget; | ||||||
| use adw::{builders::ActionRowBuilder, prelude::*}; | use adw::prelude::*; | ||||||
| use gtk::builders::ButtonBuilder; |  | ||||||
| 
 | 
 | ||||||
| /// A list box row with a single button.
 | /// A list box row with a single button.
 | ||||||
| pub struct ButtonRow { | pub struct ButtonRow { | ||||||
|  | @ -14,12 +13,12 @@ pub struct ButtonRow { | ||||||
| impl ButtonRow { | impl ButtonRow { | ||||||
|     /// Create a new button row.
 |     /// Create a new button row.
 | ||||||
|     pub fn new(title: &str, label: &str) -> Self { |     pub fn new(title: &str, label: &str) -> Self { | ||||||
|         let button = ButtonBuilder::new() |         let button = gtk::Button::builder() | ||||||
|             .valign(gtk::Align::Center) |             .valign(gtk::Align::Center) | ||||||
|             .label(label) |             .label(label) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let widget = ActionRowBuilder::new() |         let widget = adw::ActionRow::builder() | ||||||
|             .focusable(false) |             .focusable(false) | ||||||
|             .activatable_widget(&button) |             .activatable_widget(&button) | ||||||
|             .title(title) |             .title(title) | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| use gio::prelude::*; | use gio::prelude::*; | ||||||
| use gio::subclass::prelude::*; | use gio::subclass::prelude::*; | ||||||
| use once_cell::sync::Lazy; | 
 | ||||||
| use std::cell::Cell; | use std::cell::Cell; | ||||||
| 
 | 
 | ||||||
| glib::wrapper! { | glib::wrapper! { | ||||||
|  | @ -12,24 +12,28 @@ glib::wrapper! { | ||||||
| impl IndexedListModel { | impl IndexedListModel { | ||||||
|     /// Set the length of the list model.
 |     /// Set the length of the list model.
 | ||||||
|     pub fn set_length(&self, length: u32) { |     pub fn set_length(&self, length: u32) { | ||||||
|         let old_length = self.property("length"); |         let old_length = self.n_items(); | ||||||
|         self.set_property("length", &length); |         self.set_n_items(length); | ||||||
|         self.items_changed(0, old_length, length); |         self.items_changed(0, old_length, length); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Default for IndexedListModel { | impl Default for IndexedListModel { | ||||||
|     fn default() -> Self { |     fn default() -> Self { | ||||||
|         glib::Object::new(&[]) |         glib::Object::new() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| mod indexed_list_model_imp { | mod indexed_list_model_imp { | ||||||
|  |     use glib::Properties; | ||||||
|  | 
 | ||||||
|     use super::*; |     use super::*; | ||||||
| 
 | 
 | ||||||
|     #[derive(Debug, Default)] |     #[derive(Properties, Default)] | ||||||
|  |     #[properties(wrapper_type = super::IndexedListModel)] | ||||||
|     pub struct IndexedListModel { |     pub struct IndexedListModel { | ||||||
|         length: Cell<u32>, |         #[property(get, set)] | ||||||
|  |         n_items: Cell<u32>, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[glib::object_subclass] |     #[glib::object_subclass] | ||||||
|  | @ -42,36 +46,15 @@ mod indexed_list_model_imp { | ||||||
| 
 | 
 | ||||||
|     impl ObjectImpl for IndexedListModel { |     impl ObjectImpl for IndexedListModel { | ||||||
|         fn properties() -> &'static [glib::ParamSpec] { |         fn properties() -> &'static [glib::ParamSpec] { | ||||||
|             static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { |             Self::derived_properties() | ||||||
|                 vec![glib::ParamSpecUInt::new( |  | ||||||
|                     "length", |  | ||||||
|                     "Length", |  | ||||||
|                     "Length", |  | ||||||
|                     0, |  | ||||||
|                     std::u32::MAX, |  | ||||||
|                     0, |  | ||||||
|                     glib::ParamFlags::READWRITE, |  | ||||||
|                 )] |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             PROPERTIES.as_ref() |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fn set_property(&self, _: usize, value: &glib::Value, pspec: &glib::ParamSpec) { |         fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { | ||||||
|             match pspec.name() { |             self.derived_set_property(id, value, pspec) | ||||||
|                 "length" => { |  | ||||||
|                     let length = value.get::<u32>().unwrap(); |  | ||||||
|                     self.length.set(length); |  | ||||||
|                 } |  | ||||||
|                 _ => unimplemented!(), |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { |         fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value { | ||||||
|             match pspec.name() { |             self.derived_property(id, pspec) | ||||||
|                 "length" => self.length.get().to_value(), |  | ||||||
|                 _ => unimplemented!(), |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -81,7 +64,7 @@ mod indexed_list_model_imp { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fn n_items(&self) -> u32 { |         fn n_items(&self) -> u32 { | ||||||
|             self.length.get() |             self.n_items.get() | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fn item(&self, position: u32) -> Option<glib::Object> { |         fn item(&self, position: u32) -> Option<glib::Object> { | ||||||
|  | @ -98,7 +81,9 @@ glib::wrapper! { | ||||||
| impl ItemIndex { | impl ItemIndex { | ||||||
|     /// Create a new item index.
 |     /// Create a new item index.
 | ||||||
|     pub fn new(value: u32) -> Self { |     pub fn new(value: u32) -> Self { | ||||||
|         glib::Object::new(&[("value", &value)]) |         let object = glib::Object::new::<Self>(); | ||||||
|  |         object.set_value(value); | ||||||
|  |         object | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Get the value of the item index..
 |     /// Get the value of the item index..
 | ||||||
|  | @ -108,10 +93,14 @@ impl ItemIndex { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| mod item_index_imp { | mod item_index_imp { | ||||||
|  |     use glib::Properties; | ||||||
|  | 
 | ||||||
|     use super::*; |     use super::*; | ||||||
| 
 | 
 | ||||||
|     #[derive(Debug, Default)] |     #[derive(Properties, Default)] | ||||||
|  |     #[properties(wrapper_type = super::ItemIndex)] | ||||||
|     pub struct ItemIndex { |     pub struct ItemIndex { | ||||||
|  |         #[property(get, set)] | ||||||
|         value: Cell<u32>, |         value: Cell<u32>, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -125,36 +114,15 @@ mod item_index_imp { | ||||||
| 
 | 
 | ||||||
|     impl ObjectImpl for ItemIndex { |     impl ObjectImpl for ItemIndex { | ||||||
|         fn properties() -> &'static [glib::ParamSpec] { |         fn properties() -> &'static [glib::ParamSpec] { | ||||||
|             static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { |             Self::derived_properties() | ||||||
|                 vec![glib::ParamSpecUInt::new( |  | ||||||
|                     "value", |  | ||||||
|                     "Value", |  | ||||||
|                     "Value", |  | ||||||
|                     0, |  | ||||||
|                     std::u32::MAX, |  | ||||||
|                     0, |  | ||||||
|                     glib::ParamFlags::READWRITE, |  | ||||||
|                 )] |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             PROPERTIES.as_ref() |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fn set_property(&self, _: usize, value: &glib::Value, pspec: &glib::ParamSpec) { |         fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { | ||||||
|             match pspec.name() { |             self.derived_set_property(id, value, pspec) | ||||||
|                 "value" => { |  | ||||||
|                     let value = value.get::<u32>().unwrap(); |  | ||||||
|                     self.value.set(value); |  | ||||||
|                 } |  | ||||||
|                 _ => unimplemented!(), |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { |         fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value { | ||||||
|             match pspec.name() { |             self.derived_property(id, pspec) | ||||||
|                 "value" => self.value.get().to_value(), |  | ||||||
|                 _ => unimplemented!(), |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| use super::indexed_list_model::{IndexedListModel, ItemIndex}; | use super::indexed_list_model::{IndexedListModel, ItemIndex}; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::{builders::ListBoxBuilder, gdk, prelude::*}; | use gtk::{gdk, prelude::*}; | ||||||
| use std::cell::{Cell, RefCell}; | use std::cell::{Cell, RefCell}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
|  | @ -20,14 +20,14 @@ impl List { | ||||||
|     pub fn new() -> Rc<Self> { |     pub fn new() -> Rc<Self> { | ||||||
|         let model = IndexedListModel::default(); |         let model = IndexedListModel::default(); | ||||||
|         let filter = gtk::CustomFilter::new(|_| true); |         let filter = gtk::CustomFilter::new(|_| true); | ||||||
|         let filter_model = gtk::FilterListModel::new(Some(&model), Some(&filter)); |         let filter_model = gtk::FilterListModel::new(Some(model.clone()), Some(filter.clone())); | ||||||
| 
 | 
 | ||||||
|         // TODO: Switch to gtk::ListView.
 |         // TODO: Switch to gtk::ListView.
 | ||||||
|         // let selection = gtk::NoSelection::new(Some(&model));
 |         // let selection = gtk::NoSelection::new(Some(&model));
 | ||||||
|         // let factory = gtk::SignalListItemFactory::new();
 |         // let factory = gtk::SignalListItemFactory::new();
 | ||||||
|         // let widget = gtk::ListView::new(Some(&selection), Some(&factory));
 |         // let widget = gtk::ListView::new(Some(&selection), Some(&factory));
 | ||||||
| 
 | 
 | ||||||
|         let widget = ListBoxBuilder::new() |         let widget = gtk::ListBox::builder() | ||||||
|             .selection_mode(gtk::SelectionMode::None) |             .selection_mode(gtk::SelectionMode::None) | ||||||
|             .css_classes(vec![String::from("boxed-list")]) |             .css_classes(vec![String::from("boxed-list")]) | ||||||
|             .build(); |             .build(); | ||||||
|  | @ -45,7 +45,7 @@ impl List { | ||||||
|         this.filter |         this.filter | ||||||
|             .set_filter_func(clone!(@strong this => move |index| { |             .set_filter_func(clone!(@strong this => move |index| { | ||||||
|                 if let Some(cb) = &*this.filter_cb.borrow() { |                 if let Some(cb) = &*this.filter_cb.borrow() { | ||||||
|                     let index = index.downcast_ref::<ItemIndex>().unwrap().get() as usize; |                     let index = index.downcast_ref::<ItemIndex>().unwrap().value() as usize; | ||||||
|                     cb(index) |                     cb(index) | ||||||
|                 } else { |                 } else { | ||||||
|                     true |                     true | ||||||
|  | @ -81,8 +81,8 @@ impl List { | ||||||
|                         } |                         } | ||||||
|                     })); |                     })); | ||||||
| 
 | 
 | ||||||
|                     widget.add_controller(&drag_source); |                     widget.add_controller(drag_source); | ||||||
|                     widget.add_controller(&drop_target); |                     widget.add_controller(drop_target); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 widget |                 widget | ||||||
|  | @ -109,6 +109,7 @@ impl List { | ||||||
|     /// false, the item will not be shown.
 |     /// false, the item will not be shown.
 | ||||||
|     pub fn set_filter_cb<F: Fn(usize) -> bool + 'static>(&self, cb: F) { |     pub fn set_filter_cb<F: Fn(usize) -> bool + 'static>(&self, cb: F) { | ||||||
|         self.filter_cb.replace(Some(Box::new(cb))); |         self.filter_cb.replace(Some(Box::new(cb))); | ||||||
|  |         self.invalidate_filter(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Set the closure to be called to when the use has dragged an item to a
 |     /// Set the closure to be called to when the use has dragged an item to a
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| use super::Widget; | use super::Widget; | ||||||
| use gtk::{builders::ButtonBuilder, prelude::*}; | use gtk::prelude::*; | ||||||
| use gtk_macros::get_widget; | use gtk_macros::get_widget; | ||||||
| 
 | 
 | ||||||
| /// A widget displaying a title, a framed child widget and, if needed, some
 | /// A widget displaying a title, a framed child widget and, if needed, some
 | ||||||
|  | @ -46,7 +46,7 @@ impl Section { | ||||||
|     /// situations where the widget is visible. The new button will be packed
 |     /// situations where the widget is visible. The new button will be packed
 | ||||||
|     /// to the end of the title box.
 |     /// to the end of the title box.
 | ||||||
|     pub fn add_action<F: Fn() + 'static>(&self, icon_name: &str, cb: F) { |     pub fn add_action<F: Fn() + 'static>(&self, icon_name: &str, cb: F) { | ||||||
|         let button = ButtonBuilder::new() |         let button = gtk::Button::builder() | ||||||
|             .has_frame(false) |             .has_frame(false) | ||||||
|             .valign(gtk::Align::Center) |             .valign(gtk::Align::Center) | ||||||
|             .margin_top(12) |             .margin_top(12) | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| use crate::navigator::Navigator; | use crate::navigator::Navigator; | ||||||
| use crate::screens::{MainScreen, WelcomeScreen}; | use crate::screens::{MainScreen, WelcomeScreen}; | ||||||
| use adw::builders::HeaderBarBuilder; | 
 | ||||||
| use adw::prelude::*; | use adw::prelude::*; | ||||||
| use glib::clone; | use glib::clone; | ||||||
| use gtk::builders::{BoxBuilder, SpinnerBuilder}; | 
 | ||||||
| use musicus_backend::{Backend, BackendState}; | use musicus_backend::{Backend, BackendState}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
| 
 | 
 | ||||||
|  | @ -23,15 +23,15 @@ impl Window { | ||||||
|         window.set_title(Some("Musicus")); |         window.set_title(Some("Musicus")); | ||||||
|         window.set_default_size(1000, 707); |         window.set_default_size(1000, 707); | ||||||
| 
 | 
 | ||||||
|         let loading_screen = BoxBuilder::new() |         let loading_screen = gtk::Box::builder() | ||||||
|             .orientation(gtk::Orientation::Vertical) |             .orientation(gtk::Orientation::Vertical) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let header = HeaderBarBuilder::new() |         let header = gtk::HeaderBar::builder() | ||||||
|             .title_widget(&adw::WindowTitle::new("Musicus", "")) |             .title_widget(&adw::WindowTitle::new("Musicus", "")) | ||||||
|             .build(); |             .build(); | ||||||
| 
 | 
 | ||||||
|         let spinner = SpinnerBuilder::new() |         let spinner = gtk::Spinner::builder() | ||||||
|             .hexpand(true) |             .hexpand(true) | ||||||
|             .vexpand(true) |             .vexpand(true) | ||||||
|             .halign(gtk::Align::Center) |             .halign(gtk::Align::Center) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue