From adeda41eb895e75bb3884c14e123509d792635fc Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Fri, 14 Jan 2011 21:02:31 +0100 Subject: implementing presets --- preset_renderer.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 preset_renderer.c (limited to 'preset_renderer.c') diff --git a/preset_renderer.c b/preset_renderer.c new file mode 100644 index 0000000..7a219d1 --- /dev/null +++ b/preset_renderer.c @@ -0,0 +1,190 @@ +/* + * GPL 2 + */ + +#include + +#include "preset_renderer.h" + +G_DEFINE_TYPE (CFmPresetRenderer, cfm_preset_renderer, GTK_TYPE_CELL_RENDERER); + +#define ABS_RANGE_LOW 60000000 +#define ABS_RANGE_HIGH 140000000 + +enum { + PROP_0, + PROP_FREQUENCY, + PROP_NAME, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static void cfm_preset_renderer_get_size_internal(GtkCellRenderer *cell, + GtkWidget *widget, GdkRectangle *cell_area, PangoLayout *layout, + gint *x_offset, gint *y_offset, gint *width, gint *height) +{ + CFmPresetRenderer *self = CFM_PRESET_RENDERER(cell); + PangoRectangle rect; + gint min_width, min_height; + + if (layout) { + g_object_ref(layout); + } else { + layout = gtk_widget_create_pango_layout(widget, NULL); + } + + pango_layout_set_text(layout, self->freq_text, -1); + pango_layout_get_pixel_extents(layout, NULL, &rect); + min_height = cell->ypad * 2 + rect.height; + min_width = cell->xpad * 2 + rect.width; + + if (self->name && self->name[0] != '\0') { + pango_layout_set_text(layout, self->name, -1); + pango_layout_get_pixel_extents(layout, NULL, &rect); + min_height = MAX(min_height, cell->ypad * 2 + rect.height); + min_width += rect.width; + } + + if (cell_area) { + if (x_offset) *x_offset = 0; /* This renderer always expands horiz. */ + if (y_offset) { + *y_offset = cell->yalign * (cell_area->height - min_height); + } + } else { + if (x_offset) *x_offset = 0; + if (y_offset) *y_offset = 0; + } + + if (width) *width = min_width; + if (height) *height = min_height; + + g_object_unref(layout); +} + +static void cfm_preset_renderer_get_size(GtkCellRenderer *cell, + GtkWidget *widget, GdkRectangle *cell_area, gint *x_offset, gint *y_offset, + gint *width, gint *height) +{ + PangoLayout *layout = gtk_widget_create_pango_layout(widget, NULL); + + cfm_preset_renderer_get_size_internal(cell, widget, cell_area, layout, + x_offset, y_offset, width, height); + + g_object_unref(layout); +} + +static void cfm_preset_renderer_render(GtkCellRenderer *cell, GdkWindow *window, + GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, + GdkRectangle *expose_area, GtkCellRendererState flags) +{ + CFmPresetRenderer *self = CFM_PRESET_RENDERER(cell); + PangoLayout *layout = gtk_widget_create_pango_layout(widget, NULL); + gint avail_width = cell_area->width - (2*cell->xpad); + gint x_offset, y_offset, x, y; + + cfm_preset_renderer_get_size_internal(cell, widget, cell_area, layout, + &x_offset, &y_offset, NULL, NULL); + + x = cell_area->x + x_offset + cell->xpad; + y = cell_area->y + y_offset + cell->ypad; + + pango_layout_set_text(layout, self->freq_text, -1); + gtk_paint_layout(widget->style, window, GTK_STATE_NORMAL, TRUE, expose_area, + widget, "cellrenderertext", x, y, layout); + + if (self->name && self->name[0] != '\0') { + pango_layout_set_text(layout, self->name, -1); + x += avail_width / 2; + gtk_paint_layout(widget->style, window, GTK_STATE_NORMAL, TRUE, + expose_area, widget, "cellrenderertext", x, y, layout); + } + + g_object_unref(layout); +} + +static void cfm_preset_renderer_init(CFmPresetRenderer *self) +{ + +} + +static void cfm_preset_renderer_set_property(GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + CFmPresetRenderer *self = CFM_PRESET_RENDERER(object); + switch (property_id) { + case PROP_NAME: + g_free(self->name); + self->name = g_value_dup_string(value); + break; + case PROP_FREQUENCY: + g_free(self->freq_text); + self->frequency = g_value_get_ulong(value); + self->freq_text = g_strdup_printf("%.1f MHz", + self->frequency / 1000000.0f); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void cfm_preset_renderer_get_property(GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + CFmPresetRenderer *self = CFM_PRESET_RENDERER(object); + switch (property_id) { + case PROP_NAME: + g_value_set_string(value, self->name); + break; + case PROP_FREQUENCY: + g_value_set_ulong(value, self->frequency); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void cfm_preset_renderer_finalize(GObject *object) +{ + CFmPresetRenderer *self = CFM_PRESET_RENDERER(object); + g_free(self->name); + g_free(self->freq_text); + + G_OBJECT_CLASS(cfm_preset_renderer_parent_class)->finalize(object); +} + +static void cfm_preset_renderer_class_init (CFmPresetRendererClass *klass) +{ + GObjectClass* gobject_class = G_OBJECT_CLASS (klass); + GtkCellRendererClass* parent_class = GTK_CELL_RENDERER_CLASS (klass); + GParamSpec *param_spec; + + parent_class->get_size = cfm_preset_renderer_get_size; + parent_class->render = cfm_preset_renderer_render; + gobject_class->set_property = cfm_preset_renderer_set_property; + gobject_class->get_property = cfm_preset_renderer_get_property; + gobject_class->finalize = cfm_preset_renderer_finalize; + + param_spec = g_param_spec_ulong("frequency", + "Frequency", + "This is the frequency of this preset, in Hz", + ABS_RANGE_LOW, ABS_RANGE_HIGH, ABS_RANGE_LOW, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_FREQUENCY] = param_spec; + g_object_class_install_property(gobject_class, PROP_FREQUENCY, param_spec); + param_spec = g_param_spec_string("name", + "Name", + "Name for this preset", + "", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_NAME] = param_spec; + g_object_class_install_property(gobject_class, PROP_NAME, param_spec); +} + +GtkCellRenderer* cfm_preset_renderer_new() +{ + return g_object_new(CFM_TYPE_PRESET_RENDERER, NULL); +} + -- cgit v1.2.3