Use editor widget for performance editor

This commit is contained in:
Elias Projahn 2021-02-02 12:18:42 +01:00
parent d92fd419d3
commit 7eff62b5a4
7 changed files with 170 additions and 66 deletions

View file

@ -1,11 +1,10 @@
use crate::backend::Backend;
use crate::database::*;
use crate::selectors::{EnsembleSelector, InstrumentSelector, PersonSelector};
use crate::widgets::{Navigator, NavigatorScreen};
use crate::widgets::{Editor, Navigator, NavigatorScreen, Section, ButtonRow, Widget};
use gettextrs::gettext;
use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget;
use libadwaita::prelude::*;
use std::cell::RefCell;
use std::rc::Rc;
@ -13,11 +12,10 @@ use std::rc::Rc;
/// A dialog for editing a performance within a recording.
pub struct PerformanceEditor {
backend: Rc<Backend>,
widget: gtk::Box,
save_button: gtk::Button,
person_row: libadwaita::ActionRow,
ensemble_row: libadwaita::ActionRow,
role_row: libadwaita::ActionRow,
editor: Editor,
person_row: ButtonRow,
ensemble_row: ButtonRow,
role_row: ButtonRow,
reset_role_button: gtk::Button,
person: RefCell<Option<Person>>,
ensemble: RefCell<Option<Ensemble>>,
@ -29,25 +27,49 @@ pub struct PerformanceEditor {
impl PerformanceEditor {
/// Create a new performance editor.
pub fn new(backend: Rc<Backend>, performance: Option<Performance>) -> Rc<Self> {
// Create UI
let editor = Editor::new();
editor.set_title("Performance");
editor.set_may_save(false);
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/performance_editor.ui");
let performer_list = gtk::ListBoxBuilder::new()
.selection_mode(gtk::SelectionMode::None)
.build();
get_widget!(builder, gtk::Box, widget);
get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, save_button);
get_widget!(builder, gtk::Button, person_button);
get_widget!(builder, gtk::Button, ensemble_button);
get_widget!(builder, gtk::Button, role_button);
get_widget!(builder, gtk::Button, reset_role_button);
get_widget!(builder, libadwaita::ActionRow, person_row);
get_widget!(builder, libadwaita::ActionRow, ensemble_row);
get_widget!(builder, libadwaita::ActionRow, role_row);
let person_row = ButtonRow::new("Person", "Select");
let ensemble_row = ButtonRow::new("Ensemble", "Select");
performer_list.append(&person_row.get_widget());
performer_list.append(&ensemble_row.get_widget());
let performer_section = Section::new(&gettext("Performer"), &performer_list);
performer_section.set_subtitle(
&gettext("Select either a person or an ensemble as a performer."));
let role_list = gtk::ListBoxBuilder::new()
.selection_mode(gtk::SelectionMode::None)
.build();
let reset_role_button = gtk::ButtonBuilder::new()
.icon_name("user-trash-symbolic")
.valign(gtk::Align::Center)
.visible(false)
.build();
let role_row = ButtonRow::new("Role", "Select");
role_row.widget.add_suffix(&reset_role_button);
role_list.append(&role_row.get_widget());
let role_section = Section::new(&gettext("Role"), &role_list);
role_section.set_subtitle(
&gettext("Optionally, choose a role to specify what the performer does."));
editor.add_content(&performer_section);
editor.add_content(&role_section);
let this = Rc::new(PerformanceEditor {
backend,
widget,
save_button,
editor,
person_row,
ensemble_row,
role_row,
@ -59,32 +81,29 @@ impl PerformanceEditor {
navigator: RefCell::new(None),
});
// Connect signals and callbacks
back_button.connect_clicked(clone!(@strong this => move |_| {
this.editor.set_back_cb(clone!(@strong this => move || {
let navigator = this.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.pop();
}
}));
this.save_button
.connect_clicked(clone!(@strong this => move |_| {
if let Some(cb) = &*this.selected_cb.borrow() {
cb(Performance {
person: this.person.borrow().clone(),
ensemble: this.ensemble.borrow().clone(),
role: this.role.borrow().clone(),
});
}
this.editor.set_save_cb(clone!(@weak this => move || {
if let Some(cb) = &*this.selected_cb.borrow() {
cb(Performance {
person: this.person.borrow().clone(),
ensemble: this.ensemble.borrow().clone(),
role: this.role.borrow().clone(),
});
}
let navigator = this.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.pop();
}
}));
let navigator = this.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.pop();
}
}));
person_button.connect_clicked(clone!(@strong this => move |_| {
this.person_row.set_cb(clone!(@weak this => move || {
let navigator = this.navigator.borrow().clone();
if let Some(navigator) = navigator {
let selector = PersonSelector::new(this.backend.clone());
@ -101,7 +120,7 @@ impl PerformanceEditor {
}
}));
ensemble_button.connect_clicked(clone!(@strong this => move |_| {
this.ensemble_row.set_cb(clone!(@weak this => move || {
let navigator = this.navigator.borrow().clone();
if let Some(navigator) = navigator {
let selector = EnsembleSelector::new(this.backend.clone());
@ -118,7 +137,7 @@ impl PerformanceEditor {
}
}));
role_button.connect_clicked(clone!(@strong this => move |_| {
this.role_row.set_cb(clone!(@weak this => move || {
let navigator = this.navigator.borrow().clone();
if let Some(navigator) = navigator {
let selector = InstrumentSelector::new(this.backend.clone());
@ -133,11 +152,10 @@ impl PerformanceEditor {
}
}));
this.reset_role_button
.connect_clicked(clone!(@strong this => move |_| {
this.show_role(None);
this.role.replace(None);
}));
this.reset_role_button.connect_clicked(clone!(@weak this => move |_| {
this.show_role(None);
this.role.replace(None);
}));
// Initialize
@ -167,11 +185,9 @@ impl PerformanceEditor {
/// Update the UI according to person.
fn show_person(&self, person: Option<&Person>) {
if let Some(person) = person {
self.person_row.set_title(Some(&gettext("Person")));
self.person_row.set_subtitle(Some(&person.name_fl()));
self.save_button.set_sensitive(true);
self.editor.set_may_save(true);
} else {
self.person_row.set_title(Some(&gettext("Select a person")));
self.person_row.set_subtitle(None);
}
}
@ -179,11 +195,9 @@ impl PerformanceEditor {
/// Update the UI according to ensemble.
fn show_ensemble(&self, ensemble: Option<&Ensemble>) {
if let Some(ensemble) = ensemble {
self.ensemble_row.set_title(Some(&gettext("Ensemble")));
self.ensemble_row.set_subtitle(Some(&ensemble.name));
self.save_button.set_sensitive(true);
self.editor.set_may_save(true);
} else {
self.ensemble_row.set_title(Some(&gettext("Select an ensemble")));
self.ensemble_row.set_subtitle(None);
}
}
@ -191,11 +205,9 @@ impl PerformanceEditor {
/// Update the UI according to role.
fn show_role(&self, role: Option<&Instrument>) {
if let Some(role) = role {
self.role_row.set_title(Some(&gettext("Role")));
self.role_row.set_subtitle(Some(&role.name));
self.reset_role_button.show();
} else {
self.role_row.set_title(Some(&gettext("Select a role")));
self.role_row.set_subtitle(None);
self.reset_role_button.hide();
}
@ -208,7 +220,7 @@ impl NavigatorScreen for PerformanceEditor {
}
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast()
self.editor.widget.clone().upcast()
}
fn detach_navigator(&self) {