This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/mcp/gm-cell-renderer-text.c

247 lines
7.1 KiB
C

#include <string.h>
#include <config.h>
#include <glib/gi18n.h>
#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);
}