Finish off odin bindings and add raylib example

This commit is contained in:
Nic Barker 2024-08-29 21:36:31 +12:00
parent cf61b75ba5
commit b2fde01a22
7 changed files with 550 additions and 316 deletions

View File

@ -0,0 +1 @@
TODO

View File

@ -5,429 +5,423 @@ import "core:strings"
foreign import Clay "clay.a" foreign import Clay "clay.a"
String :: struct { String :: struct {
length: c.int, length: c.int,
chars: [^]c.char, chars: [^]c.char,
} }
Vector2 :: struct { Vector2 :: struct {
x: c.float, x: c.float,
y: c.float, y: c.float,
} }
Dimensions :: struct { Dimensions :: struct {
width: c.float, width: c.float,
height: c.float, height: c.float,
} }
Arena :: struct { Arena :: struct {
label: String, label: String,
nextAllocation: c.uint64_t, nextAllocation: c.uint64_t,
capacity: c.uint64_t, capacity: c.uint64_t,
memory: [^]c.char, memory: [^]c.char,
} }
BoundingBox :: struct { BoundingBox :: struct {
x: c.float, x: c.float,
y: c.float, y: c.float,
width: c.float, width: c.float,
height: c.float, height: c.float,
} }
Color :: struct { Color :: struct {
r: c.float, r: c.float,
g: c.float, g: c.float,
b: c.float, b: c.float,
a: c.float, a: c.float,
} }
CornerRadius :: struct { CornerRadius :: struct {
topLeft: c.float, topLeft: c.float,
topRight: c.float, topRight: c.float,
bottomLeft: c.float, bottomLeft: c.float,
bottomRight: c.float, bottomRight: c.float,
} }
BorderData :: struct { BorderData :: struct {
width: c.uint32_t, width: c.uint32_t,
color: Color, color: Color,
} }
RenderCommandType :: enum u8 { RenderCommandType :: enum u8 {
None, None,
Rectangle, Rectangle,
Border, Border,
Text, Text,
Image, Image,
ScissorStart, ScissorStart,
ScissorEnd, ScissorEnd,
Custom, Custom,
} }
RectangleElementConfig :: struct { RectangleElementConfig :: struct {
color: Color, color: Color,
cornerRadius: CornerRadius, cornerRadius: CornerRadius,
} }
TextElementConfig :: struct { TextElementConfig :: struct {
textColor: Color, textColor: Color,
fontId: c.uint16_t, fontId: c.uint16_t,
fontSize: c.uint16_t, fontSize: c.uint16_t,
letterSpacing: c.uint16_t, letterSpacing: c.uint16_t,
lineSpacing: c.uint16_t, lineSpacing: c.uint16_t,
} }
ImageElementConfig :: struct { ImageElementConfig :: struct {
imageData: rawptr, imageData: rawptr,
sourceDimensions: Dimensions, sourceDimensions: Dimensions,
} }
CustomElementConfig :: struct { CustomElementConfig :: struct {
customData: rawptr, customData: rawptr,
} }
BorderElementConfig :: struct { BorderElementConfig :: struct {
left: BorderData, left: BorderData,
right: BorderData, right: BorderData,
top: BorderData, top: BorderData,
bottom: BorderData, bottom: BorderData,
betweenChildren: BorderData, betweenChildren: BorderData,
cornerRadius: CornerRadius, cornerRadius: CornerRadius,
} }
ScrollElementConfig :: struct { ScrollElementConfig :: struct {
horizontal: c.bool, horizontal: c.bool,
vertical: c.bool, vertical: c.bool,
} }
FloatingAttachPointType :: enum u8 { FloatingAttachPointType :: enum u8 {
LEFT_TOP, LEFT_TOP,
LEFT_CENTER, LEFT_CENTER,
LEFT_BOTTOM, LEFT_BOTTOM,
CENTER_TOP, CENTER_TOP,
CENTER_CENTER, CENTER_CENTER,
CENTER_BOTTOM, CENTER_BOTTOM,
RIGHT_TOP, RIGHT_TOP,
RIGHT_CENTER, RIGHT_CENTER,
RIGHT_BOTTOM, RIGHT_BOTTOM,
} }
FloatingAttachPoints :: struct { FloatingAttachPoints :: struct {
element: FloatingAttachPointType, element: FloatingAttachPointType,
parent: FloatingAttachPointType, parent: FloatingAttachPointType,
} }
FloatingElementConfig :: struct { FloatingElementConfig :: struct {
offset: Vector2, offset: Vector2,
expand: Dimensions, expand: Dimensions,
zIndex: c.uint16_t, zIndex: c.uint16_t,
parentId: c.uint32_t, parentId: c.uint32_t,
attachment: FloatingAttachPoints, attachment: FloatingAttachPoints,
} }
ElementConfigUnion :: struct #raw_union { ElementConfigUnion :: struct #raw_union {
rectangleElementConfig: ^RectangleElementConfig, rectangleElementConfig: ^RectangleElementConfig,
textElementConfig: ^TextElementConfig, textElementConfig: ^TextElementConfig,
imageElementConfig: ^ImageElementConfig, imageElementConfig: ^ImageElementConfig,
customElementConfig: ^CustomElementConfig, customElementConfig: ^CustomElementConfig,
borderElementConfig: ^BorderElementConfig, borderElementConfig: ^BorderElementConfig,
} }
RenderCommand :: struct { RenderCommand :: struct {
boundingBox: BoundingBox, boundingBox: BoundingBox,
config: ElementConfigUnion, config: ElementConfigUnion,
text: String, text: String,
id: c.uint32_t, id: c.uint32_t,
commandType: RenderCommandType, commandType: RenderCommandType,
} }
ScrollContainerData :: struct { ScrollContainerData :: struct {
// Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout. // 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. // Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
scrollPosition: ^Vector2, scrollPosition: ^Vector2,
scrollContainerDimensions: Dimensions, scrollContainerDimensions: Dimensions,
contentDimensions: Dimensions, contentDimensions: Dimensions,
config: ScrollElementConfig, config: ScrollElementConfig,
// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned. // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
found: c.bool, found: c.bool,
} }
SizingType :: enum u8 { SizingType :: enum u8 {
FIT, FIT,
GROW, GROW,
PERCENT, PERCENT,
}
SizingConstraintsMinMax :: struct {
min: c.float,
max: c.float,
}
SizingConstraints :: struct #raw_union {
sizeMinMax: SizingConstraintsMinMax,
sizePercent: c.float,
} }
SizingAxis :: struct { SizingAxis :: struct {
// Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions // Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
min: c.float, constraints: SizingConstraints,
max: c.float, type: SizingType,
type: SizingType,
} }
Sizing :: struct { Sizing :: struct {
width: SizingAxis, width: SizingAxis,
height: SizingAxis, height: SizingAxis,
} }
Padding :: struct { Padding :: struct {
x: c.uint16_t, x: c.uint16_t,
y: c.uint16_t, y: c.uint16_t,
} }
LayoutDirection :: enum u8 { LayoutDirection :: enum u8 {
LEFT_TO_RIGHT, LEFT_TO_RIGHT,
TOP_TO_BOTTOM, TOP_TO_BOTTOM,
} }
LayoutAlignmentX :: enum u8 { LayoutAlignmentX :: enum u8 {
LEFT, LEFT,
RIGHT, RIGHT,
CENTER, CENTER,
} }
LayoutAlignmentY :: enum u8 { LayoutAlignmentY :: enum u8 {
TOP, TOP,
BOTTOM, BOTTOM,
CENTER, CENTER,
} }
ChildAlignment :: struct { ChildAlignment :: struct {
x: LayoutAlignmentX, x: LayoutAlignmentX,
y: LayoutAlignmentY, y: LayoutAlignmentY,
} }
LayoutConfig :: struct { LayoutConfig :: struct {
sizing: Sizing, sizing: Sizing,
padding: Padding, padding: Padding,
childGap: c.uint16_t, childGap: c.uint16_t,
layoutDirection: LayoutDirection, layoutDirection: LayoutDirection,
childAlignment: ChildAlignment, childAlignment: ChildAlignment,
} }
ClayArray :: struct($type: typeid) { ClayArray :: struct($type: typeid) {
capacity: c.uint32_t, capacity: c.uint32_t,
length: c.uint32_t, length: c.uint32_t,
internalArray: [^]type, internalArray: [^]type,
} }
@(link_prefix = "Clay_")
foreign Clay { foreign Clay {
Clay_MinMemorySize :: proc() -> c.uint32_t --- MinMemorySize :: proc() -> c.uint32_t ---
Clay_CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena --- CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena ---
Clay_SetPointerPosition :: proc(position: Vector2) --- SetPointerPosition :: proc(position: Vector2) ---
Clay_Initialize :: proc(arena: Arena) --- Initialize :: proc(arena: Arena) ---
Clay_UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) --- UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) ---
Clay_BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) --- BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) ---
Clay_EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) --- EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) ---
Clay_PointerOver :: proc(id: c.uint32_t) -> c.bool --- PointerOver :: proc(id: c.uint32_t) -> c.bool ---
Clay_GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData --- GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData ---
Clay_SetMeasureTextFunction :: proc(measureTextFunction: proc(text: [^]String, config: [^]TextElementConfig) -> Dimensions) --- SetMeasureTextFunction :: proc(measureTextFunction: proc(text: ^String, config: ^TextElementConfig) -> Dimensions) ---
Clay__OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) --- RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: c.int32_t) -> ^RenderCommand ---
Clay__OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) --- @(private)
Clay__OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) --- _OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) ---
Clay__OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) --- @(private)
Clay__OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) --- _OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
Clay__OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) --- @(private)
Clay__OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) --- _OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) ---
Clay__OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) --- @(private)
Clay__CloseElementWithChildren :: proc() --- _OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
Clay__CloseScrollElement :: proc() --- @(private)
Clay__CloseFloatingElement :: proc() --- _OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
Clay__layoutConfigs: ClayArray(LayoutConfig) @(private)
Clay__LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig --- _OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
Clay__rectangleElementConfigs: ClayArray(RectangleElementConfig) @(private)
Clay__RectangleElementConfigArray_Add :: proc(array: ^ClayArray(RectangleElementConfig), config: RectangleElementConfig) -> ^RectangleElementConfig --- _OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
Clay__textElementConfigs: ClayArray(TextElementConfig) @(private)
Clay__TextElementConfigArray_Add :: proc(array: ^ClayArray(TextElementConfig), config: TextElementConfig) -> ^TextElementConfig --- _OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
Clay__imageElementConfigs: ClayArray(ImageElementConfig) @(private)
Clay__ImageElementConfigArray_Add :: proc(array: ^ClayArray(ImageElementConfig), config: ImageElementConfig) -> ^ImageElementConfig --- _CloseElementWithChildren :: proc() ---
Clay__floatingElementConfigs: ClayArray(FloatingElementConfig) @(private)
Clay__FloatingElementConfigArray_Add :: proc(array: ^ClayArray(FloatingElementConfig), config: FloatingElementConfig) -> ^FloatingElementConfig --- _CloseScrollElement :: proc() ---
Clay__customElementConfigs: ClayArray(CustomElementConfig) @(private)
Clay__CustomElementConfigArray_Add :: proc(array: ^ClayArray(CustomElementConfig), config: CustomElementConfig) -> ^CustomElementConfig --- _CloseFloatingElement :: proc() ---
Clay__scrollElementConfigs: ClayArray(ScrollElementConfig) @(private)
Clay__ScrollElementConfigArray_Add :: proc(array: ^ClayArray(ScrollElementConfig), config: ScrollElementConfig) -> ^ScrollElementConfig --- _layoutConfigs: ClayArray(LayoutConfig)
Clay__borderElementConfigs: ClayArray(BorderElementConfig) @(private)
Clay__BorderElementConfigArray_Add :: proc(array: ^ClayArray(BorderElementConfig), config: BorderElementConfig) -> ^BorderElementConfig --- _LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig ---
Clay__HashString :: proc(toHash: String, index: c.uint32_t) -> c.uint32_t --- @(private)
_rectangleElementConfigs: ClayArray(RectangleElementConfig)
@(private)
_RectangleElementConfigArray_Add :: proc(array: ^ClayArray(RectangleElementConfig), config: RectangleElementConfig) -> ^RectangleElementConfig ---
@(private)
_textElementConfigs: ClayArray(TextElementConfig)
@(private)
_TextElementConfigArray_Add :: proc(array: ^ClayArray(TextElementConfig), config: TextElementConfig) -> ^TextElementConfig ---
@(private)
_imageElementConfigs: ClayArray(ImageElementConfig)
@(private)
_ImageElementConfigArray_Add :: proc(array: ^ClayArray(ImageElementConfig), config: ImageElementConfig) -> ^ImageElementConfig ---
@(private)
_floatingElementConfigs: ClayArray(FloatingElementConfig)
@(private)
_FloatingElementConfigArray_Add :: proc(array: ^ClayArray(FloatingElementConfig), config: FloatingElementConfig) -> ^FloatingElementConfig ---
@(private)
_customElementConfigs: ClayArray(CustomElementConfig)
@(private)
_CustomElementConfigArray_Add :: proc(array: ^ClayArray(CustomElementConfig), config: CustomElementConfig) -> ^CustomElementConfig ---
@(private)
_scrollElementConfigs: ClayArray(ScrollElementConfig)
@(private)
_ScrollElementConfigArray_Add :: proc(array: ^ClayArray(ScrollElementConfig), config: ScrollElementConfig) -> ^ScrollElementConfig ---
@(private)
_borderElementConfigs: ClayArray(BorderElementConfig)
@(private)
_BorderElementConfigArray_Add :: proc(array: ^ClayArray(BorderElementConfig), config: BorderElementConfig) -> ^BorderElementConfig ---
@(private)
_HashString :: proc(toHash: String, index: c.uint32_t) -> c.uint32_t ---
} }
MinMemorySize :: proc() -> c.uint32_t {
return Clay_MinMemorySize()
}
CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena { @(require_results, deferred_none = _CloseElementWithChildren)
return Clay_CreateArenaWithCapacityAndMemory(capacity, offset)
}
SetPointerPosition :: proc(position: Vector2) {
Clay_SetPointerPosition(position)
}
Initialize :: proc(arena: Arena) {
Clay_Initialize(arena)
}
UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) {
Clay_UpdateScrollContainers(isPointerActive, scrollDelta, deltaTime)
}
BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) {
Clay_BeginLayout(screenWidth, screenHeight)
}
EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) {
return Clay_EndLayout(screenWidth, screenHeight)
}
PointerOver :: proc(id: c.uint32_t) -> c.bool {
return Clay_PointerOver(id)
}
GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData {
return Clay_GetScrollContainerData(id)
}
@(deferred_none = Clay__CloseElementWithChildren)
Container :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) -> bool { Container :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) -> bool {
Clay__OpenContainerElement(id, layoutConfig) _OpenContainerElement(id, layoutConfig)
return true return true
} }
@(deferred_none = Clay__CloseElementWithChildren) @(require_results, deferred_none = _CloseElementWithChildren)
Rectangle :: proc( Rectangle :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) -> bool {
id: c.uint32_t, _OpenRectangleElement(id, layoutConfig, rectangleConfig)
layoutConfig: ^LayoutConfig, return true
rectangleConfig: ^RectangleElementConfig,
) -> bool {
Clay__OpenRectangleElement(id, layoutConfig, rectangleConfig)
return true
} }
Text :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) -> bool { Text :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) -> bool {
Clay__OpenTextElement(id, text, textConfig) _OpenTextElement(id, text, textConfig)
return true return true
} }
@(deferred_none = Clay__CloseElementWithChildren) @(require_results, deferred_none = _CloseElementWithChildren)
Image :: proc( Image :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) -> bool {
id: c.uint32_t, _OpenImageElement(id, layoutConfig, imageConfig)
layoutConfig: ^LayoutConfig, return true
imageConfig: ^ImageElementConfig,
) -> bool {
Clay__OpenImageElement(id, layoutConfig, imageConfig)
return true
} }
@(deferred_none = Clay__CloseScrollElement) @(require_results, deferred_none = _CloseScrollElement)
Scroll :: proc( Scroll :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, scrollConfig: ^ScrollElementConfig) -> bool {
id: c.uint32_t, _OpenScrollElement(id, layoutConfig, scrollConfig)
layoutConfig: ^LayoutConfig, return true
scrollConfig: ^ScrollElementConfig,
) -> bool {
Clay__OpenScrollElement(id, layoutConfig, scrollConfig)
return true
} }
@(deferred_none = Clay__CloseFloatingElement) @(require_results, deferred_none = _CloseFloatingElement)
Floating :: proc( Floating :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, floatingConfig: ^FloatingElementConfig) -> bool {
id: c.uint32_t, _OpenFloatingElement(id, layoutConfig, floatingConfig)
layoutConfig: ^LayoutConfig, return true
floatingConfig: ^FloatingElementConfig,
) -> bool {
Clay__OpenFloatingElement(id, layoutConfig, floatingConfig)
return true
} }
@(deferred_none = Clay__CloseElementWithChildren) @(require_results, deferred_none = _CloseElementWithChildren)
Border :: proc( Border :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, borderConfig: ^BorderElementConfig) -> bool {
id: c.uint32_t, _OpenBorderElement(id, layoutConfig, borderConfig)
layoutConfig: ^LayoutConfig, return true
borderConfig: ^BorderElementConfig,
) -> bool {
Clay__OpenBorderElement(id, layoutConfig, borderConfig)
return true
} }
@(deferred_none = Clay__CloseElementWithChildren) @(require_results, deferred_none = _CloseElementWithChildren)
Custom :: proc( Custom :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, customConfig: ^CustomElementConfig) -> bool {
id: c.uint32_t, _OpenCustomElement(id, layoutConfig, customConfig)
layoutConfig: ^LayoutConfig, return true
customConfig: ^CustomElementConfig,
) -> bool {
Clay__OpenCustomElement(id, layoutConfig, customConfig)
return true
} }
Layout :: proc(config: LayoutConfig) -> ^LayoutConfig { Layout :: proc(config: LayoutConfig) -> ^LayoutConfig {
return Clay__LayoutConfigArray_Add(&Clay__layoutConfigs, config) return _LayoutConfigArray_Add(&_layoutConfigs, config)
} }
RectangleConfig :: proc(config: RectangleElementConfig) -> ^RectangleElementConfig { RectangleConfig :: proc(config: RectangleElementConfig) -> ^RectangleElementConfig {
return Clay__RectangleElementConfigArray_Add(&Clay__rectangleElementConfigs, config) return _RectangleElementConfigArray_Add(&_rectangleElementConfigs, config)
} }
TextConfig :: proc(config: TextElementConfig) -> ^TextElementConfig { TextConfig :: proc(config: TextElementConfig) -> ^TextElementConfig {
return Clay__TextElementConfigArray_Add(&Clay__textElementConfigs, config) return _TextElementConfigArray_Add(&_textElementConfigs, config)
} }
ImageConfig :: proc(config: ImageElementConfig) -> ^ImageElementConfig { ImageConfig :: proc(config: ImageElementConfig) -> ^ImageElementConfig {
return Clay__ImageElementConfigArray_Add(&Clay__imageElementConfigs, config) return _ImageElementConfigArray_Add(&_imageElementConfigs, config)
} }
FloatingConfig :: proc(config: FloatingElementConfig) -> ^FloatingElementConfig { FloatingConfig :: proc(config: FloatingElementConfig) -> ^FloatingElementConfig {
return Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, config) return _FloatingElementConfigArray_Add(&_floatingElementConfigs, config)
} }
Custom_elementConfig :: proc(config: CustomElementConfig) -> ^CustomElementConfig { Custom_elementConfig :: proc(config: CustomElementConfig) -> ^CustomElementConfig {
return Clay__CustomElementConfigArray_Add(&Clay__customElementConfigs, config) return _CustomElementConfigArray_Add(&_customElementConfigs, config)
} }
ScrollConfig :: proc(config: ScrollElementConfig) -> ^ScrollElementConfig { ScrollConfig :: proc(config: ScrollElementConfig) -> ^ScrollElementConfig {
return Clay__ScrollElementConfigArray_Add(&Clay__scrollElementConfigs, config) return _ScrollElementConfigArray_Add(&_scrollElementConfigs, config)
} }
BorderConfig :: proc(config: BorderElementConfig) -> ^BorderElementConfig { BorderConfig :: proc(config: BorderElementConfig) -> ^BorderElementConfig {
return Clay__BorderElementConfigArray_Add(&Clay__borderElementConfigs, config) return _BorderElementConfigArray_Add(&_borderElementConfigs, config)
} }
BorderConfigOutside :: proc(outsideBorders: BorderData) -> ^BorderElementConfig { BorderConfigOutside :: proc(outsideBorders: BorderData) -> ^BorderElementConfig {
return Clay__BorderElementConfigArray_Add( return _BorderElementConfigArray_Add(
&Clay__borderElementConfigs, &_borderElementConfigs,
(BorderElementConfig) { (BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders},
left = outsideBorders, )
right = outsideBorders,
top = outsideBorders,
bottom = outsideBorders,
},
)
} }
// BorderConfig_outside_radius :: proc(width, color, radius) Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { width, color }, .right = { width, color }, .top = { width, color }, .bottom = { width, color }, .cornerRadius = { radius, radius, radius, radius } })) -> CLAY_BORDER_CONFIG_OUTSIDE_RADIUS BorderConfigOutsideRadius :: proc(outsideBorders: BorderData, radius: f32) -> ^BorderElementConfig {
return _BorderElementConfigArray_Add(
&_borderElementConfigs,
(BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders, cornerRadius = {radius, radius, radius, radius}},
)
}
// BorderConfig_all :: proc(...) Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { __VA_ARGS__ }, .right = { __VA_ARGS__ }, .top = { __VA_ARGS__ }, .bottom = { __VA_ARGS__ }, .betweenChildren = { __VA_ARGS__ } })) -> CLAY_BORDER_CONFIG_ALL BorderConfigAll :: proc(allBorders: BorderData) -> ^BorderElementConfig {
return _BorderElementConfigArray_Add(
&_borderElementConfigs,
(BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, betweenChildren = allBorders},
)
}
// BorderConfig_all_radius :: proc(width, color, radius) Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { __VA_ARGS__ }, .right = { __VA_ARGS__ }, .top = { __VA_ARGS__ }, .bottom = { __VA_ARGS__ }, .betweenChildren = { __VA_ARGS__ }, .cornerRadius = { radius, radius, radius, radius }})) -> CLAY_BORDER_CONFIG_ALL_RADIUS BorderConfigAllRadius :: proc(allBorders: BorderData, radius: f32) -> ^BorderElementConfig {
return _BorderElementConfigArray_Add(
&_borderElementConfigs,
(BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, cornerRadius = {radius, radius, radius, radius}},
)
}
// Corner_radius :: proc(radius) (Clay_CornerRadius) { radius, radius, radius, radius }) -> CLAY_CORNER_RADIUS SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
return SizingAxis{type = SizingType.FIT, constraints = {sizeMinMax = sizeMinMax}}
}
// Sizing_fit :: proc(...) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_FIT, .sizeMinMax = (Clay_SizingMinMax) {__VA_ARGS__} }) -> CLAY_SIZING_FIT SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
return SizingAxis{type = SizingType.GROW, constraints = {sizeMinMax = sizeMinMax}}
}
// Sizing_grow :: proc(...) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_GROW, .sizeMinMax = (Clay_SizingMinMax) {__VA_ARGS__} }) -> CLAY_SIZING_GROW SizingFixed :: proc(size: c.float) -> SizingAxis {
return SizingAxis{type = SizingType.FIT, constraints = {sizeMinMax = {size, size}}}
}
// Sizing_fixed :: proc(fixedSize) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_GROW, .sizeMinMax = { fixedSize, fixedSize } }) -> CLAY_SIZING_FIXED SizingPercent :: proc(sizePercent: c.float) -> SizingAxis {
return SizingAxis{type = SizingType.PERCENT, constraints = {sizePercent = sizePercent}}
}
// Sizing_percent :: proc(percentOfParent) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_PERCENT, .sizePercent = percentOfParent }) -> CLAY_SIZING_PERCENT MakeString :: proc(label: string) -> String {
return String{chars = raw_data(label), length = cast(c.int)len(label)}
ClayString :: proc(label: string) -> String {
return String{chars = raw_data(label), length = cast(c.int)len(label)}
} }
ID :: proc(label: string) -> c.uint32_t { ID :: proc(label: string) -> c.uint32_t {
return Clay__HashString(ClayString(label), 0) return _HashString(MakeString(label), 0)
} }
IDI :: proc(label: string, index: u32) -> c.uint32_t { IDI :: proc(label: string, index: u32) -> c.uint32_t {
return Clay__HashString(ClayString(label), index) return _HashString(MakeString(label), index)
} }
// _string_length :: proc(s) ((sizeof(s) / sizeof(s[0])) - sizeof(s[0]))) -> CLAY__STRING_LENGTH

