/* * SPDX-FileCopyrightText: 2018-2021 Bruce Cowan <bruce@bcowan.me.uk> * * SPDX-License-Identifier: GPL-3.0-or-later */ #include "config.h" #include "rugby-possibility-widget.h" #include <glib/gi18n.h> struct _RugbyPossibilityWidget { GtkWidget parent_instance; 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); 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, 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, 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 GskColorStop *stops) { 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_linear_gradient (snapshot, &GRAPHENE_RECT_INIT (x, y, w, h), &GRAPHENE_POINT_INIT (0, 0), &GRAPHENE_POINT_INIT (0, h), stops, 2); gtk_snapshot_pop (snapshot); GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 }; gtk_snapshot_append_border (snapshot, &rounded, (float[]) { 2., 2., 2., 2. }, (GdkRGBA[]) { black, black, black, black }); } static void rugby_possibility_widget_snapshot (GtkWidget *widget, GtkSnapshot *snapshot) { RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (widget); 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); int score = tries * try_points + utries * utry_points + kicks * kick_points; // Green const GskColorStop green_stops[] = { { 0.0, { 0.15, 0.64, 0.41, 1.0 } }, { 1.0, { 0.56, 0.94, 0.64, 1.0 } }, }; // Red const GskColorStop red_stops[] = { { 0.0, { 0.65, 0.11, 0.18, 1.0 } }, { 1.0, { 0.97, 0.38, 0.32, 1.0 } }, }; // Yellow const GskColorStop yellow_stops[] = { { 0.0, { 0.90, 0.65, 0.04, 1.0 } }, { 1.0, { 0.98, 0.94, 0.42, 1.0 } }, }; // Tries double w = width / (score / (double) try_points); for (int i = 0; i < tries; i++) { render_bar (snapshot, x, 0.0, w, height, green_stops); x += w; } // Unconverted tries w = width / (score / (double) utry_points); for (int i = 0; i < utries; i++) { render_bar (snapshot, x, 0.0, w, height, red_stops); x += w; } // Unconverted kicks w = width / (score / (double) kick_points); for (int i = 0; i < kicks; i++) { render_bar (snapshot, x, 0.0, w, height, yellow_stops); x += w; } } static void rugby_possibility_widget_constructed (GObject *obj) { RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (obj); int tries, utries, kicks; g_autoptr (GString) tooltip = g_string_new (NULL); g_object_get (self->possibility, "tries", &tries, "utries", &utries, "kicks", &kicks, NULL); if ((tries + utries) > 0) { g_string_append_printf (tooltip, ngettext ("%d try, %d converted", "%d tries, %d converted", tries + utries), tries + utries, tries); if (kicks > 0) g_string_append_printf (tooltip, ngettext (", %d kick", ", %d kicks", kicks), kicks); } else if (kicks > 0) { 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 rugby_possibility_widget_init (RugbyPossibilityWidget *self) { 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); }