From 433c3284feb8c5f97cbd6eb7f219ca374d985486 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Mon, 28 Sep 2020 17:19:34 +0200 Subject: [PATCH] Add instrument selector --- res/resources.xml | 1 + res/ui/instrument_selector.ui | 91 +++++++++++++++++++++++++ src/dialogs/instrument_selector.rs | 106 +++++++++++++++++++++++++++++ src/dialogs/mod.rs | 3 + src/dialogs/work_editor.rs | 30 +++++++- 5 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 res/ui/instrument_selector.ui create mode 100644 src/dialogs/instrument_selector.rs diff --git a/res/resources.xml b/res/resources.xml index 97a0e37..e0dcb06 100644 --- a/res/resources.xml +++ b/res/resources.xml @@ -3,6 +3,7 @@ ui/ensemble_editor.ui ui/instrument_editor.ui + ui/instrument_selector.ui ui/person_editor.ui ui/person_selector.ui ui/window.ui diff --git a/res/ui/instrument_selector.ui b/res/ui/instrument_selector.ui new file mode 100644 index 0000000..301c7f3 --- /dev/null +++ b/res/ui/instrument_selector.ui @@ -0,0 +1,91 @@ + + + + + + False + True + 350 + 300 + True + dialog + + + True + False + vertical + + + True + True + 6 + 6 + 6 + 6 + edit-find-symbolic + False + False + + + False + True + 0 + + + + + True + True + in + + + True + False + + + True + False + + + True + False + No instruments found. + + + + + + + + + True + True + 1 + + + + + + + True + False + Select instrument + True + + + True + True + True + + + True + False + list-add-symbolic + + + + + + + + diff --git a/src/dialogs/instrument_selector.rs b/src/dialogs/instrument_selector.rs new file mode 100644 index 0000000..5023bb1 --- /dev/null +++ b/src/dialogs/instrument_selector.rs @@ -0,0 +1,106 @@ +use super::selector_row::SelectorRow; +use super::InstrumentEditor; +use crate::database::*; +use gio::prelude::*; +use glib::clone; +use gtk::prelude::*; +use gtk_macros::get_widget; +use std::cell::RefCell; +use std::convert::TryInto; +use std::rc::Rc; + +pub struct InstrumentSelector +where + F: Fn(Instrument) -> () + 'static, +{ + db: Rc, + window: gtk::Window, + callback: F, + instruments: RefCell>, + list: gtk::ListBox, + search_entry: gtk::SearchEntry, +} + +impl InstrumentSelector +where + F: Fn(Instrument) -> () + 'static, +{ + pub fn new>(db: Rc, parent: &P, callback: F) -> Rc { + let builder = + gtk::Builder::from_resource("/de/johrpan/musicus_editor/ui/instrument_selector.ui"); + + get_widget!(builder, gtk::Window, window); + get_widget!(builder, gtk::Button, add_button); + get_widget!(builder, gtk::SearchEntry, search_entry); + get_widget!(builder, gtk::ListBox, list); + + let instruments = db.get_instruments(); + + for (index, instrument) in instruments.iter().enumerate() { + let label = gtk::Label::new(Some(&instrument.name)); + label.set_halign(gtk::Align::Start); + let row = SelectorRow::new(index.try_into().unwrap(), &label); + row.show_all(); + list.insert(&row, -1); + } + + let result = Rc::new(InstrumentSelector { + db: db, + window: window, + callback: callback, + instruments: RefCell::new(instruments), + search_entry: search_entry, + list: list, + }); + + result + .list + .connect_row_activated(clone!(@strong result => move |_, row| { + result.window.close(); + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + (result.callback)(result.instruments.borrow()[index].clone()); + })); + + result + .list + .set_filter_func(Some(Box::new(clone!(@strong result => move |row| { + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + let search = result.search_entry.get_text().to_string(); + + search.is_empty() || result.instruments.borrow()[index] + .name + .to_lowercase() + .contains(&result.search_entry.get_text().to_string().to_lowercase()) + })))); + + result + .search_entry + .connect_search_changed(clone!(@strong result => move |_| { + result.list.invalidate_filter(); + })); + + add_button.connect_clicked(clone!(@strong result => move |_| { + let editor = InstrumentEditor::new( + result.db.clone(), + &result.window, + None, + clone!(@strong result => move |instrument| { + result.window.close(); + (result.callback)(instrument); + }), + ); + + editor.show(); + })); + + result.window.set_transient_for(Some(parent)); + + result + } + + pub fn show(&self) { + self.window.show(); + } +} diff --git a/src/dialogs/mod.rs b/src/dialogs/mod.rs index 9a6cefb..66cb45a 100644 --- a/src/dialogs/mod.rs +++ b/src/dialogs/mod.rs @@ -4,6 +4,9 @@ pub use ensemble_editor::*; pub mod instrument_editor; pub use instrument_editor::*; +pub mod instrument_selector; +pub use instrument_selector::*; + pub mod person_editor; pub use person_editor::*; diff --git a/src/dialogs/work_editor.rs b/src/dialogs/work_editor.rs index 9ed57a8..54a4fd6 100644 --- a/src/dialogs/work_editor.rs +++ b/src/dialogs/work_editor.rs @@ -1,4 +1,5 @@ -use super::person_selector::PersonSelector; +use super::selector_row::SelectorRow; +use super::{InstrumentSelector, PersonSelector}; use crate::database::*; use glib::clone; use gtk::prelude::*; @@ -49,6 +50,7 @@ pub struct WorkEditor { composer: RefCell>, composer_label: gtk::Label, instruments: RefCell>, + instrument_list: gtk::ListBox, structure: RefCell>, } @@ -131,6 +133,7 @@ impl WorkEditor { composer: composer, composer_label: composer_label, instruments: instruments, + instrument_list: instrument_list, structure: structure, }); @@ -178,6 +181,17 @@ impl WorkEditor { })).show(); })); + add_instrument_button.connect_clicked(clone!(@strong result => move |_| { + InstrumentSelector::new(result.db.clone(), &result.window, clone!(@strong result => move |instrument| { + { + let mut instruments = result.instruments.borrow_mut(); + instruments.push(instrument); + } + + result.show_instruments(); + })).show(); + })); + result.window.set_transient_for(Some(parent)); result @@ -186,4 +200,18 @@ impl WorkEditor { pub fn show(&self) { self.window.show(); } + + fn show_instruments(&self) { + for child in self.instrument_list.get_children() { + self.instrument_list.remove(&child); + } + + for (index, instrument) in self.instruments.borrow().iter().enumerate() { + let label = gtk::Label::new(Some(&instrument.name)); + label.set_halign(gtk::Align::Start); + let row = SelectorRow::new(index.try_into().unwrap(), &label); + row.show_all(); + self.instrument_list.insert(&row, -1); + } + } }