Mega commit to change ->get_desired_size() for ->get_desired_width/height().

This commit changes gtk_extended_layout_get_desired_size() for
per dimension variants. Furthermore this commit reverts the actions
done in size-groups for now as it needs a different approach.

The natural width/height parameters added to aux_info have been changed
for a per width cache for heights and a per height cache for widths.

gtk-demo is still working, currently sizegroups are not taken
into account as mentioned above - size groups need to be alerted both
when the widths and heights are updated independantly and then that
information needs to repropagate also to other extended layout implementors.
This commit is contained in:
Tristan Van Berkom 2010-04-12 22:21:46 -04:00
parent 1b2be80f10
commit d2c35ec62a
27 changed files with 1578 additions and 811 deletions

View File

@ -719,7 +719,8 @@ gtk_cell_renderer_toggle_set_radio
#ifndef GTK_DISABLE_DEPRECATED
gtk_cell_view_get_cell_renderers
#endif
gtk_cell_view_get_desired_size_of_row
gtk_cell_view_get_desired_height_of_row
gtk_cell_view_get_desired_width_of_row
gtk_cell_view_get_displayed_row
gtk_cell_view_get_model
gtk_cell_view_get_size_of_row
@ -1507,14 +1508,18 @@ gtk_expander_set_use_underline
#if IN_HEADER(__GTK_EXTENDED_CELL_H__)
#if IN_FILE(__GTK_EXTENDED_CELL_C__)
gtk_extended_cell_get_type G_GNUC_CONST
gtk_extended_cell_get_desired_size
gtk_extended_cell_get_desired_height
gtk_extended_cell_get_desired_width
gtk_extended_cell_get_height_for_width
gtk_extended_cell_get_width_for_height
#endif
#endif
#if IN_HEADER(__GTK_EXTENDED_LAYOUT_H__)
#if IN_FILE(__GTK_EXTENDED_LAYOUT_C__)
gtk_extended_layout_get_type G_GNUC_CONST
gtk_extended_layout_get_desired_size
gtk_extended_layout_get_desired_height
gtk_extended_layout_get_desired_width
gtk_extended_layout_get_height_for_width
gtk_extended_layout_get_width_for_height
gtk_extended_layout_is_height_for_width

View File

@ -66,10 +66,13 @@ static void gtk_alignment_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_alignment_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
static void gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_alignment_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_alignment_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
G_DEFINE_TYPE_WITH_CODE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN,
G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
@ -484,42 +487,69 @@ gtk_alignment_size_allocate (GtkWidget *widget,
static void
gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_size = gtk_alignment_get_desired_size;
iface->get_desired_width = gtk_alignment_get_desired_width;
iface->get_desired_height = gtk_alignment_get_desired_height;
}
static void
gtk_alignment_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkWidget *child;
GtkAlignmentPrivate *priv;
gint minimum, natural;
priv = GTK_ALIGNMENT_GET_PRIVATE (layout);
minimum_size->width = GTK_CONTAINER (layout)->border_width * 2;
minimum_size->height = GTK_CONTAINER (layout)->border_width * 2;
*natural_size = *minimum_size;
natural = minimum = GTK_CONTAINER (layout)->border_width * 2;
if ((child = gtk_bin_get_child (GTK_BIN (layout))) && gtk_widget_get_visible (child))
{
GtkRequisition child_min, child_nat;
gint child_min, child_nat;
/* Request extra space for the padding: */
minimum_size->width += (priv->padding_left + priv->padding_right);
minimum_size->height += (priv->padding_top + priv->padding_bottom);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
minimum += (priv->padding_left + priv->padding_right);
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child),
&child_min, &child_nat);
}
else
{
minimum += (priv->padding_top + priv->padding_bottom);
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child),
&child_min, &child_nat);
}
*natural_size = *minimum_size;
natural = minimum;
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child),
&child_min, &child_nat);
minimum_size->width += child_min.width;
minimum_size->height += child_min.height;
natural_size->width += child_nat.width;
natural_size->height += child_nat.height;
minimum += child_min;
natural += child_nat;
}
if (minimum_size)
*minimum_size = minimum;
if (natural_size)
*natural_size = natural;
}
static void
gtk_alignment_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_alignment_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_alignment_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_alignment_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}
/**

View File

@ -168,17 +168,16 @@ get_child_padding_delta (GtkBin *bin,
gint *delta_h,
gint *delta_v)
{
GtkRequisition min_req, child_min;
gint hmin, vmin, child_hmin, child_vmin;
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin),
&min_req, NULL);
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (bin), &hmin, NULL);
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (bin), &vmin, NULL);
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin->child),
&child_min, NULL);
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (bin->child), &child_hmin, NULL);
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (bin->child), &child_vmin, NULL);
*delta_h = min_req.width - child_min.width;
*delta_v = min_req.height - child_min.height;
*delta_h = hmin - child_hmin;
*delta_v = vmin - child_vmin;
}
static void
@ -205,7 +204,8 @@ gtk_bin_get_width_for_height (GtkExtendedLayout *layout,
*natural_width = child_nat + hdelta;
}
else
parent_extended_layout_iface->get_height_for_width (layout, height, minimum_width, natural_width);
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, minimum_width, natural_width);
/* parent_extended_layout_iface->get_height_for_width (layout, height, minimum_width, natural_width); */
}
static void
@ -232,7 +232,8 @@ gtk_bin_get_height_for_width (GtkExtendedLayout *layout,
*natural_height = child_nat + vdelta;
}
else
parent_extended_layout_iface->get_height_for_width (layout, width, minimum_height, natural_height);
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, minimum_height, natural_height);
/* parent_extended_layout_iface->get_height_for_width (layout, width, minimum_height, natural_height); */
}

View File

@ -109,19 +109,22 @@ static void gtk_box_get_child_property (GtkContainer *container,
static GType gtk_box_child_type (GtkContainer *container);
static void gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_box_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
static gboolean gtk_box_is_height_for_width (GtkExtendedLayout *layout);
static void gtk_box_get_width_for_height (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
gint *natural_width);
static void gtk_box_get_height_for_width (GtkExtendedLayout *layout,
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface);
static gboolean gtk_box_is_height_for_width (GtkExtendedLayout *layout);
static void gtk_box_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_box_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_box_get_width_for_height (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
gint *natural_width);
static void gtk_box_get_height_for_width (GtkExtendedLayout *layout,
gint width,
gint *minimum_height,
gint *natural_height);
static GtkExtendedLayoutIface *parent_extended_layout_iface;
@ -378,8 +381,22 @@ gtk_box_size_allocate (GtkWidget *widget,
/* Assert the api is working properly */
g_assert (sizes[i].minimum_size >= 0);
g_assert (sizes[i].natural_size >= sizes[i].minimum_size);
if (sizes[i].minimum_size < 0)
g_error ("GtkBox child %s minimum %s: %d < 0 for %s %d",
gtk_widget_get_name (GTK_WIDGET (child->widget)),
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height",
sizes[i].minimum_size,
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width",
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width);
if (sizes[i].natural_size < sizes[i].minimum_size)
g_error ("GtkBox child %s natural %s: %d < minimum %d for %s %d",
gtk_widget_get_name (GTK_WIDGET (child->widget)),
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height",
sizes[i].natural_size,
sizes[i].minimum_size,
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width",
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width);
size -= sizes[i].minimum_size;
size -= child->padding * 2;
@ -749,7 +766,8 @@ gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface)
parent_extended_layout_iface = g_type_interface_peek_parent (iface);
iface->is_height_for_width = gtk_box_is_height_for_width;
iface->get_desired_size = gtk_box_get_desired_size;
iface->get_desired_width = gtk_box_get_desired_width;
iface->get_desired_height = gtk_box_get_desired_height;
iface->get_height_for_width = gtk_box_get_height_for_width;
iface->get_width_for_height = gtk_box_get_width_for_height;
}
@ -763,121 +781,106 @@ gtk_box_is_height_for_width (GtkExtendedLayout *layout)
}
static void
gtk_box_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
gtk_box_get_desired_size (GtkExtendedLayout *layout,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkBox *box;
GtkBoxPrivate *private;
GList *children;
gint nvis_children;
gint border_width;
gint minimum, natural;
box = GTK_BOX (layout);
private = GTK_BOX_GET_PRIVATE (box);
border_width = GTK_CONTAINER (box)->border_width;
minimum_size->width = minimum_size->height = 0;
natural_size->width = natural_size->height = 0;
minimum = natural = 0;
nvis_children = 0;
children = box->children;
while (children)
{
GtkBoxChild *child;
child = children->data;
children = children->next;
for (children = box->children; children; children = children->next)
{
GtkBoxChild *child = children->data;
if (gtk_widget_get_visible (child->widget))
{
GtkRequisition child_minimum_size;
GtkRequisition child_natural_size;
gint child_minimum, child_natural;
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child->widget),
&child_minimum_size,
&child_natural_size);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child->widget),
&child_minimum, &child_natural);
else
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child->widget),
&child_minimum, &child_natural);
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (private->orientation == orientation)
{
if (box->homogeneous)
{
gint width;
gint largest;
width = child_minimum_size.width + child->padding * 2;
minimum_size->width = MAX (minimum_size->width, width);
largest = child_minimum + child->padding * 2;
minimum = MAX (minimum, largest);
width = child_natural_size.width + child->padding * 2;
natural_size->width = MAX (natural_size->width, width);
largest = child_natural + child->padding * 2;
natural = MAX (natural, largest);
}
else
{
minimum_size->width += child_minimum_size.width + child->padding * 2;
natural_size->width += child_natural_size.width + child->padding * 2;
minimum += child_minimum + child->padding * 2;
natural += child_natural + child->padding * 2;
}
minimum_size->height = MAX (minimum_size->height, child_minimum_size.height);
natural_size->height = MAX (natural_size->height, child_natural_size.height);
}
else
{
if (box->homogeneous)
{
gint height;
height = child_minimum_size.height + child->padding * 2;
minimum_size->height = MAX (minimum_size->height, height);
height = child_natural_size.height + child->padding * 2;
natural_size->height = MAX (natural_size->height, height);
}
else
{
minimum_size->height += child_minimum_size.height + child->padding * 2;
natural_size->height += child_natural_size.height + child->padding * 2;
}
minimum_size->width = MAX (minimum_size->width, child_minimum_size.width);
natural_size->width = MAX (natural_size->width, child_natural_size.width);
}
}
else
{
/* The biggest mins and naturals in the opposing orientation */
minimum = MAX (minimum, child_minimum);
natural = MAX (natural, child_natural);
}
nvis_children += 1;
}
}
if (nvis_children > 0)
if (nvis_children > 0 && private->orientation == orientation)
{
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (box->homogeneous)
{
minimum_size->width *= nvis_children;
natural_size->width *= nvis_children;
}
minimum_size->width += (nvis_children - 1) * box->spacing;
natural_size->width += (nvis_children - 1) * box->spacing;
}
else
{
if (box->homogeneous)
{
minimum_size->height *= nvis_children;
natural_size->height *= nvis_children;
}
minimum_size->height += (nvis_children - 1) * box->spacing;
natural_size->height += (nvis_children - 1) * box->spacing;
}
if (box->homogeneous)
{
minimum *= nvis_children;
natural *= nvis_children;
}
minimum += (nvis_children - 1) * box->spacing;
natural += (nvis_children - 1) * box->spacing;
}
minimum_size->width += border_width * 2;
minimum_size->height += border_width * 2;
minimum += border_width * 2;
natural += border_width * 2;
natural_size->width += border_width * 2;
natural_size->height += border_width * 2;
if (minimum_size)
*minimum_size = minimum;
if (natural_size)
*natural_size = natural;
}
static void
gtk_box_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_box_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_box_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_box_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}
/**
* size_fits_for_dimension:
@ -1101,10 +1104,10 @@ gtk_box_get_width_for_height (GtkExtendedLayout *layout,
if (private->orientation == GTK_ORIENTATION_VERTICAL)
{
#if 0
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);
#else
/* Have the base class return the values previously computed by get_desired_size() */
parent_extended_layout_iface->get_width_for_height (layout, height, minimum_width, natural_width);
/* Return the defaults instead of calculating in the opposing direction */
gtk_extended_layout_get_desired_width (layout, minimum_width, natural_width);
#endif
}
else
@ -1125,8 +1128,8 @@ gtk_box_get_height_for_width (GtkExtendedLayout *layout,
#if 0
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height);
#else
/* Have the base class return the values previously computed by get_desired_size() */
parent_extended_layout_iface->get_height_for_width (layout, width, minimum_height, natural_height);
/* Return the defaults instead of calculating in the opposing direction */
gtk_extended_layout_get_desired_height (layout, minimum_height, natural_height);
#endif
}
else

