diff --git a/fitnesstrax/app/src/main.rs b/fitnesstrax/app/src/main.rs index 570c7c9..1a431a6 100644 --- a/fitnesstrax/app/src/main.rs +++ b/fitnesstrax/app/src/main.rs @@ -1,5 +1,7 @@ +use adw::prelude::*; use gio::resources_lookup_data; -use gtk::{prelude::*, STYLE_PROVIDER_PRIORITY_USER}; +use glib::Object; +use gtk::{prelude::*, subclass::prelude::*, STYLE_PROVIDER_PRIORITY_USER}; use std::env; const APP_ID_DEV: &str = "com.luminescent-dreams.fitnesstrax.dev"; @@ -9,8 +11,101 @@ const RESOURCE_BASE_PATH: &str = "/com/luminescent-dreams/fitnesstrax/"; struct AppState {} +pub struct NoDatabaseViewPrivate {} + +#[glib::object_subclass] +impl ObjectSubclass for NoDatabaseViewPrivate { + const NAME: &'static str = "NoDatabaseView"; + type Type = NoDatabaseView; + type ParentType = gtk::Box; + + fn new() -> Self { + Self {} + } +} + +impl ObjectImpl for NoDatabaseViewPrivate {} +impl WidgetImpl for NoDatabaseViewPrivate {} +impl BoxImpl for NoDatabaseViewPrivate {} + +glib::wrapper! { + pub struct NoDatabaseView(ObjectSubclass) @extends gtk::Box, gtk::Widget; +} + +impl NoDatabaseView { + pub fn new() -> Self { + let s: Self = Object::builder().build(); + + let label = gtk::Label::builder() + .label("Database is not configured.") + .build(); + s.append(&label); + s + } +} + +// window setup... +// main window with all of its layout +// modals that overlay atop the main window and capture focus +// menus +// There is more than one view for the main window. There's the view for data entry, then another +// view for showing graphs. Then a third view, or maybe a modal, for editing a day. +// +// So, the ordinary data view is the history the metrics, and the calendar. Scrollable, and items +// within the scrolling area can be clicked upon in order to open the edit. +// +// I don't need to model the whole thing at once. The graphs will be some time out, and so I can +// model just the main view, which consists of metrics, the data, and the calendar. Day entries +// should be summaries of the day, expandable to the details. +// +// Then there is the view which notifies the user that the database has not been configured. + +enum MainView { + NoDatabase(NoDatabaseView), +} + struct AppWindow { window: adw::ApplicationWindow, + current_view: MainView, +} + +impl AppWindow { + fn new(app: &adw::Application) -> AppWindow { + let stylesheet = String::from_utf8( + resources_lookup_data( + &format!("{}style.css", RESOURCE_BASE_PATH), + gio::ResourceLookupFlags::NONE, + ) + .expect("stylesheet must be available in the resources") + .to_vec(), + ) + .expect("to parse stylesheet"); + + let provider = gtk::CssProvider::new(); + provider.load_from_data(&stylesheet); + + let window = adw::ApplicationWindow::builder() + .application(app) + .width_request(800) + .height_request(600) + .build(); + + let context = window.style_context(); + context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER); + + window.present(); + + let current_view = { + let view = NoDatabaseView::new(); + window.set_content(Some(&view)); + MainView::NoDatabase(view) + }; + + Self { + window, + current_view, + } + } } fn main() { @@ -49,24 +144,7 @@ fn main() { .build(); app.connect_activate(move |app| { - let stylesheet = String::from_utf8( - resources_lookup_data( - &format!("{}style.css", RESOURCE_BASE_PATH), - gio::ResourceLookupFlags::NONE, - ) - .expect("stylesheet must be available in the resources") - .to_vec(), - ) - .expect("to parse stylesheet"); - - let provider = gtk::CssProvider::new(); - provider.load_from_data(&stylesheet); - - let window = adw::ApplicationWindow::new(app); - let context = window.style_context(); - context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER); - - window.present(); + AppWindow::new(app); }); let args: Vec = env::args().collect();