#include "rugby-cell-renderer-score.h" #include "rugby-scoring.h" enum { PROP_0, PROP_TRIES, PROP_UTRIES, PROP_PENS }; struct _RugbyCellRendererScorePrivate { gint tries; gint utries; gint pens; }; /* Style classes for the different types of score */ #define RUGBY_STYLE_CLASS_TRY "try" #define RUGBY_STYLE_CLASS_UTRY "utry" #define RUGBY_STYLE_CLASS_PEN "pen" G_DEFINE_TYPE (RugbyCellRendererScore, rugby_cell_renderer_score, GTK_TYPE_CELL_RENDERER) static void rugby_cell_renderer_score_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { RugbyCellRendererScorePrivate *priv = RUGBY_CELL_RENDERER_SCORE (object)->priv; switch (prop_id) { case PROP_TRIES: priv->tries = g_value_get_int (value); break; case PROP_UTRIES: priv->utries = g_value_get_int (value); break; case PROP_PENS: priv->pens = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void rugby_cell_renderer_score_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { RugbyCellRendererScorePrivate *priv = RUGBY_CELL_RENDERER_SCORE (object)->priv; switch (prop_id) { case PROP_TRIES: g_value_set_int (value, priv->tries); break; case PROP_UTRIES: g_value_set_int (value, priv->utries); break; case PROP_PENS: g_value_set_int (value, priv->pens); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } #define FIXED_WIDTH 400 #define FIXED_HEIGHT 20 static void rugby_cell_renderer_score_get_preferred_width (GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_width, gint *natural_width) { gint xpad; gint width; gtk_cell_renderer_get_padding (cell, &xpad, NULL); width = xpad * 2 + FIXED_WIDTH; if (minimum_width) *minimum_width = width; if (natural_width) *natural_width = width; } static void rugby_cell_renderer_score_get_preferred_height (GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_height, gint *natural_height) { gint ypad; gint height; gtk_cell_renderer_get_padding (cell, NULL, &ypad); height = ypad * 2 + FIXED_HEIGHT; if (minimum_height) *minimum_height = height; if (natural_height) *natural_height = height; } static void render_bar (GtkStyleContext *context, cairo_t *cr, gdouble x, gdouble y, gdouble width, gdouble height, RugbyScoreType type) { gtk_style_context_save (context); switch (type) { case RUGBY_SCORE_TYPE_TRY: gtk_style_context_add_class (context, RUGBY_STYLE_CLASS_TRY); break; case RUGBY_SCORE_TYPE_UTRY: gtk_style_context_add_class (context, RUGBY_STYLE_CLASS_UTRY); break; case RUGBY_SCORE_TYPE_PEN: gtk_style_context_add_class (context, RUGBY_STYLE_CLASS_PEN); break; } gtk_render_activity (context, cr, x, y, width, height); gtk_style_context_restore (context); } static void rugby_cell_renderer_score_render (GtkCellRenderer *cell, cairo_t *cr, GtkWidget *widget, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags) { RugbyCellRendererScorePrivate *priv = RUGBY_CELL_RENDERER_SCORE (cell)->priv; GtkStyleContext *context; gint xpad, ypad; gdouble x, y, total_w, w, h; GtkBorder padding, border; gint tries, utries, pens; gint total; gint i; context = gtk_widget_get_style_context (widget); gtk_cell_renderer_get_padding (cell, &xpad, &ypad); x = cell_area->x + xpad; y = cell_area->y + ypad; total_w = cell_area->width - xpad * 2; h = cell_area->height - ypad * 2; gtk_style_context_save (context); gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH); gtk_render_background (context, cr, x, y, total_w, h); gtk_render_frame (context, cr, x, y, total_w, h); gtk_style_context_get_border (context, GTK_STATE_FLAG_NORMAL, &border); gtk_style_context_get_padding (context, GTK_STATE_FLAG_NORMAL, &padding); x += border.left + padding.left; y += border.top + padding.top; total_w -= border.left + border.right + padding.left + padding.right; h -= border.top + border.bottom + padding.top + padding.bottom; gtk_style_context_restore (context); tries = priv->tries; utries = priv->utries; pens = priv->pens; total = tries * TRY_POINTS + utries * UTRY_POINTS + pens * PEN_POINTS; gtk_style_context_save (context); gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR); w = total_w / (total / 7.0); for (i = 0; i < tries; i++) { render_bar (context, cr, x, y, w, h, RUGBY_SCORE_TYPE_TRY); x += w; } w = total_w / (total / 5.0); for (i = 0; i < utries; i++) { render_bar (context, cr, x, y, w, h, RUGBY_SCORE_TYPE_UTRY); x += w; } w = total_w / (total / 3.0); for (i = 0; i < pens; i++) { render_bar (context, cr, x, y, w, h, RUGBY_SCORE_TYPE_PEN); x += w; } gtk_style_context_restore (context); } static void rugby_cell_renderer_score_class_init (RugbyCellRendererScoreClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass); obj_class->get_property = rugby_cell_renderer_score_get_property; obj_class->set_property = rugby_cell_renderer_score_set_property; cell_class->get_preferred_width = rugby_cell_renderer_score_get_preferred_width; cell_class->get_preferred_height = rugby_cell_renderer_score_get_preferred_height; cell_class->render = rugby_cell_renderer_score_render; g_object_class_install_property (obj_class, PROP_TRIES, g_param_spec_int ("tries", "Tries", "Number of tries", 0, 50, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_UTRIES, g_param_spec_int ("utries", "Unconverted Tries", "Number of Unconverted Tries", 0, 50, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PENS, g_param_spec_int ("pens", "Penalties", "Number of penalties", 0, 50, 0, G_PARAM_READWRITE)); g_type_class_add_private (klass, sizeof (RugbyCellRendererScorePrivate)); } static void rugby_cell_renderer_score_init (RugbyCellRendererScore *cellscore) { RugbyCellRendererScorePrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE ((cellscore), RUGBY_TYPE_CELL_RENDERER_SCORE, RugbyCellRendererScorePrivate); priv->tries = 0; priv->utries = 0; priv->pens = 0; gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (cellscore), 2, 2); cellscore->priv = priv; } GtkCellRenderer * rugby_cell_renderer_score_new (void) { return g_object_new (RUGBY_TYPE_CELL_RENDERER_SCORE, NULL); }