[]Struct gtk::Widget

pub struct Widget(_, _);

Widget is the base class all widgets in GTK+ derive from. It manages the widget lifecycle, states and style.

Height-for-width Geometry Management # {geometry-management}

GTK+ uses a 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.

Height-for-width geometry management is implemented in GTK+ by way of five virtual methods:

There are some important things to keep in mind when implementing height-for-width and when using it in container implementations.

The geometry management system will query a widget hierarchy in only one orientation at a time. When widgets are initially queried for their minimum sizes it is generally done in two initial passes in the SizeRequestMode chosen by the toplevel.

For example, when queried in the normal SizeRequestMode::HeightForWidth mode: First, the default minimum and natural width for each widget in the interface will be computed using WidgetExt::get_preferred_width. Because the preferred widths for each container depend on the preferred widths of their children, this information propagates up the hierarchy, and finally a minimum and natural width is determined for the entire toplevel. Next, the toplevel will use the minimum width to query for the minimum height contextual to that width using WidgetExt::get_preferred_height_for_width, which will also be a highly recursive operation. The minimum height for the minimum width is normally used to set the minimum size constraint on the toplevel (unless GtkWindowExt::set_geometry_hints is explicitly used instead).

After the toplevel window has initially requested its size in both dimensions it can go on to allocate itself a reasonable size (or a size previously specified with GtkWindowExt::set_default_size). During the recursive allocation process it’s important to note that request cycles will be recursively executed while container widgets allocate their children. Each container widget, once allocated a size, will go on to first share the space in one orientation among its children and then request each child's height for its target allocated width or its width for allocated height, depending. In this way a Widget will typically be requested its size a number of times before actually being allocated a size. The size a widget is finally allocated can of course differ from the size it has requested. For this reason, Widget caches a small number of results to avoid re-querying for the same sizes in one allocation cycle.

See [Container’s geometry management section][container-geometry-management] to learn more about how height-for-width allocations are performed by container widgets.

If a widget does move content around to intelligently use up the allocated size then it must support the request in both GtkSizeRequestModes even if the widget in question only trades sizes in a single orientation.

For instance, a Label that does height-for-width word wrapping will not expect to have WidgetClass.get_preferred_height() called because that call is specific to a width-for-height request. In this case the label must return the height required for its own 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.

Here are some examples of how a SizeRequestMode::HeightForWidth widget generally deals with width-for-height requests, for WidgetClass.get_preferred_height() it will do:

static void
foo_widget_get_preferred_height (GtkWidget *widget,
                                 gint *min_height,
                                 gint *nat_height)
{
   if (i_am_in_height_for_width_mode)
     {
       gint min_width, nat_width;

       GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
                                                           &min_width,
                                                           &nat_width);
       GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width
                                                          (widget,
                                                           min_width,
                                                           min_height,
                                                           nat_height);
     }
   else
     {
        ... some widgets do both. For instance, if a GtkLabel is
        rotated to 90 degrees it will return the minimum and
        natural height for the rotated label here.
     }
}

And in WidgetClass.get_preferred_width_for_height() it will simply return the minimum and natural width:

static void
foo_widget_get_preferred_width_for_height (GtkWidget *widget,
                                           gint for_height,
                                           gint *min_width,
                                           gint *nat_width)
{
   if (i_am_in_height_for_width_mode)
     {
       GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
                                                           min_width,
                                                           nat_width);
     }
   else
     {
        ... again if a widget is sometimes operating in
        width-for-height mode (like a rotated GtkLabel) it can go
        ahead and do its real width for height calculation here.
     }
}

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:

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

It will not work to use the wrapper functions, such as WidgetExt::get_preferred_width inside your own size request implementation. These return a request adjusted by SizeGroup and by the WidgetClass.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, SizeGroup, and so forth.

Since 3.10 GTK+ also supports baseline vertical alignment of widgets. This means that widgets are positioned such that the typographical baseline of widgets in the same row are aligned. This happens if a widget supports baselines, has a vertical alignment of Align::Baseline, and is inside a container that supports baselines and has a natural “row” that it aligns to the baseline, or a baseline assigned to it by the grandparent.

Baseline alignment support for a widget is done by the WidgetClass.get_preferred_height_and_baseline_for_width() virtual function. It allows you to report a baseline in combination with the minimum and natural height. If there is no baseline you can return -1 to indicate this. The default implementation of this virtual function calls into the WidgetClass.get_preferred_height() and WidgetClass.get_preferred_height_for_width(), so if baselines are not supported it doesn’t need to be implemented.

If a widget ends up baseline aligned it will be allocated all the space in the parent as if it was Align::Fill, but the selected baseline can be found via WidgetExt::get_allocated_baseline. If this has a value other than -1 you need to align the widget such that the baseline appears at the position.

Style Properties

