#include "rugby-possibility-widget.h" struct _RugbyPossibilityWidget { GtkDrawingArea parent_instance; RugbyPossibility *possibility; }; G_DEFINE_TYPE (RugbyPossibilityWidget, rugby_possibility_widget, GTK_TYPE_DRAWING_AREA) enum { PROP_0, PROP_POSSIBILITY, N_PROPS }; static GParamSpec *properties[N_PROPS]; #define FIXED_HEIGHT 20 static void rugby_possibility_widget_dispose (GObject *object) { RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object); g_clear_object (&self->possibility); G_OBJECT_CLASS (rugby_possibility_widget_parent_class)->dispose (object); } static void rugby_possibility_widget_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object); switch (prop_id) { case PROP_POSSIBILITY: g_value_set_object (value, self->possibility); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void rugby_possibility_widget_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object); switch (prop_id) { case PROP_POSSIBILITY: self->possibility = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void rugby_possibility_widget_get_preferred_height (GtkWidget *widget, gint *minimum_height, gint *natural_height) { if (minimum_height) *minimum_height = FIXED_HEIGHT; if (natural_height) *natural_height = FIXED_HEIGHT; } static void render_bar (cairo_t *cr, GtkStyleContext *context, gint x, gint y, gint w, gint h, const gchar *style) { gtk_style_context_save (context); gtk_style_context_add_class (context, style); gtk_render_background (context, cr, x, y, w, h); gtk_style_context_restore (context); } static gboolean rugby_possibility_widget_draw (GtkWidget *widget, cairo_t *cr) { RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (widget); gint width = gtk_widget_get_allocated_width (widget); gint height = gtk_widget_get_allocated_height (widget); gint x = 0, y = 0; GtkStyleContext *context = gtk_widget_get_style_context (widget); gtk_style_context_save (context); gtk_style_context_add_class (context, "level-cell"); gtk_render_background (context, cr, x, y, width, height); gtk_render_frame (context, cr, x, y, width, height); gint tries, utries, kicks; g_object_get (self->possibility, "tries", &tries, "utries", &utries, "kicks", &kicks, NULL); gint score = tries * 7 + utries * 5 + kicks * 3; gtk_style_context_add_class (context, "fill-block"); // Tries gint w = width / (score / 7.0); for (int i = 0; i < tries; i++) { render_bar (cr, context, x, y, w, height, "score-try"); x += w; } // Unconverted tries w = width / (score / 5.0); for (int i = 0; i < utries; i++) { render_bar (cr, context, x, y, w, height, "score-utry"); x += w; } // Unconverted kicks w = width / (score / 3.0); for (int i = 0; i < kicks; i++) { render_bar (cr, context, x, y, w, height, "score-kick"); x += w; } gtk_style_context_restore (context); return TRUE; } static void rugby_possibility_widget_constructed (GObject *obj) { RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (obj); gint tries, utries, kicks; g_autoptr (GString) tooltip = g_string_new (NULL); g_object_get (self->possibility, "tries", &tries, "utries", &utries, "kicks", &kicks, NULL); if (tries > 0 || utries > 0) g_string_append_printf (tooltip, "%d tries, %d converted", tries + utries, tries); if (kicks > 0) { if (tooltip->len == 0) g_string_append_printf (tooltip, "%d kicks", kicks); else g_string_append_printf (tooltip, ", %d kicks", kicks); } gtk_widget_set_tooltip_text (GTK_WIDGET (self), tooltip->str); G_OBJECT_CLASS (rugby_possibility_widget_parent_class)->constructed (obj); } static void rugby_possibility_widget_class_init (RugbyPossibilityWidgetClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->constructed = rugby_possibility_widget_constructed; object_class->dispose = rugby_possibility_widget_dispose; object_class->get_property = rugby_possibility_widget_get_property; object_class->set_property = rugby_possibility_widget_set_property; widget_class->draw = rugby_possibility_widget_draw; widget_class->get_preferred_height = rugby_possibility_widget_get_preferred_height; properties[PROP_POSSIBILITY] = g_param_spec_object ("possibility", "Possibility", "Possibility to be represented", RUGBY_TYPE_POSSIBILITY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties (object_class, N_PROPS, properties); } static void rugby_possibility_widget_init (RugbyPossibilityWidget *self) { } GtkWidget * rugby_possibility_widget_new (RugbyPossibility *possibility) { return g_object_new (RUGBY_TYPE_POSSIBILITY_WIDGET, "possibility", possibility, NULL); }