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:
Savanni D'Gerinel 2023-12-18 17:49:25 -05:00
parent 29dc81a991
commit 56a8133dd5
1 changed files with 73 additions and 29 deletions

View File

@ -23,6 +23,7 @@ use gio::resources_lookup_data;
use glib::Object;
use gtk::{subclass::prelude::*, STYLE_PROVIDER_PRIORITY_USER};
use std::{
cell::RefCell,
env,
sync::{Arc, RwLock},
};
@ -136,7 +137,7 @@ enum MainView {
Unconfigured(UnconfiguredView),
/// 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.
@ -144,7 +145,12 @@ struct AppWindow {
app: App,
window: adw::ApplicationWindow,
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 {
@ -155,6 +161,46 @@ impl AppWindow {
///
/// app is a core [App] object which encapsulates all of the basic logic.
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(
resources_lookup_data(
&format!("{}style.css", RESOURCE_BASE_PATH),
@ -168,23 +214,16 @@ impl AppWindow {
let provider = gtk::CssProvider::new();
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();
context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER);
window.present();
// 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
// `add_overlay`. The overlays/modals should be added as `set_child`.
let overlay = gtk::Overlay::new();
window.set_content(Some(&overlay));
s.redraw();
s
/*
let current_view = if app.database.read().unwrap().is_none() {
let view = UnconfiguredView::new();
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
// yet, and so I don't have access to `open_modal` yet.
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())
}));
@ -202,25 +244,27 @@ impl AppWindow {
MainView::HistoricalView(view)
};
*/
}
Self {
app,
window,
overlay,
current_view,
fn redraw(&self) {
match *self.current_view.borrow() {
MainView::Unconfigured(ref view) => {
self.overlay.set_child(Some(view));
let modal = 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())
});
self.overlay.add_overlay(&modal);
*self.modal.borrow_mut() = Some(modal.upcast());
}
MainView::Historical(ref view) => self.overlay.set_child(Some(view)),
}
}
/// Use [modal] as a modal overlay of the application window.
fn open_modal(&self, modal: Modal) {
self.overlay.set_child(Some(&modal));
}
/// Close the modal by discarding the component.
fn close_modal(&self) {
let none: Option<&gtk::Widget> = None;
self.overlay.set_child(none);
}
}
fn main() {