Cairn · module

Cairn.UI.Hit

lean/Cairn/UI/Hit.lean

Hit testing over a laid-out tree.

Paint order is pre-order: a node paints before its children, and children paint in list order, so later entries are on top. Every node that paints (a box with a background, border or control, every text run and every field) leaves a hit entry: its visible rect (rect.inter clip) and its owner, the nearest control at or above it. A point hits the topmost entry that contains it, and the hit goes to that entry's owner. So a label inside a button routes to the button, and an opaque panel painted over a button blocks it.

Imports Cairn.UI.Node

Order

Structures 3

structure

Cairn.Runtime.Target

lean/Cairn/UI/Hit.lean:19
Target : Type

A control-bearing node of a laid tree, with its control pulled out.

Fields
node : Laid
control : Control
Instances

Inhabited

structure

Cairn.Runtime.Hit

lean/Cairn/UI/Hit.lean:40
Hit : Type
Fields
visible : Rect
owner : Option Target
Instances

Inhabited

structure

Cairn.Runtime.LayoutFacts

lean/Cairn/UI/Hit.lean:210
LayoutFacts (laid : Laid) (t : Target) : Prop

The facts about a laid tree the pressable theorem needs, for one control t: its visible rect is nonempty, and a pointer at the centre of that rect reaches it. Layout (workstream B) proves its trees satisfy these for every control of an enabled move at sizes at or above the minimum.

Fields
nonempty : t.visible.nonempty
reaches : Reaches laid t t.visible.center

Definitions 19

def

Cairn.Runtime.Target.ref

lean/Cairn/UI/Hit.lean:26
ref (t : Target) : ControlRef
def

Cairn.Runtime.Target.visible

lean/Cairn/UI/Hit.lean:27
visible (t : Target) : Rect
def

Cairn.Runtime.Target.isField

lean/Cairn/UI/Hit.lean:29
isField (t : Target) : Bool
def

Cairn.Runtime.Target.focusable

lean/Cairn/UI/Hit.lean:35
focusable (t : Target) : Bool

Fields always take focus; other controls do unless their role is static.

def

Cairn.Runtime.paints

lean/Cairn/UI/Hit.lean:46
paints (style : Style) (control : Option Control) : Bool

Whether a box leaves a hit entry. Unpainted, control-less boxes are layout only.

def

Cairn.Runtime.hitsOf

lean/Cairn/UI/Hit.lean:51
hitsOf (o : Option Target) : Laid → List Hit

Hit entries in paint order; o is the owner inherited from the ancestors.

def

Cairn.Runtime.hitsList

lean/Cairn/UI/Hit.lean:59
hitsList (o : Option Target) : List Laid → List Hit
def

Cairn.Runtime.targetsOf

lean/Cairn/UI/Hit.lean:66
targetsOf : Laid → List Target

Every control in the tree, in paint order.

def

Cairn.Runtime.targetsList

lean/Cairn/UI/Hit.lean:73
targetsList : List Laid → List Target
def

Cairn.Runtime.hits

lean/Cairn/UI/Hit.lean:78
hits (laid : Laid) : List Hit
def

Cairn.Runtime.targets

lean/Cairn/UI/Hit.lean:79
targets (laid : Laid) : List Target
def

Cairn.Runtime.refs

lean/Cairn/UI/Hit.lean:82
refs (laid : Laid) : List ControlRef

The refs of every control in the tree, in paint order.

def

Cairn.Runtime.present

lean/Cairn/UI/Hit.lean:85
present (laid : Laid) (r : ControlRef) : Bool

r names a control in laid.

def

Cairn.Runtime.focusableIn

lean/Cairn/UI/Hit.lean:88
focusableIn (laid : Laid) (r : ControlRef) : Bool

r names a focusable control in laid.

def

Cairn.Runtime.find

lean/Cairn/UI/Hit.lean:92
find (laid : Laid) (r : ControlRef) : Option Target

The first control in paint order with this ref.

def

Cairn.Runtime.hitTarget

lean/Cairn/UI/Hit.lean:96
hitTarget (laid : Laid) (p : Point) : Option Target

The control a point hits: the owner of the topmost hit entry containing it.

def

Cairn.Runtime.hitTest

lean/Cairn/UI/Hit.lean:99
hitTest (laid : Laid) (p : Point) : Option Control
def

Cairn.Runtime.hitRef

lean/Cairn/UI/Hit.lean:101
hitRef (laid : Laid) (p : Point) : Option ControlRef
def

Cairn.Runtime.Reaches

lean/Cairn/UI/Hit.lean:202
Reaches (laid : Laid) (t : Target) (p : Point) : Prop

t is what a pointer at p reaches: t's own hit entry contains p, and everything painted after it that also contains p belongs to t (its label, its icon).

Theorems 16

