Compare commits
8 Commits
56a8133dd5
...
1d8653a0f5
Author | SHA1 | Date |
---|---|---|
Savanni D'Gerinel | 1d8653a0f5 | |
Savanni D'Gerinel | d0cb3e3b19 | |
Savanni D'Gerinel | e2850e3427 | |
Savanni D'Gerinel | 81ec202abf | |
Savanni D'Gerinel | 504780855c | |
Savanni D'Gerinel | acdf9ec150 | |
Savanni D'Gerinel | 0ebdcd7c2a | |
Savanni D'Gerinel | baf652173c |
|
@ -27,7 +27,7 @@ use std::{
|
|||
env,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use ui::{welcome_modal, Modal};
|
||||
use ui::welcome_modal;
|
||||
|
||||
const APP_ID_DEV: &str = "com.luminescent-dreams.fitnesstrax.dev";
|
||||
const APP_ID_PROD: &str = "com.luminescent-dreams.fitnesstrax";
|
||||
|
@ -48,6 +48,8 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
/// This is the view to show if the application has not yet been configured. It will walk the user
|
||||
/// through the most critical setup steps so that we can move on to the other views in the app.
|
||||
pub struct UnconfiguredViewPrivate {}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -73,14 +75,19 @@ impl UnconfiguredView {
|
|||
pub fn new() -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
|
||||
// Replace this with the welcome screen that we set up in the fitnesstrax/unconfigured-page
|
||||
// branch.
|
||||
let label = gtk::Label::builder()
|
||||
.label("Database is not configured.")
|
||||
.label("Welcome to FitnessTrax")
|
||||
.build();
|
||||
s.append(&label);
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
/// The historical view will show a window into the main database. It will show some version of
|
||||
/// daily summaries, daily details, and will provide all functions the user may need for editing
|
||||
/// records.
|
||||
pub struct HistoricalViewPrivate {}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -114,43 +121,13 @@ impl HistoricalView {
|
|||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
/// These are the possible states of the main application view.
|
||||
enum MainView {
|
||||
/// The application is not configured yet. This is a basic background widget to take up the
|
||||
/// space when there is no data to be shown.
|
||||
Unconfigured(UnconfiguredView),
|
||||
|
||||
/// The Historical view shows a history of records and whatnot.
|
||||
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. Almost
|
||||
/// everything occurs here.
|
||||
struct AppWindow {
|
||||
app: App,
|
||||
window: adw::ApplicationWindow,
|
||||
overlay: gtk::Overlay,
|
||||
|
||||
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>>,
|
||||
layout: gtk::Box,
|
||||
current_view: RefCell<gtk::Widget>,
|
||||
}
|
||||
|
||||
impl AppWindow {
|
||||
|
@ -167,38 +144,10 @@ impl AppWindow {
|
|||
.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)
|
||||
UnconfiguredView::new().upcast()
|
||||
} 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),
|
||||
HistoricalView::new().upcast()
|
||||
};
|
||||
|
||||
let stylesheet = String::from_utf8(
|
||||
|
@ -217,53 +166,38 @@ impl AppWindow {
|
|||
let context = window.style_context();
|
||||
context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
let header = adw::HeaderBar::builder()
|
||||
.title_widget(>k::Label::new(Some("FitnessTrax")))
|
||||
.build();
|
||||
|
||||
let layout = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.build();
|
||||
layout.append(&header);
|
||||
layout.append(¤t_view);
|
||||
|
||||
window.set_content(Some(&layout));
|
||||
window.present();
|
||||
|
||||
s.redraw();
|
||||
|
||||
s
|
||||
|
||||
/*
|
||||
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.
|
||||
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())
|
||||
}));
|
||||
|
||||
MainView::Unconfigured(view)
|
||||
} else {
|
||||
let view = HistoricalView::new();
|
||||
overlay.set_child(Some(&view));
|
||||
|
||||
MainView::HistoricalView(view)
|
||||
let s = Self {
|
||||
app,
|
||||
window,
|
||||
layout,
|
||||
current_view: RefCell::new(current_view),
|
||||
};
|
||||
*/
|
||||
s
|
||||
}
|
||||
|
||||
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)),
|
||||
}
|
||||
// Switch views.
|
||||
//
|
||||
// This function only replaces the old view with the one which matches the current view state.
|
||||
// It is responsible for ensuring that the new view goes into the layout in the correct
|
||||
// position.
|
||||
fn change_view(&self, view: gtk::Widget) {
|
||||
let mut current_view = self.current_view.borrow_mut();
|
||||
self.layout.remove(&*current_view);
|
||||
*current_view = view;
|
||||
self.layout.append(&*current_view);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,11 +219,6 @@ fn main() {
|
|||
|
||||
println!("database path: {}", settings.string("series-path"));
|
||||
|
||||
let adw_app = adw::Application::builder()
|
||||
.application_id(app_id)
|
||||
.resource_base_path(RESOURCE_BASE_PATH)
|
||||
.build();
|
||||
|
||||
let app = App::new();
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue