forked from AuroraMiddleware/gtk
widget: Fix gtk_widget_size_allocate()
Compute the matrix for adjusted sizes etc properly.
This commit is contained in:
parent
36ac867ea9
commit
d247e5707d
@ -208,6 +208,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
|||||||
int adjusted_for_size;
|
int adjusted_for_size;
|
||||||
int minimum_for_size = 0;
|
int minimum_for_size = 0;
|
||||||
int natural_for_size = 0;
|
int natural_for_size = 0;
|
||||||
|
int dummy = 0;
|
||||||
|
|
||||||
/* Pull the minimum for_size from the cache as it's needed to adjust
|
/* Pull the minimum for_size from the cache as it's needed to adjust
|
||||||
* the proposed 'for_size' */
|
* the proposed 'for_size' */
|
||||||
@ -221,7 +222,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
|||||||
adjusted_for_size = for_size;
|
adjusted_for_size = for_size;
|
||||||
gtk_widget_adjust_size_allocation (widget, OPPOSITE_ORIENTATION (orientation),
|
gtk_widget_adjust_size_allocation (widget, OPPOSITE_ORIENTATION (orientation),
|
||||||
&for_size, &natural_for_size,
|
&for_size, &natural_for_size,
|
||||||
NULL, &adjusted_for_size);
|
&dummy, &adjusted_for_size);
|
||||||
|
|
||||||
adjusted_for_size -= css_extra_for_size;
|
adjusted_for_size -= css_extra_for_size;
|
||||||
|
|
||||||
|
153
gtk/gtkwidget.c
153
gtk/gtkwidget.c
@ -4188,11 +4188,7 @@ gtk_widget_allocate (GtkWidget *widget,
|
|||||||
const graphene_matrix_t *transform)
|
const graphene_matrix_t *transform)
|
||||||
{
|
{
|
||||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||||
int real_width;
|
GdkRectangle adjusted;
|
||||||
int real_height;
|
|
||||||
int adjusted_width;
|
|
||||||
int adjusted_height;
|
|
||||||
graphene_matrix_t adjusted_transform;
|
|
||||||
gboolean alloc_needed;
|
gboolean alloc_needed;
|
||||||
gboolean size_changed;
|
gboolean size_changed;
|
||||||
gboolean baseline_changed;
|
gboolean baseline_changed;
|
||||||
@ -4249,9 +4245,7 @@ gtk_widget_allocate (GtkWidget *widget,
|
|||||||
priv->allocated_height = height;
|
priv->allocated_height = height;
|
||||||
priv->allocated_size_baseline = baseline;
|
priv->allocated_size_baseline = baseline;
|
||||||
|
|
||||||
adjusted_width = width;
|
adjusted = (GdkRectangle) { 0, 0, width, height };
|
||||||
adjusted_height = height;
|
|
||||||
graphene_matrix_init_from_matrix (&adjusted_transform, transform);
|
|
||||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||||
{
|
{
|
||||||
/* Go ahead and request the height for allocated width, note that the internals
|
/* Go ahead and request the height for allocated width, note that the internals
|
||||||
@ -4291,47 +4285,52 @@ gtk_widget_allocate (GtkWidget *widget,
|
|||||||
GTK_ORIENTATION_HORIZONTAL,
|
GTK_ORIENTATION_HORIZONTAL,
|
||||||
&dummy,
|
&dummy,
|
||||||
&natural_width,
|
&natural_width,
|
||||||
&adjusted_transform,
|
&adjusted.x,
|
||||||
&adjusted_width);
|
&adjusted.width);
|
||||||
gtk_widget_adjust_size_allocation (widget,
|
gtk_widget_adjust_size_allocation (widget,
|
||||||
GTK_ORIENTATION_VERTICAL,
|
GTK_ORIENTATION_VERTICAL,
|
||||||
&dummy,
|
&dummy,
|
||||||
&natural_height,
|
&natural_height,
|
||||||
&adjusted_transform,
|
&adjusted.y,
|
||||||
&adjusted_height);
|
&adjusted.height);
|
||||||
if (baseline >= 0)
|
if (baseline >= 0)
|
||||||
baseline -= priv->margin.top;
|
baseline -= priv->margin.top;
|
||||||
|
|
||||||
real_width = adjusted_width;
|
if (adjusted.width < 0 || adjusted.height < 0)
|
||||||
real_height = adjusted_height;
|
|
||||||
|
|
||||||
if (real_width < 0 || real_height < 0)
|
|
||||||
{
|
{
|
||||||
g_warning ("gtk_widget_size_allocate(): attempt to allocate %s %s %p with width %d and height %d",
|
g_warning ("gtk_widget_size_allocate(): attempt to allocate %s %s %p with width %d and height %d",
|
||||||
G_OBJECT_TYPE_NAME (widget), gtk_css_node_get_name (priv->cssnode), widget,
|
G_OBJECT_TYPE_NAME (widget), gtk_css_node_get_name (priv->cssnode), widget,
|
||||||
real_width,
|
adjusted.width,
|
||||||
real_height);
|
adjusted.height);
|
||||||
|
|
||||||
real_width = 0;
|
adjusted.width = 0;
|
||||||
real_height = 0;
|
adjusted.height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (_gtk_widget_get_has_surface (widget)))
|
if (G_UNLIKELY (_gtk_widget_get_has_surface (widget)))
|
||||||
{
|
{
|
||||||
real_width = MAX (1, real_width);
|
adjusted.width = MAX (1, adjusted.width);
|
||||||
real_height = MAX (1, real_height);
|
adjusted.height = MAX (1, adjusted.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
style = gtk_css_node_get_style (priv->cssnode);
|
style = gtk_css_node_get_style (priv->cssnode);
|
||||||
get_box_margin (style, &margin);
|
get_box_margin (style, &margin);
|
||||||
get_box_border (style, &border);
|
get_box_border (style, &border);
|
||||||
get_box_padding (style, &padding);
|
get_box_padding (style, &padding);
|
||||||
graphene_matrix_translate (&adjusted_transform,
|
adjusted.x += margin.left + border.left + padding.left;
|
||||||
&GRAPHENE_POINT3D_INIT (
|
adjusted.y += margin.top + border.top + padding.top;
|
||||||
margin.left + border.left + padding.left,
|
|
||||||
margin.top + border.top + padding.top,
|
/* Since gtk_widget_measure does it for us, we can be sure here that
|
||||||
0
|
* the given alloaction is large enough for the css margin/bordder/padding */
|
||||||
));
|
adjusted.width -= margin.left + border.left + padding.left +
|
||||||
|
margin.right + border.right + padding.right;
|
||||||
|
adjusted.height -= margin.top + border.top + padding.top +
|
||||||
|
margin.bottom + border.bottom + padding.bottom;
|
||||||
|
if (baseline >= 0)
|
||||||
|
baseline -= margin.top + border.top + padding.top;
|
||||||
|
|
||||||
|
graphene_matrix_init_translate (&priv->transform, &GRAPHENE_POINT3D_INIT (adjusted.x, adjusted.y, 0));
|
||||||
|
graphene_matrix_multiply (&priv->transform, transform, &priv->transform);
|
||||||
|
|
||||||
if (!alloc_needed && !size_changed && !baseline_changed)
|
if (!alloc_needed && !size_changed && !baseline_changed)
|
||||||
{
|
{
|
||||||
@ -4347,20 +4346,11 @@ gtk_widget_allocate (GtkWidget *widget,
|
|||||||
window_alloc.width, window_alloc.height);
|
window_alloc.width, window_alloc.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
goto only_transform_changed;
|
goto skip_allocate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Since gtk_widget_measure does it for us, we can be sure here that
|
priv->width = adjusted.width;
|
||||||
* the given alloaction is large enough for the css margin/bordder/padding */
|
priv->height = adjusted.height;
|
||||||
real_width -= margin.left + border.left + padding.left +
|
|
||||||
margin.right + border.right + padding.right;
|
|
||||||
real_height -= margin.top + border.top + padding.top +
|
|
||||||
margin.bottom + border.bottom + padding.bottom;
|
|
||||||
if (baseline >= 0)
|
|
||||||
baseline -= margin.top + border.top + padding.top;
|
|
||||||
|
|
||||||
priv->width = real_width;
|
|
||||||
priv->height = real_height;
|
|
||||||
priv->baseline = baseline;
|
priv->baseline = baseline;
|
||||||
|
|
||||||
if (g_signal_has_handler_pending (widget, widget_signals[SIZE_ALLOCATE], 0, FALSE))
|
if (g_signal_has_handler_pending (widget, widget_signals[SIZE_ALLOCATE], 0, FALSE))
|
||||||
@ -4389,9 +4379,7 @@ gtk_widget_allocate (GtkWidget *widget,
|
|||||||
|
|
||||||
gtk_widget_update_paintables (widget);
|
gtk_widget_update_paintables (widget);
|
||||||
|
|
||||||
only_transform_changed:
|
skip_allocate:
|
||||||
graphene_matrix_init_from_matrix (&priv->transform, &adjusted_transform);
|
|
||||||
|
|
||||||
if (size_changed || baseline_changed)
|
if (size_changed || baseline_changed)
|
||||||
gtk_widget_queue_draw (widget);
|
gtk_widget_queue_draw (widget);
|
||||||
else if (transform_changed && priv->parent)
|
else if (transform_changed && priv->parent)
|
||||||
@ -4616,11 +4604,10 @@ effective_align (GtkAlign align,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
adjust_for_align (GtkOrientation orientation,
|
adjust_for_align (GtkAlign align,
|
||||||
GtkAlign align,
|
gint *natural_size,
|
||||||
int *natural_size,
|
gint *allocated_pos,
|
||||||
graphene_matrix_t *transform,
|
gint *allocated_size)
|
||||||
int *allocated_size)
|
|
||||||
{
|
{
|
||||||
switch (align)
|
switch (align)
|
||||||
{
|
{
|
||||||
@ -4630,38 +4617,20 @@ adjust_for_align (GtkOrientation orientation,
|
|||||||
/* change nothing */
|
/* change nothing */
|
||||||
break;
|
break;
|
||||||
case GTK_ALIGN_START:
|
case GTK_ALIGN_START:
|
||||||
/* keep position where it is */
|
/* keep *allocated_pos where it is */
|
||||||
*allocated_size = MIN (*allocated_size, *natural_size);
|
*allocated_size = MIN (*allocated_size, *natural_size);
|
||||||
break;
|
break;
|
||||||
case GTK_ALIGN_END:
|
case GTK_ALIGN_END:
|
||||||
if (*allocated_size > *natural_size)
|
if (*allocated_size > *natural_size)
|
||||||
{
|
{
|
||||||
if (transform)
|
*allocated_pos += (*allocated_size - *natural_size);
|
||||||
{
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
||||||
graphene_matrix_translate (transform,
|
|
||||||
&GRAPHENE_POINT3D_INIT (*allocated_size - *natural_size, 0, 0));
|
|
||||||
else
|
|
||||||
graphene_matrix_translate (transform,
|
|
||||||
&GRAPHENE_POINT3D_INIT (0, *allocated_size - *natural_size, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
*allocated_size = *natural_size;
|
*allocated_size = *natural_size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GTK_ALIGN_CENTER:
|
case GTK_ALIGN_CENTER:
|
||||||
if (*allocated_size > *natural_size)
|
if (*allocated_size > *natural_size)
|
||||||
{
|
{
|
||||||
if (transform)
|
*allocated_pos += (*allocated_size - *natural_size) / 2;
|
||||||
{
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
||||||
graphene_matrix_translate (transform,
|
|
||||||
&GRAPHENE_POINT3D_INIT ((*allocated_size - *natural_size) / 2, 0, 0));
|
|
||||||
else
|
|
||||||
graphene_matrix_translate (transform,
|
|
||||||
&GRAPHENE_POINT3D_INIT (0, (*allocated_size - *natural_size) / 2, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
*allocated_size = MIN (*allocated_size, *natural_size);
|
*allocated_size = MIN (*allocated_size, *natural_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4669,27 +4638,17 @@ adjust_for_align (GtkOrientation orientation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
adjust_for_margin (GtkOrientation orientation,
|
adjust_for_margin(gint start_margin,
|
||||||
int start_margin,
|
gint end_margin,
|
||||||
int end_margin,
|
gint *minimum_size,
|
||||||
int *minimum_size,
|
gint *natural_size,
|
||||||
int *natural_size,
|
gint *allocated_pos,
|
||||||
graphene_matrix_t *transform,
|
gint *allocated_size)
|
||||||
int *allocated_size)
|
|
||||||
{
|
{
|
||||||
*minimum_size -= (start_margin + end_margin);
|
*minimum_size -= (start_margin + end_margin);
|
||||||
*natural_size -= (start_margin + end_margin);
|
*natural_size -= (start_margin + end_margin);
|
||||||
|
*allocated_pos += start_margin;
|
||||||
*allocated_size -= (start_margin + end_margin);
|
*allocated_size -= (start_margin + end_margin);
|
||||||
|
|
||||||
if (transform)
|
|
||||||
{
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
||||||
graphene_matrix_translate (transform,
|
|
||||||
&GRAPHENE_POINT3D_INIT (start_margin, 0, 0));
|
|
||||||
else
|
|
||||||
graphene_matrix_translate (transform,
|
|
||||||
&GRAPHENE_POINT3D_INIT (0, start_margin, 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -4697,32 +4656,28 @@ gtk_widget_adjust_size_allocation (GtkWidget *widget,
|
|||||||
GtkOrientation orientation,
|
GtkOrientation orientation,
|
||||||
gint *minimum_size,
|
gint *minimum_size,
|
||||||
gint *natural_size,
|
gint *natural_size,
|
||||||
graphene_matrix_t *transform,
|
gint *allocated_pos,
|
||||||
gint *allocated_size)
|
gint *allocated_size)
|
||||||
{
|
{
|
||||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||||
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
{
|
{
|
||||||
adjust_for_margin (orientation,
|
adjust_for_margin (priv->margin.left,
|
||||||
priv->margin.left,
|
|
||||||
priv->margin.right,
|
priv->margin.right,
|
||||||
minimum_size, natural_size,
|
minimum_size, natural_size,
|
||||||
transform, allocated_size);
|
allocated_pos, allocated_size);
|
||||||
adjust_for_align (orientation,
|
adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
|
||||||
effective_align (priv->halign, _gtk_widget_get_direction (widget)),
|
natural_size, allocated_pos, allocated_size);
|
||||||
natural_size, transform, allocated_size);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
adjust_for_margin (orientation,
|
adjust_for_margin (priv->margin.top,
|
||||||
priv->margin.top,
|
|
||||||
priv->margin.bottom,
|
priv->margin.bottom,
|
||||||
minimum_size, natural_size,
|
minimum_size, natural_size,
|
||||||
transform, allocated_size);
|
allocated_pos, allocated_size);
|
||||||
adjust_for_align (orientation,
|
adjust_for_align (effective_align (priv->valign, GTK_TEXT_DIR_NONE),
|
||||||
effective_align (priv->valign, GTK_TEXT_DIR_NONE),
|
natural_size, allocated_pos, allocated_size);
|
||||||
natural_size, transform, allocated_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ void gtk_widget_adjust_size_allocation (GtkWidget *w
|
|||||||
GtkOrientation orientation,
|
GtkOrientation orientation,
|
||||||
gint *minimum_size,
|
gint *minimum_size,
|
||||||
gint *natural_size,
|
gint *natural_size,
|
||||||
graphene_matrix_t *transform,
|
gint *allocated_pos,
|
||||||
gint *allocated_size);
|
gint *allocated_size);
|
||||||
void gtk_widget_adjust_baseline_request (GtkWidget *widget,
|
void gtk_widget_adjust_baseline_request (GtkWidget *widget,
|
||||||
gint *minimum_baseline,
|
gint *minimum_baseline,
|
||||||
|
Loading…
Reference in New Issue
Block a user