clay/bindings/odin/clay-odin/clay.odin

420 lines
13 KiB
Odin
Raw Normal View History

2024-08-30 09:58:08 +00:00
package clay
import "core:c"
import "core:strings"
when ODIN_OS == .Windows {
foreign import Clay "windows/clay.lib"
} else when ODIN_OS == .Linux {
2024-08-31 22:35:04 +00:00
foreign import Clay "linux/clay.a"
2024-08-30 09:58:08 +00:00
} else when ODIN_OS == .Darwin {
when ODIN_ARCH == .arm64 {
foreign import Clay "macos-arm64/clay.a"
} else {
foreign import Clay "macos/clay.a"
}
2024-08-31 01:04:33 +00:00
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
2024-08-31 22:35:04 +00:00
foreign import Clay "wasm/clay.o"
2024-08-30 09:58:08 +00:00
}
String :: struct {
length: c.int,
chars: [^]c.char,
}
Vector2 :: [2]c.float
Dimensions :: struct {
width: c.float,
height: c.float,
}
Arena :: struct {
label: String,
nextAllocation: u64,
capacity: u64,
2024-08-30 09:58:08 +00:00
memory: [^]c.char,
}
BoundingBox :: struct {
x: c.float,
y: c.float,
width: c.float,
height: c.float,
}
Color :: [4]c.float
CornerRadius :: struct {
topLeft: c.float,
topRight: c.float,
bottomLeft: c.float,
bottomRight: c.float,
}
BorderData :: struct {
width: u32,
2024-08-30 09:58:08 +00:00
color: Color,
}
2024-09-16 09:34:59 +00:00
ElementId :: struct {
id: u32,
offset: u32,
baseId: u32,
stringId: String,
}
2024-08-31 21:55:42 +00:00
when ODIN_OS == .Windows {
EnumBackingType :: u32
} else {
EnumBackingType :: u8
}
RenderCommandType :: enum EnumBackingType {
2024-08-30 09:58:08 +00:00
None,
Rectangle,
Border,
Text,
Image,
ScissorStart,
ScissorEnd,
Custom,
}
RectangleElementConfig :: struct {
color: Color,
cornerRadius: CornerRadius,
}
2024-09-16 09:34:59 +00:00
TextWrapMode :: enum EnumBackingType {
Words,
Newlines,
None,
}
2024-08-30 09:58:08 +00:00
TextElementConfig :: struct {
textColor: Color,
fontId: u16,
fontSize: u16,
letterSpacing: u16,
2024-10-06 06:34:42 +00:00
lineHeight: u16,
2024-09-16 09:34:59 +00:00
wrapMode: TextWrapMode,
2024-08-30 09:58:08 +00:00
}
ImageElementConfig :: struct {
imageData: rawptr,
sourceDimensions: Dimensions,
}
CustomElementConfig :: struct {
customData: rawptr,
}
BorderElementConfig :: struct {
left: BorderData,
right: BorderData,
top: BorderData,
bottom: BorderData,
betweenChildren: BorderData,
cornerRadius: CornerRadius,
}
ScrollElementConfig :: struct {
horizontal: bool,
vertical: bool,
2024-08-30 09:58:08 +00:00
}
2024-08-31 21:55:42 +00:00
FloatingAttachPointType :: enum EnumBackingType {
2024-08-30 09:58:08 +00:00
LEFT_TOP,
LEFT_CENTER,
LEFT_BOTTOM,
CENTER_TOP,
CENTER_CENTER,
CENTER_BOTTOM,
RIGHT_TOP,
RIGHT_CENTER,
RIGHT_BOTTOM,
}
FloatingAttachPoints :: struct {
element: FloatingAttachPointType,
parent: FloatingAttachPointType,
}
FloatingElementConfig :: struct {
offset: Vector2,
expand: Dimensions,
zIndex: u16,
parentId: u32,
2024-08-30 09:58:08 +00:00
attachment: FloatingAttachPoints,
}
ElementConfigUnion :: struct #raw_union {
rectangleElementConfig: ^RectangleElementConfig,
textElementConfig: ^TextElementConfig,
imageElementConfig: ^ImageElementConfig,
customElementConfig: ^CustomElementConfig,
borderElementConfig: ^BorderElementConfig,
}
RenderCommand :: struct {
boundingBox: BoundingBox,
config: ElementConfigUnion,
text: String,
id: u32,
2024-08-30 09:58:08 +00:00
commandType: RenderCommandType,
}
ScrollContainerData :: struct {
// Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
// Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
scrollPosition: ^Vector2,
scrollContainerDimensions: Dimensions,
contentDimensions: Dimensions,
config: ScrollElementConfig,
// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
found: bool,
2024-08-30 09:58:08 +00:00
}
2024-08-31 21:55:42 +00:00
SizingType :: enum EnumBackingType {
2024-08-30 09:58:08 +00:00
FIT,
GROW,
PERCENT,
2024-10-07 06:30:15 +00:00
FIXED,
2024-08-30 09:58:08 +00:00
}
SizingConstraintsMinMax :: struct {
min: c.float,
max: c.float,
}
SizingConstraints :: struct #raw_union {
sizeMinMax: SizingConstraintsMinMax,
sizePercent: c.float,
}
SizingAxis :: struct {
// Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
constraints: SizingConstraints,
type: SizingType,
}
Sizing :: struct {
width: SizingAxis,
height: SizingAxis,
}
Padding :: struct {
x: u16,
y: u16,
2024-08-30 09:58:08 +00:00
}
2024-08-31 21:55:42 +00:00
LayoutDirection :: enum EnumBackingType {
2024-08-30 09:58:08 +00:00
LEFT_TO_RIGHT,
TOP_TO_BOTTOM,
}
2024-08-31 21:55:42 +00:00
LayoutAlignmentX :: enum EnumBackingType {
2024-08-30 09:58:08 +00:00
LEFT,
RIGHT,
CENTER,
}
2024-08-31 21:55:42 +00:00
LayoutAlignmentY :: enum EnumBackingType {
2024-08-30 09:58:08 +00:00
TOP,
BOTTOM,
CENTER,
}
ChildAlignment :: struct {
x: LayoutAlignmentX,
y: LayoutAlignmentY,
}
LayoutConfig :: struct {
sizing: Sizing,
padding: Padding,
childGap: u16,
2024-08-30 09:58:08 +00:00
childAlignment: ChildAlignment,
2024-10-06 06:34:42 +00:00
layoutDirection: LayoutDirection,
2024-08-30 09:58:08 +00:00
}
ClayArray :: struct($type: typeid) {
capacity: u32,
length: u32,
2024-08-30 09:58:08 +00:00
internalArray: [^]type,
}
2024-08-31 01:04:33 +00:00
@(link_prefix = "Clay_", default_calling_convention = "c")
2024-08-30 09:58:08 +00:00
foreign Clay {
MinMemorySize :: proc() -> u32 ---
CreateArenaWithCapacityAndMemory :: proc(capacity: u32, offset: [^]u8) -> Arena ---
2024-09-16 09:34:59 +00:00
SetPointerState :: proc(position: Vector2, pointerDown: bool) ---
Initialize :: proc(arena: Arena, layoutDimensions: Dimensions) ---
UpdateScrollContainers :: proc(isPointerActive: bool, scrollDelta: Vector2, deltaTime: c.float) ---
2024-09-16 09:34:59 +00:00
SetLayoutDimensions :: proc(dimensions: Dimensions) ---
BeginLayout :: proc() ---
EndLayout :: proc() -> ClayArray(RenderCommand) ---
PointerOver :: proc(id: ElementId) -> bool ---
GetScrollContainerData :: proc(id: ElementId) -> ScrollContainerData ---
2024-09-13 01:38:39 +00:00
SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: ^String, config: ^TextElementConfig) -> Dimensions) ---
RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: i32) -> ^RenderCommand ---
2024-09-16 09:34:59 +00:00
SetDebugModeEnabled :: proc(enabled: bool) ---
2024-08-31 01:04:33 +00:00
}
@(link_prefix = "Clay_", default_calling_convention = "c", private)
foreign Clay {
2024-09-16 09:34:59 +00:00
_OpenContainerElement :: proc(id: ElementId, layoutConfig: ^LayoutConfig) ---
_OpenRectangleElement :: proc(id: ElementId, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
_OpenTextElement :: proc(id: ElementId, text: String, textConfig: ^TextElementConfig) ---
_OpenImageElement :: proc(id: ElementId, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
_OpenScrollElement :: proc(id: ElementId, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
_OpenFloatingElement :: proc(id: ElementId, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
_OpenBorderElement :: proc(id: ElementId, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
_OpenCustomElement :: proc(id: ElementId, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
2024-08-30 09:58:08 +00:00
_CloseElementWithChildren :: proc() ---
_CloseScrollElement :: proc() ---
_CloseFloatingElement :: proc() ---
_StoreLayoutConfig :: proc(config: LayoutConfig) -> ^LayoutConfig ---
_StoreRectangleElementConfig :: proc(config: RectangleElementConfig) -> ^RectangleElementConfig ---
_StoreTextElementConfig :: proc(config: TextElementConfig) -> ^TextElementConfig ---
_StoreImageElementConfig :: proc(config: ImageElementConfig) -> ^ImageElementConfig ---
_StoreFloatingElementConfig :: proc(config: FloatingElementConfig) -> ^FloatingElementConfig ---
_StoreCustomElementConfig :: proc(config: CustomElementConfig) -> ^CustomElementConfig ---
_StoreScrollElementConfig :: proc(config: ScrollElementConfig) -> ^ScrollElementConfig ---
_StoreBorderElementConfig :: proc(config: BorderElementConfig) -> ^BorderElementConfig ---
2024-09-28 03:49:43 +00:00
_HashString :: proc(toHash: String, index: u32, seed: u32) -> ElementId ---
_GetOpenLayoutElementId :: proc() -> u32 ---
2024-08-30 09:58:08 +00:00
}
@(require_results, deferred_none = _CloseElementWithChildren)
2024-09-16 09:34:59 +00:00
Container :: proc(id: ElementId, layoutConfig: ^LayoutConfig) -> bool {
2024-08-30 09:58:08 +00:00
_OpenContainerElement(id, layoutConfig)
return true
}
@(require_results, deferred_none = _CloseElementWithChildren)
2024-09-16 09:34:59 +00:00
Rectangle :: proc(id: ElementId, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) -> bool {
2024-08-30 09:58:08 +00:00
_OpenRectangleElement(id, layoutConfig, rectangleConfig)
return true
}
2024-09-16 09:34:59 +00:00
Text :: proc(id: ElementId, text: string, textConfig: ^TextElementConfig) -> bool {
_OpenTextElement(id, MakeString(text), textConfig)
2024-08-30 09:58:08 +00:00
return true
}
@(require_results, deferred_none = _CloseElementWithChildren)
2024-09-16 09:34:59 +00:00
Image :: proc(id: ElementId, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) -> bool {
2024-08-30 09:58:08 +00:00
_OpenImageElement(id, layoutConfig, imageConfig)
return true
}
@(require_results, deferred_none = _CloseScrollElement)
2024-09-16 09:34:59 +00:00
Scroll :: proc(id: ElementId, layoutConfig: ^LayoutConfig, scrollConfig: ^ScrollElementConfig) -> bool {
2024-08-30 09:58:08 +00:00
_OpenScrollElement(id, layoutConfig, scrollConfig)
return true
}
@(require_results, deferred_none = _CloseFloatingElement)
2024-09-16 09:34:59 +00:00
Floating :: proc(id: ElementId, layoutConfig: ^LayoutConfig, floatingConfig: ^FloatingElementConfig) -> bool {
2024-08-30 09:58:08 +00:00
_OpenFloatingElement(id, layoutConfig, floatingConfig)
return true
}
@(require_results, deferred_none = _CloseElementWithChildren)
2024-09-16 09:34:59 +00:00
Border :: proc(id: ElementId, layoutConfig: ^LayoutConfig, borderConfig: ^BorderElementConfig) -> bool {
2024-08-30 09:58:08 +00:00
_OpenBorderElement(id, layoutConfig, borderConfig)
return true
}
@(require_results, deferred_none = _CloseElementWithChildren)
2024-09-16 09:34:59 +00:00
Custom :: proc(id: ElementId, layoutConfig: ^LayoutConfig, customConfig: ^CustomElementConfig) -> bool {
2024-08-30 09:58:08 +00:00
_OpenCustomElement(id, layoutConfig, customConfig)
return true
}
Layout :: proc(config: LayoutConfig) -> ^LayoutConfig {
return _StoreLayoutConfig(config)
2024-08-30 09:58:08 +00:00
}
RectangleConfig :: proc(config: RectangleElementConfig) -> ^RectangleElementConfig {
return _StoreRectangleElementConfig(config)
2024-08-30 09:58:08 +00:00
}
TextConfig :: proc(config: TextElementConfig) -> ^TextElementConfig {
return _StoreTextElementConfig(config)
2024-08-30 09:58:08 +00:00
}
ImageConfig :: proc(config: ImageElementConfig) -> ^ImageElementConfig {
return _StoreImageElementConfig(config)
2024-08-30 09:58:08 +00:00
}
FloatingConfig :: proc(config: FloatingElementConfig) -> ^FloatingElementConfig {
return _StoreFloatingElementConfig(config)
2024-08-30 09:58:08 +00:00
}
CustomConfig :: proc(config: CustomElementConfig) -> ^CustomElementConfig {
return _StoreCustomElementConfig(config)
2024-08-30 09:58:08 +00:00
}
ScrollConfig :: proc(config: ScrollElementConfig) -> ^ScrollElementConfig {
return _StoreScrollElementConfig(config)
2024-08-30 09:58:08 +00:00
}
BorderConfig :: proc(config: BorderElementConfig) -> ^BorderElementConfig {
return _StoreBorderElementConfig(config)
2024-08-30 09:58:08 +00:00
}
BorderConfigOutside :: proc(outsideBorders: BorderData) -> ^BorderElementConfig {
return _StoreBorderElementConfig((BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders})
2024-08-30 09:58:08 +00:00
}
BorderConfigOutsideRadius :: proc(outsideBorders: BorderData, radius: f32) -> ^BorderElementConfig {
return _StoreBorderElementConfig(
2024-08-30 09:58:08 +00:00
(BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders, cornerRadius = {radius, radius, radius, radius}},
)
}
BorderConfigAll :: proc(allBorders: BorderData) -> ^BorderElementConfig {
return _StoreBorderElementConfig((BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, betweenChildren = allBorders})
2024-08-30 09:58:08 +00:00
}
BorderConfigAllRadius :: proc(allBorders: BorderData, radius: f32) -> ^BorderElementConfig {
return _StoreBorderElementConfig(
2024-08-30 09:58:08 +00:00
(BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, cornerRadius = {radius, radius, radius, radius}},
)
}
CornerRadiusAll :: proc(radius: f32) -> CornerRadius {
return CornerRadius{radius, radius, radius, radius}
}
SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
return SizingAxis{type = SizingType.FIT, constraints = {sizeMinMax = sizeMinMax}}
}
SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
return SizingAxis{type = SizingType.GROW, constraints = {sizeMinMax = sizeMinMax}}
}
SizingFixed :: proc(size: c.float) -> SizingAxis {
2024-10-07 06:30:15 +00:00
return SizingAxis{type = SizingType.FIXED, constraints = {sizeMinMax = {size, size}}}
2024-08-30 09:58:08 +00:00
}
SizingPercent :: proc(sizePercent: c.float) -> SizingAxis {
return SizingAxis{type = SizingType.PERCENT, constraints = {sizePercent = sizePercent}}
}
MakeString :: proc(label: string) -> String {
return String{chars = raw_data(label), length = cast(c.int)len(label)}
}
2024-09-16 09:34:59 +00:00
ID :: proc(label: string, index: u32 = 0) -> ElementId {
2024-09-28 03:49:43 +00:00
return _HashString(MakeString(label), index, 0)
}
IDLocal :: proc(label: string, index: u32 = 0) -> ElementId {
return _HashString(MakeString(label), index, _GetOpenLayoutElementId())
2024-08-30 09:58:08 +00:00
}