Widget introduces “style properties” - these are basically object properties that are stored not on the object, but in the style object associated to the widget. Style properties are set in [resource files][gtk3-Resource-Files]. This mechanism is used for configuring such things as the location of the scrollbar arrows through the theme, giving theme authors more control over the look of applications without the need to write a theme engine in C.

Use WidgetClass::install_style_property to install style properties for a widget class, WidgetClass::find_style_property or WidgetClass::list_style_properties to get information about existing style properties and Widget::style_get_property, WidgetExt::style_get or WidgetExt::style_get_valist to obtain the value of a style property.

Widget as Buildable

The Widget implementation of the Buildable interface supports a custom <accelerator> element, which has attributes named ”key”, ”modifiers” and ”signal” and allows to specify accelerators.

An example of a UI definition fragment specifying an accelerator:

static void
foo_widget_class_init (FooWidgetClass *klass)
{
  // ...

  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
                                               "/com/example/ui/foowidget.ui");
}

You will also need to call WidgetExt::init_template from the instance initialization function:

static void
foo_widget_init (FooWidget *self)
{
  // ...
  gtk_widget_init_template (GTK_WIDGET (self));
}

You can access widgets defined in the template using the WidgetExt::get_template_child function, but you will typically declare a pointer in the instance private data structure of your type using the same name as the widget in the template definition, and call gtk_widget_class_bind_template_child_private with that name, e.g.

typedef struct {
  GtkWidget *hello_button;
  GtkWidget *goodbye_button;
} FooWidgetPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (FooWidget, foo_widget, GTK_TYPE_BOX)

static void
foo_widget_class_init (FooWidgetClass *klass)
{
  // ...
  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
                                               "/com/example/ui/foowidget.ui");
  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
                                                FooWidget, hello_button);
  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
                                                FooWidget, goodbye_button);
}

static void
foo_widget_init (FooWidget *widget)
{

}

You can also use gtk_widget_class_bind_template_callback to connect a signal callback defined in the template with a function visible in the scope of the class, e.g.

// the signal handler has the instance and user data swapped
// because of the swapped="yes" attribute in the template XML
static void
hello_button_clicked (FooWidget *self,
                      GtkButton *button)
{
  g_print ("Hello, world!\n");
}

static void
foo_widget_class_init (FooWidgetClass *klass)
{
  // ...
  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
                                               "/com/example/ui/foowidget.ui");
  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), hello_button_clicked);
}

Implements

WidgetExt, glib::object::ObjectExt, BuildableExt, WidgetExtManual, BuildableExtManual

Methods

impl Widget[src]

pub fn get_default_direction() -> TextDirection[src]

Obtains the current default reading direction. See Widget::set_default_direction.

Returns

the current default direction.

pub fn set_default_direction(dir: TextDirection)[src]

Sets the default reading direction for widgets where the direction has not been explicitly set by WidgetExt::set_direction.

dir

the new default direction. This cannot be TextDirection::None.

Trait Implementations

impl Clone for Widget

impl Debug for Widget

impl Display for Widget[src]

impl Eq for Widget

impl Hash for Widget

impl IsA<Buildable> for Widget

impl IsA<Widget> for AboutDialog

impl IsA<Widget> for AccelLabel

impl IsA<Widget> for Bin

impl IsA<Widget> for ToggleButton

impl IsA<Widget> for ToggleToolButton

impl IsA<Widget> for ToolButton

impl IsA<Widget> for ToolItem

impl IsA<Widget> for ToolItemGroup

impl IsA<Widget> for ToolPalette

impl IsA<Widget> for ToolShell

impl IsA<Widget> for Toolbar

impl IsA<Widget> for TreeView

impl IsA<Widget> for Viewport

impl IsA<Widget> for Box

impl IsA<Widget> for VolumeButton

impl IsA<Widget> for Window

impl IsA<Widget> for AppChooser

impl IsA<Widget> for Button

impl IsA<Widget> for ButtonBox

impl IsA<Widget> for Calendar

impl IsA<Widget> for CellEditable

impl IsA<Widget> for CellView

impl IsA<Widget> for CheckButton

impl IsA<Widget> for CheckMenuItem

impl IsA<Widget> for ColorButton

impl IsA<Widget> for ActionBar

impl IsA<Widget> for ColorChooserDialog

impl IsA<Widget> for ColorChooserWidget

impl IsA<Widget> for ComboBox

impl IsA<Widget> for ComboBoxText

impl IsA<Widget> for Container

impl IsA<Widget> for Dialog

impl IsA<Widget> for DrawingArea

impl IsA<Widget> for Entry

impl IsA<Widget> for EventBox

impl IsA<Widget> for Expander

impl IsA<Widget> for Actionable

impl IsA<Widget> for FileChooserButton

impl IsA<Widget> for FileChooserDialog

impl IsA<Widget> for FileChooserWidget

