/* rugby-score-store.c * * Copyright © 2012, 2016-2018 Bruce Cowan <bruce@bcowan.eu> * * This file is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "rugby-score-store.h" #include "rugby-scoring.h" enum { FINISHED, LAST_SIGNAL }; enum { PROP_0, PROP_SCORE, PROP_LAST }; static GParamSpec *pspecs[PROP_LAST]; struct _RugbyScoreStore { GtkListStore parent_instance; gint score; }; G_DEFINE_TYPE (RugbyScoreStore, rugby_score_store, GTK_TYPE_LIST_STORE) static guint signals[LAST_SIGNAL] = { 0, }; static void rugby_score_store_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { RugbyScoreStore *self = RUGBY_SCORE_STORE (object); switch (prop_id) { case PROP_SCORE: rugby_score_store_set_score (self, g_value_get_int (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void rugby_score_store_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { RugbyScoreStore *self = RUGBY_SCORE_STORE (object); switch (prop_id) { case PROP_SCORE: g_value_set_int (value, rugby_score_store_get_score (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void rugby_score_store_class_init (RugbyScoreStoreClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->get_property = rugby_score_store_get_property; obj_class->set_property = rugby_score_store_set_property; pspecs[PROP_SCORE] = g_param_spec_int ("score", "Score", "The score", 0, 200, 0, G_PARAM_READWRITE); g_object_class_install_property (obj_class, PROP_SCORE, pspecs[PROP_SCORE]); signals[FINISHED] = g_signal_new ("finished", G_TYPE_FROM_CLASS (obj_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_INT); } static void populate_store_foreach (gpointer data, gpointer user_data) { RugbyPossibility *possiblity = (RugbyPossibility *) data; GtkListStore *store = GTK_LIST_STORE (user_data); GtkTreeIter iter; gint tries = possiblity->tries; gint utries = possiblity->utries; gint kicks = possiblity->kicks; g_autoptr (GString) string = g_string_new (NULL); if (tries > 0 || utries > 0) g_string_append_printf (string, "%d tries, %d converted", tries + utries, tries); if (kicks > 0) { if (string->len == 0) g_string_append_printf (string, "%d kicks", kicks); else g_string_append_printf (string, ", %d kicks", kicks); } gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, RUGBY_SCORE_STORE_TRIES, tries, RUGBY_SCORE_STORE_UTRIES, utries, RUGBY_SCORE_STORE_KICKS, kicks, RUGBY_SCORE_STORE_TOOLTIP, string->str, -1); } static void populate_store (RugbyScoreStore *self) { GtkListStore *store = GTK_LIST_STORE (self); g_autoptr(GPtrArray) possibilities = NULL; /* Clear the store */ gtk_list_store_clear (store); possibilities = rugby_scoring_get_possibilities (self->score); if (possibilities->len == 0) return; g_ptr_array_foreach (possibilities, populate_store_foreach, store); g_signal_emit (self, signals[FINISHED], 0, (gint) possibilities->len); } static void rugby_score_store_init (RugbyScoreStore *self) { GType types[] = { G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING }; gtk_list_store_set_column_types (GTK_LIST_STORE (self), RUGBY_SCORE_STORE_COLUMNS, types); self->score = 0; } RugbyScoreStore * rugby_score_store_new (void) { return g_object_new (RUGBY_TYPE_SCORE_STORE, NULL); } gint rugby_score_store_get_score (RugbyScoreStore *self) { g_return_val_if_fail (RUGBY_IS_SCORE_STORE (self), 0); return self->score; } void rugby_score_store_set_score (RugbyScoreStore *self, gint score) { g_return_if_fail (RUGBY_IS_SCORE_STORE (self)); g_return_if_fail (score >= 0 && score <= 200); self->score = score; g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_SCORE]); populate_store (self); }