On Fr, 2005-11-04 at 07:55 +0100, Jean Bréfort wrote: > Le jeudi 03 novembre 2005 à 22:42 +0100, Christian Neumair a écrit : > > On Mi, 2005-11-02 at 16:58 +0100, Jean Bréfort wrote: > > > I have one objection against the goffice patch: the changes in > > > go-graph-widget.c are much too large. This widget was devised to be used > > > in other apps, and do part of the job on initialization (create a graph > > > with a chart and the renderer). It looks like a complete rewrite. I > > > would prefer a new widget, or add a go_graph_widget_set_graph function > > > if we want to change the default graph. > > > > Updated according to your suggestions on IRC. Do you insist on the chart > > getters/setters? This patch still doesn't include them. > > It would be nice (at least get), because it is one less step for clients > which need only one chart.
New proposed patch, which also fixes refcounting for widget-constructed graphs and the some return_if_fail statements. -- Christian Neumair <[EMAIL PROTECTED]>
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 4 Nov 2005 10:43:17 -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 4 Nov 2005 10:43:17 -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 4 Nov 2005 10:43:18 -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 <goffice/goffice-config.h>' && \
+ 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 4 Nov 2005 10:43:18 -0000
@@ -20,7 +20,9 @@
#include <goffice-config.h>
#include "go-graph-widget.h"
-#include <gtk/gtkdrawingarea.h>
+#include "go-marshal.h"
+#include <gtk/gtklayout.h>
+#include <goffice/graph/gog-graph.h>
#include <goffice/graph/gog-object.h>
#include <goffice/graph/gog-renderer-pixbuf.h>
#include <goffice/utils/go-math.h>
@@ -30,42 +32,82 @@
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 +131,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,7 +165,20 @@ 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 :
+ if (w->graph != NULL)
+ g_object_unref (w->graph);
+ w->graph = GOG_GRAPH (g_object_ref (g_value_get_object (value)));
+ g_object_set (w->renderer, "model", w->graph, NULL);
+ break;
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
return; /* NOTE : RETURN */
}
@@ -140,6 +195,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 +227,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));
}
static gint
@@ -193,34 +276,49 @@ 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);
+ w->graph = NULL;
+
+ w->renderer = g_object_new (GOG_RENDERER_PIXBUF_TYPE, 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,
+ * or NULL to make #GOGraphWidget create its own graph, which will
+ * have an associated chart.
* 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));
+ GtkWidget *ret;
+ gboolean self_owned_graph;
+
+ g_return_val_if_fail (graph == NULL || IS_GOG_GRAPH (graph), NULL);
+
+ self_owned_graph = (graph == NULL);
+
+ if (self_owned_graph) {
+ graph = g_object_new (GOG_GRAPH_TYPE, NULL);
+ gog_object_add_by_name (GOG_OBJECT (graph), "Chart", NULL);
+ }
+
+ ret = GTK_WIDGET (g_object_new (GO_GRAPH_WIDGET_TYPE, "graph", graph, NULL));
+
+ if (self_owned_graph)
+ g_object_unref (graph);
+
+ return ret;
}
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 :
@@ -236,14 +334,32 @@ go_graph_widget_get_graph (GOGraphWidget
}
/**
+ * go_graph_widget_set_graph :
+ * @widget : #GOGraphWidget
+ * @graph: #GogGraph
+ *
+ * Sets the #GogGraph embedded in the widget. May not be NULL.
+ **/
+void
+go_graph_widget_set_graph (GOGraphWidget *widget,
+ GogGraph *graph)
+{
+ g_return_if_fail (IS_GO_GRAPH_WIDGET (widget));
+ g_return_if_fail (IS_GOG_GRAPH (graph));
+
+ g_object_set (widget, "graph", graph, NULL);
+}
+
+/**
* go_graph_widget_get_chart :
* @widget : #GOGraphWidget
*
- * Returns the #GogChart created by go_graph_widget_new().
+ * Returns the #GogChart of the embedded #GogGraph.
**/
GogChart *
go_graph_widget_get_chart (GOGraphWidget *widget)
{
g_return_val_if_fail (IS_GO_GRAPH_WIDGET (widget), NULL);
- return widget->chart;
+
+ return GOG_CHART (gog_object_get_child_by_name (GOG_OBJECT (widget->graph), "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 4 Nov 2005 10:43:18 -0000
@@ -32,12 +32,23 @@ 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);
+void go_graph_widget_set_graph (GOGraphWidget *widget,
+ GogGraph *graph);
GogChart *go_graph_widget_get_chart (GOGraphWidget *widget);
G_END_DECLS
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 4 Nov 2005 10:43:18 -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 4 Nov 2005 10:43:18 -0000
@@ -75,7 +75,7 @@ main (int argc, char *argv[])
gtk_box_pack_end (GTK_BOX (box), w, FALSE, FALSE, 2);
/* Create a graph widget and add it to the GtkVBox */
- w = go_graph_widget_new ();
+ w = go_graph_widget_new (NULL);
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));
signature.asc
Description: This is a digitally signed message part
_______________________________________________ gnumeric-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/gnumeric-list
