[][src]Struct druid::widget::Flex

pub struct Flex<T> { /* fields omitted */ }

A container with either horizontal or vertical layout.

This widget is the foundation of most layouts, and is highly configurable.

Flex layout algorithm

Children of a Flex container can have an optional flex parameter. Layout occurs in several passes. First we measure (calling their layout method) our non-flex children, providing them with unbounded space on the main axis. Next, the remaining space is divided between the flex children according to their flex factor, and they are measured. Unlike a non-flex child, a child with a non-zero flex factor has a maximum allowed size on the main axis; non-flex children are allowed to choose their size first, and freely.

If you would like a child to be forced to use up all of the flex space passed to it, you can place it in a SizedBox set to expand in the appropriate axis. There are convenience methods for this available on WidgetExt: expand_width and expand_height.

Flex or non-flex?

When should your children be flexible? With other things being equal, a flexible child has lower layout priority than a non-flexible child. Imagine, for instance, we have a row that is 30dp wide, and we have two children, both of which want to be 20dp wide. If child #1 is non-flex and child #2 is flex, the first widget will take up its 20dp, and the second widget will be constrained to 10dp.

If, instead, both widgets are flex, they will each be given equal space, and both will end up taking up 15dp.

If both are non-flex they will both take up 20dp, and will overflow the container.

 -------non-flex----- -flex-----
|       child #1     | child #2 |


 ----flex------- ----flex-------
|    child #1   |    child #2   |

In general, if you are using widgets that are opinionated about their size (such as most control widgets, which are designed to lay out nicely together, or text widgets that are sized to fit their text) you should make them non-flexible.

If you are trying to divide space evenly, or if you want a particular item to have access to all left over space, then you should make it flexible.

note: by default, a widget will not necessarily use all the space that is available to it. For instance, the TextBox widget has a default width, and will choose this width if possible, even if more space is available to it. If you want to force a widget to use all available space, you should expand it, with expand_width or expand_height.

Options

To experiment with these options, see the flex example in druid/examples.

  • CrossAxisAlignment determines how children are positioned on the cross or 'minor' axis. The default is CrossAxisAlignment::Center.

  • MainAxisAlignment determines how children are positioned on the main axis; this is only meaningful if the container has more space on the main axis than is taken up by its children.

  • must_fill_main_axis determines whether the container is obliged to be maximally large on the major axis, as determined by its own constraints. If this is true, then the container must fill the available space on that axis; otherwise it may be smaller if its children are smaller.

Additional options can be set (or overridden) in the FlexParams.

Examples

Construction with builder methods

use druid::widget::{Flex, FlexParams, Label, Slider, CrossAxisAlignment};

let my_row = Flex::row()
    .cross_axis_alignment(CrossAxisAlignment::Center)
    .must_fill_main_axis(true)
    .with_child(Label::new("hello"))
    .with_spacer(8.0)
    .with_flex_child(Slider::new(), 1.0);

Construction with mutating methods

use druid::widget::{Flex, FlexParams, Label, Slider, CrossAxisAlignment};

let mut my_row = Flex::row();
my_row.set_must_fill_main_axis(true);
my_row.set_cross_axis_alignment(CrossAxisAlignment::Center);
my_row.add_child(Label::new("hello"));
my_row.add_spacer(8.0);
my_row.add_flex_child(Slider::new(), 1.0);

Implementations

impl<T: Data> Flex<T>[src]

pub fn row() -> Self[src]

Create a new horizontal stack.

The child widgets are laid out horizontally, from left to right.

pub fn column() -> Self[src]

Create a new vertical stack.

The child widgets are laid out vertically, from top to bottom.

pub fn cross_axis_alignment(self, alignment: CrossAxisAlignment) -> Self[src]

Builder-style method for specifying the childrens' CrossAxisAlignment.

pub fn main_axis_alignment(self, alignment: MainAxisAlignment) -> Self[src]

Builder-style method for specifying the childrens' MainAxisAlignment.

