diff --git a/fitnesstrax/app/src/ui/modal.rs b/fitnesstrax/app/src/ui/modal.rs index a8ce309..ee5042c 100644 --- a/fitnesstrax/app/src/ui/modal.rs +++ b/fitnesstrax/app/src/ui/modal.rs @@ -8,9 +8,11 @@ use std::cell::RefCell; pub struct ModalPrivate { title: gtk::Label, content: RefCell, - primary_action: gtk::Button, - secondary_action: Option, - tertiary_action: Option, + primary_action: RefCell, + secondary_action: RefCell>, + tertiary_action: RefCell>, + + footer: gtk::Box, } #[glib::object_subclass] @@ -23,13 +25,22 @@ impl ObjectSubclass for ModalPrivate { let title = gtk::Label::builder().label("Modal").build(); let content = gtk::Box::new(gtk::Orientation::Vertical, 0); let actions = gtk::Box::new(gtk::Orientation::Horizontal, 0); + let primary_action = gtk::Button::builder().label("Primary").build(); + + let footer = gtk::Box::builder() + .orientation(gtk::Orientation::Horizontal) + .hexpand(true) + .build(); + footer.append(&primary_action); Self { title, content: RefCell::new(content.upcast()), - primary_action: gtk::Button::new(), - secondary_action: None, - tertiary_action: None, + primary_action: RefCell::new(primary_action), + secondary_action: RefCell::new(None), + tertiary_action: RefCell::new(None), + + footer, } } } @@ -39,16 +50,22 @@ impl WidgetImpl for ModalPrivate {} impl BoxImpl for ModalPrivate {} glib::wrapper! { - pub struct Modal(ObjectSubclass) @extends gtk::Box, gtk::Widget; + pub struct Modal(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; } impl Modal { pub fn new() -> Self { let s: Self = Object::builder().build(); + s.set_margin_start(100); + s.set_margin_end(100); + s.set_margin_top(100); + s.set_margin_bottom(100); + s.set_orientation(gtk::Orientation::Vertical); + s.append(&s.imp().title); s.append(&*s.imp().content.borrow()); - // s.append(&s.imp().actions); + s.append(&s.imp().footer); s } @@ -62,6 +79,16 @@ impl Modal { self.insert_child_after(&content, Some(&self.imp().title)); *self.imp().content.borrow_mut() = content; } + + pub fn set_primary_action(&self, action: gtk::Button) { + self.imp() + .footer + .remove(&*self.imp().primary_action.borrow()); + *self.imp().primary_action.borrow_mut() = action; + self.imp() + .footer + .append(&*self.imp().primary_action.borrow()); + } } /// The welcome modal is the first thing the user will see when FitnessTrax starts up if the @@ -71,5 +98,30 @@ impl Modal { pub fn welcome_modal() -> Modal { let modal = Modal::new(); modal.set_title("Welcome to FitnessTrax"); + + // The content should be a friendly dialog that explains to the user that they're going to set + // up the database. + let content = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .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."))); + + // 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 = gtk::Box::builder() + .orientation(gtk::Orientation::Horizontal) + .build(); + db_row.append( + >k::Label::builder() + .label("No Path Selected") + .hexpand(true) + .build(), + ); + db_row.append(>k::Button::builder().label("Select Database").build()); + + modal.set_content(content.upcast()); + modal.set_primary_action(gtk::Button::builder().label("Save Settings").build()); modal }