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

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

struct _RugbyPossibilityWidget
{
    GtkWidget parent_instance;
Bruce Cowan's avatar
Bruce Cowan committed
    GSettings *settings;
    RugbyPossibility *possibility;
};

G_DEFINE_TYPE (RugbyPossibilityWidget, rugby_possibility_widget, GTK_TYPE_WIDGET)

enum
{
    PROP_0,
    PROP_POSSIBILITY,
    N_PROPS
};

static GParamSpec *properties[N_PROPS];

static void
rugby_possibility_widget_dispose (GObject *object)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object);

Bruce Cowan's avatar
Bruce Cowan committed
    g_clear_object (&self->settings);
    g_clear_object (&self->possibility);

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

static void
rugby_possibility_widget_get_property (GObject    *object,
Bruce Cowan's avatar
Bruce Cowan committed
                                       unsigned    prop_id,
                                       GValue     *value,
                                       GParamSpec *pspec)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object);

    switch (prop_id)
    {
        case PROP_POSSIBILITY:
            g_value_set_object (value, self->possibility);
            break;
        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
rugby_possibility_widget_set_property (GObject      *object,
Bruce Cowan's avatar
Bruce Cowan committed
                                       unsigned      prop_id,
                                       const GValue *value,
                                       GParamSpec   *pspec)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object);

    switch (prop_id)
    {
        case PROP_POSSIBILITY:
            self->possibility = g_value_dup_object (value);
            break;
        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
render_bar (GtkSnapshot  *snapshot,
            double        x,
            double        y,
            double        w,
            double        h,
            const GdkRGBA color)
    GskRoundedRect rounded;
    gsk_rounded_rect_init_from_rect (&rounded,
                                     &GRAPHENE_RECT_INIT (x, y, w, h),
                                     h / 2.0);

    gtk_snapshot_push_rounded_clip (snapshot, &rounded);
    gtk_snapshot_append_color (snapshot,
                               &color,
                               &GRAPHENE_RECT_INIT (x, y, w, h));
    gtk_snapshot_pop (snapshot);

    GdkRGBA black = { 0.0, 0.0, 0.0, 0.2 };
    gtk_snapshot_append_border (snapshot,
                                &rounded,
                                (float[]) { 2.f, 2.f, 2.f, 2.f },
                                (GdkRGBA[]) { black, black, black, black });
Bruce Cowan's avatar
Bruce Cowan committed
static void
rugby_possibility_widget_snapshot (GtkWidget   *widget,
                                   GtkSnapshot *snapshot)
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (widget);
Bruce Cowan's avatar
Bruce Cowan committed
    int try_points = g_settings_get_int (self->settings, "try-points");
    int utry_points = g_settings_get_int (self->settings, "utry-points");
    int kick_points = g_settings_get_int (self->settings, "kick-points");
    int width = gtk_widget_get_width (widget);
    int height = gtk_widget_get_height (widget);
    double x = 0.0;
    int tries, utries, kicks;
    g_object_get (self->possibility,
                  "tries", &tries,
                  "utries", &utries,
                  "kicks", &kicks,
                  NULL);
Bruce Cowan's avatar
Bruce Cowan committed
    int score = tries * try_points + utries * utry_points + kicks * kick_points;
Bruce Cowan's avatar
Bruce Cowan committed
    double w = width / (score / (double) try_points);
    for (int i = 0; i < tries; i++)
    {
        // Green
        render_bar (snapshot, x, 0.0, w, height, (GdkRGBA) { 0.20, 0.82, 0.48, 1.0 });
Bruce Cowan's avatar
Bruce Cowan committed
    w = width / (score / (double) utry_points);
    for (int i = 0; i < utries; i++)
    {
        // Red
        render_bar (snapshot, x, 0.0, w, height, (GdkRGBA) { 0.88, 0.11, 0.14, 1.0 });
Bruce Cowan's avatar
Bruce Cowan committed
    w = width / (score / (double) kick_points);
    for (int i = 0; i < kicks; i++)
    {
        // Yellow
        render_bar (snapshot, x, 0.0, w, height, (GdkRGBA) { 0.97, 0.83, 0.18, 1.0 });
        x += w;
    }
}

static void
rugby_possibility_widget_constructed (GObject *obj)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (obj);
Bruce Cowan's avatar
Bruce Cowan committed
    int tries, utries, kicks;
    g_autoptr (GString) tooltip = g_string_new (NULL);

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

Bruce Cowan's avatar
Bruce Cowan committed
    if ((tries + utries) > 0)
    {
        g_string_append_printf (tooltip,
                                ngettext ("%d try, %d converted",
                                          "%d tries, %d converted",
                                          tries + utries),
                                tries + utries, tries);

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

    gtk_widget_set_tooltip_text (GTK_WIDGET (self), tooltip->str);

    G_OBJECT_CLASS (rugby_possibility_widget_parent_class)->constructed (obj);
}

static void
rugby_possibility_widget_class_init (RugbyPossibilityWidgetClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

    object_class->constructed = rugby_possibility_widget_constructed;
    object_class->dispose = rugby_possibility_widget_dispose;
    object_class->get_property = rugby_possibility_widget_get_property;
    object_class->set_property = rugby_possibility_widget_set_property;

    widget_class->snapshot = rugby_possibility_widget_snapshot;

    properties[PROP_POSSIBILITY] =
        g_param_spec_object ("possibility",
                             "Possibility",
                             "Possibility to be represented",
                             RUGBY_TYPE_POSSIBILITY,
                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);

    g_object_class_install_properties (object_class,
                                       N_PROPS,
                                       properties);
}

static void
Bruce Cowan's avatar
Bruce Cowan committed
rugby_possibility_widget_init (RugbyPossibilityWidget *self)
Bruce Cowan's avatar
Bruce Cowan committed
    self->settings = g_settings_new ("uk.me.bcowan.Rugby");
}

GtkWidget *
rugby_possibility_widget_new (RugbyPossibility *possibility)
{
    return g_object_new (RUGBY_TYPE_POSSIBILITY_WIDGET,
                         "possibility", possibility,
                         NULL);
}