GtkWidget

GtkWidget — Height-for-width geometry management

Synopsis

#include <gtk/gtk.h>

enum                GtkSizeRequestMode;
                    GtkRequestedSize;
void                gtk_widget_get_preferred_height     (GtkWidget *widget,
                                                         gint *minimum_height,
                                                         gint *natural_height);
void                gtk_widget_get_preferred_width      (GtkWidget *widget,
                                                         gint *minimum_width,
                                                         gint *natural_width);
void                gtk_widget_get_preferred_height_for_width
                                                        (GtkWidget *widget,
                                                         gint width,
                                                         gint *minimum_height,
                                                         gint *natural_height);
void                gtk_widget_get_preferred_width_for_height
                                                        (GtkWidget *widget,
                                                         gint height,
                                                         gint *minimum_width,
                                                         gint *natural_width);
GtkSizeRequestMode  gtk_widget_get_request_mode         (GtkWidget *widget);
void                gtk_widget_get_preferred_size       (GtkWidget *widget,
                                                         GtkRequisition *minimum_size,
                                                         GtkRequisition *natural_size);
gint                gtk_distribute_natural_allocation   (gint extra_space,
                                                         guint n_requested_sizes,
                                                         GtkRequestedSize *sizes);

Description

The GtkWidget interface is GTK+'s height-for-width (and width-for-height) geometry management system. Height-for-width means that a widget can change how much vertical space it needs, depending on the amount of horizontal space that it is given (and similar for width-for-height). The most common example is a label that reflows to fill up the available width, wraps to fewer lines, and therefore needs less height.

GTK+'s traditional two-pass size-allocation algorithm does not allow this flexibility. GtkWidget provides a default implementation of the GtkWidget interface for existing widgets, which always requests the same height, regardless of the available width.

Implementing GtkWidget

Some important things to keep in mind when implementing the GtkWidget interface and when using it in container implementations.

The geometry management system will query a logical hierarchy in only one orientation at a time. When widgets are initially queried for their minimum sizes it is generally done in a dual pass in the direction chosen by the toplevel.

For instance when queried in the normal height-for-width mode: First the default minimum and natural width for each widget in the interface will computed and collectively returned to the toplevel by way of gtk_widget_get_preferred_width(). Next, the toplevel will use the minimum width to query for the minimum height contextual to that width using gtk_widget_get_preferred_height_for_width(), which will also be a highly recursive operation. This minimum-for-minimum size can be used to set the minimum size constraint on the toplevel.

When allocating, each container can use the minimum and natural sizes reported by their children to allocate natural sizes and expose as much content as possible with the given allocation.

That means that the request operation at allocation time will usually fire again in contexts of different allocated sizes than the ones originally queried for. GtkWidget caches a small number of results to avoid re-querying for the same allocated size in one allocation cycle.

A widget that does not actually do height-for-width or width-for-height size negotiations only has to implement get_preferred_width() and get_preferred_height().

If a widget does move content around to smartly use up the allocated size, then it must support the request properly in both orientations; even if the request only makes sense in one orientation.

For instance, a GtkLabel that does height-for-width word wrapping will not expect to have get_preferred_height() called because that call is specific to a width-for-height request, in this case the label must return the heights contextual to its minimum possible width. By following this rule any widget that handles height-for-width or width-for-height requests will always be allocated at least enough space to fit its own content.

Often a widget needs to get its own request during size request or allocation, for example when computing height it may need to also compute width, or when deciding how to use an allocation the widget may need to know its natural size. In these cases, the widget should be careful to call its virtual methods directly, like this:

Example 46. Widget calling its own size request method.

1
GTK_WIDGET_GET_CLASS(widget)->get_preferred_width (widget), &min, &natural);


It will not work to use the wrapper functions, such as gtk_widget_get_preferred_width(), inside your own size request implementation. These return a request adjusted by GtkSizeGroup and by the GtkWidgetClass::adjust_size_request virtual method. If a widget used the wrappers inside its virtual method implementations, then the adjustments (such as widget margins) would be applied twice. GTK+ therefore does not allow this and will warn if you try to do it.

Of course if you are getting the size request for another widget, such as a child of a container, you must use the wrapper APIs; otherwise, you would not properly consider widget margins, GtkSizeGroup, and so forth.

Details

enum GtkSizeRequestMode

typedef enum
{
  GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH = 0,
  GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT
} GtkSizeRequestMode;

Specifies a preference for height-for-width or width-for-height geometry management.

GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH

Prefer height-for-width geometry management

GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT

Prefer width-for-height geometry management

GtkRequestedSize

typedef struct {
  gpointer data;
  gint     minimum_size;
  gint     natural_size;
} GtkRequestedSize;

Represents a request of a screen object in a given orientation. These are primarily used in container implementations when allocating a natural size for children calling. See gtk_distribute_natural_allocation().

