From 4ca5ac0e8d47a65220ac966e6a7e8a517f506e64 Mon Sep 17 00:00:00 2001 From: Bruce Cowan <bruce@bcowan.me.uk> Date: Sun, 2 Oct 2022 17:02:21 +0100 Subject: [PATCH] Add keyboard shortcuts --- data/gtk/help-overlay.blp | 32 ++++++++++++++++++++++++++++ data/meson.build | 1 + data/rugby.gresource.xml | 3 ++- data/window.blp | 6 +++--- src/main.c | 12 +++++++++++ src/rugby-app-window.c | 45 ++++++++++++++++++++++++++++++++++++++- src/rugby-pref-window.c | 2 +- 7 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 data/gtk/help-overlay.blp diff --git a/data/gtk/help-overlay.blp b/data/gtk/help-overlay.blp new file mode 100644 index 0000000..633ef9a --- /dev/null +++ b/data/gtk/help-overlay.blp @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2022 Bruce Cowan <bruce@bcowan.me.uk> +// +// SPDX-License-Identifier: GPL-3.0-or-later + +using Gtk 4.0; + +ShortcutsWindow help_overlay { + ShortcutsSection { + ShortcutsGroup { + title: "Application"; + + ShortcutsShortcut { + title: "Preferences"; + action-name: "app.prefs"; + } + } + + ShortcutsGroup { + title: "Score"; + + ShortcutsShortcut { + title: "Increment score"; + action-name: "win.score-changed::up"; + } + + ShortcutsShortcut { + title: "Decrement score"; + action-name: "win.score-changed::down"; + } + } + } +} diff --git a/data/meson.build b/data/meson.build index 2632f11..fd78f0c 100644 --- a/data/meson.build +++ b/data/meson.build @@ -4,6 +4,7 @@ blueprints = custom_target('blueprints', input: files( + 'gtk/help-overlay.blp', 'prefs.blp', 'window.blp' ), diff --git a/data/rugby.gresource.xml b/data/rugby.gresource.xml index 1c63d2e..eb97f5f 100644 --- a/data/rugby.gresource.xml +++ b/data/rugby.gresource.xml @@ -5,7 +5,8 @@ SPDX-License-Identifier: GPL-3.0-or-later --> <gresources> - <gresource prefix="/uk/me/bcowan/rugby"> + <gresource prefix="/uk/me/bcowan/Rugby"> + <file preprocess="xml-stripblanks" compressed="true">gtk/help-overlay.ui</file> <file preprocess="xml-stripblanks" compressed="true">prefs.ui</file> <file preprocess="xml-stripblanks" compressed="true">score-item.ui</file> <file preprocess="xml-stripblanks" compressed="true">window.ui</file> diff --git a/data/window.blp b/data/window.blp index bba80b1..6c68051 100644 --- a/data/window.blp +++ b/data/window.blp @@ -27,6 +27,7 @@ template RugbyAppWindow : Adw.ApplicationWindow { MenuButton menu_button { direction: none; menu-model: app_menu; + tooltip-text: "Main Menu"; } } @@ -45,7 +46,7 @@ template RugbyAppWindow : Adw.ApplicationWindow { }; }; factory: BuilderListItemFactory { - resource: "/uk/me/bcowan/rugby/score-item.ui"; + resource: "/uk/me/bcowan/Rugby/score-item.ui"; }; } } @@ -56,8 +57,7 @@ template RugbyAppWindow : Adw.ApplicationWindow { menu app_menu { section { item ("_Preferences", "app.prefs") - } - section { + item ("_Keyboard Shortcuts", "win.show-help-overlay") item ("_About Rugby", "app.about") } } diff --git a/src/main.c b/src/main.c index 5b992ab..081eb62 100644 --- a/src/main.c +++ b/src/main.c @@ -68,6 +68,18 @@ on_startup (GApplication *app, app_entries, G_N_ELEMENTS (app_entries), app); + gtk_application_set_accels_for_action (GTK_APPLICATION (app), + "win.show-primary-menu", + (const char*[]) { "F10", NULL }); + gtk_application_set_accels_for_action (GTK_APPLICATION (app), + "app.prefs", + (const char*[]) { "<Ctrl>comma", NULL }); + gtk_application_set_accels_for_action (GTK_APPLICATION (app), + "win.score-changed::up", + (const char*[]) { "<Ctrl>Up", "<Ctrl>Right", NULL }); + gtk_application_set_accels_for_action (GTK_APPLICATION (app), + "win.score-changed::down", + (const char*[]) { "<Ctrl>Down", "<Ctrl>Left", NULL }); } int diff --git a/src/rugby-app-window.c b/src/rugby-app-window.c index 1db5220..d9ec1f2 100644 --- a/src/rugby-app-window.c +++ b/src/rugby-app-window.c @@ -15,6 +15,9 @@ struct _RugbyAppWindow { AdwApplicationWindow parent; + + GtkWidget *scorespin; + GtkWidget *menu_button; }; G_DEFINE_TYPE (RugbyAppWindow, rugby_app_window, ADW_TYPE_APPLICATION_WINDOW) @@ -70,10 +73,47 @@ item_tooltip_cb (GtkListItem *item) return g_string_free (tooltip, FALSE); } +static void +activate_score_changed (G_GNUC_UNUSED GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data); + + double current_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (self->scorespin)); + const char *direction = g_variant_get_string (parameter, NULL); + + if (g_strcmp0 (direction, "up") == 0) + gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->scorespin), current_value + 1.0); + else if (g_strcmp0 (direction, "down") == 0) + gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->scorespin), current_value - 1.0); + else + g_assert_not_reached (); +} + +static void +activate_show_primary_menu (G_GNUC_UNUSED GSimpleAction *action, + G_GNUC_UNUSED GVariant *parameter, + gpointer user_data) +{ + RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data); + gtk_menu_button_popup (GTK_MENU_BUTTON (self->menu_button)); +} + +const GActionEntry win_entries[] = { + { .name = "score-changed", .activate = activate_score_changed, .parameter_type = "s" }, + { .name = "show-primary-menu", .activate = activate_show_primary_menu }, +}; + static void rugby_app_window_init (RugbyAppWindow *self) { gtk_widget_init_template (GTK_WIDGET (self)); + + g_action_map_add_action_entries (G_ACTION_MAP (self), + win_entries, + G_N_ELEMENTS (win_entries), + self); } static void @@ -85,7 +125,10 @@ rugby_app_window_class_init (RugbyAppWindowClass *klass) g_type_ensure (RUGBY_TYPE_LIST_STORE); gtk_widget_class_set_template_from_resource (widget_class, - "/uk/me/bcowan/rugby/window.ui"); + "/uk/me/bcowan/Rugby/window.ui"); + + gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, scorespin); + gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, menu_button); gtk_widget_class_bind_template_callback (widget_class, item_tooltip_cb); } diff --git a/src/rugby-pref-window.c b/src/rugby-pref-window.c index 4234710..79b0b08 100644 --- a/src/rugby-pref-window.c +++ b/src/rugby-pref-window.c @@ -38,7 +38,7 @@ rugby_pref_window_class_init (RugbyPrefWindowClass *klass) object_class->dispose = rugby_pref_window_dispose; gtk_widget_class_set_template_from_resource (widget_class, - "/uk/me/bcowan/rugby/prefs.ui"); + "/uk/me/bcowan/Rugby/prefs.ui"); gtk_widget_class_bind_template_child (widget_class, RugbyPrefWindow, try_spin); gtk_widget_class_bind_template_child (widget_class, RugbyPrefWindow, utry_spin); -- GitLab