diff --git a/fitnesstrax/app/src/main.rs b/fitnesstrax/app/src/main.rs index a5a7683..64fb4e1 100644 --- a/fitnesstrax/app/src/main.rs +++ b/fitnesstrax/app/src/main.rs @@ -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, + + // We have to keep around a reference to the modal so that we know what to remove from the + // overlay. + modal: RefCell>, } 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<>k::Widget> = None; - self.overlay.set_child(none); - } } fn main() {