[gtk+] iconview: Reduce complexity of sizing code
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] iconview: Reduce complexity of sizing code
- Date: Sun, 6 May 2012 22:13:04 +0000 (UTC)
commit d406bf96d4bb1191b05f1ddb374c2f57138c8d45
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]