View File

@ -159,9 +159,12 @@ static void gtk_button_set_use_action_appearance (GtkButton *button,
gboolean use_appearance);
static void gtk_button_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_button_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
static void gtk_button_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_button_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static guint button_signals[LAST_SIGNAL] = { 0 };
@ -1769,13 +1772,15 @@ gtk_button_finish_activate (GtkButton *button,
static void
gtk_button_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_size = gtk_button_get_desired_size;
iface->get_desired_width = gtk_button_get_desired_width;
iface->get_desired_height = gtk_button_get_desired_height;
}
static void
gtk_button_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkButton *button = GTK_BUTTON (layout);
GtkWidget *child;
@ -1783,47 +1788,74 @@ gtk_button_get_desired_size (GtkExtendedLayout *layout,
GtkBorder inner_border;
gint focus_width;
gint focus_pad;
gint minimum, natural;
gtk_button_get_props (button, &default_border, NULL, &inner_border, NULL);
gtk_widget_style_get (GTK_WIDGET (layout),
"focus-line-width", &focus_width,
"focus-padding", &focus_pad,
NULL);
minimum_size->width = ((GTK_CONTAINER (layout)->border_width +
GTK_WIDGET (layout)->style->xthickness) * 2 +
inner_border.left + inner_border.right);
minimum_size->height = ((GTK_CONTAINER (layout)->border_width +
GTK_WIDGET (layout)->style->ythickness) * 2 +
inner_border.top + inner_border.bottom);
if (gtk_widget_get_can_default (GTK_WIDGET (layout)))
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
minimum_size->width += default_border.left + default_border.right;
minimum_size->height += default_border.top + default_border.bottom;
minimum = ((GTK_CONTAINER (layout)->border_width +
GTK_WIDGET (layout)->style->xthickness) * 2 +
inner_border.left + inner_border.right);
if (gtk_widget_get_can_default (GTK_WIDGET (layout)))
minimum += default_border.left + default_border.right;
}
else
{
minimum = ((GTK_CONTAINER (layout)->border_width +
GTK_WIDGET (layout)->style->ythickness) * 2 +
inner_border.top + inner_border.bottom);
minimum_size->width += 2 * (focus_width + focus_pad);
minimum_size->height += 2 * (focus_width + focus_pad);
if (gtk_widget_get_can_default (GTK_WIDGET (layout)))
minimum += default_border.top + default_border.bottom;
}
*natural_size = *minimum_size;
minimum += 2 * (focus_width + focus_pad);
natural = minimum;
if ((child = gtk_bin_get_child (GTK_BIN (button))) &&
gtk_widget_get_visible (child))
{
GtkRequisition child_min;
GtkRequisition child_nat;
gint child_min, child_nat;
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child),
&child_min, &child_nat);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child),
&child_min, &child_nat);
else
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child),
&child_min, &child_nat);
minimum_size->width += child_min.width;
minimum_size->height += child_min.height;
natural_size->width += child_nat.width;
natural_size->height += child_nat.height;
minimum += child_min;
natural += child_nat;
}
if (minimum_size)
*minimum_size = minimum;
if (natural_size)
*natural_size = natural;
}
static void
gtk_button_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_button_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}
/**
* gtk_button_set_label:

View File

@ -39,7 +39,27 @@ static void gtk_cell_renderer_set_property (GObject *object,
static void set_cell_bg_color (GtkCellRenderer *cell,
GdkColor *color);
static void gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface);
/* Fallback GtkExtendedCell implementation to use remaining ->get_size() implementations */
static void gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface);
static void gtk_cell_renderer_get_desired_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
static void gtk_cell_renderer_get_desired_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
static void gtk_cell_renderer_get_height_for_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_cell_renderer_get_width_for_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width);
#define GTK_CELL_RENDERER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_RENDERER, GtkCellRendererPrivate))
@ -1036,15 +1056,26 @@ gtk_cell_renderer_stop_editing (GtkCellRenderer *cell,
}
}
static void
gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface)
{
iface->get_desired_width = gtk_cell_renderer_get_desired_width;
iface->get_desired_height = gtk_cell_renderer_get_desired_height;
iface->get_width_for_height = gtk_cell_renderer_get_width_for_height;
iface->get_height_for_width = gtk_cell_renderer_get_height_for_width;
}
static void
gtk_cell_renderer_extended_cell_get_desired_size (GtkExtendedCell *cell,
GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
gtk_cell_renderer_get_desired_size (GtkExtendedCell *cell,
GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkRequisition min_req;
/* Fallback on the old API to get the size. */
if (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size)
gtk_cell_renderer_get_size (GTK_CELL_RENDERER (cell), widget, NULL, NULL, NULL,
&min_req.width, &min_req.height);
@ -1054,24 +1085,67 @@ gtk_cell_renderer_extended_cell_get_desired_size (GtkExtendedCell *cell,
min_req.height = 0;
}
if (minimum_size)
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
minimum_size->width = min_req.width;
minimum_size->height = min_req.height;
}
if (minimum_size)
*minimum_size = min_req.width;
if (natural_size)
if (natural_size)
*natural_size = min_req.width;
}
else
{
natural_size->width = min_req.width;
natural_size->height = min_req.height;
if (minimum_size)
*minimum_size = min_req.height;
if (natural_size)
*natural_size = min_req.height;
}
}
static void
gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface)
gtk_cell_renderer_get_desired_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
iface->get_desired_size = gtk_cell_renderer_extended_cell_get_desired_size;
gtk_cell_renderer_get_desired_size (cell, widget, GTK_ORIENTATION_HORIZONTAL,
minimum_size, natural_size);
}
static void
gtk_cell_renderer_get_desired_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_cell_renderer_get_desired_size (cell, widget, GTK_ORIENTATION_VERTICAL,
minimum_size, natural_size);
}
static void
gtk_cell_renderer_get_height_for_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
{
/* Fall back on the height reported from ->get_size() */
gtk_extended_cell_get_desired_height (cell, widget, minimum_height, natural_height);
}
static void
gtk_cell_renderer_get_width_for_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width)
{
/* Fall back on the width reported from ->get_size() */
gtk_extended_cell_get_desired_width (cell, widget, minimum_width, natural_width);
}
#define __GTK_CELL_RENDERER_C__
#include "gtkaliasdef.c"

View File

@ -62,7 +62,15 @@ static GtkCellEditable *gtk_cell_renderer_text_start_editing (GtkCellRenderer
GdkRectangle *cell_area,
GtkCellRendererState flags);
static void gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface);
static void gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface);
static void gtk_cell_renderer_text_get_desired_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimal_size,
gint *desired_size);
static void gtk_cell_renderer_text_get_desired_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimal_size,
gint *desired_size);
enum {
EDITED,
@ -1936,10 +1944,22 @@ gtk_cell_renderer_text_set_fixed_height_from_font (GtkCellRendererText *renderer
}
static void
gtk_cell_renderer_text_extended_cell_get_desired_size (GtkExtendedCell *cell,
GtkWidget *widget,
GtkRequisition *minimal_size,
GtkRequisition *desired_size)
gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface)
{
/* Currently cell renderers do natural widths for ellipsizing text
* but dont yet do height-for-width/width-for-height calculations for
* wordwrapping
*/
iface->get_desired_width = gtk_cell_renderer_text_get_desired_width;
iface->get_desired_height = gtk_cell_renderer_text_get_desired_height;
}
static void
gtk_cell_renderer_text_get_desired_size (GtkExtendedCell *cell,
GtkWidget *widget,
GtkOrientation orientation,
gint *minimal_size,
gint *desired_size)
{
GtkCellRendererTextPrivate *priv;
@ -1947,9 +1967,14 @@ gtk_cell_renderer_text_extended_cell_get_desired_size (GtkExtendedCell *cell,
if (minimal_size)
{
get_size (GTK_CELL_RENDERER (cell),
widget, NULL, NULL, NULL, NULL,
&minimal_size->width, &minimal_size->height);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
get_size (GTK_CELL_RENDERER (cell),
widget, NULL, NULL, NULL, NULL,
minimal_size, NULL);
else
get_size (GTK_CELL_RENDERER (cell),
widget, NULL, NULL, NULL, NULL,
NULL, minimal_size);
}
if (desired_size)
@ -1959,19 +1984,39 @@ gtk_cell_renderer_text_extended_cell_get_desired_size (GtkExtendedCell *cell,
ellipsize = priv->ellipsize;
priv->ellipsize = PANGO_ELLIPSIZE_NONE;
get_size (GTK_CELL_RENDERER (cell),
widget, NULL, NULL, NULL, NULL,
&desired_size->width, &desired_size->height);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
get_size (GTK_CELL_RENDERER (cell),
widget, NULL, NULL, NULL, NULL,
desired_size, NULL);
else
get_size (GTK_CELL_RENDERER (cell),
widget, NULL, NULL, NULL, NULL,
NULL, desired_size);
priv->ellipsize = ellipsize;
}
}
static void
gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface)
gtk_cell_renderer_text_get_desired_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *desired_size)
{
iface->get_desired_size = gtk_cell_renderer_text_extended_cell_get_desired_size;
gtk_cell_renderer_text_get_desired_size (cell, widget, GTK_ORIENTATION_HORIZONTAL,
minimum_size, desired_size);
}
static void
gtk_cell_renderer_text_get_desired_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *desired_size)
{
gtk_cell_renderer_text_get_desired_size (cell, widget, GTK_ORIENTATION_VERTICAL,
minimum_size, desired_size);
}
#define __GTK_CELL_RENDERER_TEXT_C__
#include "gtkaliasdef.c"

View File

