A lot of work, possibly meaningless, to try to handle state within the main window
A note to self, when I return to this: the overlay modals don't make sense in this context. The main window should have views, and switching from one view to the next should involve just replacing the child. Modals can be put off until later.
This commit is contained in:
parent
29dc81a991
commit
56a8133dd5
|
@ -23,6 +23,7 @@ use gio::resources_lookup_data;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{subclass::prelude::*, STYLE_PROVIDER_PRIORITY_USER};
|
use gtk::{subclass::prelude::*, STYLE_PROVIDER_PRIORITY_USER};
|
||||||
use std::{
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
env,
|
env,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
@ -136,7 +137,7 @@ enum MainView {
|
||||||
Unconfigured(UnconfiguredView),
|
Unconfigured(UnconfiguredView),
|
||||||
|
|
||||||
/// The Historical view shows a history of records and whatnot.
|
/// The Historical view shows a history of records and whatnot.
|
||||||
HistoricalView(HistoricalView),
|
Historical(HistoricalView),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The application window, or the main window, is the main user interface for the app.
|
/// The application window, or the main window, is the main user interface for the app.
|
||||||
|
@ -144,7 +145,12 @@ struct AppWindow {
|
||||||
app: App,
|
app: App,
|
||||||
window: adw::ApplicationWindow,
|
window: adw::ApplicationWindow,
|
||||||
overlay: gtk::Overlay,
|
overlay: gtk::Overlay,
|
||||||
current_view: MainView,
|
|
||||||
|
current_view: RefCell<MainView>,
|
||||||
|
|
||||||
|
// We have to keep around a reference to the modal so that we know what to remove from the
|
||||||
|
// overlay.
|
||||||
|
modal: RefCell<Option<gtk::Widget>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppWindow {
|
impl AppWindow {
|
||||||
|
@ -155,6 +161,46 @@ impl AppWindow {
|
||||||
///
|
///
|
||||||
/// app is a core [App] object which encapsulates all of the basic logic.
|
/// app is a core [App] object which encapsulates all of the basic logic.
|
||||||
fn new(adw_app: &adw::Application, app: App) -> AppWindow {
|
fn new(adw_app: &adw::Application, app: App) -> AppWindow {
|
||||||
|
let window = adw::ApplicationWindow::builder()
|
||||||
|
.application(adw_app)
|
||||||
|
.width_request(800)
|
||||||
|
.height_request(600)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// GTK overlays aren't all that well documented. The Overlay object needs to be the
|
||||||
|
// content/child of the window. The main content should then be added to the overlay as
|
||||||
|
// `set_child`. The overlays/modals should be added as `add_overlay` and then removed with
|
||||||
|
// `remove_overlay`.
|
||||||
|
let overlay = gtk::Overlay::new();
|
||||||
|
window.set_content(Some(&overlay));
|
||||||
|
|
||||||
|
let current_view = if app.database.read().unwrap().is_none() {
|
||||||
|
let view = UnconfiguredView::new();
|
||||||
|
/*
|
||||||
|
overlay.set_child(Some(&view));
|
||||||
|
|
||||||
|
// I have to access the overlay directly here because I haven't fully constructed Self
|
||||||
|
// yet, and so I don't have access to `open_modal` yet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MainView::Unconfigured(view)
|
||||||
|
} else {
|
||||||
|
let view = HistoricalView::new();
|
||||||
|
/*
|
||||||
|
overlay.set_child(Some(&view));
|
||||||
|
*/
|
||||||
|
|
||||||
|
MainView::Historical(view)
|
||||||
|
};
|
||||||
|
|
||||||
|
let s = Self {
|
||||||
|
app,
|
||||||
|
window: window.clone(),
|
||||||
|
overlay,
|
||||||
|
current_view: RefCell::new(current_view),
|
||||||
|
modal: RefCell::new(None),
|
||||||
|
};
|
||||||
|
|
||||||
let stylesheet = String::from_utf8(
|
let stylesheet = String::from_utf8(
|
||||||
resources_lookup_data(
|
resources_lookup_data(
|
||||||
&format!("{}style.css", RESOURCE_BASE_PATH),
|
&format!("{}style.css", RESOURCE_BASE_PATH),
|
||||||
|
@ -168,23 +214,16 @@ impl AppWindow {
|
||||||
let provider = gtk::CssProvider::new();
|
let provider = gtk::CssProvider::new();
|
||||||
provider.load_from_data(&stylesheet);
|
provider.load_from_data(&stylesheet);
|
||||||
|
|
||||||
let window = adw::ApplicationWindow::builder()
|
|
||||||
.application(adw_app)
|
|
||||||
.width_request(800)
|
|
||||||
.height_request(600)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let context = window.style_context();
|
let context = window.style_context();
|
||||||
context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER);
|
context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER);
|
||||||
|
|
||||||
window.present();
|
window.present();
|
||||||
|
|
||||||
// GTK overlays aren't all that well documented. The Overlay object needs to be the
|
s.redraw();
|
||||||
// content/child of the window. The main content should then be added to the overlay as
|
|
||||||
// `add_overlay`. The overlays/modals should be added as `set_child`.
|
|
||||||
let overlay = gtk::Overlay::new();
|
|
||||||
window.set_content(Some(&overlay));
|
|
||||||
|
|
||||||
|
s
|
||||||
|
|
||||||
|
/*
|
||||||
let current_view = if app.database.read().unwrap().is_none() {
|
let current_view = if app.database.read().unwrap().is_none() {
|
||||||
let view = UnconfiguredView::new();
|
let view = UnconfiguredView::new();
|
||||||
overlay.set_child(Some(&view));
|
overlay.set_child(Some(&view));
|
||||||
|
@ -192,6 +231,9 @@ impl AppWindow {
|
||||||
// I have to access the overlay directly here because I haven't fully constructed Self
|
// I have to access the overlay directly here because I haven't fully constructed Self
|
||||||
// yet, and so I don't have access to `open_modal` yet.
|
// yet, and so I don't have access to `open_modal` yet.
|
||||||
overlay.add_overlay(&welcome_modal(|path| {
|
overlay.add_overlay(&welcome_modal(|path| {
|
||||||
|
// When a path gets selected, I want to set the path in the configuration system,
|
||||||
|
// and I want to open the database. After that, this window should be redrawn with
|
||||||
|
// its new state. So the view state also needs to change.
|
||||||
println!("path: {}", path.to_str().unwrap())
|
println!("path: {}", path.to_str().unwrap())
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -202,24 +244,26 @@ impl AppWindow {
|
||||||
|
|
||||||
MainView::HistoricalView(view)
|
MainView::HistoricalView(view)
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
Self {
|
|
||||||
app,
|
|
||||||
window,
|
|
||||||
overlay,
|
|
||||||
current_view,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use [modal] as a modal overlay of the application window.
|
fn redraw(&self) {
|
||||||
fn open_modal(&self, modal: Modal) {
|
match *self.current_view.borrow() {
|
||||||
self.overlay.set_child(Some(&modal));
|
MainView::Unconfigured(ref view) => {
|
||||||
}
|
self.overlay.set_child(Some(view));
|
||||||
|
|
||||||
/// Close the modal by discarding the component.
|
let modal = welcome_modal(|path| {
|
||||||
fn close_modal(&self) {
|
// When a path gets selected, I want to set the path in the configuration system,
|
||||||
let none: Option<>k::Widget> = None;
|
// and I want to open the database. After that, this window should be redrawn with
|
||||||
self.overlay.set_child(none);
|
// its new state. So the view state also needs to change.
|
||||||
|
println!("path: {}", path.to_str().unwrap())
|
||||||
|
});
|
||||||
|
|
||||||
|
self.overlay.add_overlay(&modal);
|
||||||
|
*self.modal.borrow_mut() = Some(modal.upcast());
|
||||||
|
}
|
||||||
|
MainView::Historical(ref view) => self.overlay.set_child(Some(view)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue