[−][src]Struct druid::widget::Flex
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 isCrossAxisAlignment::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 istrue
, 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]
self,
child: impl Widget<T> + 'static,
params: impl Into<FlexParams>
) -> Self
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]
&mut self,
child: impl Widget<T> + 'static,
params: impl Into<FlexParams>
)
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]
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env)
[src]
fn lifecycle(
&mut self,
ctx: &mut LifeCycleCtx,
event: &LifeCycle,
data: &T,
env: &Env
)
[src]
&mut self,
ctx: &mut LifeCycleCtx,
event: &LifeCycle,
data: &T,
env: &Env
)
fn update(&mut self, ctx: &mut UpdateCtx, _old_data: &T, data: &T, env: &Env)
[src]
fn layout(
&mut self,
ctx: &mut LayoutCtx,
bc: &BoxConstraints,
data: &T,
env: &Env
) -> Size
[src]
&mut self,
ctx: &mut LayoutCtx,
bc: &BoxConstraints,
data: &T,
env: &Env
) -> Size
fn paint(&mut self, ctx: &mut PaintCtx, data: &T, env: &Env)
[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,
T: Unpin,
impl<T> !UnwindSafe for Flex<T>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> RoundFrom<T> for T
fn round_from(x: T) -> T
impl<T, U> RoundInto<U> for T where
U: RoundFrom<T>,
U: RoundFrom<T>,
fn round_into(self) -> U
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]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,