mirror of https://github.com/Gnucash/gnucash
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
266 lines
8.9 KiB
266 lines
8.9 KiB
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
/*
|
|
* gog-control-foocanvas.c :
|
|
*
|
|
* Copyright (C) 2003-2004 Jody Goldberg (jody@gnome.org)
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of version 2 of the GNU General Public
|
|
* License as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
* USA
|
|
*/
|
|
|
|
#include <goffice/goffice-config.h>
|
|
#include <goffice/graph/gog-control-foocanvas.h>
|
|
#include <goffice/graph/gog-graph.h>
|
|
#include <goffice/graph/gog-object.h>
|
|
#include <libfoocanvas/foo-canvas-util.h>
|
|
|
|
#include <gsf/gsf-impl-utils.h>
|
|
#include <glib/gi18n.h>
|
|
#include <math.h>
|
|
|
|
enum {
|
|
CTRL_FOO_PROP_0,
|
|
CTRL_FOO_PROP_H,
|
|
CTRL_FOO_PROP_W,
|
|
CTRL_FOO_PROP_MODEL,
|
|
CTRL_FOO_PROP_RENDERER,
|
|
CTRL_FOO_PROP_LOGICAL_WIDTH_PTS,
|
|
CTRL_FOO_PROP_LOGICAL_HEIGHT_PTS
|
|
};
|
|
|
|
static GObjectClass *parent_klass;
|
|
|
|
#define GOG_CONTROL_FOOCANVAS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOG_CONTROL_FOOCANVAS_TYPE, GogControlFooCanvasClass))
|
|
#define IS_GOG_CONTROL_FOOCANVAS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOG_CONTROL_FOOCANVAS_TYPE))
|
|
#define GOG_CONTROL_FOOCANVAS_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), GOG_CONTROL_FOOCANVAS_TYPE, GogControlFooCanvasClass))
|
|
|
|
static void
|
|
gog_control_foocanvas_set_property (GObject *gobject, guint param_id,
|
|
GValue const *value, GParamSpec *pspec)
|
|
{
|
|
GogControlFooCanvas *ctrl = GOG_CONTROL_FOOCANVAS (gobject);
|
|
gboolean setup_renderer = (ctrl->renderer == NULL);
|
|
|
|
switch (param_id) {
|
|
case CTRL_FOO_PROP_H: ctrl->new_h = g_value_get_double (value); break;
|
|
case CTRL_FOO_PROP_W: ctrl->new_w = g_value_get_double (value); break;
|
|
|
|
case CTRL_FOO_PROP_MODEL:
|
|
if (ctrl->renderer != NULL)
|
|
g_object_unref (ctrl->renderer);
|
|
ctrl->renderer = g_object_new (GOG_RENDERER_PIXBUF_TYPE,
|
|
"model", g_value_get_object (value),
|
|
NULL);
|
|
break;
|
|
|
|
case CTRL_FOO_PROP_RENDERER:
|
|
if (ctrl->renderer != NULL)
|
|
g_object_unref (ctrl->renderer);
|
|
ctrl->renderer = GOG_RENDERER_PIXBUF (g_value_get_object (value));
|
|
if (ctrl->renderer != NULL)
|
|
g_object_ref (ctrl->renderer);
|
|
break;
|
|
case CTRL_FOO_PROP_LOGICAL_WIDTH_PTS :
|
|
g_object_set_property (G_OBJECT (ctrl->renderer),
|
|
"logical_width_pts", value);
|
|
break;
|
|
case CTRL_FOO_PROP_LOGICAL_HEIGHT_PTS :
|
|
g_object_set_property (G_OBJECT (ctrl->renderer),
|
|
"logical_height_pts", value);
|
|
break;
|
|
|
|
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
|
|
return; /* NOTE : RETURN */
|
|
}
|
|
|
|
if (setup_renderer && ctrl->renderer != NULL)
|
|
g_signal_connect_object (G_OBJECT (ctrl->renderer),
|
|
"request_update",
|
|
G_CALLBACK (foo_canvas_item_request_update),
|
|
ctrl, G_CONNECT_SWAPPED);
|
|
foo_canvas_item_request_update (FOO_CANVAS_ITEM (ctrl));
|
|
}
|
|
|
|
static void
|
|
gog_control_foocanvas_get_property (GObject *gobject, guint param_id,
|
|
GValue *value, GParamSpec *pspec)
|
|
{
|
|
GogControlFooCanvas *ctrl = GOG_CONTROL_FOOCANVAS (gobject);
|
|
|
|
switch (param_id) {
|
|
case CTRL_FOO_PROP_H: g_value_set_double (value, ctrl->new_h); break;
|
|
case CTRL_FOO_PROP_W: g_value_set_double (value, ctrl->new_w); break;
|
|
case CTRL_FOO_PROP_RENDERER : g_value_set_object (value, ctrl->renderer); break;
|
|
case CTRL_FOO_PROP_LOGICAL_WIDTH_PTS :
|
|
g_object_get_property (G_OBJECT (ctrl->renderer),
|
|
"logical_width_pts", value);
|
|
break;
|
|
case CTRL_FOO_PROP_LOGICAL_HEIGHT_PTS :
|
|
g_object_get_property (G_OBJECT (ctrl->renderer),
|
|
"logical_height_pts", value);
|
|
break;
|
|
|
|
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gog_control_foocanvas_finalize (GObject *obj)
|
|
{
|
|
GogControlFooCanvas *ctrl = GOG_CONTROL_FOOCANVAS (obj);
|
|
|
|
if (ctrl->model != NULL) {
|
|
g_object_unref (ctrl->model);
|
|
ctrl->model = NULL;
|
|
}
|
|
if (ctrl->renderer != NULL) {
|
|
g_object_unref (ctrl->renderer);
|
|
ctrl->renderer = NULL;
|
|
}
|
|
(*parent_klass->finalize) (obj);
|
|
}
|
|
|
|
static void
|
|
gog_control_foocanvas_draw (FooCanvasItem *item, GdkDrawable *drawable,
|
|
GdkEventExpose *ev)
|
|
{
|
|
GogControlFooCanvas *ctrl = GOG_CONTROL_FOOCANVAS (item);
|
|
GdkPixbuf *buffer = gog_renderer_pixbuf_get (ctrl->renderer);
|
|
GdkRectangle display_rect, draw_rect;
|
|
GdkRegion *draw_region;
|
|
|
|
if (buffer) {
|
|
display_rect.x = item->x1;
|
|
display_rect.y = item->y1;
|
|
display_rect.width = item->x2 - item->x1;
|
|
display_rect.height = item->y2 - item->y1;
|
|
|
|
draw_region = gdk_region_rectangle (&display_rect);
|
|
gdk_region_intersect (draw_region, ev->region);
|
|
if (!gdk_region_empty (draw_region)) {
|
|
gdk_region_get_clipbox (draw_region, &draw_rect);
|
|
gdk_draw_pixbuf (drawable, NULL, buffer,
|
|
/* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
|
|
draw_rect.x - display_rect.x,
|
|
draw_rect.y - display_rect.y,
|
|
draw_rect.x,
|
|
draw_rect.y,
|
|
draw_rect.width,
|
|
draw_rect.height,
|
|
GDK_RGB_DITHER_NORMAL, 0, 0);
|
|
}
|
|
gdk_region_destroy (draw_region);
|
|
}
|
|
|
|
/* we are a canvas group, there could be some children */
|
|
if (FOO_CANVAS_ITEM_CLASS (parent_klass)->draw)
|
|
(FOO_CANVAS_ITEM_CLASS (parent_klass)->draw) (item, drawable, ev);
|
|
}
|
|
|
|
static void
|
|
gog_control_foocanvas_update (FooCanvasItem *item,
|
|
double i2w_dx, double i2w_dy, gint flags)
|
|
{
|
|
GogControlFooCanvas *ctrl = GOG_CONTROL_FOOCANVAS (item);
|
|
gboolean redraw;
|
|
int x1, x2, y1, y2;
|
|
int orig_x1 = item->x1, orig_x2 = item->x2, orig_y1 = item->y1, orig_y2 = item->y2;
|
|
|
|
if (FOO_CANVAS_ITEM_CLASS (parent_klass)->update)
|
|
(FOO_CANVAS_ITEM_CLASS (parent_klass)->update) (item, i2w_dx, i2w_dy, flags);
|
|
/* foo_canvas_group_update wipes the bbox */
|
|
item->x1 = orig_x1; item->x2 = orig_x2;
|
|
item->y1 = orig_y1; item->y2 = orig_y2;
|
|
|
|
foo_canvas_w2c (item->canvas, ctrl->base.xpos, ctrl->base.ypos, &x1, &y1);
|
|
foo_canvas_w2c (item->canvas, ctrl->base.xpos + ctrl->new_w, ctrl->base.ypos + ctrl->new_h, &x2, &y2);
|
|
|
|
redraw = gog_renderer_pixbuf_update (ctrl->renderer, x2-x1, y2-y1,
|
|
item->canvas->pixels_per_unit);
|
|
if (item->x1 != x1 || item->y1 != y1 || item->x2 != x2 || item->y2 != y2)
|
|
foo_canvas_update_bbox (FOO_CANVAS_ITEM (ctrl), x1, y1, x2, y2);
|
|
else if (redraw)
|
|
foo_canvas_item_request_redraw (FOO_CANVAS_ITEM (ctrl));
|
|
}
|
|
|
|
static void
|
|
gog_control_foocanvas_bounds (FooCanvasItem *item,
|
|
double *x1, double *y1, double *x2, double *y2)
|
|
{
|
|
*x1 = item->x1;
|
|
*x2 = item->x2;
|
|
*y1 = item->y1;
|
|
*y2 = item->y2;
|
|
}
|
|
|
|
static double
|
|
gog_control_foocanvas_point (FooCanvasItem *item, double x, double y, int cx, int cy,
|
|
FooCanvasItem **actual_item)
|
|
{
|
|
*actual_item = item;
|
|
return 0.;
|
|
}
|
|
|
|
static void
|
|
gog_control_foocanvas_class_init (GogControlFooCanvasClass *klass)
|
|
{
|
|
GObjectClass *gobject_klass = (GObjectClass *) klass;
|
|
FooCanvasItemClass *item_klass = (FooCanvasItemClass *) klass;
|
|
|
|
parent_klass = g_type_class_peek_parent (klass);
|
|
|
|
gobject_klass->set_property = gog_control_foocanvas_set_property;
|
|
gobject_klass->get_property = gog_control_foocanvas_get_property;
|
|
gobject_klass->finalize = gog_control_foocanvas_finalize;
|
|
item_klass->draw = gog_control_foocanvas_draw;
|
|
item_klass->update = gog_control_foocanvas_update;
|
|
item_klass->bounds = gog_control_foocanvas_bounds;
|
|
item_klass->point = gog_control_foocanvas_point;
|
|
|
|
g_object_class_install_property (gobject_klass, CTRL_FOO_PROP_H,
|
|
g_param_spec_double ("h", _("H"), _("Height"),
|
|
0, G_MAXDOUBLE, 100., G_PARAM_READWRITE));
|
|
g_object_class_install_property (gobject_klass, CTRL_FOO_PROP_W,
|
|
g_param_spec_double ("w", _("W"), _("Width"),
|
|
0, G_MAXDOUBLE, 100., G_PARAM_READWRITE));
|
|
g_object_class_install_property (gobject_klass, CTRL_FOO_PROP_MODEL,
|
|
g_param_spec_object ("model", "model",
|
|
"the GogObject this object displays",
|
|
GOG_OBJECT_TYPE, G_PARAM_WRITABLE));
|
|
g_object_class_install_property (gobject_klass, CTRL_FOO_PROP_RENDERER,
|
|
g_param_spec_object ("renderer", "renderer",
|
|
"the GogRendererPixbuf being displayed",
|
|
GOG_RENDERER_PIXBUF_TYPE, G_PARAM_READWRITE));
|
|
g_object_class_install_property (gobject_klass, CTRL_FOO_PROP_LOGICAL_WIDTH_PTS,
|
|
g_param_spec_double ("logical_width_pts", "Logical Width Pts",
|
|
"Logical width of the drawing area in pts",
|
|
0, G_MAXDOUBLE, 0, G_PARAM_READWRITE));
|
|
g_object_class_install_property (gobject_klass, CTRL_FOO_PROP_LOGICAL_HEIGHT_PTS,
|
|
g_param_spec_double ("logical_height_pts", "Logical Height Pts",
|
|
"Logical height of the drawing area in pts",
|
|
0, G_MAXDOUBLE, 0, G_PARAM_READWRITE));
|
|
}
|
|
|
|
static void
|
|
gog_control_foocanvas_init (GogControlFooCanvas *ctrl)
|
|
{
|
|
ctrl->new_h = ctrl->new_w = 0.;
|
|
}
|
|
|
|
GSF_CLASS (GogControlFooCanvas, gog_control_foocanvas,
|
|
gog_control_foocanvas_class_init, gog_control_foocanvas_init,
|
|
FOO_TYPE_CANVAS_GROUP)
|
|
|