#include <gtk/gtk.h> #include "rugby-application.h" #include "rugby-app-window.h" #include "rugby-cell-renderer-score.h" #include "rugby-score-store.h" #include "rugby-scoring.h" struct _RugbyAppWindow { GtkApplicationWindow parent; RugbyScoreStore *store; GtkTreeModel *filter; GtkWidget *tryfilter; GtkWidget *kickfilter; GtkWidget *tryscale; GtkWidget *kickscale; GtkWidget *treeview; }; G_DEFINE_TYPE(RugbyAppWindow, rugby_app_window, GTK_TYPE_APPLICATION_WINDOW); static void scorespin_value_changed_cb (GtkSpinButton *spin, RugbyAppWindow *self) { gint score = gtk_spin_button_get_value_as_int (spin); rugby_score_store_set_score (self->store, score); gint max_tries = MAX (rugby_scoring_get_max_tries (score), 1.0); gtk_range_set_range (GTK_RANGE (self->tryscale), 0.0, max_tries); gint max_kicks = MAX (rugby_scoring_get_max_kicks (score), 1.0); gtk_range_set_range (GTK_RANGE (self->kickscale), 0.0, max_kicks); } static void tryfilter_active_cb (GObject *gobject, GParamSpec *pspec, RugbyAppWindow *self) { gboolean active = gtk_switch_get_active (GTK_SWITCH (gobject)); gtk_widget_set_sensitive (self->tryscale, active); } static void kickfilter_active_cb (GObject *gobject, GParamSpec *pspec, RugbyAppWindow *self) { gboolean active = gtk_switch_get_active (GTK_SWITCH (gobject)); gtk_widget_set_sensitive (self->kickscale, active); } static void scale_value_changed_cb (GtkRange *range, RugbyAppWindow *self) { gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (self->filter)); } static gboolean filter_visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { RugbyAppWindow *self = RUGBY_APP_WINDOW (data); gint tries, utries, kicks; gint ftries = gtk_range_get_value (GTK_RANGE (self->tryscale)); gint fkicks = gtk_range_get_value (GTK_RANGE (self->kickscale)); gtk_tree_model_get (model, iter, RUGBY_SCORE_STORE_TRIES, &tries, RUGBY_SCORE_STORE_UTRIES, &utries, RUGBY_SCORE_STORE_KICKS, &kicks, -1); gboolean try_filter = gtk_switch_get_active (GTK_SWITCH (self->tryfilter)); gboolean kick_filter = gtk_switch_get_active (GTK_SWITCH (self->kickfilter)); gboolean try_equal = ((tries + utries) == ftries); gboolean kick_equal = (kicks == fkicks); if (try_filter && kick_filter) return try_equal && kick_equal; else if (try_filter) return try_equal; else if (kick_filter) return kick_equal; else return TRUE; } static void rugby_app_window_init (RugbyAppWindow *self) { gtk_widget_init_template (GTK_WIDGET (self)); GtkCellRenderer *renderer = rugby_cell_renderer_score_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes ("Score", renderer, "tries", RUGBY_SCORE_STORE_TRIES, "utries", RUGBY_SCORE_STORE_UTRIES, "kicks", RUGBY_SCORE_STORE_KICKS, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (self->treeview), column); // TODO: put this in the builder file instead self->store = rugby_score_store_new (); self->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (self->store), NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (self->filter), filter_visible_func, self, NULL); gtk_tree_view_set_model (GTK_TREE_VIEW (self->treeview), self->filter); } static void rugby_app_window_dispose (GObject *object) { RugbyAppWindow *self = RUGBY_APP_WINDOW (object); g_clear_object (&self->store); g_clear_object (&self->filter); G_OBJECT_CLASS (rugby_app_window_parent_class)->dispose (object); } static void rugby_app_window_class_init (RugbyAppWindowClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); obj_class->dispose = rugby_app_window_dispose; gtk_widget_class_set_template_from_resource (widget_class, "/uk/me/bcowan/rugby/interface.ui"); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, tryfilter); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, kickfilter); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, tryscale); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, kickscale); gtk_widget_class_bind_template_child (widget_class, RugbyAppWindow, treeview); gtk_widget_class_bind_template_callback (widget_class, scorespin_value_changed_cb); gtk_widget_class_bind_template_callback (widget_class, tryfilter_active_cb); gtk_widget_class_bind_template_callback (widget_class, kickfilter_active_cb); gtk_widget_class_bind_template_callback (widget_class, scale_value_changed_cb); } RugbyAppWindow * rugby_app_window_new (RugbyApplication *app) { return g_object_new (RUGBY_TYPE_APP_WINDOW, "application", app, NULL); }