@ -121,10 +121,13 @@ static void gtk_cell_view_buildable_custom_tag_end (GtkBuildable
const gchar *tagname,
gpointer *data);
static void gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_cell_view_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimal_size,
GtkRequisition *natural_size);
static void gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_cell_view_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_cell_view_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static GtkBuildableIface *parent_buildable_iface;
@ -972,7 +975,8 @@ gtk_cell_view_get_displayed_row (GtkCellView *cell_view)
*
* Since: 2.6
*
* Deprecated: 3.0: Use gtk_cell_view_get_desired_size_of_row() instead.
* Deprecated: 3.0: Use gtk_cell_view_get_desired_width_of_row() and
* gtk_cell_view_get_desired_height_of_row() instead.
*/
gboolean
gtk_cell_view_get_size_of_row (GtkCellView *cell_view,
@ -981,51 +985,97 @@ gtk_cell_view_get_size_of_row (GtkCellView *cell_view,
{
GtkRequisition req;
gtk_cell_view_get_desired_size_of_row (cell_view, path, requisition, &req);
g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
gtk_cell_view_get_desired_width_of_row (cell_view, path, &req.width, NULL);
gtk_cell_view_get_desired_height_of_row (cell_view, path, &req.height, NULL);
if (requisition)
*requisition = req;
return TRUE;
}
/**
* gtk_cell_view_get_desired_size_of_row:
* @cell_view: a #GtkCellView
* @path: a #GtkTreePath
* @minimum_size: return location for the minimum requested size
* @natural_size: return location for the desired natural size
*
* Sets @minimum_size and @natural_size to the size desired by @cell_view
* to display the model row pointed to by @path.
*
* Since: 3.0
*/
void
static void
gtk_cell_view_get_desired_size_of_row (GtkCellView *cell_view,
GtkTreePath *path,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkTreeRowReference *tmp;
GtkRequisition req, nat_req;
g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
g_return_if_fail (path != NULL);
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
tmp = cell_view->priv->displayed_row;
cell_view->priv->displayed_row =
gtk_tree_row_reference_new (cell_view->priv->model, path);
gtk_cell_view_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (cell_view),
minimum_size ? minimum_size : &req,
natural_size ? natural_size : &nat_req);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_cell_view_get_desired_width (GTK_EXTENDED_LAYOUT (cell_view), minimum_size, natural_size);
else
gtk_cell_view_get_desired_height (GTK_EXTENDED_LAYOUT (cell_view), minimum_size, natural_size);
gtk_tree_row_reference_free (cell_view->priv->displayed_row);
cell_view->priv->displayed_row = tmp;
/* Restore active size */
gtk_cell_view_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (cell_view),
&req, &nat_req);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_cell_view_get_desired_width (GTK_EXTENDED_LAYOUT (cell_view), NULL, NULL);
else
gtk_cell_view_get_desired_height (GTK_EXTENDED_LAYOUT (cell_view), NULL, NULL);
}
/**
* gtk_cell_view_get_desired_width_of_row:
* @cell_view: a #GtkCellView
* @path: a #GtkTreePath
* @minimum_size: location to store the minimum size
* @natural_size: location to store the natural size
*
* Sets @minimum_size and @natural_size to the width desired by @cell_view
* to display the model row pointed to by @path.
*
* Since: 3.0
*/
void
gtk_cell_view_get_desired_width_of_row (GtkCellView *cell_view,
GtkTreePath *path,
gint *minimum_size,
gint *natural_size)
{
g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
g_return_if_fail (path != NULL);
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
gtk_cell_view_get_desired_size_of_row (cell_view, path, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
/**
* gtk_cell_view_get_desired_height_of_row:
* @cell_view: a #GtkCellView
* @path: a #GtkTreePath
* @minimum_size: location to store the minimum size
* @natural_size: location to store the natural size
*
* Sets @minimum_size and @natural_size to the height desired by @cell_view
* to display the model row pointed to by @path.
*
* Since: 3.0
*/
void
gtk_cell_view_get_desired_height_of_row (GtkCellView *cell_view,
GtkTreePath *path,
gint *minimum_size,
gint *natural_size)
{
g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
g_return_if_fail (path != NULL);
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
gtk_cell_view_get_desired_size_of_row (cell_view, path, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}
/**
@ -1137,20 +1187,27 @@ gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable,
data);
}
static void
gtk_cell_view_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimal_size,
GtkRequisition *natural_size)
gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_width = gtk_cell_view_get_desired_width;
iface->get_desired_height = gtk_cell_view_get_desired_height;
}
static void
gtk_cell_view_get_desired_size (GtkExtendedLayout *layout,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GList *i;
GtkRequisition cell_min, cell_nat;
gint cell_min, cell_nat;
gboolean first_cell = TRUE;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
gint minimum, natural;
minimal_size->width = 0;
minimal_size->height = 0;
natural_size->width = 0;
natural_size->height = 0;
minimum = natural = 0;
if (cellview->priv->displayed_row)
gtk_cell_view_set_cell_data (cellview);
@ -1162,34 +1219,55 @@ gtk_cell_view_extended_layout_get_desired_size (GtkExtendedLayout *layout,
if (info->cell->visible)
{
if (!first_cell)
if (!first_cell && orientation == GTK_ORIENTATION_HORIZONTAL)
{
minimal_size->width += cellview->priv->spacing;
natural_size->width += cellview->priv->spacing;
minimum += cellview->priv->spacing;
natural += cellview->priv->spacing;
}
gtk_extended_cell_get_desired_size (GTK_EXTENDED_CELL (info->cell),
GTK_WIDGET (cellview), &cell_min, &cell_nat);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_extended_cell_get_desired_width (GTK_EXTENDED_CELL (info->cell),
GTK_WIDGET (cellview), &cell_min, &cell_nat);
info->requested_width = cell_min;
info->natural_width = cell_nat;
info->requested_width = cell_min.width;
info->natural_width = cell_nat.width;
minimal_size->width += info->requested_width;
natural_size->width += info->natural_width;
minimal_size->height = MAX (minimal_size->height, cell_min.height);
natural_size->height = MAX (natural_size->height, cell_nat.height);
minimum += info->requested_width;
natural += info->natural_width;
}
else
{
gtk_extended_cell_get_desired_height (GTK_EXTENDED_CELL (info->cell),
GTK_WIDGET (cellview), &cell_min, &cell_nat);
minimum = MAX (minimum, cell_min);
natural = MAX (natural, cell_nat);
}
first_cell = FALSE;
}
}
if (minimum_size)
*minimum_size = minimum;
if (natural_size)
*natural_size = natural;
}
static void
gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface)
gtk_cell_view_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
iface->get_desired_size = gtk_cell_view_extended_layout_get_desired_size;
gtk_cell_view_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_cell_view_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_cell_view_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}

View File

@ -72,10 +72,14 @@ gboolean gtk_cell_view_get_size_of_row (GtkCellView *cell_v
gboolean gtk_cell_view_get_size_of_row (GtkCellView *cell_view,
GtkTreePath *path,
GtkRequisition *requisition);
void gtk_cell_view_get_desired_size_of_row (GtkCellView *cell_view,
void gtk_cell_view_get_desired_width_of_row(GtkCellView *cell_view,
GtkTreePath *path,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
gint *minimum_size,
gint *natural_size);
void gtk_cell_view_get_desired_height_of_row(GtkCellView *cell_view,
GtkTreePath *path,
gint *minimum_size,
gint *natural_size);
void gtk_cell_view_set_background_color (GtkCellView *cell_view,
const GdkColor *color);

View File

@ -467,9 +467,12 @@ static void gtk_combo_box_start_editing (GtkCellEditable *c
GdkEvent *event);
static void gtk_combo_box_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_combo_box_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
static void gtk_combo_box_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_combo_box_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
G_DEFINE_TYPE_WITH_CODE (GtkComboBox, gtk_combo_box, GTK_TYPE_BIN,
@ -5815,12 +5818,11 @@ gtk_combo_box_buildable_custom_tag_end (GtkBuildable *buildable,
}
static void
gtk_combo_box_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_size = gtk_combo_box_get_desired_size;
iface->get_desired_width = gtk_combo_box_get_desired_width;
iface->get_desired_height = gtk_combo_box_get_desired_height;
}
static void
@ -5844,8 +5846,13 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box)
GtkRequisition req, nat_req;
if (priv->cell_view)
gtk_cell_view_get_desired_size_of_row (GTK_CELL_VIEW (priv->cell_view),
path, &req, &nat_req);
{
/* XXX FIXME: Currently still not doing height-for-width in cell renderers here */
gtk_cell_view_get_desired_width_of_row (GTK_CELL_VIEW (priv->cell_view),
path, &req.width, &nat_req.width);
gtk_cell_view_get_desired_height_of_row (GTK_CELL_VIEW (priv->cell_view),
path, &req.height, &nat_req.height);
}
else
{
memset (&req, 0x0, sizeof (GtkRequisition));
@ -5865,6 +5872,11 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box)
gtk_tree_path_free (path);
}
/* XXX TODO: Split this up into 2 orientations so as
* to properly support height-for-width/width-for-height here
*
*/
static void
gtk_combo_box_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
@ -6006,5 +6018,38 @@ gtk_combo_box_get_desired_size (GtkExtendedLayout *layout,
}
}
static void
gtk_combo_box_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
GtkRequisition minimum, natural;
gtk_combo_box_get_desired_size (layout, &minimum, &natural);
if (minimum_size)
*minimum_size = minimum.width;
if (natural_size)
*natural_size = natural.width;
}
static void
gtk_combo_box_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
GtkRequisition minimum, natural;
gtk_combo_box_get_desired_size (layout, &minimum, &natural);
if (minimum_size)
*minimum_size = minimum.height;
if (natural_size)
*natural_size = natural.height;
}
#define __GTK_COMBO_BOX_C__
#include "gtkaliasdef.c"

View File

@ -1370,6 +1370,9 @@ _gtk_container_queue_resize (GtkContainer *container)
{
GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_WIDTH_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED);
if ((resize_container && widget == GTK_WIDGET (resize_container)) ||
!widget->parent)
break;

View File

@ -27,6 +27,9 @@
#include "gtkintl.h"
#include "gtkalias.h"
#define DEBUG_EXTENDED_CELL 0
GType
gtk_extended_cell_get_type (void)
{
@ -45,21 +48,21 @@ gtk_extended_cell_get_type (void)
}
/**
* gtk_extended_cell_get_desired_size:
* gtk_extended_cell_get_desired_width:
* @cell: a #GtkExtendedCell instance
* @widget: the #GtkWidget this cell will be rendering to
* @minimum_size: location for storing the minimum size, or %NULL
* @natural_size: location for storing the preferred size, or %NULL
* @minimum_size: location to store the minimum size, or %NULL
* @natural_size: location to store the natural size, or %NULL
*
* Retreives a renderer's desired size.
* Retreives a renderer's desired size when rendered to @widget.
*
* Since: 3.0
*/
void
gtk_extended_cell_get_desired_size (GtkExtendedCell *cell,
GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
gtk_extended_cell_get_desired_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
GtkExtendedCellIface *iface;
@ -68,7 +71,122 @@ gtk_extended_cell_get_desired_size (GtkExtendedCell *cell,
g_return_if_fail (NULL != minimum_size || NULL != natural_size);
iface = GTK_EXTENDED_CELL_GET_IFACE (cell);
iface->get_desired_size (cell, widget, minimum_size, natural_size);
iface->get_desired_width (cell, widget, minimum_size, natural_size);
#if DEBUG_EXTENDED_CELL
g_message ("%s returning minimum width: %d and natural width: %d",
G_OBJECT_TYPE_NAME (cell),
minimum_size ? *minimum_size : 20000,
natural_size ? *natural_size : 20000);
#endif
}
/**
* gtk_extended_cell_get_desired_height:
* @cell: a #GtkExtendedCell instance
* @widget: the #GtkWidget this cell will be rendering to
* @minimum_size: location to store the minimum size, or %NULL
* @natural_size: location to store the natural size, or %NULL
*
* Retreives a renderer's desired size when rendered to @widget.
*
* Since: 3.0
*/
void
gtk_extended_cell_get_desired_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
GtkExtendedCellIface *iface;
g_return_if_fail (GTK_IS_EXTENDED_CELL (cell));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (NULL != minimum_size || NULL != natural_size);
iface = GTK_EXTENDED_CELL_GET_IFACE (cell);
iface->get_desired_height (cell, widget, minimum_size, natural_size);
#if DEBUG_EXTENDED_CELL
g_message ("%s returning minimum height: %d and natural height: %d",
G_OBJECT_TYPE_NAME (cell),
minimum_size ? *minimum_size : 20000,
natural_size ? *natural_size : 20000);
#endif
}
/**
* gtk_extended_cell_get_width_for_height:
* @cell: a #GtkExtendedCell instance
* @height: the size which is available for allocation
* @minimum_width: location for storing the minimum size, or %NULL
* @natural_width: location for storing the preferred size, or %NULL
*
* Retreives a cell renderers's desired width if it were rendered to
* @widget with the specified @height.
*
* Since: 3.0
*/
void
gtk_extended_cell_get_width_for_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width)
{
GtkExtendedCellIface *iface;
g_return_if_fail (GTK_IS_EXTENDED_CELL (cell));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (NULL != minimum_width || NULL != natural_width);
iface = GTK_EXTENDED_CELL_GET_IFACE (cell);
iface->get_width_for_height (cell, widget, height, minimum_width, natural_width);
#if DEBUG_EXTENDED_CELL
g_message ("%s width for height: %d is minimum %d and natural: %d",
G_OBJECT_TYPE_NAME (cell), height,
minimum_width ? *minimum_width : 20000,
natural_width ? *natural_width : 20000);
#endif
}
/**
* gtk_extended_cell_get_height_for_width:
* @cell: a #GtkExtendedCell instance
* @width: the size which is available for allocation
* @minimum_height: location for storing the minimum size, or %NULL
* @natural_height: location for storing the preferred size, or %NULL
*
* Retreives a cell renderers's desired height if it were rendered to
* @widget with the specified @width.
*
* Since: 3.0
*/
void
gtk_extended_cell_get_height_for_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
{
GtkExtendedCellIface *iface;
g_return_if_fail (GTK_IS_EXTENDED_CELL (cell));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (NULL != minimum_height || NULL != natural_height);
iface = GTK_EXTENDED_CELL_GET_IFACE (cell);
iface->get_height_for_width (cell, widget, width, minimum_height, natural_height);
#if DEBUG_EXTENDED_CELL
g_message ("%s height for width: %d is minimum %d and natural: %d",
G_OBJECT_TYPE_NAME (cell), width,
minimum_height ? *minimum_height : 20000,
natural_height ? *natural_height : 20000);
#endif
}
#define __GTK_EXTENDED_CELL_C__