View File

@ -0,0 +1,224 @@
package main
import clay "clay-odin"
import "core:math"
import "vendor:raylib"
RaylibFont :: struct {
fontId: u32,
font: raylib.Font,
}
clayColorToRaylibColor :: proc(color: clay.Color) -> raylib.Color {
return raylib.Color{cast(u8)color.r, cast(u8)color.g, cast(u8)color.b, cast(u8)color.a}
}
raylibFonts := [10]RaylibFont{}
measureText :: proc "c" (text: ^clay.String, config: ^clay.TextElementConfig) -> clay.Dimensions {
// Measure string size for Font
textSize: clay.Dimensions = {0, 0}
maxTextWidth: f32 = 0
lineTextWidth: f32 = 0
textHeight: f32 = cast(f32)config.fontSize
fontToUse: raylib.Font = raylibFonts[config.fontId].font
for i := 0; i < cast(int)text.length; i += 1 {
if (text.chars[i] == '\n') {
maxTextWidth = math.max(maxTextWidth, lineTextWidth)
lineTextWidth = 0
continue
}
index: i32 = cast(i32)text.chars[i] - 32
if (fontToUse.glyphs[index].advanceX != 0) {
lineTextWidth += cast(f32)fontToUse.glyphs[index].advanceX
} else {
lineTextWidth += (fontToUse.recs[index].width + cast(f32)fontToUse.glyphs[index].offsetX)
}
}
maxTextWidth = math.max(maxTextWidth, lineTextWidth)
textSize.width = maxTextWidth / 2
textSize.height = textHeight
return textSize
}
clayRaylibRender :: proc(renderCommands: ^clay.ClayArray(clay.RenderCommand)) {
for i := 0; i < cast(int)renderCommands.length; i += 1 {
renderCommand: ^clay.RenderCommand = clay.RenderCommandArray_Get(renderCommands, cast(i32)i)
boundingBox: clay.BoundingBox = renderCommand.boundingBox
switch (renderCommand.commandType)
{
case clay.RenderCommandType.None:
{
break
}
case clay.RenderCommandType.Text:
{
// Raylib uses standard C strings so isn't compatible with cheap slices, we need to clone the string to append null terminator
text: clay.String = renderCommand.text
cloned: []u8 = make([]u8, text.length + 1)
copy(cloned[0:text.length], text.chars[0:text.length])
cloned[text.length] = 0
fontToUse: raylib.Font = raylibFonts[renderCommand.config.textElementConfig.fontId].font
raylib.DrawTextEx(
fontToUse,
cstring(raw_data(cloned)),
raylib.Vector2{boundingBox.x, boundingBox.y},
cast(f32)renderCommand.config.textElementConfig.fontSize,
cast(f32)renderCommand.config.textElementConfig.letterSpacing,
clayColorToRaylibColor(renderCommand.config.textElementConfig.textColor),
)
delete(cloned)
break
}
case clay.RenderCommandType.Image:
{
imageTexture: ^raylib.Texture2D = cast(^raylib.Texture2D)renderCommand.config.imageElementConfig.imageData
raylib.DrawTextureEx(imageTexture^, raylib.Vector2{boundingBox.x, boundingBox.y}, 0, boundingBox.width / cast(f32)imageTexture.width, raylib.WHITE)
break
}
case clay.RenderCommandType.ScissorStart:
{
raylib.BeginScissorMode(
cast(i32)math.round(boundingBox.x),
cast(i32)math.round(boundingBox.y),
cast(i32)math.round(boundingBox.width),
cast(i32)math.round(boundingBox.height),
)
break
}
case clay.RenderCommandType.ScissorEnd:
{
raylib.EndScissorMode()
break
}
case clay.RenderCommandType.Rectangle:
{
config: ^clay.RectangleElementConfig = renderCommand.config.rectangleElementConfig
if (config.cornerRadius.topLeft > 0) {
radius: f32 = (config.cornerRadius.topLeft * 2) / (boundingBox.width > boundingBox.height ? boundingBox.height : boundingBox.width)
raylib.DrawRectangleRounded(
raylib.Rectangle{boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height},
radius,
8,
clayColorToRaylibColor(config.color),
)
} else {
raylib.DrawRectangle(
cast(i32)boundingBox.x,
cast(i32)boundingBox.y,
cast(i32)boundingBox.width,
cast(i32)boundingBox.height,
clayColorToRaylibColor(config.color),
)
}
break
}
case clay.RenderCommandType.Border:
{
config: ^clay.BorderElementConfig = renderCommand.config.borderElementConfig
// Left border
if (config.left.width > 0) {
raylib.DrawRectangle(
cast(i32)math.round(boundingBox.x),
cast(i32)math.round(boundingBox.y + config.cornerRadius.topLeft),
cast(i32)config.left.width,
cast(i32)math.round(boundingBox.height - config.cornerRadius.topLeft - config.cornerRadius.bottomLeft),
clayColorToRaylibColor(config.left.color),
)
}
// Right border
if (config.right.width > 0) {
raylib.DrawRectangle(
cast(i32)math.round(boundingBox.x + boundingBox.width - cast(f32)config.right.width),
cast(i32)math.round(boundingBox.y + config.cornerRadius.topRight),
cast(i32)config.right.width,
cast(i32)math.round(boundingBox.height - config.cornerRadius.topRight - config.cornerRadius.bottomRight),
clayColorToRaylibColor(config.right.color),
)
}
// Top border
if (config.top.width > 0) {
raylib.DrawRectangle(
cast(i32)math.round(boundingBox.x + config.cornerRadius.topLeft),
cast(i32)math.round(boundingBox.y),
cast(i32)math.round(boundingBox.width - config.cornerRadius.topLeft - config.cornerRadius.topRight),
cast(i32)config.top.width,
clayColorToRaylibColor(config.top.color),
)
}
// Bottom border
if (config.bottom.width > 0) {
raylib.DrawRectangle(
cast(i32)math.round(boundingBox.x + config.cornerRadius.bottomLeft),
cast(i32)math.round(boundingBox.y + boundingBox.height - cast(f32)config.bottom.width),
cast(i32)math.round(boundingBox.width - config.cornerRadius.bottomLeft - config.cornerRadius.bottomRight),
cast(i32)config.bottom.width,
clayColorToRaylibColor(config.bottom.color),
)
}
if (config.cornerRadius.topLeft > 0) {
raylib.DrawRing(
raylib.Vector2{math.round(boundingBox.x + config.cornerRadius.topLeft), math.round(boundingBox.y + config.cornerRadius.topLeft)},
math.round(config.cornerRadius.topLeft - cast(f32)config.top.width),
config.cornerRadius.topLeft,
180,
270,
10,
clayColorToRaylibColor(config.top.color),
)
}
if (config.cornerRadius.topRight > 0) {
raylib.DrawRing(
raylib.Vector2{math.round(boundingBox.x + boundingBox.width - config.cornerRadius.topRight), math.round(boundingBox.y + config.cornerRadius.topRight)},
math.round(config.cornerRadius.topRight - cast(f32)config.top.width),
config.cornerRadius.topRight,
270,
360,
10,
clayColorToRaylibColor(config.top.color),
)
}
if (config.cornerRadius.bottomLeft > 0) {
raylib.DrawRing(
raylib.Vector2 {
math.round(boundingBox.x + config.cornerRadius.bottomLeft),
math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomLeft),
},
math.round(config.cornerRadius.bottomLeft - cast(f32)config.top.width),
config.cornerRadius.bottomLeft,
90,
180,
10,
clayColorToRaylibColor(config.bottom.color),
)
}
if (config.cornerRadius.bottomRight > 0) {
raylib.DrawRing(
raylib.Vector2 {
math.round(boundingBox.x + boundingBox.width - config.cornerRadius.bottomRight),
math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomRight),
},
math.round(config.cornerRadius.bottomRight - cast(f32)config.bottom.width),
config.cornerRadius.bottomRight,
0.1,
90,
10,
clayColorToRaylibColor(config.bottom.color),
)
}
break
}
case clay.RenderCommandType.Custom:
{
// Implement custom element rendering here
break
}
}
}
}

