summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2013-03-07 13:45:01 +0100
committerAlexander Larsson <alexl@redhat.com>2013-04-23 05:50:38 +0200
commit6acc8c0817ecc68be491300d9db8605e3e6ae9be (patch)
tree3d759b8aed8f98c93ff2090822188217cc8a1b6e
parent9a42942afbe9f535e44413c5bfe49a44577cf238 (diff)
downloadgtk+-6acc8c0817ecc68be491300d9db8605e3e6ae9be.tar.gz
GtkAlignment: Support baselines
We now report any baselines from the child, and allocate it. Also, in the case of a baselign aligned child we ignore yscale/yalign as that is not supportable.
-rw-r--r--gtk/gtkalignment.c82
1 files changed, 70 insertions, 12 deletions
diff --git a/gtk/gtkalignment.c b/gtk/gtkalignment.c
index ddd627ce86..f85c90dc32 100644
--- a/gtk/gtkalignment.c
+++ b/gtk/gtkalignment.c
@@ -108,6 +108,12 @@ static void gtk_alignment_get_preferred_height_for_width (GtkWidget *w
gint for_size,
gint *minimum_size,
gint *natural_size);
+static void gtk_alignment_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size,
+ gint *minimum_baseline,
+ gint *natural_baseline);
G_DEFINE_TYPE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN)
@@ -128,6 +134,7 @@ gtk_alignment_class_init (GtkAlignmentClass *class)
widget_class->get_preferred_height = gtk_alignment_get_preferred_height;
widget_class->get_preferred_width_for_height = gtk_alignment_get_preferred_width_for_height;
widget_class->get_preferred_height_for_width = gtk_alignment_get_preferred_height_for_width;
+ widget_class->get_preferred_height_and_baseline_for_width = gtk_alignment_get_preferred_height_and_baseline_for_width;
g_object_class_install_property (gobject_class,
PROP_XALIGN,
@@ -507,6 +514,7 @@ gtk_alignment_size_allocate (GtkWidget *widget,
gint width, height;
guint border_width;
gint padding_horizontal, padding_vertical;
+ gint baseline;
padding_horizontal = 0;
padding_vertical = 0;
@@ -520,6 +528,7 @@ gtk_alignment_size_allocate (GtkWidget *widget,
gint child_nat_width;
gint child_nat_height;
gint child_width, child_height;
+ double yalign, yscale;
border_width = gtk_container_get_border_width (GTK_CONTAINER (alignment));
@@ -529,6 +538,25 @@ gtk_alignment_size_allocate (GtkWidget *widget,
width = MAX (1, allocation->width - padding_horizontal - 2 * border_width);
height = MAX (1, allocation->height - padding_vertical - 2 * border_width);
+ baseline = gtk_widget_get_allocated_baseline (widget);
+ if (baseline != -1)
+ baseline -= border_width + priv->padding_top;
+
+ /* If we get a baseline set that means we're baseline aligned, and the parent
+ honored that. In that case we have to ignore yalign/yscale as we need
+ yalign based on the baseline and always FILL mode to ensure we can place
+ the baseline anywhere */
+ if (baseline != -1)
+ {
+ yalign = 0;
+ yscale = 1.0;
+ }
+ else
+ {
+ yalign = priv->yalign;
+ yscale = priv->yscale;
+ }
+
if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
gtk_widget_get_preferred_width (child, NULL, &child_nat_width);
@@ -559,8 +587,8 @@ gtk_alignment_size_allocate (GtkWidget *widget,
if (height > child_height)
child_allocation.height = (child_height *
- (1.0 - priv->yscale) +
- height * priv->yscale);
+ (1.0 - yscale) +
+ height * yscale);
else
child_allocation.height = height;
@@ -569,9 +597,9 @@ gtk_alignment_size_allocate (GtkWidget *widget,
else
child_allocation.x = priv->xalign * (width - child_allocation.width) + allocation->x + border_width + priv->padding_left;
- child_allocation.y = priv->yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
+ child_allocation.y = yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
- gtk_widget_size_allocate (child, &child_allocation);
+ gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
}
}
@@ -581,18 +609,30 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
GtkOrientation orientation,
gint for_size,
gint *minimum_size,
- gint *natural_size)
+ gint *natural_size,
+ gint *minimum_baseline,
+ gint *natural_baseline)
{
GtkAlignment *alignment = GTK_ALIGNMENT (widget);
GtkAlignmentPrivate *priv = alignment->priv;
GtkWidget *child;
guint minimum, natural;
+ guint top_offset;
+ guint border;
- natural = minimum = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
+ if (minimum_baseline)
+ *minimum_baseline = -1;
+ if (natural_baseline)
+ *natural_baseline = -1;
+
+ border = gtk_container_get_border_width (GTK_CONTAINER (widget));
+ natural = minimum = border * 2;
+ top_offset = border;
if ((child = gtk_bin_get_child (GTK_BIN (widget))) && gtk_widget_get_visible (child))
{
gint child_min, child_nat;
+ gint child_min_baseline = -1, child_nat_baseline = -1;
/* Request extra space for the padding: */
if (orientation == GTK_ORIENTATION_HORIZONTAL)
@@ -619,9 +659,10 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
else
{
minimum += (priv->padding_top + priv->padding_bottom);
+ top_offset += priv->padding_top;
if (for_size < 0)
- gtk_widget_get_preferred_height (child, &child_min, &child_nat);
+ gtk_widget_get_preferred_height_and_baseline_for_width (child, -1, &child_min, &child_nat, &child_min_baseline, &child_nat_baseline);
else
{
gint min_width;
@@ -634,8 +675,13 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
for_size = (min_width * (1.0 - priv->xscale) +
for_size * priv->xscale);
- gtk_widget_get_preferred_height_for_width (child, for_size, &child_min, &child_nat);
+ gtk_widget_get_preferred_height_and_baseline_for_width (child, for_size, &child_min, &child_nat, &child_min_baseline, &child_nat_baseline);
}
+
+ if (minimum_baseline && child_min_baseline >= 0)
+ *minimum_baseline = child_min_baseline + top_offset;
+ if (natural_baseline && child_nat_baseline >= 0)
+ *natural_baseline = child_nat_baseline + top_offset;
}
natural = minimum;
@@ -656,7 +702,7 @@ gtk_alignment_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size);
+ gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -664,7 +710,7 @@ gtk_alignment_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size);
+ gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size, NULL, NULL);
}
@@ -674,7 +720,7 @@ gtk_alignment_get_preferred_width_for_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size);
+ gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -683,9 +729,21 @@ gtk_alignment_get_preferred_height_for_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size);
+ gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, NULL, NULL);
}
+static void
+gtk_alignment_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size,
+ gint *minimum_baseline,
+ gint *natural_baseline)
+{
+ gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, minimum_baseline, natural_baseline);
+}
+
+
/**
* gtk_alignment_set_padding:
* @alignment: a #GtkAlignment