diff --git a/fitnesstrax/app/src/main.rs b/fitnesstrax/app/src/main.rs index c67024e..3eb3bc9 100644 --- a/fitnesstrax/app/src/main.rs +++ b/fitnesstrax/app/src/main.rs @@ -25,6 +25,8 @@ use gtk::{subclass::prelude::*, STYLE_PROVIDER_PRIORITY_USER}; use std::{ cell::RefCell, env, + path::PathBuf, + rc::Rc, sync::{Arc, RwLock}, }; use ui::FileChooserRow; @@ -72,7 +74,10 @@ glib::wrapper! { } impl WelcomeView { - pub fn new() -> Self { + pub fn new(on_save: F) -> Self + where + F: Fn(PathBuf) + 'static, + { let s: Self = Object::builder().build(); s.set_orientation(gtk::Orientation::Vertical); s.set_css_classes(&["modal"]); @@ -83,7 +88,6 @@ impl WelcomeView { .label("Welcome to FitnessTrax") .css_classes(["modal-title"]) .build(); - s.append(&title); let content = gtk::Box::builder() .css_classes(["model-content"]) @@ -91,17 +95,34 @@ impl WelcomeView { .vexpand(true) .build(); - content.append(>k::Label::new(Some("Welcome to FitnessTrax. The application has not yet been configured, so I will walk you through that. Let's start out by selecting your database."))); + let save_button = gtk::Button::builder() + .label("Save Settings") + .sensitive(false) + .build(); // The database selection row should be a box that shows a default database path, along with a // button that triggers a file chooser dialog. Once the dialog returns, the box should be // updated to reflect the chosen path. - let db_row = FileChooserRow::new(); + let db_row = FileChooserRow::new({ + let save_button = save_button.clone(); + move |_| save_button.set_sensitive(true) + }); + content.append(>k::Label::new(Some("Welcome to FitnessTrax. The application has not yet been configured, so I will walk you through that. Let's start out by selecting your database."))); content.append(&db_row); + let on_save = Box::new(on_save); + save_button.connect_clicked({ + move |_| { + if let Some(path) = db_row.path() { + on_save(path) + } + } + }); + + s.append(&title); s.append(&content); - s.append(>k::Button::builder().label("Save Settings").build()); + s.append(&save_button); s } @@ -167,7 +188,7 @@ impl AppWindow { .build(); let current_view = if app.database.read().unwrap().is_none() { - WelcomeView::new().upcast() + WelcomeView::new(&|_| {}).upcast() } else { HistoricalView::new().upcast() }; diff --git a/fitnesstrax/app/src/ui/mod.rs b/fitnesstrax/app/src/ui/mod.rs index 662d1e1..fef79fb 100644 --- a/fitnesstrax/app/src/ui/mod.rs +++ b/fitnesstrax/app/src/ui/mod.rs @@ -16,7 +16,11 @@ You should have received a copy of the GNU General Public License along with Fit use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; -use std::{cell::RefCell, path::PathBuf}; +use std::{ + cell::RefCell, + path::{Path, PathBuf}, + rc::Rc, +}; pub struct FileChooserRowPrivate { path: RefCell>, @@ -46,7 +50,10 @@ glib::wrapper! { } impl FileChooserRow { - pub fn new() -> Self { + pub fn new(on_selected: F) -> Self + where + F: Fn(PathBuf) + 'static, + { let s: Self = Object::builder().build(); s.set_orientation(gtk::Orientation::Horizontal); @@ -57,12 +64,14 @@ impl FileChooserRow { s.imp().label.set_text("No database selected"); let db_file_chooser_button = gtk::Button::builder().label("Select Database").build(); + let on_selected = Rc::new(Box::new(on_selected)); db_file_chooser_button.connect_clicked({ let s = s.clone(); move |_| { let no_window: Option<>k::Window> = None; let not_cancellable: Option<&gio::Cancellable> = None; let s = s.clone(); + let on_selected = on_selected.clone(); gtk::FileDialog::builder().build().open( no_window, not_cancellable, @@ -70,6 +79,7 @@ impl FileChooserRow { Ok(file_id) => match file_id.path() { Some(path) => { s.imp().label.set_text(path.to_str().unwrap()); + on_selected(path.clone()); *s.imp().path.borrow_mut() = Some(path); } None => { @@ -88,4 +98,8 @@ impl FileChooserRow { s } + + pub fn path(&self) -> Option { + self.imp().path.borrow().clone() + } }