From 56ff5527baf93c68fe54001dec1927e714e8bd8b Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Mon, 19 Feb 2024 09:49:20 -0500 Subject: [PATCH 1/3] Quit the application when the user clicks the header bar X --- fitnesstrax/app/src/app_window.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fitnesstrax/app/src/app_window.rs b/fitnesstrax/app/src/app_window.rs index 0a127c4..fcc1cdf 100644 --- a/fitnesstrax/app/src/app_window.rs +++ b/fitnesstrax/app/src/app_window.rs @@ -56,6 +56,10 @@ impl AppWindow { .width_request(800) .height_request(746) .build(); + window.connect_destroy({ + let adw_app = adw_app.clone(); + move |_| adw_app.quit() + }); let stylesheet = String::from_utf8( resources_lookup_data( -- 2.44.1 From c14b20b79e8cc6cc8259a7711c0613d969b99872 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Mon, 19 Feb 2024 11:58:01 -0500 Subject: [PATCH 2/3] Set up an application quit action group This ties together a menu item, closing the main window, and Ctrl-Q into the same action, which is to quit the application. --- fitnesstrax/app/src/app_window.rs | 19 +++++++++++++++---- fitnesstrax/app/src/main.rs | 10 ++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/fitnesstrax/app/src/app_window.rs b/fitnesstrax/app/src/app_window.rs index fcc1cdf..31a05c3 100644 --- a/fitnesstrax/app/src/app_window.rs +++ b/fitnesstrax/app/src/app_window.rs @@ -56,9 +56,8 @@ impl AppWindow { .width_request(800) .height_request(746) .build(); - window.connect_destroy({ - let adw_app = adw_app.clone(); - move |_| adw_app.quit() + window.connect_destroy(|s| { + let _ = gtk::prelude::WidgetExt::activate_action(s, "app.quit", None); }); let stylesheet = String::from_utf8( @@ -87,10 +86,22 @@ impl AppWindow { let initial_view = View::Placeholder(PlaceholderView::default().upcast()); + let header_bar = adw::HeaderBar::new(); + + let main_menu = gio::Menu::new(); + main_menu.append(Some("Quit"), Some("app.quit")); + let main_menu_button = gtk::MenuButton::builder() + .icon_name("open-menu") + .direction(gtk::ArrowType::Down) + .halign(gtk::Align::End) + .menu_model(&main_menu) + .build(); + header_bar.pack_end(&main_menu_button); + layout.append(&initial_view.widget()); let nav_layout = gtk::Box::new(gtk::Orientation::Vertical, 0); - nav_layout.append(&adw::HeaderBar::new()); + nav_layout.append(&header_bar); nav_layout.append(&layout); navigation.push( &adw::NavigationPage::builder() diff --git a/fitnesstrax/app/src/main.rs b/fitnesstrax/app/src/main.rs index bbad804..d03733b 100644 --- a/fitnesstrax/app/src/main.rs +++ b/fitnesstrax/app/src/main.rs @@ -25,6 +25,8 @@ mod views; use adw::prelude::*; use app_window::AppWindow; +use components::ActionGroup; +use gio::{Action, ActionEntry}; use std::{env, path::PathBuf}; const APP_ID_DEV: &str = "com.luminescent-dreams.fitnesstrax.dev"; @@ -65,6 +67,14 @@ fn main() { let icon_theme = gtk::IconTheme::for_display(&gdk::Display::default().unwrap()); icon_theme.add_resource_path(&(RESOURCE_BASE_PATH.to_owned() + "/icons/scalable/actions")); + let app_close_action = ActionEntry::builder("quit") + .activate(|app: &adw::Application, _, _| { + app.quit(); + }) + .build(); + adw_app.add_action_entries([app_close_action]); + adw_app.set_accels_for_action("app.quit", &["Q"]); + AppWindow::new(app_id, RESOURCE_BASE_PATH, adw_app, ft_app.clone()); }); -- 2.44.1 From aed473520912019a9926f60cb6a47e21415f0e54 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Mon, 19 Feb 2024 12:05:21 -0500 Subject: [PATCH 3/3] Add some documentation around the quit action --- fitnesstrax/app/src/main.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/fitnesstrax/app/src/main.rs b/fitnesstrax/app/src/main.rs index d03733b..921f708 100644 --- a/fitnesstrax/app/src/main.rs +++ b/fitnesstrax/app/src/main.rs @@ -34,6 +34,20 @@ const APP_ID_PROD: &str = "com.luminescent-dreams.fitnesstrax"; const RESOURCE_BASE_PATH: &str = "/com/luminescent-dreams/fitnesstrax/"; +/// Sets up an application-global action, `app.quit`, which will terminate the application. +fn setup_app_close_action(app: &adw::Application) { + let action = ActionEntry::builder("quit") + .activate(|app: &adw::Application, _, _| { + // right now, stopping the application is dirt simple. But we could use this + // block to add extra code that does additional shutdown steps if we ever want + // some states that shouldn't be discarded. + app.quit(); + }) + .build(); + app.add_action_entries([action]); + app.set_accels_for_action("app.quit", &["Q"]); +} + fn main() { // I still don't fully understand gio resources. resources_register_include! is convenient // because I don't have to deal with filesystem locations at runtime. However, I think other @@ -67,13 +81,7 @@ fn main() { let icon_theme = gtk::IconTheme::for_display(&gdk::Display::default().unwrap()); icon_theme.add_resource_path(&(RESOURCE_BASE_PATH.to_owned() + "/icons/scalable/actions")); - let app_close_action = ActionEntry::builder("quit") - .activate(|app: &adw::Application, _, _| { - app.quit(); - }) - .build(); - adw_app.add_action_entries([app_close_action]); - adw_app.set_accels_for_action("app.quit", &["Q"]); + setup_app_close_action(&adw_app); AppWindow::new(app_id, RESOURCE_BASE_PATH, adw_app, ft_app.clone()); }); -- 2.44.1