[gtk/revealer-support-min-size-master: 93/93] revealer: Support minimum size of child
- From: Carlos Soriano <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/revealer-support-min-size-master: 93/93] revealer: Support minimum size of child
- Date: Tue, 18 Sep 2018 09:40:00 +0000 (UTC)
commit 57ef793e6db5c4ad848d14815b1e74532cbb775e
Author: Carlos Soriano <csoriano redhat com>
Date: Tue Sep 18 10:55:02 2018 +0200
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
gtk/gtkrevealer.c | 169 ++++++++++++++++++++++--------------------------------
1 file changed, 70 insertions(+), 99 deletions(-)
---
diff --git a/gtk/gtkrevealer.c b/gtk/gtkrevealer.c
index 13c37b9a80..b0dfc0c691 100644
--- a/gtk/gtkrevealer.c
+++ b/gtk/gtkrevealer.c
@@ -294,72 +294,46 @@ effective_transition (GtkRevealer *revealer)
}
static void
-gtk_revealer_get_child_allocation (GtkRevealer *revealer,
- const GtkAllocation *allocation,
- GtkAllocation *child_allocation)
+gtk_revealer_real_add (GtkContainer *container,
+ GtkWidget *child)
{
+ GtkRevealer *revealer = GTK_REVEALER (container);
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);
+ g_return_if_fail (child != NULL);
- 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;
- }
- }
+ gtk_widget_set_child_visible (child, priv->current_pos != 0.0);
+ GTK_CONTAINER_CLASS (gtk_revealer_parent_class)->add (container, child);
}
-static void
-gtk_revealer_real_add (GtkContainer *container,
- GtkWidget *child)
+static double
+get_child_size_scale (GtkRevealer *revealer,
+ GtkOrientation orientation)
{
- GtkRevealer *revealer = GTK_REVEALER (container);
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
- g_return_if_fail (child != NULL);
+ 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;
- gtk_widget_set_child_visible (child, priv->current_pos != 0.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;
- GTK_CONTAINER_CLASS (gtk_revealer_parent_class)->add (container, child);
+ case GTK_REVEALER_TRANSITION_TYPE_NONE:
+ case GTK_REVEALER_TRANSITION_TYPE_CROSSFADE:
+ default:
+ return 1.0;
+ }
}
static void
@@ -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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]