View File

@ -42,20 +42,46 @@ struct _GtkExtendedCellIface
/* virtual table */
void (*get_desired_size) (GtkExtendedCell *cell,
GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
void (* get_desired_width) (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void (* get_desired_height) (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void (* get_width_for_height) (GtkExtendedCell *cell,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width);
void (* get_height_for_width) (GtkExtendedCell *cell,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
};
GType gtk_extended_cell_get_type (void) G_GNUC_CONST;
void gtk_extended_cell_get_desired_size (GtkExtendedCell *cell,
GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
void gtk_extended_cell_get_desired_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void gtk_extended_cell_get_desired_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
void gtk_extended_cell_get_width_for_height (GtkExtendedCell *cell,
GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width);
void gtk_extended_cell_get_height_for_width (GtkExtendedCell *cell,
GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
G_END_DECLS

View File

@ -24,9 +24,14 @@
#include <config.h>
#include "gtkextendedlayout.h"
#include "gtksizegroup.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "gtkalias.h"
#define DEBUG_EXTENDED_LAYOUT 0
GType
gtk_extended_layout_get_type (void)
{
@ -45,33 +50,41 @@ gtk_extended_layout_get_type (void)
return extended_layout_type;
}
/**
* gtk_extended_layout_get_desired_size:
* @layout: a #GtkExtendedLayout instance
* @minimum_size: location for storing the minimum size, or %NULL
* @natural_size: location for storing the preferred size, or %NULL
*
* Retreives a widget's minimum and natural size and caches the values.
*
* <note><para>This api will consider any restrictions imposed by
* #GtkSizeGroup<!-- -->s or previous calls to gtk_widget_set_size_request().
* </para></note>
*
* Since: 3.0
*/
void
gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
/* looks for a cached size request for this for_size. If not
* found, returns the oldest entry so it can be overwritten */
static gboolean
_gtk_extended_layout_get_cached_desired_size (gfloat for_size,
GtkDesiredSize *cached_sizes,
GtkDesiredSize **result)
{
g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
g_return_if_fail (NULL != minimum_size || NULL != natural_size);
guint i;
_gtk_size_group_compute_desired_size (GTK_WIDGET (layout), minimum_size, natural_size);
*result = &cached_sizes[0];
for (i = 0; i < GTK_N_CACHED_SIZES; i++)
{
GtkDesiredSize *cs;
cs = &cached_sizes[i];
if (cs->age > 0 &&
cs->for_size == for_size)
{
*result = cs;
return TRUE;
}
else if (cs->age < (*result)->age)
{
*result = cs;
}
}
return FALSE;
}
/**
* gtk_extended_layout_is_height_for_width:
* @layout: a #GtkExtendedLayout instance
@ -99,6 +112,147 @@ gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout)
return TRUE;
}
/**
* gtk_extended_layout_get_desired_width:
* @layout: a #GtkExtendedLayout instance
* @minimum_width: location to store the minimum size, or %NULL
* @natural_width: location to store the natural size, or %NULL
*
* Retreives a widget's minimum and natural size in a single dimension.
*
* Since: 3.0
*/
void
gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_width,
gint *natural_width)
{
GtkWidgetAuxInfo *aux_info;
gboolean found_in_cache = FALSE;
GtkDesiredSize *cached_size;
g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
g_return_if_fail (minimum_width != NULL || natural_width != NULL);
aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE);
cached_size = &aux_info->desired_widths[0];
if (GTK_WIDGET_WIDTH_REQUEST_NEEDED (layout) == FALSE)
found_in_cache = _gtk_extended_layout_get_cached_desired_size (-1, aux_info->desired_widths,
&cached_size);
if (!found_in_cache)
{
GtkRequisition requisition;
gint minimum_width = 0, natural_width = 0;
/* Unconditionally envoke size-request and use those return values as
* the base end of our values */
_gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition);
/* Envoke this after, default GtkWidgetClass will simply copy over widget->requisition
*/
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout,
&minimum_width,
&natural_width);
cached_size->minimum_size = MAX (minimum_width, requisition.width);
cached_size->natural_size = MAX (natural_width, requisition.width);
cached_size->for_size = -1;
cached_size->age = aux_info->cached_width_age;
aux_info->cached_width_age ++;
GTK_PRIVATE_UNSET_FLAG (layout, GTK_WIDTH_REQUEST_NEEDED);
}
if (minimum_width)
*minimum_width = cached_size->minimum_size;
if (natural_width)
*natural_width = cached_size->natural_size;
#if DEBUG_EXTENDED_LAYOUT
g_message ("%s returning minimum width: %d and natural width: %d",
G_OBJECT_TYPE_NAME (layout),
cached_size->minimum_size,
cached_size->natural_size);
#endif
}
/**
* gtk_extended_layout_get_desired_height:
* @layout: a #GtkExtendedLayout instance
* @minimum_width: location to store the minimum size, or %NULL
* @natural_width: location to store the natural size, or %NULL
*
* Retreives a widget's minimum and natural size in a single dimension.
*
* Since: 3.0
*/
void
gtk_extended_layout_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_height,
gint *natural_height)
{
GtkWidgetAuxInfo *aux_info;
gboolean found_in_cache = FALSE;
GtkDesiredSize *cached_size;
g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE);
cached_size = &aux_info->desired_heights[0];
if (GTK_WIDGET_HEIGHT_REQUEST_NEEDED (layout) == FALSE)
found_in_cache = _gtk_extended_layout_get_cached_desired_size (-1, aux_info->desired_heights,
&cached_size);
if (!found_in_cache)
{
GtkRequisition requisition;
gint minimum_height = 0, natural_height = 0;
/* Unconditionally envoke size-request and use those return values as
* the base end of our values */
_gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition);
/* Envoke this after, default GtkWidgetClass will simply copy over widget->requisition
*/
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout,
&minimum_height,
&natural_height);
cached_size->minimum_size = MAX (minimum_height, requisition.height);
cached_size->natural_size = MAX (natural_height, requisition.height);
cached_size->for_size = -1;
cached_size->age = aux_info->cached_height_age;
aux_info->cached_height_age ++;
GTK_PRIVATE_UNSET_FLAG (layout, GTK_HEIGHT_REQUEST_NEEDED);
}
if (minimum_height)
*minimum_height = cached_size->minimum_size;
if (natural_height)
*natural_height = cached_size->natural_size;
#if DEBUG_EXTENDED_LAYOUT
g_message ("%s returning minimum height: %d and natural height: %d",
G_OBJECT_TYPE_NAME (layout),
cached_size->minimum_size,
cached_size->natural_size);
#endif
}
/**
@ -106,7 +260,7 @@ gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout)
* @layout: a #GtkExtendedLayout instance
* @height: the size which is available for allocation
* @minimum_size: location for storing the minimum size, or %NULL
* @natural_size: location for storing the preferred size, or %NULL
* @natural_size: location for storing the natural size, or %NULL
*
* Retreives a widget's desired width if it would be given
* the specified @height.
@ -119,20 +273,61 @@ gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout,
gint *minimum_width,
gint *natural_width)
{
GtkExtendedLayoutIface *iface;
GtkWidgetAuxInfo *aux_info;
gboolean found_in_cache = FALSE;
GtkDesiredSize *cached_size;
g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
g_return_if_fail (minimum_width != NULL || natural_width != NULL);
/* XXX Maybe here we do _gtk_size_group_compute_width_for_height()
* and return hard coded minimum widths/heights for for widgets with
* explicit size requests as well as fetch the common minimum/natural
* widths/heights for size grouped widgets.
*/
aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE);
iface = GTK_EXTENDED_LAYOUT_GET_IFACE (layout);
iface->get_width_for_height (layout, height, minimum_width, natural_width);
cached_size = &aux_info->desired_widths[0];
if (GTK_WIDGET_WIDTH_REQUEST_NEEDED (layout) == FALSE)
found_in_cache = _gtk_extended_layout_get_cached_desired_size (height, aux_info->desired_widths,
&cached_size);
if (!found_in_cache)
{
GtkRequisition requisition;
gint minimum_width = 0, natural_width = 0;
/* Unconditionally envoke size-request and use those return values as
* the base end of our values */
_gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition);
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_width_for_height (layout,
height,
&minimum_width,
&natural_width);
cached_size->minimum_size = MAX (minimum_width, requisition.width);
cached_size->natural_size = MAX (natural_width, requisition.width);
cached_size->for_size = height;
cached_size->age = aux_info->cached_width_age;
aux_info->cached_width_age++;
GTK_PRIVATE_UNSET_FLAG (layout, GTK_WIDTH_REQUEST_NEEDED);
}
if (minimum_width)
*minimum_width = cached_size->minimum_size;
if (natural_width)
*natural_width = cached_size->natural_size;
g_assert (!minimum_width || !natural_width || *minimum_width <= *natural_width);
#if DEBUG_EXTENDED_LAYOUT
g_message ("%s width for height: %d is minimum %d and natural: %d",
G_OBJECT_TYPE_NAME (layout), height,
cached_size->minimum_size,
cached_size->natural_size);
#endif
}
/**
@ -140,7 +335,7 @@ gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout,
* @layout: a #GtkExtendedLayout instance
* @width: the size which is available for allocation
* @minimum_size: location for storing the minimum size, or %NULL
* @natural_size: location for storing the preferred size, or %NULL
* @natural_size: location for storing the natural size, or %NULL
*
* Retreives a widget's desired height if it would be given
* the specified @width.
@ -153,15 +348,131 @@ gtk_extended_layout_get_height_for_width (GtkExtendedLayout *layout,
gint *minimum_height,
gint *natural_height)
{
GtkExtendedLayoutIface *iface;
GtkWidgetAuxInfo *aux_info;
gboolean found_in_cache = FALSE;
GtkDesiredSize *cached_size;
g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE);
cached_size = &aux_info->desired_heights[0];
if (GTK_WIDGET_HEIGHT_REQUEST_NEEDED (layout) == FALSE)
found_in_cache = _gtk_extended_layout_get_cached_desired_size (width, aux_info->desired_heights,
&cached_size);
if (!found_in_cache)
{
GtkRequisition requisition;
gint minimum_height = 0, natural_height = 0;
/* Unconditionally envoke size-request and use those return values as
* the base end of our values */
_gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition);
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_height_for_width (layout,
width,
&minimum_height,
&natural_height);
cached_size->minimum_size = MAX (minimum_height, requisition.height);
cached_size->natural_size = MAX (natural_height, requisition.height);
cached_size->for_size = width;
cached_size->age = aux_info->cached_height_age;
aux_info->cached_height_age++;
GTK_PRIVATE_UNSET_FLAG (layout, GTK_HEIGHT_REQUEST_NEEDED);
}
if (minimum_height)
*minimum_height = cached_size->minimum_size;
if (natural_height)
*natural_height = cached_size->natural_size;
g_assert (!minimum_height || !natural_height || *minimum_height <= *natural_height);
#if DEBUG_EXTENDED_LAYOUT
g_message ("%s height for width: %d is minimum %d and natural: %d",
G_OBJECT_TYPE_NAME (layout), width,
cached_size->minimum_size,
cached_size->natural_size);
#endif
}
/**
* gtk_extended_layout_get_desired_size:
* @layout: a #GtkExtendedLayout instance
* @width: the size which is available for allocation
* @minimum_size: location for storing the minimum size, or %NULL
* @natural_size: location for storing the natural size, or %NULL
*
* Retreives the minimum and natural size of a widget taking
* into account the widget's preference for height-for-width management.
*
* This is used to retreive a suitable size by container widgets whom dont
* impose any restrictions on the child placement, examples of these are
* #GtkWindow and #GtkScrolledWindow.
*
* Since: 3.0
*/
void
gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
{
gint min_width, nat_width;
gint min_height, nat_height;
g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
iface = GTK_EXTENDED_LAYOUT_GET_IFACE (layout);
iface->get_height_for_width (layout, width, minimum_height, natural_height);
if (gtk_extended_layout_is_height_for_width (layout))
{
gtk_extended_layout_get_desired_width (layout, &min_width, &nat_width);
gtk_extended_layout_get_height_for_width (layout, nat_width, &min_height, &nat_height);
g_assert (!minimum_height || !natural_height || *minimum_height <= *natural_height);
/* The minimum size here is the minimum height for the natrual width */
if (minimum_size)
{
minimum_size->width = nat_width;
minimum_size->height = min_height;
}
}
else
{
gtk_extended_layout_get_desired_height (layout, &min_height, &nat_height);
gtk_extended_layout_get_height_for_width (layout, nat_height, &min_width, &nat_width);
/* The minimum size here is the minimum width for the natrual height */
if (minimum_size)
{
minimum_size->width = min_width;
minimum_size->height = nat_height;
}
}
if (natural_size)
{
natural_size->width = nat_width;
natural_size->height = nat_height;
}
#if DEBUG_EXTENDED_LAYOUT
g_message ("get_desired_size called on a %s; minimum width: %d natural width: %d minimum height %d natural height %d",
G_OBJECT_TYPE_NAME (layout), min_width, nat_width, min_height, nat_height);
#endif
}
#define __GTK_EXTENDED_LAYOUT_C__
#include "gtkaliasdef.c"

