diff --git a/fitnesstrax/app/Cargo.toml b/fitnesstrax/app/Cargo.toml index 470ecea..66f08ef 100644 --- a/fitnesstrax/app/Cargo.toml +++ b/fitnesstrax/app/Cargo.toml @@ -11,7 +11,7 @@ emseries = { path = "../../emseries" } ft-core = { path = "../core" } gio = { version = "0.18" } glib = { version = "0.18" } -gtk = { version = "0.7", package = "gtk4", features = [ "v4_8" ] } +gtk = { version = "0.7", package = "gtk4", features = [ "v4_10" ] } tokio = { version = "1.34", features = [ "full" ] } [build-dependencies] diff --git a/fitnesstrax/app/resources/style.css b/fitnesstrax/app/resources/style.css index e69de29..8870aa5 100644 --- a/fitnesstrax/app/resources/style.css +++ b/fitnesstrax/app/resources/style.css @@ -0,0 +1,21 @@ +.modal { + margin: 64px; + background-color: @view_bg_color; + border: 1px solid grey; + border-radius: 10px +} + +.modal-title { + font-size: larger; + padding: 8px; + background-color: @headerbar_bg_color; + border-bottom: 1px solid @headerbar_border_color; + border-radius: 10px 10px 0px 0px; +} + +.modal-content { + padding: 8px; +} + +.modal-footer { +} diff --git a/fitnesstrax/app/src/ui/modal.rs b/fitnesstrax/app/src/ui/modal.rs index ee5042c..e113815 100644 --- a/fitnesstrax/app/src/ui/modal.rs +++ b/fitnesstrax/app/src/ui/modal.rs @@ -22,7 +22,10 @@ impl ObjectSubclass for ModalPrivate { type ParentType = gtk::Box; fn new() -> Self { - let title = gtk::Label::builder().label("Modal").build(); + let title = gtk::Label::builder() + .label("Modal") + .css_classes(["modal-title"]) + .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(); @@ -30,6 +33,7 @@ impl ObjectSubclass for ModalPrivate { let footer = gtk::Box::builder() .orientation(gtk::Orientation::Horizontal) .hexpand(true) + .css_classes(["modal-footer"]) .build(); footer.append(&primary_action); @@ -56,11 +60,8 @@ glib::wrapper! { impl Modal { pub fn new() -> Self { let s: Self = Object::builder().build(); + s.set_css_classes(&["modal"]); - 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); @@ -76,6 +77,9 @@ impl Modal { pub fn set_content(&self, content: gtk::Widget) { self.remove(&*self.imp().content.borrow()); + content.add_css_class("modal-content"); + content.set_hexpand(true); + content.set_vexpand(true); self.insert_child_after(&content, Some(&self.imp().title)); *self.imp().content.borrow_mut() = content; } @@ -105,7 +109,10 @@ pub fn welcome_modal() -> Modal { .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."))); + let instructions = gtk::Label::builder() + .wrap(true) + .label("The application has not yet been configured, so I will walk you through that. Fortunately, it is very easy, and we only need to select the location for your database.").build(); + content.append(&instructions); // 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 @@ -113,13 +120,28 @@ pub fn welcome_modal() -> Modal { 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()); + + let db_file_label = gtk::Label::builder() + .label("No Path Selected") + .hexpand(true) + .build(); + + let db_file_chooser = gtk::Button::builder().label("Select Database").build(); + db_file_chooser.connect_clicked(|_| { + let no_window: Option<>k::Window> = None; + let not_cancellable: Option<&gio::Cancellable> = None; + gtk::FileDialog::builder() + .build() + .open(no_window, not_cancellable, |m_file_id| match m_file_id { + Ok(m_file_id) => println!("The user selected {:?}", m_file_id.path()), + Err(err) => println!("file opening failed: {}", err), + }); + }); + + db_row.append(&db_file_label); + db_row.append(&db_file_chooser); + + content.append(&db_row); modal.set_content(content.upcast()); modal.set_primary_action(gtk::Button::builder().label("Save Settings").build());