Cairn · module

Cairn.Layout.Core

lean/Cairn/Layout/Core.lean

Layout

layout m window node turns a Node into a Laid: every rect, clip, baseline, caret and selection resolved in integer logical points. It is total and pure, and works in two passes:

  1. Measure (measure, bottom-up): each node's preferred ("hug") size, stored in a Sized tree so that no subtree is measured twice. It is passed the width the parent offers, which only wrapped text (Node.para) uses: a para measures into a clipping column of its lines, one text each (paraLines), so arrange never sees a para.
  2. Arrange (arrange, top-down): each node is given a rect by its parent and places its children inside its content box.

The semantics are specified in docs/layout.md; the theorems are in Cairn.Layout.Proofs. Every definition here is plain structural recursion over lists so that the proofs can follow the code.

Imports Cairn.UI.Node, Cairn.Text.Wrap

Order

Structures 2

structure

Cairn.Layout.Item

lean/Cairn/Layout/Core.lean:38
Item : Type

What a parent needs to know about a child to place it.

Fields
width : Sizing
height : Sizing
size : Size
stretch : Bool

Whether align := .stretch may stretch the child. Text is never stretched: its rect is always its measured box.

structure

Cairn.Layout.Line

lean/Cairn/Layout/Core.lean:189
Line : Type

Everything a line of children shares.

Fields
horiz : Bool
align : Align
c0 : Int

Cross-axis start and length of the content box.

cc : Int
L : Int

Leftover space for fill children, and how many there are.

f : Nat
spacing : Int

Space after the i-th child.

Inductive types 1

inductive

Cairn.Layout.Sized

lean/Cairn/Layout/Core.lean:31
Sized : Type

A node with its preferred size resolved. This is the measure pass's output and the arrange pass's input. size is the size the node asks for: fixed n gives n, hug and fill give the intrinsic size of the content plus padding, floored at zero.

Constructors
box (style : Style) (control : Option Control) (size : Size)
  (children : List Sized) : Sized
text (style : TextStyle) (content : String) (size : Size) : Sized
field (style : Style) (text : TextStyle) (control : Control)
  (view : FieldView) (size : Size) : Sized
Instances

Inhabited

Definitions 51

def

Cairn.Layout.Sized.size

lean/Cairn/Layout/Core.lean:48
size : Sized → Size
def

Cairn.Layout.Sized.sizings

lean/Cairn/Layout/Core.lean:52
sizings : Sized → Sizing × Sizing

Sizing on each axis (text always hugs).

def

Cairn.Layout.Sized.item

lean/Cairn/Layout/Core.lean:56
item (s : Sized) : Item
def

Cairn.Layout.resolve

lean/Cairn/Layout/Core.lean:64
resolve (s : Sizing) (intrinsic : Int) : Int

Resolve a preferred length: fixed n is n; hug and fill are the intrinsic length, floored at zero.

def

Cairn.Layout.gaps

lean/Cairn/Layout/Core.lean:70
gaps (gap k : Nat) : Int

Total length of the gaps between k children.

def

Cairn.Layout.maxAll

lean/Cairn/Layout/Core.lean:73
maxAll : List Int → Int

Largest element, or 0.

def

Cairn.Layout.contentSize

lean/Cairn/Layout/Core.lean:78
contentSize (axis : Axis) (gap : Nat) (kids : List Size) : Size

Intrinsic content size of a container from its children's preferred sizes.

def

Cairn.Layout.FieldView.shown

lean/Cairn/Layout/Core.lean:85
shown (v : FieldView) : String

The string a field sizes itself to: its text, or its placeholder when empty.

def

Cairn.Layout.offAt

lean/Cairn/Layout/Core.lean:88
offAt (offs : Array Int) (i : Nat) : Int

Caret offset at scalar index i, clamped to the end of the text.

def

Cairn.Layout.innerAvail

lean/Cairn/Layout/Core.lean:92
innerAvail (st : Style) (aw : Int) : Int

The width a box offers its children to wrap in: its own (fixed) width or the width it was offered, less its horizontal padding.

def

Cairn.Layout.wrapWidth

lean/Cairn/Layout/Core.lean:96
wrapWidth (wr : Wrap) (aw : Int) : Int

The width a wrapped text breaks at: its fixed width, or the width it was offered.

def

Cairn.Layout.paraStyle

lean/Cairn/Layout/Core.lean:102
paraStyle (wr : Wrap) : Style

A wrapped text is laid out as a column of its lines that clips to its rect.

def

