summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Churaev <lamefun.x0r@gmail.com>2018-03-08 05:11:00 +0300
committerNikita Churaev <lamefun.x0r@gmail.com>2018-03-17 21:04:57 +0300
commit00fe3e5d18033c70367fe558dc3bbf62f063180b (patch)
treec127ec4aa6f18380468cb0a98baefb641b33641d
parent597e585f1d0419af7fc25785cfe68b4877a9479f (diff)
downloadnautilus-00fe3e5d18033c70367fe558dc3bbf62f063180b.tar.gz
canvas-container: Distribute icons horizontally
Nautilus has always had a view that tries to emulate a grid, however the grid doesn't distribute the spacing of the icons when resizing and rather just snaps them on the left side. We can actually fix this by distributing evenly the spacing left. However there is a case where that looks bad, and that's when there is less than a single line of icons, since the icons will be spaced out along the whole view. We can fix that too by distributing the spacing in a function manner. This commit distributes the spacing of the icons in an evenly way when there is one or more lines full, and it uses a fast decreasing but smooth incremental function when there is less icons than a full single line. Eventually we will move to new views where the space is already distributed by the gtk containers, however we might want to keep the function spacing distribution too, so this code will be helpful at that point.
-rw-r--r--src/nautilus-canvas-container.c70
1 files changed, 61 insertions, 9 deletions
diff --git a/src/nautilus-canvas-container.c b/src/nautilus-canvas-container.c
index 1b91f4f87..09c570118 100644
--- a/src/nautilus-canvas-container.c
+++ b/src/nautilus-canvas-container.c
@@ -1178,7 +1178,7 @@ lay_down_one_line (NautilusCanvasContainer *container,
{
GList *p;
NautilusCanvasIcon *icon;
- double x, y_offset;
+ double x, ltr_icon_x, icon_x, y_offset;
IconPositions *position;
int i;
gboolean is_rtl;
@@ -1193,15 +1193,14 @@ lay_down_one_line (NautilusCanvasContainer *container,
icon = p->data;
position = &g_array_index (positions, IconPositions, i++);
+ ltr_icon_x = x + position->x_offset;
+ icon_x = is_rtl ? get_mirror_x_position (container, icon, ltr_icon_x) : ltr_icon_x;
y_offset = position->y_offset;
- icon_set_position
- (icon,
- is_rtl ? get_mirror_x_position (container, icon, x + position->x_offset) : x + position->x_offset,
- y + y_offset);
+ icon_set_position (icon, icon_x, y + y_offset);
nautilus_canvas_item_set_entire_text (icon->item, whole_text);
- icon->saved_ltr_x = is_rtl ? get_mirror_x_position (container, icon, icon->x) : icon->x;
+ icon->saved_ltr_x = is_rtl ? ltr_icon_x : icon->x;
x += position->width;
}
@@ -1215,6 +1214,7 @@ lay_down_icons_horizontal (NautilusCanvasContainer *container,
GList *p, *line_start;
NautilusCanvasIcon *icon;
double canvas_width, y;
+ double available_width;
GArray *positions;
IconPositions *position;
EelDRect bounds;
@@ -1222,8 +1222,10 @@ lay_down_icons_horizontal (NautilusCanvasContainer *container,
double max_height_above, max_height_below;
double height_above, height_below;
double line_width;
+ double min_grid_width;
double grid_width;
- int icon_width, icon_size;
+ double num_columns;
+ double icon_width, icon_size;
int i;
GtkAllocation allocation;
@@ -1242,10 +1244,60 @@ lay_down_icons_horizontal (NautilusCanvasContainer *container,
/* Lay out icons a line at a time. */
canvas_width = CANVAS_WIDTH (container, allocation);
-
- grid_width = nautilus_canvas_container_get_grid_size_for_zoom_level (container->details->zoom_level);
+ min_grid_width = nautilus_canvas_container_get_grid_size_for_zoom_level (container->details->zoom_level);
icon_size = nautilus_canvas_container_get_icon_size_for_zoom_level (container->details->zoom_level);
+ /* Subtracting 1.0 adds some room for error to prevent the jitter due to
+ * the code not being able to decide how many columns should be there, as
+ * "double" is not perfectly precise and increasing the size of the the
+ * window by one pixel could well make it so that the space taken by the
+ * icons and the padding is actually greater than the canvas with by like
+ * 0.01, causing an entire column to be dropped unnecessarily. This fix is
+ * adapted from Nemo.
+ */
+ available_width = MAX (1.0, canvas_width - ICON_PAD_LEFT - ICON_PAD_RIGHT - 1.0);
+ num_columns = MAX (1.0, floor (available_width / min_grid_width));
+
+ if (g_list_nth (icons, num_columns) != NULL)
+ {
+ grid_width = available_width / num_columns;
+ }
+ else
+ {
+ /* It does not look good when the icons jump around when new columns are
+ * added or removed to the grid while there is only one line. It does
+ * not look good either when the icons do not move at all when the
+ * window is resized.
+ *
+ * To do this, we first compute the maximum extra fraction we can add to
+ * the grid width. Adding this much, however, would simply distribute
+ * the icons evenly, which looks bad when there's a wide window with
+ * only a few icons.
+ *
+ * To fix this, we need to apply a function to the fraction which never
+ * makes it larger and instead makes its growth slow down quickly but
+ * smoothly as the window gets wider and wider. Here's the function used
+ * by this code:
+ *
+ * f(x) = ∜(x + 1) - 1
+ *
+ * The +1 and -1 are there to skip the 0 to 1 part of ∜ where it makes
+ * the number larger.
+ */
+
+ double num_icons = MAX (1.0, g_list_length (icons));
+
+ double used_width = num_icons * min_grid_width;
+ double unused_width = available_width - used_width;
+
+ double max_extra_fraction = (unused_width / num_icons) / min_grid_width;
+ double extra_fraction = pow(max_extra_fraction + 1.0, 1.0 / 4.0) - 1.0;
+
+ grid_width = min_grid_width * (1 + extra_fraction);
+ }
+
+ grid_width = MAX (min_grid_width, grid_width);
+
line_width = 0;
line_start = icons;
y = start_y + CONTAINER_PAD_TOP;