[gtk+] gtkrevealer: add css padding support
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gtkrevealer: add css padding support
- Date: Fri, 5 Jun 2015 03:41:37 +0000 (UTC)
commit c37f569ae8fed4e5306f78ec44a89aeefd4aec64
Author: Carlos Soriano <csoriano gnome org>
Date: Wed Jun 3 14:58:04 2015 +0200
gtkrevealer: add css padding support
Add css padding support to GtkRevealer.
As a future work, GtkRevealer still needs to support the border
property.
https://bugzilla.gnome.org/show_bug.cgi?id=750338
gtk/gtkrevealer.c | 205 +++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 151 insertions(+), 54 deletions(-)
---
diff --git a/gtk/gtkrevealer.c b/gtk/gtkrevealer.c
index 5509b75..2e90c27 100644
--- a/gtk/gtkrevealer.c
+++ b/gtk/gtkrevealer.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
- * Copyright (c) 2013 Red Hat, Inc.
+ * Copyright 2013, 2015 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -17,7 +17,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author: Alexander Larsson <alexl redhat com>
- *
+ * Carlos Soriano <csoriano gnome org>
*/
#include "config.h"
@@ -116,6 +116,20 @@ static void gtk_revealer_real_get_preferred_width_for_height (GtkWidget
G_DEFINE_TYPE_WITH_PRIVATE (GtkRevealer, gtk_revealer, GTK_TYPE_BIN)
static void
+gtk_revealer_get_padding (GtkRevealer *revealer,
+ GtkBorder *padding)
+{
+ GtkWidget *widget = GTK_WIDGET (revealer);
+ GtkStyleContext *context;
+ GtkStateFlags state;
+
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_style_context_get_state (context);
+
+ gtk_style_context_get_padding (context, state, padding);
+}
+
+static void
gtk_revealer_init (GtkRevealer *revealer)
{
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
@@ -297,10 +311,17 @@ gtk_revealer_get_child_allocation (GtkRevealer *revealer,
{
GtkWidget *child;
GtkRevealerTransitionType transition;
+ GtkBorder padding;
+ gint vertical_padding, horizontal_padding;
g_return_if_fail (revealer != NULL);
g_return_if_fail (allocation != NULL);
+ /* See explanation on gtk_revealer_real_size_allocate */
+ gtk_revealer_get_padding (revealer, &padding);
+ vertical_padding = padding.top + padding.bottom;
+ horizontal_padding = padding.left + padding.right;
+
child_allocation->x = 0;
child_allocation->y = 0;
child_allocation->width = 0;
@@ -312,15 +333,15 @@ gtk_revealer_get_child_allocation (GtkRevealer *revealer,
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
- gtk_widget_get_preferred_width_for_height (child, allocation->height, NULL,
+ gtk_widget_get_preferred_width_for_height (child, MAX (0, allocation->height - vertical_padding),
NULL,
&child_allocation->width);
else
- gtk_widget_get_preferred_height_for_width (child, allocation->width, NULL,
+ gtk_widget_get_preferred_height_for_width (child, MAX (0, allocation->width - horizontal_padding),
NULL,
&child_allocation->height);
}
- child_allocation->width = MAX (child_allocation->width, allocation->width);
- child_allocation->height = MAX (child_allocation->height, allocation->height);
+ child_allocation->width = MAX (child_allocation->width, allocation->width - horizontal_padding);
+ child_allocation->height = MAX (child_allocation->height, allocation->height - vertical_padding);
}
static void
@@ -335,6 +356,7 @@ gtk_revealer_real_realize (GtkWidget *widget)
GtkWidget *child;
GtkStyleContext *context;
GtkRevealerTransitionType transition;
+ GtkBorder padding;
gtk_widget_set_realized (widget, TRUE);
@@ -359,16 +381,29 @@ gtk_revealer_real_realize (GtkWidget *widget)
gtk_revealer_get_child_allocation (revealer, &allocation, &child_allocation);
+ gtk_revealer_get_padding (revealer, &padding);
attributes.x = 0;
attributes.y = 0;
attributes.width = child_allocation.width;
attributes.height = child_allocation.height;
+ /* See explanation on gtk_revealer_real_size_allocate */
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
- attributes.y = allocation.height - child_allocation.height;
+ {
+ attributes.y = allocation.height - child_allocation.height - padding.bottom;
+ attributes.x = padding.left;
+ }
else if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
- attributes.x = allocation.width - child_allocation.width;
+ {
+ attributes.y = padding.top;
+ attributes.x = allocation.width - child_allocation.width - padding.right;
+ }
+ else
+ {
+ attributes.y = padding.top;
+ attributes.x = padding.left;
+ }
priv->bin_window =
gdk_window_new (priv->view_window, &attributes, attributes_mask);
@@ -440,6 +475,7 @@ gtk_revealer_real_size_allocate (GtkWidget *widget,
gboolean window_visible;
int bin_x, bin_y;
GtkRevealerTransitionType transition;
+ GtkBorder padding;
g_return_if_fail (allocation != NULL);
@@ -463,17 +499,54 @@ gtk_revealer_real_size_allocate (GtkWidget *widget,
gdk_window_show (priv->view_window);
}
+ /* The view window will follow the revealer allocation, which is modified
+ * along the animation */
gdk_window_move_resize (priv->view_window,
allocation->x, allocation->y,
allocation->width, allocation->height);
+ gtk_revealer_get_padding (revealer, &padding);
bin_x = 0;
bin_y = 0;
+
transition = effective_transition (revealer);
+ /* The child allocation is fixed (it is not modified by the animation),
+ * and it's origin is relative to the bin_window.
+ * The bin_window has the same allocation as the child, and then the bin_window
+ * deals with the relative positioning with respect to the revealer taking
+ * into account the paddings of the revealer.
+ *
+ * For most of transitions, the bin_window moves along with the revealer,
+ * as its allocation changes.
+ * However for GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN
+ * we need to first move the bin_window upwards and then slide it down in
+ * the revealer.
+ * Otherwise the child would appear as static and the revealer will allocate
+ * following the animation, clipping the child.
+ * To calculate the correct y position for this case:
+ * allocation->height - child_allocation.height is the relative position
+ * towards the revealer taking into account the animation progress with
+ * both vertical paddings added, therefore we need to substract the part
+ * that we don't want to take into account for the y position, which
+ * in this case is the bottom padding.
+ *
+ * The same special treatment is needed for GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT.
+ */
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
- bin_y = allocation->height - child_allocation.height;
+ {
+ bin_y = allocation->height - child_allocation.height - padding.bottom;
+ bin_x = padding.left;
+ }
else if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
- bin_x = allocation->width - child_allocation.width;
+ {
+ bin_y = padding.top;
+ bin_x = allocation->width - child_allocation.width - padding.right;
+ }
+ else
+ {
+ bin_x = padding.left;
+ bin_y = padding.top;
+ }
gdk_window_move_resize (priv->bin_window,
bin_x, bin_y,
@@ -736,105 +809,129 @@ gtk_revealer_get_child_revealed (GtkRevealer *revealer)
*/
static void
-gtk_revealer_real_get_preferred_height (GtkWidget *widget,
- gint *minimum_height_out,
- gint *natural_height_out)
+set_height_with_paddings (GtkRevealer *revealer,
+ gint preferred_minimum_height,
+ gint preferred_natural_height,
+ gint *minimum_height_out,
+ gint *natural_height_out)
{
- GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
gint minimum_height;
gint natural_height;
GtkRevealerTransitionType transition;
+ GtkBorder padding;
+ gint vertical_padding;
- GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height (widget, &minimum_height,
&natural_height);
+ gtk_revealer_get_padding (revealer, &padding);
+ vertical_padding = padding.top + padding.bottom;
+ minimum_height = preferred_minimum_height + vertical_padding;
+ natural_height = preferred_natural_height + vertical_padding;
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
- natural_height = round (natural_height * priv->current_pos);
-
- minimum_height = MIN (minimum_height, natural_height);
+ {
+ /* Padding are included in the animation */
+ minimum_height = round (minimum_height * priv->current_pos);
+ natural_height = round (natural_height * priv->current_pos);
+ }
- *minimum_height_out = minimum_height;
+ *minimum_height_out = MIN (minimum_height, natural_height);
*natural_height_out = natural_height;
}
static void
+gtk_revealer_real_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height_out,
+ gint *natural_height_out)
+{
+ GtkRevealer *revealer = GTK_REVEALER (widget);
+ gint minimum_height;
+ gint natural_height;
+
+ GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height (widget, &minimum_height,
&natural_height);
+
+ set_height_with_paddings (revealer, minimum_height, natural_height,
+ minimum_height_out, natural_height_out);
+}
+
+static void
gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_height_out,
gint *natural_height_out)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
- GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
gint minimum_height;
gint natural_height;
- GtkRevealerTransitionType transition;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height_for_width (widget, width,
&minimum_height, &natural_height);
- transition = effective_transition (revealer);
- if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
- transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
- transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
- natural_height = round (natural_height * priv->current_pos);
-
- minimum_height = MIN (minimum_height, natural_height);
-
- *minimum_height_out = minimum_height;
- *natural_height_out = natural_height;
+ set_height_with_paddings (revealer, minimum_height, natural_height,
+ minimum_height_out, natural_height_out);
}
static void
-gtk_revealer_real_get_preferred_width (GtkWidget *widget,
- gint *minimum_width_out,
- gint *natural_width_out)
+set_width_with_paddings (GtkRevealer *revealer,
+ gint preferred_minimum_width,
+ gint preferred_natural_width,
+ gint *minimum_width_out,
+ gint *natural_width_out)
{
- GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
gint minimum_width;
gint natural_width;
GtkRevealerTransitionType transition;
+ GtkBorder padding;
+ gint horizontal_padding;
- GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width (widget, &minimum_width, &natural_width);
+ gtk_revealer_get_padding (revealer, &padding);
+ horizontal_padding = padding.left + padding.right;
+ minimum_width = preferred_natural_width + horizontal_padding;
+ natural_width = preferred_minimum_width + horizontal_padding;
transition = effective_transition (revealer);
- if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
- transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
+ if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
- natural_width = round (natural_width * priv->current_pos);
-
- minimum_width = MIN (minimum_width, natural_width);
+ {
+ /* Paddings are included in the animation */
+ minimum_width = round (minimum_width * priv->current_pos);
+ natural_width = round (natural_width * priv->current_pos);
+ }
- *minimum_width_out = minimum_width;
+ *minimum_width_out = MIN (minimum_width, natural_width);
*natural_width_out = natural_width;
}
static void
+gtk_revealer_real_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width_out,
+ gint *natural_width_out)
+{
+ GtkRevealer *revealer = GTK_REVEALER (widget);
+ gint minimum_width;
+ gint natural_width;
+
+ GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width (widget, &minimum_width, &natural_width);
+ set_width_with_paddings (revealer, minimum_width, natural_width,
+ minimum_width_out, natural_width_out);
+}
+
+static void
gtk_revealer_real_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum_width_out,
gint *natural_width_out)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
- GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
gint minimum_width;
gint natural_width;
- GtkRevealerTransitionType transition;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width_for_height (widget, height,
&minimum_width, &natural_width);
- transition = effective_transition (revealer);
- if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
- transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
- transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
- natural_width = round (natural_width * priv->current_pos);
-
- minimum_width = MIN (minimum_width, natural_width);
-
- *minimum_width_out = minimum_width;
- *natural_width_out = natural_width;
+ set_width_with_paddings (revealer, minimum_width, natural_width,
+ minimum_width_out, natural_width_out);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]