View File

@ -41,15 +41,14 @@ struct _GtkExtendedLayoutIface
GTypeInterface g_iface;
/* virtual table */
/* TODO: Change for get_desired_width()/get_desired_height() for clarity sake */
void (* get_desired_size) (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
gboolean (* is_height_for_width) (GtkExtendedLayout *layout);
void (* get_desired_width) (GtkExtendedLayout *layout,
gint *minimum_width,
gint *natural_width);
void (* get_desired_height) (GtkExtendedLayout *layout,
gint *minimum_height,
gint *natural_height);
void (* get_width_for_height) (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
@ -62,12 +61,13 @@ struct _GtkExtendedLayoutIface
GType gtk_extended_layout_get_type (void) G_GNUC_CONST;
void gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
gboolean gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout);
void gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_width,
gint *natural_width);
void gtk_extended_layout_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_height,
gint *natural_height);
void gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
@ -77,6 +77,10 @@ void gtk_extended_layout_get_height_for_width (GtkExtendedLayout *layout,
gint *minimum_height,
gint *natural_height);
void gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
G_END_DECLS

View File

@ -303,9 +303,12 @@ static void emit_activate_link (GtkLabel *label,
static void gtk_label_layout_interface_init (GtkExtendedLayoutIface *iface);
static void gtk_label_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
static void gtk_label_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_label_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_label_get_width_for_height (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
@ -348,14 +351,6 @@ add_move_binding (GtkBindingSet *binding_set,
G_TYPE_BOOLEAN, TRUE);
}
static void
gtk_label_layout_interface_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_size = gtk_label_get_desired_size;
iface->get_width_for_height = gtk_label_get_width_for_height;
iface->get_height_for_width = gtk_label_get_height_for_width;
}
static void
gtk_label_class_init (GtkLabelClass *class)
{
@ -3198,16 +3193,29 @@ get_single_line_height (GtkWidget *widget,
return PANGO_PIXELS (ascent + descent);
}
static void
gtk_label_layout_interface_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_width = gtk_label_get_desired_width;
iface->get_desired_height = gtk_label_get_desired_height;
iface->get_width_for_height = gtk_label_get_width_for_height;
iface->get_height_for_width = gtk_label_get_height_for_width;
}
static void
gtk_label_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkLabelPrivate *priv = GTK_LABEL_GET_PRIVATE (layout);
GtkLabel *label = GTK_LABEL (layout);
PangoRectangle required_rect;
GtkWidgetAuxInfo *aux_info;
PangoLayout *natural_layout;
gint minimum = 0, natural = 0;
/*
* If word wrapping is on, then the height requisition can depend
@ -3268,9 +3276,10 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
/* XXX TODO: Ideally for wrapping labels, the width should be one char or the length
* of the longest word in the text depending on wrap mode.
*/
minimum_size->width = required_rect.width + label->misc.xpad * 2;
minimum_size->height = required_rect.height + label->misc.ypad * 2;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
minimum = required_rect.width + label->misc.xpad * 2;
else
minimum = required_rect.height + label->misc.ypad * 2;
/* Natural size */
natural_layout = pango_layout_copy (label->layout);
@ -3293,12 +3302,38 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
required_rect.width = PANGO_PIXELS_CEIL (required_rect.width);
required_rect.height = PANGO_PIXELS_CEIL (required_rect.height);
natural_size->width = required_rect.width + label->misc.xpad * 2;
natural_size->height = required_rect.height + label->misc.ypad * 2;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
natural = required_rect.width + label->misc.xpad * 2;
else
natural = required_rect.height + label->misc.ypad * 2;
g_object_unref (natural_layout);
if (minimum_size)
*minimum_size = minimum;
if (natural_size)
*natural_size = natural;
}
static void
gtk_label_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_label_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_label_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_label_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}
static void
get_size_for_allocation (GtkLabel *label,
GtkOrientation orientation,
@ -3351,18 +3386,7 @@ gtk_label_get_width_for_height (GtkExtendedLayout *layout,
if (90 == angle || 270 == angle)
get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL, height, minimum_width, natural_width);
else
{
GtkRequisition minimum_size, natural_size;
gtk_extended_layout_get_desired_size (layout,
minimum_width ? &minimum_size : NULL,
natural_width ? &natural_size : NULL);
if (minimum_width)
*minimum_width = minimum_size.width;
if (natural_width)
*natural_width = natural_size.width;
}
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, minimum_width, natural_width);
}
static void
@ -3377,18 +3401,7 @@ gtk_label_get_height_for_width (GtkExtendedLayout *layout,
if (0 == angle || 180 == angle)
get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL, width, minimum_height, natural_height);
else
{
GtkRequisition minimum_size, natural_size;
gtk_extended_layout_get_desired_size (layout,
minimum_height ? &minimum_size : NULL,
natural_height ? &natural_size : NULL);
if (minimum_height)
*minimum_height = minimum_size.height;
if (natural_height)
*natural_height = natural_size.height;
}
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, minimum_height, natural_height);
}
static void
@ -3617,8 +3630,10 @@ get_layout_location (GtkLabel *label,
}
else
{
req_width = widget->requisition.width;
req_height = widget->requisition.height;
req_width = logical.width;
req_height = logical.height;
/* req_width = widget->requisition.width; */
/* req_height = widget->requisition.height; */
}
x = floor (widget->allocation.x + (gint)misc->xpad +

View File

@ -35,37 +35,42 @@ G_BEGIN_DECLS
*/
typedef enum
{
PRIVATE_GTK_USER_STYLE = 1 << 0,
PRIVATE_GTK_RESIZE_PENDING = 1 << 2,
PRIVATE_GTK_HAS_POINTER = 1 << 3, /* If the pointer is above a window belonging to the widget */
PRIVATE_GTK_SHADOWED = 1 << 4, /* If there is a grab in effect shadowing the widget */
PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5,
PRIVATE_GTK_IN_REPARENT = 1 << 6,
PRIVATE_GTK_DIRECTION_SET = 1 << 7, /* If the reading direction is not DIR_NONE */
PRIVATE_GTK_DIRECTION_LTR = 1 << 8, /* If the reading direction is DIR_LTR */
PRIVATE_GTK_ANCHORED = 1 << 9, /* If widget has a GtkWindow ancestor */
PRIVATE_GTK_CHILD_VISIBLE = 1 << 10, /* If widget should be mapped when parent is mapped */
PRIVATE_GTK_REDRAW_ON_ALLOC = 1 << 11, /* If we should queue a draw on the entire widget when it is reallocated */
PRIVATE_GTK_ALLOC_NEEDED = 1 << 12, /* If we we should allocate even if the allocation is the same */
PRIVATE_GTK_REQUEST_NEEDED = 1 << 13 /* Whether we need to call gtk_widget_size_request */
PRIVATE_GTK_USER_STYLE = 1 << 0,
PRIVATE_GTK_RESIZE_PENDING = 1 << 2,
PRIVATE_GTK_HAS_POINTER = 1 << 3, /* If the pointer is above a window belonging to the widget */
PRIVATE_GTK_SHADOWED = 1 << 4, /* If there is a grab in effect shadowing the widget */
PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5,
PRIVATE_GTK_IN_REPARENT = 1 << 6,
PRIVATE_GTK_DIRECTION_SET = 1 << 7, /* If the reading direction is not DIR_NONE */
PRIVATE_GTK_DIRECTION_LTR = 1 << 8, /* If the reading direction is DIR_LTR */
PRIVATE_GTK_ANCHORED = 1 << 9, /* If widget has a GtkWindow ancestor */
PRIVATE_GTK_CHILD_VISIBLE = 1 << 10, /* If widget should be mapped when parent is mapped */
PRIVATE_GTK_REDRAW_ON_ALLOC = 1 << 11, /* If we should queue a draw on the entire widget when it is reallocated */
PRIVATE_GTK_ALLOC_NEEDED = 1 << 12, /* If we we should allocate even if the allocation is the same */
PRIVATE_GTK_REQUEST_NEEDED = 1 << 13, /* Whether we need to call gtk_widget_size_request */
PRIVATE_GTK_WIDTH_REQUEST_NEEDED = 1 << 14, /* Whether we need to call gtk_extended_layout_get_desired_width */
PRIVATE_GTK_HEIGHT_REQUEST_NEEDED = 1 << 15 /* Whether we need to call gtk_extended_layout_get_desired_height */
} GtkPrivateFlags;
/* Macros for extracting a widgets private_flags from GtkWidget.
*/
#define GTK_PRIVATE_FLAGS(wid) (GTK_WIDGET (wid)->private_flags)
#define GTK_WIDGET_USER_STYLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_USER_STYLE) != 0)
#define GTK_CONTAINER_RESIZE_PENDING(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_PENDING) != 0)
#define GTK_WIDGET_HAS_POINTER(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_POINTER) != 0)
#define GTK_WIDGET_SHADOWED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_SHADOWED) != 0)
#define GTK_WIDGET_HAS_SHAPE_MASK(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_SHAPE_MASK) != 0)
#define GTK_WIDGET_IN_REPARENT(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_IN_REPARENT) != 0)
#define GTK_WIDGET_DIRECTION_SET(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_SET) != 0)
#define GTK_WIDGET_DIRECTION_LTR(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_LTR) != 0)
#define GTK_WIDGET_ANCHORED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ANCHORED) != 0)
#define GTK_WIDGET_CHILD_VISIBLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_CHILD_VISIBLE) != 0)
#define GTK_WIDGET_REDRAW_ON_ALLOC(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REDRAW_ON_ALLOC) != 0)
#define GTK_WIDGET_ALLOC_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ALLOC_NEEDED) != 0)
#define GTK_WIDGET_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REQUEST_NEEDED) != 0)
#define GTK_PRIVATE_FLAGS(wid) (GTK_WIDGET (wid)->private_flags)
#define GTK_WIDGET_USER_STYLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_USER_STYLE) != 0)
#define GTK_CONTAINER_RESIZE_PENDING(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_PENDING) != 0)
#define GTK_WIDGET_HAS_POINTER(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_POINTER) != 0)
#define GTK_WIDGET_SHADOWED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_SHADOWED) != 0)
#define GTK_WIDGET_HAS_SHAPE_MASK(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_SHAPE_MASK) != 0)
#define GTK_WIDGET_IN_REPARENT(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_IN_REPARENT) != 0)
#define GTK_WIDGET_DIRECTION_SET(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_SET) != 0)
#define GTK_WIDGET_DIRECTION_LTR(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_LTR) != 0)
#define GTK_WIDGET_ANCHORED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ANCHORED) != 0)
#define GTK_WIDGET_CHILD_VISIBLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_CHILD_VISIBLE) != 0)
#define GTK_WIDGET_REDRAW_ON_ALLOC(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REDRAW_ON_ALLOC) != 0)
#define GTK_WIDGET_ALLOC_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ALLOC_NEEDED) != 0)
#define GTK_WIDGET_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REQUEST_NEEDED) != 0)
#define GTK_WIDGET_WIDTH_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_WIDTH_REQUEST_NEEDED) != 0)
#define GTK_WIDGET_HEIGHT_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HEIGHT_REQUEST_NEEDED) != 0)
/* Macros for setting and clearing private widget flags.
* we use a preprocessor string concatenation here for a clear

View File

@ -142,6 +142,20 @@ static void gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjus
static void gtk_scrolled_window_update_real_placement (GtkScrolledWindow *scrolled_window);
static void gtk_scrolled_window_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_scrolled_window_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_scrolled_window_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_scrolled_window_get_height_for_width (GtkExtendedLayout *layout,
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_scrolled_window_get_width_for_height (GtkExtendedLayout *layout,
gint width,
gint *minimum_height,
gint *natural_height);
static guint signals[LAST_SIGNAL] = {0};
@ -1706,10 +1720,20 @@ _gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window)
}
}
static void
gtk_scrolled_window_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
gtk_scrolled_window_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_width = gtk_scrolled_window_get_desired_width;
iface->get_desired_height = gtk_scrolled_window_get_desired_height;
iface->get_height_for_width = gtk_scrolled_window_get_height_for_width;
iface->get_width_for_height = gtk_scrolled_window_get_width_for_height;
}
static void
gtk_scrolled_window_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
{
GtkScrolledWindow *scrolled_window;
GtkBin *bin;
@ -1821,62 +1845,58 @@ gtk_scrolled_window_extended_layout_get_desired_size (GtkExtendedLayout *layout,
}
}
static void
gtk_scrolled_window_extended_layout_get_height_for_width (GtkExtendedLayout *layout,
gint width,
gint *minimum_height,
gint *natural_height)
static void
gtk_scrolled_window_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
GtkRequisition minimum_size;
GtkRequisition natural_size;
GtkRequisition minimum, natural;
g_return_if_fail (GTK_IS_WIDGET (layout));
gtk_scrolled_window_get_desired_size (layout, &minimum, &natural);
#if 0
TODO: integrate height-for-width with size-groups
#else
gtk_extended_layout_get_desired_size (layout,
minimum_height ? &minimum_size : NULL,
natural_height ? &natural_size : NULL);
if (minimum_size)
*minimum_size = minimum.width;
if (minimum_height)
*minimum_height = minimum_size.height;
if (natural_height)
*natural_height = natural_size.height;
#endif
if (natural_size)
*natural_size = natural.width;
}
static void
gtk_scrolled_window_extended_layout_get_width_for_height (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
gint *natural_width)
{
GtkRequisition minimum_size;
GtkRequisition natural_size;
g_return_if_fail (GTK_IS_WIDGET (layout));
gtk_scrolled_window_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
GtkRequisition minimum, natural;
#if 0
TODO: integrate width-for-height with size-groups
#else
gtk_extended_layout_get_desired_size (layout,
minimum_width ? &minimum_size : NULL,
natural_width ? &natural_size : NULL);
gtk_scrolled_window_get_desired_size (layout, &minimum, &natural);
if (minimum_width)
*minimum_width = minimum_size.width;
if (natural_width)
*natural_width = natural_size.width;
#endif
if (minimum_size)
*minimum_size = minimum.height;
if (natural_size)
*natural_size = natural.height;
}
static void
gtk_scrolled_window_extended_layout_init (GtkExtendedLayoutIface *iface)
gtk_scrolled_window_get_height_for_width (GtkExtendedLayout *layout,
gint width,
gint *minimum_height,
gint *natural_height)
{
iface->get_desired_size = gtk_scrolled_window_extended_layout_get_desired_size;
iface->get_width_for_height = gtk_scrolled_window_extended_layout_get_width_for_height;
iface->get_height_for_width = gtk_scrolled_window_extended_layout_get_height_for_width;
g_return_if_fail (GTK_IS_WIDGET (layout));
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, minimum_height, natural_height);
}
static void
gtk_scrolled_window_get_width_for_height (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
gint *natural_width)
{
g_return_if_fail (GTK_IS_WIDGET (layout));
GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, minimum_width, natural_width);
}
#define __GTK_SCROLLED_WINDOW_C__

View File

@ -25,18 +25,8 @@
#include "gtkprivate.h"
#include "gtksizegroup.h"
#include "gtkbuildable.h"
#include "gtkextendedlayout.h"
#include "gtkalias.h"
#define GTK_SIZE_GROUP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_SIZE_GROUP, GtkSizeGroupPrivate))
typedef struct _GtkSizeGroupPrivate GtkSizeGroupPrivate;
struct _GtkSizeGroupPrivate
{
GtkRequisition natural_size;
};
enum {
PROP_0,
PROP_MODE,
@ -164,6 +154,8 @@ real_queue_resize (GtkWidget *widget)
{
GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_WIDTH_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED);
if (widget->parent)
_gtk_container_queue_resize (GTK_CONTAINER (widget->parent));
@ -332,7 +324,6 @@ gtk_size_group_class_init (GtkSizeGroupClass *klass)
GTK_PARAM_READWRITE));
initialize_size_group_quarks ();
g_type_class_add_private (klass, sizeof (GtkSizeGroupPrivate));
}
static void
@ -607,49 +598,25 @@ gtk_size_group_get_widgets (GtkSizeGroup *size_group)
return size_group->widgets;
}
static void
get_base_dimensions (GtkWidget *widget,
GtkSizeGroupMode mode,
gint *minimum_size,
gint *natural_size)
static gint
get_base_dimension (GtkWidget *widget,
GtkSizeGroupMode mode)
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
{
if (minimum_size)
{
if (aux_info && aux_info->width > 0)
*minimum_size = aux_info->width;
else
*minimum_size = widget->requisition.width;
}
if (natural_size)
{
if (aux_info)
*natural_size = aux_info->natural_size.width;
else
*natural_size = widget->requisition.width;
}
if (aux_info && aux_info->width > 0)
return aux_info->width;
else
return widget->requisition.width;
}
else
{
if (minimum_size)
{
if (aux_info && aux_info->height > 0)
*minimum_size = aux_info->height;
else
*minimum_size = widget->requisition.height;
}
if (natural_size)
{
if (aux_info)
*natural_size = aux_info->natural_size.height;
else
*natural_size = widget->requisition.height;
}
if (aux_info && aux_info->height > 0)
return aux_info->height;
else
return widget->requisition.height;
}
}
@ -658,72 +625,31 @@ do_size_request (GtkWidget *widget)
{
if (GTK_WIDGET_REQUEST_NEEDED (widget))
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE);
GtkRequisition extended_minimum;
gtk_widget_ensure_style (widget);
GTK_PRIVATE_UNSET_FLAG (widget, GTK_REQUEST_NEEDED);
/* First, allow client code to; extended classes or signal connections; to
* modify the initial size request.
*
* Note here that there is no convention of filling the argument or widget->requisition,
* so we have no choice but to fire size request with this pointer.
*/
g_signal_emit_by_name (widget, "size-request", &widget->requisition);
/* Now get the extended layout minimum and natural size
*/
extended_minimum.width = 0;
extended_minimum.height = 0;
GTK_EXTENDED_LAYOUT_GET_IFACE
(widget)->get_desired_size (GTK_EXTENDED_LAYOUT (widget),
&extended_minimum,
&aux_info->natural_size);
/* Base the base widget requisition on both the size-requst and the extended layout size
*/
widget->requisition.width = MAX (widget->requisition.width, extended_minimum.width);
widget->requisition.height = MAX (widget->requisition.height, extended_minimum.height);
/* Additionally allow a "size-request" to overflow the natural size.
*/
aux_info->natural_size.width = MAX (aux_info->natural_size.width, widget->requisition.width);
aux_info->natural_size.height = MAX (aux_info->natural_size.height, widget->requisition.height);
/* Assert that pure extended layout cases return initial minimum sizes smaller or equal
* to their possible natural size.
*
* Note that this only determines the return of gtk_widget_get_desired_size() and caches
* the initial hints. Height for width cases will further be addressed in containers
* using gtk_extended_layout_get_height_for_width().
*/
g_assert (widget->requisition.width <= aux_info->natural_size.width);
g_assert (widget->requisition.height <= aux_info->natural_size.height);
g_signal_emit_by_name (widget,
"size-request",
&widget->requisition);
}
}
static void
compute_base_dimensions (GtkWidget *widget,
GtkSizeGroupMode mode,
gint *minimum_size,
gint *natural_size)
static gint
compute_base_dimension (GtkWidget *widget,
GtkSizeGroupMode mode)
{
do_size_request (widget);
get_base_dimensions (widget, mode, minimum_size, natural_size);
return get_base_dimension (widget, mode);
}
static void
static gint
compute_dimension (GtkWidget *widget,
GtkSizeGroupMode mode,
gint *minimum_size,
gint *natural_size)
GtkSizeGroupMode mode)
{
GSList *widgets = NULL;
GSList *groups = NULL;
GSList *tmp_list;
gint result = 0;
add_widget_to_closure (widget, mode, &groups, &widgets);
@ -734,26 +660,16 @@ compute_dimension (GtkWidget *widget,
if (!groups)
{
compute_base_dimensions (widget, mode, minimum_size, natural_size);
result = compute_base_dimension (widget, mode);
}
else
{
GtkSizeGroup *group = groups->data;
GtkSizeGroupPrivate *priv = GTK_SIZE_GROUP_GET_PRIVATE (group);
gint result_minimum_size = 0;
gint result_natural_size = 0;
if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width)
{
result_minimum_size = group->requisition.width;
result_natural_size = priv->natural_size.width;
}
result = group->requisition.width;
else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height)
{
result_minimum_size = group->requisition.height;
result_natural_size = priv->natural_size.height;
}
result = group->requisition.height;
else
{
tmp_list = widgets;
@ -761,20 +677,13 @@ compute_dimension (GtkWidget *widget,
{
GtkWidget *tmp_widget = tmp_list->data;
gint tmp_widget_minimum_size;
gint tmp_widget_natural_size;
gint dimension = compute_base_dimension (tmp_widget, mode);
compute_base_dimensions (tmp_widget, mode,
&tmp_widget_minimum_size,
&tmp_widget_natural_size);
if (gtk_widget_get_mapped (tmp_widget) || !group->ignore_hidden)
{
if (result_minimum_size < tmp_widget_minimum_size)
result_minimum_size = tmp_widget_minimum_size;
if (result_natural_size < tmp_widget_natural_size)
result_natural_size = tmp_widget_natural_size;
}
if (gtk_widget_get_mapped (tmp_widget) || !group->ignore_hidden)
{
if (dimension > result)
result = dimension;
}
tmp_list = tmp_list->next;
}
@ -783,45 +692,38 @@ compute_dimension (GtkWidget *widget,
while (tmp_list)
{
GtkSizeGroup *tmp_group = tmp_list->data;
GtkSizeGroupPrivate *tmp_priv = GTK_SIZE_GROUP_GET_PRIVATE (tmp_group);
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
{
tmp_group->have_width = TRUE;
tmp_group->requisition.width = result_minimum_size;
tmp_priv->natural_size.width = result_natural_size;
tmp_group->requisition.width = result;
}
else
{
tmp_group->have_height = TRUE;
tmp_group->requisition.height = result_minimum_size;
tmp_priv->natural_size.height = result_natural_size;
tmp_group->requisition.height = result;
}
tmp_list = tmp_list->next;
}
}
if (minimum_size)
*minimum_size = result_minimum_size;
if (natural_size)
*natural_size = result_natural_size;
}
g_slist_foreach (widgets, (GFunc)g_object_unref, NULL);
g_slist_free (widgets);
g_slist_free (groups);
return result;
}
static void
get_dimensions (GtkWidget *widget,
GtkSizeGroupMode mode,
gint *minimum_size,
gint *natural_size)
static gint
get_dimension (GtkWidget *widget,
GtkSizeGroupMode mode)
{
GSList *widgets = NULL;
GSList *groups = NULL;
gint result = 0;
add_widget_to_closure (widget, mode, &groups, &widgets);
@ -830,69 +732,38 @@ get_dimensions (GtkWidget *widget,
if (!groups)
{
get_base_dimensions (widget, mode, minimum_size, natural_size);
result = get_base_dimension (widget, mode);
}
else
{
GtkSizeGroup *group = groups->data;
GtkSizeGroupPrivate *priv = GTK_SIZE_GROUP_GET_PRIVATE (group);
if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width)
{
if (minimum_size)
*minimum_size = group->requisition.width;
if (natural_size)
*natural_size = priv->natural_size.width;
}
result = group->requisition.width;
else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height)
{
if (minimum_size)
*minimum_size = group->requisition.height;
if (natural_size)
*natural_size = priv->natural_size.height;
}
result = group->requisition.height;
}
g_slist_free (widgets);
g_slist_free (groups);
return result;
}
static void
get_fast_size (GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
get_fast_child_requisition (GtkWidget *widget,
GtkRequisition *requisition)
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
if (minimum_size)
{
*minimum_size = widget->requisition;
*requisition = widget->requisition;
if (aux_info)
{
if (aux_info->width > 0)
minimum_size->width = aux_info->width;
if (aux_info->height > 0)
minimum_size->height = aux_info->height;
}
}
if (natural_size)
if (aux_info)
{
if (aux_info)
{
*natural_size = aux_info->natural_size;
/* Explicit size request sets the baseline for natural size
* as well as the minimum size
*/
if (aux_info->width > natural_size->width)
natural_size->width = aux_info->width;
if (aux_info->height > natural_size->height)
natural_size->height = aux_info->height;
}
else
*natural_size = widget->requisition;
if (aux_info->width > 0)
requisition->width = aux_info->width;
if (aux_info && aux_info->height > 0)
requisition->height = aux_info->height;
}
}
@ -903,8 +774,6 @@ get_fast_size (GtkWidget *widget,
*
* Retrieve the "child requisition" of the widget, taking account grouping
* of the widget's requisition with other widgets.
*
* Deprecated: 3.0: Use _gtk_size_group_compute_desired_size() instead
**/
void
_gtk_size_group_get_child_requisition (GtkWidget *widget,
@ -916,48 +785,52 @@ _gtk_size_group_get_child_requisition (GtkWidget *widget,
{
if (get_size_groups (widget))
{
get_dimensions (widget, GTK_SIZE_GROUP_HORIZONTAL, &requisition->width, NULL);
get_dimensions (widget, GTK_SIZE_GROUP_VERTICAL, &requisition->height, NULL);
requisition->width = get_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL);
requisition->height = get_dimension (widget, GTK_SIZE_GROUP_VERTICAL);
/* Only do the full computation if we actually have size groups */
}
else
get_fast_size (widget, requisition, NULL);
get_fast_child_requisition (widget, requisition);
}
}
/**
* _gtk_size_group_compute_desired_size:
* _gtk_size_group_compute_requisition:
* @widget: a #GtkWidget
* @minimum_size: location to store computed minimum size
* @natural_size: location to store computed natural size
* @requisition: location to store computed requisition.
*
* Compute the desired size of a widget taking into account grouping of
* Compute the requisition of a widget taking into account grouping of
* the widget's requisition with other widgets.
**/
void
_gtk_size_group_compute_desired_size (GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
_gtk_size_group_compute_requisition (GtkWidget *widget,
GtkRequisition *requisition)
{
gint width;
gint height;
initialize_size_group_quarks ();
if (get_size_groups (widget))
{
/* Only do the full computation if we actually have size groups */
width = compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL);
height = compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL);
compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL,
minimum_size ? &minimum_size->width : NULL,
natural_size ? &natural_size->width : NULL);
compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL,
minimum_size ? &minimum_size->height : NULL,
natural_size ? &natural_size->height : NULL);
if (requisition)
{
requisition->width = width;
requisition->height = height;
}
}
else
{
do_size_request (widget);
get_fast_size (widget, minimum_size, natural_size);
if (requisition)
get_fast_child_requisition (widget, requisition);
}
}

