#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 *store = RUGBY_SCORE_STORE (object); switch (prop_id) { case PROP_SCORE: rugby_score_store_set_score (store, 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 *store = RUGBY_SCORE_STORE (object); switch (prop_id) { case PROP_SCORE: g_value_set_int (value, rugby_score_store_get_score (store)); 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]); /** * RugbyScoreStore::finished: * @store: the object which received the signal * * Emitted when possibilities checking has finished. */ 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_autofree gchar *tooltip = g_strdup_printf ("%d tries, %d converted, %d kicks", tries, utries, 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, tooltip, -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 *store) { GType types[] = { G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING }; gtk_list_store_set_column_types (GTK_LIST_STORE (store), RUGBY_SCORE_STORE_COLUMNS, types); store->score = 0; } /** * rugby_score_store_new: * * Creates a #RugbyScoreStore. This can be used to update a #GtkTreeView with * possibilities. * * Returns: a new #RugbyScoreStore */ RugbyScoreStore * rugby_score_store_new (void) { return g_object_new (RUGBY_TYPE_SCORE_STORE, NULL); } /** * rugby_score_store_get_score: * @scores: a #RugbyScoreStore * * Gets the current score. * * Returns: the current score */ gint rugby_score_store_get_score (RugbyScoreStore *store) { g_return_val_if_fail (RUGBY_IS_SCORE_STORE (store), 0); return store->score; } /** * rugby_score_store_set_score: * @scores: a #RugbyScoreStore * @score: the new score * * Sets the current score. */ void rugby_score_store_set_score (RugbyScoreStore *store, gint score) { g_return_if_fail (RUGBY_IS_SCORE_STORE (store)); g_return_if_fail (score >= 0 && score <= 200); store->score = score; g_object_notify_by_pspec (G_OBJECT (store), pspecs[PROP_SCORE]); populate_store (store); }