#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 _RugbyScoreStorePrivate { 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, 150, 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, G_STRUCT_OFFSET (RugbyScoreStoreClass, finished), NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_INT); g_type_class_add_private (klass, sizeof (RugbyScoreStorePrivate)); } static void populate_store (GObject *object, GParamSpec *pspec) { GtkListStore *store = GTK_LIST_STORE (object); RugbyScoreStorePrivate *priv = RUGBY_SCORE_STORE (object)->priv; GVariant *possibilities; GVariant *possibility; GVariantIter iter; gsize total; /* Clear the store */ gtk_list_store_clear (store); possibilities = rugby_scoring_get_possibilities (priv->score); if (possibilities == NULL) return; total = g_variant_iter_init (&iter, possibilities); while ((possibility = g_variant_iter_next_value (&iter))) { gint tries, utries, pens; GString *tooltip; GtkTreeIter iter; g_variant_get (possibility, "(iii)", &tries, &utries, &pens); g_variant_unref (possibility); tooltip = g_string_new_len (NULL, 20); if (utries > 0 || tries > 0) { g_string_append_printf (tooltip, "%d tries, %d converted", tries + utries, tries); if (pens > 0) g_string_append_printf (tooltip, ", %d kicks", pens); } else if (utries == 0 && tries == 0) g_string_append_printf (tooltip, "%d kicks", pens); /* Put result in list store */ 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_PENS, pens, RUGBY_SCORE_STORE_TOOLTIP, tooltip->str, -1); g_string_free (tooltip, TRUE); } g_signal_emit (store, signals[FINISHED], 0, (gint) total); } static void rugby_score_store_init (RugbyScoreStore *store) { RugbyScoreStorePrivate *priv; GType types[] = { G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING }; priv = G_TYPE_INSTANCE_GET_PRIVATE (store, RUGBY_TYPE_SCORE_STORE, RugbyScoreStorePrivate); gtk_list_store_set_column_types (GTK_LIST_STORE (store), RUGBY_SCORE_STORE_COLUMNS, types); priv->score = 0; g_signal_connect (store, "notify::score", G_CALLBACK (populate_store), NULL); store->priv = priv; } /** * 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->priv->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)); store->priv->score = score; g_object_notify_by_pspec (G_OBJECT (store), pspecs[PROP_SCORE]); }