Skip to main content

Layout

Struct Layout 

Source
pub struct Layout<'a, T> { /* private fields */ }
Expand description

A layout tree. T is user data attached to the nodes — a colour, say — handed back with each computed rectangle.

Implementations§

Source§

impl<'a, T> Layout<'a, T>

Source

pub fn new() -> Self

Creates an empty tree.

Source

pub fn leaf(&mut self, style: Style, data: T) -> NodeId

Adds a leaf — a node with no children — carrying associated data.

Source

pub fn measured_leaf( &mut self, style: Style, data: T, measure: MeasureFn<'a>, ) -> NodeId

Adds a measured leaf: its size comes from measure, given the space offered, rather than from a dimension fixed in the style.

Source

pub fn add_margin_top(&mut self, node: NodeId, dy: f32)

Adds dy to a node’s top margin, after it has been built.

Baseline alignment needs it: a row can only know how far to push a child down once it has measured every child, and by then the children are nodes rather than styles. Nothing else should reach for this — a style is otherwise settled when the node is made.

Source

pub fn fill_parent(&mut self, node: NodeId, horizontal: bool, grow: bool)

Makes a node fill the space its parent leaves it, after it has been built: growing along the parent’s main axis, stretching across it, or both.

This is what MainAxisSize::Max needs and cannot express on its own. A row that fills its line is asking about the parent’s axis, not its own — grow if the parent runs the same way, stretch if it runs across — and a widget does not know what it was put inside. The parent does, so it says so here.

Source

pub fn allow_shrink(&mut self, node: NodeId)

Lets a node give way along its parent’s main axis, after it has been built.

The default is not to: the reference hands an inflexible child of a row or a column an unbounded main axis, so it is never squeezed and a line that does not fit overflows and says so. Flexbox’s default is the opposite — every item absorbs its share of a deficit — and a framework that quietly crushes a button rather than reporting a layout that does not fit is a framework whose bugs are invisible.

The exception is a box with one child, which is not dividing a line: it is handing its own constraints down, and the reference bounds a lone child by them. Only a node that has not asked for something else is touched. Growing is not asking for something else: a lone child that fills its parent is still bounded by it, and one that both grows and refuses to give way is a box that can only get bigger than the thing holding it.

Source

pub fn set_tile_shape(&mut self, node: NodeId, ratio: f32)

Gives a node the shape of a tile: a height derived from the width it ends up with by ratio (width / height, taffy’s convention and the reference’s).

A grid’s tiles are all the same shape in the reference, and that shape is the container’s say rather than each tile’s — a tile cannot know how wide its column came out — which is why it is imposed here instead of asked of the child.

Only the ratio is set, and that is enough in a grid: a track’s width is definite, so the height follows from it. It would not be enough across a flex, where a box is merely stretched by the cross-axis alignment and there is no number to derive the other axis from (which is why crate::Style::aspect_ratio is paired with a percentage width there).

A child that has already chosen a size of its own keeps it.

Source

pub fn set_min_width(&mut self, node: NodeId, width: f32)

Sets a node’s minimum width, after it has been built.

It is what stops a leaf being squeezed along a row, and only a row can say so: the same number across a column would be a floor on the cross axis, where the box is handed a width rather than asked for one.

Source

pub fn fill_root(&mut self, node: NodeId, horizontal: bool)

Makes the root of a layout fill one axis of whatever room it is computed in.

A root has no parent to grow into, so the flex machinery fill_parent uses has nothing to work with. A percentage does: it resolves against the available space when that space is definite, and falls back to hugging the content when it is not — which is the right answer in both cases. A row at the top of a frame fills the window; the same row measured for its natural size still shrink-wraps.

Source

pub fn container(&mut self, style: Style, children: &[NodeId]) -> NodeId

Adds a container — a node with children — with no associated data.

Source

pub fn compute(&mut self, root: NodeId, available: Size)

Computes the layout from root, within the given available space.

Source

pub fn compute_filled(&mut self, root: NodeId, width: f32, height: f32)

Computes the layout of content that is handed a box: both axes are definite, and an unset (Auto) root dimension takes the box’s size instead of hugging the content.

The distinction from Layout::compute is who decides the size. A widget laid out in the ordinary way is asked how big it wants to be; a page of a paged view is told, and a page that hugged its content would leave the rest of the panel empty and unclickable.

Source

pub fn compute_tight( &mut self, root: NodeId, width: f32, height: f32, free_x: bool, free_y: bool, )

Computes the layout of content forced into a box on the axes that are not free: the node’s own width or height is overruled rather than merely bounded.

The difference from Layout::compute_filled is who wins when the content has already chosen. Filling defers to it — an explicit size is a size the caller asked for — while this overrules it, which is what a stack layer pinned to two opposite edges means: the edges say how wide it is, and a width of its own is not a second opinion but a contradiction.

Source

pub fn compute_scroll( &mut self, root: NodeId, width: f32, height: f32, free_x: bool, free_y: bool, )

Computes the layout of scrollable content: each axis is either constrained to the viewport or free, in which case the content takes its natural size, according to free_x and free_y.

Source

pub fn size_of(&self, node: NodeId) -> Size

The size a node came out at, after a compute*.

Layout::absolute_rects answers the same question for a whole subtree and allocates one entry per node to do it; this is for the one caller that wants a single box back — a measurement asking how big the thing it just laid out is.

Source

pub fn absolute_rects(&self, root: NodeId) -> Vec<(Rect, Option<&T>)>

Walks the tree in prefix order and returns, for each node, its rectangle in absolute coordinates along with any associated data.

taffy expresses positions relative to the parent; here we accumulate the offsets to get absolute coordinates that can be rendered directly.

Source

pub fn overflows(&self, root: NodeId) -> Vec<Overflowing>

Every box in the tree whose children spill out of it, with the edge and the amount — the measurement behind Overflowing.

Only within one taffy tree, which is exactly the useful scope: a scrollable, a stack, a page view, a fitter and an overflow box are all laid out as leaves here and their content computed separately, so content larger than its viewport — the one overflow that is deliberate — never reaches this walk.

Trait Implementations§

Source§

impl<T> Default for Layout<'_, T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'a, T> !RefUnwindSafe for Layout<'a, T>

§

impl<'a, T> !Send for Layout<'a, T>

§

impl<'a, T> !Sync for Layout<'a, T>

§

impl<'a, T> !UnwindSafe for Layout<'a, T>

§

impl<'a, T> Freeze for Layout<'a, T>
where TaffyTree<T>: Freeze,

§

impl<'a, T> Unpin for Layout<'a, T>
where TaffyTree<T>: Unpin,

§

impl<'a, T> UnsafeUnpin for Layout<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.