/* * SPDX-FileCopyrightText: 2017-2022 Bruce Cowan <bruce@bcowan.me.uk> * * SPDX-License-Identifier: GPL-3.0-or-later */ #include "config.h" #include "rugby-app-window.h" #include "rugby-list-store.h" #include "rugby-possibility.h" #include "rugby-possibility-widget.h" #include <glib/gi18n.h> struct _RugbyAppWindow { AdwApplicationWindow parent; GtkWidget *scorespin; GtkWidget *tryspin; GtkWidget *stack; GtkWidget *empty_page; GtkWidget *list_page; GtkCustomFilter *try_filter; }; G_DEFINE_TYPE (RugbyAppWindow, rugby_app_window, ADW_TYPE_APPLICATION_WINDOW) static void list_store_items_changed_cb ( GListModel *model, G_GNUC_UNUSED unsigned position, G_GNUC_UNUSED unsigned removed, G_GNUC_UNUSED unsigned added, RugbyAppWindow *self) { unsigned n_items = g_list_model_get_n_items (model); if (n_items == 0) gtk_stack_set_visible_child (GTK_STACK (self->stack), self->empty_page); else gtk_stack_set_visible_child (GTK_STACK (self->stack), self->list_page); } static char * item_tooltip_cb (GtkListItem *item) { RugbyPossibility *possibility = gtk_list_item_get_item (item); if (!possibility) return NULL; int tries, utries, kicks; GString *tooltip = g_string_new (NULL); g_object_get (possibility, "tries", &tries, "utries", &utries, "kicks", &kicks, NULL); if (tries > 0 && utries == 0) { g_string_printf (tooltip, ngettext ("%d converted try", "%d converted tries", tries), tries); } else if (utries > 0 && tries == 0) { g_string_printf (tooltip, ngettext ("%d unconverted try", "%d unconverted tries", utries), utries); } else if (tries + utries > 0) { g_string_printf (tooltip, ngettext ("%d try, %d converted", "%d tries, %d converted", tries + utries), tries + utries, tries); } if (kicks > 0) { if (tries > 0 || utries > 0) g_string_append_printf (tooltip, ", "); g_string_append_printf (tooltip, ngettext ("%d kick", "%d kicks", kicks), kicks); } 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 try_spin_value_changed_cb (G_GNUC_UNUSED GtkSpinButton *btn, gpointer user_data) { RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data); gtk_filter_changed (GTK_FILTER (self->try_filter), GTK_FILTER_CHANGE_DIFFERENT); } static void rugby_app_window_dispose (GObject *object) { gtk_widget_dispose_template (GTK_WIDGET (object), RUGBY_TYPE_APP_WINDOW); G_OBJECT_CLASS (rugby_app_window_parent_class)->dispose (object); } static gboolean try_filter_func (gpointer item, gpointer user_data) { RugbyPossibility *possibility = RUGBY_POSSIBILITY (item); RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data); int tries, utries; g_object_get (possibility, "tries", &tries, "utries", &utries, NULL); if ((tries + utries) == gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (self->tryspin))) return TRUE; return FALSE; } static void show_try_filter_change_state (GSimpleAction *action, GVariant *value, gpointer user_data) { RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data); if (g_variant_get_boolean (value)) { gtk_custom_filter_set_filter_func (self->try_filter, try_filter_func, self, NULL); gtk_filter_changed (GTK_FILTER (self->try_filter), GTK_FILTER_CHANGE_DIFFERENT); } else { gtk_custom_filter_set_filter_func (self->try_filter, NULL, NULL, NULL); } g_simple_action_set_state (action, value); } static void rugby_app_window_init (RugbyAppWindow *self) { gtk_widget_init_template (GTK_WIDGET (self)); const GActionEntry win_entries[] = { { .name = "score-changed", .activate = activate_score_changed, .parameter_type = "s" }, { .name = "show-try-filter", .state = "false", .change_state = show_try_filter_change_state }, }; g_action_map_add_action_entries (G_ACTION_MAP (self), win_entries, G_N_ELEMENTS (win_entries), self); } static void rugby_app_window_class_init (RugbyAppWindowClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); g_type_ensure (RUGBY_TYPE_POSSIBILITY_WIDGET); g_type_ensure (RUGBY_TYPE_LIST_STORE); object_class->dispose = rugby_app_window_dispose; gtk_widget_class_set_template_from_resource (widget_class, "/uk/me/bcowan/Rugby/gtk/window.ui"); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, scorespin); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, tryspin); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, stack); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, empty_page); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, list_page); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, try_filter); gtk_widget_class_bind_template_callback (widget_class, try_spin_value_changed_cb); gtk_widget_class_bind_template_callback (widget_class, item_tooltip_cb); gtk_widget_class_bind_template_callback (widget_class, list_store_items_changed_cb); } RugbyAppWindow * rugby_app_window_new (GtkApplication *app) { return g_object_new (RUGBY_TYPE_APP_WINDOW, "application", app, NULL); }