View File

@ -0,0 +1,54 @@
package main
import clay "clay-odin"
import "core:c"
import "core:fmt"
import "vendor:raylib"
createLayout :: proc() -> clay.ClayArray(clay.RenderCommand) {
clay.BeginLayout(1024, 768)
layoutConfig: clay.LayoutConfig = clay.LayoutConfig {
sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}},
padding = {16, 16},
}
rectangleConfig: clay.RectangleElementConfig = clay.RectangleElementConfig {
cornerRadius = {topLeft = 5},
}
if clay.Rectangle(
clay.ID("Outer Container"),
clay.Layout({sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}}, padding = {16, 16}}),
clay.RectangleConfig({cornerRadius = {topLeft = 5}}),
) {
if clay.Rectangle(clay.ID("Inner Container"), &layoutConfig, &rectangleConfig) {
if clay.Rectangle(clay.ID("percentContainer"), clay.Layout({sizing = {width = clay.SizingPercent(0.5)}}), clay.RectangleConfig({})) {}
if clay.Rectangle(clay.ID("growContainer"), clay.Layout({sizing = {width = clay.SizingGrow({max = 200})}}), clay.RectangleConfig({})) {}
clay.Text(clay.ID("textfield"), clay.MakeString("Texti"), clay.TextConfig({fontId = 0, fontSize = 24, textColor = {255, 255, 255, 255}}))
}
}
return clay.EndLayout(1024, 768)
}
main :: proc() {
minMemorySize: c.uint32_t = clay.MinMemorySize()
memory := make([^]u8, minMemorySize)
arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
clay.SetMeasureTextFunction(measureText)
clay.Initialize(arena)
raylib.InitWindow(1024, 768, "Raylib Odin Example")
raylibFonts[0] = RaylibFont {
font = raylib.LoadFontEx("resources/Roboto-Regular.ttf", 32, nil, 0),
fontId = 0,
}
raylib.SetTextureFilter(raylibFonts[0].font.texture, raylib.TextureFilter.TRILINEAR)
for !raylib.WindowShouldClose() {
renderCommands: clay.ClayArray(clay.RenderCommand) = createLayout()
raylib.BeginDrawing()
clayRaylibRender(&renderCommands)
raylib.EndDrawing()
}
}

