[gtk+] Revert "Use minimum/natural size semantics"



commit a3cd0ee7d8a610feff39984254306cec4a6c9c73
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jun 1 10:16:01 2014 -0400

    Revert "Use minimum/natural size semantics"
    
    This reverts commit 6d53c2339f79baa0b295ecc614f41f9daab2e132.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=731054 showed some
    major regressions caused by this commit.

 gtk/gtktreeprivate.h    |    4 +-
 gtk/gtktreeview.c       |  170 ++++++++++++++++++++++++++++------------------
 gtk/gtktreeviewcolumn.c |   62 +++++++++---------
 3 files changed, 135 insertions(+), 101 deletions(-)
---
diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h
index d813352..a2d6d6c 100644
--- a/gtk/gtktreeprivate.h
+++ b/gtk/gtktreeprivate.h
@@ -99,9 +99,7 @@ void _gtk_tree_view_column_unrealize_button (GtkTreeViewColumn *column);
  
 void _gtk_tree_view_column_set_tree_view    (GtkTreeViewColumn *column,
                                             GtkTreeView       *tree_view);
-void _gtk_tree_view_column_request_width    (GtkTreeViewColumn *tree_column,
-                                            gint              *minimum,
-                                            gint              *natural);
+gint _gtk_tree_view_column_request_width    (GtkTreeViewColumn *tree_column);
 void _gtk_tree_view_column_allocate         (GtkTreeViewColumn *tree_column,
                                             int                x_offset,
                                             int                width);
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 9a7b337..0001c18 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -371,10 +371,10 @@ struct _GtkTreeViewPrivate
   gint drag_pos;
   gint x_drag;
 
-  /* Column width allocation */
-  gint minimum_width;
-  gint natural_width;
-  gint n_expand_columns;
+  /* Non-interactive Header Resizing, expand flag support */
+  gint last_extra_space;
+  gint last_extra_space_per_column;
+  gint last_number_of_expand_columns;
 
   /* ATK Hack */
   GtkTreeDestroyCountFunc destroy_count_func;
@@ -481,6 +481,8 @@ struct _GtkTreeViewPrivate
 
   guint in_grab : 1;
 
+  guint post_validation_flag : 1;
+
   /* Whether our key press handler is to avoid sending an unhandled binding to the search entry */
   guint search_entry_avoid_unhandled_binding : 1;
 
@@ -1790,9 +1792,6 @@ gtk_tree_view_init (GtkTreeView *tree_view)
   tree_view->priv->header_height = 1;
   tree_view->priv->x_drag = 0;
   tree_view->priv->drag_pos = -1;
-  tree_view->priv->minimum_width = 0;
-  tree_view->priv->natural_width = 0;
-  tree_view->priv->n_expand_columns = 0;
   tree_view->priv->header_has_focus = FALSE;
   tree_view->priv->pressed_button = -1;
   tree_view->priv->press_start_x = -1;
@@ -1825,6 +1824,8 @@ gtk_tree_view_init (GtkTreeView *tree_view)
 
   tree_view->priv->tooltip_column = -1;
 
+  tree_view->priv->post_validation_flag = FALSE;
+
   tree_view->priv->last_button_x = -1;
   tree_view->priv->last_button_y = -1;
 
@@ -2565,16 +2566,12 @@ gtk_tree_view_get_preferred_width (GtkWidget *widget,
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
   GList *list;
   GtkTreeViewColumn *column;
-  gint column_minimum, column_natural;
+  gint width = 0;
 
   /* we validate some rows initially just to make sure we have some size.
    * In practice, with a lot of static lists, this should get a good width.
    */
   do_validate_rows (tree_view, FALSE);
-  
-  tree_view->priv->minimum_width = 0;
-  tree_view->priv->natural_width = 0;
-  tree_view->priv->n_expand_columns = 0;
 
   /* keep this in sync with size_allocate below */
   for (list = tree_view->priv->columns; list; list = list->next)
@@ -2583,18 +2580,10 @@ gtk_tree_view_get_preferred_width (GtkWidget *widget,
       if (!gtk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column)
        continue;
 
-      _gtk_tree_view_column_request_width (column, &column_minimum, &column_natural);
-      tree_view->priv->minimum_width += column_minimum;
-      tree_view->priv->natural_width += column_natural;
-
-      if (gtk_tree_view_column_get_expand (column))
-       tree_view->priv->n_expand_columns++;
+      width += _gtk_tree_view_column_request_width (column);
     }
 
-  if (minimum != NULL)
-    *minimum = tree_view->priv->minimum_width;
-  if (natural != NULL)
-    *natural = tree_view->priv->natural_width;
+  *minimum = *natural = width;
 }
 
 static void
