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
This commit is contained in:
Matthias Clasen
2020-09-24 14:18:38 -04:00
parent 9fde0137a0
commit 7eb0ae39c5
3 changed files with 102 additions and 10 deletions

View File

@@ -25,6 +25,9 @@
#include "gtkintl.h" #include "gtkintl.h"
#include "gtklistitemwidgetprivate.h" #include "gtklistitemwidgetprivate.h"
#include "gtkwidgetprivate.h" #include "gtkwidgetprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssnumbervalueprivate.h"
struct _GtkColumnViewCell struct _GtkColumnViewCell
{ {
@@ -44,6 +47,37 @@ struct _GtkColumnViewCellClass
G_DEFINE_TYPE (GtkColumnViewCell, gtk_column_view_cell, GTK_TYPE_LIST_ITEM_WIDGET) 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 static void
gtk_column_view_cell_measure (GtkWidget *widget, gtk_column_view_cell_measure (GtkWidget *widget,
GtkOrientation orientation, GtkOrientation orientation,
@@ -56,15 +90,18 @@ gtk_column_view_cell_measure (GtkWidget *widget,
GtkColumnViewCell *cell = GTK_COLUMN_VIEW_CELL (widget); GtkColumnViewCell *cell = GTK_COLUMN_VIEW_CELL (widget);
GtkWidget *child = gtk_widget_get_first_child (widget); GtkWidget *child = gtk_widget_get_first_child (widget);
int fixed_width = gtk_column_view_column_get_fixed_width (cell->column); 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 (orientation == GTK_ORIENTATION_VERTICAL)
{ {
if (fixed_width > -1) if (fixed_width > -1)
{ {
if (for_size == -1) if (for_size == -1)
for_size = fixed_width; for_size = unadj_width;
else 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 (orientation == GTK_ORIENTATION_HORIZONTAL)
{ {
if (fixed_width > -1) 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 height,
int baseline) int baseline)
{ {
GtkColumnViewCell *self = GTK_COLUMN_VIEW_CELL (widget);
GtkWidget *child = gtk_widget_get_first_child (widget); GtkWidget *child = gtk_widget_get_first_child (widget);
if (child) 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 static void

View File

@@ -128,7 +128,7 @@ gtk_column_view_layout_allocate (GtkLayoutManager *layout_manager,
child = _gtk_widget_get_next_sibling (child)) child = _gtk_widget_get_next_sibling (child))
{ {
GtkColumnViewColumn *column; GtkColumnViewColumn *column;
int col_x, col_width; int col_x, col_width, min;
if (!gtk_widget_should_layout (child)) if (!gtk_widget_should_layout (child))
continue; 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_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);
} }
} }

View File

@@ -32,6 +32,8 @@
#include "gtkgestureclick.h" #include "gtkgestureclick.h"
#include "gtkpopovermenu.h" #include "gtkpopovermenu.h"
#include "gtknative.h" #include "gtknative.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssnumbervalueprivate.h"
struct _GtkColumnViewTitle struct _GtkColumnViewTitle
{ {
@@ -52,6 +54,37 @@ struct _GtkColumnViewTitleClass
G_DEFINE_TYPE (GtkColumnViewTitle, gtk_column_view_title, GTK_TYPE_WIDGET) 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 static void
gtk_column_view_title_measure (GtkWidget *widget, gtk_column_view_title_measure (GtkWidget *widget,
GtkOrientation orientation, GtkOrientation orientation,
@@ -64,15 +97,18 @@ gtk_column_view_title_measure (GtkWidget *widget,
GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (widget); GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (widget);
GtkWidget *child = gtk_widget_get_first_child (widget); GtkWidget *child = gtk_widget_get_first_child (widget);
int fixed_width = gtk_column_view_column_get_fixed_width (self->column); 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 (orientation == GTK_ORIENTATION_VERTICAL)
{ {
if (fixed_width > -1) if (fixed_width > -1)
{ {
if (for_size == -1) if (for_size == -1)
for_size = fixed_width; for_size = unadj_width;
else 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 (orientation == GTK_ORIENTATION_HORIZONTAL)
{ {
if (fixed_width > -1) 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); GtkWidget *child = gtk_widget_get_first_child (widget);
if (child) 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) if (self->popup_menu)
gtk_native_check_resize (GTK_NATIVE (self->popup_menu)); gtk_native_check_resize (GTK_NATIVE (self->popup_menu));