osui::elements::flex
The flex
module provides FlexRow
and FlexCol
elements, which are powerful layout containers for automatically arranging their children either horizontally or vertically, with optional spacing. They are "ghost" elements, meaning they control the layout of their children but don't draw any visual elements themselves by default.
FlexRow
Struct
Arranges children in a row (horizontally).
pub struct FlexRow {
pub gap: u16, // Spacing in cells between adjacent children horizontally
children: Vec<Arc<Widget>>,
size: (u16, u16), // Internal tracking of the FlexRow's calculated size
}
Associated Methods
FlexRow::new() -> Self
Creates a new FlexRow
instance with no children, no gap, and default size.
Example:
use osui::prelude::*;
let my_row = FlexRow::new();
Element
Trait Implementation for FlexRow
render(&mut self, scope: &mut RenderScope, _: &RenderContext)
Similar to Div
, this method primarily ensures the RenderScope
's area reflects its calculated size. It doesn't draw anything visually for the FlexRow
itself.
after_render(&mut self, scope: &mut RenderScope, render_context: &RenderContext)
This method calculates and applies the layout for its children:
- Clones the
RenderScope
'sRawTransform
to use as a basis. - Stores the original parent size from the
RenderScope
. - Sets the
RenderScope
'sparent_size
to its own (FlexRow's) determinedwidth
andheight
. - Initializes
v = 0
; this variable tracks the current horizontal offset for placing children. - Creates a
RowRenderer
helper which will modifyRenderScope
's transforms for each child. - Iterates through
self.children
, callingscope.render_widget
for each. TheRowRenderer
updates thex
position for each child and incrementsv
to prepare for the next child. - Restores the original
parent_size
to theRenderScope
. - Updates
self.size
based on the final accumulated width and maximum height of its children (as calculated byRowRenderer
).
draw_child(&mut self, element: &Arc<Widget>)
Adds a child Widget
to the FlexRow
's internal children
list and injects NoRenderRoot
into the child to prevent direct rendering by the main Screen
loop.
is_ghost(&mut self) -> bool
Returns true
, as FlexRow
is a layout-only container.
as_any(&self) -> &dyn std::any::Any
/ as_any_mut(&mut self) -> &mut dyn std::any::Any
Standard implementations for downcasting.
FlexCol
Struct
Arranges children in a column (vertically).
pub struct FlexCol {
pub gap: u16, // Spacing in cells between adjacent children vertically
children: Vec<Arc<Widget>>,
size: (u16, u16), // Internal tracking of the FlexCol's calculated size
}
Associated Methods
FlexCol::new() -> Self
Creates a new FlexCol
instance with no children, no gap, and default size.
Example:
use osui::prelude::*;
let my_col = FlexCol::new();
Element
Trait Implementation for FlexCol
The implementation mirrors FlexRow
, but for vertical arrangement:
render(&mut self, scope: &mut RenderScope, _: &RenderContext)
Ensures RenderScope
area is set. No direct drawing.
after_render(&mut self, scope: &mut RenderScope, render_context: &RenderContext)
- Clones
RawTransform
. - Sets
RenderScope
parent_size
to its own dimensions. - Initializes
v = 0
(this variable tracks the current vertical offset). - Creates a
ColumnRenderer
helper. - Iterates
children
, callingscope.render_widget
. TheColumnRenderer
updates they
position for each child and incrementsv
for the next child. - Restores original
parent_size
. - Updates
self.size
based on the accumulated height and maximum width of its children.
draw_child(&mut self, element: &Arc<Widget>)
Adds child and injects NoRenderRoot
.
is_ghost(&mut self) -> bool
Returns true
.
as_any(&self) -> &dyn std::any::Any
/ as_any_mut(&mut self) -> &mut dyn std::any::Any
Standard implementations.
RowRenderer
(Helper)
An ElementRenderer
implementation specifically for FlexRow
to adjust the RenderScope
for its children's positions.
pub struct RowRenderer<'a>(&'a mut RawTransform, u16, &'a mut u16);
ElementRenderer
Trait Implementation for RowRenderer
before_draw(&mut self, scope: &mut RenderScope, _widget: &Arc<Widget>)
Called for each child of a FlexRow
just before the child is drawn.
- Updates the
FlexRow
'sRawTransform
(self.0
) to encompass the child's area and the running horizontal offset. - Adjusts the child's
RawTransform
(t
) by the parentFlexRow
's absolute position and adds the current horizontal offset (*self.2
). - Increments
*self.2
(the running horizontal offset) by the child's width, its horizontal padding, and thegap
to prepare for the next child. - Adds the parent
FlexRow
's padding to the child'sRawTransform
padding.
ColumnRenderer
(Helper)
An ElementRenderer
implementation specifically for FlexCol
to adjust the RenderScope
for its children's positions.
pub struct ColumnRenderer<'a>(&'a mut RawTransform, u16, &'a mut u16);
ElementRenderer
Trait Implementation for ColumnRenderer
before_draw(&mut self, scope: &mut RenderScope, _widget: &Arc<Widget>)
Called for each child of a FlexCol
just before the child is drawn.
- Updates the
FlexCol
'sRawTransform
(self.0
) to encompass the child's area and the running vertical offset. - Adjusts the child's
RawTransform
(t
) by the parentFlexCol
's absolute position and adds the current vertical offset (*self.2
). - Increments
*self.2
(the running vertical offset) by the child's height, its vertical padding, and thegap
to prepare for the next child. - Adds the parent
FlexCol
's padding to the child'sRawTransform
padding.
Usage in rsx!
use osui::prelude::*;
rsx! {
// A FlexRow with 2 cells gap between items
@Transform::new().padding(1,1);
@Style { background: Background::Outline(0x00FF00) };
FlexRow, gap: 2, {
"First Item"
Div { "Second Item (a Div)" }
@Style { foreground: Some(0xFF0000) };
"Third Item (Red Text)"
}
// A FlexCol with 1 cell gap, centered horizontally
@Transform::new().x(Center).margin(0, 5); // Margin to separate from the row above
@Style { background: Background::Outline(0x0000FF) };
FlexCol, gap: 1, {
"Column Item 1"
Input { } // An input field
"Column Item 3"
}
}
Flex containers are powerful for building responsive and neatly aligned layouts without manual coordinate calculations.