[gtk/matthiasc/for-master] columview: Fix column resizing



commit 7eb0ae39c5549bfaa4efb879ef49b1186f48c5c1
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Sep 24 14:18:38 2020 -0400

    columview: Fix column resizing
    
    We were not handling the fixed_width quite right,
    and that was causing screaming from the GTK size
    allocation machinery.
    
    Fixes: #3178

 gtk/gtkcolumnviewcell.c   | 54 +++++++++++++++++++++++++++++++++++++++++++----
 gtk/gtkcolumnviewlayout.c |  6 ++++--
 gtk/gtkcolumnviewtitle.c  | 52 +++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 102 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkcolumnviewcell.c b/gtk/gtkcolumnviewcell.c
index ace8037188..0881a6ccd3 100644
--- a/gtk/gtkcolumnviewcell.c
+++ b/gtk/gtkcolumnviewcell.c
@@ -25,6 +25,9 @@
 #include "gtkintl.h"
 #include "gtklistitemwidgetprivate.h"
 #include "gtkwidgetprivate.h"
+#include "gtkcssnodeprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+
 
 struct _GtkColumnViewCell
 {
@@ -44,6 +47,37 @@ struct _GtkColumnViewCellClass
 
 G_DEFINE_TYPE (GtkColumnViewCell, gtk_column_view_cell, GTK_TYPE_LIST_ITEM_WIDGET)
 
+static int
+get_number (GtkCssValue *value)
+{
+  double d = _gtk_css_number_value_get (value, 100);
+
+  if (d < 1)
+    return ceil (d);
+  else
+    return floor (d);
+}
+
+static int
+unadjust_width (GtkWidget *widget,
+                int        width)
+{
+  GtkCssStyle *style;
+  int widget_margins;
+  int css_extra;
+
+  style = gtk_css_node_get_style (gtk_widget_get_css_node (widget));
+  css_extra = get_number (style->size->margin_left) +
+              get_number (style->size->margin_right) +
+              get_number (style->border->border_left_width) +
+              get_number (style->border->border_right_width) +
+              get_number (style->size->padding_left) +
+              get_number (style->size->padding_right);
+  widget_margins = widget->priv->margin.left + widget->priv->margin.right;
+
+  return MAX (0, width - widget_margins - css_extra);
+}
+
 static void
 gtk_column_view_cell_measure (GtkWidget      *widget,
                               GtkOrientation  orientation,
@@ -56,15 +90,18 @@ gtk_column_view_cell_measure (GtkWidget      *widget,
   GtkColumnViewCell *cell = GTK_COLUMN_VIEW_CELL (widget);
   GtkWidget *child = gtk_widget_get_first_child (widget);
   int fixed_width = gtk_column_view_column_get_fixed_width (cell->column);
+  int unadj_width;
+
+  unadj_width = unadjust_width (widget, fixed_width);
 
   if (orientation == GTK_ORIENTATION_VERTICAL)
     {
       if (fixed_width > -1)
         {
           if (for_size == -1)
-            for_size = fixed_width;
+            for_size = unadj_width;
           else
-            for_size = MIN (for_size, fixed_width);
+            for_size = MIN (for_size, unadj_width);
         }
     }
 
@@ -74,7 +111,10 @@ gtk_column_view_cell_measure (GtkWidget      *widget,
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
       if (fixed_width > -1)
-        *minimum = *natural = fixed_width;
+        {
+          *minimum = 0;
+          *natural = unadj_width;
+        }
     }
 }
 
@@ -84,10 +124,16 @@ gtk_column_view_cell_size_allocate (GtkWidget *widget,
                                     int        height,
                                     int        baseline)
 {
+  GtkColumnViewCell *self = GTK_COLUMN_VIEW_CELL (widget);
   GtkWidget *child = gtk_widget_get_first_child (widget);
 
   if (child)
-    gtk_widget_allocate (child, width, height, baseline, NULL);
+    {
+      if (gtk_column_view_column_get_fixed_width (self->column) > -1)
+        gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, height, NULL, &width, NULL, NULL);
+
+      gtk_widget_allocate (child, width, height, baseline, NULL);
+    }
 }
 
 static void
diff --git a/gtk/gtkcolumnviewlayout.c b/gtk/gtkcolumnviewlayout.c
index 1b56a3b6ff..6f9dfdb13c 100644
--- a/gtk/gtkcolumnviewlayout.c
+++ b/gtk/gtkcolumnviewlayout.c
@@ -128,7 +128,7 @@ gtk_column_view_layout_allocate (GtkLayoutManager *layout_manager,
        child = _gtk_widget_get_next_sibling (child))
     {
       GtkColumnViewColumn *column;
-      int col_x, col_width;
+      int col_x, col_width, min;
 
       if (!gtk_widget_should_layout (child))
         continue;
@@ -144,7 +144,9 @@ gtk_column_view_layout_allocate (GtkLayoutManager *layout_manager,
           gtk_column_view_column_get_header_allocation (column, &col_x, &col_width);
         }
 
-      gtk_widget_size_allocate (child, &(GtkAllocation) { col_x, 0, col_width, height }, baseline);
+      gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
+
+      gtk_widget_size_allocate (child, &(GtkAllocation) { col_x, 0, MAX (min, col_width), height }, 
baseline);
     }
 }
 
