Skip to content

Instantly share code, notes, and snippets.

@turbo

turbo/clay.nim Secret

Created April 27, 2025 10:01
Show Gist options
  • Select an option

  • Save turbo/9cc624442333c91d646cc6d0b6255eda to your computer and use it in GitHub Desktop.

Select an option

Save turbo/9cc624442333c91d646cc6d0b6255eda to your computer and use it in GitHub Desktop.
{.compile: "clay.c".}
type
ClayString* {.bycopy.} = object
isStaticallyAllocated*: bool
length*: int32
chars*: cstring
ClayStringSlice* {.bycopy.} = object
length*: int32
chars*: cstring
baseChars*: cstring
ClayArena* {.bycopy.} = object
nextAllocation*: uint
capacity*: csize_t
memory*: pointer
ClayDimensions* {.bycopy.} = object
width*, height*: cfloat
ClayVector2* {.bycopy.} = object
x*, y*: cfloat
ClayColor* {.bycopy.} = object
r*, g*, b*, a*: cfloat
ClayBoundingBox* {.bycopy.} = object
x*, y*, width*, height*: cfloat
ClayElementId* {.bycopy.} = object
id*, offset*, baseId*: uint32
stringId*: ClayString
ClayCornerRadius* {.bycopy.} = object
topLeft*, topRight*, bottomLeft*, bottomRight*: cfloat
############################################################
# Enums – packed to uint8 #
############################################################
type
ClayErrorType* {.size: sizeof(uint8).} = enum
# A text measurement function wasn't provided using Clay_SetMeasureTextFunction(), or the provided function was null.
CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED
# Clay attempted to allocate its internal data structures but ran out of space.
# The arena passed to Clay_Initialize was created with a capacity smaller than that required by Clay_MinMemorySize().
CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED
# Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxElementCount().
CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED
# Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxMeasureTextCacheWordCount().
CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED
# Two elements were declared with exactly the same ID within one layout.
CLAY_ERROR_TYPE_DUPLICATE_ID
# A floating element was declared using CLAY_ATTACH_TO_ELEMENT_ID and either an invalid .parentId was provided or no element with the provided .parentId was found.
CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND
# An element was declared that using CLAY_SIZING_PERCENT but the percentage value was over 1. Percentage values are expected to be in the 0-1 range.
CLAY_ERROR_TYPE_PERCENTAGE_OVER_1
# Clay encountered an internal error. It would be wonderful if you could report this so we can fix it!
CLAY_ERROR_TYPE_INTERNAL_ERROR
ClayLayoutDirection* {.size: sizeof(uint8).} = enum
clLeftToRight = 0,
clTopToBottom
ClayLayoutAlignmentX* {.size: sizeof(uint8).} = enum
clAlignLeft = 0,
clAlignRight,
clAlignCenterX
ClayLayoutAlignmentY* {.size: sizeof(uint8).} = enum
clAlignTop = 0,
clAlignBottom,
clAlignCenterY
ClaySizingType* {.size: sizeof(uint8).} = enum
clSizingFit = 0,
clSizingGrow,
clSizingPercent,
clSizingFixed
ClayWrapMode* {.size: sizeof(uint8).} = enum
clWrapWords = 0,
clWrapNewLines,
clWrapNone
ClayTextElementConfigWrapMode* {.size: sizeof(uint8).} = enum
# (default) breaks on whitespace characters.
CLAY_TEXT_WRAP_WORDS
# Don't break on space characters, only on newlines.
CLAY_TEXT_WRAP_NEWLINES
# Disable text wrapping entirely.
CLAY_TEXT_WRAP_NONE
ClayTextAlignment* {.size: sizeof(uint8).} = enum
clTextLeft = 0,
clTextCenter,
clTextRight
ClayFloatingAttachPointType* {.size: sizeof(uint8).} = enum
CLAY_ATTACH_POINT_LEFT_TOP
CLAY_ATTACH_POINT_LEFT_CENTER
CLAY_ATTACH_POINT_LEFT_BOTTOM
CLAY_ATTACH_POINT_CENTER_TOP
CLAY_ATTACH_POINT_CENTER_CENTER
CLAY_ATTACH_POINT_CENTER_BOTTOM
CLAY_ATTACH_POINT_RIGHT_TOP
CLAY_ATTACH_POINT_RIGHT_CENTER
CLAY_ATTACH_POINT_RIGHT_BOTTOM
ClayPointerCaptureMode* {.size: sizeof(uint8).} = enum
CLAY_POINTER_CAPTURE_MODE_CAPTURE
CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH
ClayFloatingAttachToElement* {.size: sizeof(uint8).} = enum
## (default) Disables floating for this element.
CLAY_ATTACH_TO_NONE
## Attaches this floating element to its parent, positioned based on the .
## attachPoints and .offset fields.
CLAY_ATTACH_TO_PARENT
## Attaches this floating element to an element with a specific ID,
## specified with the .parentId field. positioned based on the .
## attachPoints and .offset fields.
CLAY_ATTACH_TO_ELEMENT_WITH_ID
## Attaches this floating element to the root of the layout, which combined
## with the .offset field provides functionality similar to "absolute
## positioning".
CLAY_ATTACH_TO_ROOT
ClayRenderCommandType* {.size: sizeof(uint8).} = enum
clCmdNone = 0,
clCmdRect,
clCmdBorder,
clCmdText,
clCmdImage,
clCmdScissorStart,
clCmdScissorEnd,
clCmdCustom
type
ClayChildAlignment* {.bycopy.} = object
x*: ClayLayoutAlignmentX
y*: ClayLayoutAlignmentY
ClaySizingMinMax* {.bycopy.} = object
min*, max*: cfloat
ClaySizingAxisUnion* {.union.} = object
minMax*: ClaySizingMinMax
percent*: cfloat
ClaySizingAxis* {.bycopy.} = object
size*: ClaySizingAxisUnion
kind*: ClaySizingType
ClaySizing* {.bycopy.} = object
width*: ClaySizingAxis
height*: ClaySizingAxis
ClayPadding* {.bycopy.} = object
left*, right*, top*, bottom*: uint16
ClayLayoutConfig* {.bycopy.} = object
sizing*: ClaySizing
padding*: ClayPadding
childGap*: uint16
childAlignment*: ClayChildAlignment
layoutDirection*: ClayLayoutDirection
ClayErrorData* {.bycopy.} = object
errorType*: ClayErrorType
errorText*: ClayString
############################################################
# Opaque handle #
############################################################
type ClayContext* = distinct pointer
type
ClayRectangleRenderData* {.bycopy.} = object
backgroundColor*: ClayColor
cornerRadius*: ClayCornerRadius
ClayTextRenderData* {.bycopy.} = object
stringContents*: ClayStringSlice
textColor*: ClayColor
fontId*, fontSize*, letterSpacing*, lineHeight*: uint16
ClayBorderRenderData* {.bycopy.} = object
color*: ClayColor
cornerRadius*: ClayCornerRadius
width*: ClayBorderWidth
ClayImageRenderData* {.bycopy.} = object
backgroundColor*: ClayColor
cornerRadius*: ClayCornerRadius
srcDimensions*: ClayDimensions
imageData*: pointer
ClayScrollRenderData* {.bycopy.} = object
horizontal*, vertical*: bool # ! WTF
ClayCustomRenderData* {.bycopy.} = object
backgroundColor*: ClayColor
cornerRadius*: ClayCornerRadius
customData*: pointer
ClayRenderData* {.union.} = object # bycopy?
rectangle*: ClayRectangleRenderData
text*: ClayTextRenderData
image*: ClayImageRenderData
custom*: ClayCustomRenderData
border*: ClayBorderRenderData
scroll*: ClayScrollRenderData
ClayRenderCommand* {.bycopy.} = object
boundingBox*: ClayBoundingBox
renderData*: ClayRenderData
userData*: pointer
id*: uint32
zIndex*: int16
commandType*: ClayRenderCommandType
ClayRenderCommandArray* {.bycopy.} = object
capacity*, length*: int32
internalArray*: ptr UncheckedArray[ClayRenderCommand]
ClayErrorHandler* {.bycopy.} = object
errorFn*: (proc(errorText: ClayErrorData))
userData*: pointer
ClayTextElementConfig* {.bycopy.} = object
userData*: pointer
textColor*: ClayColor
fontId*: uint16
fontSize*: uint16
letterSpacing*: uint16
lineHeight*: uint16
wrapMode*: ClayTextElementConfigWrapMode
textAlignment*: ClayTextAlignment
ClayImageElementConfig* {.bycopy.} = object
imageData*: pointer
srcDimensions*: ClayDimensions
ClayFloatingAttachPoints* {.bycopy.} = object
element*: ClayFloatingAttachPointType
parent*: ClayFloatingAttachPointType
ClayFloatingElementConfig* {.bycopy.} = object
offset*: ClayVector2
expand*: ClayDimensions
parentId*: uint32
zIndex*: int16
attachPoints*: ClayFloatingAttachPoints
pointerCaptureMode*: ClayPointerCaptureMode
attachTo*: ClayFloatingAttachToElement
ClayCustomElementConfig* {.bycopy.} = object
customData*: pointer
ClayScrollElementConfig* {.bycopy.} = object
horizontal*, vertical*: bool
ClayBorderWidth* {.bycopy.} = object
left*, right*, top*, bottom*: uint16
betweenChildren*: uint16
ClayBorderElementConfig* {.bycopy.} = object
color*: ClayColor
width*: ClayBorderWidth
ClayElementDeclaration* {.bycopy.} = object
id*: ClayElementId
layout*: ClayLayoutConfig
backgroundColor*: ClayColor
cornerRadius*: ClayCornerRadius
image*: ClayImageElementConfig
floating*: ClayFloatingElementConfig
custom*: ClayCustomElementConfig
scroll*: ClayScrollElementConfig
border*: ClayBorderElementConfig
userData*: pointer
{.push callConv: cdecl, importc: "Clay__$1".}
proc OpenElement*()
proc ConfigureOpenElement*(config: ClayElementDeclaration)
proc CloseElement*()
proc HashString*(key: ClayString, offset, seed: uint32): ClayElementId
proc OpenTextElement*(text: ClayString, textConfig: ptr ClayTextElementConfig)
proc StoreTextElementConfig*(config: ClayTextElementConfig): ptr ClayTextElementConfig
proc GetParentElementId(): uint32
{.pop.}
{.push callConv: cdecl, importc: "$1".}
proc Clay_MinMemorySize*(): uint32
proc Clay_CreateArenaWithCapacityAndMemory*(capacity: uint32, memory: pointer): ClayArena
proc Clay_SetPointerState*(position: ClayVector2, pointerDown: bool)
proc Clay_Initialize*(
arena: ClayArena,
layoutDimensions: ClayDimensions,
errorHandler: ClayErrorHandler
): ClayContext
proc Clay_GetCurrentContext*(): ClayContext
proc Clay_SetCurrentContext*(ctx: ClayContext)
proc Clay_UpdateScrollContainers*(
enableDragScrolling: bool,
scrollDelta: ClayVector2,
deltaTime: cfloat
)
proc Clay_SetLayoutDimensions*(dimensions: ClayDimensions)
proc Clay_BeginLayout*()
proc Clay_EndLayout*(): ClayRenderCommandArray
proc Clay_GetElementId*(idString: ClayString): ClayElementId
proc Clay_GetElementIdWithIndex*(idString: ClayString, index: uint32): ClayElementId
proc Clay_GetElementData*(id: ClayElementId): pointer
proc Clay_Hovered*(): bool
proc Clay_OnHover*(fn: pointer, userData: int)
proc Clay_PointerOver*(id: ClayElementId): bool
proc Clay_GetScrollContainerData*(id: ClayElementId): pointer
proc Clay_SetMeasureTextFunction*(
fn: (proc(
text: ClayStringSlice,
config: ClayTextElementConfig,
userData: pointer
): ClayDimensions),
userData: pointer
)
proc Clay_SetQueryScrollOffsetFunction*(fn: pointer, userData: pointer)
proc Clay_SetDebugModeEnabled*(enabled: bool)
proc Clay_IsDebugModeEnabled*(): bool
proc Clay_SetCullingEnabled*(enabled: bool)
proc Clay_GetMaxElementCount*(): int32
proc Clay_SetMaxElementCount*(cnt: int32)
proc Clay_GetMaxMeasureTextCacheWordCount*(): int32
proc Clay_SetMaxMeasureTextCacheWordCount*(cnt: int32)
proc Clay_ResetMeasureTextCache*()
{.pop.}
template clayString*(s: static[string]): ClayString =
ClayString(length: s.len.int32, chars: cstring(s), isStaticallyAllocated: true)
template clayId*(label: static[string]): ClayElementId =
Clay_GetElementId(clayString(label))
template clayIdI*(label: static[string], idx: uint32): ClayElementId =
Clay_GetElementIdWithIndex(clayString(label), idx)
template clayDimensions*(w, h: cfloat): ClayDimensions =
ClayDimensions(width: w, height: h)
template clayVec2*(x, y: cfloat): ClayVector2 =
ClayVector2(x: x, y: y)
template paddingAll*(p: uint16): ClayPadding =
ClayPadding(left: p, right: p, top: p, bottom: p)
template cornerRadius*(r: cfloat): ClayCornerRadius =
ClayCornerRadius(topLeft: r, topRight: r, bottomLeft: r, bottomRight: r)
const FloatMax* = 3.4028235e38'f32
func sizingAxisFit*(min = 0.0f32, max = FloatMax): ClaySizingAxis =
result.size.minMax = ClaySizingMinMax(min: min, max: max)
result.kind = clSizingFit
func sizingAxisFixed*(fixedSize: cfloat): ClaySizingAxis =
result.size.minMax = ClaySizingMinMax(min: fixedSize, max: fixedSize)
result.kind = clSizingFixed
func sizingAxisGrow*(min = 0.0f32, max = FloatMax): ClaySizingAxis =
result.size.minMax = ClaySizingMinMax(min: min, max: max)
result.kind = clSizingGrow
proc `$`*(str: ClayStringSlice): string =
let strLen = str.length
return ($str.chars)[0..<strLen]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment