#include "common.h" #include "customcellrendererrate.h" /* Private class member */ #define PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ CUSTOM_TYPE_CELL_RENDERER_RATE, \ CustomCellRendererRatePrivate)) typedef struct _CustomCellRendererRatePrivate CustomCellRendererRatePrivate; struct _CustomCellRendererRatePrivate { gfloat rate; gchar buffer[10]; }; static void custom_cell_renderer_rate_get_property(GObject* object, guint param_id, GValue* value, GParamSpec* pspec); static void custom_cell_renderer_rate_set_property(GObject* object, guint param_id, const GValue* value, GParamSpec* pspec); static void convert_rate_to_string(gchar* str, guint size, gfloat rate); enum { PROP_0, PROP_RATE, }; G_DEFINE_TYPE(CustomCellRendererRate, custom_cell_renderer_rate, GTK_TYPE_CELL_RENDERER_TEXT) static void custom_cell_renderer_rate_init(CustomCellRendererRate* cell_rate) { g_object_set(cell_rate, "xalign", 1.0f, NULL); convert_rate_to_string(PRIVATE(cell_rate)->buffer, sizeof(PRIVATE(cell_rate)->buffer), PRIVATE(cell_rate)->rate); g_object_set(cell_rate, "text", PRIVATE(cell_rate)->buffer, NULL); } static void custom_cell_renderer_rate_class_init(CustomCellRendererRateClass *cell_rate_class) { GObjectClass *object_class; /* GtkCellRendererClass *cell_renderer_class; */ object_class = G_OBJECT_CLASS(cell_rate_class); /* cell_renderer_class = GTK_CELL_RENDERER_CLASS(cell_rate_class); */ g_type_class_add_private(object_class, sizeof(CustomCellRendererRatePrivate)); object_class->set_property = custom_cell_renderer_rate_set_property; object_class->get_property = custom_cell_renderer_rate_get_property; g_object_class_install_property(object_class, PROP_RATE, g_param_spec_float("rate", "Rate", "The transfer rate in kilo (1000) byte per second", 0.0, G_MAXFLOAT, 0, G_PARAM_READABLE | G_PARAM_WRITABLE)); } GtkCellRenderer* custom_cell_renderer_rate_new(void) { return g_object_new(CUSTOM_TYPE_CELL_RENDERER_RATE, NULL); } void custom_cell_renderer_rate_get_property(GObject* object, guint param_id, GValue* value, GParamSpec* pspec) { CustomCellRendererRate* rate = CUSTOM_CELL_RENDERER_RATE(object); switch (param_id) { case PROP_RATE: g_value_set_float(value, PRIVATE(rate)->rate); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); } } void custom_cell_renderer_rate_set_property(GObject* object, guint param_id, const GValue* value, GParamSpec* pspec) { CustomCellRendererRate* rate = CUSTOM_CELL_RENDERER_RATE(object); gboolean changed = FALSE; switch (param_id) { case PROP_RATE: { gfloat rate_value = g_value_get_float(value); if (PRIVATE(rate)->rate != rate_value) { PRIVATE(rate)->rate = rate_value; changed = TRUE; } break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); } if (changed) { convert_rate_to_string(PRIVATE(rate)->buffer, sizeof(PRIVATE(rate)->buffer), PRIVATE(rate)->rate); g_object_set(rate, "text", PRIVATE(rate)->buffer, NULL); } } void convert_rate_to_string(gchar* str, guint size, gfloat rate) { if (rate <= 0.0f) { g_assert(size >= 1); *str = '\0'; } else if (rate < 0.9f) { g_snprintf(str, size, "%3.0fB", rate * 1000.0f); } else if (rate <= 900.0f) { g_snprintf(str, size, "%3.2fkB", rate); } else if (rate <= 900000.0f) { g_snprintf(str, size, "%3.2fMB", rate / 1000.0f); } else { g_snprintf(str, size, "%3.2fGB", rate / 1000000.0f); } }