Update gtk and libadwaita

This commit is contained in:
Elias Projahn 2021-10-10 10:24:18 +02:00
parent 7c9c01d3ea
commit ae2f01afda
34 changed files with 260 additions and 120 deletions

71
Cargo.lock generated
View file

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3
[[package]] [[package]]
name = "aes" name = "aes"
version = "0.6.0" version = "0.6.0"
@ -194,6 +196,15 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "cfg-expr"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571"
dependencies = [
"smallvec",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
@ -565,9 +576,9 @@ dependencies = [
[[package]] [[package]]
name = "gdk4" name = "gdk4"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03132f21de5fe15ded4f950328fb44e007037aea7c6bbbc3f082493d5d3c164" checksum = "4c0f7f98ad25b81ac9462f74a091b0e4c0983ed1e74d19a38230c772b4dcef81"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
@ -581,9 +592,9 @@ dependencies = [
[[package]] [[package]]
name = "gdk4-sys" name = "gdk4-sys"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3453f8dc11a6167a7269355fcfbd6b96d10625395e87f77199e7dbba9077b58c" checksum = "262a79666b42e1884577f11a050439a964b95dec55343ac6ace7930e1415fa18"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
@ -593,7 +604,7 @@ dependencies = [
"graphene-sys", "graphene-sys",
"libc", "libc",
"pango-sys", "pango-sys",
"system-deps 3.1.1", "system-deps 4.0.0",
] ]
[[package]] [[package]]
@ -813,9 +824,9 @@ dependencies = [
[[package]] [[package]]
name = "gsk4" name = "gsk4"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2699e9ff7ba3ca3582043bfd45ea3af3c45fa461fea75a369bcc6ab77eacde2" checksum = "20b71f2e2cc699c2e0fbfa22899eeaffd84f9c1dc01e9263deac8664eec22dc0"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
@ -829,9 +840,9 @@ dependencies = [
[[package]] [[package]]
name = "gsk4-sys" name = "gsk4-sys"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27cf692f33ec2f438a89cb57018f57260b73193929da9d37b873e47a7662a7e0" checksum = "30468aff80e4faadf22f9ba164ea17511a69a9995d7a13827a13424ef47b2472"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk4-sys", "gdk4-sys",
@ -840,7 +851,7 @@ dependencies = [
"graphene-sys", "graphene-sys",
"libc", "libc",
"pango-sys", "pango-sys",
"system-deps 3.1.1", "system-deps 4.0.0",
] ]
[[package]] [[package]]
@ -1016,9 +1027,9 @@ checksum = "da5bf7748fd4cd0b2490df8debcc911809dbcbee4ece9531b96c29a9c729de5a"
[[package]] [[package]]
name = "gtk4" name = "gtk4"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8801459abe49508a914c591d0cf355a6aea9762058334ba6efe63bdf40e479" checksum = "906f9308d15789d96a736881582181d710ae0937197119df459f3d2b46ef6776"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
@ -1039,9 +1050,9 @@ dependencies = [
[[package]] [[package]]
name = "gtk4-macros" name = "gtk4-macros"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca4260cbbdad77f91c57b4836ff63c6c51dc79b2feadc83c0869e4d379dcbee5" checksum = "4d0d008cdf23214c697482415dd20f666bdf3cc9f5e803b017223c17c5b59a6e"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -1055,9 +1066,9 @@ dependencies = [
[[package]] [[package]]
name = "gtk4-sys" name = "gtk4-sys"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "580a7215a4d681e068cb1ea93e7293ca0d84b738d9b0c82b630199f21d3c82ef" checksum = "d06be0a6322aa77dd372f726e97efbcbb192d9a824a414a8874f238effd7747c"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
@ -1069,7 +1080,7 @@ dependencies = [
"gsk4-sys", "gsk4-sys",
"libc", "libc",
"pango-sys", "pango-sys",
"system-deps 3.1.1", "system-deps 4.0.0",
] ]
[[package]] [[package]]
@ -1190,9 +1201,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libadwaita" name = "libadwaita"
version = "0.1.0-alpha" version = "0.1.0-alpha-6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52d8221b476b16ee55b18bf4209e0fb5457c66375b9af8f8cef91ff930e82da6" checksum = "d8d01ba5036df1c3e09be88b4b8e0906af977bb7ec28d5faec81a1de94bc775c"
dependencies = [ dependencies = [
"gdk-pixbuf", "gdk-pixbuf",
"gdk4", "gdk4",
@ -1201,14 +1212,15 @@ dependencies = [
"gtk4", "gtk4",
"libadwaita-sys", "libadwaita-sys",
"libc", "libc",
"once_cell",
"pango", "pango",
] ]
[[package]] [[package]]
name = "libadwaita-sys" name = "libadwaita-sys"
version = "0.1.0-alpha" version = "0.1.0-alpha-6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80594e5894e4145639c75164ee33cf607f42c667318475cb1d5db8132b77eab4" checksum = "3127d83c55f64c466925b9d1e27a964187f193e94c7c8820ad6b29d6e5f487d8"
dependencies = [ dependencies = [
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
"gdk4-sys", "gdk4-sys",
@ -1218,7 +1230,7 @@ dependencies = [
"gtk4-sys", "gtk4-sys",
"libc", "libc",
"pango-sys", "pango-sys",
"system-deps 3.1.1", "system-deps 4.0.0",
] ]
[[package]] [[package]]
@ -2151,7 +2163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c248107ad7bc1ac07066a4d003cae9e9a7bc2e27d3418f7a9cdcdc8699dbea70" checksum = "c248107ad7bc1ac07066a4d003cae9e9a7bc2e27d3418f7a9cdcdc8699dbea70"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cfg-expr", "cfg-expr 0.7.4",
"heck", "heck",
"itertools 0.10.1", "itertools 0.10.1",
"pkg-config", "pkg-config",
@ -2162,6 +2174,19 @@ dependencies = [
"version-compare 0.0.11", "version-compare 0.0.11",
] ]
[[package]]
name = "system-deps"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c1889ab44c2a423ba9ba4d64cd04989b25c0280ca7ade813f05368418722a04"
dependencies = [
"cfg-expr 0.9.0",
"heck",
"pkg-config",
"toml",
"version-compare 0.0.11",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.25" version = "1.0.25"

View file

@ -5,15 +5,15 @@ edition = "2018"
[dependencies] [dependencies]
anyhow = "1.0.33" anyhow = "1.0.33"
adw = { package = "libadwaita", version = "0.1.0-alpha" } adw = { package = "libadwaita", version = "0.1.0-alpha-6" }
async-trait = "0.1.42" async-trait = "0.1.42"
futures-channel = "0.3.5" futures-channel = "0.3.5"
gdk = { package = "gdk4", version = "0.1.0" } gdk = { package = "gdk4", version = "0.3.0" }
gettext-rs = { version = "0.5.0", features = ["gettext-system"] } gettext-rs = { version = "0.5.0", features = ["gettext-system"] }
gio = "0.14.0" gio = "0.14.0"
glib = "0.14.0" glib = "0.14.0"
gstreamer = "0.17.0" gstreamer = "0.17.0"
gtk = { package = "gtk4", version = "0.1.0" } gtk = { package = "gtk4", version = "0.3.0" }
gtk-macros = "0.3.0" gtk-macros = "0.3.0"
log = "0.4.14" log = "0.4.14"
musicus_backend = { version = "0.1.0", path = "../backend" } musicus_backend = { version = "0.1.0", path = "../backend" }

View file

@ -4,7 +4,6 @@ use crate::widgets::{ButtonRow, Editor, Section, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
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;
@ -165,30 +164,30 @@ impl PerformanceEditor {
/// Update the UI according to person. /// Update the UI according to person.
fn show_person(&self, person: Option<&Person>) { fn show_person(&self, person: Option<&Person>) {
if let Some(person) = person { if let Some(person) = person {
self.person_row.set_subtitle(Some(&person.name_fl())); self.person_row.set_subtitle(&person.name_fl());
self.editor.set_may_save(true); self.editor.set_may_save(true);
} else { } else {
self.person_row.set_subtitle(None); self.person_row.set_subtitle("");
} }
} }
/// Update the UI according to ensemble. /// Update the UI according to ensemble.
fn show_ensemble(&self, ensemble: Option<&Ensemble>) { fn show_ensemble(&self, ensemble: Option<&Ensemble>) {
if let Some(ensemble) = ensemble { if let Some(ensemble) = ensemble {
self.ensemble_row.set_subtitle(Some(&ensemble.name)); self.ensemble_row.set_subtitle(&ensemble.name);
self.editor.set_may_save(true); self.editor.set_may_save(true);
} else { } else {
self.ensemble_row.set_subtitle(None); self.ensemble_row.set_subtitle("");
} }
} }
/// Update the UI according to role. /// Update the UI according to role.
fn show_role(&self, role: Option<&Instrument>) { fn show_role(&self, role: Option<&Instrument>) {
if let Some(role) = role { if let Some(role) = role {
self.role_row.set_subtitle(Some(&role.name)); self.role_row.set_subtitle(&role.name);
self.reset_role_button.show(); self.reset_role_button.show();
} else { } else {
self.role_row.set_subtitle(None); self.role_row.set_subtitle("");
self.reset_role_button.hide(); self.reset_role_button.hide();
} }
} }

View file

@ -6,7 +6,6 @@ use adw::prelude::*;
use anyhow::Result; use anyhow::Result;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::db::{generate_id, Performance, Recording, Work}; use musicus_backend::db::{generate_id, Performance, Recording, Work};
use std::cell::RefCell; use std::cell::RefCell;
@ -139,7 +138,7 @@ impl Screen<Option<Recording>, Recording> for RecordingEditor {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&performance.get_title())); row.set_title(&performance.get_title());
row.add_suffix(&delete_button); row.add_suffix(&delete_button);
row.add_suffix(&edit_button); row.add_suffix(&edit_button);
row.set_activatable_widget(Some(&edit_button)); row.set_activatable_widget(Some(&edit_button));
@ -177,8 +176,8 @@ impl Screen<Option<Recording>, Recording> for RecordingEditor {
impl RecordingEditor { impl RecordingEditor {
/// Update the UI according to work. /// Update the UI according to work.
fn work_selected(&self, work: &Work) { fn work_selected(&self, work: &Work) {
self.work_row.set_title(Some(&gettext("Work"))); self.work_row.set_title(&gettext("Work"));
self.work_row.set_subtitle(Some(&work.get_title())); self.work_row.set_subtitle(&work.get_title());
self.save_button.set_sensitive(true); self.save_button.set_sensitive(true);
} }

View file

@ -7,7 +7,6 @@ use adw::prelude::*;
use anyhow::Result; use anyhow::Result;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::db::{generate_id, Instrument, Person, Work, WorkPart, WorkSection}; use musicus_backend::db::{generate_id, Instrument, Person, Work, WorkPart, WorkSection};
use std::cell::RefCell; use std::cell::RefCell;
@ -163,7 +162,7 @@ impl Screen<Option<Work>, Work> for WorkEditor {
})); }));
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_title(Some(&instrument.name)); row.set_title(&instrument.name);
row.add_suffix(&delete_button); row.add_suffix(&delete_button);
row.upcast() row.upcast()
@ -235,7 +234,7 @@ impl Screen<Option<Work>, Work> for WorkEditor {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&pos.get_title())); row.set_title(&pos.get_title());
row.add_suffix(&delete_button); row.add_suffix(&delete_button);
row.add_suffix(&edit_button); row.add_suffix(&edit_button);
row.set_activatable_widget(Some(&edit_button)); row.set_activatable_widget(Some(&edit_button));
@ -303,8 +302,8 @@ impl Screen<Option<Work>, Work> for WorkEditor {
impl WorkEditor { impl WorkEditor {
/// Update the UI according to person. /// Update the UI according to person.
fn show_composer(&self, person: &Person) { fn show_composer(&self, person: &Person) {
self.composer_row.set_title(Some(&gettext("Composer"))); self.composer_row.set_title(&gettext("Composer"));
self.composer_row.set_subtitle(Some(&person.name_fl())); self.composer_row.set_subtitle(&person.name_fl());
self.validate(); self.validate();
} }

View file

@ -5,7 +5,6 @@ use crate::selectors::MediumSelector;
use crate::widgets::Widget; use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::db::Medium; use musicus_backend::db::Medium;
use musicus_backend::import::ImportSession; use musicus_backend::import::ImportSession;
@ -47,7 +46,7 @@ impl ImportScreen {
} }
} }
Err(err) => { Err(err) => {
this.error_row.set_subtitle(Some(&err.to_string())); this.error_row.set_subtitle(&err.to_string());
this.matching_stack.set_visible_child_name("error"); this.matching_stack.set_visible_child_name("error");
} }
} }

View file

@ -4,8 +4,6 @@ use crate::widgets::{List, Widget};
use adw::prelude::*; use adw::prelude::*;
use anyhow::Result; use anyhow::Result;
use glib::clone; use glib::clone;
use glib::prelude::*;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::db::{generate_id, Medium, Track}; use musicus_backend::db::{generate_id, Medium, Track};
use musicus_backend::import::ImportSession; use musicus_backend::import::ImportSession;
@ -122,8 +120,8 @@ impl Screen<(Arc<ImportSession>, Option<Medium>), Medium> for MediumEditor {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&title)); row.set_title(&title);
row.set_subtitle(Some(&subtitle)); row.set_subtitle(&subtitle);
row.add_suffix(&edit_button); row.add_suffix(&edit_button);
row.set_activatable_widget(Some(&edit_button)); row.set_activatable_widget(Some(&edit_button));

