Skip to content
Snippets Groups Projects
rugby-app-window.c 7.27 KiB
Newer Older
Bruce Cowan's avatar
Bruce Cowan committed
/*
Bruce Cowan's avatar
Bruce Cowan committed
 * SPDX-FileCopyrightText: 2017-2023 Bruce Cowan <bruce@bcowan.me.uk>
 * SPDX-License-Identifier: GPL-3.0-or-later
Bruce Cowan's avatar
Bruce Cowan committed
#include "config.h"
Bruce Cowan's avatar
Bruce Cowan committed
#include "rugby-app-window.h"
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
#include "rugby-list-store.h"
Bruce Cowan's avatar
Bruce Cowan committed
#include "rugby-possibility.h"
Bruce Cowan's avatar
Bruce Cowan committed
#include "rugby-possibility-widget.h"

#include <glib/gi18n.h>
Bruce Cowan's avatar
Bruce Cowan committed

struct _RugbyAppWindow
{
    AdwApplicationWindow parent;
Bruce Cowan's avatar
Bruce Cowan committed

    GtkWidget *scorespin;
Bruce Cowan's avatar
Bruce Cowan committed
    GtkWidget *tryspin;
Bruce Cowan's avatar
Bruce Cowan committed
    GtkWidget *stack;
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
    GSettings *win_settings;

Bruce Cowan's avatar
Bruce Cowan committed
    GtkCustomFilter *try_filter;
G_DEFINE_TYPE (RugbyAppWindow, rugby_app_window, ADW_TYPE_APPLICATION_WINDOW)
Bruce Cowan's avatar
Bruce Cowan committed
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_name (GTK_STACK (self->stack), "empty_page");
Bruce Cowan's avatar
Bruce Cowan committed
    else
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "list_page");
Bruce Cowan's avatar
Bruce Cowan committed
static char *
item_tooltip_cb (GtkListItem *item)
Bruce Cowan's avatar
Bruce Cowan committed
    RugbyPossibility *possibility = gtk_list_item_get_item (item);
Bruce Cowan's avatar
Bruce Cowan committed
    if (!possibility)
      return NULL;
Bruce Cowan's avatar
Bruce Cowan committed

    int tries, utries, kicks;
    GString *tooltip = g_string_new (NULL);

    g_object_get (possibility,
                  "tries", &tries,
                  "utries", &utries,
                  "kicks", &kicks,
                  NULL);

Bruce Cowan's avatar
Bruce Cowan committed
    if (tries > 0 && utries == 0)
Bruce Cowan's avatar
Bruce Cowan committed
    {
Bruce Cowan's avatar
Bruce Cowan committed
        g_string_printf (tooltip, ngettext ("%d converted try",
                                            "%d converted tries",
                                            tries),
                         tries);
Bruce Cowan's avatar
Bruce Cowan committed
    }
Bruce Cowan's avatar
Bruce Cowan committed
    else if (utries > 0 && tries == 0)
Bruce Cowan's avatar
Bruce Cowan committed
    {
Bruce Cowan's avatar
Bruce Cowan committed
        g_string_printf (tooltip, ngettext ("%d unconverted try",
                                            "%d unconverted tries",
                                            utries),
                         utries);
    }
    else if (tries + utries > 0)
    {
Bruce Cowan's avatar
Bruce Cowan committed
        g_string_printf (tooltip, ngettext ("%d try (%d converted)",
                                            "%d tries (%d converted)",
Bruce Cowan's avatar
Bruce Cowan committed
                                            tries + utries),
                         tries + utries, tries);
    }

    if (kicks > 0)
    {
        if (tries > 0 || utries > 0)
Bruce Cowan's avatar
Bruce Cowan committed
            g_string_append_printf (tooltip, " and ");
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
        g_string_append_printf (tooltip,
Bruce Cowan's avatar
Bruce Cowan committed
                                ngettext ("%d kick", "%d kicks", kicks),
Bruce Cowan's avatar
Bruce Cowan committed
                                kicks);
    }

    return g_string_free (tooltip, FALSE);
Bruce Cowan's avatar
Bruce Cowan committed
static void
activate_score_changed (G_GNUC_UNUSED GSimpleAction *action,
                                      GVariant      *parameter,
Bruce Cowan's avatar
Bruce Cowan committed
                                      void          *user_data)
Bruce Cowan's avatar
Bruce Cowan committed
{
    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 ();
}

Bruce Cowan's avatar
Bruce Cowan committed
static void
try_spin_value_changed_cb (G_GNUC_UNUSED GtkSpinButton *btn,
Bruce Cowan's avatar
Bruce Cowan committed
                                         void          *user_data)
Bruce Cowan's avatar
Bruce Cowan committed
{
    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);
Bruce Cowan's avatar
Bruce Cowan committed
    g_clear_object (&RUGBY_APP_WINDOW (object)->win_settings);

    G_OBJECT_CLASS (rugby_app_window_parent_class)->dispose (object);
}

Bruce Cowan's avatar
Bruce Cowan committed
static gboolean
Bruce Cowan's avatar
Bruce Cowan committed
try_filter_func (void *item,
                 void *user_data)
Bruce Cowan's avatar
Bruce Cowan committed
{
    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,
Bruce Cowan's avatar
Bruce Cowan committed
                              void          *user_data)
Bruce Cowan's avatar
Bruce Cowan committed
{
    RugbyAppWindow *self = RUGBY_APP_WINDOW (user_data);

    if (g_variant_get_boolean (value))
Bruce Cowan's avatar
Bruce Cowan committed
    {
        gtk_custom_filter_set_filter_func (self->try_filter, try_filter_func, self, NULL);
Bruce Cowan's avatar
Bruce Cowan committed
        gtk_filter_changed (GTK_FILTER (self->try_filter), GTK_FILTER_CHANGE_MORE_STRICT);
Bruce Cowan's avatar
Bruce Cowan committed
    }
    else
    {
        gtk_custom_filter_set_filter_func (self->try_filter, NULL, NULL, NULL);
Bruce Cowan's avatar
Bruce Cowan committed
        gtk_filter_changed (GTK_FILTER (self->try_filter), GTK_FILTER_CHANGE_LESS_STRICT);
Bruce Cowan's avatar
Bruce Cowan committed
    }

    g_simple_action_set_state (action, value);
Bruce Cowan's avatar
Bruce Cowan committed
}

Bruce Cowan's avatar
Bruce Cowan committed
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 },
Bruce Cowan's avatar
Bruce Cowan committed
    g_action_map_add_action_entries (G_ACTION_MAP (self),
                                     win_entries,
                                     G_N_ELEMENTS (win_entries),
                                     self);
Bruce Cowan's avatar
Bruce Cowan committed

    self->win_settings = g_settings_new ("uk.me.bcowan.Rugby.window");
    g_settings_bind (self->win_settings, "height",
                     self, "default-height",
                     G_SETTINGS_BIND_DEFAULT);
    g_settings_bind (self->win_settings, "width",
                     self, "default-width",
                     G_SETTINGS_BIND_DEFAULT);
Bruce Cowan's avatar
Bruce Cowan committed
}

static void
rugby_app_window_class_init (RugbyAppWindowClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
Bruce Cowan's avatar
Bruce Cowan committed
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

Bruce Cowan's avatar
Bruce Cowan committed
    g_type_ensure (RUGBY_TYPE_POSSIBILITY_WIDGET);
    g_type_ensure (RUGBY_TYPE_LIST_STORE);
    object_class->dispose = rugby_app_window_dispose;

Bruce Cowan's avatar
Bruce Cowan committed
    gtk_widget_class_set_template_from_resource (widget_class,
Bruce Cowan's avatar
Bruce Cowan committed
                                                 "/uk/me/bcowan/Rugby/gtk/window.ui");
Bruce Cowan's avatar
Bruce Cowan committed

    gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, scorespin);
Bruce Cowan's avatar
Bruce Cowan committed
    gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, tryspin);
Bruce Cowan's avatar
Bruce Cowan committed
    gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, stack);
Bruce Cowan's avatar
Bruce Cowan committed
    gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, try_filter);

    gtk_widget_class_bind_template_callback (widget_class, try_spin_value_changed_cb);
Bruce Cowan's avatar
Bruce Cowan committed
    gtk_widget_class_bind_template_callback (widget_class, item_tooltip_cb);
Bruce Cowan's avatar
Bruce Cowan committed
    gtk_widget_class_bind_template_callback (widget_class, list_store_items_changed_cb);
Bruce Cowan's avatar
Bruce Cowan committed
}

RugbyAppWindow *
Bruce Cowan's avatar
Bruce Cowan committed
rugby_app_window_new (GtkApplication *app)
Bruce Cowan's avatar
Bruce Cowan committed
    return g_object_new (RUGBY_TYPE_APP_WINDOW,
                         "application", app,
                         NULL);