Hi,

Here's attached a patch that enhances graph legends with horizontal
layout and multi-column/line capabilities.

http://emmanuel.pacaud.free.fr/screenshots/gnumeric/gnumeric-legend.png

Since 1.6 is going to be released very soon, do you think this patch is
commitable ?

        Emmanuel.
? goffice/graph/.gog-legend.c.swp
Index: goffice/graph/gog-axis.c
===================================================================
RCS file: /cvs/gnome/goffice/goffice/graph/gog-axis.c,v
retrieving revision 1.138
diff -u -p -r1.138 gog-axis.c
--- goffice/graph/gog-axis.c	30 Aug 2005 00:50:11 -0000	1.138
+++ goffice/graph/gog-axis.c	20 Sep 2005 13:29:16 -0000
@@ -1898,7 +1898,7 @@ gog_axis_view_padding_request (GogView *
 	GogAxisType type = gog_axis_get_atype (axis);
 	GogObjectPosition pos;
 	GogViewAllocation tmp = *bbox;
-	GogViewRequisition req;
+	GogViewRequisition req, available;
 	GogViewPadding label_padding, child_padding;
 	GSList *ptr;
 	double const pad_h = gog_renderer_pt2r_y (view->renderer, PAD_HACK);
@@ -1910,7 +1910,9 @@ gog_axis_view_padding_request (GogView *
 		child = ptr->data;
 		pos = child->model->position;
 		if (IS_GOG_LABEL (child->model) && !(pos & GOG_POSITION_MANUAL)) {
-			gog_view_size_request (child, &req);
+			available.w = bbox->w;
+			available.h = bbox->h;
+			gog_view_size_request (child, &available, &req);
 			if (type == GOG_AXIS_X) 
 				label_padding.hb += req.h + pad_h;
 			else  
@@ -1952,23 +1954,26 @@ gog_axis_view_size_allocate (GogView *vi
 	GogViewAllocation tmp = *bbox;
 	GogViewAllocation const *plot_area = gog_chart_view_get_plot_area (view->parent);
 	GogViewAllocation child_bbox;
-	GogViewRequisition req;
+	GogViewRequisition req, available;
 	GogObjectPosition pos;
 	double const pad_h = gog_renderer_pt2r_y (view->renderer, PAD_HACK);
 	double const pad_w = gog_renderer_pt2r_x (view->renderer, PAD_HACK);
 
+	available.w = bbox->w;
+	available.h = bbox->h;
+
 	for (ptr = view->children; ptr != NULL ; ptr = ptr->next) {
 		child = ptr->data;
 		pos = child->model->position;
 		if (IS_GOG_LABEL (child->model) && (pos & GOG_POSITION_MANUAL)) {
-			gog_view_size_request (child, &req);
+			gog_view_size_request (child, &available, &req);
 			child_bbox = gog_object_get_manual_allocation (gog_view_get_model (child), 
 								       plot_area, &req);
 			gog_view_size_allocate (child, &child_bbox);
 		} else {
 			if (GOG_POSITION_IS_SPECIAL (pos)) {
 				if (IS_GOG_LABEL (child->model)) {
-					gog_view_size_request (child, &req);
+					gog_view_size_request (child, &available, &req);
 					if (type == GOG_AXIS_X) {
 						child_bbox.x = plot_area->x + (plot_area->w - req.w) / 2.0;
 						child_bbox.w = plot_area->w;
Index: goffice/graph/gog-label.c
===================================================================
RCS file: /cvs/gnome/goffice/goffice/graph/gog-label.c,v
retrieving revision 1.44
diff -u -p -r1.44 gog-label.c
--- goffice/graph/gog-label.c	18 Aug 2005 14:20:35 -0000	1.44
+++ goffice/graph/gog-label.c	20 Sep 2005 13:29:16 -0000
@@ -437,7 +437,9 @@ typedef GogOutlinedViewClass	GogTextView
 static GogViewClass *text_view_parent_klass;
 
 static void
-gog_text_view_size_request (GogView *v, GogViewRequisition *req)
+gog_text_view_size_request (GogView *v, 
+			    GogViewRequisition const *available,
+			    GogViewRequisition *req)
 {
 	GogText *text = GOG_TEXT (v->model);
 	char *str = gog_text_get_str (text);
@@ -452,7 +454,7 @@ gog_text_view_size_request (GogView *v, 
 		req->h = aabr.h;
 		g_free (str);
 	}
-	text_view_parent_klass->size_request (v, req);
+	text_view_parent_klass->size_request (v, available, req);
 }
 
 static void
Index: goffice/graph/gog-legend.c
===================================================================
RCS file: /cvs/gnome/goffice/goffice/graph/gog-legend.c,v
retrieving revision 1.45
diff -u -p -r1.45 gog-legend.c
--- goffice/graph/gog-legend.c	8 Aug 2005 08:56:59 -0000	1.45
+++ goffice/graph/gog-legend.c	20 Sep 2005 13:29:16 -0000
@@ -34,6 +34,8 @@
 #include <gtk/gtknotebook.h>
 #include <glib/gi18n.h>
 
+#include <math.h>
+
 struct _GogLegend {
 	GogOutlinedObject base;
 
@@ -222,9 +224,15 @@ GSF_CLASS (GogLegend, gog_legend,
 
 typedef struct {
 	GogOutlinedView	base;
-	double		line_height;
+	gboolean	is_vertical;
+	double		element_width;
+	double		element_height;
+	unsigned	element_per_blocks;
+	unsigned	num_blocks;
 	gboolean	uses_lines;
+	double		label_offset;
 } GogLegendView;
+
 typedef GogOutlinedViewClass	GogLegendViewClass;
 
 #define GOG_LEGEND_VIEW_TYPE	(gog_legend_view_get_type ())
@@ -234,151 +242,203 @@ typedef GogOutlinedViewClass	GogLegendVi
 static GogViewClass *lview_parent_klass;
 
 typedef struct {
-	GogView const *view;
-	GogViewRequisition maximum;
-	gboolean	uses_lines;
-	GogStyle* legend_style;
-} size_closure;
+	GogView const 		*view;
+	GogViewRequisition 	 maximum;
+	gboolean		 uses_lines;
+	GogStyle		*legend_style;
+} SizeClosure;
 
 static void
-cb_size_elements (unsigned i, GogStyle const *style, char const *name,
-		  size_closure *dat)
+cb_size_elements (unsigned i, GogStyle const *style, 
+		  char const *name, SizeClosure *data)
 {
 	GOGeometryAABR aabr;
 	
-	gog_renderer_push_style (dat->view->renderer, dat->legend_style);
-	gog_renderer_get_text_AABR (dat->view->renderer, name, &aabr);
-	gog_renderer_pop_style (dat->view->renderer);
-
-	if (dat->maximum.w < aabr.w)
-		dat->maximum.w = aabr.w;
-	if (dat->maximum.h < aabr.h)
-		dat->maximum.h = aabr.h;
-	if (!dat->uses_lines && (style->interesting_fields & GOG_STYLE_LINE))
-		dat->uses_lines = TRUE;
+	gog_renderer_push_style (data->view->renderer, data->legend_style);
+	gog_renderer_get_text_AABR (data->view->renderer, name, &aabr);
+	gog_renderer_pop_style (data->view->renderer);
+
+	if (data->maximum.w < aabr.w)
+		data->maximum.w = aabr.w;
+	if (data->maximum.h < aabr.h)
+		data->maximum.h = aabr.h;
+	if (!data->uses_lines && (style->interesting_fields & GOG_STYLE_LINE))
+		data->uses_lines = TRUE;
 }
 
 static void
-gog_legend_view_size_request (GogView *v, GogViewRequisition *avail)
+gog_legend_view_size_request (GogView *v, 
+			      GogViewRequisition const *available, 
+			      GogViewRequisition *req)
 {
-	size_closure dat;
-	GogViewRequisition res;
 	GogChart *chart = GOG_CHART (v->model->parent);
+	GogLegendView *glv = GOG_LEGEND_VIEW (v);
 	GogLegend *l = GOG_LEGEND (v->model);
-	unsigned n, mult = 1;
+	GogViewRequisition child_req, residual;
+	SizeClosure data;
+	double available_space, element_size, swatch_padding;
+	unsigned num_elements;
+
+	residual = *available;
+	req->w = req->h = 0;
+	gog_view_size_child_request (v, available, req, &child_req);
+	lview_parent_klass->size_request (v, available, req);
+	residual.w -= req->w;
+	residual.h -= req->h;
+
+	glv->is_vertical = gog_object_get_position_flags (GOG_OBJECT (l), GOG_POSITION_COMPASS) &
+		(GOG_POSITION_E | GOG_POSITION_W);
+
+	gog_chart_get_cardinality (chart, NULL, &num_elements);
+	
+	data.view = v;
+	data.maximum.w = 0.;
+	data.maximum.h = gog_renderer_pt2r_y (v->renderer, l->swatch_size_pts) * 1.2;
+	data.uses_lines = FALSE;
+	data.legend_style = GOG_STYLED_OBJECT (l)->style;
 
-#warning TODO : make this smarter (multiple columns and shrinking text)
-	dat.view = v;
-	dat.maximum.w = 0.;
-	dat.maximum.h = gog_renderer_pt2r_y (v->renderer, l->swatch_size_pts);
-	dat.uses_lines = FALSE;
-	dat.legend_style = GOG_STYLED_OBJECT (l)->style;
 	gog_chart_foreach_elem (chart, TRUE,
-		(GogEnumFunc) cb_size_elements, &dat);
-	((GogLegendView *)v)->line_height = dat.maximum.h;
-	((GogLegendView *)v)->uses_lines = dat.uses_lines;
-
-	if (dat.uses_lines)
-		mult = 3;
-
-	/* 1/2 between swatch and label */
-	res.w = dat.maximum.w + gog_renderer_pt2r_x (v->renderer,
-		mult * l->swatch_size_pts + .5 * l->swatch_padding_pts);
-	gog_chart_get_cardinality (chart, NULL, &n);
-	res.h = n * dat.maximum.h;
-
-	gog_view_size_child_request (v, avail, &res);
-	avail->w = res.w;
-	avail->h = res.h;
-	lview_parent_klass->size_request (v, avail);
+		(GogEnumFunc) cb_size_elements, &data);
+
+	swatch_padding = gog_renderer_pt2r_x (v->renderer, l->swatch_padding_pts);
+	glv->label_offset = gog_renderer_pt2r_x (v->renderer,
+		(data.uses_lines ? 3 : 1) * l->swatch_size_pts + swatch_padding * .5);
+
+	data.maximum.w += glv->label_offset + swatch_padding;
+	
+	glv->element_height = data.maximum.h;
+	glv->element_width = data.maximum.w;
+	glv->uses_lines = data.uses_lines;
+
+	available_space = glv->is_vertical ? residual.h : residual.w;
+	element_size = glv->is_vertical ? data.maximum.h : data.maximum.w;	
+	
+	glv->element_per_blocks = available_space > 0. ? floor (available_space / element_size) : 0;
+	
+	if (glv->element_per_blocks < 1) {
+	       	req->w = req->h = -1;
+		return;
+	}
+
+	glv->num_blocks = floor ((num_elements - 1) / glv->element_per_blocks) + 1;
+
+	if (glv->is_vertical) {
+		req->h += MIN (glv->element_per_blocks, num_elements) * data.maximum.h;
+		req->w += glv->num_blocks * data.maximum.w - swatch_padding;
+	} else {
+		req->h += glv->num_blocks * data.maximum.h;
+		req->w += MIN (glv->element_per_blocks, num_elements) * data.maximum.w - swatch_padding;
+	}
+
+	req->w = MAX (child_req.w, req->w);
+	req->h = MAX (child_req.h, req->h);
 }
 
 typedef struct {
 	GogView const *view;
+	double x, y;
+	double element_step_x, element_step_y;
+	double block_step_x, block_step_y;
 	GogViewAllocation swatch;
-	double step;
-	double label_offset;
-	double bottom;
 	ArtVpath line_path[3];
-} render_closure;
+} RenderClosure;
 
 static void
 cb_render_elements (unsigned i, GogStyle const *base_style, char const *name,
-		    render_closure *dat)
+		    RenderClosure *data)
 {
-	GogViewAllocation swatch = dat->swatch;
-	GogView  const   *v = dat->view;
+	GogView const *view = data->view;
+	GogLegendView *glv = GOG_LEGEND_VIEW (view);
+	GogRenderer *renderer = view->renderer;
+	GogStyledObject *obj = GOG_STYLED_OBJECT (data->view->model);
 	GogStyle *style = NULL;
-	GogViewAllocation pos, rectangle;
-	GogStyledObject *obj = GOG_STYLED_OBJECT (dat->view->model);
 	GogStyle *legend_style = obj->style;
-	
-	swatch.y += i * dat->step;
-	/* Allow for floating point inaccuracy */
-	if (swatch.y > dat->bottom + 0.0001)
-		return;
+	GogViewAllocation pos, rectangle;
 
+	if (i > 0) {
+		if ((i % glv->element_per_blocks) != 0) {
+			data->x += data->element_step_x;
+			data->y += data->element_step_y;
+		} else {
+			data->x += data->block_step_x;
+			data->y += data->block_step_y;
+		}
+	}
+	
 	if (base_style->interesting_fields & GOG_STYLE_LINE) { /* line and marker */
 		style = (GogStyle *)base_style;
-		gog_renderer_push_style (v->renderer, style);
-		dat->line_path[0].y = dat->line_path[1].y =  swatch.y + dat->step / 2.;
-		gog_renderer_draw_sharp_path (v->renderer, dat->line_path);
-		gog_renderer_draw_marker (v->renderer,
-			(dat->line_path[0].x + dat->line_path[1].x) / 2.,
-			dat->line_path[0].y);
+		gog_renderer_push_style (renderer, style);
+		data->line_path[0].x = data->x;
+		data->line_path[1].x = data->x + data->swatch.w * 3.;
+		data->line_path[0].y = 
+		data->line_path[1].y = data->y + glv->element_height / 2.;
+		gog_renderer_draw_sharp_path (renderer, data->line_path);
+		gog_renderer_draw_marker (renderer, data->x + data->swatch.w  * 1.5, 
+					  data->line_path[0].y);
 	} else {					/* area swatch */
 		style = gog_style_dup (base_style);
-		style->outline.width = 0; /* hairline */
+		style->outline.width = 0; 
 		style->outline.color = RGBA_BLACK;
 
-		rectangle = swatch;
-		rectangle.y += (dat->step - swatch.h) / 2.0;
+		rectangle = data->swatch;
+		rectangle.x += data->x;
+		rectangle.y += data->y;
 
-		gog_renderer_push_style (v->renderer, style);
-		gog_renderer_draw_sharp_rectangle (v->renderer, &rectangle);
+		gog_renderer_push_style (renderer, style);
+		gog_renderer_draw_sharp_rectangle (renderer, &rectangle);
 	}
-	pos.x = swatch.x + dat->label_offset;
-	pos.y = swatch.y;
-	pos.h = pos.w = -1;
-	gog_renderer_pop_style (v->renderer);
-	gog_renderer_push_style (v->renderer, legend_style);
-	gog_renderer_draw_text (v->renderer, name, &pos, GTK_ANCHOR_NW, NULL);
+	gog_renderer_pop_style (renderer);
 
-	gog_renderer_pop_style (v->renderer);
+	pos.x = data->x + glv->label_offset;
+	pos.y = data->y + glv->element_height / 2.0;
+	pos.w = pos.h = -1;
 
-	if (style != base_style)
+	gog_renderer_push_style (renderer, legend_style);
+	gog_renderer_draw_text (renderer, name, &pos, GTK_ANCHOR_W, NULL);
+	gog_renderer_pop_style (renderer);
+
+	if (style != base_style && style != NULL)
 		g_object_unref (style);
 }
 
 static void
 gog_legend_view_render (GogView *v, GogViewAllocation const *bbox)
 {
-	render_closure dat;
+	GogLegendView *glv = GOG_LEGEND_VIEW (v);
 	GogLegend *l = GOG_LEGEND (v->model);
-	double pad_x = gog_renderer_pt2r_x (v->renderer, l->swatch_padding_pts);
+	RenderClosure data;
 
 	(lview_parent_klass->render) (v, bbox);
+	
+	if (glv->element_per_blocks < 1)
+		return;
 
-	dat.view = v;
-	dat.swatch.x  = v->residual.x;
-	dat.swatch.y  = v->residual.y;
-	dat.swatch.w  = gog_renderer_pt2r_x (v->renderer, l->swatch_size_pts);
-	dat.swatch.h  = gog_renderer_pt2r_y (v->renderer, l->swatch_size_pts);
-	dat.label_offset = dat.swatch.w + pad_x / 2.;
-	if (((GogLegendView *)v)->uses_lines) {
-		dat.line_path[0].code = ART_MOVETO;
-		dat.line_path[1].code = ART_LINETO;
-		dat.line_path[2].code = ART_END;
-		dat.line_path[0].x = dat.swatch.x;
-		dat.line_path[1].x = dat.swatch.x + 3. * dat.swatch.w;
-		dat.swatch.x += dat.swatch.w;
-		dat.label_offset += dat.swatch.w;
+	if (glv->uses_lines) {
+		data.line_path[0].code = ART_MOVETO;
+		data.line_path[1].code = ART_LINETO;
+		data.line_path[2].code = ART_END;
 	}
-	dat.step      = ((GogLegendView *)v)->line_height;
-	dat.bottom    = v->residual.y + v->residual.h -
-		((GogLegendView *)v)->line_height;
+	data.view = v;
+	data.x = v->residual.x;
+	data.y = v->residual.y;
+	data.element_step_x = glv->is_vertical ? 0 : glv->element_width;
+	data.element_step_y = glv->is_vertical ? glv->element_height : 0;
+	data.block_step_x = glv->is_vertical ? 
+		+ glv->element_width : 
+		- glv->element_width * (glv->element_per_blocks - 1);
+	data.block_step_y = glv->is_vertical ? 
+		- glv->element_height * (glv->element_per_blocks - 1) :
+		+ glv->element_height;
+	data.swatch.w = gog_renderer_pt2r_x (v->renderer, 
+					     l->swatch_size_pts);
+	data.swatch.h = gog_renderer_pt2r_y (v->renderer, 
+					     l->swatch_size_pts);
+	data.swatch.x = (glv->label_offset - data.swatch.w -
+			 gog_renderer_pt2r_x (v->renderer, l->swatch_padding_pts) * .5) * .5;
+	data.swatch.y = (glv->element_height - data.swatch.h) * .5;
+	
 	gog_chart_foreach_elem (GOG_CHART (v->model->parent), TRUE,
-		(GogEnumFunc) cb_render_elements, &dat);
+		(GogEnumFunc) cb_render_elements, &data);
 }
 
 static void
Index: goffice/graph/gog-outlined-object.c
===================================================================
RCS file: /cvs/gnome/goffice/goffice/graph/gog-outlined-object.c,v
retrieving revision 1.12
diff -u -p -r1.12 gog-outlined-object.c
--- goffice/graph/gog-outlined-object.c	8 Aug 2005 08:56:59 -0000	1.12
+++ goffice/graph/gog-outlined-object.c	20 Sep 2005 13:29:16 -0000
@@ -103,7 +103,9 @@ gog_outlined_object_get_pad (GogOutlined
 static GogViewClass *oview_parent_klass;
 
 static void
-gog_outlined_view_size_request (GogView *v, GogViewRequisition *req)
+gog_outlined_view_size_request (GogView *v, 
+				GogViewRequisition const *available,
+				GogViewRequisition *req)
 {
 	GogOutlinedObject *goo = GOG_OUTLINED_OBJECT (v->model);
 	double outline = gog_renderer_line_size (v->renderer, 
Index: goffice/graph/gog-view.c
===================================================================
RCS file: /cvs/gnome/goffice/goffice/graph/gog-view.c,v
retrieving revision 1.31
diff -u -p -r1.31 gog-view.c
--- goffice/graph/gog-view.c	15 Aug 2005 11:30:21 -0000	1.31
+++ goffice/graph/gog-view.c	20 Sep 2005 13:29:16 -0000
@@ -209,7 +209,9 @@ gog_view_padding_request_real (GogView *
 }
 
 static void
-gog_view_size_request_real (GogView *view, GogViewRequisition *req)
+gog_view_size_request_real (GogView *view, 
+			    GogViewRequisition const *available,
+			    GogViewRequisition *req)
 {
 	req->w = req->h = 1.;
 }
@@ -220,8 +222,8 @@ gog_view_size_allocate_real (GogView *vi
 	GSList *ptr;
 	GogView *child;
 	GogObjectPosition pos;
-	GogViewRequisition req;
-	GogViewAllocation tmp, available = *allocation, res = *allocation;
+	GogViewRequisition req, available;
+	GogViewAllocation tmp, res = *allocation;
 	double const pad_h = gog_renderer_pt2r_y (view->renderer, PAD_HACK);
 	double const pad_w = gog_renderer_pt2r_x (view->renderer, PAD_HACK);
 
@@ -230,15 +232,19 @@ gog_view_size_allocate_real (GogView *vi
 
 		pos = child->model->position;
 		if (pos & GOG_POSITION_MANUAL) {
-			gog_view_size_request (child, &req);
+			available.w = res.w;
+			available.h = res.h;
+			gog_view_size_request (child, &available, &req);
 			tmp = gog_object_get_manual_allocation (gog_view_get_model (child),
-								&available, &req);
+								allocation, &req);
 			gog_view_size_allocate (child, &tmp);
 		} else if (pos & GOG_POSITION_COMPASS) {
 			gboolean vertical = TRUE;
 
 			/* Dead simple */
-			gog_view_size_request (child, &req);
+			available.w = res.w;
+			available.h = res.h;
+			gog_view_size_request (child, &available, &req);
 			if (req.h > res.h)
 				req.h = res.h;
 			if (req.w > res.w)
@@ -438,24 +444,29 @@ gog_view_padding_request (GogView *view,
 /**
  * gog_view_size_request :
  * @view : a #GogView
+ * @available : available space.
  * @requisition : a #GogViewRequisition.
  *
- * When called @requisition holds the available space and is populated with the
- * desired size based on that input and other elements of the view or its model's
- * state (eg the position).
+ * When called @available holds the available space and @requisition is populated
+ * with the desired size based on that input and other elements of the view or 
+ * its model's state (eg the position).
  *
  * Remember that the size request is not necessarily the size a view will
  * actually be allocated.
  **/
 void
-gog_view_size_request (GogView *view, GogViewRequisition *requisition)
+gog_view_size_request (GogView *view, 
+		       GogViewRequisition const *available, 
+		       GogViewRequisition *requisition)
 {
 	GogViewClass *klass = GOG_VIEW_GET_CLASS (view);
 
 	g_return_if_fail (klass != NULL);
 	g_return_if_fail (requisition != NULL);
+	g_return_if_fail (available != NULL);
+
 	if (klass->size_request)
-		(klass->size_request) (view, requisition);
+		(klass->size_request) (view, available, requisition);
 	else
 		requisition->w = requisition->h = 1.;
 }
@@ -519,12 +530,12 @@ gog_view_render	(GogView *view, GogViewA
 
 	g_return_if_fail (view->renderer != NULL);
 
-	if (view->residual.w < 0 || view->residual.h < 0)
+	if (view->allocation.w < 0 || view->allocation.h < 0)
 		return;
 	
 	if (klass->clip) {
 		gog_renderer_push_clip (view->renderer, 
-					gog_renderer_get_rectangle_vpath (&view->allocation));
+			gog_renderer_get_rectangle_vpath (&view->allocation));
 		klass->render (view, bbox);
 		gog_renderer_pop_clip (view->renderer);
 	}
@@ -584,26 +595,29 @@ gog_view_info_at_point (GogView *view, d
 /**
  * gog_view_size_child_request :
  * @view : #GogView
- * @avail : the amount of space available in total
- * @req : holds the amount of space for the parent, and is expanded with the
- * 	needs of the children.
+ * @available : the amount of space available in total
+ * @req : additionnal requisition
+ * @min_req : minimum size for displaying all children
  *
- * Takes the space requested in @req and expands it to hold all @view->model's
+ * Returns additionnal requision in @req which must be added to parent requisition,
+ * and minimum requisition in @min_req which is minimum space for displaying all
  * children.
- * Returns the necessary size in @req.
  **/
 void
 gog_view_size_child_request (GogView *view,
-			     GogViewRequisition const *avail,
-			     GogViewRequisition *res)
+			     GogViewRequisition const *available,
+			     GogViewRequisition *req,
+			     GogViewRequisition *min_req)
 {
 	GSList *ptr, *list;
 	GogView *child;
 	GogObjectPosition pos;
-	GogViewRequisition req;
+	GogViewRequisition child_req;
 	double const pad_h = gog_renderer_pt2r_y (view->renderer, PAD_HACK);
 	double const pad_w = gog_renderer_pt2r_x (view->renderer, PAD_HACK);
 
+	req->w = req->h = min_req->w = min_req->h = 0.;
+
 	/* walk the list in reverse */
 	list = g_slist_reverse (g_slist_copy (view->children));
 	for (ptr = list; ptr != NULL ; ptr = ptr->next) {
@@ -614,19 +628,23 @@ gog_view_size_child_request (GogView *vi
 			g_warning ("manual is not supported yet");
 		} else if (pos & GOG_POSITION_COMPASS) {
 			/* Dead simple */
-			gog_view_size_request (child, &req);
+			gog_view_size_request (child, available, &child_req);
 
 			if (pos & (GOG_POSITION_N|GOG_POSITION_S)) {
-				if (req.h > 0)
-					res->h += req.h + pad_h;
-			} else if (res->h < req.h)
-				res->h = req.h;
+				if (child_req.h > 0) {
+					req->h += child_req.h + pad_h;
+					min_req->h += child_req.h + pad_h;
+				}
+			} else if (min_req->h < child_req.h)
+				min_req->h = child_req.h;
 
 			if (pos & (GOG_POSITION_E|GOG_POSITION_W)) {
-				if (req.w > 0)
-					res->w += req.w + pad_w;
-			} else if (res->w < req.w)
-				res->w = req.w;
+				if (child_req.w > 0) {
+					req->w += child_req.w + pad_w;
+					min_req->w += child_req.w + pad_w;
+				}
+			} else if (min_req->w < child_req.w)
+				min_req->w = child_req.w;
 
 		} else if (!(GOG_POSITION_IS_SPECIAL (pos)))
 			g_warning ("[GogView::size_child_request] unexpected position %x for child %p of %p",
Index: goffice/graph/gog-view.h
===================================================================
RCS file: /cvs/gnome/goffice/goffice/graph/gog-view.h,v
retrieving revision 1.13
diff -u -p -r1.13 gog-view.h
--- goffice/graph/gog-view.h	8 Aug 2005 08:57:00 -0000	1.13
+++ goffice/graph/gog-view.h	20 Sep 2005 13:29:16 -0000
@@ -49,8 +49,10 @@ typedef struct {
 
 	/* Virtuals */
 	void	 (*state_init)    (GogView *);
-	void	 (*padding_request) 		(GogView *, GogViewAllocation const *bbox, GogViewPadding *padding);
-	void	 (*size_request)    		(GogView *, GogViewRequisition *req);
+	void	 (*padding_request) 		(GogView *view, GogViewAllocation const *bbox, 
+						 GogViewPadding *padding);
+	void	 (*size_request)    		(GogView *view, GogViewRequisition const *available, 
+						 GogViewRequisition *req);
 	void	 (*size_allocate)   		(GogView *, GogViewAllocation const *bbox);
 	void	 (*render)        (GogView *, GogViewAllocation const *bbox);
 	gboolean (*info_at_point) (GogView *, double x, double y,
@@ -72,7 +74,8 @@ void	   gog_view_render	     (GogView *v
 void       gog_view_queue_redraw     (GogView *v);
 void       gog_view_queue_resize     (GogView *v);
 void	   gog_view_padding_request  (GogView *v, GogViewAllocation const *bbox, GogViewPadding *padding);
-void       gog_view_size_request     (GogView *v, GogViewRequisition *req);
+void       gog_view_size_request     (GogView *v, GogViewRequisition const *available, 
+				      GogViewRequisition *requisition);
 void       gog_view_size_allocate    (GogView *v, GogViewAllocation const *a);
 gboolean   gog_view_update_sizes     (GogView *v);
 gboolean   gog_view_info_at_point    (GogView *container, double x, double y,
@@ -84,7 +87,8 @@ GogView   *gog_view_find_child_view  (Go
 /* protected */
 void gog_view_size_child_request (GogView *v,
 				  GogViewRequisition const *avail,
-				  GogViewRequisition *req);
+				  GogViewRequisition *req,
+				  GogViewRequisition *min_req);
 
 G_END_DECLS
 
_______________________________________________
gnumeric-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnumeric-list

Reply via email to