View File

@ -102,9 +102,8 @@ GSList * gtk_size_group_get_widgets (GtkSizeGroup *size_group);
void _gtk_size_group_get_child_requisition (GtkWidget *widget,
GtkRequisition *requisition);
void _gtk_size_group_compute_desired_size (GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
void _gtk_size_group_compute_requisition (GtkWidget *widget,
GtkRequisition *requisition);
void _gtk_size_group_queue_resize (GtkWidget *widget);
G_END_DECLS

View File

@ -68,7 +68,13 @@ static void gtk_socket_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
static void gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
static void gtk_socket_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_socket_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_socket_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
/* Local data */
@ -102,7 +108,7 @@ _gtk_socket_get_private (GtkSocket *socket)
G_DEFINE_TYPE_WITH_CODE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
gtk_socket_extended_layout_interface_init))
gtk_socket_extended_layout_init))
static void
@ -1013,18 +1019,29 @@ _gtk_socket_advance_toplevel_focus (GtkSocket *socket,
}
static void
gtk_socket_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimal_size,
GtkRequisition *desired_size)
gtk_socket_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_width = gtk_socket_get_desired_width;
iface->get_desired_height = gtk_socket_get_desired_height;
}
static void
gtk_socket_get_desired_size (GtkExtendedLayout *layout,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkSocket *socket = GTK_SOCKET (layout);
GtkSocketPrivate *priv;
if (socket->plug_widget)
{
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (socket->plug_widget),
minimal_size,
desired_size);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (socket->plug_widget),
minimum_size, natural_size);
else
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (socket->plug_widget),
minimum_size, natural_size);
}
else
{
@ -1038,37 +1055,44 @@ gtk_socket_extended_layout_get_desired_size (GtkExtendedLayout *layout,
if (socket->is_mapped && priv->have_natural_size)
{
if (minimal_size)
if (minimum_size)
{
minimal_size->width = MAX (socket->request_width, 1);
minimal_size->height = MAX (socket->request_height, 1);
*minimum_size =
(orientation == GTK_ORIENTATION_HORIZONTAL) ?
MAX (socket->request_width, 1) : MAX (socket->request_height, 1);
}
if (desired_size)
if (natural_size)
{
desired_size->width = MAX (priv->natural_width, 1);
desired_size->height = MAX (priv->natural_height, 1);
*natural_size =
(orientation == GTK_ORIENTATION_HORIZONTAL) ?
MAX (priv->natural_width, 1) : MAX (priv->natural_height, 1);
}
}
else
{
if (minimal_size)
{
minimal_size->width = 1;
minimal_size->height = 1;
}
if (desired_size)
{
desired_size->width = 1;
desired_size->height = 1;
}
if (minimum_size)
*minimum_size = 1;
if (natural_size)
*natural_size = 1;
}
}
}
static void
gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
gtk_socket_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
iface->get_desired_size = gtk_socket_extended_layout_get_desired_size;
gtk_socket_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_socket_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_socket_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}

