forked from AuroraMiddleware/gtk
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
This commit is contained in:
parent
3d82fc6d7e
commit
c37f569ae8
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- 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
|
* 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
|
* 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
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
*
|
||||||
* Author: Alexander Larsson <alexl@redhat.com>
|
* Author: Alexander Larsson <alexl@redhat.com>
|
||||||
*
|
* Carlos Soriano <csoriano@gnome.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -115,6 +115,20 @@ static void gtk_revealer_real_get_preferred_width_for_height (GtkWidget
|
|||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkRevealer, gtk_revealer, GTK_TYPE_BIN)
|
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
|
static void
|
||||||
gtk_revealer_init (GtkRevealer *revealer)
|
gtk_revealer_init (GtkRevealer *revealer)
|
||||||
{
|
{
|
||||||
@ -297,10 +311,17 @@ gtk_revealer_get_child_allocation (GtkRevealer *revealer,
|
|||||||
{
|
{
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
GtkRevealerTransitionType transition;
|
GtkRevealerTransitionType transition;
|
||||||
|
GtkBorder padding;
|
||||||
|
gint vertical_padding, horizontal_padding;
|
||||||
|
|
||||||
g_return_if_fail (revealer != NULL);
|
g_return_if_fail (revealer != NULL);
|
||||||
g_return_if_fail (allocation != 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->x = 0;
|
||||||
child_allocation->y = 0;
|
child_allocation->y = 0;
|
||||||
child_allocation->width = 0;
|
child_allocation->width = 0;
|
||||||
@ -312,15 +333,15 @@ gtk_revealer_get_child_allocation (GtkRevealer *revealer,
|
|||||||
transition = effective_transition (revealer);
|
transition = effective_transition (revealer);
|
||||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
||||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
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);
|
&child_allocation->width);
|
||||||
else
|
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->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
child_allocation->width = MAX (child_allocation->width, allocation->width);
|
child_allocation->width = MAX (child_allocation->width, allocation->width - horizontal_padding);
|
||||||
child_allocation->height = MAX (child_allocation->height, allocation->height);
|
child_allocation->height = MAX (child_allocation->height, allocation->height - vertical_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -335,6 +356,7 @@ gtk_revealer_real_realize (GtkWidget *widget)
|
|||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
GtkStyleContext *context;
|
GtkStyleContext *context;
|
||||||
GtkRevealerTransitionType transition;
|
GtkRevealerTransitionType transition;
|
||||||
|
GtkBorder padding;
|
||||||
|
|
||||||
gtk_widget_set_realized (widget, TRUE);
|
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_child_allocation (revealer, &allocation, &child_allocation);
|
||||||
|
|
||||||
|
gtk_revealer_get_padding (revealer, &padding);
|
||||||
attributes.x = 0;
|
attributes.x = 0;
|
||||||
attributes.y = 0;
|
attributes.y = 0;
|
||||||
attributes.width = child_allocation.width;
|
attributes.width = child_allocation.width;
|
||||||
attributes.height = child_allocation.height;
|
attributes.height = child_allocation.height;
|
||||||
|
|
||||||
|
/* See explanation on gtk_revealer_real_size_allocate */
|
||||||
transition = effective_transition (revealer);
|
transition = effective_transition (revealer);
|
||||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
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)
|
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 =
|
priv->bin_window =
|
||||||
gdk_window_new (priv->view_window, &attributes, attributes_mask);
|
gdk_window_new (priv->view_window, &attributes, attributes_mask);
|
||||||
@ -440,6 +475,7 @@ gtk_revealer_real_size_allocate (GtkWidget *widget,
|
|||||||
gboolean window_visible;
|
gboolean window_visible;
|
||||||
int bin_x, bin_y;
|
int bin_x, bin_y;
|
||||||
GtkRevealerTransitionType transition;
|
GtkRevealerTransitionType transition;
|
||||||
|
GtkBorder padding;
|
||||||
|
|
||||||
g_return_if_fail (allocation != NULL);
|
g_return_if_fail (allocation != NULL);
|
||||||
|
|
||||||
@ -463,17 +499,54 @@ gtk_revealer_real_size_allocate (GtkWidget *widget,
|
|||||||
gdk_window_show (priv->view_window);
|
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,
|
gdk_window_move_resize (priv->view_window,
|
||||||
allocation->x, allocation->y,
|
allocation->x, allocation->y,
|
||||||
allocation->width, allocation->height);
|
allocation->width, allocation->height);
|
||||||
|
|
||||||
|
gtk_revealer_get_padding (revealer, &padding);
|
||||||
bin_x = 0;
|
bin_x = 0;
|
||||||
bin_y = 0;
|
bin_y = 0;
|
||||||
|
|
||||||
transition = effective_transition (revealer);
|
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)
|
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)
|
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,
|
gdk_window_move_resize (priv->bin_window,
|
||||||
bin_x, bin_y,
|
bin_x, bin_y,
|
||||||
@ -736,30 +809,53 @@ gtk_revealer_get_child_revealed (GtkRevealer *revealer)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_revealer_real_get_preferred_height (GtkWidget *widget,
|
set_height_with_paddings (GtkRevealer *revealer,
|
||||||
|
gint preferred_minimum_height,
|
||||||
|
gint preferred_natural_height,
|
||||||
gint *minimum_height_out,
|
gint *minimum_height_out,
|
||||||
gint *natural_height_out)
|
gint *natural_height_out)
|
||||||
{
|
{
|
||||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
|
||||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
||||||
gint minimum_height;
|
gint minimum_height;
|
||||||
gint natural_height;
|
gint natural_height;
|
||||||
GtkRevealerTransitionType transition;
|
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);
|
transition = effective_transition (revealer);
|
||||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
|
if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
|
||||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
|
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
|
||||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
||||||
|
{
|
||||||
|
/* Padding are included in the animation */
|
||||||
|
minimum_height = round (minimum_height * priv->current_pos);
|
||||||
natural_height = round (natural_height * priv->current_pos);
|
natural_height = round (natural_height * priv->current_pos);
|
||||||
|
}
|
||||||
|
|
||||||
minimum_height = MIN (minimum_height, natural_height);
|
*minimum_height_out = MIN (minimum_height, natural_height);
|
||||||
|
|
||||||
*minimum_height_out = minimum_height;
|
|
||||||
*natural_height_out = 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
|
static void
|
||||||
gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
|
gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
|
||||||
gint width,
|
gint width,
|
||||||
@ -767,23 +863,45 @@ gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
|
|||||||
gint *natural_height_out)
|
gint *natural_height_out)
|
||||||
{
|
{
|
||||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
|
||||||
gint minimum_height;
|
gint minimum_height;
|
||||||
gint natural_height;
|
gint natural_height;
|
||||||
GtkRevealerTransitionType transition;
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height_for_width (widget, width, &minimum_height, &natural_height);
|
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height_for_width (widget, width, &minimum_height, &natural_height);
|
||||||
|
|
||||||
|
set_height_with_paddings (revealer, minimum_height, natural_height,
|
||||||
|
minimum_height_out, natural_height_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_width_with_paddings (GtkRevealer *revealer,
|
||||||
|
gint preferred_minimum_width,
|
||||||
|
gint preferred_natural_width,
|
||||||
|
gint *minimum_width_out,
|
||||||
|
gint *natural_width_out)
|
||||||
|
{
|
||||||
|
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
||||||
|
gint minimum_width;
|
||||||
|
gint natural_width;
|
||||||
|
GtkRevealerTransitionType transition;
|
||||||
|
GtkBorder padding;
|
||||||
|
gint horizontal_padding;
|
||||||
|
|
||||||
|
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);
|
transition = effective_transition (revealer);
|
||||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
|
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
|
||||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
|
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
|
{
|
||||||
natural_height = round (natural_height * priv->current_pos);
|
/* Paddings are included in the animation */
|
||||||
|
minimum_width = round (minimum_width * priv->current_pos);
|
||||||
|
natural_width = round (natural_width * priv->current_pos);
|
||||||
|
}
|
||||||
|
|
||||||
minimum_height = MIN (minimum_height, natural_height);
|
*minimum_width_out = MIN (minimum_width, natural_width);
|
||||||
|
*natural_width_out = natural_width;
|
||||||
*minimum_height_out = minimum_height;
|
|
||||||
*natural_height_out = natural_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -792,23 +910,12 @@ gtk_revealer_real_get_preferred_width (GtkWidget *widget,
|
|||||||
gint *natural_width_out)
|
gint *natural_width_out)
|
||||||
{
|
{
|
||||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
|
||||||
gint minimum_width;
|
gint minimum_width;
|
||||||
gint natural_width;
|
gint natural_width;
|
||||||
GtkRevealerTransitionType transition;
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width (widget, &minimum_width, &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,
|
||||||
transition = effective_transition (revealer);
|
minimum_width_out, natural_width_out);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -818,23 +925,13 @@ gtk_revealer_real_get_preferred_width_for_height (GtkWidget *widget,
|
|||||||
gint *natural_width_out)
|
gint *natural_width_out)
|
||||||
{
|
{
|
||||||
GtkRevealer *revealer = GTK_REVEALER (widget);
|
GtkRevealer *revealer = GTK_REVEALER (widget);
|
||||||
GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
|
|
||||||
gint minimum_width;
|
gint minimum_width;
|
||||||
gint natural_width;
|
gint natural_width;
|
||||||
GtkRevealerTransitionType transition;
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width_for_height (widget, height, &minimum_width, &natural_width);
|
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width_for_height (widget, height, &minimum_width, &natural_width);
|
||||||
|
|
||||||
transition = effective_transition (revealer);
|
set_width_with_paddings (revealer, minimum_width, natural_width,
|
||||||
if (transition == GTK_REVEALER_TRANSITION_TYPE_NONE ||
|
minimum_width_out, natural_width_out);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user