View File

@ -1,45 +0,0 @@
package main
import clay "clay-odin"
import "core:c"
import "core:fmt"
measureText :: proc(text: [^]clay.String, config: [^]clay.TextElementConfig) -> clay.Dimensions {
return clay.Dimensions{20, 20}
}
main :: proc() {
minMemorySize: c.uint32_t = clay.MinMemorySize()
memory := make([^]u8, minMemorySize)
arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
clay.Initialize(arena)
clay.BeginLayout(1024, 768)
layoutConfig: clay.LayoutConfig = clay.LayoutConfig {
sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}},
padding = {16, 16},
}
rectangleConfig: clay.RectangleElementConfig = clay.RectangleElementConfig {
cornerRadius = {topLeft = 5},
}
if clay.Rectangle(
clay.ID("Outer Container"),
clay.Layout(
{
sizing = {
width = {type = clay.SizingType.GROW},
height = {type = clay.SizingType.GROW},
},
padding = {16, 16},
},
),
clay.RectangleConfig({cornerRadius = {topLeft = 5}}),
) {
if clay.Rectangle(clay.ID("Inner Container"), &layoutConfig, &rectangleConfig) {
}
}
renderCommands: clay.ClayArray(clay.RenderCommand) = clay.EndLayout(1024, 768)
x: int = 5
}

View File

@ -0,0 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/DanielGavin/ols/master/misc/odinfmt.schema.json",
"character_width": 180,
"sort_imports": true,
"tabs": false
}

Binary file not shown.