[gtk+/gtk-3-4] iconview: Reduce complexity of sizing code



commit a21e348d3e56019325df302d3953c86fa26b63ee
Author: Benjamin Otte <otte redhat com>
Date:   Sun May 6 00:51:14 2012 +0200

    iconview: Reduce complexity of sizing code
    
    Always assume max-columns and min-rows. The old approach was kinda
    insane.
    
    As an example, try to write an algorithm that optimizes the minimum size
    for infinite (take a reasonably large number like 2520) word-wrapped
    Monospace text cells containing the text "XXXXX XXX XXX XXXXX" (keep in
    mind that this is the easy problem, because it's assuming equal cell
    renderers). There's 4 ways to reasonably lay out this text:
    19 glyphs (19x1):
      XXXXX XXX XXX XXXXX
    18 glyphs (9x2):
      XXXXX XXX
      XXX XXXXX
    21 glyphs (7x3):
      XXXXX
      XXX XXX
      XXXXX
    20 glyphs (5x4):
      XXXXX
      XXX
      XXX
      XXXXX
    The best thing to do usually is using the 9x2 approach, but that's
    neither the one using the natural nor the one using the minimum size.
    
    As a side note, this does not include spacing and padding, which might
    also influence the decision. Nor does it include height-for-width
    considerations. Look at this table (numbers given in glyphs, not pixels,
    as for pixel-sizes it gets even more interesting):
      given  best solution
      width  columns  sizing  glyphs per cell
       6      1       6x4           20
       7      1       7x3           21
       8      1       7x3           24
       9      1       9x2           18
      10      1/2     9x2/5x4       20
      11      1/2     9x2/5x4       22
      12      1/2     9x2/5x4       24
      13      1/2     9x2/5x4       26
      14      2       7x3           21
      15      3       5x4           20
      16      3       5x4           21.3
      17      3       5x4           22.7
      18      2       9x2           18
      19      1/2    19x1/8x2       19
      20      1/2/4  19x1/8x2/5x4   20
      21      1-4     any           21
      22      1-4     any           22
      23      1-4     any           23
      24      1-4     any           24
      25      5       5x4           20
      26      5       5x4           20.8
      27      3       9x2           18
      28      3       9x2           18.7
      29      3       9x2           19.3
      30      3/6     9x2/5x4       20
    
    Now of course, nobody wants the number of columns to randomly change in
    inexplicable ways while they enlarge or shrink an iconview, so we not
    only have to optimize for smallest or other size measurements, but we
    also have to optimize for "most pleasing to the eye".
    
    And last but not least, I'd like to once again remind you - if you kept
    up until now - that this discussion was for identically-sized cells
    only.

 gtk/gtkiconview.c |   68 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 44 insertions(+), 24 deletions(-)
---
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index aeead95..f4cfe9a 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -1463,16 +1463,31 @@ static void
 gtk_icon_view_compute_n_items_for_size (GtkIconView    *icon_view,
                                         GtkOrientation  orientation,
                                         gint            size,
-                                        gint           *min_columns,
-                                        gint           *max_columns)
+                                        gint           *min_items,
+                                        gint           *max_items)
 {
   GtkIconViewPrivate *priv = icon_view->priv;
   int minimum, natural;
 
   if (priv->columns > 0)
     {
-      *min_columns = priv->columns;
-      *max_columns = priv->columns;
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          if (min_items)
+            *min_items = priv->columns;
+          if (max_items)
+            *max_items = priv->columns;
+        }
+      else
+        {
+          int n_items = gtk_icon_view_get_n_items (icon_view);
+
+          if (min_items)
+            *min_items = (n_items + priv->columns - 1) / priv->columns;
+          if (max_items)
+            *max_items = (n_items + priv->columns - 1) / priv->columns;
+        }
+
       return;
     }
 