@@ -2609,10 +2598,7 @@ gtk_tree_view_get_preferred_height (GtkWidget *widget,
 
   height = gtk_tree_view_get_height (tree_view) + gtk_tree_view_get_effective_header_height (tree_view);
 
-  if (minimum != NULL)
-    *minimum = height;
-  if (natural != NULL)
-    *natural = height;
+  *minimum = *natural = height;
 }
 
 static int
@@ -2644,9 +2630,12 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget,
   GList *list, *first_column, *last_column;
   GtkTreeViewColumn *column;
   GtkAllocation widget_allocation;
-  gint minimum_width, natural_width, n_expand_columns, width;
-  gint column_minimum, column_natural, column_width;
+  gint width = 0;
+  gint extra, extra_per_column, extra_for_last;
+  gint full_requested_width = 0;
+  gint number_of_expand_columns = 0;
   gboolean rtl;
+  gboolean update_expand;
   
   tree_view = GTK_TREE_VIEW (widget);
 
@@ -2666,65 +2655,111 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget,
 
   rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
 
-  gtk_widget_get_allocation (widget, &widget_allocation);
+  /* find out how many extra space and expandable columns we have */
+  for (list = tree_view->priv->columns; list != last_column->next; list = list->next)
+    {
+      column = (GtkTreeViewColumn *)list->data;
 
-  minimum_width = tree_view->priv->minimum_width;
-  natural_width = tree_view->priv->natural_width;
-  n_expand_columns = tree_view->priv->n_expand_columns;
+      if (!gtk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column)
+       continue;
 
-  width = MAX (widget_allocation.width, minimum_width);
+      full_requested_width += _gtk_tree_view_column_request_width (column);
 
-  /* We change the width here.  The user might have been resizing columns,
-   * which changes the total width of the tree view.  This is of
-   * importance for getting the horizontal scroll bar right.
+      if (gtk_tree_view_column_get_expand (column))
+       number_of_expand_columns++;
+    }
+
+  /* Only update the expand value if the width of the widget has changed,
+   * or the number of expand columns has changed, or if there are no expand
+   * columns, or if we didn't have an size-allocation yet after the
+   * last validated node.
    */
-  if (tree_view->priv->width != width)
+  update_expand = (width_changed && *width_changed == TRUE)
+      || number_of_expand_columns != tree_view->priv->last_number_of_expand_columns
+      || number_of_expand_columns == 0
+      || tree_view->priv->post_validation_flag == TRUE;
+
+  tree_view->priv->post_validation_flag = FALSE;
+
+  gtk_widget_get_allocation (widget, &widget_allocation);
+  if (!update_expand)
     {
-      tree_view->priv->width = width;
-      if (width_changed)
-        *width_changed = TRUE;
+      extra = tree_view->priv->last_extra_space;
+      extra_for_last = MAX (widget_allocation.width - full_requested_width - extra, 0);
+    }
+  else
+    {
+      extra = MAX (widget_allocation.width - full_requested_width, 0);
+      extra_for_last = 0;
+
+      tree_view->priv->last_extra_space = extra;
+    }
+
+  if (number_of_expand_columns > 0)
+    extra_per_column = extra/number_of_expand_columns;
+  else
+    extra_per_column = 0;
+
+  if (update_expand)
+    {
+      tree_view->priv->last_extra_space_per_column = extra_per_column;
+      tree_view->priv->last_number_of_expand_columns = number_of_expand_columns;
     }
 
-  /* iterate through columns in reverse order */
-  for (list = (rtl ? first_column : last_column); 
-       list != (rtl ? last_column->next : first_column->prev);
-       list = (rtl ? list->next : list->prev)) 
+  for (list = (rtl ? last_column : first_column); 
+       list != (rtl ? first_column->prev : last_column->next);
+       list = (rtl ? list->prev : list->next)) 
     {
+      gint column_width;
+
       column = list->data;
 
       if (!gtk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column)
        continue;
 
-      _gtk_tree_view_column_request_width (column, &column_minimum, &column_natural);
-      
-      column_width = column_natural;
+      column_width = _gtk_tree_view_column_request_width (column);
 
-      if (width > natural_width)
-        {
-         /* We need to expand some columns.  If there are none marked to
-          * expand, give all the extra space to the last column. */
-         if (n_expand_columns == 0)
+      if (gtk_tree_view_column_get_expand (column))
+       {
+         if (number_of_expand_columns == 1)
            {
-             column_width = column_natural + (width - natural_width);
+             /* We add the remander to the last column as
+              * */
+             column_width += extra;
            }
-         else if (gtk_tree_view_column_get_expand (column))
+         else
            {
-             column_width = column_natural + (width - natural_width) / n_expand_columns;
-             n_expand_columns--;
+             column_width += extra_per_column;
+             extra -= extra_per_column;
+             number_of_expand_columns --;
            }
-        }
-      else if (width < natural_width)
+       }
+      else if (number_of_expand_columns == 0 &&
+              list == last_column)
        {
-         /* We need to shrink some columns.  Starting with later columns,
-          * shrink each one down to its minimum width as necessary. */
-         column_width = MAX (column_natural + (width - natural_width), column_minimum);
+         column_width += extra;
        }
-       
-      _gtk_tree_view_column_allocate (column, width - column_width, column_width);
-      
-      minimum_width -= column_minimum;
-      natural_width -= column_natural;
-      width -= column_width;
+
+      /* In addition to expand, the last column can get even more
+       * extra space so all available space is filled up.
+       */
+      if (extra_for_last > 0 && list == last_column)
+       column_width += extra_for_last;
+
+      _gtk_tree_view_column_allocate (column, width, column_width);
+
+      width += column_width;
+    }
+
+  /* We change the width here.  The user might have been resizing columns,
+   * which changes the total width of the tree view.  This is of
+   * importance for getting the horizontal scroll bar right.
+   */
+  if (tree_view->priv->width != width)
+    {
+      tree_view->priv->width = width;
+      if (width_changed)
+        *width_changed = TRUE;
     }
 }
 
