align layout patch



Hello,

Here is a patch to make nautilus lay down icons basically like picture
below for auto lay out mode.
http://llanero.eresmas.net/nautilus/nautilus-align.png
 
Also this patch get rids of extra blank areas on the right side of the
icon view.

Stretching an icon in a folder with alot of files might result in
stretched icon moving to a new position that is off viewable area of the
window.
   
-- 
 "There has grown in the minds of certain groups in this country the
idea that just because
a man or corporation has made a profit out of the public for a number of
years, the
government and the courts are charged with guaranteeing such profit in
the future, even in
the face of changing circumstances and contrary to public interest. This
strange doctrine
is supported by neither statue or common law. Neither corporations or
individuals have the
right to come into court and ask that the clock of history be stopped,
or turned back."

-Robert Heinlein, Life Line, 1939
Index: nautilus/libnautilus-private/nautilus-icon-container.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v
retrieving revision 1.294
diff -u -b -B -p -u -r1.294 nautilus-icon-container.c
--- nautilus/libnautilus-private/nautilus-icon-container.c	15 Aug 2002 14:47:25 -0000	1.294
+++ nautilus/libnautilus-private/nautilus-icon-container.c	26 Aug 2002 10:02:09 -0000
@@ -797,78 +797,85 @@ get_icon_space_width (NautilusIconContai
 
 typedef struct {
 	double width;
+	double height_above;
+	double height_below;
 	double x_offset;
 	double y_offset;
-} IconPositions;
+} IconPositionInfo;
 
 static void
