From 9e7350b08713a66c2e5e4cb6214aae742b65e7e8 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Mon, 19 Feb 2024 18:41:38 -0500 Subject: [PATCH] Add an about page that calls out gtk-rs and the GUI development book --- fitnesstrax/app/resources/style.css | 8 +++ fitnesstrax/app/src/about.rs | 80 +++++++++++++++++++++++++++++ fitnesstrax/app/src/app_window.rs | 1 + fitnesstrax/app/src/main.rs | 13 ++++- 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 fitnesstrax/app/src/about.rs diff --git a/fitnesstrax/app/resources/style.css b/fitnesstrax/app/resources/style.css index b7c7dec..55916f5 100644 --- a/fitnesstrax/app/resources/style.css +++ b/fitnesstrax/app/resources/style.css @@ -74,4 +74,12 @@ .step-view { padding: 8px; margin: 8px; +} + +.about__content { + padding: 32px; +} + +.about label { + margin-bottom: 16px; } \ No newline at end of file diff --git a/fitnesstrax/app/src/about.rs b/fitnesstrax/app/src/about.rs new file mode 100644 index 0000000..73f85c3 --- /dev/null +++ b/fitnesstrax/app/src/about.rs @@ -0,0 +1,80 @@ +/* +Copyright 2023 - 2024, Savanni D'Gerinel + +This file is part of FitnessTrax. + +FitnessTrax is free software: you can redistribute it and/or modify it under the terms of the GNU +General Public License as published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +FitnessTrax is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see . +*/ + +use glib::Object; +use gtk::{prelude::*, subclass::prelude::*}; + +#[derive(Default)] +pub struct AboutWindowPrivate {} + +#[glib::object_subclass] +impl ObjectSubclass for AboutWindowPrivate { + const NAME: &'static str = "AboutWindow"; + type Type = AboutWindow; + type ParentType = gtk::Window; +} + +impl ObjectImpl for AboutWindowPrivate {} +impl WidgetImpl for AboutWindowPrivate {} +impl WindowImpl for AboutWindowPrivate {} + +glib::wrapper! { + pub struct AboutWindow(ObjectSubclass) @extends gtk::Window, gtk::Widget; +} + +impl Default for AboutWindow { + fn default() -> Self { + let s: Self = Object::builder().build(); + s.set_width_request(600); + s.set_height_request(700); + s.add_css_class("about"); + + s.set_title(Some("About Fitnesstrax")); + let copyright = gtk::Label::builder() + .label("Copyright 2023-2024, Savanni D'Gerinel ") + .halign(gtk::Align::Start) + .build(); + + let gtk_rs_thanks = gtk::Label::builder() + .label("I owe a huge debt of gratitude to the GTK-RS project (https://gtk-rs.org/), which makes it possible for me to write this application to begin with. Further, I owe a particular debt to Julian Hofer and his book, GUI development with Rust and GTK 4 (https://gtk-rs.org/gtk4-rs/stable/latest/book/). Without this book, I would have continued to stumble around writing bad user interfaces with even worse code.") + .halign(gtk::Align::Start).wrap(true) + .build(); + + let dependencies = gtk::Label::builder() + .label("This application depends on many libraries, most of which are licensed under the BSD-3 or GPL-3 licenses.") + .halign(gtk::Align::Start).wrap(true) + .build(); + + let content = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .css_classes(["about__content"]) + .build(); + content.append(©right); + content.append(>k_rs_thanks); + content.append(&dependencies); + + let scroller = gtk::ScrolledWindow::builder() + .child(&content) + .hexpand(true) + .vexpand(true) + .hscrollbar_policy(gtk::PolicyType::Never) + .build(); + + s.set_child(Some(&scroller)); + + s + } +} diff --git a/fitnesstrax/app/src/app_window.rs b/fitnesstrax/app/src/app_window.rs index 3bdd4a4..81a9eb9 100644 --- a/fitnesstrax/app/src/app_window.rs +++ b/fitnesstrax/app/src/app_window.rs @@ -89,6 +89,7 @@ impl AppWindow { let header_bar = adw::HeaderBar::new(); let main_menu = gio::Menu::new(); + main_menu.append(Some("About"), Some("app.about")); main_menu.append(Some("Quit"), Some("app.quit")); let main_menu_button = gtk::MenuButton::builder() .icon_name("open-menu") diff --git a/fitnesstrax/app/src/main.rs b/fitnesstrax/app/src/main.rs index b6ca965..98a8cc2 100644 --- a/fitnesstrax/app/src/main.rs +++ b/fitnesstrax/app/src/main.rs @@ -1,5 +1,5 @@ /* -Copyright 2023, Savanni D'Gerinel +Copyright 2023 - 2024, Savanni D'Gerinel This file is part of FitnessTrax. @@ -14,6 +14,7 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see . */ +mod about; mod app; mod app_window; mod components; @@ -33,6 +34,15 @@ const APP_ID_PROD: &str = "com.luminescent-dreams.fitnesstrax"; const RESOURCE_BASE_PATH: &str = "/com/luminescent-dreams/fitnesstrax/"; +fn setup_app_about_action(app: &adw::Application) { + let action = ActionEntry::builder("about") + .activate(|app: &adw::Application, _, _| { + let window = about::AboutWindow::default(); + window.present(); + }).build(); + app.add_action_entries([action]); +} + /// 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") @@ -80,6 +90,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")); + setup_app_about_action(adw_app); setup_app_close_action(adw_app); AppWindow::new(app_id, RESOURCE_BASE_PATH, adw_app, ft_app.clone());