Replace stack with new navigator widget

This commit is contained in:
Elias Projahn 2020-10-17 11:31:43 +02:00
parent cefd7dad95
commit 9a9a181739
8 changed files with 268 additions and 206 deletions

View file

@ -1,3 +1,4 @@
use super::*;
use crate::backend::*;
use crate::database::*;
use crate::widgets::*;
@ -9,10 +10,11 @@ use std::cell::RefCell;
use std::rc::Rc;
pub struct EnsembleScreen {
pub widget: gtk::Box,
backend: Rc<Backend>,
widget: gtk::Box,
stack: gtk::Stack,
recording_list: Rc<List<RecordingDescription>>,
back: RefCell<Option<Box<dyn Fn() -> () + 'static>>>,
navigator: RefCell<Option<Rc<Navigator>>>,
}
impl EnsembleScreen {
@ -59,10 +61,11 @@ impl EnsembleScreen {
recording_frame.add(&recording_list.widget.clone());
let result = Rc::new(Self {
backend,
widget,
stack,
recording_list,
back: RefCell::new(None),
navigator: RefCell::new(None),
});
search_entry.connect_search_changed(clone!(@strong result => move |_| {
@ -70,15 +73,26 @@ impl EnsembleScreen {
}));
back_button.connect_clicked(clone!(@strong result => move |_| {
if let Some(back) = &*result.back.borrow() {
back();
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.pop();
}
}));
result
.recording_list
.set_selected(clone!(@strong result => move |recording| {
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.push(RecordingScreen::new(result.backend.clone(), recording.clone()));
}
}));
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
let recordings = backend
let recordings = clone
.backend
.get_recordings_for_ensemble(ensemble.id)
.await
.unwrap();
@ -93,18 +107,18 @@ impl EnsembleScreen {
result
}
}
pub fn set_back<B>(&self, back: B)
where
B: Fn() -> () + 'static,
{
self.back.replace(Some(Box::new(back)));
impl NavigatorScreen for EnsembleScreen {
fn attach_navigator(&self, navigator: Rc<Navigator>) {
self.navigator.replace(Some(navigator));
}
pub fn set_recording_selected<S>(&self, selected: S)
where
S: Fn(&RecordingDescription) -> () + 'static,
{
self.recording_list.set_selected(selected);
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast()
}
fn detach_navigator(&self) {
self.navigator.replace(None);
}
}

View file

@ -1,3 +1,4 @@
use super::*;
use crate::backend::*;
use crate::database::*;
use crate::widgets::*;
@ -9,11 +10,12 @@ use std::cell::RefCell;
use std::rc::Rc;
pub struct PersonScreen {
pub widget: gtk::Box,
backend: Rc<Backend>,
widget: gtk::Box,
stack: gtk::Stack,
work_list: Rc<List<WorkDescription>>,
recording_list: Rc<List<RecordingDescription>>,
back: RefCell<Option<Box<dyn Fn() -> () + 'static>>>,
navigator: RefCell<Option<Rc<Navigator>>>,
}
impl PersonScreen {
@ -77,11 +79,12 @@ impl PersonScreen {
recording_frame.add(&recording_list.widget);
let result = Rc::new(Self {
backend,
widget,
stack,
work_list,
recording_list,
back: RefCell::new(None),
navigator: RefCell::new(None),
});
search_entry.connect_search_changed(clone!(@strong result => move |_| {
@ -90,16 +93,43 @@ impl PersonScreen {
}));
back_button.connect_clicked(clone!(@strong result => move |_| {
if let Some(back) = &*result.back.borrow() {
back();
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.clone().pop();
}
}));
result
.work_list
.set_selected(clone!(@strong result => move |work| {
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.push(WorkScreen::new(result.backend.clone(), work.clone()));
}
}));
result
.recording_list
.set_selected(clone!(@strong result => move |recording| {
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.push(RecordingScreen::new(result.backend.clone(), recording.clone()));
}
}));
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
let works = backend.get_work_descriptions(person.id).await.unwrap();
let recordings = backend.get_recordings_for_person(person.id).await.unwrap();
let works = clone
.backend
.get_work_descriptions(person.id)
.await
.unwrap();
let recordings = clone
.backend
.get_recordings_for_person(person.id)
.await
.unwrap();
if works.is_empty() && recordings.is_empty() {
clone.stack.set_visible_child_name("nothing");
@ -122,25 +152,18 @@ impl PersonScreen {
result
}
}
pub fn set_back<B>(&self, back: B)
where
B: Fn() -> () + 'static,
{
self.back.replace(Some(Box::new(back)));
impl NavigatorScreen for PersonScreen {
fn attach_navigator(&self, navigator: Rc<Navigator>) {
self.navigator.replace(Some(navigator));
}
pub fn set_work_selected<S>(&self, selected: S)
where
S: Fn(&WorkDescription) -> () + 'static,
{
self.work_list.set_selected(selected);
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast()
}
pub fn set_recording_selected<S>(&self, selected: S)
where
S: Fn(&RecordingDescription) -> () + 'static,
{
self.recording_list.set_selected(selected);
fn detach_navigator(&self) {
self.navigator.replace(None);
}
}

View file

@ -1,5 +1,6 @@
use crate::backend::*;
use crate::database::*;
use crate::widgets::*;
use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget;
@ -8,8 +9,8 @@ use std::cell::RefCell;
use std::rc::Rc;
pub struct RecordingScreen {
pub widget: gtk::Box,
back: RefCell<Option<Box<dyn Fn() -> () + 'static>>>,
widget: gtk::Box,
navigator: RefCell<Option<Rc<Navigator>>>,
}
impl RecordingScreen {
@ -27,22 +28,30 @@ impl RecordingScreen {
let result = Rc::new(Self {
widget,
back: RefCell::new(None),
navigator: RefCell::new(None),
});
back_button.connect_clicked(clone!(@strong result => move |_| {
if let Some(back) = &*result.back.borrow() {
back();
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.clone().pop();
}
}));
result
}
}
pub fn set_back<B>(&self, back: B)
where
B: Fn() -> () + 'static,
{
self.back.replace(Some(Box::new(back)));
impl NavigatorScreen for RecordingScreen {
fn attach_navigator(&self, navigator: Rc<Navigator>) {
self.navigator.replace(Some(navigator));
}
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast()
}
fn detach_navigator(&self) {
self.navigator.replace(None);
}
}

View file

@ -1,3 +1,4 @@
use super::*;
use crate::backend::*;
use crate::database::*;
use crate::widgets::*;
@ -9,10 +10,11 @@ use std::cell::RefCell;
use std::rc::Rc;
pub struct WorkScreen {
pub widget: gtk::Box,
backend: Rc<Backend>,
widget: gtk::Box,
stack: gtk::Stack,
recording_list: Rc<List<RecordingDescription>>,
back: RefCell<Option<Box<dyn Fn() -> () + 'static>>>,
navigator: RefCell<Option<Rc<Navigator>>>,
}
impl WorkScreen {
@ -59,10 +61,11 @@ impl WorkScreen {
recording_frame.add(&recording_list.widget);
let result = Rc::new(Self {
backend,
widget,
stack,
recording_list,
back: RefCell::new(None),
navigator: RefCell::new(None),
});
search_entry.connect_search_changed(clone!(@strong result => move |_| {
@ -70,15 +73,29 @@ impl WorkScreen {
}));
back_button.connect_clicked(clone!(@strong result => move |_| {
if let Some(back) = &*result.back.borrow() {
back();
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.clone().pop();
}
}));
result
.recording_list
.set_selected(clone!(@strong result => move |recording| {
let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator {
navigator.push(RecordingScreen::new(result.backend.clone(), recording.clone()));
}
}));
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
let recordings = backend.get_recordings_for_work(work.id).await.unwrap();
let recordings = clone
.backend
.get_recordings_for_work(work.id)
.await
.unwrap();
if recordings.is_empty() {
clone.stack.set_visible_child_name("nothing");
@ -90,18 +107,18 @@ impl WorkScreen {
result
}
}
pub fn set_back<B>(&self, back: B)
where
B: Fn() -> () + 'static,
{
self.back.replace(Some(Box::new(back)));
impl NavigatorScreen for WorkScreen {
fn attach_navigator(&self, navigator: Rc<Navigator>) {
self.navigator.replace(Some(navigator));
}
pub fn set_recording_selected<S>(&self, selected: S)
where
S: Fn(&RecordingDescription) -> () + 'static,
{
self.recording_list.set_selected(selected);
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast()
}
fn detach_navigator(&self) {
self.navigator.replace(None);
}
}