Index: goffice/graph/gog-object.c =================================================================== RCS file: /cvs/gnome/goffice/goffice/graph/gog-object.c,v retrieving revision 1.50 diff -u -p -r1.50 gog-object.c --- goffice/graph/gog-object.c 17 Oct 2005 12:59:21 -0000 1.50 +++ goffice/graph/gog-object.c 2 Nov 2005 14:30:40 -0000 @@ -1023,6 +1023,22 @@ gog_object_get_child_by_role (GogObject } /** + * + * gog_object_get_child_by_name : + * @obj : a #GogObject + * @role : a #char to use as a filter + * + * A convenience routine to handle a unique child + * Returns NULL and spews an error if there is more than one. + **/ +GogObject * +gog_object_get_child_by_name (GogObject const *obj, const char *name) +{ + return gog_object_get_child_by_role (obj, + gog_object_find_role_by_name (obj, name)); +} + +/** * gog_object_is_deletable : * @obj : a #GogObject * Index: goffice/graph/gog-object.h =================================================================== RCS file: /cvs/gnome/goffice/goffice/graph/gog-object.h,v retrieving revision 1.28 diff -u -p -r1.28 gog-object.h --- goffice/graph/gog-object.h 25 Aug 2005 09:31:36 -0000 1.28 +++ goffice/graph/gog-object.h 2 Nov 2005 14:30:41 -0000 @@ -146,6 +146,7 @@ char const *gog_object_get_name (GogOb void gog_object_set_name (GogObject *obj, char *name, GError **err); GSList *gog_object_get_children (GogObject const *obj, GogObjectRole const *filter); GogObject *gog_object_get_child_by_role(GogObject const *obj, GogObjectRole const *role); +GogObject *gog_object_get_child_by_name(GogObject const *obj, const char *name); gpointer gog_object_get_editor (GogObject *obj, GogDataAllocator *dalloc, GOCmdContext *cc); GogView *gog_object_new_view (GogObject const *obj, GogView *view); Index: goffice/gtk/Makefile.am =================================================================== RCS file: /cvs/gnome/goffice/goffice/gtk/Makefile.am,v retrieving revision 1.30 diff -u -p -r1.30 Makefile.am --- goffice/gtk/Makefile.am 5 Sep 2005 21:02:55 -0000 1.30 +++ goffice/gtk/Makefile.am 2 Nov 2005 14:30:41 -0000 @@ -22,7 +22,9 @@ libgoffice_gtk_la_SOURCES = \ go-action-combo-stack.c \ go-action-combo-text.c \ \ - go-graph-widget.c + go-graph-widget.c \ + \ + go-marshal.list libgoffice_gtk_ladir = $(goffice_include_dir)/gtk @@ -68,6 +70,24 @@ UNUSED = \ go-dock-item-grip.h \ go-dock-layout.c \ go-dock-layout.h + +GENMARSHAL_COMMAND = $(GLIB_GENMARSHAL) --prefix=goffice_gtk_marshal +SUFFIXES = .list + +.list.h: + $(GENMARSHAL_COMMAND) --header $< >$@ + +.list.c: + (echo '/* This file has been automatically generated. Do not edit. */' && \ + echo '#include ' && \ + echo '#include "$*.h"' && \ + $(GENMARSHAL_COMMAND) --body $< ) >$@ + +BUILT_SOURCES = go-marshal.h + +non-intermediate: go-marshal.c + +CLEANFILES = go-marshal.h go-marshal.c EXTRA_DIST = $(UNUSED) Index: goffice/gtk/go-graph-widget.c =================================================================== RCS file: /cvs/gnome/goffice/goffice/gtk/go-graph-widget.c,v retrieving revision 1.3 diff -u -p -r1.3 go-graph-widget.c --- goffice/gtk/go-graph-widget.c 8 Aug 2005 08:57:00 -0000 1.3 +++ goffice/gtk/go-graph-widget.c 2 Nov 2005 14:30:41 -0000 @@ -20,7 +20,9 @@ #include #include "go-graph-widget.h" -#include +#include "go-marshal.h" +#include +#include #include #include #include @@ -30,42 +32,83 @@ enum { GRAPH_WIDGET_PROP_0, GRAPH_WIDGET_PROP_ASPECT_RATIO, + GRAPH_WIDGET_PROP_REFERENCE_DIRECTION, + GRAPH_WIDGET_PROP_ZOOM_FACTOR, + GRAPH_WIDGET_PROP_GRAPH }; -struct _GOGraphWidget{ - GtkDrawingArea base; +struct _GOGraphWidget{ + GtkLayout base; GogRendererPixbuf *renderer; GogGraph *graph; GogChart *chart; /* first chart created on init */ - double aspect_ratio, width, height, xoffset, yoffset; + + double aspect_ratio, zoom_factor; + int width, height, xoffset, yoffset; + GOGraphWidgetReferenceDirection reference_direction; /* Idle handler ID */ guint idle_id; }; -typedef GtkDrawingAreaClass GOGraphWidgetClass; +struct _GOGraphWidgetClass { + GtkLayoutClass parent_class; +}; static GtkWidgetClass *graph_parent_klass; +static void go_graph_widget_request_update (GOGraphWidget *w); + +GType +go_graph_widget_reference_direction_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GEnumValue values [] = { + { GO_GRAPH_WIDGET_REFERENCE_DIRECTION_NONE, "GO_GRAPH_WIDGET_REFERENCE_DIRECTION_NONE", "horizontal" }, + { GO_GRAPH_WIDGET_REFERENCE_DIRECTION_HORIZONTAL, "GO_GRAPH_WIDGET_REFERENCE_DIRECTION_HORIZONTAL", "horizontal" }, + { GO_GRAPH_WIDGET_REFERENCE_DIRECTION_VERTICAL, "GO_GRAPH_WIDGET_REFERENCE_DIRECTION_VERTICAL", "vertical" }, + { 0, NULL, NULL } + }; + + type = g_enum_register_static ("GOGraphWidgetReferenceDirection", values); + } + + return type; +} + /* Size allocation handler for the widget */ static void go_graph_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GOGraphWidget *w = GO_GRAPH_WIDGET (widget); + w->width = allocation->width; w->height = allocation->height; + if (w->aspect_ratio > 0.) { - if (w->height > w->width * w->aspect_ratio) { - w->yoffset = (w->height - w->width * w->aspect_ratio) / 2.; + if (w->reference_direction == GO_GRAPH_WIDGET_REFERENCE_DIRECTION_HORIZONTAL || + (w->reference_direction == GO_GRAPH_WIDGET_REFERENCE_DIRECTION_NONE && + w->zoom_factor > 1.0 ? + w->height < w->width * w->aspect_ratio : + w->height > w->width * w->aspect_ratio)) { + w->yoffset = MAX (0, w->height - w->width * w->aspect_ratio) / 2.; w->height = w->width * w->aspect_ratio; w->xoffset = 0; } else { - w->xoffset = (w->width - w->height / w->aspect_ratio) / 2.; + w->xoffset = MAX (0, w->width - w->height / w->aspect_ratio) / 2.; w->width = w->height / w->aspect_ratio; w->yoffset = 0; } } + + w->height *= w->zoom_factor; + w->width *= w->zoom_factor; + + gtk_layout_set_size (GTK_LAYOUT (w), w->width - w->xoffset, w->height - w->yoffset); + gog_renderer_pixbuf_update (w->renderer, w->width, w->height, 1.0); graph_parent_klass->size_allocate (widget, allocation); } @@ -89,7 +132,7 @@ go_graph_widget_expose_event (GtkWidget gdk_region_intersect (draw_region, event->region); if (!gdk_region_empty (draw_region)) { gdk_region_get_clipbox (draw_region, &draw_rect); - gdk_draw_pixbuf (widget->window, NULL, pixbuf, + gdk_draw_pixbuf (GTK_LAYOUT (widget)->bin_window, NULL, pixbuf, /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */ draw_rect.x - display_rect.x, draw_rect.y - display_rect.y, @@ -123,6 +166,21 @@ go_graph_widget_set_property (GObject *o w->aspect_ratio = g_value_get_double (value); w->xoffset = w->yoffset = 0.; break; + case GRAPH_WIDGET_PROP_REFERENCE_DIRECTION : + w->reference_direction = g_value_get_enum (value); + w->xoffset = w->yoffset = 0.; + break; + case GRAPH_WIDGET_PROP_ZOOM_FACTOR : + w->zoom_factor = g_value_get_double (value); + break; + case GRAPH_WIDGET_PROP_GRAPH : + w->graph = (GogGraph *) g_value_get_object (value); + w->renderer = g_object_new (GOG_RENDERER_PIXBUF_TYPE, + "model", g_object_ref (w->graph), + NULL); + g_signal_connect_swapped (w->renderer, "request_update", + G_CALLBACK (go_graph_widget_request_update), w); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec); return; /* NOTE : RETURN */ @@ -140,6 +198,15 @@ go_graph_widget_get_property (GObject *o case GRAPH_WIDGET_PROP_ASPECT_RATIO : g_value_set_double (value, w->aspect_ratio); break; + case GRAPH_WIDGET_PROP_REFERENCE_DIRECTION : + g_value_set_enum (value, w->reference_direction); + break; + case GRAPH_WIDGET_PROP_ZOOM_FACTOR : + g_value_set_double (value, w->zoom_factor); + break; + case GRAPH_WIDGET_PROP_GRAPH : + g_value_set_object (value, w->graph); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec); break; @@ -163,7 +230,26 @@ go_graph_widget_class_init (GOGraphWidge GRAPH_WIDGET_PROP_ASPECT_RATIO, g_param_spec_double ("aspect-ratio", "aspect-ratio", "Aspect ratio for rendering the graph, used only if greater than 0.", - -G_MAXDOUBLE, G_MAXDOUBLE, -1., G_PARAM_READWRITE)); + -G_MAXDOUBLE, G_MAXDOUBLE, -1., G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + GRAPH_WIDGET_PROP_REFERENCE_DIRECTION, + g_param_spec_enum ("reference-direction", "reference-direction", + "The direction that should be used as base direction for the aspect ratio. " + "The choice of this direction influences the size allocation behavior of the widget.", + go_graph_widget_reference_direction_get_type (), + GO_GRAPH_WIDGET_REFERENCE_DIRECTION_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + GRAPH_WIDGET_PROP_ZOOM_FACTOR, + g_param_spec_double ("zoom-factor", "zoom-factor", + "This factor determines how big the widget will actually be compared to its allocation size.", + 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + GRAPH_WIDGET_PROP_GRAPH, + g_param_spec_object ("graph", "graph", + "The graph to render.", + gog_graph_get_type (), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static gint @@ -193,34 +279,25 @@ go_graph_widget_request_update (GOGraphW static void go_graph_widget_init (GOGraphWidget *w) { - w->graph = (GogGraph *) g_object_new (GOG_GRAPH_TYPE, NULL); - w->renderer = g_object_new (GOG_RENDERER_PIXBUF_TYPE, - "model", w->graph, - NULL); - g_signal_connect_swapped (w->renderer, "request_update", - G_CALLBACK (go_graph_widget_request_update), w); - /* by default, create one chart and add it to the graph */ - w->chart = (GogChart *) - gog_object_add_by_name (GOG_OBJECT (w->graph), "Chart", NULL); w->idle_id = 0; } /** * go_graph_widget_new : * - * Creates a new #GOGraphWidget with an embedded #GogGraph. Also add a #GogChart inside - * graph. + * Creates a new #GOGraphWidget, which embeds the specified #GogGraph. * Returns the newly created #GOGraphWidget. **/ GtkWidget * -go_graph_widget_new (void) +go_graph_widget_new (GogGraph *graph) { - return GTK_WIDGET (g_object_new (GO_GRAPH_WIDGET_TYPE, NULL)); + g_return_val_if_fail (IS_GOG_GRAPH (graph), NULL); + return GTK_WIDGET (g_object_new (GO_GRAPH_WIDGET_TYPE, "graph", graph, NULL)); } GSF_CLASS (GOGraphWidget, go_graph_widget, go_graph_widget_class_init, go_graph_widget_init, - gtk_drawing_area_get_type ()) + gtk_layout_get_type ()) /** * go_graph_widget_get_graph : @@ -233,17 +310,4 @@ go_graph_widget_get_graph (GOGraphWidget { g_return_val_if_fail (IS_GO_GRAPH_WIDGET (widget), NULL); return widget->graph; -} - -/** - * go_graph_widget_get_chart : - * @widget : #GOGraphWidget - * - * Returns the #GogChart created by go_graph_widget_new(). - **/ -GogChart * -go_graph_widget_get_chart (GOGraphWidget *widget) -{ - g_return_val_if_fail (IS_GO_GRAPH_WIDGET (widget), NULL); - return widget->chart; } Index: goffice/gtk/go-graph-widget.h =================================================================== RCS file: /cvs/gnome/goffice/goffice/gtk/go-graph-widget.h,v retrieving revision 1.2 diff -u -p -r1.2 go-graph-widget.h --- goffice/gtk/go-graph-widget.h 8 Aug 2005 08:57:00 -0000 1.2 +++ goffice/gtk/go-graph-widget.h 2 Nov 2005 14:30:41 -0000 @@ -32,10 +32,19 @@ G_BEGIN_DECLS #define GO_GRAPH_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GO_GRAPH_WIDGET_TYPE, GOGraphWidget)) #define IS_GO_GRAPH_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GO_GRAPH_WIDGET_TYPE)) -typedef struct _GOGraphWidget GOGraphWidget; +typedef struct _GOGraphWidget GOGraphWidget; +typedef struct _GOGraphWidgetClass GOGraphWidgetClass; + +typedef enum { + GO_GRAPH_WIDGET_REFERENCE_DIRECTION_NONE, + GO_GRAPH_WIDGET_REFERENCE_DIRECTION_HORIZONTAL, + GO_GRAPH_WIDGET_REFERENCE_DIRECTION_VERTICAL +} GOGraphWidgetReferenceDirection; + +GType go_graph_widget_reference_direction_get_type (void); GType go_graph_widget_get_type (void); -GtkWidget *go_graph_widget_new (void); +GtkWidget *go_graph_widget_new (GogGraph *graph); GogGraph *go_graph_widget_get_graph (GOGraphWidget *widget); GogChart *go_graph_widget_get_chart (GOGraphWidget *widget); Index: goffice/gtk/go-marshal.list =================================================================== RCS file: goffice/gtk/go-marshal.list diff -N goffice/gtk/go-marshal.list --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ goffice/gtk/go-marshal.list 2 Nov 2005 14:30:41 -0000 @@ -0,0 +1 @@ +VOID:OBJECT,OBJECT Index: tests/pie-demo.c =================================================================== RCS file: /cvs/gnome/goffice/tests/pie-demo.c,v retrieving revision 1.7 diff -u -p -r1.7 pie-demo.c --- tests/pie-demo.c 8 Aug 2005 08:57:07 -0000 1.7 +++ tests/pie-demo.c 2 Nov 2005 14:30:41 -0000 @@ -74,11 +74,15 @@ main (int argc, char *argv[]) w = gtk_hseparator_new (); gtk_box_pack_end (GTK_BOX (box), w, FALSE, FALSE, 2); + /* create a graph and an associated chart */ + graph = (GogGraph *) g_object_new (GOG_GRAPH_TYPE, NULL); + chart = (GogChart *) gog_object_add_by_name (GOG_OBJECT (graph), "Chart", NULL); /* Create a graph widget and add it to the GtkVBox */ - w = go_graph_widget_new (); + w = go_graph_widget_new (graph); + g_object_set (G_OBJECT (w), "aspect-ratio", 1.0, NULL); + g_assert (graph == go_graph_widget_get_graph (GO_GRAPH_WIDGET (w))); + g_object_unref (graph); gtk_box_pack_end (GTK_BOX (box), w, TRUE, TRUE, 0); - /* Get the embedded graph */ - graph = go_graph_widget_get_graph (GO_GRAPH_WIDGET (w)); /* Add a title */ label = (GogLabel *) g_object_new (GOG_LABEL_TYPE, NULL); data = go_data_scalar_str_new (title, FALSE); @@ -88,8 +92,6 @@ main (int argc, char *argv[]) style = gog_styled_object_get_style (GOG_STYLED_OBJECT (label)); desc = pango_font_description_from_string ("Sans bold 16"); gog_style_set_font_desc (style, desc); - /* Get the chart created by the widget initialization */ - chart = go_graph_widget_get_chart (GO_GRAPH_WIDGET (w)); /* Create a pie plot and add it to the chart */ pie = (GogPlot *) gog_plot_new_by_name ("GogPiePlot"); gog_object_add_by_name (GOG_OBJECT (chart), "Plot", GOG_OBJECT (pie));