Cairn.Layout.paraLines

lean/Cairn/Layout/Core.lean:108
paraLines (m : TextMetrics) (ts : TextStyle) (wr : Wrap) (aw : Int)
  (s : String) : List Sized

The lines of a wrapped text, each a text sized to its width by the line height. The offsets come from one measurement of the whole string.

def

Cairn.Layout.measure

lean/Cairn/Layout/Core.lean:117
measure (m : TextMetrics) (aw : Int) : Node → Sized

The measure pass. aw is the width the parent offers, which only wrapped text uses.

def

Cairn.Layout.measureList

lean/Cairn/Layout/Core.lean:134
measureList (m : TextMetrics) (aw : Int) : List Node → List Sized
def

Cairn.Sizing.isFill

lean/Cairn/Layout/Core.lean:141
isFill : Sizing → Bool
def

Cairn.Layout.mainBase

lean/Cairn/Layout/Core.lean:146
mainBase (s : Sizing) (pref : Int) : Int

Main-axis length a child asks for before leftover space is shared: fill asks for 0.

def

Cairn.Layout.cumShare

lean/Cairn/Layout/Core.lean:153
cumShare (L : Int) (f n : Nat) : Int

The first n of f equal shares of L, together: ⌊L·n/f⌋.

def

Cairn.Layout.fillShare

lean/Cairn/Layout/Core.lean:157
fillShare (L : Int) (f j : Nat) : Int

The j-th of f equal shares of L. The shares telescope, so they sum to exactly L, and they differ by at most one (the larger ones come later).

def

Cairn.Layout.crossPlace

lean/Cairn/Layout/Core.lean:160
crossPlace (al : Align) (c0 cc : Int) (s : Sizing) (pref : Int)
  (stretch : Bool) : Int × Int

Cross-axis placement within [c0, c0 + cc): returns position and length.

def

Cairn.Layout.Item.mainSizing

lean/Cairn/Layout/Core.lean:173
mainSizing (horiz : Bool) (it : Item) : Sizing
def

Cairn.Layout.Item.crossSizing

lean/Cairn/Layout/Core.lean:174
crossSizing (horiz : Bool) (it : Item) : Sizing
def

Cairn.Layout.Item.mainPref

lean/Cairn/Layout/Core.lean:175
mainPref (horiz : Bool) (it : Item) : Int
def

Cairn.Layout.Item.crossPref

lean/Cairn/Layout/Core.lean:176
crossPref (horiz : Bool) (it : Item) : Int
def

Cairn.Layout.mainSize

lean/Cairn/Layout/Core.lean:180
mainSize (horiz : Bool) (L : Int) (f j : Nat) (it : Item) : Int

The main-axis length of an item, given the shared leftover L among f fill children, j of which come before it.

def

Cairn.Layout.mkRect

lean/Cairn/Layout/Core.lean:185
mkRect (horiz : Bool) (mainPos mainLen crossPos crossLen : Int) : Rect
def

Cairn.Layout.Line.go

lean/Cairn/Layout/Core.lean:203
go (ln : Line) : Nat → Nat → Int → List Item → List Rect

Place a line of children: i is the child's index, j the number of fill children before it, pos where it starts on the main axis.

def

Cairn.Layout.spacing

lean/Cairn/Layout/Core.lean:213
spacing (justify : Align) (gap : Nat) (free : Int) (k i : Nat) : Int

Space after child i for justify: gap, plus for stretch (space-between) an equal share of the free space when there is some and more than one child.

def

Cairn.Layout.startOffset

lean/Cairn/Layout/Core.lean:219
startOffset (justify : Align) (free : Int) : Int

Where the first child starts, relative to the content box, for justify.

def

Cairn.Layout.mainOf

lean/Cairn/Layout/Core.lean:226
mainOf (horiz : Bool) (r : Rect) : Int

The main-axis length of a row (horiz) or column's content box.

def

Cairn.Layout.baseSum

lean/Cairn/Layout/Core.lean:229
baseSum (horiz : Bool) (items : List Item) : Int

Sum of the children's base lengths (fill children count 0).

def

Cairn.Layout.fillCount

lean/Cairn/Layout/Core.lean:233
fillCount (horiz : Bool) (items : List Item) : Nat

Number of fill children on the main axis.

def

Cairn.Layout.leftover

lean/Cairn/Layout/Core.lean:237
leftover (horiz : Bool) (st : Style) (content : Rect) (items : List Item) : Int

Leftover main-axis space shared by fill children, floored at zero.

