forked from AuroraMiddleware/gtk
revealer: Support minimum size of child
Up until now when allocating the child it only used the natural size while the measuring also used the minimum size, resulting in a clipped child when animating if the child had different minimum size and natural size. This was an obvious case when using labels that had ellipsization. This commit gives full allocation to the child by inverting the size the revealer reduces from its animation progress. Code done by Benjamin Otte. Closes: https://gitlab.gnome.org/GNOME/gtk/issues/635
This commit is contained in:
parent
f3e6d00db1
commit
57ef793e6d
@ -293,61 +293,6 @@ effective_transition (GtkRevealer *revealer)
|
||||
return priv->transition_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_get_child_allocation (GtkRevealer *revealer,
|
||||
const GtkAllocation *allocation,
|
||||
GtkAllocation *child_allocation)
|
||||
{
|
||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
||||
GtkWidget *child;
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
g_return_if_fail (revealer != NULL);
|
||||
g_return_if_fail (allocation != NULL);
|
||||
|
||||
child_allocation->x = 0;
|
||||
child_allocation->y = 0;
|
||||
child_allocation->width = 0;
|
||||
child_allocation->height = 0;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (revealer));
|
||||
if (child != NULL && gtk_widget_get_visible (child))
|
||||
{
|
||||
transition = effective_transition (revealer);
|
||||
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL,
|
||||
MAX (0, allocation->height),
|
||||
NULL, &child_allocation->width, NULL, NULL);
|
||||
else
|
||||
gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL,
|
||||
MAX (0, allocation->width),
|
||||
NULL, &child_allocation->height, NULL, NULL);
|
||||
|
||||
child_allocation->width = MAX (child_allocation->width, allocation->width);
|
||||
child_allocation->height = MAX (child_allocation->height, allocation->height);
|
||||
|
||||
switch (transition)
|
||||
{
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT:
|
||||
child_allocation->x = - child_allocation->width * (1 - priv->current_pos);
|
||||
break;
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN:
|
||||
child_allocation->y = - child_allocation->height * (1 - priv->current_pos);
|
||||
break;
|
||||
|
||||
case GTK_REVEALER_TRANSITION_TYPE_NONE:
|
||||
case GTK_REVEALER_TRANSITION_TYPE_CROSSFADE:
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT:
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_add (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
@ -362,6 +307,35 @@ gtk_revealer_real_add (GtkContainer *container,
|
||||
GTK_CONTAINER_CLASS (gtk_revealer_parent_class)->add (container, child);
|
||||
}
|
||||
|
||||
static double
|
||||
get_child_size_scale (GtkRevealer *revealer,
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
||||
|
||||
switch (effective_transition (revealer))
|
||||
{
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT:
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT:
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
return priv->current_pos;
|
||||
else
|
||||
return 1.0;
|
||||
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN:
|
||||
case GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP:
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
return priv->current_pos;
|
||||
else
|
||||
return 1.0;
|
||||
|
||||
case GTK_REVEALER_TRANSITION_TYPE_NONE:
|
||||
case GTK_REVEALER_TRANSITION_TYPE_CROSSFADE:
|
||||
default:
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_real_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
@ -374,8 +348,32 @@ gtk_revealer_real_size_allocate (GtkWidget *widget,
|
||||
if (child != NULL && gtk_widget_get_visible (child))
|
||||
{
|
||||
GtkAllocation child_allocation;
|
||||
double hscale, vscale;
|
||||
|
||||
gtk_revealer_get_child_allocation (revealer, allocation, &child_allocation);
|
||||
child_allocation = *allocation;
|
||||
|
||||
hscale = get_child_size_scale (revealer, GTK_ORIENTATION_HORIZONTAL);
|
||||
vscale = get_child_size_scale (revealer, GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
if (hscale <= 0 || vscale <= 0)
|
||||
{
|
||||
/* don't allocate anything, the child is invisible and the numbers
|
||||
* don't make sense. */
|
||||
return;
|
||||
}
|
||||
else if (hscale < 1.0)
|
||||
{
|
||||
g_assert (vscale == 1.0);
|
||||
child_allocation.width = MIN (G_MAXINT, ceil (child_allocation.width / hscale));
|
||||
if (effective_transition (revealer) == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
child_allocation.x = allocation->width - child_allocation.width;
|
||||
}
|
||||
else if (vscale < 1.0)
|
||||
{
|
||||
child_allocation.height = MIN (G_MAXINT, ceil (child_allocation.height / vscale));
|
||||
if (effective_transition (revealer) == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
||||
child_allocation.y = allocation->height - child_allocation.height;
|
||||
}
|
||||
gtk_widget_size_allocate (child, &child_allocation, -1);
|
||||
}
|
||||
}
|
||||
@ -552,46 +550,6 @@ gtk_revealer_get_child_revealed (GtkRevealer *revealer)
|
||||
return !reveal_child;
|
||||
}
|
||||
|
||||
/* These all report only the natural size, ignoring the minimal size,
|
||||
* because its not really possible to allocate the right size during
|
||||
* animation if the child size can change (without the child
|
||||
* re-arranging itself during the animation).
|
||||
*/
|
||||
|
||||
static void
|
||||
set_height (GtkRevealer *revealer,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
||||
{
|
||||
*minimum_height = round (*minimum_height * priv->current_pos);
|
||||
*natural_height = round (*natural_height * priv->current_pos);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_width (GtkRevealer *revealer,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
||||
GtkRevealerTransitionType transition;
|
||||
|
||||
transition = effective_transition (revealer);
|
||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
{
|
||||
*minimum_width = round (*minimum_width * priv->current_pos);
|
||||
*natural_width = round (*natural_width * priv->current_pos);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_revealer_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@ -601,15 +559,28 @@ gtk_revealer_measure (GtkWidget *widget,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkRevealer *self = GTK_REVEALER (widget);
|
||||
double scale;
|
||||
|
||||
scale = get_child_size_scale (self, OPPOSITE_ORIENTATION (orientation));
|
||||
|
||||
if (for_size >= 0)
|
||||
{
|
||||
if (scale == 0)
|
||||
return;
|
||||
else
|
||||
for_size = MIN (G_MAXINT, ceil (for_size / scale));
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->measure (widget,
|
||||
orientation,
|
||||
for_size,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
set_width (GTK_REVEALER (widget), minimum, natural);
|
||||
else
|
||||
set_height (GTK_REVEALER (widget), minimum, natural);
|
||||
|
||||
scale = get_child_size_scale (self, orientation);
|
||||
*minimum = ceil (*minimum * scale);
|
||||
*natural = ceil (*natural * scale);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user