musicus/src/window.rs

328 lines
11 KiB
Rust
Raw Normal View History

2020-10-16 21:24:55 +02:00
use crate::backend::*;
use crate::dialogs::*;
use crate::screens::*;
use crate::widgets::*;
2020-11-01 10:13:21 +01:00
use futures::prelude::*;
use gettextrs::gettext;
2020-09-27 21:58:42 +02:00
use gio::prelude::*;
2020-09-28 15:02:19 +02:00
use glib::clone;
2020-09-27 21:58:42 +02:00
use gtk::prelude::*;
use gtk_macros::{action, get_widget};
use libhandy::prelude::*;
2020-09-28 15:02:19 +02:00
use std::rc::Rc;
2020-09-27 21:58:42 +02:00
pub struct Window {
backend: Rc<Backend>,
2020-10-16 21:24:55 +02:00
window: libhandy::ApplicationWindow,
2020-11-01 10:13:21 +01:00
stack: gtk::Stack,
leaflet: libhandy::Leaflet,
2020-10-16 21:24:55 +02:00
sidebar_box: gtk::Box,
poe_list: Rc<PoeList>,
navigator: Rc<Navigator>,
2020-09-27 21:58:42 +02:00
}
impl Window {
2020-09-28 15:02:19 +02:00
pub fn new(app: &gtk::Application) -> Rc<Self> {
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/window.ui");
get_widget!(builder, libhandy::ApplicationWindow, window);
2020-11-01 10:13:21 +01:00
get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::Button, select_music_library_path_button);
get_widget!(builder, libhandy::Leaflet, leaflet);
2020-10-31 23:48:11 +01:00
get_widget!(builder, gtk::Button, add_button);
2020-10-16 21:24:55 +02:00
get_widget!(builder, gtk::Box, sidebar_box);
get_widget!(builder, gtk::Box, empty_screen);
2020-11-01 10:13:21 +01:00
let backend = Rc::new(Backend::new());
2020-11-01 19:09:31 +01:00
backend.clone().init();
2020-10-16 21:24:55 +02:00
let poe_list = PoeList::new(backend.clone());
let navigator = Navigator::new(&empty_screen);
2020-10-16 21:24:55 +02:00
let result = Rc::new(Self {
backend,
window,
2020-11-01 10:13:21 +01:00
stack,
2020-10-16 21:24:55 +02:00
leaflet,
sidebar_box,
poe_list,
navigator,
2020-09-27 21:58:42 +02:00
});
2020-10-16 21:24:55 +02:00
result.window.set_application(Some(app));
2020-11-01 10:13:21 +01:00
select_music_library_path_button.connect_clicked(clone!(@strong result => move |_| {
let dialog = gtk::FileChooserNative::new(
Some(&gettext("Select music library folder")),
Some(&result.window),
gtk::FileChooserAction::SelectFolder,
None,
None);
2020-11-01 10:13:21 +01:00
if let gtk::ResponseType::Accept = dialog.run() {
if let Some(path) = dialog.get_filename() {
2020-11-01 10:13:21 +01:00
let context = glib::MainContext::default();
let backend = result.backend.clone();
context.spawn_local(async move {
backend.set_music_library_path(path).await.unwrap();
});
}
}
}));
2020-10-31 23:48:11 +01:00
add_button.connect_clicked(clone!(@strong result => move |_| {
TracksEditor::new(result.backend.clone(), &result.window, clone!(@strong result => move || {
result.reload();
})).show();
}));
action!(
result.window,
"preferences",
clone!(@strong result => move |_, _| {
Preferences::new(result.backend.clone(), &result.window).show();
})
);
2020-09-28 15:02:19 +02:00
action!(
result.window,
"add-person",
clone!(@strong result => move |_, _| {
PersonEditor::new(result.backend.clone(), &result.window, None, clone!(@strong result => move |_| {
2020-10-16 21:24:55 +02:00
result.reload();
2020-09-28 20:09:49 +02:00
})).show();
2020-09-28 15:02:19 +02:00
})
);
2020-09-28 15:08:24 +02:00
action!(
result.window,
"add-instrument",
clone!(@strong result => move |_, _| {
InstrumentEditor::new(result.backend.clone(), &result.window, None, |instrument| {
2020-09-28 15:08:24 +02:00
println!("{:?}", instrument);
}).show();
})
);
2020-09-27 21:58:42 +02:00
2020-09-28 16:00:51 +02:00
action!(
result.window,
"add-work",
clone!(@strong result => move |_, _| {
WorkEditor::new(result.backend.clone(), &result.window, None, clone!(@strong result => move |_| {
2020-10-16 21:24:55 +02:00
result.reload();
2020-09-28 20:09:49 +02:00
})).show();
2020-09-28 16:00:51 +02:00
})
);
2020-09-27 21:58:42 +02:00
2020-09-28 15:14:05 +02:00
action!(
result.window,
"add-ensemble",
clone!(@strong result => move |_, _| {
2020-10-16 21:24:55 +02:00
EnsembleEditor::new(result.backend.clone(), &result.window, None, clone!(@strong result => move |_| {
result.reload();
})).show();
2020-09-28 15:14:05 +02:00
})
);
2020-09-27 21:58:42 +02:00
2020-10-09 23:02:50 +02:00
action!(
result.window,
"add-recording",
clone!(@strong result => move |_, _| {
RecordingEditor::new(result.backend.clone(), &result.window, None, clone!(@strong result => move |_| {
2020-10-16 21:24:55 +02:00
result.reload();
2020-10-09 23:02:50 +02:00
})).show();
})
);
2020-09-27 21:58:42 +02:00
2020-10-31 23:07:25 +01:00
action!(
result.window,
"add-tracks",
clone!(@strong result => move |_, _| {
TracksEditor::new(result.backend.clone(), &result.window, clone!(@strong result => move || {
result.reload();
})).show();
})
);
action!(
result.window,
"edit-person",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
2020-10-11 21:13:15 +02:00
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
let person = result.backend.get_person(id).await.unwrap();
PersonEditor::new(result.backend.clone(), &result.window, Some(person), clone!(@strong result => move |_| {
2020-10-16 21:24:55 +02:00
result.reload();
})).show();
2020-10-11 21:13:15 +02:00
});
})
);
action!(
result.window,
"delete-person",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
2020-10-11 21:13:15 +02:00
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
result.backend.delete_person(id).await.unwrap();
2020-10-16 21:24:55 +02:00
result.reload();
2020-10-11 21:13:15 +02:00
});
})
);
action!(
result.window,
"edit-ensemble",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
2020-10-11 21:13:15 +02:00
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
let ensemble = result.backend.get_ensemble(id).await.unwrap();
EnsembleEditor::new(result.backend.clone(), &result.window, Some(ensemble), clone!(@strong result => move |_| {
2020-10-16 21:24:55 +02:00
result.reload();
})).show();
2020-10-11 21:13:15 +02:00
});
})
);
action!(
result.window,
"delete-ensemble",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
2020-10-11 21:13:15 +02:00
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
result.backend.delete_ensemble(id).await.unwrap();
2020-10-16 21:24:55 +02:00
result.reload();
2020-10-11 21:13:15 +02:00
});
})
);
action!(
result.window,
"edit-work",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
let work = result.backend.get_work_description(id).await.unwrap();
WorkEditor::new(result.backend.clone(), &result.window, Some(work), clone!(@strong result => move |_| {
result.reload();
})).show();
});
})
);
action!(
result.window,
"delete-work",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
result.backend.delete_work(id).await.unwrap();
result.reload();
});
})
);
action!(
result.window,
"edit-recording",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
let recording = result.backend.get_recording_description(id).await.unwrap();
RecordingEditor::new(result.backend.clone(), &result.window, Some(recording), clone!(@strong result => move |_| {
result.reload();
})).show();
});
})
);
action!(
result.window,
"delete-recording",
Some(glib::VariantTy::new("x").unwrap()),
clone!(@strong result => move |_, id| {
let id = id.unwrap().get().unwrap();
let result = result.clone();
let c = glib::MainContext::default();
c.spawn_local(async move {
result.backend.delete_recording(id).await.unwrap();
result.reload();
});
})
);
2020-11-01 10:13:21 +01:00
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
let mut state_stream = clone.backend.state_stream.borrow_mut();
while let Some(state) = state_stream.next().await {
match state {
BackendState::NoMusicLibrary => {
clone.stack.set_visible_child_name("empty");
}
BackendState::Loading => {
clone.stack.set_visible_child_name("loading");
}
BackendState::Ready => {
clone.stack.set_visible_child_name("content");
clone.poe_list.clone().reload();
}
}
}
});
result.leaflet.add(&result.navigator.widget);
result
.poe_list
.set_selected(clone!(@strong result => move |poe| {
result.leaflet.set_visible_child(&result.navigator.widget);
match poe {
PersonOrEnsemble::Person(person) => {
result.navigator.clone().replace(PersonScreen::new(result.backend.clone(), person.clone()));
}
PersonOrEnsemble::Ensemble(ensemble) => {
result.navigator.clone().replace(EnsembleScreen::new(result.backend.clone(), ensemble.clone()));
}
}
}));
result
.sidebar_box
.pack_start(&result.poe_list.widget, true, true, 0);
2020-09-28 15:02:19 +02:00
result
2020-09-27 21:58:42 +02:00
}
pub fn present(&self) {
self.window.present();
}
2020-09-28 20:09:49 +02:00
2020-10-16 21:24:55 +02:00
fn reload(&self) {
self.poe_list.clone().reload();
self.navigator.reset();
2020-10-16 21:24:55 +02:00
self.leaflet.set_visible_child(&self.sidebar_box);
2020-09-28 20:09:49 +02:00
}
2020-09-27 21:58:42 +02:00
}