diff options
author | Benjamin Otte <otte.benjamin@googlemail.com> | 2018-09-18 15:19:12 +0000 |
---|---|---|
committer | Benjamin Otte <otte.benjamin@googlemail.com> | 2018-09-18 15:19:12 +0000 |
commit | 60cb315be67dc054e71d3084434da0c5e58b1b76 (patch) | |
tree | d60cabe7bf9fc2b5200fe6ba65b8edba1ecf00c8 | |
parent | 58cdd5139e7ba93fd9a7d52da72872027b0ddfb7 (diff) | |
parent | 57ef793e6db5c4ad848d14815b1e74532cbb775e (diff) | |
download | gtk+-60cb315be67dc054e71d3084434da0c5e58b1b76.tar.gz |
Merge branch 'revealer-support-min-size-master' into 'master'
gtkrevealer: support minimum size of child
Closes #635
See merge request GNOME/gtk!317
-rw-r--r-- | gtk/gtkrevealer.c | 169 |
1 files 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 |