def

Cairn.Layout.free

lean/Cairn/Layout/Core.lean:242
free (horiz : Bool) (st : Style) (content : Rect) (items : List Item) : Int

Main-axis space left after every child and gap; this is what justify distributes. With fill children the line is full unless it overflows.

def

Cairn.Layout.lineOf

lean/Cairn/Layout/Core.lean:247
lineOf (horiz : Bool) (st : Style) (content : Rect) (items : List Item) : Line
def

Cairn.Layout.lineRects

lean/Cairn/Layout/Core.lean:255
lineRects (horiz : Bool) (st : Style) (content : Rect) (items : List Item) :
  List Rect

Rects for the children of a row (horiz) or column with content box content.

def

Cairn.Layout.stackRects

lean/Cairn/Layout/Core.lean:262
stackRects (st : Style) (content : Rect) (items : List Item) : List Rect

Rects for the children of a stack: each child is placed in the whole content box, horizontally by justify and vertically by align.

def

Cairn.Layout.placeRects

lean/Cairn/Layout/Core.lean:269
placeRects (st : Style) (r : Rect) (items : List Item) : List Rect

Rects for a container's children before any scrolling, given the container's rect.

def

Cairn.Layout.Axis.horiz

lean/Cairn/Layout/Core.lean:276
horiz : Axis → Bool

Whether an axis runs horizontally (rows) or vertically (columns and stacks).

def

Cairn.Rect.scrollBy

lean/Cairn/Layout/Core.lean:281
scrollBy (horiz : Bool) (o : Int) (q : Rect) : Rect

q moved back by o points along an axis: left when horiz, otherwise up.

def

Cairn.Style.clips

lean/Cairn/Layout/Core.lean:285
clips (st : Style) : Bool

Whether a box clips its children: when it says so, and always when it scrolls.

def

Cairn.Layout.scrolled

lean/Cairn/Layout/Core.lean:288
scrolled (st : Style) (rs : List Rect) : List Rect

Children's rects moved by a scroll box's offset; unchanged in any other box.

def

Cairn.Layout.childRects

lean/Cairn/Layout/Core.lean:296
childRects (st : Style) (r : Rect) (items : List Item) : List Rect

Rects for a container's children, given the container's rect: placed as its axis says, then, in a scroll box (scroll = some o), moved back by o along that axis (a row scrolls horizontally, a column or stack vertically).

def

Cairn.Layout.scrollFor

lean/Cairn/Layout/Core.lean:304
scrollFor (co cw : Int) : Int

How far a field's text is scrolled left so that a caret at offset co is visible in a content box cw wide: zero unless the caret would fall off the right edge, and then just enough to put it at the right edge.

def

Cairn.Layout.field

lean/Cairn/Layout/Core.lean:308
field (m : TextMetrics) (clip r : Rect) (st : Style) (ts : TextStyle)
  (ctl : Control) (v : FieldView) : Laid

Lay out a field in r: text vertically centred in the content box, scrolled horizontally so the caret is visible.

def

Cairn.Layout.innerClip

lean/Cairn/Layout/Core.lean:325
innerClip (st : Style) (clip r : Rect) : Rect

Region a container's children may paint in: its own clip, intersected with its rect when it clips (Style.clips: a scroll box always does).

def

Cairn.Layout.arrange

lean/Cairn/Layout/Core.lean:329
arrange (m : TextMetrics) (clip r : Rect) : Sized → Laid

The arrange pass: lay out s in r, painting within clip.

def

Cairn.Layout.arrangeList

lean/Cairn/Layout/Core.lean:337
arrangeList (m : TextMetrics) (clip : Rect) :
  List Rect → List Sized → List Laid

Arrange children against their rects (the lists always have the same length; a missing rect would be empty).

def

Cairn.Layout.windowRect

lean/Cairn/Layout/Core.lean:344
windowRect (w : Size) : Rect

The window as a rect at the origin, sizes floored at zero.

def

Cairn.Layout.rootRect

lean/Cairn/Layout/Core.lean:348
rootRect (window : Size) (s : Sized) : Rect

The root's rect: at the origin, fill takes the window's length, otherwise the preferred length.

def

Cairn.Layout.layout

lean/Cairn/Layout/Core.lean:354
layout (m : TextMetrics) (window : Size) (n : Node) : Laid

Lay out a view in a window.

Instances 1

instance

Cairn.Layout.instInhabitedSized

lean/Cairn/Layout/Core.lean:35
instInhabitedSized : Inhabited Sized