etui/geometry
Types
A responsive breakpoint: applies constraints when area width >= min_width.
pub type Breakpoint {
Breakpoint(min_width: Int, constraints: List(Constraint))
}
Constructors
-
Breakpoint(min_width: Int, constraints: List(Constraint))
Layout constraint: how much space to claim.
Priority (highest → lowest): Length > Min/Max > Ratio/Percentage > Fill
pub type Constraint {
Length(Int)
Min(Int)
Max(Int)
Percentage(Int)
Ratio(Int, Int)
Fill
}
Constructors
-
Length(Int)Fixed cell count. Highest priority. Allocated first.
-
Min(Int)At least n cells. Participates in flexible distribution with a floor.
-
Max(Int)At most n cells. Participates in flexible distribution with a ceiling.
-
Percentage(Int)Percentage of total (0..100). Computed cumulatively to avoid pixel loss.
-
Ratio(Int, Int)Rational fraction of total: numerator/denominator. Exact integer math.
Ratio(1, 3)is one-third of the total space. -
FillFlexible. Divides leftover equally after Length + Percentage + Ratio.
How to split a rectangle when laying out widgets.
pub type Direction {
Horizontal
Vertical
}
Constructors
-
HorizontalConstraints stacked along X axis (side-by-side columns).
-
VerticalConstraints stacked along Y axis (rows).
How to distribute leftover space among children in a flex layout.
| Justify | Description |
|---|---|
FlexStart | Pack children at the start; leftover space at the end. |
FlexEnd | Pack children at the end; leftover space at the start. |
FlexCenter | Center children; leftover space split evenly on both sides. |
FlexBetween | Children spread out; space between them (none at edges). |
FlexAround | Equal space around each child (half at edges). |
pub type FlexJustify {
FlexStart
FlexEnd
FlexCenter
FlexBetween
FlexAround
}
Constructors
-
FlexStart -
FlexEnd -
FlexCenter -
FlexBetween -
FlexAround
Coordinate on the screen.
pub type Position {
Position(x: Int, y: Int)
}
Constructors
-
Position(x: Int, y: Int)
Values
pub fn bottom(rect: Rect) -> Int
Y coordinate of the bottom edge (exclusive: y + height).
pub fn centered_rect(width: Int, height: Int, area: Rect) -> Rect
Center a rect of width × height within area.
Clamps to area bounds. Common for popup placement.
let popup_area = geometry.centered_rect(60, 20, screen)
pub fn contains(rect: Rect, pos: Position) -> Bool
Check if a position is inside the rect (inclusive of edges).
pub fn hit_test(rect: Rect, x: Int, y: Int) -> Bool
True if terminal cell (x, y) is inside rect.
Convenience wrapper over contains for use with mouse event coordinates.
pub fn intersect(a: Rect, b: Rect) -> Result(Rect, Nil)
Intersection of two rects. Returns the overlapping rect if any.
pub fn percent_rect(pct_w: Int, pct_h: Int, area: Rect) -> Rect
Center a rect sized as a percentage of area (pct_w and pct_h are 0–100).
Useful for responsive popup sizing:
let popup_area = geometry.percent_rect(60, 40, screen) // 60% wide, 40% tall
pub fn rect_new(x: Int, y: Int, width: Int, height: Int) -> Rect
Create a Rect with clamped width/height to non-negative.
pub fn resolve_sizes(
total: Int,
constraints: List(Constraint),
) -> List(Int)
Distribute total space among constraints.
Returns a list of sizes (one per constraint) that sum to ≤ total. Sum equals total when Fill (or Min/Max) is present or constraints saturate.
Algorithm (three-phase Discrete Cumulative Allocation):
- Length, exact, allocated first. Clamped to remaining budget in order.
- Percentage + Ratio, proportional from total. Cumulative to prevent jitter. Scaled proportionally if combined demand exceeds available budget.
- Fill + Min + Max, divide remaining equally. Min applies a floor; Max applies a ceiling. Fill gets equal share.
pub fn split(
direction: Direction,
area: Rect,
constraints: List(Constraint),
) -> List(Rect)
Split a rect along a direction by applying constraints.
pub fn split_flex(
direction: Direction,
area: Rect,
constraints: List(Constraint),
justify: FlexJustify,
gap: Int,
) -> List(Rect)
Flex layout: children have fixed sizes (from constraints), leftover space
distributed according to justify. Use for toolbars, status bars, centering
a widget in a larger area, or equal-gap grids.
gap is the minimum gap between children (cells). Ignored when justify
provides its own spacing (Between/Around). With FlexStart/End/Center,
gap acts like split_with_spacing’s spacing parameter.
// Center a 20-wide widget in a 80-wide area:
split_flex(Horizontal, area, [Length(20)], FlexCenter, 0)
// Three buttons with 2-cell gap between:
split_flex(Horizontal, area, [Length(10), Length(10), Length(10)], FlexStart, 2)
// Toolbar: left item + right item, space between:
split_flex(Horizontal, area, [Length(10), Length(10)], FlexBetween, 0)
pub fn split_h(
area: Rect,
constraints: List(Constraint),
) -> List(Rect)
Split horizontally (columns side-by-side). Shorthand for split(Horizontal, ...).
pub fn split_responsive(
area: Rect,
breakpoints: List(Breakpoint),
) -> List(Rect)
Split area horizontally using the first breakpoint whose min_width <=
area.size.width, evaluated in descending order. Falls back to the last
breakpoint (assumed smallest). Returns [area] if breakpoints is empty.
Example, two columns on wide screens, stacked on narrow:
geometry.split_responsive(area, [
geometry.Breakpoint(80, [Percentage(50), Percentage(50)]),
geometry.Breakpoint(0, [Percentage(100)]),
])
pub fn split_v(
area: Rect,
constraints: List(Constraint),
) -> List(Rect)
Split vertically (rows stacked). Shorthand for split(Vertical, ...).
pub fn split_with_spacing(
direction: Direction,
area: Rect,
constraints: List(Constraint),
spacing: Int,
) -> List(Rect)
Split a rect with spacing cells of gap between each child.
Gap cells are taken from the total before distributing to constraints.
// Two columns with a 1-cell gap
split_with_spacing(Horizontal, area, [Fill, Fill], 1)