diff --git a/gtk/gtkcolumnviewtitle.c b/gtk/gtkcolumnviewtitle.c
index 12c39d9ba3..bc06da1670 100644
--- a/gtk/gtkcolumnviewtitle.c
+++ b/gtk/gtkcolumnviewtitle.c
@@ -32,6 +32,8 @@
 #include "gtkgestureclick.h"
 #include "gtkpopovermenu.h"
 #include "gtknative.h"
+#include "gtkcssnodeprivate.h"
+#include "gtkcssnumbervalueprivate.h"
 
 struct _GtkColumnViewTitle
 {
@@ -52,6 +54,37 @@ struct _GtkColumnViewTitleClass
 
 G_DEFINE_TYPE (GtkColumnViewTitle, gtk_column_view_title, GTK_TYPE_WIDGET)
 
+static int
+get_number (GtkCssValue *value)
+{
+  double d = _gtk_css_number_value_get (value, 100);
+
+  if (d < 1)
+    return ceil (d);
+  else
+    return floor (d);
+}
+
+static int
+unadjust_width (GtkWidget *widget,
+                int        width)
+{
+  GtkCssStyle *style;
+  int widget_margins;
+  int css_extra;
+
+  style = gtk_css_node_get_style (gtk_widget_get_css_node (widget));
+  css_extra = get_number (style->size->margin_left) +
+              get_number (style->size->margin_right) +
+              get_number (style->border->border_left_width) +
+              get_number (style->border->border_right_width) +
+              get_number (style->size->padding_left) +
+              get_number (style->size->padding_right);
+  widget_margins = widget->priv->margin.left + widget->priv->margin.right;
+
+  return MAX (0, width - widget_margins - css_extra);
+}
+
 static void
 gtk_column_view_title_measure (GtkWidget      *widget,
                                GtkOrientation  orientation,
@@ -64,15 +97,18 @@ gtk_column_view_title_measure (GtkWidget      *widget,
   GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (widget);
   GtkWidget *child = gtk_widget_get_first_child (widget);
   int fixed_width = gtk_column_view_column_get_fixed_width (self->column);
+  int unadj_width;
+
+  unadj_width = unadjust_width (widget, fixed_width);
 
   if (orientation == GTK_ORIENTATION_VERTICAL)
     {
       if (fixed_width > -1)
         {
           if (for_size == -1)
-            for_size = fixed_width;
+            for_size = unadj_width;
           else
-            for_size = MIN (for_size, fixed_width);
+            for_size = MIN (for_size, unadj_width);
         }
     }
 
@@ -82,7 +118,10 @@ gtk_column_view_title_measure (GtkWidget      *widget,
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
       if (fixed_width > -1)
-        *minimum = *natural = fixed_width;
+        {
+          *minimum = 0;
+          *natural = unadj_width;
+        }
     }
 }
 
@@ -96,7 +135,12 @@ gtk_column_view_title_size_allocate (GtkWidget *widget,
   GtkWidget *child = gtk_widget_get_first_child (widget);
 
   if (child)
-    gtk_widget_allocate (child, width, height, baseline, NULL);
+    {
+      if (gtk_column_view_column_get_fixed_width (self->column) > -1)
+        gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, height, NULL, &width, NULL, NULL);
+
+      gtk_widget_allocate (child, width, height, baseline, NULL);
+    }
 
   if (self->popup_menu)
     gtk_native_check_resize (GTK_NATIVE (self->popup_menu));


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