Add AgChartRenderer class
It is a subclass of GdkCellRendererPixbuf specialised in displaying Astrognome chart previews.
This commit is contained in:
parent
7fe82cdc68
commit
13728943d6
@ -40,6 +40,7 @@ PKG_CHECK_MODULES([GDA], [libgda-5.0 libgda-sqlite-5.0])
|
||||
PKG_CHECK_MODULES([PIXBUF], [gdk-pixbuf-2.0])
|
||||
PKG_CHECK_MODULES([RSVG], [librsvg-2.0])
|
||||
PKG_CHECK_MODULES([SWE_GLIB], [swe-glib >= 2.1.0])
|
||||
PKG_CHECK_MODULES([CAIRO], [cairo]);
|
||||
|
||||
LIBGD_INIT([
|
||||
main-view
|
||||
|
@ -20,6 +20,7 @@ astrognome_source_files = \
|
||||
ag-preferences.c \
|
||||
ag-db.c \
|
||||
ag-display-theme.c \
|
||||
ag-chart-renderer.c \
|
||||
astrognome.c \
|
||||
$(NULL)
|
||||
|
||||
@ -32,9 +33,9 @@ AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Astrognome\" -DLOCALEDIR=\"$(localedir)\" -DPKGDA
|
||||
bin_PROGRAMS = astrognome
|
||||
|
||||
astrognome_SOURCES = $(astrognome_source_files) $(BUILT_SOURCES)
|
||||
astrognome_LDADD = $(SWE_GLIB_LIBS) $(GTK_LIBS) $(LIBXML_LIBS) $(LIBXSLT_LIBS) $(WEBKIT_LIBS) $(GDA_LIBS) $(PIXBUF_LIBS) $(RSVG_LIBS) $(top_builddir)/libgd/libgd.la
|
||||
astrognome_LDADD = $(SWE_GLIB_LIBS) $(GTK_LIBS) $(LIBXML_LIBS) $(LIBXSLT_LIBS) $(WEBKIT_LIBS) $(GDA_LIBS) $(PIXBUF_LIBS) $(RSVG_LIBS) $(CAIRO_LIBS) $(top_builddir)/libgd/libgd.la
|
||||
astrognome_LDFLAGS = -rdynamic
|
||||
astrognome_CFLAGS = $(SWE_GLIB_CFLAGS) $(CFLAGS) $(GTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(WEBKIT_CFLAGS) $(GDA_CFLAGS) $(PIXBUF_CFLAGS) $(RSVG_CFLAGS) -Wall
|
||||
astrognome_CFLAGS = $(SWE_GLIB_CFLAGS) $(CFLAGS) $(GTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(WEBKIT_CFLAGS) $(GDA_CFLAGS) $(PIXBUF_CFLAGS) $(RSVG_CFLAGS) $(CAIRO_CFLAGS) -Wall
|
||||
|
||||
# The following two lines generate a .dir-locals.el file, so
|
||||
# company-mode won’t die due to unknown includes
|
||||
|
305
src/ag-chart-renderer.c
Normal file
305
src/ag-chart-renderer.c
Normal file
@ -0,0 +1,305 @@
|
||||
#include <cairo.h>
|
||||
|
||||
#include "ag-chart-renderer.h"
|
||||
|
||||
typedef struct {
|
||||
gchar *css_class;
|
||||
gboolean checked;
|
||||
gboolean toggle_visible;
|
||||
} AgChartRendererPrivate;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
AG_CHART_RENDERER_PROP_CSS_CLASS,
|
||||
AG_CHART_RENDERER_PROP_CHECKED,
|
||||
AG_CHART_RENDERER_PROP_TOGGLE_VISIBLE,
|
||||
};
|
||||
|
||||
static void ag_chart_renderer_dispose(GObject *gobject);
|
||||
static void ag_chart_renderer_finalize(GObject *gobject);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(AgChartRenderer, ag_chart_renderer, GTK_TYPE_CELL_RENDERER_PIXBUF);
|
||||
|
||||
static void
|
||||
ag_chart_renderer_render(GtkCellRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
GtkWidget *widget,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(AG_CHART_RENDERER(renderer));
|
||||
int margin;
|
||||
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
gtk_style_context_save(context);
|
||||
gtk_style_context_add_class(context, "ag-chart-renderer");
|
||||
|
||||
if (priv->css_class) {
|
||||
gtk_style_context_add_class(context, priv->css_class);
|
||||
}
|
||||
|
||||
cairo_save(cr);
|
||||
gdk_cairo_rectangle(cr, cell_area);
|
||||
cairo_clip(cr);
|
||||
|
||||
cairo_translate(cr, cell_area->x, cell_area->y);
|
||||
|
||||
margin = MAX(AG_CHART_RENDERER_TILE_MARGIN, (int)((cell_area->width - AG_CHART_RENDERER_TILE_SIZE) / 2));
|
||||
|
||||
g_object_get(renderer, "pixbuf", &pixbuf, NULL);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
GdkRectangle area = {margin, margin, AG_CHART_RENDERER_TILE_SIZE, AG_CHART_RENDERER_TILE_SIZE};
|
||||
|
||||
g_debug("Rendering chart with preview image");
|
||||
|
||||
GTK_CELL_RENDERER_CLASS(ag_chart_renderer_parent_class)->render(renderer, cr, widget, &area, &area, flags);
|
||||
} else {
|
||||
g_debug("Rendering chart without preview image");
|
||||
|
||||
gtk_render_frame(context, cr, margin, margin, AG_CHART_RENDERER_TILE_SIZE, AG_CHART_RENDERER_TILE_SIZE);
|
||||
gtk_render_background(context, cr, margin, margin, AG_CHART_RENDERER_TILE_SIZE, AG_CHART_RENDERER_TILE_SIZE);
|
||||
}
|
||||
|
||||
gtk_style_context_restore(context);
|
||||
|
||||
if (priv->toggle_visible) {
|
||||
gint xpad,
|
||||
ypad,
|
||||
x_offset,
|
||||
check_x,
|
||||
check_y;
|
||||
|
||||
gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(renderer), &xpad, &ypad);
|
||||
|
||||
if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) {
|
||||
x_offset = xpad;
|
||||
} else {
|
||||
x_offset = cell_area->width - AG_CHART_RENDERER_CHECK_ICON_SIZE - xpad;
|
||||
}
|
||||
|
||||
check_x = x_offset;
|
||||
check_y = cell_area->height - AG_CHART_RENDERER_CHECK_ICON_SIZE - ypad;
|
||||
|
||||
gtk_style_context_save(context);
|
||||
gtk_style_context_add_class(context, GTK_STYLE_CLASS_CHECK);
|
||||
|
||||
if (priv->checked) {
|
||||
gtk_style_context_set_state(context, GTK_STATE_FLAG_CHECKED);
|
||||
}
|
||||
|
||||
gtk_render_background(context, cr, check_x, check_y, AG_CHART_RENDERER_CHECK_ICON_SIZE, AG_CHART_RENDERER_CHECK_ICON_SIZE);
|
||||
gtk_render_frame(context, cr, check_x, check_y, AG_CHART_RENDERER_CHECK_ICON_SIZE, AG_CHART_RENDERER_CHECK_ICON_SIZE);
|
||||
gtk_render_check(context, cr, check_x, check_y, AG_CHART_RENDERER_CHECK_ICON_SIZE, AG_CHART_RENDERER_CHECK_ICON_SIZE);
|
||||
|
||||
gtk_style_context_restore(context);
|
||||
}
|
||||
|
||||
cairo_restore(cr);
|
||||
}
|
||||
|
||||
void
|
||||
ag_chart_renderer_set_css_class(AgChartRenderer *chart_renderer, const gchar *css_class)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(chart_renderer);
|
||||
|
||||
g_free(priv->css_class);
|
||||
priv->css_class = g_strdup(css_class);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
ag_chart_renderer_get_css_class(AgChartRenderer *chart_renderer)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(chart_renderer);
|
||||
|
||||
return priv->css_class;
|
||||
}
|
||||
|
||||
void
|
||||
ag_chart_renderer_set_checked(AgChartRenderer *chart_renderer, gboolean checked)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(chart_renderer);
|
||||
|
||||
priv->checked = checked;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ag_chart_renderer_get_checked(AgChartRenderer *chart_renderer)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(chart_renderer);
|
||||
|
||||
return priv->checked;
|
||||
}
|
||||
|
||||
void
|
||||
ag_chart_renderer_set_toggle_visible(AgChartRenderer *chart_renderer, gboolean toggle_visible)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(chart_renderer);
|
||||
|
||||
priv->toggle_visible = toggle_visible;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ag_chart_renderer_get_toggle_visible(AgChartRenderer *chart_renderer)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(chart_renderer);
|
||||
|
||||
return priv->toggle_visible;
|
||||
}
|
||||
|
||||
static void
|
||||
ag_chart_renderer_get_property(GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
AgChartRenderer *chart_renderer = AG_CHART_RENDERER(gobject);
|
||||
|
||||
switch (prop_id) {
|
||||
case AG_CHART_RENDERER_PROP_CSS_CLASS:
|
||||
g_value_set_string(value, ag_chart_renderer_get_css_class(chart_renderer));
|
||||
|
||||
break;
|
||||
|
||||
case AG_CHART_RENDERER_PROP_CHECKED:
|
||||
g_value_set_boolean(value, ag_chart_renderer_get_checked(chart_renderer));
|
||||
|
||||
break;
|
||||
|
||||
case AG_CHART_RENDERER_PROP_TOGGLE_VISIBLE:
|
||||
g_value_set_boolean(value, ag_chart_renderer_get_toggle_visible(chart_renderer));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ag_chart_renderer_set_property(GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
AgChartRenderer *chart_renderer = AG_CHART_RENDERER(gobject);
|
||||
|
||||
switch (prop_id) {
|
||||
case AG_CHART_RENDERER_PROP_CSS_CLASS:
|
||||
ag_chart_renderer_set_css_class(chart_renderer, g_value_get_string(value));
|
||||
|
||||
break;
|
||||
|
||||
case AG_CHART_RENDERER_PROP_CHECKED:
|
||||
ag_chart_renderer_set_checked(chart_renderer, g_value_get_boolean(value));
|
||||
|
||||
break;
|
||||
|
||||
case AG_CHART_RENDERER_PROP_TOGGLE_VISIBLE:
|
||||
ag_chart_renderer_set_toggle_visible(chart_renderer, g_value_get_boolean(value));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ag_chart_renderer_class_init(AgChartRendererClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *)klass;
|
||||
GtkCellRendererClass *cell_renderer_class = (GtkCellRendererClass *)klass;
|
||||
|
||||
gobject_class->dispose = ag_chart_renderer_dispose;
|
||||
gobject_class->finalize = ag_chart_renderer_finalize;
|
||||
gobject_class->set_property = ag_chart_renderer_set_property;
|
||||
gobject_class->get_property = ag_chart_renderer_get_property;
|
||||
cell_renderer_class->render = ag_chart_renderer_render;
|
||||
|
||||
g_object_class_install_property(
|
||||
G_OBJECT_CLASS(klass),
|
||||
AG_CHART_RENDERER_PROP_CSS_CLASS,
|
||||
g_param_spec_string(
|
||||
"css-class",
|
||||
"css-class",
|
||||
"CSS Class",
|
||||
NULL,
|
||||
G_PARAM_STATIC_NAME
|
||||
| G_PARAM_STATIC_NICK
|
||||
| G_PARAM_STATIC_BLURB
|
||||
| G_PARAM_READABLE
|
||||
| G_PARAM_WRITABLE
|
||||
)
|
||||
);
|
||||
|
||||
g_object_class_install_property(
|
||||
G_OBJECT_CLASS(klass),
|
||||
AG_CHART_RENDERER_PROP_CHECKED,
|
||||
g_param_spec_boolean(
|
||||
"checked",
|
||||
"checked",
|
||||
"Checked",
|
||||
FALSE,
|
||||
G_PARAM_STATIC_NAME
|
||||
| G_PARAM_STATIC_NICK
|
||||
| G_PARAM_STATIC_BLURB
|
||||
| G_PARAM_READABLE
|
||||
| G_PARAM_WRITABLE
|
||||
)
|
||||
);
|
||||
|
||||
g_object_class_install_property(
|
||||
G_OBJECT_CLASS(klass),
|
||||
AG_CHART_RENDERER_PROP_TOGGLE_VISIBLE,
|
||||
g_param_spec_boolean(
|
||||
"toggle-visible",
|
||||
"toggle-visible",
|
||||
"Toggle visible",
|
||||
FALSE,
|
||||
G_PARAM_STATIC_NAME
|
||||
| G_PARAM_STATIC_NICK
|
||||
| G_PARAM_STATIC_BLURB
|
||||
| G_PARAM_READABLE
|
||||
| G_PARAM_WRITABLE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
ag_chart_renderer_init(AgChartRenderer *chart_renderer)
|
||||
{
|
||||
AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(chart_renderer);
|
||||
|
||||
priv->checked = FALSE;
|
||||
priv->toggle_visible = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ag_chart_renderer_dispose(GObject *gobject)
|
||||
{
|
||||
G_OBJECT_CLASS(ag_chart_renderer_parent_class)->dispose(gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
ag_chart_renderer_finalize (GObject *gobject)
|
||||
{
|
||||
g_signal_handlers_destroy(gobject);
|
||||
G_OBJECT_CLASS(ag_chart_renderer_parent_class)->finalize(gobject);
|
||||
}
|
||||
|
||||
AgChartRenderer *
|
||||
ag_chart_renderer_new(void)
|
||||
{
|
||||
AgChartRenderer *chart_renderer = NULL;
|
||||
|
||||
chart_renderer = g_object_new(AG_TYPE_CHART_RENDERER, NULL);
|
||||
|
||||
return chart_renderer;
|
||||
}
|
58
src/ag-chart-renderer.h
Normal file
58
src/ag-chart-renderer.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef __AG_CHART_RENDERER_H__
|
||||
#define __AG_CHART_RENDERER_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define AG_TYPE_CHART_RENDERER \
|
||||
(ag_chart_renderer_get_type())
|
||||
#define AG_CHART_RENDERER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
AG_TYPE_CHART_RENDERER, \
|
||||
AgChartRenderer))
|
||||
#define AG_CHART_RENDERER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
AG_TYPE_CHART_RENDERER, \
|
||||
AgChartRendererClass))
|
||||
#define IS_AG_CHART_RENDERER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
AG_TYPE_CHART_RENDERER))
|
||||
#define IS_AG_CHART_RENDERER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
AG_TYPE_CHART_RENDERER))
|
||||
#define AG_CHART_RENDERER_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
AG_TYPE_CHART_RENDERER, \
|
||||
AgChartRendererClass))
|
||||
|
||||
typedef struct _AgChartRenderer AgChartRenderer;
|
||||
typedef struct _AgChartRendererClass AgChartRendererClass;
|
||||
|
||||
struct _AgChartRendererClass
|
||||
{
|
||||
GtkCellRendererPixbufClass parent_class;
|
||||
};
|
||||
|
||||
struct _AgChartRenderer
|
||||
{
|
||||
GtkCellRendererPixbuf parent;
|
||||
};
|
||||
|
||||
#define AG_CHART_RENDERER_TILE_SIZE 256
|
||||
#define AG_CHART_RENDERER_CHECK_ICON_SIZE 40
|
||||
#define AG_CHART_RENDERER_TILE_MARGIN AG_CHART_RENDERER_CHECK_ICON_SIZE / 4
|
||||
#define AG_CHART_RENDERER_TILE_MARGIN_BOTTOM AG_CHART_RENDERER_CHECK_ICON_SIZE / 8
|
||||
|
||||
GType ag_chart_renderer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
AgChartRenderer *ag_chart_renderer_new(void);
|
||||
|
||||
void ag_chart_renderer_set_toggle_visible(AgChartRenderer *chart_renderer, gboolean toggle_visible);
|
||||
|
||||
gboolean ag_chart_renderer_get_toggle_visible(AgChartRenderer *chart_renderer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __AG_CHART_RENDERER_H__ */
|
Loading…
Reference in New Issue
Block a user