View File

@ -469,6 +469,13 @@ static void gtk_tree_view_buildable_add_child (GtkBuildable *tree_view,
const gchar *type);
static void gtk_tree_view_buildable_init (GtkBuildableIface *iface);
static void gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_tree_view_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_tree_view_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static gboolean scroll_row_timeout (gpointer data);
static void add_scroll_timeout (GtkTreeView *tree_view);
@ -15733,9 +15740,17 @@ gtk_tree_view_get_minimum_size (GtkWidget *widget,
}
static void
gtk_tree_view_extended_layout_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimal_size,
GtkRequisition *desired_size)
gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_width = gtk_tree_view_get_desired_width;
iface->get_desired_height = gtk_tree_view_get_desired_height;
}
static void
gtk_tree_view_get_desired_size (GtkExtendedLayout *layout,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkTreeView *tree_view;
gint natural_width = 0;
@ -15746,32 +15761,49 @@ gtk_tree_view_extended_layout_get_desired_size (GtkExtendedLayout *layout,
gtk_tree_view_get_minimum_size (GTK_WIDGET (layout), &requisition);
for (column_iter = tree_view->priv->columns; column_iter; column_iter = column_iter->next)
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
GtkTreeViewColumn *column = column_iter->data;
for (column_iter = tree_view->priv->columns; column_iter; column_iter = column_iter->next)
{
GtkTreeViewColumn *column = column_iter->data;
if (!column->visible)
continue;
natural_width += gtk_tree_view_get_real_natural_width_from_column (tree_view, column);
}
if (!column->visible)
continue;
if (minimum_size)
*minimum_size = requisition.width;
natural_width += gtk_tree_view_get_real_natural_width_from_column (tree_view, column);
if (natural_size)
*natural_size = MAX (requisition.width, natural_width);
}
if (minimal_size)
*minimal_size = requisition;
if (desired_size)
else
{
desired_size->height = requisition.height;
desired_size->width = MAX (requisition.width, natural_width);
if (minimum_size)
*minimum_size = requisition.height;
if (natural_size)
*natural_size = requisition.height;
}
}
static void
gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface)
gtk_tree_view_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
iface->get_desired_size = gtk_tree_view_extended_layout_get_desired_size;
gtk_tree_view_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_tree_view_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_tree_view_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}
#define __GTK_TREE_VIEW_C__
#include "gtkaliasdef.c"

