Module taffy::tree::traits

source ·
Expand description

The abstractions that make up the core of Taffy’s low-level API

§Examples

The following examples demonstrate end-to-end implementation of Taffy’s traits and usage of the low-level compute APIs:

  • custom_tree_vec which implements a custom Taffy tree using a Vec as an arena with NodeId’s being index’s into the Vec.
  • custom_tree_owned_partial which implements a custom Taffy tree using directly owned children with NodeId’s being index’s into vec on parent node.
  • custom_tree_owned_unsafe which implements a custom Taffy tree using directly owned children with NodeId’s being pointers.

§Overview

§Trait dependency tree

The tree below illustrates which traits depend on which other traits.

TraversePartialTree     - Access a node's children
├──  LayoutPartialTree  - Run layout algorithms on a node and it's direct children
└──  TraverseTree       - Recursively access a node's descendants
    ├──  RoundTree      - Round a float-valued`  layout to integer pixels
    └──  PrintTree      - Print a debug representation of a node tree

§A table of traits

§All of the traits on one page

§TraversePartialTree and TraverseTree

These traits are Taffy’s abstraction for downward tree traversal:

  • TraversePartialTree allows access to a single container node, and it’s immediate children. This is the only “traverse” trait that is required for use of Taffy’s core layout algorithms (flexbox, grid, etc).
  • TraverseTree is a marker trait which uses the same API signature as TraversePartialTree, but extends it with a guarantee that the child/children methods can be used to recurse infinitely down the tree. It is required by the RoundTree and the PrintTree traits.
pub trait TraversePartialTree {
    /// Type representing an iterator of the children of a node
    type ChildIter<'a>: Iterator<Item = NodeId>
    where
        Self: 'a;

    /// Get the list of children IDs for the given node
    fn child_ids(&self, parent_node_id: NodeId) -> Self::ChildIter<'_>;

    /// Get the number of children for the given node
    fn child_count(&self, parent_node_id: NodeId) -> usize;

    /// Get a specific child of a node, where the index represents the nth child
    fn get_child_id(&self, parent_node_id: NodeId, child_index: usize) -> NodeId;
}

pub trait TraverseTree: TraversePartialTree {}

You must implement TraversePartialTree to access any of Taffy’s low-level API. If your tree implementation allows you to implement TraverseTree with the correct semantics (full recursive traversal is available) then you should.

§LayoutPartialTree

Requires: TraversePartialTree
Enables: Flexbox, Grid, Block and Leaf layout algorithms from the crate::compute module

Any type that implements LayoutPartialTree can be laid out using Taffy’s algorithms

Note that this trait extends TraversePartialTree (not TraverseTree). Taffy’s algorithm implementations have been designed such that they can be used for a laying out a single node that only has access to it’s immediate children.

pub trait LayoutPartialTree: TraversePartialTree {
    /// Get a reference to the [`Style`] for this node.
    fn get_style(&self, node_id: NodeId) -> &Style;

    /// Set the node's unrounded layout
    fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout);

    /// Get a mutable reference to the [`Cache`] for this node.
    fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache;

    /// Compute the specified node's size or full layout given the specified constraints
    fn compute_child_layout(&mut self, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput;
}

§RoundTree

Requires: TraverseTree

Trait used by the round_layout method which takes a tree of unrounded float-valued layouts and performs rounding to snap the values to the pixel grid.

As indicated by it’s dependence on TraverseTree, it required full recursive access to the tree.

pub trait RoundTree: TraverseTree {
    /// Get the node's unrounded layout
    fn get_unrounded_layout(&self, node_id: NodeId) -> &Layout;
    /// Get a reference to the node's final layout
    fn set_final_layout(&mut self, node_id: NodeId, layout: &Layout);
}

§PrintTree

Requires: TraverseTree

/// Trait used by the `print_tree` method which prints a debug representation
///
/// As indicated by it's dependence on `TraverseTree`, it required full recursive access to the tree.
pub trait PrintTree: TraverseTree {
    /// Get a debug label for the node (typically the type of node: flexbox, grid, text, image, etc)
    fn get_debug_label(&self, node_id: NodeId) -> &'static str;
    /// Get a reference to the node's final layout
    fn get_final_layout(&self, node_id: NodeId) -> &Layout;
}

Traits§

  • Trait used by the compute_cached_layout method which allows cached layout results to be stored and retrieved.
  • Extends LayoutPartialTree with getters for the styles required for CSS Grid layout
  • Any type that implements LayoutPartialTree can be laid out using Taffy’s algorithms
  • A private trait which allows us to add extra convenience methods to types which implement LayoutTree without making those methods public.
  • Trait used by the print_tree method which prints a debug representation
  • Trait used by the round_layout method which takes a tree of unrounded float-valued layouts and performs rounding to snap the values to the pixel grid.
  • Taffy’s abstraction for downward tree traversal.
  • A marker trait which extends TraversePartialTree