Search Results for

    Show / Hide Table of Contents

    Class FlexboxLayoutAlgorithm410

    Summer 2022: Current/most recommended Layout Algorithm (this is the official algorithm for the 4.0.0 release of FlexBuilder) available in the standard (non-Pro) release.

    Implements the CSS3 FlexBox Specification following the suggested algorithm in the specification itself (which is not 100% optimal in performance, but produces the 'most correct' visual results).

    Inheritance
    Object
    IFlexboxLayoutAlgorithm
    ILayoutAlgorithmV4
    ILayoutAlgorithmV4x1
    FlexboxLayoutAlgorithm410
    Implements
    IFlexboxDescribableLayoutAlgorithm,
    Inherited Members
    ILayoutAlgorithmV4x1.calculatorForContentSizes
    ILayoutAlgorithmV4x1._InlineAxisFor(FlexItem)
    ILayoutAlgorithmV4x1.CalculateContentSizeFromPhase1Results(FlexContainer, List<FlexLine>, Axis, Boolean)
    ILayoutAlgorithmV4x1._CacheInvalidateMinContentSize(FlexItem)
    ILayoutAlgorithmV4x1._CacheInvalidateMaxContentSize(FlexItem)
    ILayoutAlgorithmV4x1._SetChildSizes(FlexContainer, List<FlexLine>, Dictionary<FlexItem, Vector2>, Action<FlexContainer, Vector2>)
    ILayoutAlgorithmV4x1._ExecutePhase1(FlexContainer, CSSContainerSize, Nullable<Vector2>)
    ILayoutAlgorithmV4x1._ExecutePhase2(FlexContainer, List<FlexLine>)
    ILayoutAlgorithmV4x1.Phase2PositionChildren(FlexContainer, List<FlexLine>)
    ILayoutAlgorithmV4.CalculateAdvances(Int32, FlexContainer, Single, Single, Single)
    ILayoutAlgorithmV4.ResolveAlignSelf(FlexItem)
    ILayoutAlgorithmV4._HasResolvableLengthForAxis(FlexItem, Axis, Nullable<Single>)
    ILayoutAlgorithmV4._GetFirstAncestorComponent<T>(Transform)
    ILayoutAlgorithmV4._GetHighestAncestorComponent<T>(Transform)
    ILayoutAlgorithmV4.IsScrollportContainer(FlexContainer)
    ILayoutAlgorithmV4._ScaledShrinkFactor(FlexItem, Single, Axis, Nullable<Single>)
    ILayoutAlgorithmV4.ConvertBoxLengthToOuterLength(FlexItem, Axis, Single, ContentLength, Boolean)
    ILayoutAlgorithmV4.ConvertBoxLengthToOuterLength(FlexItem, Axis, Single, CSSAvailableLength, Boolean)
    ILayoutAlgorithmV4.ConvertBoxLengthToOuterLength(FlexItem, Axis, BoxLength, CSSAvailableLength, Boolean)
    ILayoutAlgorithmV4.ConvertOuterLengthToBoxLength(FlexItem, Single, Axis, CSSAvailableLength)
    ILayoutAlgorithmV4.Legacy_ConvertOuterLengthToBoxLength(FlexItem, Single, Axis, CSSAvailableLength)
    ILayoutAlgorithmV4.ConvertOuterLengthToBoxLength(FlexItem, Single, Axis, ContentLength)
    ILayoutAlgorithmV4.ConvertContentSizeToBoxSize(FlexItem, Vector2, Vector2)
    ILayoutAlgorithmV4.ConvertContentLengthToBoxLength(FlexItem, ContentLength, Axis, CSSAvailableLength)
    ILayoutAlgorithmV4.ConvertContentLengthToBoxLength(FlexItem, ContentLength, Axis, ContentLength)
    ILayoutAlgorithmV4.ConvertContentLengthToBoxLength(FlexItem, ContentLength, Axis, Nullable<Single>)
    ILayoutAlgorithmV4.ConvertContentLengthToAvailableLength(ContentLength)
    ILayoutAlgorithmV4.ConvertBoxLengthToContentLength(FlexItem, Single, Axis, CSSAvailableSpace)
    ILayoutAlgorithmV4.ConvertBoxLengthToContentLength(FlexItem, Single, Axis, ContentLength)
    ILayoutAlgorithmV4.ConvertBoxLengthToContentLength(FlexItem, BoxLength, Axis, CSSAvailableLength)
    ILayoutAlgorithmV4.ConvertSelfContainingBlockSizeToContentLength(FlexItem, DefiniteContainingBlockSize, Axis)
    ILayoutAlgorithmV4.ConvertBoxLengthToInnerLength(FlexItem, Axis, BoxLength, DefiniteContainingBlockSize)
    ILayoutAlgorithmV4.Legacy_ConvertBoxLengthToInnerLength(FlexItem, Axis, Single)
    ILayoutAlgorithmV4.ConvertPaddingLengthToContentLength(FlexItem, PaddingLength, Axis, Func<Nullable<Single>>)
    ILayoutAlgorithmV4.ConvertBoxLengthToPaddingLength(FlexItem, BoxLength, Axis, CSSAvailableSpace2)
    ILayoutAlgorithmV4.ConvertBoxLengthToBorderLength(FlexItem, Single, Axis, ContentLength)
    ILayoutAlgorithmV4.ConvertBoxLengthToPaddingLength(FlexItem, BoxLength, Axis, CSSAvailableLength)
    ILayoutAlgorithmV4.ConvertOuterLengthToBorderLength(FlexItem, Single, Axis, CSSAvailableLength)
    ILayoutAlgorithmV4.IsFullyInflexible(FlexItem)
    ILayoutAlgorithmV4.CanGrowOrShrinkIn(FlexItem, Axis)
    ILayoutAlgorithmV4.IsDefinite(FlexContainer, Axis, Single)
    ILayoutAlgorithmV4.IsDefinite(FlexItem, Axis, Single)
    ILayoutAlgorithmV4.IsDefinite(GameObject, Axis, Single)
    ILayoutAlgorithmV4.debugExecutedTimes()
    ILayoutAlgorithmV4.lastTimePhase1Executed(FlexContainer)
    ILayoutAlgorithmV4.lastTimePhase2Executed(FlexContainer)
    ILayoutAlgorithmV4.executedPhase1OnContainer(FlexContainer)
    ILayoutAlgorithmV4.executedPhase2OnContainer(FlexContainer)
    IFlexboxLayoutAlgorithm.version
    IFlexboxLayoutAlgorithm.defaultAssetName
    Namespace: NinjaTools.FlexBuilder.LayoutAlgorithms
    Assembly: cs.temp.dll.dll
    Syntax
    public class FlexboxLayoutAlgorithm410 : ILayoutAlgorithmV4x1, IFlexboxDescribableLayoutAlgorithm

    Properties

    - (ReadOnlyCollection<String>) featureDescription

    Overrides
    ILayoutAlgorithmV4.featureDescription

    Methods

    - (Nullable<Single>) ClampToContainersInnerMinMaxSizes(FlexItem, ContentLength, Axis)

    InnerContentLengthOfContainerIfAlreadyKnown(FlexItem, Nullable<Single>, Axis) - this simpler version is used much later, during Spec 9.4.8.3, when an edge-case needs to "clamp the line’s cross-size to be within the container’s computed min and max cross sizes"

    Parameters
    FlexItem containerAsItem
    ContentLength boxLength
    Axis axis
    Returns
    Nullable<Single>

    - (ContentLength) ContentLengthItemInAxis(FlexItem, Axis, CSSAvailableSpace, Boolean, Boolean)

    Parameters
    FlexItem item
    Axis axis
    CSSAvailableSpace containersInnerSize
    Boolean scaleToFit
    Boolean containerIsShowDebugMessages
    Returns
    ContentLength

    - (Vector2) ContentSizeOfContainerInAxis(FlexContainer, Axis, CSSAvailableSpace, Boolean, Boolean)

    Parameters
    FlexContainer itemIsContainer
    Axis axis
    CSSAvailableSpace containersInnerSize
    Boolean scaleToFit
    Boolean containerIsShowDebugMessages
    Returns
    Vector2

    - (ContentLength) GetItemLengthInAxis(FlexItem, Axis, CSSAvailableSpace, Boolean, Boolean)

    NOTE: This is where ALMOST ALL execution time happens: either being forced to recursively relayout child FlexContainer(s) and/or being forced to query the Unity Transform tree and run heuristics to decide what an appropriate ContentSize is for a given GameObject.

    In several places the Spec is badly defined, and says essentially 'figure it out yourself, invent a 'size' for a thing, and we're going to leave you guessing what that means in this particular context'. This method tries to handle all those cases - in particular: it will calculate the 'most appropriate' content-size for the supplied item, using the contextual information provided (different callers will setup the 'available-space' parameter differently based on their own conextual clues/requirements)

    Parameters
    FlexItem item
    Axis axis
    CSSAvailableSpace containersInnerSize
    Boolean scaleToFit
    Boolean containerIsShowDebugMessages
    Returns
    ContentLength

    - (Boolean) HasValidSize(FlexContainer)

    Current implementation: any size with zero OR positive lengths in both dimensions is 'valid' (even if it is 0-width or 0-height); the only 'invalid' sizes are negative ones.

    TODO: upgrade this system to actually store explicit valid/invalid data either on each FlexContainer, or in a parallel data structure.

    Parameters
    FlexContainer container
    Returns
    Boolean

    - (ContentLength) InnerContentLengthOfContainerIfAlreadyKnown(FlexItem, Nullable, Axis)

    The problem: There is a bug in the official spec, in 9.2.2 it glosses-over a core problem: the authors never calculate the value of "the space available to the flex container" (they only ever calculate the space available WITHIN the container, ie available to the container's children) -- and they naively characterise this as "might result in an infinite value" -- but the reality is: it should rarely result in infinite, and it's up to us as implementers to do something considerably more intelligent and responsible than the spec authors did.

    This method provides an extensible/replaceable way of making the decision.

    Ideal is: scan upwards through the FlexContainer hierarchy until we EITHER find an ancestor FlexContainer that is 'invalid' in size (forcing us to return 'null', aka infinite), OR we find an ancestor with definite INNER size.

    Default is: check only the immediate 'container's parent container', and use the rules for %age in an unknown context, which in CSS are: 1. %age width/max-width/height/min-height etc convert to 'AUTO', and 2. padding converts to '0'.

    If there's no parent container, or the parent has invalid size, we return null, forcing the Spec-9.3 code to NEVER WRAP lines (because it interprets that as 'infinite space'.


    NOTE: The PRIMARY challenge is when you encounter percentage values of padding: if the initial container has non-percentage padding then this method terminates immediately, as it requires only a simple check on "is container's parent container valid or not?"


    Parameters
    FlexItem containerAsItem
    Nullable<Single> boxLength
    Axis axis
    Returns
    ContentLength

    - (Boolean) IsDefiniteSize(ContentLength, out Single)

    Ideally you should not be using this, but there is one place where the CSSContentLengthConstrainable has already been converted down, using .definiteValue, and so its cleaner for that code to call this variant on IsDefiniteSize(CSSContentLengthConstrainable, out Single) and have the same readable code than to be doing the null-check there.

    Parameters
    ContentLength length
    Single definiteValue
    Returns
    Boolean

    - (Boolean) IsDefiniteSize(CSSContainerLength, out Single)

    Parameters
    CSSContainerLength length
    Single definiteValue
    Returns
    Boolean

    - (Boolean) IsDefiniteSize(CSSContentLengthConstrainable, out Single)

    This is used in two places where the Spec says "if container's cross-size is definite", but the Spec is wrong: the cross-size is NOT definite (according to CSS: "can be determined without performing layout" - https://www.w3.org/TR/css-sizing-3/#definite) in either place but it might be known in each place because the layout needed to determine it has ALREADY been performed DURING this layout-execution. We treat that case "as if" it were definite - and the browser vendors appear to do the same thing, so we assume it is the Spec that is wrong (perhaps the authors didn't read the CSS-Sizing-3 Spec closely enough, and used 'definite' wrongly - but it's hard to tell since 'definite' is so badly defined even there, and Flexbox authors chose to explictly REDEFINE it in a semi-proprietary fashion too!).

    Parameters
    CSSContentLengthConstrainable length
    Single definiteValue
    Returns
    Boolean

    - (Nullable<Single>) MinMainSizeForItemInAxis(FlexItem, Axis, ContentLength, Boolean)

    Used by 9.7.x to limit the shrinking of items during flex-shrink

    Specification: (incomprehensibly complex) "Clamp each non-frozen item’s target main size by its used min and max main sizes and floor its content-box size at zero." Web-browsers implementation: (slightly more sane, actually how it's done) "Clamp by its used min if it has one, or else by its used size if it has one, or else by its intrinsic minimum content-size in that dimension"

    Parameters
    FlexItem element
    Axis axis
    ContentLength parentSizeForPercentagesInAxis
    Boolean showDebugMessages
    Returns
    Nullable<Single>

    - ((T1, T2)<List<FlexLine>, Dictionary<FlexItem, Vector2>>) Phase1CalculateChildSizes(FlexContainer, CSSContainerSize, CSSAvailableSpace)

    Main method for calculating FlexItem SIZES

    (called by the layout algorithm internally, before it does the calculation of POSITIONS).

    NOTE: returns "BORDER_BOX" sizes, not BOX sizes nor CONTENT_BOX sizes, nor MARGIN_BOX sizes

    Parameters
    FlexContainer container
    CSSContainerSize containersNewSize
    CSSAvailableSpace whenSizeUnknown_parentsAvailableSpace
    Returns
    (T1, T2)<List<FlexLine>, Dictionary<FlexItem, Vector2>>
    Overrides
    ILayoutAlgorithmV4x1.Phase1CalculateChildSizes(FlexContainer, CSSContainerSize, CSSAvailableSpace)

    - (CSSAvailableSpace) Spec_9_2_2_AvailableSpaceWithinContainer(FlexContainer, CSSContainerSize, CSSAvailableSpace)

    Spec: 9.2.2 https://www.w3.org/TR/css-flexbox-1/#algo-available

    NB: we MUST diverge from the spec here a little - basic FlexContainers can follow the Spec but by definition our RootFlexContainers (which contain the special-case handling for 'how we integrate with the wider Unity UI ecosystem') must be doing something a little different - they have to take into account UnityUI.

    NOTE: returns values that are EITHER constraints OR ContentLengths OR null (null meaning 'unknown content-length; for percentage calcs that need a value, use 0 or auto based on contextual clues', as per CSS Sizing Spec)

    Parameters
    FlexContainer container
    CSSContainerSize constrainedOrCurrentSize
    CSSAvailableSpace whenSizeUnknown_parentsAvailableSpace
    Returns
    CSSAvailableSpace

    - (List<FlexLine>) Spec_9_3_5_CollectIntoFlexLines(FlexContainer, List, Dictionary, ContentLength)

    Spec: https://www.w3.org/TR/css-flexbox-1/#algo-line-break

    NOTE: requires a special ContentLength that has been pre-converted to "0" for MIN_CONTENT, or "null" for MAX_CONTENT (where most code uses null for BOTH of those)

    Parameters
    FlexContainer container
    List<FlexItem> childItems
    Dictionary<FlexItem, Single> childOuterHypotheticalLengths
    ContentLength spaceOrInfiniteOrZero
    Returns
    List<FlexLine>

    - (Dictionary<FlexItem, Single>) Spec_9_3_6_ResolveFlexibleLengths(FlexContainer, List, Dictionary, ContentLength)

    Spec: https://www.w3.org/TR/css-flexbox-1/#algo-flex

    9.3.6: "Resolve the flexible lengths of all the flex items to find their used main size." NB: this delegates 100% to 9.7 (yes, the numbering is weird in the specification itself!)

    NOTE: requires a special ContentLength that has been pre-converted to "0" for MIN_CONTENT, or "null" for MAX_CONTENT (where most code uses null for BOTH of those)

    Parameters
    FlexContainer container
    List<FlexLine> flexLines
    Dictionary<FlexItem, Single> childBoxLengths
    ContentLength availableMainLength
    Returns
    Dictionary<FlexItem, Single>

    - (Dictionary<FlexItem, Single>) Spec_9_4_11(FlexContainer, List, Dictionary, ContentLength)

    Spec: 9.4.11 https://www.w3.org/TR/css-flexbox-1/#algo-stretch

    "Determine the used cross size of each flex item [handling STRETCH etc]"

    Parameters
    FlexContainer container
    List<FlexLine> flexLines
    Dictionary<FlexItem, Single> childHypotheticalCrossLengths
    ContentLength containerCrossLengthForPercentages
    Returns
    Dictionary<FlexItem, Single>

    - (void) Spec_9_4_8_1(AlignItems, List, out List)

    Spec: 9.4.8.1 https://www.w3.org/TR/css-flexbox-1/#algo-cross-line

    ------- NOTE: this requires --inline-- axis, which is defined ONLY based on Latin-vs-Japanese/Chinese/etc writing mode --------

    Collect all the flex items whose inline-axis is parallel to the main-axis, whose align-self is baseline, and whose cross-axis margins are both non-auto. Find the largest of the distances between each item’s baseline and its hypothetical outer cross-start edge, and the largest of the distances between each item’s baseline and its hypothetical outer cross-end edge, and sum these two values. Among all the items not collected by the previous step, find the largest outer hypothetical cross size. The used cross-size of the flex line is the largest of the numbers found in the previous two steps and zero. If the flex container is single-line, then clamp the line’s cross-size to be within the container’s computed min and max cross sizes. Note that if CSS 2.1’s definition of min/max-width/height applied more generally, this behavior would fall out automatically."

    Parameters
    AlignItems containerAlignItems
    List<FlexItem> itemsInLine
    List<FlexItem> unprocessedItems

    - (void) Spec_9_4_8_CalculateFlexLinesCrossSizes(FlexContainer, List, Dictionary, CSSContainerLength, CSSAvailableSpace)

    Spec 9.4.8: https://www.w3.org/TR/css-flexbox-1/#algo-cross-line

    "Calculate the cross size of each flex line."

    The Spec authors create a non-defined concept of "a flexline", and then never state what the "size" is of such a thing - is it a box-size, a content-size, a border-size? - leaving it ambiguous how we should later interpret that "size" during sizing and layout.

    By implication, what they failed to write is: "the size of a flexline is an outer-size (ie its a MARGIN_BOX size)", since one of their statements is to calculate it from "the container's inner cross size", and the inner-size of a parent is defined as matching the outer-size of its contents.

    Parameters
    FlexContainer container
    List<FlexLine> flexLines
    Dictionary<FlexItem, Single> childHypotheticalCrossLengths
    CSSContainerLength containerCrossLength
    CSSAvailableSpace containersAvailableSpace

    - (void) Spec_9_4_9_ExpandFlexLinesIfStretch(FlexContainer, List, CSSContainerLength, CSSAvailableSpace)

    Spec 9.4.9: https://www.w3.org/TR/css-flexbox-1/#algo-line-stretch

    As per Spec_9_4_8_CalculateFlexLinesCrossSizes(FlexContainer, List<FlexLine>, Dictionary<FlexItem, Single>, CSSContainerLength, CSSAvailableSpace), we treat the flexlines 'sizes' as 'outer sizes'.

    "Handle 'align-content: stretch'"

    Spec is wrong here: they say the only thing that needs to be definite is "container ... cross size", but their algorithm ALSO requires that the "container ... inner cross size" is definite (which is NOT GUARANTEED by the constraint the Spec authors wrote down - you can have a %age padding (non-definite) with a pixel width (definite)).

    AS A RESULT: if the inner-length can't be directly calculated, we skip this section. TODO: using the already-written IsDefinite() method, consider inserting here specific support for trying to resolve the inner-length (requires recursing up the chain / modifying the definite-length calculation)

    Parameters
    FlexContainer container
    List<FlexLine> lines
    CSSContainerLength containerCrossLengthDefinite
    CSSAvailableSpace containersAvailableSpace

    - (Dictionary<FlexItem, Single>) Spec_9_7_ResolveFlexibleLengths_SingleLine(FlexContainer, FlexLine, Dictionary, Single, ContentLength)

    Spec: https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths

    NB: omits the final step - "Set each item’s used main size to its target main size" - instead returning the 'target main sizes' and leaving it up to the caller to do the 'set' call.

    Parameters
    FlexContainer container
    FlexLine flexLine
    Dictionary<FlexItem, Single> childBoxLengths
    Single leftoverSpace
    ContentLength containerInnerMainLength
    Returns
    Dictionary<FlexItem, Single>

    - (Single) Spec_Sizing3_StretchFitSize(FlexItem, Nullable, Axis)

    Spec: https://www.w3.org/TR/css-sizing-3/#stretch-fit-size

    NOTE: this part of the spec is wrong, and has already been overwritten by future 'unfinished' revisions to the Spec, and the hotlinking in the Spec now is broken (the CSS authors didn't bother to check / fix their links when making updates). We're using (as much as possible) the 'old' version that was originally in the Spec, but the people who write CSS made some terrible decisions here (not least: breaking their own documents during updates!)

    Historically: "stretch-fit size: The size a box would take if its outer size filled the available space in the given axis; in other words, the stretch fit into the available space, if that is definite."

    Parameters
    FlexItem child
    Nullable<Single> availableSpace
    Axis axis
    Returns
    Single
    Exceptions
    Exception

    Implements

    IFlexboxDescribableLayoutAlgorithm,
    In This Article
    Back to top http://flexbuilder.ninja