View File

@ -2644,9 +2644,15 @@ gtk_tree_view_column_cell_get_real_size (GtkTreeViewColumn *tree_column,
nat_req.width += tree_column->spacing;
}
gtk_extended_cell_get_desired_size (GTK_EXTENDED_CELL (info->cell),
tree_column->tree_view,
&min_req, &nat_req);
/* XXX TODO: Cell renderers are not really doing height-for-width yet.
*/
gtk_extended_cell_get_desired_width (GTK_EXTENDED_CELL (info->cell),
tree_column->tree_view,
&min_req.width, &nat_req.width);
gtk_extended_cell_get_height_for_width (GTK_EXTENDED_CELL (info->cell),
tree_column->tree_view,
nat_req.width,
&min_req.height, &nat_req.height);
min_req.width += focus_line_width * 2;
min_req.height += focus_line_width * 2;

View File

@ -69,6 +69,13 @@ static void gtk_viewport_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void gtk_viewport_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_viewport_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_viewport_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
G_DEFINE_TYPE_WITH_CODE (GtkViewport, gtk_viewport, GTK_TYPE_BIN,
G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
@ -829,44 +836,67 @@ gtk_viewport_style_set (GtkWidget *widget,
}
}
static void
gtk_viewport_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
{
GtkWidget *child;
GtkRequisition child_min, child_nat;
child = gtk_bin_get_child (GTK_BIN (layout));
minimum_size->width = GTK_CONTAINER (layout)->border_width;
minimum_size->height = GTK_CONTAINER (layout)->border_width;
natural_size->width = GTK_CONTAINER (layout)->border_width;
natural_size->height = GTK_CONTAINER (layout)->border_width;
if (GTK_VIEWPORT (layout)->shadow_type != GTK_SHADOW_NONE)
{
minimum_size->width += 2 * GTK_WIDGET (layout)->style->xthickness;
minimum_size->height += 2 * GTK_WIDGET (layout)->style->ythickness;
natural_size->width += 2 * GTK_WIDGET (layout)->style->xthickness;
natural_size->height += 2 * GTK_WIDGET (layout)->style->ythickness;
}
if (child && gtk_widget_get_visible (child))
{
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
minimum_size->width += child_min.width;
minimum_size->height += child_min.height;
natural_size->width += child_nat.width;
natural_size->height += child_nat.height;
}
}
static void
gtk_viewport_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_size = gtk_viewport_get_desired_size;
iface->get_desired_width = gtk_viewport_get_desired_width;
iface->get_desired_height = gtk_viewport_get_desired_height;
}
static void
gtk_viewport_get_desired_size (GtkExtendedLayout *layout,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkWidget *child;
gint child_min, child_nat;
gint minimum, natural;
child = gtk_bin_get_child (GTK_BIN (layout));
/* XXX This should probably be (border_width * 2); but GTK+ has
* been doing this with a single border for a while now...
*/
minimum = GTK_CONTAINER (layout)->border_width;
if (GTK_VIEWPORT (layout)->shadow_type != GTK_SHADOW_NONE)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
minimum += 2 * GTK_WIDGET (layout)->style->xthickness;
else
minimum += 2 * GTK_WIDGET (layout)->style->ythickness;
}
natural = minimum;
if (child && gtk_widget_get_visible (child))
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
else
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
minimum += child_min;
natural += child_nat;
}
}
static void
gtk_viewport_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_viewport_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_viewport_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
gtk_viewport_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}
#define __GTK_VIEWPORT_C__

View File

@ -344,10 +344,13 @@ static void gtk_widget_buildable_custom_finished (GtkBuildable
static void gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
GtkBuilder *builder);
static void gtk_widget_layout_interface_init (GtkExtendedLayoutIface *iface);
static void gtk_widget_real_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size);
static void gtk_widget_extended_layout_init (GtkExtendedLayoutIface *iface);
static void gtk_widget_real_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_widget_real_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size);
static void gtk_widget_queue_tooltip_query (GtkWidget *widget);
@ -426,7 +429,7 @@ gtk_widget_get_type (void)
const GInterfaceInfo layout_info =
{
(GInterfaceInitFunc) gtk_widget_layout_interface_init,
(GInterfaceInitFunc) gtk_widget_extended_layout_init,
(GInterfaceFinalizeFunc) NULL,
NULL /* interface data */
};
@ -2849,6 +2852,8 @@ gtk_widget_init (GtkWidget *widget)
GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_WIDTH_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
widget->style = gtk_widget_get_default_style ();
@ -3889,7 +3894,7 @@ gtk_widget_size_request (GtkWidget *widget,
"to widget->requisition. gtk_widget_set_usize() may not work properly.");
#endif /* G_ENABLE_DEBUG */
_gtk_size_group_compute_desired_size (widget, requisition, NULL);
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (widget), requisition, NULL);
}
/**
@ -9277,12 +9282,16 @@ _gtk_widget_get_aux_info (GtkWidget *widget,
aux_info->width = -1;
aux_info->height = -1;
aux_info->cached_width_age = 1;
aux_info->cached_height_age = 1;
g_object_set_qdata (G_OBJECT (widget), quark_aux_info, aux_info);
}
return aux_info;
}
/*****************************************
* gtk_widget_aux_info_destroy:
*
@ -10719,18 +10728,33 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
* GtkExtendedLayout implementation
*/
static void
gtk_widget_real_get_desired_size (GtkExtendedLayout *layout,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
gtk_widget_real_get_desired_width (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
/* Set the initial values so that unimplemented classes will fall back
* on the "size-request" collected values (see gtksizegroup.c:do_size_request()).
*/
if (minimum_size)
memset (minimum_size, 0x0, sizeof (GtkRequisition));
*minimum_size = GTK_WIDGET (layout)->requisition.width;
if (natural_size)
memset (natural_size, 0x0, sizeof (GtkRequisition));
*natural_size = GTK_WIDGET (layout)->requisition.width;
}
static void
gtk_widget_real_get_desired_height (GtkExtendedLayout *layout,
gint *minimum_size,
gint *natural_size)
{
/* Set the initial values so that unimplemented classes will fall back
* on the "size-request" collected values (see gtksizegroup.c:do_size_request()).
*/
if (minimum_size)
*minimum_size = GTK_WIDGET (layout)->requisition.height;
if (natural_size)
*natural_size = GTK_WIDGET (layout)->requisition.height;
}
static void
@ -10739,23 +10763,7 @@ gtk_widget_real_get_height_for_width (GtkExtendedLayout *layout,
gint *minimum_height,
gint *natural_height)
{
GtkRequisition minimum_size;
GtkRequisition natural_size;
g_return_if_fail (GTK_IS_WIDGET (layout));
#if 0
TODO: integrate height-for-width with size-groups
#else
gtk_extended_layout_get_desired_size (layout,
minimum_height ? &minimum_size : NULL,
natural_height ? &natural_size : NULL);
if (minimum_height)
*minimum_height = minimum_size.height;
if (natural_height)
*natural_height = natural_size.height;
#endif
gtk_extended_layout_get_desired_height (layout, minimum_height, natural_height);
}
static void
@ -10763,30 +10771,15 @@ gtk_widget_real_get_width_for_height (GtkExtendedLayout *layout,
gint height,
gint *minimum_width,
gint *natural_width)
{
GtkRequisition minimum_size;
GtkRequisition natural_size;
g_return_if_fail (GTK_IS_WIDGET (layout));
#if 0
TODO: integrate width-for-height with size-groups
#else
gtk_extended_layout_get_desired_size (layout,
minimum_width ? &minimum_size : NULL,
natural_width ? &natural_size : NULL);
if (minimum_width)
*minimum_width = minimum_size.width;
if (natural_width)
*natural_width = natural_size.width;
#endif
{
gtk_extended_layout_get_desired_width (layout, minimum_width, natural_width);
}
static void
gtk_widget_layout_interface_init (GtkExtendedLayoutIface *iface)
gtk_widget_extended_layout_init (GtkExtendedLayoutIface *iface)
{
iface->get_desired_size = gtk_widget_real_get_desired_size;
iface->get_desired_width = gtk_widget_real_get_desired_width;
iface->get_desired_height = gtk_widget_real_get_desired_height;
iface->get_width_for_height = gtk_widget_real_get_width_for_height;
iface->get_height_for_width = gtk_widget_real_get_height_for_width;
}

View File

@ -459,17 +459,22 @@ typedef enum
#define GTK_TYPE_REQUISITION (gtk_requisition_get_type ())
/* Size of the width-for-height/height-for-width caches */
#define GTK_N_CACHED_SIZES 3
/* forward declaration to avoid excessive includes (and concurrent includes)
*/
typedef struct _GtkRequisition GtkRequisition;
typedef struct _GtkSelectionData GtkSelectionData;
typedef struct _GtkWidgetClass GtkWidgetClass;
typedef struct _GtkWidgetAuxInfo GtkWidgetAuxInfo;
typedef struct _GtkDesiredSize GtkDesiredSize;
typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo;
typedef struct _GtkClipboard GtkClipboard;
typedef struct _GtkTooltip GtkTooltip;
typedef struct _GtkWindow GtkWindow;
/**
* GtkAllocation:
* @x: the X position of the widget's area relative to its parents allocation.
@ -799,6 +804,14 @@ struct _GtkWidgetClass
void (*_gtk_reserved7) (void);
};
struct _GtkDesiredSize
{
guint age;
gint for_size;
gint minimum_size;
gint natural_size;
};
struct _GtkWidgetAuxInfo
{
gint x;
@ -809,7 +822,10 @@ struct _GtkWidgetAuxInfo
guint x_set : 1;
guint y_set : 1;
GtkRequisition natural_size;
GtkDesiredSize desired_widths[GTK_N_CACHED_SIZES];
GtkDesiredSize desired_heights[GTK_N_CACHED_SIZES];
guint cached_width_age;
guint cached_height_age;
};
struct _GtkWidgetShapeInfo

View File

@ -4949,43 +4949,18 @@ gtk_window_size_request (GtkWidget *widget,
if (bin->child && gtk_widget_get_visible (bin->child))
{
GtkRequisition child_requisition, child_natural;
gint wfh, hfw;
gint width, height;
/* XXX Use the minimum width for the natural height; even if its an hbox.
*
* This doesnt need to be here; naturally it will use the preference of the child
* except for testing purposes its more interesting this way.
*/
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (bin->child), NULL, &height);
gtk_extended_layout_get_width_for_height (GTK_EXTENDED_LAYOUT (bin->child), height, &width, NULL);
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin->child),
&child_requisition,
&child_natural);
/* TODO: Change wrapping label requisitions to desired a user intended wrap length,
* and make the minimum size out the minimum height for the natural-width, instead of
* the minimum height for the minimum width, which is backwards */
if (window->type != GTK_WINDOW_POPUP)
{
if (gtk_extended_layout_is_height_for_width (GTK_EXTENDED_LAYOUT (bin->child)))
{
gtk_extended_layout_get_height_for_width (GTK_EXTENDED_LAYOUT (bin->child),
child_natural.width,
&hfw, NULL);
requisition->width += child_requisition.height;
requisition->height += hfw;
}
else
{
gtk_extended_layout_get_width_for_height (GTK_EXTENDED_LAYOUT (bin->child),
child_natural.height,
&wfh, NULL);
requisition->width += wfh;
requisition->height += child_requisition.height;
}
}
else
{
requisition->width += child_requisition.width;
requisition->height += child_requisition.height;
}
requisition->width += width;
requisition->height += height;
}
}