Compare commits
7 Commits
doc-scale-
...
wip/baseli
Author | SHA1 | Date | |
---|---|---|---|
|
dba6649098 | ||
|
fe2062925c | ||
|
169ba01c2a | ||
|
3244628724 | ||
|
2954b45f54 | ||
|
d8a65ae304 | ||
|
854fedbb45 |
@@ -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
|
||||
|
350
gtk/gtkbox.c
350
gtk/gtkbox.c
@@ -94,7 +94,8 @@ enum {
|
||||
PROP_0,
|
||||
PROP_ORIENTATION,
|
||||
PROP_SPACING,
|
||||
PROP_HOMOGENEOUS
|
||||
PROP_HOMOGENEOUS,
|
||||
PROP_BASELINE_POSITION
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -116,6 +117,7 @@ struct _GtkBoxPrivate
|
||||
guint default_expand : 1;
|
||||
guint homogeneous : 1;
|
||||
guint spacing_set : 1;
|
||||
guint baseline_pos : 2;
|
||||
};
|
||||
|
||||
typedef struct _GtkBoxChild GtkBoxChild;
|
||||
@@ -200,6 +202,12 @@ static void gtk_box_get_preferred_height_for_width (GtkWidget
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkBox, gtk_box, GTK_TYPE_CONTAINER,
|
||||
@@ -220,6 +228,7 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
widget_class->get_preferred_width = gtk_box_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_box_get_preferred_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_box_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_box_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->get_preferred_width_for_height = gtk_box_get_preferred_width_for_height;
|
||||
widget_class->compute_expand = gtk_box_compute_expand;
|
||||
widget_class->direction_changed = gtk_box_direction_changed;
|
||||
@@ -255,6 +264,15 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_BASELINE_POSITION,
|
||||
g_param_spec_enum ("baseline-position",
|
||||
P_("Baseline position"),
|
||||
P_("The position of the baseline aligned widgets if extra space is availible"),
|
||||
GTK_TYPE_BASELINE_POSITION,
|
||||
GTK_BASELINE_POSITION_CENTER,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkBox:expand:
|
||||
*
|
||||
@@ -340,6 +358,7 @@ gtk_box_init (GtkBox *box)
|
||||
private->homogeneous = FALSE;
|
||||
private->spacing = 0;
|
||||
private->spacing_set = FALSE;
|
||||
private->baseline_pos = GTK_BASELINE_POSITION_CENTER;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -361,6 +380,9 @@ gtk_box_set_property (GObject *object,
|
||||
case PROP_SPACING:
|
||||
gtk_box_set_spacing (box, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_BASELINE_POSITION:
|
||||
gtk_box_set_baseline_position (box, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_HOMOGENEOUS:
|
||||
gtk_box_set_homogeneous (box, g_value_get_boolean (value));
|
||||
break;
|
||||
@@ -387,6 +409,9 @@ gtk_box_get_property (GObject *object,
|
||||
case PROP_SPACING:
|
||||
g_value_set_int (value, private->spacing);
|
||||
break;
|
||||
case PROP_BASELINE_POSITION:
|
||||
g_value_set_enum (value, private->baseline_pos);
|
||||
break;
|
||||
case PROP_HOMOGENEOUS:
|
||||
g_value_set_boolean (value, private->homogeneous);
|
||||
break;
|
||||
@@ -435,6 +460,11 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
GtkTextDirection direction;
|
||||
GtkAllocation child_allocation;
|
||||
GtkRequestedSize *sizes;
|
||||
gint child_minimum_baseline, child_natural_baseline;
|
||||
gint minimum_above, natural_above;
|
||||
gint minimum_below, natural_below;
|
||||
gboolean have_baseline;
|
||||
gint baseline;
|
||||
|
||||
GtkPackType packing;
|
||||
|
||||
@@ -461,6 +491,10 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
else
|
||||
size = allocation->height - (nvis_children - 1) * private->spacing;
|
||||
|
||||
have_baseline = FALSE;
|
||||
minimum_above = natural_above = 0;
|
||||
minimum_below = natural_below = 0;
|
||||
|
||||
/* Retrieve desired size for visible children. */
|
||||
for (i = 0, children = private->children; children; children = children->next)
|
||||
{
|
||||
@@ -475,11 +509,11 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size);
|
||||
else
|
||||
gtk_widget_get_preferred_height_for_width (child->widget,
|
||||
allocation->width,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size);
|
||||
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget,
|
||||
allocation->width,
|
||||
&sizes[i].minimum_size,
|
||||
&sizes[i].natural_size,
|
||||
NULL, NULL);
|
||||
|
||||
/* Assert the api is working properly */
|
||||
if (sizes[i].minimum_size < 0)
|
||||
@@ -537,28 +571,9 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
extra = 0;
|
||||
}
|
||||
|
||||
/* Allocate child positions. */
|
||||
/* Allocate child sizes. */
|
||||
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
|
||||
{
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
child_allocation.y = allocation->y;
|
||||
child_allocation.height = MAX (1, allocation->height);
|
||||
if (packing == GTK_PACK_START)
|
||||
x = allocation->x;
|
||||
else
|
||||
x = allocation->x + allocation->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_allocation.x = allocation->x;
|
||||
child_allocation.width = MAX (1, allocation->width);
|
||||
if (packing == GTK_PACK_START)
|
||||
y = allocation->y;
|
||||
else
|
||||
y = allocation->y + allocation->height;
|
||||
}
|
||||
|
||||
for (i = 0, children = private->children;
|
||||
children;
|
||||
children = children->next)
|
||||
@@ -605,6 +620,105 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
sizes[i].natural_size = child_size;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child->widget) == GTK_ALIGN_BASELINE)
|
||||
{
|
||||
int child_allocation_width;
|
||||
int child_minimum_height, child_natural_height;
|
||||
|
||||
if (child->fill)
|
||||
child_allocation_width = MAX (1, child_size - child->padding * 2);
|
||||
else
|
||||
child_allocation_width = sizes[i].minimum_size;
|
||||
|
||||
child_minimum_baseline = -1;
|
||||
child_natural_baseline = -1;
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget,
|
||||
child_allocation_width,
|
||||
&child_minimum_height, &child_natural_height,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
minimum_below = MAX (minimum_below, child_minimum_height - child_minimum_baseline);
|
||||
natural_below = MAX (natural_below, child_natural_height - child_natural_baseline);
|
||||
minimum_above = MAX (minimum_above, child_minimum_baseline);
|
||||
natural_above = MAX (natural_above, child_natural_baseline);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline == -1 && have_baseline)
|
||||
{
|
||||
gint height = MAX (1, allocation->height);
|
||||
|
||||
/* TODO: This is purely based on the minimum baseline, when things fit we should
|
||||
use the natural one? */
|
||||
|
||||
switch (private->baseline_pos)
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
baseline = minimum_above;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
baseline = minimum_above + (height - (minimum_above + minimum_below)) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
baseline = height - minimum_below;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate child positions. */
|
||||
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
|
||||
{
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
child_allocation.y = allocation->y;
|
||||
child_allocation.height = MAX (1, allocation->height);
|
||||
if (packing == GTK_PACK_START)
|
||||
x = allocation->x;
|
||||
else
|
||||
x = allocation->x + allocation->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_allocation.x = allocation->x;
|
||||
child_allocation.width = MAX (1, allocation->width);
|
||||
if (packing == GTK_PACK_START)
|
||||
y = allocation->y;
|
||||
else
|
||||
y = allocation->y + allocation->height;
|
||||
}
|
||||
|
||||
for (i = 0, children = private->children;
|
||||
children;
|
||||
children = children->next)
|
||||
{
|
||||
child = children->data;
|
||||
|
||||
/* If widget is not visible, skip it. */
|
||||
if (!gtk_widget_get_visible (child->widget))
|
||||
continue;
|
||||
|
||||
/* If widget is packed differently skip it, but still increment i,
|
||||
* since widget is visible and will be handled in next loop iteration.
|
||||
*/
|
||||
if (child->pack != packing)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
child_size = sizes[i].natural_size;
|
||||
|
||||
/* Assign the child's position. */
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
@@ -658,7 +772,7 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
child_allocation.y -= child_size;
|
||||
}
|
||||
}
|
||||
gtk_widget_size_allocate (child->widget, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child->widget, &child_allocation, baseline);
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -1015,18 +1129,28 @@ static void
|
||||
gtk_box_get_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBox *box;
|
||||
GtkBoxPrivate *private;
|
||||
GList *children;
|
||||
gint nvis_children;
|
||||
gint minimum, natural;
|
||||
gint minimum_above, natural_above;
|
||||
gint minimum_below, natural_below;
|
||||
gboolean have_baseline;
|
||||
gint min_baseline, nat_baseline;
|
||||
|
||||
box = GTK_BOX (widget);
|
||||
private = box->priv;
|
||||
|
||||
have_baseline = FALSE;
|
||||
minimum = natural = 0;
|
||||
minimum_above = natural_above = 0;
|
||||
minimum_below = natural_below = 0;
|
||||
min_baseline = nat_baseline = -1;
|
||||
|
||||
nvis_children = 0;
|
||||
|
||||
@@ -1037,13 +1161,15 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
if (gtk_widget_get_visible (child->widget))
|
||||
{
|
||||
gint child_minimum, child_natural;
|
||||
gint child_minimum_baseline = -1, child_natural_baseline = -1;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_widget_get_preferred_width (child->widget,
|
||||
&child_minimum, &child_natural);
|
||||
else
|
||||
gtk_widget_get_preferred_height (child->widget,
|
||||
&child_minimum, &child_natural);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget, -1,
|
||||
&child_minimum, &child_natural,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
|
||||
if (private->orientation == orientation)
|
||||
{
|
||||
@@ -1065,9 +1191,20 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The biggest mins and naturals in the opposing orientation */
|
||||
minimum = MAX (minimum, child_minimum);
|
||||
natural = MAX (natural, child_natural);
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
minimum_below = MAX (minimum_below, child_minimum - child_minimum_baseline);
|
||||
natural_below = MAX (natural_below, child_natural - child_natural_baseline);
|
||||
minimum_above = MAX (minimum_above, child_minimum_baseline);
|
||||
natural_above = MAX (natural_above, child_natural_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The biggest mins and naturals in the opposing orientation */
|
||||
minimum = MAX (minimum, child_minimum);
|
||||
natural = MAX (natural, child_natural);
|
||||
}
|
||||
}
|
||||
|
||||
nvis_children += 1;
|
||||
@@ -1085,11 +1222,23 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
natural += (nvis_children - 1) * private->spacing;
|
||||
}
|
||||
|
||||
if (have_baseline)
|
||||
{
|
||||
min_baseline = minimum_above;
|
||||
nat_baseline = natural_above;
|
||||
}
|
||||
|
||||
if (minimum_size)
|
||||
*minimum_size = minimum;
|
||||
*minimum_size = MAX (minimum, minimum_below + minimum_above);
|
||||
|
||||
if (natural_size)
|
||||
*natural_size = natural;
|
||||
*natural_size = MAX (natural, natural_below + natural_above);
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = min_baseline;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = nat_baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1097,7 +1246,7 @@ gtk_box_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1105,14 +1254,16 @@ gtk_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
gint avail_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
GtkBoxChild *child;
|
||||
@@ -1120,11 +1271,16 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
gint nvis_children;
|
||||
gint nexpand_children;
|
||||
gint computed_minimum = 0, computed_natural = 0;
|
||||
gint computed_minimum_above = 0, computed_natural_above = 0;
|
||||
gint computed_minimum_below = 0, computed_natural_below = 0;
|
||||
gint computed_minimum_baseline = -1, computed_natural_baseline = -1;
|
||||
GtkRequestedSize *sizes;
|
||||
GtkPackType packing;
|
||||
gint size, extra, i;
|
||||
gint child_size, child_minimum, child_natural;
|
||||
gint child_minimum_baseline, child_natural_baseline;
|
||||
gint n_extra_widgets = 0;
|
||||
gboolean have_baseline;
|
||||
|
||||
count_expand_children (box, &nvis_children, &nexpand_children);
|
||||
|
||||
@@ -1199,6 +1355,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
extra = 0;
|
||||
}
|
||||
|
||||
have_baseline = FALSE;
|
||||
/* Allocate child positions. */
|
||||
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
|
||||
{
|
||||
@@ -1260,26 +1417,64 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
}
|
||||
|
||||
|
||||
child_minimum_baseline = child_natural_baseline = -1;
|
||||
/* Assign the child's position. */
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_widget_get_preferred_height_for_width (child->widget,
|
||||
child_size, &child_minimum, &child_natural);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget, child_size,
|
||||
&child_minimum, &child_natural,
|
||||
&child_minimum_baseline, &child_natural_baseline);
|
||||
else /* (private->orientation == GTK_ORIENTATION_VERTICAL) */
|
||||
gtk_widget_get_preferred_width_for_height (child->widget,
|
||||
child_size, &child_minimum, &child_natural);
|
||||
|
||||
|
||||
computed_minimum = MAX (computed_minimum, child_minimum);
|
||||
computed_natural = MAX (computed_natural, child_natural);
|
||||
if (child_minimum_baseline >= 0)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
|
||||
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
|
||||
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
|
||||
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_minimum = MAX (computed_minimum, child_minimum);
|
||||
computed_natural = MAX (computed_natural, child_natural);
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_baseline)
|
||||
{
|
||||
computed_minimum = MAX (computed_minimum, computed_minimum_below + computed_minimum_above);
|
||||
computed_natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
|
||||
switch (private->baseline_pos)
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
computed_minimum_baseline = computed_minimum_above;
|
||||
computed_natural_baseline = computed_natural_above;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
computed_minimum_baseline = computed_minimum_above + MAX((computed_minimum - (computed_minimum_above + computed_minimum_below)) / 2, 0);
|
||||
computed_natural_baseline = computed_natural_above + MAX((computed_natural - (computed_natural_above + computed_natural_below)) / 2, 0);
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
computed_minimum_baseline = computed_minimum - computed_minimum_below;
|
||||
computed_natural_baseline = computed_natural - computed_natural_below;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = computed_minimum_baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = computed_natural_baseline;
|
||||
|
||||
if (minimum_size)
|
||||
*minimum_size = computed_minimum;
|
||||
if (natural_size)
|
||||
*natural_size = computed_natural;
|
||||
*natural_size = MAX (computed_natural, computed_natural_below + computed_natural_above);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1355,24 +1550,46 @@ gtk_box_get_preferred_width_for_height (GtkWidget *widget,
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_VERTICAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width);
|
||||
gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width, NULL, NULL);
|
||||
else
|
||||
gtk_box_compute_size_for_orientation (box, height, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (width < 0)
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
else
|
||||
{
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
else
|
||||
{
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
gtk_box_compute_size_for_orientation (box, width, minimum_height, natural_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height);
|
||||
else
|
||||
gtk_box_compute_size_for_orientation (box, width, minimum_height, natural_height);
|
||||
gtk_box_get_preferred_height_and_baseline_for_width (widget, width, minimum_height, natural_height, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1550,6 +1767,35 @@ gtk_box_get_spacing (GtkBox *box)
|
||||
return box->priv->spacing;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_box_set_baseline_position (GtkBox *box,
|
||||
GtkBaselinePosition position)
|
||||
{
|
||||
GtkBoxPrivate *private;
|
||||
|
||||
g_return_if_fail (GTK_IS_BOX (box));
|
||||
|
||||
private = box->priv;
|
||||
|
||||
if (position != private->baseline_pos)
|
||||
{
|
||||
private->baseline_pos = position;
|
||||
|
||||
g_object_notify (G_OBJECT (box), "baseline-position");
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (box));
|
||||
}
|
||||
}
|
||||
|
||||
GtkBaselinePosition
|
||||
gtk_box_get_baseline_position (GtkBox *box)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_BOX (box), GTK_BASELINE_POSITION_CENTER);
|
||||
|
||||
return box->priv->baseline_pos;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gtk_box_set_spacing_set (GtkBox *box,
|
||||
gboolean spacing_set)
|
||||
|
@@ -89,6 +89,9 @@ gboolean gtk_box_get_homogeneous (GtkBox *box);
|
||||
void gtk_box_set_spacing (GtkBox *box,
|
||||
gint spacing);
|
||||
gint gtk_box_get_spacing (GtkBox *box);
|
||||
void gtk_box_set_baseline_position (GtkBox *box,
|
||||
GtkBaselinePosition position);
|
||||
GtkBaselinePosition gtk_box_get_baseline_position (GtkBox *box);
|
||||
|
||||
void gtk_box_reorder_child (GtkBox *box,
|
||||
GtkWidget *child,
|
||||
|
@@ -170,6 +170,12 @@ static void gtk_button_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static guint button_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@@ -196,6 +202,7 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
|
||||
widget_class->get_preferred_width = gtk_button_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_button_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_button_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->destroy = gtk_button_destroy;
|
||||
widget_class->screen_changed = gtk_button_screen_changed;
|
||||
widget_class->realize = gtk_button_realize;
|
||||
@@ -1150,11 +1157,15 @@ gtk_button_construct_child (GtkButton *button)
|
||||
else
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, image_spacing);
|
||||
|
||||
gtk_widget_set_valign (box, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->align_set)
|
||||
align = gtk_alignment_new (priv->xalign, priv->yalign, 0.0, 0.0);
|
||||
else
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
|
||||
gtk_widget_set_valign (align, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->image_position == GTK_POS_LEFT ||
|
||||
priv->image_position == GTK_POS_TOP)
|
||||
gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0);
|
||||
@@ -1172,6 +1183,8 @@ gtk_button_construct_child (GtkButton *button)
|
||||
else
|
||||
label = gtk_label_new (label_text);
|
||||
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->image_position == GTK_POS_RIGHT ||
|
||||
priv->image_position == GTK_POS_BOTTOM)
|
||||
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
||||
@@ -1196,6 +1209,8 @@ gtk_button_construct_child (GtkButton *button)
|
||||
else
|
||||
label = gtk_label_new (priv->label_text);
|
||||
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
|
||||
if (priv->align_set)
|
||||
gtk_misc_set_alignment (GTK_MISC (label), priv->xalign, priv->yalign);
|
||||
|
||||
@@ -1584,6 +1599,7 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
GtkBorder border;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint baseline;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
@@ -1651,7 +1667,10 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
child_allocation.width = MAX (1, child_allocation.width);
|
||||
child_allocation.height = MAX (1, child_allocation.height);
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline != -1)
|
||||
baseline -= child_allocation.y - allocation->y;
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2063,7 +2082,9 @@ static void
|
||||
gtk_button_get_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (widget);
|
||||
GtkStyleContext *context;
|
||||
@@ -2074,6 +2095,7 @@ gtk_button_get_size (GtkWidget *widget,
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint minimum, natural;
|
||||
gint top_offset;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
@@ -2084,6 +2106,8 @@ gtk_button_get_size (GtkWidget *widget,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
top_offset = 0;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
minimum = padding.left + padding.right +
|
||||
@@ -2097,9 +2121,14 @@ gtk_button_get_size (GtkWidget *widget,
|
||||
minimum = padding.top + padding.bottom +
|
||||
border.top + border.bottom;
|
||||
|
||||
top_offset = padding.top + border.top + focus_width + focus_pad;
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (widget)))
|
||||
minimum += default_border.top + default_border.bottom;
|
||||
}
|
||||
{
|
||||
minimum += default_border.top + default_border.bottom;
|
||||
top_offset += default_border.top;
|
||||
}
|
||||
}
|
||||
|
||||
minimum += 2 * (focus_width + focus_pad);
|
||||
natural = minimum;
|
||||
@@ -2108,11 +2137,17 @@ gtk_button_get_size (GtkWidget *widget,
|
||||
gtk_widget_get_visible (child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
gint child_min_baseline = -1, child_nat_baseline = -1;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_widget_get_preferred_width (child, &child_min, &child_nat);
|
||||
else
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
@@ -2130,7 +2165,7 @@ gtk_button_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2138,7 +2173,20 @@ gtk_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
/* GtkButton is GTK_SIZE_REQUEST_CONSTANT mode, so width will be -1 all the time */
|
||||
g_assert (width == -1);
|
||||
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -309,12 +309,17 @@ static void gtk_container_adjust_size_request (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_container_adjust_baseline_request (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *allocated_pos,
|
||||
gint *allocated_size);
|
||||
static void gtk_container_adjust_baseline_allocation (GtkWidget *widget,
|
||||
gint *baseline);
|
||||
static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
|
||||
|
||||
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
|
||||
@@ -444,7 +449,9 @@ gtk_container_class_init (GtkContainerClass *class)
|
||||
widget_class->focus = gtk_container_focus;
|
||||
|
||||
widget_class->adjust_size_request = gtk_container_adjust_size_request;
|
||||
widget_class->adjust_baseline_request = gtk_container_adjust_baseline_request;
|
||||
widget_class->adjust_size_allocation = gtk_container_adjust_size_allocation;
|
||||
widget_class->adjust_baseline_allocation = gtk_container_adjust_baseline_allocation;
|
||||
widget_class->get_request_mode = gtk_container_get_request_mode;
|
||||
|
||||
class->add = gtk_container_add_unimplemented;
|
||||
@@ -1917,6 +1924,28 @@ gtk_container_adjust_size_request (GtkWidget *widget,
|
||||
minimum_size, natural_size);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_baseline_request (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkContainer *container;
|
||||
|
||||
container = GTK_CONTAINER (widget);
|
||||
|
||||
if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
|
||||
{
|
||||
int border_width;
|
||||
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
*minimum_baseline += border_width;
|
||||
*natural_baseline += border_width;
|
||||
}
|
||||
|
||||
parent_class->adjust_baseline_request (widget, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@@ -1952,6 +1981,27 @@ gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
allocated_size);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_baseline_allocation (GtkWidget *widget,
|
||||
gint *baseline)
|
||||
{
|
||||
GtkContainer *container;
|
||||
int border_width;
|
||||
|
||||
container = GTK_CONTAINER (widget);
|
||||
|
||||
if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
|
||||
{
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
if (*baseline >= 0)
|
||||
*baseline -= border_width;
|
||||
}
|
||||
|
||||
parent_class->adjust_baseline_allocation (widget, baseline);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
gint hfw;
|
||||
gint wfh;
|
||||
|
@@ -70,7 +70,8 @@ typedef enum
|
||||
GTK_ALIGN_FILL,
|
||||
GTK_ALIGN_START,
|
||||
GTK_ALIGN_END,
|
||||
GTK_ALIGN_CENTER
|
||||
GTK_ALIGN_CENTER,
|
||||
GTK_ALIGN_BASELINE
|
||||
} GtkAlign;
|
||||
|
||||
|
||||
@@ -125,6 +126,20 @@ typedef enum
|
||||
GTK_FILL = 1 << 2
|
||||
} GtkAttachOptions;
|
||||
|
||||
/**
|
||||
* GtkBaselinePosition:
|
||||
* @GTK_BASELINE_POSITION_TOP:
|
||||
* @GTK_BASELINE_POSITION_CENTER:
|
||||
* @GTK_BASELINE_POSITION_BOTTOM:
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_BASELINE_POSITION_TOP,
|
||||
GTK_BASELINE_POSITION_CENTER,
|
||||
GTK_BASELINE_POSITION_BOTTOM
|
||||
} GtkBaselinePosition;
|
||||
|
||||
/**
|
||||
* GtkButtonBoxStyle:
|
||||
* @GTK_BUTTONBOX_DEFAULT_STYLE: Default packing.
|
||||
|
108
gtk/gtklabel.c
108
gtk/gtklabel.c
@@ -519,6 +519,12 @@ static void gtk_label_get_preferred_height_for_width (GtkWidget
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static GtkBuildableIface *buildable_parent_iface = NULL;
|
||||
|
||||
@@ -585,6 +591,7 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
widget_class->get_preferred_height = gtk_label_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_label_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_label_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_label_get_preferred_height_and_baseline_for_width;
|
||||
|
||||
class->move_cursor = gtk_label_move_cursor;
|
||||
class->copy_clipboard = gtk_label_copy_clipboard;
|
||||
@@ -3434,15 +3441,18 @@ gtk_label_get_request_mode (GtkWidget *widget)
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_size_for_allocation (GtkLabel *label,
|
||||
GtkOrientation orientation,
|
||||
gint allocation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
gint text_height;
|
||||
gint text_height, baseline;
|
||||
|
||||
layout = gtk_label_get_measuring_layout (label, NULL, allocation * PANGO_SCALE);
|
||||
|
||||
@@ -3454,6 +3464,16 @@ get_size_for_allocation (GtkLabel *label,
|
||||
if (natural_size)
|
||||
*natural_size = text_height;
|
||||
|
||||
if (minimum_baseline || natural_baseline)
|
||||
{
|
||||
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = baseline;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = baseline;
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
@@ -3550,7 +3570,9 @@ static void
|
||||
gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
@@ -3558,6 +3580,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
PangoRectangle smallest_rect;
|
||||
GtkBorder border;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
gtk_label_get_preferred_layout_size (label, &smallest_rect, &widest_rect);
|
||||
|
||||
/* Now that we have minimum and natural sizes in pango extents, apply a possible transform */
|
||||
@@ -3612,7 +3640,8 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
smallest_rect.height,
|
||||
minimum_size, natural_size);
|
||||
minimum_size, natural_size,
|
||||
NULL, NULL);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -3639,7 +3668,16 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
widest_rect.width,
|
||||
minimum_size, natural_size);
|
||||
minimum_size, natural_size,
|
||||
minimum_baseline, natural_baseline);
|
||||
|
||||
if (priv->angle == 180)
|
||||
{
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = *minimum_size - *minimum_baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = *natural_size - *natural_baseline;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3652,6 +3690,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
|
||||
*minimum_size += border.top + border.bottom;
|
||||
*natural_size += border.top + border.bottom;
|
||||
|
||||
if (minimum_baseline && *minimum_baseline != -1)
|
||||
*minimum_baseline += border.top;
|
||||
|
||||
if (natural_baseline && *natural_baseline != -1)
|
||||
*natural_baseline += border.top;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3660,7 +3704,7 @@ gtk_label_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3668,7 +3712,7 @@ gtk_label_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3691,7 +3735,8 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
|
||||
|
||||
get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL,
|
||||
MAX (1, height - border.top - border.bottom),
|
||||
minimum_width, natural_width);
|
||||
minimum_width, natural_width,
|
||||
NULL, NULL);
|
||||
|
||||
if (minimum_width)
|
||||
*minimum_width += border.right + border.left;
|
||||
@@ -3704,15 +3749,17 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
|
||||
if (priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
|
||||
if (width != -1 && priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
|
||||
{
|
||||
GtkBorder border;
|
||||
|
||||
@@ -3723,7 +3770,13 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
|
||||
get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL,
|
||||
MAX (1, width - border.left - border.right),
|
||||
minimum_height, natural_height);
|
||||
minimum_height, natural_height,
|
||||
minimum_baseline, natural_baseline);
|
||||
|
||||
if (minimum_baseline && *minimum_baseline >= 0)
|
||||
*minimum_baseline += border.top;
|
||||
if (natural_baseline && *natural_baseline >= 0)
|
||||
*natural_baseline += border.top;
|
||||
|
||||
if (minimum_height)
|
||||
*minimum_height += border.top + border.bottom;
|
||||
@@ -3732,7 +3785,18 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
*natural_height += border.top + border.bottom;
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
|
||||
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
return gtk_label_get_preferred_height_and_baseline_for_width (widget, width,
|
||||
minimum_height, natural_height,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3827,6 +3891,7 @@ get_layout_location (GtkLabel *label,
|
||||
gint req_height;
|
||||
gfloat xalign, yalign;
|
||||
PangoRectangle logical;
|
||||
gint baseline, layout_baseline, baseline_offset;
|
||||
|
||||
misc = GTK_MISC (label);
|
||||
widget = GTK_WIDGET (label);
|
||||
@@ -3859,6 +3924,15 @@ get_layout_location (GtkLabel *label,
|
||||
|
||||
x = floor (allocation.x + border.left + xalign * (allocation.width - req_width) - logical.x);
|
||||
|
||||
baseline_offset = 0;
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline >= 0 && !priv->have_transform)
|
||||
{
|
||||
layout_baseline = pango_layout_get_baseline (priv->layout) / PANGO_SCALE;
|
||||
baseline_offset = baseline - layout_baseline;
|
||||
yalign = 0.0; /* Can't support yalign while baseline aligning */
|
||||
}
|
||||
|
||||
/* bgo#315462 - For single-line labels, *do* align the requisition with
|
||||
* respect to the allocation, even if we are under-allocated. For multi-line
|
||||
* labels, always show the top of the text when they are under-allocated. The
|
||||
@@ -3873,9 +3947,9 @@ get_layout_location (GtkLabel *label,
|
||||
* middle". You want to read the first line, at least, to get some context.
|
||||
*/
|
||||
if (pango_layout_get_line_count (priv->layout) == 1)
|
||||
y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y;
|
||||
y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y + baseline_offset;
|
||||
else
|
||||
y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y;
|
||||
y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y + baseline_offset;
|
||||
|
||||
if (xp)
|
||||
*xp = x;
|
||||
|
@@ -98,11 +98,16 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
SizeRequestCache *cache;
|
||||
GtkWidgetClass *widget_class;
|
||||
gint min_size = 0;
|
||||
gint nat_size = 0;
|
||||
gint min_baseline = -1;
|
||||
gint nat_baseline = -1;
|
||||
gboolean found_in_cache;
|
||||
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
@@ -113,7 +118,11 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
orientation,
|
||||
for_size,
|
||||
&min_size,
|
||||
&nat_size);
|
||||
&nat_size,
|
||||
&min_baseline,
|
||||
&nat_baseline);
|
||||
|
||||
widget_class = GTK_WIDGET_GET_CLASS (widget);
|
||||
|
||||
if (!found_in_cache)
|
||||
{
|
||||
@@ -126,7 +135,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
if (for_size < 0)
|
||||
{
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_size, &nat_size);
|
||||
widget_class->get_preferred_width (widget, &min_size, &nat_size);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
else
|
||||
@@ -140,17 +149,17 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
gtk_widget_get_preferred_height (widget, &minimum_height, &natural_height);
|
||||
|
||||
/* convert for_size to unadjusted height (for_size is a proposed allocation) */
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
&minimum_height,
|
||||
&natural_height,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
widget_class->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
&minimum_height,
|
||||
&natural_height,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width_for_height (widget,
|
||||
MAX (adjusted_for_size, minimum_height),
|
||||
&min_size, &nat_size);
|
||||
widget_class->get_preferred_width_for_height (widget,
|
||||
MAX (adjusted_for_size, minimum_height),
|
||||
&min_size, &nat_size);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
}
|
||||
@@ -159,7 +168,9 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
if (for_size < 0)
|
||||
{
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_size, &nat_size);
|
||||
widget_class->get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
&min_size, &nat_size,
|
||||
&min_baseline, &nat_baseline);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
else
|
||||
@@ -173,17 +184,17 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
gtk_widget_get_preferred_width (widget, &minimum_width, &natural_width);
|
||||
|
||||
/* convert for_size to unadjusted width (for_size is a proposed allocation) */
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
&minimum_width,
|
||||
&natural_width,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
widget_class->adjust_size_allocation (widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
&minimum_width,
|
||||
&natural_width,
|
||||
&ignored_position,
|
||||
&adjusted_for_size);
|
||||
|
||||
push_recursion_check (widget, orientation, for_size);
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget,
|
||||
MAX (adjusted_for_size, minimum_width),
|
||||
&min_size, &nat_size);
|
||||
widget_class->get_preferred_height_and_baseline_for_width (widget, MAX (adjusted_for_size, minimum_width),
|
||||
&min_size, &nat_size,
|
||||
&min_baseline, &nat_baseline);
|
||||
pop_recursion_check (widget, orientation);
|
||||
}
|
||||
}
|
||||
@@ -196,10 +207,10 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
|
||||
adjusted_min = min_size;
|
||||
adjusted_natural = nat_size;
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_request (widget,
|
||||
orientation,
|
||||
&adjusted_min,
|
||||
&adjusted_natural);
|
||||
widget_class->adjust_size_request (widget,
|
||||
orientation,
|
||||
&adjusted_min,
|
||||
&adjusted_natural);
|
||||
|
||||
if (adjusted_min < min_size ||
|
||||
adjusted_natural < nat_size)
|
||||
@@ -227,11 +238,42 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
nat_size = adjusted_natural;
|
||||
}
|
||||
|
||||
if (min_baseline != -1 || nat_baseline != -1)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
g_warning ("%s %p reported a horizontal baseline",
|
||||
G_OBJECT_TYPE_NAME (widget), widget);
|
||||
min_baseline = -1;
|
||||
nat_baseline = -1;
|
||||
}
|
||||
else if (min_baseline == -1 || nat_baseline == -1)
|
||||
{
|
||||
g_warning ("%s %p reported baseline for only one of min/natural (min: %d, natural: %d)",
|
||||
G_OBJECT_TYPE_NAME (widget), widget,
|
||||
min_baseline, nat_baseline);
|
||||
min_baseline = -1;
|
||||
nat_baseline = -1;
|
||||
}
|
||||
else if (gtk_widget_get_valign_with_baseline (widget) != GTK_ALIGN_BASELINE)
|
||||
{
|
||||
/* Ignore requested baseline for non-aligned widgets */
|
||||
min_baseline = -1;
|
||||
nat_baseline = -1;
|
||||
}
|
||||
else
|
||||
widget_class->adjust_baseline_request (widget,
|
||||
&min_baseline,
|
||||
&nat_baseline);
|
||||
}
|
||||
|
||||
_gtk_size_request_cache_commit (cache,
|
||||
orientation,
|
||||
for_size,
|
||||
min_size,
|
||||
nat_size);
|
||||
nat_size,
|
||||
min_baseline,
|
||||
nat_baseline);
|
||||
}
|
||||
|
||||
if (minimum_size)
|
||||
@@ -240,15 +282,26 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
if (natural_size)
|
||||
*natural_size = nat_size;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = min_baseline;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = nat_baseline;
|
||||
|
||||
g_assert (min_size <= nat_size);
|
||||
|
||||
GTK_NOTE (SIZE_REQUEST,
|
||||
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d (hit cache: %s)\n",
|
||||
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d",
|
||||
widget, G_OBJECT_TYPE_NAME (widget),
|
||||
orientation == GTK_ORIENTATION_HORIZONTAL ?
|
||||
"width for height" : "height for width" ,
|
||||
for_size, min_size, nat_size,
|
||||
found_in_cache ? "yes" : "no"));
|
||||
for_size, min_size, nat_size);
|
||||
if (min_baseline != -1 || nat_baseline != -1)
|
||||
g_print (", baseline %d/%d",
|
||||
min_baseline, nat_baseline);
|
||||
g_print (" (hit cache: %s)\n",
|
||||
found_in_cache ? "yes" : "no")
|
||||
);
|
||||
}
|
||||
|
||||
/* This is the main function that checks for a cached size and
|
||||
@@ -261,7 +314,9 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GHashTable *widgets;
|
||||
GHashTableIter iter;
|
||||
@@ -274,12 +329,17 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
*minimum = 0;
|
||||
if (natural)
|
||||
*natural = 0;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_LIKELY (!_gtk_widget_get_sizegroups (widget)))
|
||||
{
|
||||
gtk_widget_query_size_for_orientation (widget, orientation, for_size, minimum, natural);
|
||||
gtk_widget_query_size_for_orientation (widget, orientation, for_size, minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -293,7 +353,7 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkWidget *tmp_widget = key;
|
||||
gint min_dimension, nat_dimension;
|
||||
|
||||
gtk_widget_query_size_for_orientation (tmp_widget, orientation, for_size, &min_dimension, &nat_dimension);
|
||||
gtk_widget_query_size_for_orientation (tmp_widget, orientation, for_size, &min_dimension, &nat_dimension, NULL, NULL);
|
||||
|
||||
min_result = MAX (min_result, min_dimension);
|
||||
nat_result = MAX (nat_result, nat_dimension);
|
||||
@@ -303,6 +363,13 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
|
||||
g_hash_table_destroy (widgets);
|
||||
|
||||
/* Baselines make no sense with sizegroups really */
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
if (minimum)
|
||||
*minimum = min_result;
|
||||
|
||||
@@ -375,7 +442,8 @@ gtk_widget_get_preferred_width (GtkWidget *widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum_width,
|
||||
natural_width);
|
||||
natural_width,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -409,7 +477,8 @@ gtk_widget_get_preferred_height (GtkWidget *widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum_height,
|
||||
natural_height);
|
||||
natural_height,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -446,7 +515,8 @@ gtk_widget_get_preferred_width_for_height (GtkWidget *widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
height,
|
||||
minimum_width,
|
||||
natural_width);
|
||||
natural_width,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,7 +551,29 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum_height,
|
||||
natural_height);
|
||||
natural_height,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
|
||||
g_return_if_fail (width >= -1);
|
||||
|
||||
_gtk_widget_compute_size_for_orientation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum_height,
|
||||
natural_height,
|
||||
minimum_baseline,
|
||||
natural_baseline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -67,7 +67,9 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint minimum_size,
|
||||
gint natural_size)
|
||||
gint natural_size,
|
||||
gint minimum_baseline,
|
||||
gint natural_baseline)
|
||||
{
|
||||
SizeRequest **cached_sizes;
|
||||
SizeRequest *cached_size;
|
||||
@@ -78,6 +80,8 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
||||
{
|
||||
cache->cached_size[orientation].minimum_size = minimum_size;
|
||||
cache->cached_size[orientation].natural_size = natural_size;
|
||||
cache->cached_size[orientation].minimum_baseline = minimum_baseline;
|
||||
cache->cached_size[orientation].natural_baseline = natural_baseline;
|
||||
cache->flags[orientation].cached_size_valid = TRUE;
|
||||
return;
|
||||
}
|
||||
@@ -92,7 +96,9 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
||||
for (i = 0; i < n_sizes; i++)
|
||||
{
|
||||
if (cached_sizes[i]->cached_size.minimum_size == minimum_size &&
|
||||
cached_sizes[i]->cached_size.natural_size == natural_size)
|
||||
cached_sizes[i]->cached_size.natural_size == natural_size &&
|
||||
cached_sizes[i]->cached_size.minimum_baseline == minimum_baseline &&
|
||||
cached_sizes[i]->cached_size.natural_baseline == natural_baseline)
|
||||
{
|
||||
cached_sizes[i]->lower_for_size = MIN (cached_sizes[i]->lower_for_size, for_size);
|
||||
cached_sizes[i]->upper_for_size = MAX (cached_sizes[i]->upper_for_size, for_size);
|
||||
@@ -125,6 +131,8 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
||||
cached_size->upper_for_size = for_size;
|
||||
cached_size->cached_size.minimum_size = minimum_size;
|
||||
cached_size->cached_size.natural_size = natural_size;
|
||||
cached_size->cached_size.minimum_baseline = minimum_baseline;
|
||||
cached_size->cached_size.natural_baseline = natural_baseline;
|
||||
}
|
||||
|
||||
/* looks for a cached size request for this for_size.
|
||||
@@ -137,7 +145,9 @@ _gtk_size_request_cache_lookup (SizeRequestCache *cache,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
CachedSize *result = NULL;
|
||||
|
||||
@@ -168,6 +178,8 @@ _gtk_size_request_cache_lookup (SizeRequestCache *cache,
|
||||
{
|
||||
*minimum = result->minimum_size;
|
||||
*natural = result->natural_size;
|
||||
*minimum_baseline = result->minimum_baseline;
|
||||
*natural_baseline = result->natural_baseline;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
|
@@ -41,6 +41,8 @@ G_BEGIN_DECLS
|
||||
typedef struct {
|
||||
gint minimum_size;
|
||||
gint natural_size;
|
||||
gint minimum_baseline;
|
||||
gint natural_baseline;
|
||||
} CachedSize;
|
||||
|
||||
typedef struct
|
||||
@@ -72,12 +74,16 @@ void _gtk_size_request_cache_commit (SizeRequestCach
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint minimum_size,
|
||||
gint natural_size);
|
||||
gint natural_size,
|
||||
gint minimum_baseline,
|
||||
gint natural_baseline);
|
||||
gboolean _gtk_size_request_cache_lookup (SizeRequestCache *cache,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
156
gtk/gtkwidget.c
156
gtk/gtkwidget.c
@@ -392,6 +392,7 @@ struct _GtkWidgetPrivate
|
||||
|
||||
/* The widget's allocated size */
|
||||
GtkAllocation allocation;
|
||||
gint allocated_baseline;
|
||||
|
||||
/* The widget's requested sizes */
|
||||
SizeRequestCache requests;
|
||||
@@ -686,6 +687,12 @@ static void gtk_widget_real_get_width (GtkWidget
|
||||
static void gtk_widget_real_get_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_widget_real_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static void gtk_widget_queue_tooltip_query (GtkWidget *widget);
|
||||
|
||||
@@ -694,12 +701,17 @@ static void gtk_widget_real_adjust_size_request (GtkWidget
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_widget_real_adjust_baseline_request (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint *minimum_size,
|
||||
gint *natural_size,
|
||||
gint *allocated_pos,
|
||||
gint *allocated_size);
|
||||
static void gtk_widget_real_adjust_baseline_allocation (GtkWidget *widget,
|
||||
gint *baseline);
|
||||
|
||||
static void gtk_widget_set_usize_internal (GtkWidget *widget,
|
||||
gint width,
|
||||
@@ -981,6 +993,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
klass->get_preferred_height = gtk_widget_real_get_height;
|
||||
klass->get_preferred_width_for_height = gtk_widget_real_get_width_for_height;
|
||||
klass->get_preferred_height_for_width = gtk_widget_real_get_height_for_width;
|
||||
klass->get_preferred_height_and_baseline_for_width = gtk_widget_real_get_preferred_height_and_baseline_for_width;
|
||||
klass->state_changed = NULL;
|
||||
klass->state_flags_changed = gtk_widget_real_state_flags_changed;
|
||||
klass->parent_set = NULL;
|
||||
@@ -1040,7 +1053,9 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
klass->get_accessible = gtk_widget_real_get_accessible;
|
||||
|
||||
klass->adjust_size_request = gtk_widget_real_adjust_size_request;
|
||||
klass->adjust_baseline_request = gtk_widget_real_adjust_baseline_request;
|
||||
klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
|
||||
klass->adjust_baseline_allocation = gtk_widget_real_adjust_baseline_allocation;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_NAME,
|
||||
@@ -5185,23 +5200,10 @@ gtk_widget_invalidate_widget_windows (GtkWidget *widget,
|
||||
invalidate_predicate, widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_size_allocate:
|
||||
* @widget: a #GtkWidget
|
||||
* @allocation: position and size to be allocated to @widget
|
||||
*
|
||||
* This function is only used by #GtkContainer subclasses, to assign a size
|
||||
* and position to their child widgets.
|
||||
*
|
||||
* In this function, the allocation may be adjusted. It will be forced
|
||||
* to a 1x1 minimum size, and the adjust_size_allocation virtual
|
||||
* method on the child will be used to adjust the allocation. Standard
|
||||
* adjustments include removing the widget's margins, and applying the
|
||||
* widget's #GtkWidget:halign and #GtkWidget:valign properties.
|
||||
**/
|
||||
void
|
||||
gtk_widget_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
gtk_widget_size_allocate_with_baseline (GtkWidget *widget,
|
||||
GtkAllocation *allocation,
|
||||
gint baseline)
|
||||
{
|
||||
GtkWidgetPrivate *priv;
|
||||
GdkRectangle real_allocation;
|
||||
@@ -5209,9 +5211,11 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
GdkRectangle adjusted_allocation;
|
||||
gboolean alloc_needed;
|
||||
gboolean size_changed;
|
||||
gboolean baseline_changed;
|
||||
gboolean position_changed;
|
||||
gint natural_width, natural_height, dummy;
|
||||
gint min_width, min_height;
|
||||
gint old_baseline;
|
||||
|
||||
priv = widget->priv;
|
||||
|
||||
@@ -5238,17 +5242,27 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
|
||||
name = g_type_name (G_OBJECT_TYPE (G_OBJECT (widget)));
|
||||
g_print ("gtk_widget_size_allocate: %*s%s %d %d\n",
|
||||
g_print ("gtk_widget_size_allocate: %*s%s %d %d",
|
||||
2 * depth, " ", name,
|
||||
allocation->width, allocation->height);
|
||||
if (baseline != -1)
|
||||
g_print (" baseline: %d", baseline);
|
||||
g_print ("\n");
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
/* Never pass a baseline to a child unless it requested it.
|
||||
This means containers don't have to manually check for this. */
|
||||
if (baseline != -1 &&
|
||||
gtk_widget_get_valign_with_baseline (widget) != GTK_ALIGN_BASELINE)
|
||||
baseline = -1;
|
||||
|
||||
alloc_needed = priv->alloc_needed;
|
||||
/* Preserve request/allocate ordering */
|
||||
priv->alloc_needed = FALSE;
|
||||
|
||||
old_allocation = priv->allocation;
|
||||
old_baseline = priv->allocated_baseline;
|
||||
real_allocation = *allocation;
|
||||
|
||||
adjusted_allocation = real_allocation;
|
||||
@@ -5298,6 +5312,9 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
&natural_height,
|
||||
&adjusted_allocation.y,
|
||||
&adjusted_allocation.height);
|
||||
if (baseline >= 0)
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_baseline_allocation (widget,
|
||||
&baseline);
|
||||
|
||||
if (adjusted_allocation.x < real_allocation.x ||
|
||||
adjusted_allocation.y < real_allocation.y ||
|
||||
@@ -5327,14 +5344,16 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
real_allocation.width = MAX (real_allocation.width, 1);
|
||||
real_allocation.height = MAX (real_allocation.height, 1);
|
||||
|
||||
baseline_changed = old_baseline != baseline;
|
||||
size_changed = (old_allocation.width != real_allocation.width ||
|
||||
old_allocation.height != real_allocation.height);
|
||||
position_changed = (old_allocation.x != real_allocation.x ||
|
||||
old_allocation.y != real_allocation.y);
|
||||
|
||||
if (!alloc_needed && !size_changed && !position_changed)
|
||||
if (!alloc_needed && !size_changed && !position_changed && !baseline_changed)
|
||||
goto out;
|
||||
|
||||
priv->allocated_baseline = baseline;
|
||||
g_signal_emit (widget, widget_signals[SIZE_ALLOCATE], 0, &real_allocation);
|
||||
|
||||
/* Size allocation is god... after consulting god, no further requests or allocations are needed */
|
||||
@@ -5368,7 +5387,7 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
if ((size_changed || position_changed) && priv->parent &&
|
||||
if ((size_changed || position_changed || baseline_changed) && priv->parent &&
|
||||
gtk_widget_get_realized (priv->parent) && _gtk_container_get_reallocate_redraws (GTK_CONTAINER (priv->parent)))
|
||||
{
|
||||
cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->parent->priv->allocation);
|
||||
@@ -5380,6 +5399,28 @@ out:
|
||||
gtk_widget_pop_verify_invariants (widget);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_widget_size_allocate:
|
||||
* @widget: a #GtkWidget
|
||||
* @allocation: position and size to be allocated to @widget
|
||||
*
|
||||
* This function is only used by #GtkContainer subclasses, to assign a size
|
||||
* and position to their child widgets.
|
||||
*
|
||||
* In this function, the allocation may be adjusted. It will be forced
|
||||
* to a 1x1 minimum size, and the adjust_size_allocation virtual
|
||||
* method on the child will be used to adjust the allocation. Standard
|
||||
* adjustments include removing the widget's margins, and applying the
|
||||
* widget's #GtkWidget:halign and #GtkWidget:valign properties.
|
||||
**/
|
||||
void
|
||||
gtk_widget_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
gtk_widget_size_allocate_with_baseline (widget, allocation, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_common_ancestor:
|
||||
* @widget_a: a #GtkWidget
|
||||
@@ -5601,6 +5642,7 @@ adjust_for_align (GtkAlign align,
|
||||
{
|
||||
switch (align)
|
||||
{
|
||||
case GTK_ALIGN_BASELINE:
|
||||
case GTK_ALIGN_FILL:
|
||||
/* change nothing */
|
||||
break;
|
||||
@@ -5671,6 +5713,18 @@ gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_real_adjust_baseline_allocation (GtkWidget *widget,
|
||||
gint *baseline)
|
||||
{
|
||||
const GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info_or_defaults (widget);
|
||||
|
||||
if (baseline >= 0)
|
||||
*baseline -= aux_info->margin.top;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_widget_real_can_activate_accel (GtkWidget *widget,
|
||||
guint signal_id)
|
||||
@@ -11012,6 +11066,28 @@ gtk_widget_real_adjust_size_request (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_real_adjust_baseline_request (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
const GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
aux_info =_gtk_widget_get_aux_info_or_defaults (widget);
|
||||
|
||||
if (aux_info->height >= 0)
|
||||
{
|
||||
/* No baseline support for explicitly set height */
|
||||
*minimum_baseline = -1;
|
||||
*natural_baseline = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum_baseline += aux_info->margin.top;
|
||||
*natural_baseline += aux_info->margin.top;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_widget_peek_request_cache:
|
||||
*
|
||||
@@ -13162,6 +13238,25 @@ gtk_widget_real_get_width_for_height (GtkWidget *widget,
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_real_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
if (width == -1)
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
|
||||
else
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget, width, minimum_height, natural_height);
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_halign:
|
||||
* @widget: a #GtkWidget
|
||||
@@ -13203,6 +13298,13 @@ gtk_widget_set_halign (GtkWidget *widget,
|
||||
g_object_notify (G_OBJECT (widget), "halign");
|
||||
}
|
||||
|
||||
GtkAlign
|
||||
gtk_widget_get_valign_with_baseline (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->valign;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_valign:
|
||||
* @widget: a #GtkWidget
|
||||
@@ -13214,8 +13316,12 @@ gtk_widget_set_halign (GtkWidget *widget,
|
||||
GtkAlign
|
||||
gtk_widget_get_valign (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->valign;
|
||||
GtkAlign align;
|
||||
|
||||
align = gtk_widget_get_valign_with_baseline (widget);
|
||||
if (align == GTK_ALIGN_BASELINE)
|
||||
return GTK_ALIGN_FILL;
|
||||
return align;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13992,6 +14098,14 @@ gtk_widget_get_allocated_height (GtkWidget *widget)
|
||||
return widget->priv->allocation.height;
|
||||
}
|
||||
|
||||
int
|
||||
gtk_widget_get_allocated_baseline (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
|
||||
|
||||
return widget->priv->allocated_baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_requisition:
|
||||
* @widget: a #GtkWidget
|
||||
|
@@ -433,14 +433,23 @@ struct _GtkWidgetClass
|
||||
gboolean (* touch_event) (GtkWidget *widget,
|
||||
GdkEventTouch *event);
|
||||
|
||||
void (* get_preferred_height_and_baseline_for_width) (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
void (* adjust_baseline_request)(GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
void (* adjust_baseline_allocation) (GtkWidget *widget,
|
||||
gint *baseline);
|
||||
|
||||
/*< private >*/
|
||||
|
||||
GtkWidgetClassPrivate *priv;
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
void (*_gtk_reserved5) (void);
|
||||
void (*_gtk_reserved6) (void);
|
||||
void (*_gtk_reserved7) (void);
|
||||
@@ -498,6 +507,9 @@ void gtk_widget_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition);
|
||||
void gtk_widget_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
void gtk_widget_size_allocate_with_baseline (GtkWidget *widget,
|
||||
GtkAllocation *allocation,
|
||||
gint baseline);
|
||||
|
||||
GtkSizeRequestMode gtk_widget_get_request_mode (GtkWidget *widget);
|
||||
void gtk_widget_get_preferred_width (GtkWidget *widget,
|
||||
@@ -514,6 +526,12 @@ void gtk_widget_get_preferred_width_for_height (GtkWidget *w
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
void gtk_widget_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
void gtk_widget_get_preferred_size (GtkWidget *widget,
|
||||
GtkRequisition *minimum_size,
|
||||
GtkRequisition *natural_size);
|
||||
@@ -659,6 +677,7 @@ void gtk_widget_unregister_window (GtkWidget *widget,
|
||||
|
||||
int gtk_widget_get_allocated_width (GtkWidget *widget);
|
||||
int gtk_widget_get_allocated_height (GtkWidget *widget);
|
||||
int gtk_widget_get_allocated_baseline (GtkWidget *widget);
|
||||
|
||||
void gtk_widget_get_allocation (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
@@ -756,6 +775,7 @@ GtkAlign gtk_widget_get_halign (GtkWidget *widget);
|
||||
void gtk_widget_set_halign (GtkWidget *widget,
|
||||
GtkAlign align);
|
||||
GtkAlign gtk_widget_get_valign (GtkWidget *widget);
|
||||
GtkAlign gtk_widget_get_valign_with_baseline (GtkWidget *widget);
|
||||
void gtk_widget_set_valign (GtkWidget *widget,
|
||||
GtkAlign align);
|
||||
gint gtk_widget_get_margin_left (GtkWidget *widget);
|
||||
|
@@ -69,7 +69,9 @@ void _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
gint *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
gboolean _gtk_widget_get_translation_to_window (GtkWidget *widget,
|
||||
GdkWindow *window,
|
||||
|
@@ -36,6 +36,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
testappchooser \
|
||||
testappchooserbutton \
|
||||
testassistant \
|
||||
testbaseline \
|
||||
testbbox \
|
||||
testboxcss \
|
||||
testbuttons \
|
||||
@@ -164,6 +165,7 @@ testiconview_DEPENDENCIES = $(TEST_DEPS)
|
||||
testaccel_DEPENDENCIES = $(TEST_DEPS)
|
||||
testadjustsize_DEPENDENCIES = $(TEST_DEPS)
|
||||
testassistant_DEPENDENCIES = $(TEST_DEPS)
|
||||
testbaseline_DEPENDENCIES = $(TEST_DEPS)
|
||||
testbbox_DEPENDENCIES = $(TEST_DEPS)
|
||||
testbuttons_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcairo_DEPENDENCIES = $(TEST_DEPS)
|
||||
@@ -354,6 +356,9 @@ testmerge_SOURCES = \
|
||||
testactions_SOURCES = \
|
||||
testactions.c
|
||||
|
||||
testbaseline_SOURCES = \
|
||||
testbaseline.c
|
||||
|
||||
testbbox_SOURCES = \
|
||||
testbbox.c
|
||||
|
||||
|
109
tests/testbaseline.c
Normal file
109
tests/testbaseline.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Nokia Corporation.
|
||||
* Author: Xan Lopez <xan.lopez@nokia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
GtkWidget *window, *label, *button;
|
||||
GtkWidget *vbox, *hbox;
|
||||
PangoFontDescription *font;
|
||||
int i, j;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
for (j = 0; j < 5; j++)
|
||||
{
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
|
||||
|
||||
char *aligns[] = { "FILL", "START", "END", "CENTER", "BASELINE" };
|
||||
label = gtk_label_new (aligns[j]);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
label = gtk_label_new ("A string XYyj,Ö...");
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 7*(i+1)* 1024);
|
||||
gtk_widget_override_font (label, font);
|
||||
|
||||
gtk_widget_set_valign (label, j);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
|
||||
|
||||
if (j == 0)
|
||||
label = gtk_label_new ("Baseline:");
|
||||
else
|
||||
label = gtk_label_new ("Normal:");
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
button = gtk_button_new_with_label ("│Xyj,Ö");
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 7*(i+1)* 1024);
|
||||
gtk_widget_override_font (button, font);
|
||||
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
button = gtk_button_new_with_label ("│Xyj,Ö");
|
||||
|
||||
gtk_button_set_image (GTK_BUTTON (button),
|
||||
gtk_image_new_from_icon_name ("face-sad", GTK_ICON_SIZE_BUTTON));
|
||||
gtk_button_set_always_show_image (GTK_BUTTON (button), TRUE);
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 7*(i+1)* 1024);
|
||||
gtk_widget_override_font (button, font);
|
||||
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user