#include #include #include #include "gm-cell-renderer-text.h" #include "gm-debug.h" struct _GmCellRendererTextPrivate { gchar *name; gchar *status; gint width; }; #define GM_CELL_RENDERER_TEXT_GET_PRIVATE(object)( \ G_TYPE_INSTANCE_GET_PRIVATE((object), \ GM_TYPE_CELL_RENDERER_TEXT, GmCellRendererTextPrivate)) static void gm_cell_renderer_text_class_init(GmCellRendererTextClass *klass); static void gm_cell_renderer_text_init(GmCellRendererText *cell); static void cell_renderer_text_finalize(GObject *object); static void cell_renderer_text_get_property(GObject *object, guint param_id, GValue *value, GParamSpec *pspec); static void cell_renderer_text_set_property(GObject *object, guint param_id, GValue const *value, GParamSpec *pspec); static void cell_renderer_text_get_size(GtkCellRenderer *cell, GtkWidget *widget, GdkRectangle *cell_area, gint *x_offset, gint *y_offset, gint *width, gint *height); static void cell_renderer_text_render(GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags); static void cell_renderer_text_update_text(GmCellRendererText *cell, GtkWidget *widget, gint new_width, gboolean selected); /* Properties */ enum { PROP_0, PROP_NAME, PROP_STATUS }; G_DEFINE_TYPE (GmCellRendererText, gm_cell_renderer_text, GTK_TYPE_CELL_RENDERER_TEXT); static gpointer parent_class; static void gm_cell_renderer_text_class_init(GmCellRendererTextClass *klass) { GObjectClass *object_class; GtkCellRendererClass *cell_class; object_class = G_OBJECT_CLASS(klass); cell_class = GTK_CELL_RENDERER_CLASS(klass); parent_class = g_type_class_peek_parent(klass); object_class->finalize = cell_renderer_text_finalize; object_class->get_property = cell_renderer_text_get_property; object_class->set_property = cell_renderer_text_set_property; cell_class->get_size = cell_renderer_text_get_size; cell_class->render = cell_renderer_text_render; g_object_class_install_property(object_class, PROP_NAME, g_param_spec_string("name", "Name", "Player name", NULL, G_PARAM_READWRITE)); g_object_class_install_property(object_class, PROP_STATUS, g_param_spec_string ("status", "Status", "Contact status string", NULL, G_PARAM_READWRITE)); g_type_class_add_private(object_class, sizeof(GmCellRendererTextPrivate)); } static void gm_cell_renderer_text_init(GmCellRendererText *cell) { cell->priv = GM_CELL_RENDERER_TEXT_GET_PRIVATE(cell); //g_object_set(cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL); cell->priv->name = g_strdup(""); cell->priv->status = g_strdup(""); } static void cell_renderer_text_finalize(GObject *object) { GmCellRendererText *cell; cell = GM_CELL_RENDERER_TEXT(object); g_free(cell->priv->name); g_free(cell->priv->status); G_OBJECT_CLASS(parent_class)->finalize(object); } static void cell_renderer_text_get_property(GObject *object, guint param_id, GValue *value, GParamSpec *pspec) { GmCellRendererText *cell; cell = GM_CELL_RENDERER_TEXT(object); switch (param_id) { case PROP_NAME: g_value_set_string(value, cell->priv->name); break; case PROP_STATUS: g_value_set_string(value, cell->priv->status); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); break; } } static void cell_renderer_text_set_property(GObject *object, guint param_id, GValue const *value, GParamSpec *pspec) { GmCellRendererText *cell; const gchar *str; cell = GM_CELL_RENDERER_TEXT(object); switch (param_id) { case PROP_NAME: g_free(cell->priv->name); str = g_value_get_string(value); cell->priv->name = g_strdup(str); if (cell->priv->name) { g_strdelimit(cell->priv->name, "\n\r\t", ' '); } break; case PROP_STATUS: g_free(cell->priv->status); str = g_value_get_string(value); cell->priv->status = g_strdup(str); if (cell->priv->status) { g_strdelimit(cell->priv->status, "\n\r\t", ' '); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); break; } } static void cell_renderer_text_get_size(GtkCellRenderer *cell, GtkWidget *widget, GdkRectangle *cell_area, gint *x_offset, gint *y_offset, gint *width, gint *height) { GmCellRendererText *celltext; celltext = GM_CELL_RENDERER_TEXT(cell); cell_renderer_text_update_text(celltext, widget, 0, 0); GTK_CELL_RENDERER_CLASS(parent_class)->get_size(cell, widget, cell_area, x_offset, y_offset, width, height); } static void cell_renderer_text_render(GtkCellRenderer *cell, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { GmCellRendererText *celltext; celltext = GM_CELL_RENDERER_TEXT(cell); cell_renderer_text_update_text(celltext, widget, cell_area->width, (flags & GTK_CELL_RENDERER_SELECTED)); GTK_CELL_RENDERER_CLASS(parent_class)->render(cell, window, widget, background_area, cell_area, expose_area, flags); } static void cell_renderer_text_update_text(GmCellRendererText *cell, GtkWidget *widget, gint new_width, gboolean selected) { PangoAttrList *attr_list; PangoAttribute *attr_color, *attr_style, *attr_size; GtkStyle *style; GdkColor color; gchar *str; gboolean show_status = FALSE; gint font_size; cell->priv->width = new_width; attr_color = NULL; if (cell->priv->status && *(cell->priv->status) != '\0') { show_status = TRUE; } if (cell->priv->name != NULL) { str = g_strdup_printf("%s%s%s", cell->priv->name, !show_status ? "" : "\n", !show_status ? "" : cell->priv->status); } else { g_object_set(cell, "visible", TRUE, "weight", PANGO_WEIGHT_NORMAL, "text", "", NULL); return; } style = gtk_widget_get_style(widget); color = style->text_aa[GTK_STATE_NORMAL]; font_size = pango_font_description_get_size(style->font_desc) / PANGO_SCALE; attr_list = pango_attr_list_new(); attr_size = pango_attr_size_new(pango_font_description_get_size( style->font_desc) / (font_size >= 10 ? 1.2 : 1.0)); attr_size->start_index = 0; attr_size->end_index = strlen(cell->priv->name); pango_attr_list_insert(attr_list, attr_size); attr_style = pango_attr_style_new(PANGO_STYLE_ITALIC); attr_style->start_index = attr_size->end_index + 1; attr_style->end_index = -1; pango_attr_list_insert(attr_list, attr_style); if (!selected) { attr_color = pango_attr_foreground_new(color.red, color.green, color.blue); attr_color->start_index = attr_style->start_index; attr_color->end_index = -1; pango_attr_list_insert(attr_list, attr_color); } attr_size = pango_attr_size_new(pango_font_description_get_size( style->font_desc) / (font_size >= 10 ? 1.5 : 1.2)); attr_size->start_index = attr_style->start_index; attr_size->end_index = -1; pango_attr_list_insert(attr_list, attr_size); g_object_set(cell, "visible", TRUE, "weight", PANGO_WEIGHT_NORMAL, "text", str, "attributes", attr_list, NULL); pango_attr_list_unref(attr_list); g_free(str); } GtkCellRenderer * gm_cell_renderer_text_new (void) { return g_object_new(GM_TYPE_CELL_RENDERER_TEXT, NULL); }