@@ -6186,6 +6221,7 @@ validate_row (GtkTreeView *tree_view,
       _gtk_rbtree_node_set_height (tree, node, height);
     }
   _gtk_rbtree_node_mark_valid (tree, node);
+  tree_view->priv->post_validation_flag = TRUE;
 
   return retval;
 }
diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c
index 5001217..487b44b 100644
--- a/gtk/gtktreeviewcolumn.c
+++ b/gtk/gtktreeviewcolumn.c
@@ -2094,48 +2094,48 @@ gtk_tree_view_column_get_x_offset (GtkTreeViewColumn *tree_column)
   return tree_column->priv->x_offset;
 }
 
-void
-_gtk_tree_view_column_request_width (GtkTreeViewColumn *tree_column,
-                                     gint              *minimum,
-                                     gint              *natural)
+gint
+_gtk_tree_view_column_request_width (GtkTreeViewColumn *tree_column)
 {
-  GtkTreeViewColumnPrivate *priv = tree_column->priv;
-  gint minimum_width = 1, natural_width = 1;
-  gint button_minimum, button_natural;
+  GtkTreeViewColumnPrivate *priv;
+  gint real_requested_width;
 
-  if (priv->column_type != GTK_TREE_VIEW_COLUMN_FIXED)
-    {
-      gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &minimum_width, &natural_width);
-      minimum_width += priv->padding;
-      natural_width += priv->padding;
+  priv = tree_column->priv;
 
-      if (gtk_tree_view_get_headers_visible (GTK_TREE_VIEW (priv->tree_view)))
-        {
-          gtk_widget_get_preferred_width (priv->button, &button_minimum, &button_natural);
-          minimum_width = MAX (minimum_width, button_minimum);
-          natural_width = MAX (natural_width, button_natural);
-        }
+  if (priv->fixed_width != -1)
+    {
+      real_requested_width = priv->fixed_width;
     }
+  else if (gtk_tree_view_get_headers_visible (GTK_TREE_VIEW (priv->tree_view)))
+    {
+      gint button_request;
+      gint requested_width;
 
-  if (priv->fixed_width != -1)
-    natural_width = MAX (priv->fixed_width, minimum_width);
+      gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &requested_width, NULL);
+      requested_width += priv->padding;
 
-  if (priv->min_width != -1)
+      gtk_widget_get_preferred_width (priv->button, &button_request, NULL);
+      real_requested_width = MAX (requested_width, button_request);
+    }
+  else
     {
-      minimum_width = MAX (minimum_width, priv->min_width);
-      natural_width = MAX (natural_width, priv->min_width);
+      gint requested_width;
+
+      gtk_cell_area_context_get_preferred_width (priv->cell_area_context, &requested_width, NULL);
+      requested_width += priv->padding;
+
+      real_requested_width = requested_width;
+      if (real_requested_width < 0)
+        real_requested_width = 0;
     }
 
+  if (priv->min_width != -1)
+    real_requested_width = MAX (real_requested_width, priv->min_width);
+
   if (priv->max_width != -1)
-    {
-      minimum_width = MIN (minimum_width, priv->max_width);
-      natural_width = MIN (natural_width, priv->max_width);
-    }
+    real_requested_width = MIN (real_requested_width, priv->max_width);
 
-  if (minimum != NULL)
-    *minimum = minimum_width;
-  if (natural != NULL)
-    *natural = natural_width;
+  return real_requested_width;
 }
 
 void


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