View file

@ -2,7 +2,6 @@ use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::Widget; use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*;
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;
@ -69,7 +68,7 @@ impl Screen<(Recording, Vec<usize>), Vec<usize>> for TrackEditor {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.add_prefix(&check); row.add_prefix(&check);
row.set_activatable_widget(Some(&check)); row.set_activatable_widget(Some(&check));
row.set_title(Some(&part.title)); row.set_title(&part.title);
parts_list.append(&row); parts_list.append(&row);
} }

View file

@ -2,7 +2,6 @@ use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::Widget; use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*;
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;
@ -80,7 +79,7 @@ impl Screen<Arc<ImportSession>, Vec<usize>> for TrackSelector {
row.add_prefix(&check); row.add_prefix(&check);
row.set_activatable_widget(Some(&check)); row.set_activatable_widget(Some(&check));
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&track.name)); row.set_title(&track.name);
track_list.append(&row); track_list.append(&row);
} }

View file

@ -6,7 +6,6 @@ use crate::widgets::{List, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::db::Recording; use musicus_backend::db::Recording;
use musicus_backend::import::ImportSession; use musicus_backend::import::ImportSession;
@ -147,8 +146,8 @@ impl Screen<Arc<ImportSession>, TrackSetData> for TrackSetEditor {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&title)); row.set_title(&title);
row.set_subtitle(Some(track_name)); row.set_subtitle(track_name);
row.add_suffix(&edit_button); row.add_suffix(&edit_button);
row.set_activatable_widget(Some(&edit_button)); row.set_activatable_widget(Some(&edit_button));
@ -183,10 +182,8 @@ impl TrackSetEditor {
/// Set everything up after selecting a recording. /// Set everything up after selecting a recording.
fn recording_selected(&self) { fn recording_selected(&self) {
if let Some(recording) = &*self.recording.borrow() { if let Some(recording) = &*self.recording.borrow() {
self.recording_row self.recording_row.set_title(&recording.work.get_title());
.set_title(Some(&recording.work.get_title())); self.recording_row.set_subtitle(&recording.get_performers());
self.recording_row
.set_subtitle(Some(&recording.get_performers()));
self.save_button.set_sensitive(true); self.save_button.set_sensitive(true);
} }

View file

@ -1,6 +1,6 @@
use super::Navigator; use super::Navigator;
use adw::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::Backend; use musicus_backend::Backend;
use std::rc::Rc; use std::rc::Rc;
@ -17,7 +17,7 @@ impl NavigatorWindow {
window.set_default_size(600, 424); window.set_default_size(600, 424);
let placeholder = gtk::Label::new(None); let placeholder = gtk::Label::new(None);
let navigator = Navigator::new(backend, &window, &placeholder); let navigator = Navigator::new(backend, &window, &placeholder);
adw::prelude::WindowExt::set_child(&window, Some(&navigator.widget)); window.set_content(Some(&navigator.widget));
let this = Rc::new(Self { navigator, window }); let this = Rc::new(Self { navigator, window });

View file

@ -2,7 +2,6 @@ use crate::navigator::NavigatorWindow;
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::Backend; use musicus_backend::Backend;
use std::rc::Rc; use std::rc::Rc;
@ -66,7 +65,7 @@ impl Preferences {
if let gtk::ResponseType::Accept = response { if let gtk::ResponseType::Accept = response {
if let Some(file) = dialog.file() { if let Some(file) = dialog.file() {
if let Some(path) = file.path() { if let Some(path) = file.path() {
this.music_library_path_row.set_subtitle(Some(path.to_str().unwrap())); this.music_library_path_row.set_subtitle(path.to_str().unwrap());
spawn!(@clone this, async move { spawn!(@clone this, async move {
this.backend.set_music_library_path(path).await.unwrap(); this.backend.set_music_library_path(path).await.unwrap();
@ -85,7 +84,7 @@ impl Preferences {
let dialog = ServerDialog::new(this.backend.clone(), &this.window); let dialog = ServerDialog::new(this.backend.clone(), &this.window);
dialog.set_selected_cb(clone!(@strong this => move |url| { dialog.set_selected_cb(clone!(@strong this => move |url| {
this.url_row.set_subtitle(Some(&url)); this.url_row.set_subtitle(&url);
})); }));
dialog.show(); dialog.show();
@ -98,9 +97,9 @@ impl Preferences {
spawn!(@clone this, async move { spawn!(@clone this, async move {
if let Some(data) = replace!(window.navigator, LoginDialog, this.backend.get_login_data()).await { if let Some(data) = replace!(window.navigator, LoginDialog, this.backend.get_login_data()).await {
if let Some(data) = data { if let Some(data) = data {
this.login_row.set_subtitle(Some(&data.username)); this.login_row.set_subtitle(&data.username);
} else { } else {
this.login_row.set_subtitle(Some(&gettext("Not logged in"))); this.login_row.set_subtitle(&gettext("Not logged in"));
} }
} }
}); });
@ -110,15 +109,15 @@ impl Preferences {
if let Some(path) = this.backend.get_music_library_path() { if let Some(path) = this.backend.get_music_library_path() {
this.music_library_path_row this.music_library_path_row
.set_subtitle(Some(path.to_str().unwrap())); .set_subtitle(path.to_str().unwrap());
} }
if let Some(url) = this.backend.get_server_url() { if let Some(url) = this.backend.get_server_url() {
this.url_row.set_subtitle(Some(&url)); this.url_row.set_subtitle(&url);
} }
if let Some(data) = this.backend.get_login_data() { if let Some(data) = this.backend.get_login_data() {
this.login_row.set_subtitle(Some(&data.username)); this.login_row.set_subtitle(&data.username);
} }
this this

View file

@ -2,7 +2,6 @@ use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::Widget; use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::client::{LoginData, UserRegistration}; use musicus_backend::client::{LoginData, UserRegistration};
use std::cell::RefCell; use std::cell::RefCell;
@ -103,7 +102,7 @@ impl Screen<(), LoginData> for RegisterDialog {
spawn!(@clone this, async move { spawn!(@clone this, async move {
let captcha = this.handle.backend.cl().get_captcha().await.unwrap(); let captcha = this.handle.backend.cl().get_captcha().await.unwrap();
this.captcha_row.set_title(Some(&captcha.question)); this.captcha_row.set_title(&captcha.question);
this.captcha_id.replace(Some(captcha.id)); this.captcha_id.replace(Some(captcha.id));
this.widget.set_visible_child_name("content"); this.widget.set_visible_child_name("content");
}); });

View file

@ -6,7 +6,6 @@ use crate::widgets::{List, Section, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::{Ensemble, Medium, Recording}; use musicus_backend::db::{Ensemble, Medium, Recording};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -77,8 +76,8 @@ impl Screen<Ensemble, ()> for EnsembleScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.work.get_title())); row.set_title(&recording.work.get_title());
row.set_subtitle(Some(&recording.get_performers())); row.set_subtitle(&recording.get_performers());
let recording = recording.to_owned(); let recording = recording.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
@ -106,7 +105,7 @@ impl Screen<Ensemble, ()> for EnsembleScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&medium.name)); row.set_title(&medium.name);
let medium = medium.to_owned(); let medium = medium.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -7,7 +7,6 @@ use crate::widgets::{List, PlayerBar, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::db::PersonOrEnsemble; use musicus_backend::db::PersonOrEnsemble;
use std::cell::RefCell; use std::cell::RefCell;
@ -96,7 +95,7 @@ impl Screen<(), ()> for MainScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&poe.get_title())); row.set_title(&poe.get_title());
let poe = poe.to_owned(); let poe = poe.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -4,7 +4,6 @@ use crate::widgets::{List, Section, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::Medium; use musicus_backend::db::Medium;
use std::rc::Rc; use std::rc::Rc;
@ -80,7 +79,7 @@ impl Screen<Medium, ()> for MediumScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_selectable(false); row.set_selectable(false);
row.set_activatable(false); row.set_activatable(false);
row.set_title(Some(&title)); row.set_title(&title);
row.set_margin_start(12); row.set_margin_start(12);
row.upcast() row.upcast()

View file

@ -6,7 +6,6 @@ use crate::widgets::{List, Section, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::{Medium, Person, Recording, Work}; use musicus_backend::db::{Medium, Person, Recording, Work};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -83,7 +82,7 @@ impl Screen<Person, ()> for PersonScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&work.title)); row.set_title(&work.title);
let work = work.to_owned(); let work = work.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
@ -110,8 +109,8 @@ impl Screen<Person, ()> for PersonScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.work.get_title())); row.set_title(&recording.work.get_title());
row.set_subtitle(Some(&recording.get_performers())); row.set_subtitle(&recording.get_performers());
let recording = recording.to_owned(); let recording = recording.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
@ -139,7 +138,7 @@ impl Screen<Person, ()> for PersonScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&medium.name)); row.set_title(&medium.name);
let medium = medium.to_owned(); let medium = medium.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -3,7 +3,6 @@ use crate::widgets::{List, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use musicus_backend::db::Track; use musicus_backend::db::Track;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -227,7 +226,7 @@ impl Screen<(), ()> for PlayerScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_selectable(false); row.set_selectable(false);
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&title)); row.set_title(&title);
if first { if first {
let subtitle = if !parts.is_empty() { let subtitle = if !parts.is_empty() {
@ -236,7 +235,7 @@ impl Screen<(), ()> for PlayerScreen {
track.recording.get_performers() track.recording.get_performers()
}; };
row.set_subtitle(Some(&subtitle)); row.set_subtitle(&subtitle);
} }
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -5,7 +5,6 @@ use crate::widgets::{List, Section, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::{Recording, Track}; use musicus_backend::db::{Recording, Track};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -88,7 +87,7 @@ impl Screen<Recording, ()> for RecordingScreen {
}; };
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_title(Some(&title)); row.set_title(&title);
row.upcast() row.upcast()
})); }));

View file

@ -20,7 +20,7 @@ impl Screen<(), ()> for WelcomeScreen {
.build(); .build();
let header = adw::HeaderBarBuilder::new() let header = adw::HeaderBarBuilder::new()
.title_widget(&adw::WindowTitle::new(Some("Musicus"), None)) .title_widget(&adw::WindowTitle::new("Musicus", ""))
.build(); .build();
let button = gtk::ButtonBuilder::new() let button = gtk::ButtonBuilder::new()

View file

@ -6,7 +6,6 @@ use crate::widgets::{List, Section, Widget};
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::{Recording, Work}; use musicus_backend::db::{Recording, Work};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -72,8 +71,8 @@ impl Screen<Work, ()> for WorkScreen {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.work.get_title())); row.set_title(&recording.work.get_title());
row.set_subtitle(Some(&recording.get_performers())); row.set_subtitle(&recording.get_performers());
let recording = recording.to_owned(); let recording = recording.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -5,7 +5,6 @@ use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::Ensemble; use musicus_backend::db::Ensemble;
use std::rc::Rc; use std::rc::Rc;
@ -55,7 +54,7 @@ impl Screen<(), Ensemble> for EnsembleSelector {
.set_make_widget(clone!(@weak this => @default-panic, move |ensemble| { .set_make_widget(clone!(@weak this => @default-panic, move |ensemble| {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&ensemble.name)); row.set_title(&ensemble.name);
let ensemble = ensemble.to_owned(); let ensemble = ensemble.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -5,7 +5,6 @@ use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::Instrument; use musicus_backend::db::Instrument;
use std::rc::Rc; use std::rc::Rc;
@ -55,7 +54,7 @@ impl Screen<(), Instrument> for InstrumentSelector {
.set_make_widget(clone!(@weak this => @default-panic, move |instrument| { .set_make_widget(clone!(@weak this => @default-panic, move |instrument| {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&instrument.name)); row.set_title(&instrument.name);
let instrument = instrument.to_owned(); let instrument = instrument.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -4,7 +4,6 @@ use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::{Medium, PersonOrEnsemble}; use musicus_backend::db::{Medium, PersonOrEnsemble};
use std::rc::Rc; use std::rc::Rc;
@ -72,7 +71,7 @@ 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 = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&poe.get_title())); row.set_title(&poe.get_title());
let poe = poe.to_owned(); let poe = poe.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
@ -146,7 +145,7 @@ impl Screen<PersonOrEnsemble, Medium> for MediumSelectorMediumScreen {
.set_make_widget(clone!(@weak this => @default-panic, move |medium| { .set_make_widget(clone!(@weak this => @default-panic, move |medium| {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&medium.name)); row.set_title(&medium.name);
let medium = medium.to_owned(); let medium = medium.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -5,7 +5,6 @@ use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::Person; use musicus_backend::db::Person;
use std::rc::Rc; use std::rc::Rc;
@ -55,7 +54,7 @@ impl Screen<(), Person> for PersonSelector {
.set_make_widget(clone!(@weak this => @default-panic, move |person| { .set_make_widget(clone!(@weak this => @default-panic, move |person| {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&person.name_lf())); row.set_title(&person.name_lf());
let person = person.to_owned(); let person = person.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -5,7 +5,6 @@ use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::{Person, Recording, Work}; use musicus_backend::db::{Person, Recording, Work};
use std::rc::Rc; use std::rc::Rc;
@ -64,7 +63,7 @@ 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 = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&person.name_lf())); row.set_title(&person.name_lf());
let person = person.to_owned(); let person = person.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
@ -145,7 +144,7 @@ impl Screen<Person, Work> for RecordingSelectorWorkScreen {
.set_make_widget(clone!(@weak this => @default-panic, move |work| { .set_make_widget(clone!(@weak this => @default-panic, move |work| {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&work.title)); row.set_title(&work.title);
let work = work.to_owned(); let work = work.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
@ -212,7 +211,7 @@ impl Screen<Work, Recording> for RecordingSelectorRecordingScreen {
.set_make_widget(clone!(@weak this => @default-panic, move |recording| { .set_make_widget(clone!(@weak this => @default-panic, move |recording| {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.get_performers())); row.set_title(&recording.get_performers());
let recording = recording.to_owned(); let recording = recording.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -137,12 +137,12 @@ impl<T> Selector<T> {
/// Set the title to be shown in the header. /// Set the title to be shown in the header.
pub fn set_title(&self, title: &str) { pub fn set_title(&self, title: &str) {
self.title_label.set_label(&title); self.title_label.set_label(title);
} }
/// Set the subtitle to be shown in the header. /// Set the subtitle to be shown in the header.
pub fn set_subtitle(&self, subtitle: &str) { pub fn set_subtitle(&self, subtitle: &str) {
self.subtitle_label.set_label(&subtitle); self.subtitle_label.set_label(subtitle);
self.subtitle_label.show(); self.subtitle_label.show();
} }

View file

@ -5,7 +5,6 @@ use crate::widgets::Widget;
use adw::prelude::*; use adw::prelude::*;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*;
use musicus_backend::db::{Person, Work}; use musicus_backend::db::{Person, Work};
use std::rc::Rc; use std::rc::Rc;
@ -58,7 +57,7 @@ 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 = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&person.name_lf())); row.set_title(&person.name_lf());
let person = person.to_owned(); let person = person.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
@ -135,7 +134,7 @@ impl Screen<Person, Work> for WorkSelectorWorkScreen {
.set_make_widget(clone!(@weak this => @default-panic, move |work| { .set_make_widget(clone!(@weak this => @default-panic, move |work| {
let row = adw::ActionRow::new(); let row = adw::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&work.title)); row.set_title(&work.title);
let work = work.to_owned(); let work = work.to_owned();
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {

View file

@ -1,6 +1,5 @@
use super::Widget; use super::Widget;
use adw::prelude::*; use adw::prelude::*;
use gtk::prelude::*;
/// A list box row with a single button. /// A list box row with a single button.
pub struct ButtonRow { pub struct ButtonRow {
@ -31,7 +30,7 @@ impl ButtonRow {
} }
/// Set the subtitle of the row. /// Set the subtitle of the row.
pub fn set_subtitle(&self, subtitle: Option<&str>) { pub fn set_subtitle(&self, subtitle: &str) {
self.widget.set_subtitle(subtitle); self.widget.set_subtitle(subtitle);
} }

View file

@ -58,7 +58,7 @@ impl Editor {
/// Show a title in the header bar. /// Show a title in the header bar.
pub fn set_title(&self, title: &str) { pub fn set_title(&self, title: &str) {
self.window_title.set_title(Some(title)); self.window_title.set_title(title);
} }
/// Set whether the user should be able to click the save button. /// Set whether the user should be able to click the save button.
@ -78,7 +78,7 @@ impl Editor {
/// Show an error page. The page contains a button to get back to the /// Show an error page. The page contains a button to get back to the
/// actual editor. /// actual editor.
pub fn error(&self, title: &str, description: &str) { pub fn error(&self, title: &str, description: &str) {
self.status_page.set_title(Some(title)); self.status_page.set_title(title);
self.status_page.set_description(Some(description)); self.status_page.set_description(Some(description));
self.widget.set_visible_child_name("error"); self.widget.set_visible_child_name("error");
} }

View file

@ -1,5 +1,4 @@
use adw::prelude::*; use adw::prelude::*;
use gtk::prelude::*;
/// A list box row with an entry. /// A list box row with an entry.
pub struct EntryRow { pub struct EntryRow {

View file

@ -73,12 +73,12 @@ impl Screen {
/// Show a title in the header bar. /// Show a title in the header bar.
pub fn set_title(&self, title: &str) { pub fn set_title(&self, title: &str) {
self.window_title.set_title(Some(title)); self.window_title.set_title(title);
} }
/// Show a subtitle in the header bar. /// Show a subtitle in the header bar.
pub fn set_subtitle(&self, subtitle: &str) { pub fn set_subtitle(&self, subtitle: &str) {
self.window_title.set_subtitle(Some(subtitle)); self.window_title.set_subtitle(subtitle);
} }
/// Add a new item to the action menu and register a callback for it. /// Add a new item to the action menu and register a callback for it.

View file

@ -0,0 +1,143 @@
use super::{List, Widget};
use gtk::prelude::*;
use glib::clone;
use itertools::Itertools;
use musicus_backend::db::{Recording, Track, Work};
use std::{cell::RefCell, rc::Rc};
/// A widget for displaying a list of tracks.
pub struct TrackList {
tracks: RefCell<Vec<Track>>,
list: Rc<List>,
}
impl TrackList {
pub fn new() -> Rc<Self> {
let list = List::new();
let this = Rc::new(Self {
tracks: RefCell::new(Vec::new()),
list,
});
this.list.set_make_widget_cb(clone!(@weak this => move |index| {
this.track_row(index)
}));
this
}
fn track_row(&self, index: usize) -> gtk::Widget {
let tracks = self.tracks.borrow();
let track = &tracks[index];
if index > 0 {
let previous_track = &tracks[index - 1];
if previous_track.recording.id != track.recording.id {
return TrackRow::new
}
}
}
}
impl Widget for TrackList {
fn get_widget(&self) -> gtk::Widget {
self.list.get_widget()
}
}
/// Create a new separator row.
fn separator() -> gtk::ListBoxRow {
gtk::ListBoxRowBuilder::new()
.selectable(false)
.activatable(false)
.child(&gtk::Separator::new(gtk::Orientation::Horizontal))
.build()
}
/// Return an unfinished builder for a recording row.
fn recording_row(recording: &Recording) -> adw::ActionRowBuilder {
adw::ActionRowBuilder::new()
.title(&recording.work.get_title())
.subtitle(&recording.get_performers())
}
/// Get a string representing the given list of work parts.
fn parts_string(work: &Work, part_indices: &[usize]) -> String {
part_indices
.iter()
.map(|index| work.parts[*index].title.clone())
.collect::<Vec<String>>()
.join(", ")
}
/// A widget for displaying a single track within a list box.
struct TrackRow {
pub widget: gtk::ListBoxRow,
status_image: gtk::Image,
}
impl TrackRow {
/// Create a new track row.
///
/// Depending on the value of `header`, the row will display additional
/// information on the recording.
pub fn new(track: &Track, header: bool) -> Self {
let widget = gtk::ListBoxRow::new();
let content = gtk::Box::new(gtk::Orientation::Horizontal, 6);
let status_image = gtk::Image::from_icon_name(None);
content.append(&status_image);
if header {
let work_label = gtk::LabelBuilder::new()
.label(&track.recording.work.get_title())
.css_classes(vec![String::from("heading")])
.build();
let performers_label = gtk::LabelBuilder::new()
.label(&track.recording.get_performers())
.css_classes(vec![String::from("heading")])
.margin_bottom(6)
.build();
let labels = gtk::Box::new(gtk::Orientation::Vertical, 0);
labels.append(&work_label);
labels.append(&performers_label);
let title = track.title();
if !title.is_empty() {
let title_label = gtk::Label::new(Some(&track.title()));
labels.append(&title_label);
}
content.append(&labels);
} else {
content.append(&title_label);
}
widget.set_child(Some(&content));
Self {
widget,
status_image,
}
}
pub fn set_playing(&self, playing: bool) {
if playing {
self.status_image
.set_from_icon_name(Some("media-playback-start-symbolic"));
} else {
self.status_image.set_from_icon_name(None);
}
}
}
struct ListItem {
playing: bool,
header: Option<(String, String)>,
title: Option<String>,
}

View file

@ -25,7 +25,7 @@ impl Window {
.build(); .build();
let header = adw::HeaderBarBuilder::new() let header = adw::HeaderBarBuilder::new()
.title_widget(&adw::WindowTitle::new(Some("Musicus"), None)) .title_widget(&adw::WindowTitle::new("Musicus", ""))
.build(); .build();
let spinner = gtk::SpinnerBuilder::new() let spinner = gtk::SpinnerBuilder::new()
@ -42,7 +42,7 @@ impl Window {
loading_screen.append(&spinner); loading_screen.append(&spinner);
let navigator = Navigator::new(Rc::clone(&backend), &window, &loading_screen); let navigator = Navigator::new(Rc::clone(&backend), &window, &loading_screen);
adw::prelude::ApplicationWindowExt::set_child(&window, Some(&navigator.widget)); adw::traits::ApplicationWindowExt::set_content(&window, Some(&navigator.widget));
let this = Rc::new(Self { let this = Rc::new(Self {
backend, backend,