pub fn must_fill_main_axis(self, fill: bool) -> Self[src]

Builder-style method for setting whether the container must expand to fill the available space on its main axis.

If any children have flex then this container will expand to fill all available space on its main axis; But if no children are flex, this flag determines whether or not the container should shrink to fit, or must expand to fill.

If it expands, and there is extra space left over, that space is distributed in accordance with the MainAxisAlignment.

The default value is false.

pub fn with_child(self, child: impl Widget<T> + 'static) -> Self[src]

Builder-style variant of add_child.

Convenient for assembling a group of widgets in a single expression.

pub fn with_flex_child(
    self,
    child: impl Widget<T> + 'static,
    params: impl Into<FlexParams>
) -> Self
[src]

Builder-style method to add a flexible child to the container.

This method is used when you need more control over the behaviour of the widget you are adding. In the general case, this likely means giving that child a 'flex factor', but it could also mean giving the child a custom CrossAxisAlignment, or a combination of the two.

This function takes a child widget and FlexParams; importantly you can pass in a float as your FlexParams in most cases.

For the non-builder varient, see add_flex_child.

Examples

use druid::widget::{Flex, FlexParams, Label, Slider, CrossAxisAlignment};

let my_row = Flex::row()
    .with_flex_child(Slider::new(), 1.0)
    .with_flex_child(Slider::new(), FlexParams::new(1.0, CrossAxisAlignment::End));

pub fn with_spacer(self, len: impl Into<KeyOrValue<f64>>) -> Self[src]

Builder-style method for adding a fixed-size spacer to the container.

pub fn with_flex_spacer(self, flex: f64) -> Self[src]

Builder-style method for adding a flex spacer to the container.

pub fn set_cross_axis_alignment(&mut self, alignment: CrossAxisAlignment)[src]

Set the childrens' CrossAxisAlignment.

pub fn set_main_axis_alignment(&mut self, alignment: MainAxisAlignment)[src]

Set the childrens' MainAxisAlignment.

pub fn set_must_fill_main_axis(&mut self, fill: bool)[src]

Set whether the container must expand to fill the available space on its main axis.

pub fn add_child(&mut self, child: impl Widget<T> + 'static)[src]

Add a non-flex child widget.

See also with_child.

pub fn add_flex_child(
    &mut self,
    child: impl Widget<T> + 'static,
    params: impl Into<FlexParams>
)
[src]

Add a flexible child widget.

This method is used when you need more control over the behaviour of the widget you are adding. In the general case, this likely means giving that child a 'flex factor', but it could also mean giving the child a custom CrossAxisAlignment, or a combination of the two.

This function takes a child widget and FlexParams; importantly you can pass in a float as your FlexParams in most cases.

For the builder-style varient, see with_flex_child.

Examples

use druid::widget::{Flex, FlexParams, Label, Slider, CrossAxisAlignment};

let mut my_row = Flex::row();
my_row.add_flex_child(Slider::new(), 1.0);
my_row.add_flex_child(Slider::new(), FlexParams::new(1.0, CrossAxisAlignment::End));

pub fn add_spacer(&mut self, len: impl Into<KeyOrValue<f64>>)[src]

Add an empty spacer widget with the given length.

pub fn add_flex_spacer(&mut self, flex: f64)[src]

Add an empty spacer widget with a specific flex factor.

Trait Implementations

impl<T: Data> Widget<T> for Flex<T>[src]

Auto Trait Implementations

impl<T> !RefUnwindSafe for Flex<T>

impl<T> !Send for Flex<T>

impl<T> !Sync for Flex<T>

impl<T> Unpin for Flex<T> where
    T: Unpin

impl<T> !UnwindSafe for Flex<T>

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<T> From<T> for T[src]

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

impl<T> RoundFrom<T> for T

impl<T, U> RoundInto<U> for T where
    U: RoundFrom<T>, 

impl<T> Same<T> for T

type Output = T

Should always be Self

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

type Error = Infallible

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.