Skip to content

State and ids

Id :: clay.ElementId
Interaction :: struct {...}
Pointer_Event :: struct {...}
Pointer_Event_Kind :: enum {...}
scope :: proc{scope_int, scope_string}
after :: proc(name: string, seconds: f64) -> bool
anim :: proc(eid: Id, slot: u32, target: f32, speed: f32 = 0, from: Maybe(f32) = nil) -> f32
clicked :: proc() -> bool
every :: proc(name: string, seconds: f64) -> bool
hide :: proc()
hovered :: proc() -> bool
id :: proc(label: string) -> Id
id_indexed :: proc(label: string, index: int) -> Id
interact :: proc(eid: Id, disabled := false) -> (s: Interaction)
is_shown :: proc(name: string) -> bool
last_id :: proc() -> Id
pointer_events :: proc(eid: Id, wheel := false) -> []Pointer_Event
reset_timer :: proc(name: string)
scope_int :: proc(key: int) -> bool
scope_string :: proc(key: string) -> bool
set_last :: proc(eid: Id, state := Interaction{}, submitted := false)
show :: proc(name: string)
sub_id :: proc(parent: Id, name: string, index := 0) -> Id
submitted :: proc() -> bool
widget_state :: proc(eid: Id, $T: typeid, destroy: proc(_: ^T) = nil) -> (state: ^T, created: bool)
Id :: clay.ElementId

Source: kiln/state.odin:13

Interaction :: struct {
hovered: bool, // the pointer is over the element
pressed: bool, // the left button went down on the element and is down over it
held: bool, // the left button went down on the element and is still down (anywhere)
clicked: bool, // released over the element in this frame
right_clicked: bool, // the right button went down on the element in this frame
started: bool, // the left button went down on the element in this frame (a drag starts)
released: bool, // the left button that went down on the element was released in this frame, anywhere
disabled: bool,
pos: [2]f32, // pointer position in pixels, relative to the element's top left corner (as laid out in the previous frame)
}

Pointer state of an element in the current frame, returned by interact.

FieldTypeNotes
hoveredboolthe pointer is over the element
pressedboolthe left button went down on the element and is down over it
heldboolthe left button went down on the element and is still down (anywhere)
clickedboolreleased over the element in this frame
right_clickedboolthe right button went down on the element in this frame
startedboolthe left button went down on the element in this frame (a drag starts)
releasedboolthe left button that went down on the element was released in this frame, anywhere
disabledbool
pos[2]f32pointer position in pixels, relative to the element’s top left corner (as laid out in the previous frame)

Source: kiln/state.odin:120

Pointer_Event :: struct {
kind: Pointer_Event_Kind,
button: MouseButton, // Press and Release
pos: [2]f32, // pixels, relative to the element's top left corner (window for the backend)
wheel: [2]f32, // Wheel: pixels to scroll
pressure: f32, // 0..1; 1 for devices without pressure, like a mouse
modifiers: bit_set[Modifier],
time: f64, // seconds since the app started
}

One thing the pointer did, in the order it happened. Several moves in one frame are the pointer’s path between frames, if the platform reports it.

FieldTypeNotes
kindPointer_Event_Kind
buttonMouseButtonPress and Release
pos[2]f32pixels, relative to the element’s top left corner (window for the backend)
wheel[2]f32Wheel: pixels to scroll
pressuref320..1; 1 for devices without pressure, like a mouse
modifiersbit_set[Modifier]
timef64seconds since the app started

Source: kiln/state.odin:211

Pointer_Event_Kind :: enum {
Move,
Press,
Release,
Wheel,
}

Values: .Move, .Press, .Release, .Wheel

Source: kiln/state.odin:202

scope :: proc{scope_int, scope_string}

Opens an id scope: elements inside get ids that depend on key instead of their position. Use it in loops over data that can change, so the UI state of an item follows the item:

for p in m.people {
if kiln.scope(p.id) { ... }
}

Calls one of these, depending on the argument types:

Source: kiln/state.odin:88

after :: proc(name: string, seconds: f64) -> bool

True once, seconds after the first call (while it is called in every frame).

ArgumentTypeDefault
namestringrequired
secondsf64required
ReturnsType
#0bool

Source: kiln/state.odin:454

anim :: proc(eid: Id, slot: u32, target: f32, speed: f32 = 0, from: Maybe(f32) = nil) -> f32

Moves the value stored for (id, slot) exponentially towards target and returns it. slot lets one widget animate several values, speed is the rate per second (0 = the theme’s anim_speed). The first value of a new tween is target, or from if given (e.g. from = 0 for things that fade in when they appear).

ArgumentTypeDefault
eidIdrequired
slotu32required
targetf32required
speedf320
fromMaybe(f32)nil
ReturnsType
#0f32

Source: kiln/state.odin:344

