Forked from
Bruce Cowan / Rugby
193 commits behind the upstream repository.
-
Bruce Cowan authoredBruce Cowan authored
rugby-application.c 8.67 KiB
#include "rugby-application.h"
#include "rugby-cell-renderer-score.h"
#include "rugby-score-store.h"
#include "rugby-scoring.h"
struct _RugbyApplicationPrivate
{
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->priv->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->priv->tryscale), 0.0, max_tries);
max_kicks = MAX (rugby_scoring_get_max_kicks (score), 1.0);
gtk_range_set_range (GTK_RANGE (app->priv->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->priv->tryscale, TRUE);
else
gtk_widget_set_sensitive (app->priv->tryscale, FALSE);
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->priv->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->priv->kickscale, TRUE);
else
gtk_widget_set_sensitive (app->priv->kickscale, FALSE);
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->priv->fmodel));
}
static void
scale_changed_cb (GtkRange *range,
RugbyApplication *app)
{
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (app->priv->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)
{
RugbyApplicationPrivate *priv = app->priv;
gint ctries, ckicks; /* TODO fix these crap names */
gint tries, utries, kicks;
gboolean try, kick;
ctries = (gint) gtk_range_get_value (GTK_RANGE (app->priv->tryscale));
ckicks = (gint) gtk_range_get_value (GTK_RANGE (app->priv->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 (priv->tryfilter));
kick = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->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 *app)
{
RugbyApplicationPrivate *priv = RUGBY_APPLICATION (app)->priv;
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);
priv->tryfilter = GTK_WIDGET (gtk_builder_get_object (builder, "tryfilter"));
g_signal_connect (priv->tryfilter, "toggled",
G_CALLBACK (tryfilter_toggled_cb), app);
priv->tryscale = GTK_WIDGET (gtk_builder_get_object (builder, "tryscale"));
g_signal_connect (priv->tryscale, "value-changed",
G_CALLBACK (scale_changed_cb), app);
priv->kickfilter = GTK_WIDGET (gtk_builder_get_object (builder, "kickfilter"));
g_signal_connect (priv->kickfilter, "toggled",
G_CALLBACK (kickfilter_toggled_cb), app);
priv->kickscale = GTK_WIDGET (gtk_builder_get_object (builder, "kickscale"));
g_signal_connect (priv->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 */
priv->store = rugby_score_store_new ();
priv->fmodel = gtk_tree_model_filter_new (GTK_TREE_MODEL (priv->store), NULL);
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->fmodel),
(GtkTreeModelFilterVisibleFunc) filter_func, app, NULL);
gtk_tree_view_set_model (GTK_TREE_VIEW (tree), priv->fmodel);
statusbar = GTK_WIDGET (gtk_builder_get_object (builder, "status"));
g_signal_connect (priv->store, "finished",
G_CALLBACK (store_finished_cb), statusbar);
/* init CSS */
provider = gtk_css_provider_new ();
/* TODO load this from resource */
gtk_css_provider_load_from_path (provider, "rugby.css", NULL);
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;
g_type_class_add_private (klass, sizeof (RugbyApplicationPrivate));
}
static void
rugby_application_init (RugbyApplication *app)
{
app->priv = G_TYPE_INSTANCE_GET_PRIVATE (app, RUGBY_TYPE_APPLICATION, RugbyApplicationPrivate);
}
/**
* rugby_application_new:
*
* Creates a #RugbyApplication. This is the main UI of the program
*
* Returns: a new #RugbyApplication
*/
RugbyApplication *
rugby_application_new (void)
{
g_type_init ();
g_set_application_name ("Rugby");
return g_object_new (RUGBY_TYPE_APPLICATION,
"application-id", "uk.me.bcowan.Rugby",
NULL);
}