Compare commits
45 Commits
matthiasc/
...
wip/baseli
Author | SHA1 | Date | |
---|---|---|---|
|
1c2393cc73 | ||
|
75fe9b5f57 | ||
|
3de86b38a0 | ||
|
95d5f0c33b | ||
|
9269fc82b1 | ||
|
0c4103f9b7 | ||
|
4034a13263 | ||
|
926c50c3f9 | ||
|
0fca2a0f82 | ||
|
a4f1bc97a5 | ||
|
6ce70b33c6 | ||
|
8535e32b8d | ||
|
e240742d0a | ||
|
c75e10e9ea | ||
|
5405383cb2 | ||
|
aeab118289 | ||
|
fc5ba0a6ef | ||
|
3d92798c96 | ||
|
8cb229a847 | ||
|
9cfb89990e | ||
|
8b8d6e188d | ||
|
f7863d7fa5 | ||
|
7918b3d1a3 | ||
|
601b5f4f52 | ||
|
89ef97cd25 | ||
|
8f17db9b4a | ||
|
dcacd41641 | ||
|
6b3f27c76c | ||
|
faf2d7aab7 | ||
|
2725f74d92 | ||
|
498bb2046a | ||
|
c7c2767d76 | ||
|
e3345e74c5 | ||
|
361ff36120 | ||
|
37c9c5e49e | ||
|
d0ab7336ba | ||
|
639f1407c9 | ||
|
62952efc04 | ||
|
21c2e6da9a | ||
|
3e2606f4f4 | ||
|
ac7dcd90cc | ||
|
e6b12e0fd7 | ||
|
f76e22b39e | ||
|
7a568a6127 | ||
|
df6dcfb511 |
@@ -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
|
||||
|
184
gtk/gtkbbox.c
184
gtk/gtkbbox.c
@@ -101,6 +101,12 @@ static void gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static void gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
@@ -143,6 +149,7 @@ gtk_button_box_class_init (GtkButtonBoxClass *class)
|
||||
widget_class->get_preferred_height = gtk_button_box_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_button_box_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_button_box_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_button_box_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_button_box_size_allocate;
|
||||
|
||||
container_class->remove = gtk_button_box_remove;
|
||||
@@ -438,7 +445,10 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
gint *nvis_children,
|
||||
gint *nvis_secondaries,
|
||||
gint **widths,
|
||||
gint **heights)
|
||||
gint **heights,
|
||||
gint **baselines,
|
||||
gint *baseline,
|
||||
gint *baseline_height)
|
||||
{
|
||||
GtkButtonBox *bbox;
|
||||
GList *children, *list;
|
||||
@@ -446,6 +456,7 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
gint nsecondaries;
|
||||
gint needed_width;
|
||||
gint needed_height;
|
||||
gint needed_above, needed_below;
|
||||
gint avg_w, avg_h;
|
||||
GtkRequisition child_requisition;
|
||||
gint ipad_w;
|
||||
@@ -456,11 +467,15 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
gint ipad_y;
|
||||
gboolean homogeneous;
|
||||
gint i;
|
||||
gint max_above, max_below, child_baseline;
|
||||
GtkOrientation orientation;
|
||||
gboolean have_baseline;
|
||||
|
||||
g_return_if_fail (GTK_IS_BUTTON_BOX (widget));
|
||||
|
||||
bbox = GTK_BUTTON_BOX (widget);
|
||||
|
||||
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
|
||||
homogeneous = gtk_box_get_homogeneous (GTK_BOX (widget));
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
@@ -475,22 +490,33 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
list = children = _gtk_box_get_children (GTK_BOX (bbox));
|
||||
needed_width = child_min_width;
|
||||
needed_height = child_min_height;
|
||||
needed_above = 0;
|
||||
needed_below = 0;
|
||||
ipad_w = ipad_x * 2;
|
||||
ipad_h = ipad_y * 2;
|
||||
|
||||
have_baseline = FALSE;
|
||||
max_above = max_below = 0;
|
||||
avg_w = avg_h = 0;
|
||||
while (children)
|
||||
for (children = list; children != NULL; children = children->next)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
child = children->data;
|
||||
children = children->next;
|
||||
|
||||
if (gtk_widget_get_visible (child))
|
||||
{
|
||||
nchildren += 1;
|
||||
gtk_widget_get_preferred_size (child,
|
||||
&child_requisition, NULL);
|
||||
gtk_widget_get_preferred_size_and_baseline (child,
|
||||
&child_requisition, NULL, &child_baseline, NULL);
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
|
||||
child_baseline != -1)
|
||||
{
|
||||
have_baseline = TRUE;
|
||||
max_above = MAX (max_above, child_baseline + ipad_y);
|
||||
max_below = MAX (max_below , child_requisition.height + ipad_h - (child_baseline + ipad_y));
|
||||
}
|
||||
avg_w += child_requisition.width + ipad_w;
|
||||
avg_h += child_requisition.height + ipad_h;
|
||||
}
|
||||
@@ -498,8 +524,14 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
avg_w /= MAX (nchildren, 1);
|
||||
avg_h /= MAX (nchildren, 1);
|
||||
|
||||
if (baseline)
|
||||
*baseline = have_baseline ? max_above : -1;
|
||||
if (baseline_height)
|
||||
*baseline_height = max_above + max_below;
|
||||
|
||||
*widths = g_new (gint, nchildren);
|
||||
*heights = g_new (gint, nchildren);
|
||||
*baselines = g_new (gint, nchildren);
|
||||
|
||||
i = 0;
|
||||
children = list;
|
||||
@@ -520,7 +552,8 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
if (is_secondary)
|
||||
nsecondaries++;
|
||||
|
||||
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
|
||||
gtk_widget_get_preferred_size_and_baseline (child,
|
||||
&child_requisition, NULL, &child_baseline, NULL);
|
||||
|
||||
if (homogeneous ||
|
||||
(!non_homogeneous && (child_requisition.width + ipad_w < avg_w * 1.5)))
|
||||
@@ -534,16 +567,38 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
(*widths)[i] = child_requisition.width + ipad_w;
|
||||
}
|
||||
|
||||
(*baselines)[i] = -1;
|
||||
|
||||
if (homogeneous ||
|
||||
(!non_homogeneous && (child_requisition.height + ipad_h < avg_h * 1.5)))
|
||||
{
|
||||
(*heights)[i] = -1;
|
||||
if (child_requisition.height + ipad_h > needed_height)
|
||||
needed_height = child_requisition.height + ipad_h;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
|
||||
child_baseline != -1)
|
||||
{
|
||||
(*baselines)[i] = child_baseline + ipad_y;
|
||||
|
||||
if (child_baseline + ipad_y > needed_above)
|
||||
needed_above = child_baseline + ipad_y;
|
||||
if (child_requisition.height - child_baseline + ipad_y > needed_below)
|
||||
needed_below = child_requisition.height - child_baseline + ipad_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (child_requisition.height + ipad_h > needed_height)
|
||||
needed_height = child_requisition.height + ipad_h;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*heights)[i] = child_requisition.height + ipad_h;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
|
||||
child_baseline != -1)
|
||||
(*baselines)[i] = child_baseline + ipad_y;
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -552,12 +607,18 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
needed_height = MAX (needed_height, needed_above + needed_below);
|
||||
|
||||
for (i = 0; i < nchildren; i++)
|
||||
{
|
||||
if ((*widths)[i] == -1)
|
||||
(*widths)[i] = needed_width;
|
||||
if ((*heights)[i] == -1)
|
||||
(*heights)[i] = needed_height;
|
||||
{
|
||||
(*heights)[i] = needed_height;
|
||||
if ((*baselines)[i] != -1)
|
||||
(*baselines)[i] = needed_above;
|
||||
}
|
||||
}
|
||||
|
||||
if (nvis_children)
|
||||
@@ -569,19 +630,24 @@ gtk_button_box_child_requisition (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
gtk_button_box_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition)
|
||||
GtkRequisition *requisition,
|
||||
gint *baseline)
|
||||
{
|
||||
GtkButtonBoxPrivate *priv;
|
||||
GtkButtonBox *bbox;
|
||||
gint nvis_children;
|
||||
gint max_size;
|
||||
gint max_size, max_above, max_below;
|
||||
gint total_size;
|
||||
gint spacing;
|
||||
GtkOrientation orientation;
|
||||
gint *widths;
|
||||
gint *heights;
|
||||
gint *baselines;
|
||||
gint i;
|
||||
|
||||
if (baseline)
|
||||
*baseline = -1;
|
||||
|
||||
bbox = GTK_BUTTON_BOX (widget);
|
||||
priv = bbox->priv;
|
||||
|
||||
@@ -591,16 +657,22 @@ gtk_button_box_size_request (GtkWidget *widget,
|
||||
gtk_button_box_child_requisition (widget,
|
||||
&nvis_children,
|
||||
NULL,
|
||||
&widths, &heights);
|
||||
&widths, &heights, &baselines, baseline, NULL);
|
||||
|
||||
max_size = 0;
|
||||
max_size = max_above = max_below = 0;
|
||||
total_size = 0;
|
||||
for (i = 0; i < nvis_children; i++)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
total_size += widths[i];
|
||||
max_size = MAX (max_size, heights[i]);
|
||||
if (baselines[i] == -1)
|
||||
max_size = MAX (max_size, heights[i]);
|
||||
else
|
||||
{
|
||||
max_above = MAX (max_above, baselines[i]);
|
||||
max_below = MAX (max_below, heights[i] - baselines[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -610,6 +682,23 @@ gtk_button_box_size_request (GtkWidget *widget,
|
||||
}
|
||||
g_free (widths);
|
||||
g_free (heights);
|
||||
g_free (baselines);
|
||||
|
||||
max_size = MAX (max_size, max_above + max_below);
|
||||
|
||||
switch (gtk_box_get_baseline_position (GTK_BOX (widget)))
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
if (baseline != NULL && *baseline != -1)
|
||||
*baseline += (max_size - (max_above + max_below)) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
if (baseline != NULL && *baseline != -1)
|
||||
*baseline += max_size - (max_above + max_below);
|
||||
break;
|
||||
}
|
||||
|
||||
if (nvis_children == 0)
|
||||
{
|
||||
@@ -656,7 +745,7 @@ gtk_button_box_get_preferred_width (GtkWidget *widget,
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
|
||||
gtk_button_box_size_request (widget, &requisition);
|
||||
gtk_button_box_size_request (widget, &requisition, NULL);
|
||||
|
||||
*minimum = *natural = requisition.width;
|
||||
}
|
||||
@@ -666,11 +755,9 @@ gtk_button_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
|
||||
gtk_button_box_size_request (widget, &requisition);
|
||||
|
||||
*minimum = *natural = requisition.height;
|
||||
gtk_button_box_get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -691,6 +778,26 @@ gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gtk_button_box_get_preferred_height (widget, minimum, natural);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
gint baseline;
|
||||
|
||||
gtk_button_box_size_request (widget, &requisition, &baseline);
|
||||
|
||||
*minimum = *natural = requisition.height;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
@@ -714,10 +821,13 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
gint ipad_x, ipad_y;
|
||||
gint *widths;
|
||||
gint *heights;
|
||||
gint *baselines;
|
||||
gint *sizes;
|
||||
gint primary_size;
|
||||
gint secondary_size;
|
||||
gint total_size;
|
||||
gint baseline, baseline_height;
|
||||
gint child_baseline, allocated_baseline;
|
||||
gint i;
|
||||
|
||||
bbox = GTK_BUTTON_BOX (widget);
|
||||
@@ -733,7 +843,27 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
gtk_button_box_child_requisition (widget,
|
||||
&nvis_children,
|
||||
&n_secondaries,
|
||||
&widths, &heights);
|
||||
&widths, &heights, &baselines, &baseline, &baseline_height);
|
||||
|
||||
allocated_baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (allocated_baseline != -1)
|
||||
baseline = allocated_baseline;
|
||||
else if (baseline != -1)
|
||||
{
|
||||
/* TODO: modify baseline based on baseline_pos && allocated_baseline*/
|
||||
switch (gtk_box_get_baseline_position (GTK_BOX (widget)))
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
baseline = baseline;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
baseline = baseline + (allocation->height - baseline_height) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
baseline = allocation->height - (baseline_height - baseline);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
n_primaries = nvis_children - n_secondaries;
|
||||
primary_size = 0;
|
||||
@@ -917,10 +1047,17 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
{
|
||||
child_allocation.width = widths[i];
|
||||
child_allocation.height = heights[i];
|
||||
child_baseline = -1;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
|
||||
if (baselines[i] != -1)
|
||||
{
|
||||
child_allocation.y = allocation->y + baseline - baselines[i];
|
||||
child_baseline = baselines[i];
|
||||
}
|
||||
else
|
||||
child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
|
||||
|
||||
if (gtk_button_box_get_child_secondary (bbox, child))
|
||||
{
|
||||
@@ -953,7 +1090,7 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, child_baseline);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -961,6 +1098,7 @@ gtk_button_box_size_allocate (GtkWidget *widget,
|
||||
g_list_free (list);
|
||||
g_free (widths);
|
||||
g_free (heights);
|
||||
g_free (baselines);
|
||||
}
|
||||
|
||||
/**
|
||||
|
382
gtk/gtkbox.c
382
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,39 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
natural += (nvis_children - 1) * private->spacing;
|
||||
}
|
||||
|
||||
minimum = MAX (minimum, minimum_below + minimum_above);
|
||||
natural = MAX (natural, natural_below + natural_above);
|
||||
|
||||
if (have_baseline)
|
||||
{
|
||||
switch (private->baseline_pos)
|
||||
{
|
||||
case GTK_BASELINE_POSITION_TOP:
|
||||
min_baseline = minimum_above;
|
||||
nat_baseline = natural_above;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_CENTER:
|
||||
min_baseline = minimum_above + (minimum - (minimum_above + minimum_below)) / 2;
|
||||
nat_baseline = natural_above + (natural - (natural_above + natural_below)) / 2;
|
||||
break;
|
||||
case GTK_BASELINE_POSITION_BOTTOM:
|
||||
min_baseline = minimum - minimum_below;
|
||||
nat_baseline = natural - natural_below;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (minimum_size)
|
||||
*minimum_size = minimum;
|
||||
|
||||
if (natural_size)
|
||||
*natural_size = natural;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = min_baseline;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = nat_baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1097,7 +1262,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 +1270,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 +1287,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 +1371,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 +1433,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 +1566,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 +1783,55 @@ gtk_box_get_spacing (GtkBox *box)
|
||||
return box->priv->spacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_set_baseline_position:
|
||||
* @box: a #GtkBox
|
||||
* @position: a #GtkBaselinePosition
|
||||
*
|
||||
* Sets the baseline position of a box. This affects
|
||||
* only horizontal boxes with at least one baseline aligned
|
||||
* child. If there is more vertical space availible than requested,
|
||||
* and the baseline is not allocated by the parent then
|
||||
* @position is used to allocate the baseline wrt the
|
||||
* extra space available.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_get_baseline_position:
|
||||
* @box: a #GtkBox
|
||||
*
|
||||
* Gets the value set by gtk_box_set_baseline_position().
|
||||
*
|
||||
* Return value: the baseline position
|
||||
**/
|
||||
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,11 @@ gboolean gtk_box_get_homogeneous (GtkBox *box);
|
||||
void gtk_box_set_spacing (GtkBox *box,
|
||||
gint spacing);
|
||||
gint gtk_box_get_spacing (GtkBox *box);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gtk_box_set_baseline_position (GtkBox *box,
|
||||
GtkBaselinePosition position);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
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,16 @@ gtk_button_construct_child (GtkButton *button)
|
||||
else
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, image_spacing);
|
||||
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_BASELINE);
|
||||
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 +1184,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 +1210,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 +1600,7 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
GtkBorder border;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint baseline;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
@@ -1635,6 +1652,10 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
child_allocation.height = child_allocation.height - (focus_width + focus_pad) * 2;
|
||||
}
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline != -1)
|
||||
baseline -= child_allocation.y - allocation->y;
|
||||
|
||||
if (priv->depressed)
|
||||
{
|
||||
gint child_displacement_x;
|
||||
@@ -1651,7 +1672,7 @@ 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);
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2063,7 +2084,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 +2097,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 +2108,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 +2123,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 +2139,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 +2167,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 +2175,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -39,6 +39,9 @@ struct _GtkButtonPrivate
|
||||
gfloat xalign;
|
||||
gfloat yalign;
|
||||
|
||||
/* This is only used by checkbox and subclasses */
|
||||
gfloat baseline_align;
|
||||
|
||||
guint activate_timeout;
|
||||
guint32 grab_time;
|
||||
|
||||
|
@@ -58,6 +58,12 @@ static void gtk_check_button_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_check_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gtk_check_button_draw (GtkWidget *widget,
|
||||
@@ -80,6 +86,7 @@ gtk_check_button_class_init (GtkCheckButtonClass *class)
|
||||
|
||||
widget_class->get_preferred_width = gtk_check_button_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_check_button_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_check_button_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_check_button_size_allocate;
|
||||
widget_class->draw = gtk_check_button_draw;
|
||||
|
||||
@@ -287,9 +294,12 @@ gtk_check_button_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (widget);
|
||||
|
||||
@@ -301,6 +311,7 @@ gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint indicator_spacing;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint old_minimum, old_natural;
|
||||
guint border_width;
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
@@ -320,29 +331,61 @@ gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
gint child_min_baseline = -1, child_nat_baseline = -1;
|
||||
|
||||
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 + border_width;
|
||||
if (natural_baseline && child_nat_baseline >= 0)
|
||||
*natural_baseline = child_nat_baseline + border_width;
|
||||
|
||||
*minimum += child_min;
|
||||
*natural += child_nat;
|
||||
|
||||
}
|
||||
|
||||
old_minimum = *minimum;
|
||||
old_natural = *natural;
|
||||
|
||||
temp = indicator_size + indicator_spacing * 2;
|
||||
*minimum = MAX (*minimum, temp) + 2 * (focus_width + focus_pad);
|
||||
*natural = MAX (*natural, temp) + 2 * (focus_width + focus_pad);
|
||||
|
||||
if (minimum_baseline && *minimum_baseline != -1)
|
||||
minimum_baseline += (*minimum - old_minimum) / 2;
|
||||
if (natural_baseline && *natural_baseline != -1)
|
||||
natural_baseline += (*natural - old_natural) / 2;
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_height (widget, minimum, natural);
|
||||
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_height_and_baseline_for_width (widget, width,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_check_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_check_button_get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_check_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
PangoContext *pango_context;
|
||||
PangoFontMetrics *metrics;
|
||||
GtkCheckButton *check_button;
|
||||
GtkToggleButton *toggle_button;
|
||||
GtkButton *button;
|
||||
GtkAllocation child_allocation;
|
||||
gint baseline;
|
||||
|
||||
button = GTK_BUTTON (widget);
|
||||
check_button = GTK_CHECK_BUTTON (widget);
|
||||
@@ -389,8 +432,21 @@ gtk_check_button_size_allocate (GtkWidget *widget,
|
||||
child_allocation.x = allocation->x + allocation->width
|
||||
- (child_allocation.x - allocation->x + child_allocation.width);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
pango_context = gtk_widget_get_pango_context (widget);
|
||||
metrics = pango_context_get_metrics (pango_context,
|
||||
pango_context_get_font_description (pango_context),
|
||||
pango_context_get_language (pango_context));
|
||||
button->priv->baseline_align =
|
||||
(double)pango_font_metrics_get_ascent (metrics) /
|
||||
(pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics));
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->size_allocate (widget, allocation);
|
||||
@@ -448,6 +504,7 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
|
||||
gint indicator_spacing;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint baseline;
|
||||
guint border_width;
|
||||
gboolean interior_focus;
|
||||
GtkAllocation allocation;
|
||||
@@ -458,6 +515,7 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
|
||||
toggle_button = GTK_TOGGLE_BUTTON (check_button);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
@@ -472,7 +530,11 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
|
||||
x = indicator_spacing + border_width;
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
if (baseline == -1)
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
else
|
||||
y = CLAMP (baseline - indicator_size * button->priv->baseline_align,
|
||||
0, allocation.height - indicator_size);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (check_button));
|
||||
if (!interior_focus || !(child && gtk_widget_get_visible (child)))
|
||||
|
@@ -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;
|
||||
|
@@ -47,7 +47,8 @@ typedef enum {
|
||||
GTK_DEBUG_PRINTING = 1 << 10,
|
||||
GTK_DEBUG_BUILDER = 1 << 11,
|
||||
GTK_DEBUG_SIZE_REQUEST = 1 << 12,
|
||||
GTK_DEBUG_NO_CSS_CACHE = 1 << 13
|
||||
GTK_DEBUG_NO_CSS_CACHE = 1 << 13,
|
||||
GTK_DEBUG_BASELINES = 1 << 14
|
||||
} GtkDebugFlag;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
@@ -787,6 +787,7 @@ gtk_dialog_add_button (GtkDialog *dialog,
|
||||
button = gtk_button_new_from_stock (button_text);
|
||||
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_widget_show (button);
|
||||
|
||||
|
@@ -367,6 +367,12 @@ static void gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_entry_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_entry_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static void gtk_entry_draw_frame (GtkWidget *widget,
|
||||
@@ -682,6 +688,7 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
widget_class->unrealize = gtk_entry_unrealize;
|
||||
widget_class->get_preferred_width = gtk_entry_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_entry_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_entry_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_entry_size_allocate;
|
||||
widget_class->draw = gtk_entry_draw;
|
||||
widget_class->enter_notify_event = gtk_entry_enter_notify;
|
||||
@@ -3305,16 +3312,19 @@ gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
PangoFontMetrics *metrics;
|
||||
GtkBorder borders;
|
||||
PangoContext *context;
|
||||
gint height;
|
||||
gint height, baseline;
|
||||
PangoLayout *layout;
|
||||
|
||||
layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||
@@ -3333,8 +3343,27 @@ gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
|
||||
height += borders.top + borders.bottom;
|
||||
|
||||
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
|
||||
baseline += borders.top;
|
||||
|
||||
*minimum = height;
|
||||
*natural = height;
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_entry_get_preferred_height_and_baseline_for_width (widget,
|
||||
-1,
|
||||
minimum,
|
||||
natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3452,13 +3481,17 @@ gtk_entry_get_frame_size (GtkEntry *entry,
|
||||
GtkAllocation allocation;
|
||||
GtkRequisition requisition;
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
gint area_height, y_pos;
|
||||
gint baseline;
|
||||
gint req_height;
|
||||
GtkBorder borders;
|
||||
|
||||
gtk_widget_get_preferred_size (widget, &requisition, NULL);
|
||||
|
||||
req_height = requisition.height - gtk_widget_get_margin_top (widget) - gtk_widget_get_margin_bottom (widget);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
if (x)
|
||||
*x = allocation.x;
|
||||
@@ -3468,7 +3501,17 @@ gtk_entry_get_frame_size (GtkEntry *entry,
|
||||
if (priv->is_cell_renderer)
|
||||
*y = 0;
|
||||
else
|
||||
*y = (allocation.height - req_height) / 2;
|
||||
{
|
||||
if (baseline == -1)
|
||||
*y = (allocation.height - req_height) / 2;
|
||||
else
|
||||
{
|
||||
_gtk_entry_get_borders (entry, &borders);
|
||||
area_height = req_height - borders.top - borders.bottom;
|
||||
y_pos = ((area_height * PANGO_SCALE - priv->ascent - priv->descent) / 2 + priv->ascent) / PANGO_SCALE;
|
||||
*y = baseline - y_pos - borders.top;
|
||||
}
|
||||
}
|
||||
|
||||
*y += allocation.y;
|
||||
}
|
||||
|
@@ -51,6 +51,7 @@ G_BEGIN_DECLS
|
||||
* or top
|
||||
* @GTK_ALIGN_CENTER: center natural width of widget inside the
|
||||
* allocation
|
||||
* @GTK_ALIGN_BASELINE: align the widget according to the baseline. Since 3.10.
|
||||
*
|
||||
* Controls how a widget deals with extra space in a single (x or y)
|
||||
* dimension.
|
||||
@@ -64,13 +65,18 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Note that in horizontal context @GTK_ALIGN_START and @GTK_ALIGN_END
|
||||
* are interpreted relative to text direction.
|
||||
*
|
||||
* GTK_ALIGN_BASELINE support for it is optional for containers and widgets, and
|
||||
* it is only supported for vertical alignment. When its not supported by
|
||||
* a child or a container it is treated as @GTK_ALIGN_FILL.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_ALIGN_FILL,
|
||||
GTK_ALIGN_START,
|
||||
GTK_ALIGN_END,
|
||||
GTK_ALIGN_CENTER
|
||||
GTK_ALIGN_CENTER,
|
||||
GTK_ALIGN_BASELINE
|
||||
} GtkAlign;
|
||||
|
||||
|
||||
@@ -125,6 +131,28 @@ typedef enum
|
||||
GTK_FILL = 1 << 2
|
||||
} GtkAttachOptions;
|
||||
|
||||
/**
|
||||
* GtkBaselinePosition:
|
||||
* @GTK_BASELINE_POSITION_TOP: Align the baseline at the top
|
||||
* @GTK_BASELINE_POSITION_CENTER: Center the baseline
|
||||
* @GTK_BASELINE_POSITION_BOTTOM: Align the baseline at the bottom
|
||||
*
|
||||
* Whenever a container has some form of natural row it may align
|
||||
* children in that row along a common typographical baseline. If
|
||||
* the amount of verical space in the row is taller than the total
|
||||
* requested height of the baseline-aligned children then it can use a
|
||||
* #GtkBaselinePosition to select where to put the baseline inside the
|
||||
* extra availible space.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_BASELINE_POSITION_TOP,
|
||||
GTK_BASELINE_POSITION_CENTER,
|
||||
GTK_BASELINE_POSITION_BOTTOM
|
||||
} GtkBaselinePosition;
|
||||
|
||||
/**
|
||||
* GtkButtonBoxStyle:
|
||||
* @GTK_BUTTONBOX_DEFAULT_STYLE: Default packing.
|
||||
|
@@ -65,6 +65,12 @@ static void gtk_event_box_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_event_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gtk_event_box_draw (GtkWidget *widget,
|
||||
@@ -96,6 +102,7 @@ gtk_event_box_class_init (GtkEventBoxClass *class)
|
||||
widget_class->unmap = gtk_event_box_unmap;
|
||||
widget_class->get_preferred_width = gtk_event_box_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_event_box_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_event_box_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_event_box_size_allocate;
|
||||
widget_class->draw = gtk_event_box_draw;
|
||||
|
||||
@@ -515,9 +522,12 @@ gtk_event_box_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkWidget *child;
|
||||
@@ -528,9 +538,30 @@ gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
if (natural)
|
||||
*natural = 0;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
child = gtk_bin_get_child (bin);
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
gtk_widget_get_preferred_height (child, minimum, natural);
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (child,
|
||||
-1,
|
||||
minimum,
|
||||
natural,
|
||||
minimum_baseline,
|
||||
natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_event_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_event_box_get_preferred_height_and_baseline_for_width (widget, -1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -539,6 +570,7 @@ gtk_event_box_size_allocate (GtkWidget *widget,
|
||||
{
|
||||
GtkBin *bin;
|
||||
GtkAllocation child_allocation;
|
||||
gint baseline;
|
||||
GtkEventBoxPrivate *priv;
|
||||
GtkWidget *child;
|
||||
|
||||
@@ -578,9 +610,10 @@ gtk_event_box_size_allocate (GtkWidget *widget,
|
||||
child_allocation.height);
|
||||
}
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
child = gtk_bin_get_child (bin);
|
||||
if (child)
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
710
gtk/gtkgrid.c
710
gtk/gtkgrid.c
File diff suppressed because it is too large
Load Diff
@@ -103,6 +103,18 @@ gboolean gtk_grid_get_column_homogeneous (GtkGrid *grid);
|
||||
void gtk_grid_set_column_spacing (GtkGrid *grid,
|
||||
guint spacing);
|
||||
guint gtk_grid_get_column_spacing (GtkGrid *grid);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gtk_grid_set_row_baseline_position (GtkGrid *grid,
|
||||
gint row,
|
||||
GtkBaselinePosition pos);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GtkBaselinePosition gtk_grid_get_row_baseline_position (GtkGrid *grid,
|
||||
gint row);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gtk_grid_set_baseline_row (GtkGrid *grid,
|
||||
gint row);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
gint gtk_grid_get_baseline_row (GtkGrid *grid);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -140,6 +140,8 @@ struct _GtkImagePrivate
|
||||
|
||||
gchar *filename; /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
|
||||
gchar *resource_path; /* Only used with GTK_IMAGE_PIXBUF */
|
||||
|
||||
float baseline_align;
|
||||
};
|
||||
|
||||
|
||||
@@ -154,6 +156,12 @@ static void gtk_image_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_image_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static void gtk_image_style_updated (GtkWidget *widget);
|
||||
static void gtk_image_screen_changed (GtkWidget *widget,
|
||||
@@ -207,6 +215,7 @@ gtk_image_class_init (GtkImageClass *class)
|
||||
widget_class->draw = gtk_image_draw;
|
||||
widget_class->get_preferred_width = gtk_image_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_image_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_image_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->unmap = gtk_image_unmap;
|
||||
widget_class->unrealize = gtk_image_unrealize;
|
||||
widget_class->style_updated = gtk_image_style_updated;
|
||||
@@ -1393,6 +1402,26 @@ gtk_image_get_preferred_size (GtkImage *image,
|
||||
*height_out = height;
|
||||
}
|
||||
|
||||
static float
|
||||
gtk_image_get_baseline_align (GtkImage *image)
|
||||
{
|
||||
PangoContext *pango_context;
|
||||
PangoFontMetrics *metrics;
|
||||
|
||||
if (image->priv->baseline_align == 0.0)
|
||||
{
|
||||
pango_context = gtk_widget_get_pango_context (GTK_WIDGET (image));
|
||||
metrics = pango_context_get_metrics (pango_context,
|
||||
pango_context_get_font_description (pango_context),
|
||||
pango_context_get_language (pango_context));
|
||||
image->priv->baseline_align =
|
||||
(float)pango_font_metrics_get_ascent (metrics) /
|
||||
(pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics));
|
||||
}
|
||||
|
||||
return image->priv->baseline_align;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_image_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
@@ -1401,7 +1430,7 @@ gtk_image_draw (GtkWidget *widget,
|
||||
GtkImagePrivate *priv;
|
||||
GtkMisc *misc;
|
||||
GtkStyleContext *context;
|
||||
gint x, y, width, height;
|
||||
gint x, y, width, height, baseline;
|
||||
gfloat xalign, yalign;
|
||||
GtkBorder border;
|
||||
|
||||
@@ -1427,8 +1456,28 @@ gtk_image_draw (GtkWidget *widget,
|
||||
if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
|
||||
xalign = 1.0 - xalign;
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
x = floor ((gtk_widget_get_allocated_width (widget) - width) * xalign) + border.left;
|
||||
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign) + border.top;
|
||||
if (baseline == -1)
|
||||
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign) + border.top;
|
||||
else
|
||||
{
|
||||
PangoContext *pango_context;
|
||||
PangoFontMetrics *metrics;
|
||||
float baseline_align;
|
||||
|
||||
pango_context = gtk_widget_get_pango_context (widget);
|
||||
metrics = pango_context_get_metrics (pango_context,
|
||||
pango_context_get_font_description (pango_context),
|
||||
pango_context_get_language (pango_context));
|
||||
baseline_align =
|
||||
(double)pango_font_metrics_get_ascent (metrics) /
|
||||
(pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics));
|
||||
|
||||
y = CLAMP (baseline - height * baseline_align,
|
||||
border.top, gtk_widget_get_allocated_height (widget) - height);
|
||||
}
|
||||
|
||||
if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
|
||||
{
|
||||
@@ -1535,15 +1584,37 @@ gtk_image_get_preferred_width (GtkWidget *widget,
|
||||
*minimum = *natural = width;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gint height;
|
||||
float baseline_align;
|
||||
|
||||
gtk_image_get_preferred_size (GTK_IMAGE (widget), NULL, &height);
|
||||
*minimum = *natural = height;
|
||||
|
||||
if (minimum_baseline || natural_baseline)
|
||||
{
|
||||
baseline_align = gtk_image_get_baseline_align (GTK_IMAGE (widget));
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = height * baseline_align;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = height * baseline_align;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gint height;
|
||||
|
||||
gtk_image_get_preferred_size (GTK_IMAGE (widget), NULL, &height);
|
||||
*minimum = *natural = height;
|
||||
gtk_image_get_preferred_height_and_baseline_for_width (widget, -1, minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1558,9 +1629,13 @@ icon_theme_changed (GtkImage *image)
|
||||
static void
|
||||
gtk_image_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GtkImage *image = GTK_IMAGE (widget);
|
||||
GtkImagePrivate *priv = image->priv;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
|
||||
|
||||
icon_theme_changed (GTK_IMAGE (widget));
|
||||
icon_theme_changed (image);
|
||||
priv->baseline_align = 0.0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
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;
|
||||
@@ -3462,15 +3469,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);
|
||||
|
||||
@@ -3482,6 +3492,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);
|
||||
}
|
||||
|
||||
@@ -3578,7 +3598,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;
|
||||
@@ -3586,6 +3608,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 */
|
||||
@@ -3640,7 +3668,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
|
||||
@@ -3667,7 +3696,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
|
||||
{
|
||||
@@ -3680,6 +3718,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3688,7 +3732,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
|
||||
@@ -3696,7 +3740,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
|
||||
@@ -3719,7 +3763,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;
|
||||
@@ -3732,15 +3777,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;
|
||||
|
||||
@@ -3751,7 +3798,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;
|
||||
@@ -3760,7 +3813,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
|
||||
@@ -3855,6 +3919,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);
|
||||
@@ -3887,6 +3952,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
|
||||
@@ -3901,9 +3975,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;
|
||||
|
@@ -172,7 +172,8 @@ static const GDebugKey gtk_debug_keys[] = {
|
||||
{"printing", GTK_DEBUG_PRINTING},
|
||||
{"builder", GTK_DEBUG_BUILDER},
|
||||
{"size-request", GTK_DEBUG_SIZE_REQUEST},
|
||||
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE}
|
||||
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE},
|
||||
{"baselines", GTK_DEBUG_BASELINES}
|
||||
};
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
|
@@ -903,6 +903,7 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
|
||||
gint indicator_size, indicator_spacing;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint baseline;
|
||||
guint border_width;
|
||||
gboolean interior_focus;
|
||||
|
||||
@@ -923,9 +924,14 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
|
||||
_gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
x = indicator_spacing + border_width;
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
if (baseline == -1)
|
||||
y = (allocation.height - indicator_size) / 2;
|
||||
else
|
||||
y = CLAMP (baseline - indicator_size * button->priv->baseline_align,
|
||||
0, allocation.height - indicator_size);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (check_button));
|
||||
if (!interior_focus || !(child && gtk_widget_get_visible (child)))
|
||||
|
@@ -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,122 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum_height,
|
||||
natural_height);
|
||||
natural_height,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_preferred_height_and_baseline_for_width:
|
||||
* @widget: a #GtkWidget instance
|
||||
* @width: the width which is available for allocation, or -1 if none
|
||||
* @minimum_height: (out) (allow-none): location for storing the minimum height, or %NULL
|
||||
* @natural_height: (out) (allow-none): location for storing the natural height, or %NULL
|
||||
* @minimum_baseline: (out) (allow-none): location for storing the baseline for the minimum height, or %NULL
|
||||
* @natural_baseline: (out) (allow-none): location for storing the baseline for the natural height, or %NULL
|
||||
*
|
||||
* Retrieves a widget's minimum and natural height and the corresponding baselines if it would be given
|
||||
* the specified @width, or the default height if @width is -1. The baselines may be -1 which means
|
||||
* that no baseline is requested for this widget.
|
||||
*
|
||||
* The returned request will be modified by the
|
||||
* GtkWidgetClass::adjust_size_request and GtkWidgetClass::adjust_baseline_request virtual methods
|
||||
* and by any #GtkSizeGroup<!-- -->s that have been applied. That is, the returned request
|
||||
* is the one that should be used for layout, not necessarily the one
|
||||
* returned by the widget itself.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_preferred_size_and_baseline:
|
||||
* @widget: a #GtkWidget instance
|
||||
* @minimum_size: (out) (allow-none): location for storing the minimum size, or %NULL
|
||||
* @natural_size: (out) (allow-none): location for storing the natural size, or %NULL
|
||||
*
|
||||
* Retrieves the minimum and natural size and the corresponding baselines of a widget, taking
|
||||
* into account the widget's preference for height-for-width management. The baselines may
|
||||
* be -1 which means that no baseline is requested for this widget.
|
||||
*
|
||||
* This is used to retrieve a suitable size by container widgets which do
|
||||
* not impose any restrictions on the child placement. It can be used
|
||||
* to deduce toplevel window and menu sizes as well as child widgets in
|
||||
* free-form containers such as GtkLayout.
|
||||
*
|
||||
* <note><para>Handle with care. Note that the natural height of a height-for-width
|
||||
* widget will generally be a smaller size than the minimum height, since the required
|
||||
* height for the natural width is generally smaller than the required height for
|
||||
* the minimum width.</para></note>
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gtk_widget_get_preferred_size_and_baseline (GtkWidget *widget,
|
||||
GtkRequisition *minimum_size,
|
||||
GtkRequisition *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gint min_width, nat_width;
|
||||
gint min_height, nat_height;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
gtk_widget_get_preferred_width (widget, &min_width, &nat_width);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->width = min_width;
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (widget, min_width,
|
||||
&minimum_size->height, NULL, minimum_baseline, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->width = nat_width;
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (widget, nat_width,
|
||||
NULL, &natural_size->height, NULL, natural_baseline);
|
||||
}
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
|
||||
{
|
||||
gtk_widget_get_preferred_height_and_baseline_for_width (widget, -1, &min_height, &nat_height, minimum_baseline, natural_baseline);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->height = min_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, min_height,
|
||||
&minimum_size->width, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->height = nat_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, nat_height,
|
||||
NULL, &natural_size->width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,6 +688,9 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
|
||||
* height for the natural width is generally smaller than the required height for
|
||||
* the minimum width.</para></note>
|
||||
*
|
||||
* Use gtk_widget_get_preferred_size_and_baseline() if you want to support
|
||||
* baseline alignment.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
void
|
||||
@@ -510,50 +698,10 @@ gtk_widget_get_preferred_size (GtkWidget *widget,
|
||||
GtkRequisition *minimum_size,
|
||||
GtkRequisition *natural_size)
|
||||
{
|
||||
gint min_width, nat_width;
|
||||
gint min_height, nat_height;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
gtk_widget_get_preferred_width (widget, &min_width, &nat_width);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->width = min_width;
|
||||
gtk_widget_get_preferred_height_for_width (widget, min_width,
|
||||
&minimum_size->height, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->width = nat_width;
|
||||
gtk_widget_get_preferred_height_for_width (widget, nat_width,
|
||||
NULL, &natural_size->height);
|
||||
}
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
|
||||
{
|
||||
gtk_widget_get_preferred_height (widget, &min_height, &nat_height);
|
||||
|
||||
if (minimum_size)
|
||||
{
|
||||
minimum_size->height = min_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, min_height,
|
||||
&minimum_size->width, NULL);
|
||||
}
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
natural_size->height = nat_height;
|
||||
gtk_widget_get_preferred_width_for_height (widget, nat_height,
|
||||
NULL, &natural_size->width);
|
||||
}
|
||||
}
|
||||
gtk_widget_get_preferred_size_and_baseline (widget, minimum_size, natural_size,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
compare_gap (gconstpointer p1,
|
||||
gconstpointer p2,
|
||||
|
@@ -32,31 +32,38 @@ _gtk_size_request_cache_init (SizeRequestCache *cache)
|
||||
}
|
||||
|
||||
static void
|
||||
free_sizes (SizeRequest **sizes)
|
||||
free_sizes_x (SizeRequestX **sizes)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
|
||||
g_slice_free (SizeRequest, sizes[i]);
|
||||
|
||||
g_slice_free1 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
||||
g_slice_free (SizeRequestX, sizes[i]);
|
||||
|
||||
g_slice_free1 (sizeof (SizeRequestY *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
||||
}
|
||||
|
||||
static void
|
||||
free_sizes_y (SizeRequestY **sizes)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
|
||||
g_slice_free (SizeRequestY, sizes[i]);
|
||||
|
||||
g_slice_free1 (sizeof (SizeRequestY *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_size_request_cache_free (SizeRequestCache *cache)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (cache->requests[i])
|
||||
free_sizes (cache->requests[i]);
|
||||
}
|
||||
if (cache->requests_x)
|
||||
free_sizes_x (cache->requests_x);
|
||||
if (cache->requests_x)
|
||||
free_sizes_y (cache->requests_y);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_size_request_cache_clear (SizeRequestCache *cache)
|
||||
|
||||
{
|
||||
_gtk_size_request_cache_free (cache);
|
||||
_gtk_size_request_cache_init (cache);
|
||||
@@ -67,17 +74,34 @@ _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;
|
||||
guint i, n_sizes;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
g_assert (minimum_baseline == -1);
|
||||
g_assert (natural_baseline == -1);
|
||||
}
|
||||
|
||||
/* First handle caching of the base requests */
|
||||
if (for_size < 0)
|
||||
{
|
||||
cache->cached_size[orientation].minimum_size = minimum_size;
|
||||
cache->cached_size[orientation].natural_size = natural_size;
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
cache->cached_size_x.minimum_size = minimum_size;
|
||||
cache->cached_size_x.natural_size = natural_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache->cached_size_y.minimum_size = minimum_size;
|
||||
cache->cached_size_y.natural_size = natural_size;
|
||||
cache->cached_size_y.minimum_baseline = minimum_baseline;
|
||||
cache->cached_size_y.natural_baseline = natural_baseline;
|
||||
}
|
||||
|
||||
cache->flags[orientation].cached_size_valid = TRUE;
|
||||
return;
|
||||
}
|
||||
@@ -86,45 +110,99 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
||||
* in the cache and if this result can be used to extend
|
||||
* that cache entry
|
||||
*/
|
||||
cached_sizes = cache->requests[orientation];
|
||||
n_sizes = cache->flags[orientation].n_cached_requests;
|
||||
|
||||
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]->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);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not found, pull a new size from the cache, the returned size cache
|
||||
* will immediately be used to cache the new computed size so we go ahead
|
||||
* and increment the last_cached_request right away */
|
||||
if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
cache->flags[orientation].n_cached_requests++;
|
||||
cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
|
||||
SizeRequestX **cached_sizes;
|
||||
SizeRequestX *cached_size;
|
||||
cached_sizes = cache->requests_x;
|
||||
|
||||
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]->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);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not found, pull a new size from the cache, the returned size cache
|
||||
* will immediately be used to cache the new computed size so we go ahead
|
||||
* and increment the last_cached_request right away */
|
||||
if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
{
|
||||
cache->flags[orientation].n_cached_requests++;
|
||||
cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
cache->flags[orientation].last_cached_request = 0;
|
||||
}
|
||||
|
||||
if (cache->requests_x == NULL)
|
||||
cache->requests_x = g_slice_alloc0 (sizeof (SizeRequestX *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||
|
||||
if (cache->requests_x[cache->flags[orientation].last_cached_request] == NULL)
|
||||
cache->requests_x[cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequestX);
|
||||
|
||||
cached_size = cache->requests_x[cache->flags[orientation].last_cached_request];
|
||||
cached_size->lower_for_size = for_size;
|
||||
cached_size->upper_for_size = for_size;
|
||||
cached_size->cached_size.minimum_size = minimum_size;
|
||||
cached_size->cached_size.natural_size = natural_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
cache->flags[orientation].last_cached_request = 0;
|
||||
SizeRequestY **cached_sizes;
|
||||
SizeRequestY *cached_size;
|
||||
cached_sizes = cache->requests_y;
|
||||
|
||||
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.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);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not found, pull a new size from the cache, the returned size cache
|
||||
* will immediately be used to cache the new computed size so we go ahead
|
||||
* and increment the last_cached_request right away */
|
||||
if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
{
|
||||
cache->flags[orientation].n_cached_requests++;
|
||||
cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
cache->flags[orientation].last_cached_request = 0;
|
||||
}
|
||||
|
||||
if (cache->requests_y == NULL)
|
||||
cache->requests_y = g_slice_alloc0 (sizeof (SizeRequestY *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||
|
||||
if (cache->requests_y[cache->flags[orientation].last_cached_request] == NULL)
|
||||
cache->requests_y[cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequestY);
|
||||
|
||||
cached_size = cache->requests_y[cache->flags[orientation].last_cached_request];
|
||||
cached_size->lower_for_size = for_size;
|
||||
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;
|
||||
}
|
||||
|
||||
if (cache->requests[orientation] == NULL)
|
||||
cache->requests[orientation] = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||
|
||||
if (cache->requests[orientation][cache->flags[orientation].last_cached_request] == NULL)
|
||||
cache->requests[orientation][cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequest);
|
||||
|
||||
cached_size = cache->requests[orientation][cache->flags[orientation].last_cached_request];
|
||||
cached_size->lower_for_size = for_size;
|
||||
cached_size->upper_for_size = for_size;
|
||||
cached_size->cached_size.minimum_size = minimum_size;
|
||||
cached_size->cached_size.natural_size = natural_size;
|
||||
}
|
||||
|
||||
/* looks for a cached size request for this for_size.
|
||||
@@ -137,40 +215,85 @@ _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;
|
||||
|
||||
if (for_size < 0)
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
if (cache->flags[orientation].cached_size_valid)
|
||||
result = &cache->cached_size[orientation];
|
||||
CachedSizeX *result = NULL;
|
||||
|
||||
if (for_size < 0)
|
||||
{
|
||||
if (cache->flags[orientation].cached_size_valid)
|
||||
result = &cache->cached_size_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
|
||||
/* Search for an already cached size */
|
||||
for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
|
||||
{
|
||||
SizeRequestX *cur = cache->requests_x[i];
|
||||
|
||||
if (cur->lower_for_size <= for_size &&
|
||||
cur->upper_for_size >= for_size)
|
||||
{
|
||||
result = &cur->cached_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
*minimum = result->minimum_size;
|
||||
*natural = result->natural_size;
|
||||
*minimum_baseline = -1;
|
||||
*natural_baseline = -1;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
CachedSizeY *result = NULL;
|
||||
|
||||
/* Search for an already cached size */
|
||||
for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
|
||||
{
|
||||
SizeRequest *cur = cache->requests[orientation][i];
|
||||
if (for_size < 0)
|
||||
{
|
||||
if (cache->flags[orientation].cached_size_valid)
|
||||
result = &cache->cached_size_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (cur->lower_for_size <= for_size &&
|
||||
cur->upper_for_size >= for_size)
|
||||
{
|
||||
result = &cur->cached_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Search for an already cached size */
|
||||
for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
|
||||
{
|
||||
SizeRequestY *cur = cache->requests_y[i];
|
||||
|
||||
if (cur->lower_for_size <= for_size &&
|
||||
cur->upper_for_size >= for_size)
|
||||
{
|
||||
result = &cur->cached_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
*minimum = result->minimum_size;
|
||||
*natural = result->natural_size;
|
||||
*minimum_baseline = result->minimum_baseline;
|
||||
*natural_baseline = result->natural_baseline;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
*minimum = result->minimum_size;
|
||||
*natural = result->natural_size;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@@ -41,19 +41,35 @@ G_BEGIN_DECLS
|
||||
typedef struct {
|
||||
gint minimum_size;
|
||||
gint natural_size;
|
||||
} CachedSize;
|
||||
} CachedSizeX;
|
||||
|
||||
typedef struct {
|
||||
gint minimum_size;
|
||||
gint natural_size;
|
||||
gint minimum_baseline;
|
||||
gint natural_baseline;
|
||||
} CachedSizeY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint lower_for_size; /* The minimum for_size with the same result */
|
||||
gint upper_for_size; /* The maximum for_size with the same result */
|
||||
CachedSize cached_size;
|
||||
} SizeRequest;
|
||||
CachedSizeX cached_size;
|
||||
} SizeRequestX;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint lower_for_size; /* The minimum for_size with the same result */
|
||||
gint upper_for_size; /* The maximum for_size with the same result */
|
||||
CachedSizeY cached_size;
|
||||
} SizeRequestY;
|
||||
|
||||
typedef struct {
|
||||
SizeRequest **requests[2];
|
||||
SizeRequestX **requests_x;
|
||||
SizeRequestY **requests_y;
|
||||
|
||||
CachedSize cached_size[2];
|
||||
CachedSizeX cached_size_x;
|
||||
CachedSizeY cached_size_y;
|
||||
|
||||
GtkSizeRequestMode request_mode : 3;
|
||||
guint request_mode_valid : 1;
|
||||
@@ -72,12 +88,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
|
||||
|
||||
|
@@ -222,6 +222,12 @@ static void gtk_spin_button_get_preferred_width (GtkWidget *widget,
|
||||
static void gtk_spin_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gtk_spin_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
static void gtk_spin_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gint gtk_spin_button_draw (GtkWidget *widget,
|
||||
@@ -309,6 +315,7 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
|
||||
widget_class->unrealize = gtk_spin_button_unrealize;
|
||||
widget_class->get_preferred_width = gtk_spin_button_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_spin_button_get_preferred_height;
|
||||
widget_class->get_preferred_height_and_baseline_for_width = gtk_spin_button_get_preferred_height_and_baseline_for_width;
|
||||
widget_class->size_allocate = gtk_spin_button_size_allocate;
|
||||
widget_class->draw = gtk_spin_button_draw;
|
||||
widget_class->scroll_event = gtk_spin_button_scroll;
|
||||
@@ -1197,14 +1204,20 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_spin_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkSpinButton *spin_button = GTK_SPIN_BUTTON (widget);
|
||||
GtkSpinButtonPrivate *priv = spin_button->priv;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_spin_button_parent_class)->get_preferred_height (widget, minimum, natural);
|
||||
GTK_WIDGET_CLASS (gtk_spin_button_parent_class)->get_preferred_height_and_baseline_for_width (widget, width,
|
||||
minimum, natural,
|
||||
minimum_baseline,
|
||||
natural_baseline);
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
|
||||
{
|
||||
@@ -1216,9 +1229,22 @@ gtk_spin_button_get_preferred_height (GtkWidget *widget,
|
||||
|
||||
*minimum += up_panel_height + down_panel_height;
|
||||
*natural += up_panel_height + down_panel_height;
|
||||
|
||||
if (minimum_baseline && *minimum_baseline != -1)
|
||||
*minimum_baseline += up_panel_height;
|
||||
if (natural_baseline && *natural_baseline != -1)
|
||||
*natural_baseline += up_panel_height;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_spin_button_get_preferred_height_and_baseline_for_width (widget, -1, minimum, natural, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
|
239
gtk/gtkwidget.c
239
gtk/gtkwidget.c
@@ -95,6 +95,7 @@
|
||||
* <listitem>#GtkWidgetClass.get_preferred_height()</listitem>
|
||||
* <listitem>#GtkWidgetClass.get_preferred_height_for_width()</listitem>
|
||||
* <listitem>#GtkWidgetClass.get_preferred_width_for_height()</listitem>
|
||||
* <listitem>#GtkWidgetClass.get_preferred_height_and_baseline_for_width()</listitem>
|
||||
* </itemizedlist>
|
||||
*
|
||||
* There are some important things to keep in mind when implementing
|
||||
@@ -222,6 +223,26 @@
|
||||
* container, you <emphasis>must</emphasis> use the wrapper APIs.
|
||||
* Otherwise, you would not properly consider widget margins,
|
||||
* #GtkSizeGroup, and so forth.
|
||||
*
|
||||
* Since 3.10 Gtk+ also supports baseline vertical alignment of widgets. This
|
||||
* means that widgets are positioned such that the typographical baseline of
|
||||
* widgets in the same row are aligned. This happens if a widget supports baselines,
|
||||
* has a vertical alignment of %GTK_ALIGN_BASELINE, and is inside a container
|
||||
* that supports baselines and has a natural "row" that it aligns to the baseline,
|
||||
* or a baseline assigned to it by the grandparent.
|
||||
*
|
||||
* Baseline alignment support for a widget is done by the #GtkWidgetClass.get_preferred_height_and_baseline_for_width()
|
||||
* virtual function. It allows you to report a baseline in combination with the
|
||||
* minimum and natural height. If there is no baseline you can return -1 to indicate
|
||||
* this. The default implementation of this virtual function calls into the
|
||||
* #GtkWidgetClass.get_preferred_height() and #GtkWidgetClass.get_preferred_height_for_width(),
|
||||
* so if baselines are not supported it doesn't need to be implemented.
|
||||
*
|
||||
* If a widget ends up baseline aligned it will be allocated all the space in the parent
|
||||
* as if it was %GTK_ALIGN_FILL, but the selected baseline can be found via gtk_widget_get_allocated_baseline().
|
||||
* If this has a value other than -1 you need to align the widget such that the baseline
|
||||
* appears at the position.
|
||||
*
|
||||
* </para>
|
||||
* </refsect2>
|
||||
* <refsect2 id="style-properties">
|
||||
@@ -395,6 +416,7 @@ struct _GtkWidgetPrivate
|
||||
|
||||
/* The widget's allocated size */
|
||||
GtkAllocation allocation;
|
||||
gint allocated_baseline;
|
||||
|
||||
/* The widget's requested sizes */
|
||||
SizeRequestCache requests;
|
||||
@@ -689,6 +711,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);
|
||||
|
||||
@@ -697,12 +725,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,
|
||||
@@ -984,6 +1017,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;
|
||||
@@ -1043,7 +1077,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,
|
||||
@@ -5189,22 +5225,31 @@ gtk_widget_invalidate_widget_windows (GtkWidget *widget,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_size_allocate:
|
||||
* gtk_widget_size_allocate_with_baseline:
|
||||
* @widget: a #GtkWidget
|
||||
* @allocation: position and size to be allocated to @widget
|
||||
* @baseline: The baseline of the child, or -1
|
||||
*
|
||||
* This function is only used by #GtkContainer subclasses, to assign a size
|
||||
* and position to their child widgets.
|
||||
* This function is only used by #GtkContainer subclasses, to assign a size,
|
||||
* position and (optionally) baseline 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.
|
||||
* In this function, the allocation and baseline may be adjusted. It
|
||||
* will be forced to a 1x1 minimum size, and the
|
||||
* adjust_size_allocation virtual and adjust_baseline_allocation
|
||||
* methods on the child will be used to adjust the allocation and
|
||||
* baseline. Standard adjustments include removing the widget's
|
||||
* margins, and applying the widget's #GtkWidget:halign and
|
||||
* #GtkWidget:valign properties.
|
||||
*
|
||||
* If the child widget does not have a valign of %GTK_ALIGN_BASELINE the
|
||||
* baseline argument is ignored and -1 is used instead.
|
||||
*
|
||||
* Since: 3.10
|
||||
**/
|
||||
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;
|
||||
@@ -5212,9 +5257,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;
|
||||
|
||||
@@ -5241,17 +5288,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;
|
||||
@@ -5301,6 +5358,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 ||
|
||||
@@ -5330,14 +5390,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 */
|
||||
@@ -5356,7 +5418,7 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
cairo_region_destroy (invalidate);
|
||||
}
|
||||
|
||||
if (size_changed)
|
||||
if (size_changed || baseline_changed)
|
||||
{
|
||||
if (priv->redraw_on_alloc)
|
||||
{
|
||||
@@ -5371,7 +5433,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);
|
||||
@@ -5383,6 +5445,31 @@ 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.
|
||||
*
|
||||
* For baseline support in containers you need to use gtk_widget_size_allocate_with_baseline()
|
||||
* instead.
|
||||
**/
|
||||
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
|
||||
@@ -5604,6 +5691,7 @@ adjust_for_align (GtkAlign align,
|
||||
{
|
||||
switch (align)
|
||||
{
|
||||
case GTK_ALIGN_BASELINE:
|
||||
case GTK_ALIGN_FILL:
|
||||
/* change nothing */
|
||||
break;
|
||||
@@ -5674,6 +5762,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)
|
||||
@@ -6166,6 +6266,26 @@ _gtk_widget_draw_internal (GtkWidget *widget,
|
||||
0, cr,
|
||||
&result);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_BASELINES))
|
||||
{
|
||||
gint baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
gint width = gtk_widget_get_allocated_width (widget);
|
||||
|
||||
if (baseline != -1)
|
||||
{
|
||||
cairo_save (cr);
|
||||
cairo_new_path (cr);
|
||||
cairo_move_to (cr, 0, baseline+0.5);
|
||||
cairo_line_to (cr, width, baseline+0.5);
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
cairo_set_source_rgba (cr, 1.0, 0, 0, 0.25);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cairo_status (cr) &&
|
||||
_gtk_cairo_get_event (cr))
|
||||
{
|
||||
@@ -11015,6 +11135,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:
|
||||
*
|
||||
@@ -13165,6 +13307,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
|
||||
@@ -13206,19 +13367,44 @@ gtk_widget_set_halign (GtkWidget *widget,
|
||||
g_object_notify (G_OBJECT (widget), "halign");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_valign_with_baseline:
|
||||
* @widget: a #GtkWidget
|
||||
*
|
||||
* Gets the value of the #GtkWidget:valign property, including
|
||||
* %GTK_ALIGN_BASELINE.
|
||||
*
|
||||
* Returns: the vertical alignment of @widget
|
||||
*/
|
||||
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
|
||||
*
|
||||
* Gets the value of the #GtkWidget:valign property.
|
||||
*
|
||||
* Returns: the vertical alignment of @widget
|
||||
* For backwards compatibility reasons this method will never return
|
||||
* %GTK_ALIGN_BASELINE, but instead it will convert it to
|
||||
* %GTK_ALIGN_FILL. If your widget want to support baseline aligned
|
||||
* children it must use gtk_widget_get_valign_with_baseline().
|
||||
*
|
||||
* Returns: the vertical alignment of @widget, ignoring baseline alignment
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13995,6 +14181,25 @@ gtk_widget_get_allocated_height (GtkWidget *widget)
|
||||
return widget->priv->allocation.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_allocated_baseline:
|
||||
* @widget: the widget to query
|
||||
*
|
||||
* Returns the baseline that has currently been allocated to @widget.
|
||||
* This function is intended to be used when implementing handlers
|
||||
* for the #GtkWidget::draw function, and when allocating child
|
||||
* widgets in #GtkWidget::size_allocate.
|
||||
*
|
||||
* Returns: the baseline of the @widget, or -1 if none
|
||||
**/
|
||||
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,10 @@ void gtk_widget_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition);
|
||||
void gtk_widget_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
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,9 +527,22 @@ void gtk_widget_get_preferred_width_for_height (GtkWidget *w
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
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);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gtk_widget_get_preferred_size_and_baseline (GtkWidget *widget,
|
||||
GtkRequisition *minimum_size,
|
||||
GtkRequisition *natural_size,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
GDK_DEPRECATED_IN_3_0_FOR(gtk_widget_get_preferred_size)
|
||||
void gtk_widget_get_child_requisition (GtkWidget *widget,
|
||||
@@ -659,6 +685,8 @@ void gtk_widget_unregister_window (GtkWidget *widget,
|
||||
|
||||
int gtk_widget_get_allocated_width (GtkWidget *widget);
|
||||
int gtk_widget_get_allocated_height (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
int gtk_widget_get_allocated_baseline (GtkWidget *widget);
|
||||
|
||||
void gtk_widget_get_allocation (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
@@ -756,6 +784,8 @@ GtkAlign gtk_widget_get_halign (GtkWidget *widget);
|
||||
void gtk_widget_set_halign (GtkWidget *widget,
|
||||
GtkAlign align);
|
||||
GtkAlign gtk_widget_get_valign (GtkWidget *widget);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
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 \
|
||||
@@ -165,6 +166,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)
|
||||
@@ -356,6 +358,9 @@ testmerge_SOURCES = \
|
||||
testactions_SOURCES = \
|
||||
testactions.c
|
||||
|
||||
testbaseline_SOURCES = \
|
||||
testbaseline.c
|
||||
|
||||
testbbox_SOURCES = \
|
||||
testbbox.c
|
||||
|
||||
|
382
tests/testbaseline.c
Normal file
382
tests/testbaseline.c
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
static char *baseline_pos_str[] = {
|
||||
"BASELINE_POSITION_TOP",
|
||||
"BASELINE_POSITION_CENTER",
|
||||
"BASELINE_POSITION_BOTTOM"
|
||||
};
|
||||
|
||||
static void
|
||||
baseline_row_value_changed (GtkSpinButton *spin_button,
|
||||
GtkGrid *grid)
|
||||
{
|
||||
gint row = gtk_spin_button_get_value_as_int (spin_button);
|
||||
|
||||
gtk_grid_set_baseline_row (grid, row);
|
||||
}
|
||||
|
||||
static void
|
||||
homogeneous_changed (GtkToggleButton *toggle_button,
|
||||
GtkGrid *grid)
|
||||
{
|
||||
gtk_grid_set_row_homogeneous (grid, gtk_toggle_button_get_active (toggle_button));
|
||||
}
|
||||
|
||||
static void
|
||||
baseline_position_changed (GtkComboBox *combo,
|
||||
GtkBox *hbox)
|
||||
{
|
||||
int i = gtk_combo_box_get_active (combo);
|
||||
|
||||
gtk_box_set_baseline_position (hbox, i);
|
||||
}
|
||||
|
||||
static void
|
||||
image_size_value_changed (GtkSpinButton *spin_button,
|
||||
GtkImage *image)
|
||||
{
|
||||
gint size = gtk_spin_button_get_value_as_int (spin_button);
|
||||
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
GtkWidget *window, *label, *entry, *button, *grid, *notebook;
|
||||
GtkWidget *vbox, *hbox, *grid_hbox, *spin, *spin2, *toggle, *combo, *image, *ebox;
|
||||
PangoFontDescription *font;
|
||||
GtkAdjustment *adjustment;
|
||||
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);
|
||||
|
||||
notebook = gtk_notebook_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), notebook);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
vbox, gtk_label_new ("hboxes"));
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
|
||||
|
||||
char *aligns_names[] = { "FILL", "BASELINE" };
|
||||
GtkAlign aligns[] = { GTK_ALIGN_FILL, GTK_ALIGN_BASELINE};
|
||||
|
||||
label = gtk_label_new (aligns_names[j]);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
label = gtk_label_new ("│XYyj,Ö...");
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 5*(i+1)* 1024);
|
||||
gtk_widget_override_font (label, font);
|
||||
|
||||
gtk_widget_set_valign (label, aligns[j]);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
entry = gtk_entry_new ();
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), "│XYyj,Ö...");
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 5*(i+1)* 1024);
|
||||
gtk_widget_override_font (entry, font);
|
||||
|
||||
gtk_widget_set_valign (entry, aligns[j]);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
}
|
||||
|
||||
spin = gtk_spin_button_new (NULL, 0, 1);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (spin), GTK_ORIENTATION_VERTICAL);
|
||||
gtk_widget_set_valign (spin, aligns[j]);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), spin);
|
||||
}
|
||||
|
||||
grid_hbox = hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), baseline_pos_str[0]);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), baseline_pos_str[1]);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), baseline_pos_str[2]);
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 1);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), combo);
|
||||
|
||||
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);
|
||||
|
||||
g_signal_connect (G_OBJECT (combo), "changed",
|
||||
G_CALLBACK (baseline_position_changed), hbox);
|
||||
|
||||
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, 5*(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, 5*(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);
|
||||
}
|
||||
|
||||
ebox = gtk_event_box_new ();
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (ebox, GTK_ALIGN_BASELINE);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), ebox);
|
||||
|
||||
image = gtk_image_new_from_icon_name ("face-sad", GTK_ICON_SIZE_BUTTON);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 34);
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_BASELINE);
|
||||
gtk_container_add (GTK_CONTAINER (ebox), image);
|
||||
|
||||
button = gtk_toggle_button_new_with_label ("│Xyj,Ö");
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
|
||||
button = gtk_toggle_button_new_with_label ("│Xyj,Ö");
|
||||
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), TRUE);
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
|
||||
button = gtk_check_button_new_with_label ("│Xyj,Ö");
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
|
||||
button = gtk_radio_button_new_with_label (NULL, "│Xyj,Ö");
|
||||
if (j == 0)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
}
|
||||
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
vbox, gtk_label_new ("grid"));
|
||||
|
||||
grid_hbox = hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
|
||||
|
||||
label = gtk_label_new ("Align me:");
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_valign (grid, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 8);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 8);
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
char *labels[] = { "Normal:", "Baseline (top):", "Baseline (center):", "Baseline (bottom):"};
|
||||
label = gtk_label_new (labels[j]);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
label,
|
||||
0, j,
|
||||
1, 1);
|
||||
gtk_widget_set_vexpand (label, TRUE);
|
||||
|
||||
if (j != 0)
|
||||
gtk_grid_set_row_baseline_position (GTK_GRID (grid),
|
||||
j, (GtkBaselinePosition)(j-1));
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
label = gtk_label_new ("Xyjg,Ö.");
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 5*(i+1)* 1024);
|
||||
gtk_widget_override_font (label, font);
|
||||
|
||||
if (j != 0)
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
label,
|
||||
i+1, j,
|
||||
1, 1);
|
||||
}
|
||||
|
||||
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, 5*(i+1)* 1024);
|
||||
gtk_widget_override_font (button, font);
|
||||
|
||||
if (j != 0)
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
button,
|
||||
i+4, j,
|
||||
1, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (hbox), grid);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
|
||||
|
||||
adjustment = gtk_adjustment_new (0.0, -1.0, 5.0, 1.0, 1.0, 0.0);
|
||||
spin = gtk_spin_button_new (adjustment, 1.0, 0);
|
||||
g_signal_connect (spin, "value-changed", (GCallback)baseline_row_value_changed, grid);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), spin);
|
||||
|
||||
toggle = gtk_toggle_button_new_with_label ("Homogeneous");
|
||||
g_signal_connect (toggle, "toggled", (GCallback)homogeneous_changed, grid);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), toggle);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), baseline_pos_str[0]);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), baseline_pos_str[1]);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), baseline_pos_str[2]);
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 1);
|
||||
g_signal_connect (G_OBJECT (combo), "changed",
|
||||
G_CALLBACK (baseline_position_changed), grid_hbox);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), combo);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
vbox, gtk_label_new ("button box"));
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
|
||||
|
||||
adjustment = gtk_adjustment_new (34.0, 1.0, 64.0, 1.0, 1.0, 0.0);
|
||||
spin = gtk_spin_button_new (adjustment, 1.0, 0);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), spin);
|
||||
|
||||
adjustment = gtk_adjustment_new (16.0, 1.0, 64.0, 1.0, 1.0, 0.0);
|
||||
spin2 = gtk_spin_button_new (adjustment, 1.0, 0);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), spin2);
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
|
||||
|
||||
gtk_box_set_baseline_position (GTK_BOX (hbox), j);
|
||||
|
||||
label = gtk_label_new (baseline_pos_str[j]);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
gtk_widget_set_vexpand (label, TRUE);
|
||||
|
||||
image = gtk_image_new_from_icon_name ("face-sad", GTK_ICON_SIZE_BUTTON);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 34);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
|
||||
g_signal_connect (spin, "value-changed", (GCallback)image_size_value_changed, image);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
button = gtk_button_new_with_label ("│Xyj,Ö");
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 5*(i+1)* 1024);
|
||||
gtk_widget_override_font (button, font);
|
||||
|
||||
if (i != 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,Ö");
|
||||
|
||||
image = gtk_image_new_from_icon_name ("face-sad", GTK_ICON_SIZE_BUTTON);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 16);
|
||||
gtk_button_set_image (GTK_BUTTON (button), image);
|
||||
if (i == 0)
|
||||
g_signal_connect (spin2, "value-changed", (GCallback)image_size_value_changed, image);
|
||||
gtk_button_set_always_show_image (GTK_BUTTON (button), TRUE);
|
||||
|
||||
font = pango_font_description_new ();
|
||||
pango_font_description_set_size (font, 5*(i+1)* 1024);
|
||||
gtk_widget_override_font (button, font);
|
||||
|
||||
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