diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-09-24 14:18:38 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-09-24 14:18:38 -0400 |
commit | 7eb0ae39c5549bfaa4efb879ef49b1186f48c5c1 (patch) | |
tree | 429fceea0f5c745f8b782006a145decfe9481113 | |
parent | 9fde0137a052ebdb0374a1303a70517cd43afa72 (diff) | |
download | gtk+-7eb0ae39c5549bfaa4efb879ef49b1186f48c5c1.tar.gz |
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
-rw-r--r-- | gtk/gtkcolumnviewcell.c | 54 | ||||
-rw-r--r-- | gtk/gtkcolumnviewlayout.c | 6 | ||||
-rw-r--r-- | 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)); |