Cairn · module

Cairn.App

lean/Cairn/App.lean

An app is its state, its surfaces, and its moves. The runtime (Cairn.Runtime) owns interaction state (hover, press, focus, window size), turns events into actions by hit testing the laid-out frame or checking the menu, and calls update.

Imports Cairn.UI.Node, Cairn.Input, Cairn.Claim, Cairn.Surface, Cairn.Font

Order

Structures 2

structure

Cairn.UI

lean/Cairn/App.lean:19
UI : Type

Interaction state the runtime owns and the view may read (hover reveals, focus rings).

Fields
size : Size
hover : Option ControlRef
pressed : Option ControlRef
focus : Option ControlRef
windowFocused : Bool
scroll : List (ControlRef × Int)

The offset of each scroll box that has scrolled, by its Style.scrollRef. The runtime moves them (the wheel, the trackpad, the page keys, Tab into a box) and clamps them to the box's content; the view reads them with scrollOf (docs/runtime.md, "Scrolling").

lists : List (ControlRef × VList.Known)

What the runtime knows of each virtual list on screen, by its scrollRef: the heights of the rows it has laid, and the anchor (docs/runtime.md, "Virtual lists"). The runtime records them after every layout; VList.node reads them.

kept : List (ControlRef × Int)

The offsets of scroll boxes that are not on screen and that the app keeps (App.keepScroll), as they were when they left: the view reads them with scrollOf when the box comes back (docs/runtime.md, "Scrolling").

keptLists : List (ControlRef × VList.Known)

What the runtime knew of each virtual list not on screen that the app keeps, likewise.

menu : Option ControlRef

The control whose menu (Style.menu) is open now, if one is: the runtime opens it (a secondary click, a menu button, the context-menu key) and closes it when the host says the native menu closed, an item was chosen, or the control or its menu is gone. A view may read it (a ⋯ button drawn pressed while its menu is open).

Instances

Inhabited Repr

structure

Cairn.App

lean/Cairn/App.lean:137
App (S : Type) : Type
Fields
init : S
surfaces : List (Surface S)

What the app shows: at most one window (a later window is ignored), panels and status items. An app with no window is an accessory app (no Dock icon, no main menu).

update : S × List Effect

A person's moves: every action names a control on screen.

receive : S × List Effect

The outside world: the clock, timers, replies and subscription events (docs/effects.md). Ignored by default.

subscriptions : List Sub

The outside inputs the app wants in this state. The runtime diffs them after every delivery and starts and stops subscriptions to match.

initEffects : List Effect

Effects to run once, when the first clock arrives (so timers start from a real time).

claims : List ClaimInfo

Every claim the app makes, from the claim commands.

initFocus : Option ControlRef

The control that has keyboard focus at launch, if it is focusable there.

maxInFlight : Nat

How many requests of capped kinds (Request.Kind.capped: http, upload, loadImage) may be with the host at once (at least 1). The runtime queues the rest (docs/effects.md, "Requests in flight").

minSize : Size

The window's smallest content size in this state, in points. The host keeps the window at least this big, so a person can't drag it smaller (NSWindow.contentMinSize; trusted, ^1010), and the view can be proved good at every size from it up (with Grid.minBox, for instance). 0 × 0, no minimum, by default.

keepScroll : List ControlRef

The scroll boxes and virtual lists (by Style.scrollRef) whose offset, and what the runtime knows of their rows, outlive their leaving the view in this state: a list on a tab not shown comes back where it was. Any other box's offset is forgotten when it leaves the tree (docs/runtime.md, "Scrolling"). None by default.

Inductive types 1

inductive

Cairn.Surface

lean/Cairn/App.lean:79
Surface (S : Type) : Type

One thing an app shows (docs/surfaces.md). An app declares a fixed list of them; whether each is shown, and what it shows, is a function of the state. place is the surface's place claim: its durable identity on the wire, in the map and in the debug socket.

Constructors
window {S : Type} (place : ClaimId) (title : String) (view : S → UI → Node) :
  Surface S

M1's window: Metal content laid out at the window's size, with input.

panel {S : Type} (place : ClaimId)
  (view : TextMetrics → S → Option PanelView) : Surface S

A non-activating, click-through overlay panel; none hides it. It takes no input, so its view doesn't read UI. The view is given the text metrics the panel is laid out with, so it can measure content (Cairn.Layout.measure), for instance to animate between two heights.

