Skip to content
Snippets Groups Projects
rugby-application.c 8.36 KiB
Newer Older
Bruce Cowan's avatar
Bruce Cowan committed
#include "rugby-application.h"

#include "rugby-cell-renderer-score.h"
#include "rugby-score-store.h"
#include "rugby-scoring.h"

struct _RugbyApplication
Bruce Cowan's avatar
Bruce Cowan committed
{
  	GtkApplication parent_instance;

Bruce Cowan's avatar
Bruce Cowan committed
	GtkWidget *tryfilter;
	GtkWidget *tryscale;
	GtkWidget *kickfilter;
	GtkWidget *kickscale;
Bruce Cowan's avatar
Bruce Cowan committed
	RugbyScoreStore *store;
	GtkTreeModel *fmodel;
};

G_DEFINE_TYPE (RugbyApplication, rugby_application, GTK_TYPE_APPLICATION)

static void
scorespin_changed_cb (GtkSpinButton    *spin,
                      RugbyApplication *app)
{
	gint score;
Bruce Cowan's avatar
Bruce Cowan committed
	gint max_tries;
	gint max_kicks;
Bruce Cowan's avatar
Bruce Cowan committed

	score = gtk_spin_button_get_value_as_int (spin);
	rugby_score_store_set_score (app->store, score);
Bruce Cowan's avatar
Bruce Cowan committed

	/* I'd rather not have to do this */
Bruce Cowan's avatar
Bruce Cowan committed
	max_tries = MAX (rugby_scoring_get_max_tries (score), 1.0);
	gtk_range_set_range (GTK_RANGE (app->tryscale), 0.0, max_tries);
Bruce Cowan's avatar
Bruce Cowan committed

	max_kicks = MAX (rugby_scoring_get_max_kicks (score), 1.0);
	gtk_range_set_range (GTK_RANGE (app->kickscale), 0.0, max_kicks);
Bruce Cowan's avatar
Bruce Cowan committed
}

static void
tryfilter_toggled_cb (GtkToggleButton  *toggle,
                      RugbyApplication *app)
{
	if (gtk_toggle_button_get_active (toggle))
		gtk_widget_set_sensitive (app->tryscale, TRUE);
Bruce Cowan's avatar
Bruce Cowan committed
	else
		gtk_widget_set_sensitive (app->tryscale, FALSE);
Bruce Cowan's avatar
Bruce Cowan committed

	gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->fmodel));
Bruce Cowan's avatar
Bruce Cowan committed
}

Bruce Cowan's avatar
Bruce Cowan committed
/* TODO replace this with one function */
Bruce Cowan's avatar
Bruce Cowan committed
static void
Bruce Cowan's avatar
Bruce Cowan committed
kickfilter_toggled_cb (GtkToggleButton  *toggle,
                       RugbyApplication *app)
Bruce Cowan's avatar
Bruce Cowan committed
{
	if (gtk_toggle_button_get_active (toggle))
		gtk_widget_set_sensitive (app->kickscale, TRUE);
Bruce Cowan's avatar
Bruce Cowan committed
	else
		gtk_widget_set_sensitive (app->kickscale, FALSE);
Bruce Cowan's avatar
Bruce Cowan committed

	gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->fmodel));
Bruce Cowan's avatar
Bruce Cowan committed
}

static void
Bruce Cowan's avatar
Bruce Cowan committed
scale_changed_cb (GtkRange         *range,
                  RugbyApplication *app)
Bruce Cowan's avatar
Bruce Cowan committed
{
	gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->fmodel));
Bruce Cowan's avatar
Bruce Cowan committed
}

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)
{
Bruce Cowan's avatar
Bruce Cowan committed
	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));
Bruce Cowan's avatar
Bruce Cowan committed
	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));
Bruce Cowan's avatar
Bruce Cowan committed

	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;
Bruce Cowan's avatar
Bruce Cowan committed
}

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 */
Bruce Cowan's avatar
Bruce Cowan committed
	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 ();
Bruce Cowan's avatar
Bruce Cowan committed
	if (!gtk_builder_add_from_resource (builder, "/uk/me/bcowan/rugby/interface.ui", &err))
Bruce Cowan's avatar
Bruce Cowan committed
	{
		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)
Bruce Cowan's avatar
Bruce Cowan committed
{
  	RugbyApplication *app = RUGBY_APPLICATION (self);
Bruce Cowan's avatar
Bruce Cowan committed
	GtkBuilder *builder;
	GError *err = NULL;
	GtkWidget *score;
	GtkWidget *tree;
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *column;
	GtkWidget *statusbar;
	GtkWidget *window;
	GtkCssProvider *provider;

	builder = gtk_builder_new ();
Bruce Cowan's avatar
Bruce Cowan committed
	if (!gtk_builder_add_from_resource (builder, "/uk/me/bcowan/rugby/interface.ui", &err))
Bruce Cowan's avatar
Bruce Cowan committed
	{
		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",
Bruce Cowan's avatar
Bruce Cowan committed
	                  G_CALLBACK (tryfilter_toggled_cb), app);

	app->tryscale = GTK_WIDGET (gtk_builder_get_object (builder, "tryscale"));
	g_signal_connect (app->tryscale, "value-changed",
Bruce Cowan's avatar
Bruce Cowan committed
	                  G_CALLBACK (scale_changed_cb), app);

	app->kickfilter = GTK_WIDGET (gtk_builder_get_object (builder, "kickfilter"));
	g_signal_connect (app->kickfilter, "toggled",
Bruce Cowan's avatar
Bruce Cowan committed
	                  G_CALLBACK (kickfilter_toggled_cb), app);
Bruce Cowan's avatar
Bruce Cowan committed

	app->kickscale = GTK_WIDGET (gtk_builder_get_object (builder, "kickscale"));
	g_signal_connect (app->kickscale, "value-changed",
Bruce Cowan's avatar
Bruce Cowan committed
	                  G_CALLBACK (scale_changed_cb), app);
Bruce Cowan's avatar
Bruce Cowan committed

	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,
Bruce Cowan's avatar
Bruce Cowan committed
	                                                   "kicks", RUGBY_SCORE_STORE_KICKS,
Bruce Cowan's avatar
Bruce Cowan committed
	                                                   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),
Bruce Cowan's avatar
Bruce Cowan committed
	                                        (GtkTreeModelFilterVisibleFunc) filter_func, app, NULL);
	gtk_tree_view_set_model (GTK_TREE_VIEW (tree), app->fmodel);
Bruce Cowan's avatar
Bruce Cowan committed

	statusbar = GTK_WIDGET (gtk_builder_get_object (builder, "status"));
	g_signal_connect (app->store, "finished",
Bruce Cowan's avatar
Bruce Cowan committed
	                  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");
Bruce Cowan's avatar
Bruce Cowan committed
	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);
Bruce Cowan's avatar
Bruce Cowan committed
}

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)
{
Bruce Cowan's avatar
Bruce Cowan committed
}

/**
 * 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);
}