Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProwlEngine/Prowl.Paper/llms.txt

Use this file to discover all available pages before exploring further.

UnitValue is the fundamental measurement type used throughout Prowl.Paper’s layout engine. Rather than forcing a single unit mode, every UnitValue is a composite of four independent components — Px, Pct, Grow, and AutoFactor — evaluated together as Px + (Pct/100 × parent) + Grow × remainderShare + AutoFactor × contentSize. This design lets you express natural combinations such as “50% of the parent minus 8 pixels” (Percentage(50, -8)) or “fill remaining space with a 10px floor” (Stretch(1) + Pixels(10)) without needing separate union types.

Unit types at a glance

TypeFactoryComponents setResolves using
PixelsUnitValue.Pixels(v)Px = vFixed pixel value
PercentageUnitValue.Percentage(v, offset)Pct = v, Px = offsetFraction of parent size
StretchUnitValue.Stretch(f)Grow = fShare of leftover space
AutoUnitValue.AutoAutoFactor = 1Element’s content size

Struct fields

Px
float
Raw pixel offset. Contributes a fixed amount to the resolved size regardless of parent or content dimensions.
Pct
float
Percentage of the parent container’s corresponding dimension, expressed in the range 0–100. A value of 50 means 50% of the parent.
Grow
float
Stretch (flex-grow) factor. After all fixed and percentage sizes are subtracted from the available space, the remainder is distributed among siblings weighted by their Grow values.
AutoFactor
float
Content-size multiplier. 1.0 means “use the full intrinsic content size”; 0.0 means content is ignored. The sentinel value UnitValue.Auto sets this to 1 with all other components at 0.

Constructor

public UnitValue(float px, float pct = 0f, float grow = 0f, float autoFactor = 0f)
Directly constructs a composite unit value. Prefer the factory methods below for common cases.

Factory methods

UnitValue.Pixels(float value)

Creates a pure pixel value with no percentage, stretch, or auto component.
UnitValue width = UnitValue.Pixels(120f); // Always 120 pixels wide

UnitValue.Percentage(float value, float offset = 0f)

Creates a percentage of the parent, with an optional pixel offset baked in. The offset is stored in Px so arithmetic remains clean.
UnitValue half      = UnitValue.Percentage(50f);       // 50% of parent
UnitValue halfMinus = UnitValue.Percentage(50f, -8f);  // 50% − 8px

UnitValue.Stretch(float factor = 1f)

Creates a stretch unit that claims a proportional share of the remaining space after fixed/percentage elements are placed. Siblings with higher factors get proportionally more space.
UnitValue fill   = UnitValue.Stretch();      // factor = 1 (default)
UnitValue double = UnitValue.Stretch(2f);    // claims twice as much as Stretch(1)

Pre-allocated constants

ConstantEquivalentNotes
UnitValue.Autonew UnitValue(0,0,0,1)Sizes to content
UnitValue.ZeroPixelsnew UnitValue(0,0,0,0)Explicit zero
UnitValue.StretchOnenew UnitValue(0,0,1,0)Stretch(1) without allocation

Predicate properties

All predicates are read-only and examine the raw component values:
PropertyReturns true when…
HasGrowGrow > 0 — participates in stretch distribution
HasAutoAutoFactor > 0 — has a content-size contribution
IsFixedGrow == 0 && AutoFactor == 0 — resolves without stretch or content measurement
IsAutoExactly the Auto sentinel (Px=0, Pct=0, Grow=0, AutoFactor=1)
IsStretchPurely a stretch factor — no Px, Pct, or AutoFactor
IsPixelsPurely a pixel value — no Pct, Grow, or AutoFactor
IsPercentageCarries a Pct component with no Grow or AutoFactor
UnitValue.Pixels(40).IsFixed      // true
UnitValue.Stretch().HasGrow       // true
UnitValue.Auto.IsAuto             // true
UnitValue.Percentage(50).IsFixed  // true — percentages are fixed relative to parent
IsFixed returns true for percentage values because they resolve to a definite length once the parent size is known, without participating in stretch competition or content measurement.

Arithmetic operators

UnitValue arithmetic combines components element-wise, making compound values natural to express:
// "Fill remaining space but never narrower than 10px"
UnitValue minFloor = UnitValue.Stretch(1) + UnitValue.Pixels(10);

// "50% of parent minus 8px padding"
UnitValue padded = UnitValue.Percentage(50) + UnitValue.Pixels(-8);

// Scale a value
UnitValue doubled = UnitValue.Pixels(100) * 2f;
OperatorDescription
a + bComponent-wise addition
a - bComponent-wise subtraction
-aNegate all components
a * scalarScale all components by a float
scalar * aCommutative scalar multiply
a / scalarDivide all components by a float

Interpolation

UnitValue.Lerp(UnitValue a, UnitValue b, float t)

Linearly interpolates each component independently. t is clamped to [0, 1]. Because components are interpolated separately, mixing unit types produces intermediate values that are meaningful — for example, Lerp(Pixels(0), Auto, 0.5f) yields {AutoFactor: 0.5}, which contributes half the content size.
UnitValue start  = UnitValue.Pixels(0);
UnitValue end    = UnitValue.Pixels(200);
UnitValue midway = UnitValue.Lerp(start, end, 0.5f); // Pixels(100)

// Used automatically by the animation system during Transition()
The style transition engine calls UnitValue.Lerp internally whenever a layout property like Width or Height is animated with .Transition(GuiProp.Width, duration).

Implicit conversions

Both int and float implicitly convert to UnitValue as pixel values, so you can pass numeric literals directly to any layout API:
element.Width(200);     // Same as Width(UnitValue.Pixels(200))
element.Height(48f);    // Same as Height(UnitValue.Pixels(48f))

Comparison and equality

UnitValue implements IEquatable<UnitValue>. Two values are equal when all four components are identical:
bool eq = UnitValue.Pixels(10) == UnitValue.Pixels(10); // true
bool ne = UnitValue.Pixels(10) != UnitValue.Auto;        // true
The == / != operators delegate to Equals(UnitValue other), which compares Px, Pct, Grow, and AutoFactor as floats.

ToString()

Returns a human-readable string listing only the non-zero components, joined with +:
UnitValue.Pixels(40).ToString()                           // "40px"
UnitValue.Percentage(50, -8).ToString()                   // "-8px + 50%"
UnitValue.Stretch(2).ToString()                           // "2grow"
UnitValue.Auto.ToString()                                 // "1auto"
(UnitValue.Stretch(1) + UnitValue.Pixels(10)).ToString()  // "10px + 1grow"
new UnitValue(0,0,0,0).ToString()                         // "0px"

Resolution internals

Two methods expose how a value is resolved at layout time. These are used by the layout engine and are rarely needed in application code:
// Fixed floor only: Px + (Pct/100) × parentValue
float floor = value.Floor(parentValue);

// Full resolution including grow/auto contributions via a defaultValue fallback
float px = value.ToPx(parentValue, defaultValue);

// Resolved and clamped between min and max
float clamped = value.ToPxClamped(parentValue, defaultValue, in min, in max);

Practical examples

// Absolute pixel dimensions
element.Width(UnitValue.Pixels(320f))
       .Height(UnitValue.Pixels(48f));

Build docs developers (and LLMs) love