@@ -1493,14 +1508,21 @@ gtk_icon_view_compute_n_items_for_size (GtkIconView    *icon_view,
       natural += priv->row_spacing;
     }
 
-  if (size <= minimum)
-    *max_columns = 1;
-  else
-    *max_columns = size / minimum;
-  if (size <= natural)
-    *min_columns = 1;
-  else
-    *min_columns = size / natural;
+  if (max_items)
+    {
+      if (size <= minimum)
+        *max_items = 1;
+      else
+        *max_items = size / minimum;
+    }
+
+  if (min_items)
+    {
+      if (size <= natural)
+        *min_items = 1;
+      else
+        *min_items = size / natural;
+    }
 }
 
 static GtkSizeRequestMode
@@ -1545,17 +1567,16 @@ gtk_icon_view_get_preferred_width_for_height (GtkWidget *widget,
 {
   GtkIconView *icon_view = GTK_ICON_VIEW (widget);
   GtkIconViewPrivate *priv = icon_view->priv;
-  int item_min, item_nat, min_rows, max_rows, n_items;
+  int item_min, item_nat, rows, n_items;
 
-  gtk_icon_view_compute_n_items_for_size (icon_view, GTK_ORIENTATION_VERTICAL, height, &min_rows, &max_rows);
+  gtk_icon_view_compute_n_items_for_size (icon_view, GTK_ORIENTATION_VERTICAL, height, &rows, NULL);
   n_items = gtk_icon_view_get_n_items (icon_view);
 
   height = height + priv->row_spacing - 2 * priv->margin;
 
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_HORIZONTAL, height / max_rows - priv->row_spacing, &item_min, NULL);
-  *minimum = item_min * ((n_items + max_rows - 1) / max_rows);
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_HORIZONTAL, height / min_rows - priv->row_spacing, NULL, &item_nat);
-  *natural = item_nat * ((n_items + min_rows - 1) / min_rows);
+  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_HORIZONTAL, height / rows - priv->row_spacing, &item_min, &item_nat);
+  *minimum = item_min * ((n_items + rows - 1) / rows);
+  *natural = item_nat * ((n_items + rows - 1) / rows);
 
   *minimum += 2 * priv->margin;
   *natural += 2 * priv->margin;
@@ -1598,17 +1619,16 @@ gtk_icon_view_get_preferred_height_for_width (GtkWidget *widget,
 {
   GtkIconView *icon_view = GTK_ICON_VIEW (widget);
   GtkIconViewPrivate *priv = icon_view->priv;
-  int item_min, item_nat, min_columns, max_columns, n_items;
+  int item_min, item_nat, columns, n_items;
 
-  gtk_icon_view_compute_n_items_for_size (icon_view, GTK_ORIENTATION_HORIZONTAL, width, &min_columns, &max_columns);
+  gtk_icon_view_compute_n_items_for_size (icon_view, GTK_ORIENTATION_HORIZONTAL, width, NULL, &columns);
   n_items = gtk_icon_view_get_n_items (icon_view);
 
   width = width + priv->column_spacing - 2 * priv->margin;
 
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_VERTICAL, width / max_columns - priv->column_spacing, &item_min, NULL);
-  *minimum = (item_min + priv->row_spacing) * ((n_items + max_columns - 1) / max_columns) - priv->row_spacing;
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_VERTICAL, width / min_columns - priv->column_spacing, NULL, &item_nat);
-  *natural = (item_nat + priv->row_spacing) * ((n_items + min_columns - 1) / min_columns) - priv->row_spacing;
+  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_VERTICAL, width / columns - priv->column_spacing, &item_min, &item_nat);
+  *minimum = (item_min + priv->row_spacing) * ((n_items + columns - 1) / columns) - priv->row_spacing;
+  *natural = (item_nat + priv->row_spacing) * ((n_items + columns - 1) / columns) - priv->row_spacing;
 
   *minimum += 2 * priv->margin;
   *natural += 2 * priv->margin;



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