theorem

Cairn.Runtime.hitsOf_owner

provedlean/Cairn/UI/Hit.lean:106
hitsOf_owner (o : Option Target) (l : Laid) (h : Hit) :
  h ∈ hitsOf o l → h.owner = o ∨ ∃ t, t ∈ targetsOf l ∧ h.owner = some t
theorem

Cairn.Runtime.hitsList_owner

provedlean/Cairn/UI/Hit.lean:125
hitsList_owner (o : Option Target) (ls : List Laid) (h : Hit) :
  h ∈ hitsList o ls → h.owner = o ∨ ∃ t, t ∈ targetsList ls ∧ h.owner = some t
theorem

Cairn.Runtime.targetsOf_control

provedlean/Cairn/UI/Hit.lean:140
targetsOf_control (l : Laid) (t : Target) :
  t ∈ targetsOf l → t.node.control? = some t.control
theorem

Cairn.Runtime.targetsList_control

provedlean/Cairn/UI/Hit.lean:153
targetsList_control (ls : List Laid) (t : Target) :
  t ∈ targetsList ls → t.node.control? = some t.control
theorem

Cairn.Runtime.hits_owner_mem

provedlean/Cairn/UI/Hit.lean:164
hits_owner_mem {laid : Laid} {h : Hit} {t : Target} (hm : h ∈ hits laid)
  (ho : h.owner = some t) : t ∈ targets laid

Every owner of a hit entry is a control of the tree.

theorem

Cairn.Runtime.hitTarget_mem

provedlean/Cairn/UI/Hit.lean:171
hitTarget_mem {laid : Laid} {p : Point} {t : Target}
  (h : hitTarget laid p = some t) : t ∈ targets laid

The hit test only ever answers with a control of the tree.

theorem

Cairn.Runtime.mem_refs

provedlean/Cairn/UI/Hit.lean:180
mem_refs {laid : Laid} {t : Target} (h : t ∈ targets laid) : t.ref ∈ refs laid
theorem

Cairn.Runtime.present_iff

provedlean/Cairn/UI/Hit.lean:183
present_iff {laid : Laid} {r : ControlRef} :
  present laid r = true ↔ r ∈ refs laid
theorem

Cairn.Runtime.find_mem

provedlean/Cairn/UI/Hit.lean:186
find_mem {laid : Laid} {r : ControlRef} {t : Target}
  (h : find laid r = some t) : t ∈ targets laid ∧ t.ref = r
theorem

Cairn.Runtime.hitRef_present

provedlean/Cairn/UI/Hit.lean:191
hitRef_present {laid : Laid} {p : Point} {r : ControlRef}
  (h : hitRef laid p = some r) : r ∈ refs laid
theorem

Cairn.Runtime.Rect.contains_center

provedlean/Cairn/UI/Hit.lean:214
contains_center {r : Rect} (h : r.nonempty) : r.contains r.center = true
theorem

Cairn.Runtime.find?_reverse_split

provedlean/Cairn/UI/Hit.lean:220
find?_reverse_split {α : Type} {q : α → Bool} {pre post : List α} {a : α}
  (ha : q a = true) :
  ∃ b, List.find? q (pre ++ a :: post).reverse = some b ∧ (b = a ∨ b ∈ post ∧ q b = true)

The last element satisfying q in pre ++ a :: post is a or comes after it.

theorem

Cairn.Runtime.hitTarget_of_reaches

provedlean/Cairn/UI/Hit.lean:230
hitTarget_of_reaches {laid : Laid} {t : Target} {p : Point}
  (h : Reaches laid t p) : hitTarget laid p = some t

Hit-test level pressability at a point.

theorem

Cairn.Runtime.reaches_mem

provedlean/Cairn/UI/Hit.lean:241
reaches_mem {laid : Laid} {t : Target} {p : Point} (h : Reaches laid t p) :
  t ∈ targets laid
theorem

Cairn.Runtime.hitTest_center

provedlean/Cairn/UI/Hit.lean:246
hitTest_center {laid : Laid} {t : Target} (h : LayoutFacts laid t) :
  hitTest laid t.visible.center = some t.control

Pressable, hit-test level. Under the layout facts, hit testing at the centre of a control's visible rect returns that control.

theorem

Cairn.Runtime.LayoutFacts.contains_center

provedlean/Cairn/UI/Hit.lean:250
contains_center {laid : Laid} {t : Target}
  (h : LayoutFacts laid t) : t.visible.contains t.visible.center = true

Instances 2

instance

Cairn.Runtime.instInhabitedTarget

lean/Cairn/UI/Hit.lean:22
instInhabitedTarget : Inhabited Target
instance

Cairn.Runtime.instInhabitedHit

lean/Cairn/UI/Hit.lean:43
instInhabitedHit : Inhabited Hit