gpointer data;

A client pointer

gint minimum_size;

The minimum size needed for allocation in a given orientation

gint natural_size;

The natural size for allocation in a given orientation

gtk_widget_get_preferred_height ()

void                gtk_widget_get_preferred_height     (GtkWidget *widget,
                                                         gint *minimum_height,
                                                         gint *natural_height);

Retrieves a widget's initial minimum and natural height.

Note

This call is specific to width-for-height requests.

The returned request will be modified by the GtkWidgetClass::adjust_size_request virtual method and by any GtkSizeGroup that have been applied. That is, the returned request is the one that should be used for layout, not necessarily the one returned by the widget itself.

widget :

a GtkWidget instance

minimum_height :

location to store the minimum height, or NULL. [out][allow-none]

natural_height :

location to store the natural height, or NULL. [out][allow-none]

Since 3.0


gtk_widget_get_preferred_width ()

void                gtk_widget_get_preferred_width      (GtkWidget *widget,
                                                         gint *minimum_width,
                                                         gint *natural_width);

Retrieves a widget's initial minimum and natural width.

Note

This call is specific to height-for-width requests.

The returned request will be modified by the GtkWidgetClass::adjust_size_request virtual method and by any GtkSizeGroup that have been applied. That is, the returned request is the one that should be used for layout, not necessarily the one returned by the widget itself.

widget :

a GtkWidget instance

minimum_width :

location to store the minimum width, or NULL. [out][allow-none]

natural_width :

location to store the natural width, or NULL. [out][allow-none]

Since 3.0


gtk_widget_get_preferred_height_for_width ()

void                gtk_widget_get_preferred_height_for_width
                                                        (GtkWidget *widget,
                                                         gint width,
                                                         gint *minimum_height,
                                                         gint *natural_height);

Retrieves a widget's minimum and natural height if it would be given the specified width.

The returned request will be modified by the GtkWidgetClass::adjust_size_request virtual method and by any GtkSizeGroup that have been applied. That is, the returned request is the one that should be used for layout, not necessarily the one returned by the widget itself.

widget :

a GtkWidget instance

width :

the width which is available for allocation

minimum_height :

location for storing the minimum height, or NULL. [out][allow-none]

natural_height :

location for storing the natural height, or NULL. [out][allow-none]

Since 3.0


gtk_widget_get_preferred_width_for_height ()

void                gtk_widget_get_preferred_width_for_height
                                                        (GtkWidget *widget,
                                                         gint height,
                                                         gint *minimum_width,
                                                         gint *natural_width);

Retrieves a widget's minimum and natural width if it would be given the specified height.

The returned request will be modified by the GtkWidgetClass::adjust_size_request virtual method and by any GtkSizeGroup that have been applied. That is, the returned request is the one that should be used for layout, not necessarily the one returned by the widget itself.

widget :

a GtkWidget instance

height :

the height which is available for allocation

minimum_width :

location for storing the minimum width, or NULL. [out][allow-none]

natural_width :

location for storing the natural width, or NULL. [out][allow-none]

Since 3.0


gtk_widget_get_request_mode ()

GtkSizeRequestMode  gtk_widget_get_request_mode         (GtkWidget *widget);

Gets whether the widget prefers a height-for-width layout or a width-for-height layout.

Note

GtkBin widgets generally propagate the preference of their child, container widgets need to request something either in context of their children or in context of their allocation capabilities.

widget :

a GtkWidget instance

Returns :

The GtkSizeRequestMode preferred by widget.

Since 3.0


gtk_widget_get_preferred_size ()

void                gtk_widget_get_preferred_size       (GtkWidget *widget,
                                                         GtkRequisition *minimum_size,
                                                         GtkRequisition *natural_size);

Retrieves the minimum and natural size of a widget taking into account the widget's preference for height-for-width management.

This is used to retrieve a suitable size by container widgets which do not impose any restrictions on the child placement.

widget :

a GtkWidget instance

minimum_size :

location for storing the minimum size, or NULL. [out][allow-none]

natural_size :

location for storing the natural size, or NULL. [out][allow-none]

Since 3.0


gtk_distribute_natural_allocation ()

gint                gtk_distribute_natural_allocation   (gint extra_space,
                                                         guint n_requested_sizes,
                                                         GtkRequestedSize *sizes);

Distributes extra_space to child sizes by bringing up smaller children up to natural size first.

The remaining space will be added to the minimum_size member of the GtkRequestedSize struct. If all sizes reach their natural size then the remaining space is returned.

extra_space :

Extra space to redistribute among children after subtracting minimum sizes and any child padding from the overall allocation

n_requested_sizes :

Number of requests to fit into the allocation

sizes :

An array of structs with a client pointer and a minimum/natural size in the orientation of the allocation.

Returns :

The remainder of extra_space after redistributing space to sizes.