impl IsA<Widget> for Fixed

impl IsA<Widget> for FlowBox

impl IsA<Widget> for FlowBoxChild

impl IsA<Widget> for FontButton

impl IsA<Widget> for FontChooserDialog

impl IsA<Widget> for FontChooserWidget

impl IsA<Widget> for Frame

impl IsA<Widget> for AppChooserButton

impl IsA<Widget> for GLArea

impl IsA<Widget> for Grid

impl IsA<Widget> for HeaderBar

impl IsA<Widget> for IconView

impl IsA<Widget> for Image

impl IsA<Widget> for InfoBar

impl IsA<Widget> for Invisible

impl IsA<Widget> for Label

impl IsA<Widget> for Layout

impl IsA<Widget> for LevelBar

impl IsA<Widget> for AppChooserDialog

impl IsA<Widget> for LinkButton

impl IsA<Widget> for ListBox

impl IsA<Widget> for ListBoxRow

impl IsA<Widget> for LockButton

impl IsA<Widget> for Menu

impl IsA<Widget> for MenuBar

impl IsA<Widget> for MenuButton

impl IsA<Widget> for MenuItem

impl IsA<Widget> for MenuShell

impl IsA<Widget> for MenuToolButton

impl IsA<Widget> for AppChooserWidget

impl IsA<Widget> for MessageDialog

impl IsA<Widget> for Misc

impl IsA<Widget> for ModelButton

impl IsA<Widget> for Notebook

impl IsA<Widget> for OffscreenWindow

impl IsA<Widget> for Overlay

impl IsA<Widget> for Paned

impl IsA<Widget> for PlacesSidebar

impl IsA<Widget> for Plug

impl IsA<Widget> for Popover

impl IsA<Widget> for ApplicationWindow

impl IsA<Widget> for PopoverMenu

impl IsA<Widget> for ProgressBar

impl IsA<Widget> for RadioButton

impl IsA<Widget> for RadioMenuItem

impl IsA<Widget> for RadioToolButton

impl IsA<Widget> for Range

impl IsA<Widget> for RecentChooserDialog

impl IsA<Widget> for RecentChooserMenu

impl IsA<Widget> for RecentChooserWidget

impl IsA<Widget> for Revealer

impl IsA<Widget> for AspectFrame

impl IsA<Widget> for Scale

impl IsA<Widget> for ScaleButton

impl IsA<Widget> for Scrollbar

impl IsA<Widget> for ScrolledWindow

impl IsA<Widget> for SearchBar

impl IsA<Widget> for SearchEntry

impl IsA<Widget> for Separator

impl IsA<Widget> for SeparatorMenuItem

impl IsA<Widget> for SeparatorToolItem

impl IsA<Widget> for ShortcutLabel

impl IsA<Widget> for Assistant

impl IsA<Widget> for ShortcutsWindow

impl IsA<Widget> for Socket

impl IsA<Widget> for SpinButton

impl IsA<Widget> for Spinner

impl IsA<Widget> for Stack

impl IsA<Widget> for StackSidebar

impl IsA<Widget> for StackSwitcher

impl IsA<Widget> for Statusbar

impl IsA<Widget> for Switch

impl IsA<Widget> for TextView

impl Ord for Widget

impl<T: ObjectType> PartialEq<T> for Widget

impl<T: ObjectType> PartialOrd<T> for Widget

impl StaticType for Widget

Auto Trait Implementations

impl RefUnwindSafe for Widget

impl !Send for Widget

impl !Sync for Widget

impl Unpin for Widget

impl UnwindSafe for Widget

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<Super, Sub> CanDowncast<Sub> for Super where
    Sub: IsA<Super>,
    Super: IsA<Super>, 

impl<T> Cast for T where
    T: ObjectType, 

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ObjectExt for T where
    T: ObjectType, 

impl<'a, T> ToGlibContainerFromSlice<'a, *const GList> for T where
    T: GlibPtrDefault + ToGlibPtr<'a, <T as GlibPtrDefault>::GlibType>, 

type Storage = (Option<List>, Vec<Stash<'a, <T as GlibPtrDefault>::GlibType, T>>)

impl<'a, T> ToGlibContainerFromSlice<'a, *mut GArray> for T where
    T: GlibPtrDefault + ToGlibPtr<'a, <T as GlibPtrDefault>::GlibType>, 

type Storage = (Option<Array>, Vec<Stash<'a, <T as GlibPtrDefault>::GlibType, T>>)

impl<'a, T> ToGlibContainerFromSlice<'a, *mut GList> for T where
    T: GlibPtrDefault + ToGlibPtr<'a, <T as GlibPtrDefault>::GlibType>, 

type Storage = (Option<List>, Vec<Stash<'a, <T as GlibPtrDefault>::GlibType, T>>)

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T> ToValue for T where
    T: SetValue + ?Sized

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = !

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.