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

@ -157,10 +157,19 @@ SizingType :: enum u8 {
PERCENT,
}
SizingAxis :: struct {
// Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
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,
}
@ -210,224 +219,209 @@ ClayArray :: struct($type: typeid) {
internalArray: [^]type,
}
@(link_prefix = "Clay_")
foreign Clay {
Clay_MinMemorySize :: proc() -> c.uint32_t ---
Clay_CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena ---
Clay_SetPointerPosition :: proc(position: Vector2) ---
Clay_Initialize :: proc(arena: Arena) ---
Clay_UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) ---
Clay_BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) ---
Clay_EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) ---
Clay_PointerOver :: proc(id: c.uint32_t) -> c.bool ---
Clay_GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData ---
Clay_SetMeasureTextFunction :: proc(measureTextFunction: proc(text: [^]String, config: [^]TextElementConfig) -> Dimensions) ---
Clay__OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) ---
Clay__OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
Clay__OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) ---
Clay__OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
Clay__OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
Clay__OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
Clay__OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
Clay__OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
Clay__CloseElementWithChildren :: proc() ---
Clay__CloseScrollElement :: proc() ---
Clay__CloseFloatingElement :: proc() ---
Clay__layoutConfigs: ClayArray(LayoutConfig)
Clay__LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig ---
Clay__rectangleElementConfigs: ClayArray(RectangleElementConfig)
Clay__RectangleElementConfigArray_Add :: proc(array: ^ClayArray(RectangleElementConfig), config: RectangleElementConfig) -> ^RectangleElementConfig ---
Clay__textElementConfigs: ClayArray(TextElementConfig)
Clay__TextElementConfigArray_Add :: proc(array: ^ClayArray(TextElementConfig), config: TextElementConfig) -> ^TextElementConfig ---
Clay__imageElementConfigs: ClayArray(ImageElementConfig)
Clay__ImageElementConfigArray_Add :: proc(array: ^ClayArray(ImageElementConfig), config: ImageElementConfig) -> ^ImageElementConfig ---
Clay__floatingElementConfigs: ClayArray(FloatingElementConfig)
Clay__FloatingElementConfigArray_Add :: proc(array: ^ClayArray(FloatingElementConfig), config: FloatingElementConfig) -> ^FloatingElementConfig ---
Clay__customElementConfigs: ClayArray(CustomElementConfig)
Clay__CustomElementConfigArray_Add :: proc(array: ^ClayArray(CustomElementConfig), config: CustomElementConfig) -> ^CustomElementConfig ---
Clay__scrollElementConfigs: ClayArray(ScrollElementConfig)
Clay__ScrollElementConfigArray_Add :: proc(array: ^ClayArray(ScrollElementConfig), config: ScrollElementConfig) -> ^ScrollElementConfig ---
Clay__borderElementConfigs: ClayArray(BorderElementConfig)
Clay__BorderElementConfigArray_Add :: proc(array: ^ClayArray(BorderElementConfig), config: BorderElementConfig) -> ^BorderElementConfig ---
Clay__HashString :: proc(toHash: String, index: c.uint32_t) -> c.uint32_t ---
MinMemorySize :: proc() -> c.uint32_t ---
CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena ---
SetPointerPosition :: proc(position: Vector2) ---
Initialize :: proc(arena: Arena) ---
UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) ---
BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) ---
EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) ---
PointerOver :: proc(id: c.uint32_t) -> c.bool ---
GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData ---
SetMeasureTextFunction :: proc(measureTextFunction: proc(text: ^String, config: ^TextElementConfig) -> Dimensions) ---
RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: c.int32_t) -> ^RenderCommand ---
@(private)
_OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) ---
@(private)
_OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
@(private)
_OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) ---
@(private)
_OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
@(private)
_OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
@(private)
_OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
@(private)
_OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
@(private)
_OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
@(private)
_CloseElementWithChildren :: proc() ---
@(private)
_CloseScrollElement :: proc() ---
@(private)
_CloseFloatingElement :: proc() ---
@(private)
_layoutConfigs: ClayArray(LayoutConfig)
@(private)
_LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig ---
@(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 {
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)
@(require_results, deferred_none = _CloseElementWithChildren)
Container :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) -> bool {
Clay__OpenContainerElement(id, layoutConfig)
_OpenContainerElement(id, layoutConfig)
return true
}
@(deferred_none = Clay__CloseElementWithChildren)
Rectangle :: proc(
id: c.uint32_t,
layoutConfig: ^LayoutConfig,
rectangleConfig: ^RectangleElementConfig,
) -> bool {
Clay__OpenRectangleElement(id, layoutConfig, rectangleConfig)
@(require_results, deferred_none = _CloseElementWithChildren)
Rectangle :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) -> bool {
_OpenRectangleElement(id, layoutConfig, rectangleConfig)
return true
}
Text :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) -> bool {
Clay__OpenTextElement(id, text, textConfig)
_OpenTextElement(id, text, textConfig)
return true
}
@(deferred_none = Clay__CloseElementWithChildren)
Image :: proc(
id: c.uint32_t,
layoutConfig: ^LayoutConfig,
imageConfig: ^ImageElementConfig,
) -> bool {
Clay__OpenImageElement(id, layoutConfig, imageConfig)
@(require_results, deferred_none = _CloseElementWithChildren)
Image :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) -> bool {
_OpenImageElement(id, layoutConfig, imageConfig)
return true
}
@(deferred_none = Clay__CloseScrollElement)
Scroll :: proc(
id: c.uint32_t,
layoutConfig: ^LayoutConfig,
scrollConfig: ^ScrollElementConfig,
) -> bool {
Clay__OpenScrollElement(id, layoutConfig, scrollConfig)
@(require_results, deferred_none = _CloseScrollElement)
Scroll :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, scrollConfig: ^ScrollElementConfig) -> bool {
_OpenScrollElement(id, layoutConfig, scrollConfig)
return true
}
@(deferred_none = Clay__CloseFloatingElement)
Floating :: proc(
id: c.uint32_t,
layoutConfig: ^LayoutConfig,
floatingConfig: ^FloatingElementConfig,
) -> bool {
Clay__OpenFloatingElement(id, layoutConfig, floatingConfig)
@(require_results, deferred_none = _CloseFloatingElement)
Floating :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, floatingConfig: ^FloatingElementConfig) -> bool {
_OpenFloatingElement(id, layoutConfig, floatingConfig)
return true
}
@(deferred_none = Clay__CloseElementWithChildren)
Border :: proc(
id: c.uint32_t,
layoutConfig: ^LayoutConfig,
borderConfig: ^BorderElementConfig,
) -> bool {
Clay__OpenBorderElement(id, layoutConfig, borderConfig)
@(require_results, deferred_none = _CloseElementWithChildren)
Border :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, borderConfig: ^BorderElementConfig) -> bool {
_OpenBorderElement(id, layoutConfig, borderConfig)
return true
}
@(deferred_none = Clay__CloseElementWithChildren)
Custom :: proc(
id: c.uint32_t,
layoutConfig: ^LayoutConfig,
customConfig: ^CustomElementConfig,
) -> bool {
Clay__OpenCustomElement(id, layoutConfig, customConfig)
@(require_results, deferred_none = _CloseElementWithChildren)
Custom :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, customConfig: ^CustomElementConfig) -> bool {
_OpenCustomElement(id, layoutConfig, customConfig)
return true
}
Layout :: proc(config: LayoutConfig) -> ^LayoutConfig {
return Clay__LayoutConfigArray_Add(&Clay__layoutConfigs, config)
return _LayoutConfigArray_Add(&_layoutConfigs, config)
}
RectangleConfig :: proc(config: RectangleElementConfig) -> ^RectangleElementConfig {
return Clay__RectangleElementConfigArray_Add(&Clay__rectangleElementConfigs, config)
return _RectangleElementConfigArray_Add(&_rectangleElementConfigs, config)
}
TextConfig :: proc(config: TextElementConfig) -> ^TextElementConfig {
return Clay__TextElementConfigArray_Add(&Clay__textElementConfigs, config)
return _TextElementConfigArray_Add(&_textElementConfigs, config)
}
ImageConfig :: proc(config: ImageElementConfig) -> ^ImageElementConfig {
return Clay__ImageElementConfigArray_Add(&Clay__imageElementConfigs, config)
return _ImageElementConfigArray_Add(&_imageElementConfigs, config)
}
FloatingConfig :: proc(config: FloatingElementConfig) -> ^FloatingElementConfig {
return Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, config)
return _FloatingElementConfigArray_Add(&_floatingElementConfigs, config)
}
Custom_elementConfig :: proc(config: CustomElementConfig) -> ^CustomElementConfig {
return Clay__CustomElementConfigArray_Add(&Clay__customElementConfigs, config)
return _CustomElementConfigArray_Add(&_customElementConfigs, config)
}
ScrollConfig :: proc(config: ScrollElementConfig) -> ^ScrollElementConfig {
return Clay__ScrollElementConfigArray_Add(&Clay__scrollElementConfigs, config)
return _ScrollElementConfigArray_Add(&_scrollElementConfigs, config)
}
BorderConfig :: proc(config: BorderElementConfig) -> ^BorderElementConfig {
return Clay__BorderElementConfigArray_Add(&Clay__borderElementConfigs, config)
return _BorderElementConfigArray_Add(&_borderElementConfigs, config)
}
BorderConfigOutside :: proc(outsideBorders: BorderData) -> ^BorderElementConfig {
return Clay__BorderElementConfigArray_Add(
&Clay__borderElementConfigs,
(BorderElementConfig) {
left = outsideBorders,
right = outsideBorders,
top = outsideBorders,
bottom = outsideBorders,
},
return _BorderElementConfigArray_Add(
&_borderElementConfigs,
(BorderElementConfig){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
ClayString :: proc(label: string) -> String {
MakeString :: proc(label: string) -> String {
return String{chars = raw_data(label), length = cast(c.int)len(label)}
}
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 {
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.