#include "rugby-application.h" #include "rugby-cell-renderer-score.h" #include "rugby-score-store.h" #include "rugby-scoring.h" struct _RugbyApplication { GtkApplication parent_instance; GtkWidget *tryfilter; GtkWidget *tryscale; GtkWidget *kickfilter; GtkWidget *kickscale; RugbyScoreStore *store; GtkTreeModel *fmodel; }; G_DEFINE_TYPE (RugbyApplication, rugby_application, GTK_TYPE_APPLICATION) static void scorespin_changed_cb (GtkSpinButton *spin, RugbyApplication *app) { gint score; gint max_tries; gint max_kicks; score = gtk_spin_button_get_value_as_int (spin); rugby_score_store_set_score (app->store, score); /* I'd rather not have to do this */ max_tries = MAX (rugby_scoring_get_max_tries (score), 1.0); gtk_range_set_range (GTK_RANGE (app->tryscale), 0.0, max_tries); max_kicks = MAX (rugby_scoring_get_max_kicks (score), 1.0); gtk_range_set_range (GTK_RANGE (app->kickscale), 0.0, max_kicks); } static void tryfilter_toggled_cb (GtkToggleButton *toggle, RugbyApplication *app) { if (gtk_toggle_button_get_active (toggle)) gtk_widget_set_sensitive (app->tryscale, TRUE); else gtk_widget_set_sensitive (app->tryscale, FALSE); gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->fmodel)); } /* TODO replace this with one function */ static void kickfilter_toggled_cb (GtkToggleButton *toggle, RugbyApplication *app) { if (gtk_toggle_button_get_active (toggle)) gtk_widget_set_sensitive (app->kickscale, TRUE); else gtk_widget_set_sensitive (app->kickscale, FALSE); gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->fmodel)); } static void scale_changed_cb (GtkRange *range, RugbyApplication *app) { gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->fmodel)); } static void store_finished_cb (RugbyScoreStore *store, gint possibilities, GtkStatusbar *bar) { gchar *status; guint context_id; status = g_strdup_printf ("%d possibilities", possibilities); context_id = gtk_statusbar_get_context_id (bar, "possibilities count"); gtk_statusbar_pop (bar, context_id); gtk_statusbar_push (bar, context_id, status); g_free (status); } static gboolean filter_func (GtkTreeModel *model, GtkTreeIter *iter, RugbyApplication *app) { gint ctries, ckicks; /* TODO fix these crap names */ gint tries, utries, kicks; gboolean try, kick; ctries = (gint) gtk_range_get_value (GTK_RANGE (app->tryscale)); ckicks = (gint) gtk_range_get_value (GTK_RANGE (app->kickscale)); gtk_tree_model_get (model, iter, RUGBY_SCORE_STORE_TRIES, &tries, RUGBY_SCORE_STORE_UTRIES, &utries, RUGBY_SCORE_STORE_KICKS, &kicks, -1); try = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (app->tryfilter)); kick = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (app->kickfilter)); if (try && kick) return ((tries + utries == ctries) && (kicks == ckicks)) ? TRUE : FALSE; else if (try) return (tries + utries == ctries) ? TRUE : FALSE; else if (kick) return (kicks == ckicks) ? TRUE : FALSE; return TRUE; } static void app_about (GSimpleAction *action, GVariant *parameter, gpointer user_data) { GtkApplication *application = GTK_APPLICATION (user_data); GList *windows; GtkWindow *window; windows = gtk_application_get_windows (application); window = windows->data; /* TODO show proper about dialogue */ gtk_show_about_dialog (window, "program-name", "Rugby", "license-type", GTK_LICENSE_MIT_X11, NULL); } static void app_quit (GSimpleAction *action, GVariant *parameter, gpointer user_data) { GApplication *application = G_APPLICATION (user_data); g_application_quit (application); } static GActionEntry app_entries[] = { { "about", app_about, NULL, NULL, NULL }, { "quit", app_quit, NULL, NULL, NULL } }; static void rugby_application_startup (GApplication *application) { GtkBuilder *builder; GError *err = NULL; G_APPLICATION_CLASS (rugby_application_parent_class)->startup (application); g_action_map_add_action_entries (G_ACTION_MAP (application), app_entries, G_N_ELEMENTS (app_entries), application); builder = gtk_builder_new (); if (!gtk_builder_add_from_resource (builder, "/uk/me/bcowan/rugby/interface.ui", &err)) { g_error ("Error: %s", err->message); } gtk_application_set_app_menu (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu"))); g_object_unref (builder); } static void rugby_application_activate (GApplication *self) { RugbyApplication *app = RUGBY_APPLICATION (self); GtkBuilder *builder; GError *err = NULL; GtkWidget *score; GtkWidget *tree; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkWidget *statusbar; GtkWidget *window; GtkCssProvider *provider; builder = gtk_builder_new (); if (!gtk_builder_add_from_resource (builder, "/uk/me/bcowan/rugby/interface.ui", &err)) { g_error ("Error: %s", err->message); } score = GTK_WIDGET (gtk_builder_get_object (builder, "scorespin")); g_signal_connect (score, "value-changed", G_CALLBACK (scorespin_changed_cb), app); app->tryfilter = GTK_WIDGET (gtk_builder_get_object (builder, "tryfilter")); g_signal_connect (app->tryfilter, "toggled", G_CALLBACK (tryfilter_toggled_cb), app); app->tryscale = GTK_WIDGET (gtk_builder_get_object (builder, "tryscale")); g_signal_connect (app->tryscale, "value-changed", G_CALLBACK (scale_changed_cb), app); app->kickfilter = GTK_WIDGET (gtk_builder_get_object (builder, "kickfilter")); g_signal_connect (app->kickfilter, "toggled", G_CALLBACK (kickfilter_toggled_cb), app); app->kickscale = GTK_WIDGET (gtk_builder_get_object (builder, "kickscale")); g_signal_connect (app->kickscale, "value-changed", G_CALLBACK (scale_changed_cb), app); tree = GTK_WIDGET (gtk_builder_get_object (builder, "treeview")); /* Would be nice to use GtkBuilder */ renderer = rugby_cell_renderer_score_new (); 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 (tree), column); /* Create a TreeModelFilter */ app->store = rugby_score_store_new (); app->fmodel = gtk_tree_model_filter_new (GTK_TREE_MODEL (app->store), NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (app->fmodel), (GtkTreeModelFilterVisibleFunc) filter_func, app, NULL); gtk_tree_view_set_model (GTK_TREE_VIEW (tree), app->fmodel); statusbar = GTK_WIDGET (gtk_builder_get_object (builder, "status")); g_signal_connect (app->store, "finished", G_CALLBACK (store_finished_cb), statusbar); /* init CSS */ provider = gtk_css_provider_new (); gtk_css_provider_load_from_resource (provider, "/uk/me/bcowan/rugby/rugby.css"); gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (app)); gtk_widget_show_all (window); g_object_unref (builder); } static void rugby_application_class_init (RugbyApplicationClass *klass) { GApplicationClass *app_class = G_APPLICATION_CLASS (klass); app_class->startup = rugby_application_startup; app_class->activate = rugby_application_activate; } static void rugby_application_init (RugbyApplication *app) { } /** * rugby_application_new: * * Creates a #RugbyApplication. This is the main UI of the program * * Returns: a new #RugbyApplication */ RugbyApplication * rugby_application_new (void) { g_set_application_name ("Rugby"); return g_object_new (RUGBY_TYPE_APPLICATION, "application-id", "uk.me.bcowan.Rugby", NULL); }