mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 19:57:25 +01:00
Fully functional person editor
This commit is contained in:
parent
f49f23a501
commit
3dc601e0f0
10 changed files with 214 additions and 43 deletions
|
|
@ -67,9 +67,12 @@ mod imp {
|
|||
|
||||
fn signals() -> &'static [Signal] {
|
||||
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
|
||||
vec![Signal::builder("instrument-selected")
|
||||
.param_types([Instrument::static_type()])
|
||||
.build()]
|
||||
vec![
|
||||
Signal::builder("instrument-selected")
|
||||
.param_types([Instrument::static_type()])
|
||||
.build(),
|
||||
Signal::builder("create").build(),
|
||||
]
|
||||
});
|
||||
|
||||
SIGNALS.as_ref()
|
||||
|
|
@ -113,6 +116,14 @@ impl MusicusInstrumentSelectorPopover {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn connect_create<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.connect_local("create", true, move |values| {
|
||||
let obj = values[0].get::<Self>().unwrap();
|
||||
f(&obj);
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn search_changed(&self, entry: >k::SearchEntry) {
|
||||
self.search(&entry.text());
|
||||
|
|
@ -135,7 +146,12 @@ impl MusicusInstrumentSelectorPopover {
|
|||
fn search(&self, search: &str) {
|
||||
let imp = self.imp();
|
||||
|
||||
let instruments = imp.library.get().unwrap().search_instruments(search).unwrap();
|
||||
let instruments = imp
|
||||
.library
|
||||
.get()
|
||||
.unwrap()
|
||||
.search_instruments(search)
|
||||
.unwrap();
|
||||
|
||||
imp.list_box.remove_all();
|
||||
|
||||
|
|
@ -182,7 +198,7 @@ impl MusicusInstrumentSelectorPopover {
|
|||
}
|
||||
|
||||
fn create(&self) {
|
||||
log::info!("Create instrument!");
|
||||
self.emit_by_name::<()>("create", &[]);
|
||||
self.popdown();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,30 @@
|
|||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gtk::glib;
|
||||
use std::cell::OnceCell;
|
||||
|
||||
use crate::{db::models::Person, editor::translation_editor::MusicusTranslationEditor};
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gettextrs::gettext;
|
||||
use gtk::glib::{self, subclass::Signal};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::{
|
||||
db::models::Person, editor::translation_editor::MusicusTranslationEditor,
|
||||
library::MusicusLibrary,
|
||||
};
|
||||
|
||||
mod imp {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||
#[template(file = "data/ui/person_editor.blp")]
|
||||
pub struct MusicusPersonEditor {
|
||||
pub navigation: OnceCell<adw::NavigationView>,
|
||||
pub library: OnceCell<MusicusLibrary>,
|
||||
pub person_id: OnceCell<String>,
|
||||
|
||||
#[template_child]
|
||||
pub name_editor: TemplateChild<MusicusTranslationEditor>,
|
||||
#[template_child]
|
||||
pub save_button: TemplateChild<gtk::Button>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
|
@ -30,7 +44,18 @@ mod imp {
|
|||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for MusicusPersonEditor {}
|
||||
impl ObjectImpl for MusicusPersonEditor {
|
||||
fn signals() -> &'static [Signal] {
|
||||
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
|
||||
vec![Signal::builder("created")
|
||||
.param_types([Person::static_type()])
|
||||
.build()]
|
||||
});
|
||||
|
||||
SIGNALS.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for MusicusPersonEditor {}
|
||||
impl NavigationPageImpl for MusicusPersonEditor {}
|
||||
}
|
||||
|
|
@ -42,13 +67,46 @@ glib::wrapper! {
|
|||
|
||||
#[gtk::template_callbacks]
|
||||
impl MusicusPersonEditor {
|
||||
pub fn new(person: Option<&Person>) -> Self {
|
||||
pub fn new(
|
||||
navigation: &adw::NavigationView,
|
||||
library: &MusicusLibrary,
|
||||
person: Option<&Person>,
|
||||
) -> Self {
|
||||
let obj: Self = glib::Object::new();
|
||||
|
||||
obj.imp().navigation.set(navigation.to_owned()).unwrap();
|
||||
obj.imp().library.set(library.to_owned()).unwrap();
|
||||
|
||||
if let Some(person) = person {
|
||||
obj.imp().save_button.set_label(&gettext("Save changes"));
|
||||
obj.imp().person_id.set(person.person_id.clone()).unwrap();
|
||||
obj.imp().name_editor.set_translation(&person.name);
|
||||
}
|
||||
|
||||
obj
|
||||
}
|
||||
|
||||
pub fn connect_created<F: Fn(&Self, Person) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.connect_local("created", true, move |values| {
|
||||
let obj = values[0].get::<Self>().unwrap();
|
||||
let person = values[1].get::<Person>().unwrap();
|
||||
f(&obj, person);
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn save(&self, _: >k::Button) {
|
||||
let library = self.imp().library.get().unwrap();
|
||||
let name = self.imp().name_editor.translation();
|
||||
|
||||
if let Some(person_id) = self.imp().person_id.get() {
|
||||
library.update_person(person_id, name).unwrap();
|
||||
} else {
|
||||
let person = library.create_person(name).unwrap();
|
||||
self.emit_by_name::<()>("created", &[&person]);
|
||||
}
|
||||
|
||||
self.imp().navigation.get().unwrap().pop();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,9 +67,12 @@ mod imp {
|
|||
|
||||
fn signals() -> &'static [Signal] {
|
||||
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
|
||||
vec![Signal::builder("person-selected")
|
||||
.param_types([Person::static_type()])
|
||||
.build()]
|
||||
vec![
|
||||
Signal::builder("person-selected")
|
||||
.param_types([Person::static_type()])
|
||||
.build(),
|
||||
Signal::builder("create").build(),
|
||||
]
|
||||
});
|
||||
|
||||
SIGNALS.as_ref()
|
||||
|
|
@ -113,6 +116,14 @@ impl MusicusPersonSelectorPopover {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn connect_create<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.connect_local("create", true, move |values| {
|
||||
let obj = values[0].get::<Self>().unwrap();
|
||||
f(&obj);
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn search_changed(&self, entry: >k::SearchEntry) {
|
||||
self.search(&entry.text());
|
||||
|
|
@ -182,7 +193,7 @@ impl MusicusPersonSelectorPopover {
|
|||
}
|
||||
|
||||
fn create(&self) {
|
||||
log::info!("Create person!");
|
||||
self.emit_by_name::<()>("create", &[]);
|
||||
self.popdown();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,9 +67,12 @@ mod imp {
|
|||
|
||||
fn signals() -> &'static [Signal] {
|
||||
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
|
||||
vec![Signal::builder("role-selected")
|
||||
.param_types([Role::static_type()])
|
||||
.build()]
|
||||
vec![
|
||||
Signal::builder("role-selected")
|
||||
.param_types([Role::static_type()])
|
||||
.build(),
|
||||
Signal::builder("create").build(),
|
||||
]
|
||||
});
|
||||
|
||||
SIGNALS.as_ref()
|
||||
|
|
@ -113,6 +116,14 @@ impl MusicusRoleSelectorPopover {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn connect_create<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.connect_local("create", true, move |values| {
|
||||
let obj = values[0].get::<Self>().unwrap();
|
||||
f(&obj);
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn search_changed(&self, entry: >k::SearchEntry) {
|
||||
self.search(&entry.text());
|
||||
|
|
@ -182,7 +193,7 @@ impl MusicusRoleSelectorPopover {
|
|||
}
|
||||
|
||||
fn create(&self) {
|
||||
log::info!("Create role!");
|
||||
self.emit_by_name::<()>("create", &[]);
|
||||
self.popdown();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ impl MusicusTranslationEditor {
|
|||
self.add_entry(&util::LANG, &self.imp().entry_row.text());
|
||||
}
|
||||
|
||||
fn translation(&self) -> TranslatedString {
|
||||
pub fn translation(&self) -> TranslatedString {
|
||||
let imp = self.imp();
|
||||
let mut translation = HashMap::<String, String>::new();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
},
|
||||
editor::{
|
||||
instrument_selector_popover::MusicusInstrumentSelectorPopover,
|
||||
person_selector_popover::MusicusPersonSelectorPopover,
|
||||
person_editor::MusicusPersonEditor, person_selector_popover::MusicusPersonSelectorPopover,
|
||||
translation_editor::MusicusTranslationEditor,
|
||||
work_editor_composer_row::MusicusWorkEditorComposerRow,
|
||||
},
|
||||
|
|
@ -80,24 +80,20 @@ mod imp {
|
|||
let persons_popover = MusicusPersonSelectorPopover::new(self.library.get().unwrap());
|
||||
|
||||
let obj = self.obj().clone();
|
||||
persons_popover.connect_person_selected(
|
||||
move |_: &MusicusPersonSelectorPopover, person: Person| {
|
||||
let role = obj.library().composer_default_role().unwrap();
|
||||
let composer = Composer { person, role };
|
||||
let row = MusicusWorkEditorComposerRow::new(&obj.library(), composer);
|
||||
persons_popover.connect_person_selected(move |_, person| {
|
||||
obj.add_composer(person);
|
||||
});
|
||||
|
||||
row.connect_remove(clone!(@weak obj => move |row| {
|
||||
obj.imp().composer_list.remove(row);
|
||||
obj.imp().composer_rows.borrow_mut().retain(|c| c != row);
|
||||
}));
|
||||
let obj = self.obj().clone();
|
||||
persons_popover.connect_create(move |_| {
|
||||
let editor = MusicusPersonEditor::new(&obj.navigation(), &obj.library(), None);
|
||||
|
||||
obj.imp()
|
||||
.composer_list
|
||||
.insert(&row, obj.imp().composer_rows.borrow().len() as i32);
|
||||
editor.connect_created(clone!(@weak obj => move |_, person| {
|
||||
obj.add_composer(person);
|
||||
}));
|
||||
|
||||
obj.imp().composer_rows.borrow_mut().push(row);
|
||||
},
|
||||
);
|
||||
obj.navigation().push(&editor);
|
||||
});
|
||||
|
||||
self.select_person_box.append(&persons_popover);
|
||||
self.persons_popover.set(persons_popover).unwrap();
|
||||
|
|
@ -210,4 +206,21 @@ impl MusicusWorkEditor {
|
|||
fn add_instrument(&self, _: &adw::ActionRow) {
|
||||
self.imp().instruments_popover.get().unwrap().popup();
|
||||
}
|
||||
|
||||
fn add_composer(&self, person: Person) {
|
||||
let role = self.library().composer_default_role().unwrap();
|
||||
let composer = Composer { person, role };
|
||||
let row = MusicusWorkEditorComposerRow::new(&self.library(), composer);
|
||||
|
||||
row.connect_remove(clone!(@weak self as obj => move |row| {
|
||||
obj.imp().composer_list.remove(row);
|
||||
obj.imp().composer_rows.borrow_mut().retain(|c| c != row);
|
||||
}));
|
||||
|
||||
self.imp()
|
||||
.composer_list
|
||||
.insert(&row, self.imp().composer_rows.borrow().len() as i32);
|
||||
|
||||
self.imp().composer_rows.borrow_mut().push(row);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue