247 lines
7.1 KiB
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);
|
|
}
|