statusItem {S : Type} (place : ClaimId) (view : S → Option StatusItem) :
  Surface S

A menu bar status item and its native menu; none removes it from the menu bar.

menuBar {S : Type} (place : ClaimId) (view : S → List MenuItem) : Surface S

The app's own items in the main menu bar (docs/surfaces.md, "The app's menus"). A top-level submenu is a menu of its own in the menu bar, after the app menu, in order (Go, View); every other top-level entry goes in the app menu, after the app's name and before Hide and Quit, which stay the host's. An item's shortcut is its key equivalent, honoured whenever the app is active. Shown only while the app has a window: an accessory app has no main menu.

Definitions 10

def

Cairn.UI.listOf

lean/Cairn/App.lean:48
listOf (ui : UI) (r : ControlRef) : VList.Known

What the runtime knows of the virtual list r: nothing until it has been laid. A list the app keeps (App.keepScroll) is known while it is not on screen too.

def

Cairn.UI.scrollOf

lean/Cairn/App.lean:58
scrollOf (ui : UI) (r : ControlRef) : Int

The runtime's offset for the scroll box r: 0 until it has scrolled. A box the app keeps (App.keepScroll) keeps its offset while it is not on screen.

def

Cairn.UI.scrolling

lean/Cairn/App.lean:72
scrolling (ui : UI) (r : ControlRef) (st : Style) : Style

st as the scroll box r whose offset the runtime owns: scrolled by ui.scrollOf r.

example : (({} : UI).scrolling ⟨14, 0⟩ {}).scroll = some 0 := rfl
def

Cairn.Surface.place

lean/Cairn/App.lean:100
place {S : Type} : Surface S → ClaimId
def

Cairn.Surface.comap

lean/Cairn/App.lean:104
comap {S T : Type} (f : T → S) : Surface S → Surface T

The same surface over a bigger state (Cairn.Runtime.logged wraps an app's state).

def

Cairn.firstWindow

lean/Cairn/App.lean:116
firstWindow {S : Type} :
  List (Surface S) → Option (ClaimId × String × (S → UI → Node))

The first window in a surface list: its place, title and view.

def

Cairn.emptyView

lean/Cairn/App.lean:134
emptyView : Node

What an app with no window lays out as its window: nothing.

def

Cairn.App.view

lean/Cairn/App.lean:178
view {S : Type} (app : App S) : S → UI → Node

The window's view, as M1's App.view was; an empty box when there is no window. Every M1 theorem about view is about this.

def

Cairn.App.windowPlace

lean/Cairn/App.lean:185
windowPlace {S : Type} (app : App S) : Option ClaimId

The window's place claim, if the app has a window. Bare surface-local events (M1's) go to this window.

def

Cairn.App.accessory

lean/Cairn/App.lean:196
accessory {S : Type} (app : App S) : Bool

An app with no window runs as an accessory (docs/surfaces.md, section 3).

Theorems 3

theorem

Cairn.Surface.place_comap

provedlean/Cairn/App.lean:110
place_comap {S T : Type} (f : T → S) (x : Surface S) :
  (comap f x).place = x.place
theorem

Cairn.firstWindow_comap

provedlean/Cairn/App.lean:121
firstWindow_comap {S T : Type} (f : T → S) (xs : List (Surface S)) :
  firstWindow (List.map (Surface.comap f) xs) =
    Option.map
      (fun x =>
        match x with
        | (p, t, v) => (p, t, fun s ui => v (f s) ui))
      (firstWindow xs)
theorem

Cairn.App.view_comap

provedlean/Cairn/App.lean:188
view_comap {S : Type} (app : App S) {T : Type} (f : T → S) (b : App T)
  (h : b.surfaces = List.map (Surface.comap f) app.surfaces) (s : T) (ui : UI) :
  b.view s ui = app.view (f s) ui

The view of an app whose surfaces are app's over a bigger state reads the smaller one.

Instances 3

instance

Cairn.instInhabitedUI

lean/Cairn/App.lean:44
instInhabitedUI : Inhabited UI
instance

Cairn.instReprUI

lean/Cairn/App.lean:44
instReprUI : Repr UI
instance

Cairn.instDecidableEqUI

lean/Cairn/App.lean:44
instDecidableEqUI : DecidableEq UI