-lay_down_one_line (NautilusIconContainer *container,
-		   GList *line_start,
-		   GList *line_end,
-		   double y,
-		   GArray *positions)
+lay_down_all_lines (GList *icons,
+		    GQueue *positions,
+		    GArray *rows,
+		    GArray *columns,
+		    double extra_columns_space)
 {
-	GList *p;
-	NautilusIcon *icon;
-	double x;
-	IconPositions *position;
-	int i;
+	GList *p, *q;
+	IconPositionInfo *position;
+	double x, *column_width, *baseline;
+	unsigned int row;
+	unsigned int column;
 
 	/* FIXME: Should layout differently when in RTL base mode */
 
-	/* Lay out the icons along the baseline. */
+	/* Lay out the icons along the baseline and columns's centers. */
+	for(row = 0, p = icons; row < rows->len; row++) {
 	x = 0;
-	i = 0;
-	for (p = line_start; p != line_end; p = p->next) {
-		icon = p->data;
+		baseline = &g_array_index (rows, double, row);
 
-		position = &g_array_index (positions, IconPositions, i++);
+		for (column = 0; p != NULL && column < columns->len; column++, p = p->next) {
+			q = g_queue_pop_head_link (positions);
+			position = q->data;
+			column_width = &g_array_index (columns, double, column);		
 
 		icon_set_position
-			(icon,
-			 x + position->x_offset,
-			 y + position->y_offset);
+				((NautilusIcon*) p->data,
+				 (*column_width + extra_columns_space) / 2 - position->x_offset + x,
+				 *baseline + position->y_offset);
+
+			x += *column_width + extra_columns_space;
 
-		x += position->width;
+			g_free (position);
+			g_list_free_1 (q);
+		}
 	}
 }
 
 
 static void
-lay_down_icons_horizontal (NautilusIconContainer *container,
+lay_down_icons_align (NautilusIconContainer *container,
 			   GList *icons,
 			   double start_y)
 {
-	GList *p, *line_start;
+	GList *p;
+	GQueue *positions;
+	GArray *rows, *columns;
+	IconPositionInfo *position;
 	NautilusIcon *icon;
-	double canvas_width, line_width, space_width, y;
-	GArray *positions;
-	IconPositions *position;
+	GnomeCanvasItem *item;
 	ArtDRect bounds;
 	ArtDRect icon_bounds;
-	GnomeCanvasItem *item;
-	double max_height_above, max_height_below;
+	double canvas_width, line_width, space_width;
+	double  y, *baseline, extra_columns_space;
+	double max_height_above, max_height_below, *max_column_width;
 	double height_above, height_below;
-	int i;
+	unsigned int column, row;
 
+	g_return_if_fail (icons != NULL);
 	g_assert (NAUTILUS_IS_ICON_CONTAINER (container));
 
-	positions = g_array_new (FALSE, FALSE, sizeof (IconPositions));
+	positions = g_queue_new ();
+	columns   = g_array_new (FALSE, TRUE, sizeof (double));
 	
-	/* Lay out icons a line at a time. */
 	canvas_width = (GTK_WIDGET (container)->allocation.width
 			- container->details->left_margin
 			- container->details->right_margin)
 		/ GNOME_CANVAS (container)->pixels_per_unit;
+	
 	line_width = 0;
-	line_start = icons;
-	y = start_y;
-	i = 0;
-	max_height_above = 0;
-	max_height_below = 0;
+	column = 0;
 	for (p = icons; p != NULL; p = p->next) {
 		icon = p->data;
-
 		/* Get the width of the icon. */
 		item = GNOME_CANVAS_ITEM (icon->item);
 		
@@ -879,64 +886,138 @@ lay_down_icons_horizontal (NautilusIconC
 		
 		space_width = get_icon_space_width (container, &bounds);
 		
+		if (line_width + space_width - ICON_PAD_RIGHT <= canvas_width) {
+			++column;
+    		}	
+
 		icon_bounds = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
 
 		/* Calculate size above/below baseline */
 		height_above = icon_bounds.y1 - bounds.y0;
 		height_below = bounds.y1 - icon_bounds.y1;
 
-		/* If this icon doesn't fit, it's time to lay out the line that's queued up. */
+		position = g_new0 (IconPositionInfo, 1);
+		position->width = space_width;
+		position->height_above = height_above;
+		position->height_below = height_below;
+		position->y_offset = icon_bounds.y0 - icon_bounds.y1;
+		position->x_offset = (icon_bounds.x1 - icon_bounds.x0) / 2;
+		g_queue_push_tail (positions, position);
+	}
+	
+	/* sizes columns array to maximum possible
+	   number of columns */
+	g_array_set_size (columns, column);
+
+	/* sizes rows array to minimum possible 
+	   number of rows to avoids frequent reallocation*/
+	row = (unsigned int) ceil (positions->length / column);
+	rows = g_array_sized_new (FALSE, FALSE,  sizeof (double), row);
 		
+	y = start_y;
+	row = 0;
+	column = 0;
+	max_height_above = 0;
+	max_height_below = 0;
+	p = positions->head;
+	while (p != NULL) {
+		position = p->data;
+		space_width = position->width;
+		height_above = position->height_above;  
+		height_below = position->height_below;
+			
+		/* finds maximum widths for columns */
+		max_column_width = &g_array_index (columns, double, column);
+		if(space_width > *max_column_width) {
 		/* FIXME: why don't we want to guarantee a small white space to the right of
 		 * the last column just like we guarantee a small white space to the left of
 		 * the first column?
 		 */
-		if (line_start != p && line_width + space_width - ICON_PAD_RIGHT > canvas_width) {
-			/* Advance to the baseline. */
-			y += ICON_PAD_TOP + max_height_above;
+			if (line_width + space_width - *max_column_width
+			    - ICON_PAD_RIGHT > canvas_width) {
+				/* new line width exceeds canvas width */
 			
-			lay_down_one_line (container, line_start, p, y, positions);
+				/* discard last column */
+				g_array_set_size (columns, columns->len - 1);
 			
-			/* Advance to next line. */
-			y += max_height_below + ICON_PAD_BOTTOM;
+				/* reset maximum columns's widths */
+				for (column = 0; column < columns->len; column++) {
+					max_column_width = &g_array_index (columns, double, column);
+					*max_column_width = 0;
+				}
 
-			line_width = 0;
-			line_start = p;
-			i = 0;
+				/* resizes rows array to next minimum possible 
+				   number of rows to avoids frequent reallocation*/
+				row = (unsigned int) ceil (positions->length / columns->len);
+				g_array_set_size (rows, row);
 			
-			max_height_above = height_above;
-			max_height_below = height_below;
+				/* start over */
+				y = start_y;
+				row = 0;
+				column = 0;
+				line_width = 0;
+				max_height_above = 0;
+				max_height_below = 0;
+				p = positions->head;				
+				continue;
 		} else {
+				line_width = line_width + space_width - *max_column_width;
+				*max_column_width = space_width;
+			}
+		}	
+	
+		/* find maximum heights for rows */
 			if (height_above > max_height_above) {
 				max_height_above = height_above;
 			}
 			if (height_below > max_height_below) {
 				max_height_below = height_below;
 			}
-		}
-		
-		g_array_set_size (positions, i + 1);
-		position = &g_array_index (positions, IconPositions, i++);
-		position->width = space_width;
-		position->x_offset = (space_width - (icon_bounds.x1 - icon_bounds.x0)) / 2;
-		position->y_offset = icon_bounds.y0 - icon_bounds.y1;
-
-		/* Add this icon. */
-		line_width += space_width;
-	}
 
-	/* Lay down that last line of icons. */
-	if (line_start != NULL) {
+		if (column == columns->len - 1) {
 		/* Advance to the baseline. */
 		y += ICON_PAD_TOP + max_height_above;
 		
-		lay_down_one_line (container, line_start, NULL, y, positions);
+			g_array_set_size (rows, row + 1);
+			baseline = &g_array_index (rows, double, row++);
+			*baseline = y;
 		
 		/* Advance to next line. */
 		y += max_height_below + ICON_PAD_BOTTOM;
+			column = 0;
+			
+			max_height_above = 0;
+			max_height_below = 0;
+		} else {
+			/* next column */
+			++column;
+		}
+		
+		p = p->next;
 	}
 
-	g_array_free (positions, TRUE);
+	/* get baseline for possible incomplete
+	   last line */
+	if (positions->length % columns->len) {
+		/* Advance to the baseline. */
+		y += ICON_PAD_TOP + max_height_above;
+		
+		g_array_set_size (rows, row + 1);
+		baseline = &g_array_index (rows, double, row++);
+		*baseline = y;
+	}
+
+	extra_columns_space = (canvas_width - line_width) / columns->len;
+   
+	lay_down_all_lines (icons, 
+			    positions,
+			    rows, 
+			    columns, 
+			    extra_columns_space);
+    
+	g_queue_free (positions);
+	g_array_free (rows, TRUE);
+	g_array_free (columns, TRUE);
 }
 
 /* Search for available space at location */
@@ -1206,7 +1287,7 @@ lay_down_icons (NautilusIconContainer *c
 	switch (container->details->layout_mode)
 	{
 	case NAUTILUS_ICON_LAYOUT_L_R_T_B:
-		lay_down_icons_horizontal (container, icons, start_y);
+		lay_down_icons_align (container, icons, start_y);
 		break;
 		
 	case NAUTILUS_ICON_LAYOUT_T_B_L_R:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]