clicked :: proc() -> bool

True if the last widget or container was clicked in this frame.

ReturnsType
#0bool

Source: kiln/state.odin:308

every :: proc(name: string, seconds: f64) -> bool

True once every seconds (the first time seconds after the first call) while it is called in every frame. Timers are keyed by name like dialogs, not by position:

if kiln.every("refresh", 300) {append(out, Refresh{})}
ArgumentTypeDefault
namestringrequired
secondsf64required
ReturnsType
#0bool

Source: kiln/state.odin:445

hide :: proc()

Hides the shown dialog or drawer.

Source: kiln/state.odin:407

hovered :: proc() -> bool

True if the pointer is over the last widget or container.

ReturnsType
#0bool

Source: kiln/state.odin:313

id :: proc(label: string) -> Id

The id of an element labeled label in the current scope. The n-th use of the same label in a scope gets its own id, so equal labels never clash.

ArgumentTypeDefault
labelstringrequired
ReturnsType
#0Id

Source: kiln/state.odin:39

id_indexed :: proc(label: string, index: int) -> Id

Like id, for the index-th element of a kind (list rows, tabs, …).

ArgumentTypeDefault
labelstringrequired
indexintrequired
ReturnsType
#0Id

Source: kiln/state.odin:44

interact :: proc(eid: Id, disabled := false) -> (s: Interaction)

Tracks the pointer for an element. Call it once per frame before declaring the element. A press goes to the topmost interactive element under the pointer, so a button inside a clickable list item takes the click and the item does not. Disabled elements never react.

ArgumentTypeDefault
eidIdrequired
disabledboolfalse
ReturnsType
sInteraction

Source: kiln/state.odin:142

is_shown :: proc(name: string) -> bool
ArgumentTypeDefault
namestringrequired
ReturnsType
#0bool

Source: kiln/state.odin:411

last_id :: proc() -> Id

The id of the last widget or container, e.g. to attach custom floating elements to it.

ReturnsType
#0Id

Source: kiln/state.odin:323

pointer_events :: proc(eid: Id, wheel := false) -> []Pointer_Event

The pointer events of this frame that belong to an element: all of them while a press that started on it goes on (even outside of it), otherwise those over it while it is the topmost interactive element. Call interact for the element before, every frame. With wheel, the element takes the mouse wheel: scroll containers around it do not scroll while the pointer is over it. The events live until the end of the frame.

for e in kiln.pointer_events(eid) {
if e.kind == .Move && s.held {append(&points, e.pos)}
}
ArgumentTypeDefault
eidIdrequired
wheelboolfalse
ReturnsType
#0[]Pointer_Event

Source: kiln/state.odin:237

reset_timer :: proc(name: string)

Starts the timer name over.

ArgumentTypeDefault
namestringrequired

Source: kiln/state.odin:462

scope_int :: proc(key: int) -> bool
ArgumentTypeDefault
keyintrequired
ReturnsType
#0bool

Source: kiln/state.odin:94

scope_string :: proc(key: string) -> bool
ArgumentTypeDefault
keystringrequired
ReturnsType
#0bool

Source: kiln/state.odin:100

set_last :: proc(eid: Id, state := Interaction{}, submitted := false)

Makes a custom widget the last item, so clicked, hovered, submitted, tooltip and context_menu after it refer to it. Pass the Interaction from interact.

ArgumentTypeDefault
eidIdrequired
stateInteractionInteraction{}
submittedboolfalse

Source: kiln/state.odin:303

show :: proc(name: string)

Shows the dialog or drawer with this name (replacing the one that is shown).

ArgumentTypeDefault
namestringrequired

Source: kiln/state.odin:401

sub_id :: proc(parent: Id, name: string, index := 0) -> Id

Id of a part of a widget (list entry, segment, popup, …), derived from the widget’s id.

ArgumentTypeDefault
parentIdrequired
namestringrequired
indexint0
ReturnsType
#0Id

Source: kiln/state.odin:78

submitted :: proc() -> bool

True if Enter was pressed in the last text field in this frame.

ReturnsType
#0bool

Source: kiln/state.odin:318

widget_state :: proc(eid: Id, $T: typeid, destroy: proc(_: ^T) = nil) -> (state: ^T, created: bool)

UI state of a custom widget that kiln keeps between frames, one T per element id (a drag in progress, a scroll position, a cache). It starts zeroed (created is true then) and is freed when the widget was not shown for a while; destroy frees what T owns:

Draft :: struct {points: [dynamic][2]f32}
draft, _ := kiln.widget_state(eid, Draft, proc(d: ^Draft) {delete(d.points)})
ArgumentTypeDefault
eidIdrequired
$Ttypeidrequired
destroyproc(_: ^T)nil
ReturnsType
state^T
createdbool

Source: kiln/state.odin:487