Merge branch 'main' into main

This commit is contained in:
AICDG 2025-01-21 14:57:31 +08:00 committed by GitHub
commit e81e1ad08f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 653 additions and 236 deletions

View File

@ -3,6 +3,10 @@ project(clay)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(APPLE)
enable_language(OBJC)
endif()
add_subdirectory("examples/cpp-project-example") add_subdirectory("examples/cpp-project-example")
add_subdirectory("examples/raylib-multi-context") add_subdirectory("examples/raylib-multi-context")
add_subdirectory("examples/raylib-sidebar-scrolling-container") add_subdirectory("examples/raylib-sidebar-scrolling-container")
@ -12,6 +16,7 @@ if(NOT MSVC)
add_subdirectory("examples/introducing-clay-video-demo") add_subdirectory("examples/introducing-clay-video-demo")
add_subdirectory("examples/SDL2-video-demo") add_subdirectory("examples/SDL2-video-demo")
add_subdirectory("examples/minimal-imgui") add_subdirectory("examples/minimal-imgui")
add_subdirectory("examples/SDL3-simple-demo")
endif() endif()
add_subdirectory("examples/introducing-clay-video-demo") add_subdirectory("examples/introducing-clay-video-demo")
add_subdirectory("examples/SDL2-video-demo") add_subdirectory("examples/SDL2-video-demo")

View File

@ -94,12 +94,12 @@ Clay_RenderCommandArray CreateLayout() {
Clay_BeginLayout(); Clay_BeginLayout();
// An example of laying out a UI with a fixed width sidebar and flexible width main content // An example of laying out a UI with a fixed width sidebar and flexible width main content
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = {16, 16}, .childGap = 16 }), CLAY_RECTANGLE({ .color = {250,250,255,255} })) { CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }), CLAY_RECTANGLE({ .color = {250,250,255,255} })) {
CLAY(CLAY_ID("SideBar"), CLAY(CLAY_ID("SideBar"),
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = {16, 16}, .childGap = 16 }), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }),
CLAY_RECTANGLE({ .color = COLOR_LIGHT }) CLAY_RECTANGLE({ .color = COLOR_LIGHT })
) { ) {
CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = {16, 16}, .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER }), CLAY_RECTANGLE({ .color = COLOR_RED })) { CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {} CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {}
CLAY_TEXT(CLAY_STRING("Clay - UI Library"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255, 255, 255, 255} })); CLAY_TEXT(CLAY_STRING("Clay - UI Library"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255, 255, 255, 255} }));
} }
@ -218,7 +218,7 @@ Clay UIs are built using the C macro `CLAY()`. This macro creates a new empty el
Child elements are added by opening a block: `{}` after calling the `CLAY()` macro (exactly like you would with an `if` statement or `for` loop), and declaring child components inside the braces. Child elements are added by opening a block: `{}` after calling the `CLAY()` macro (exactly like you would with an `if` statement or `for` loop), and declaring child components inside the braces.
```C ```C
// Parent element with 8px of padding // Parent element with 8px of padding
CLAY(CLAY_LAYOUT({ .padding = 8 })) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8) })) {
// Child element 1 // Child element 1
CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 })); CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 }));
// Child element 2 with red background // Child element 2 with red background
@ -233,7 +233,7 @@ However, unlike HTML and other declarative DSLs, these macros are just C. As a r
// Re-usable "components" are just functions that declare more UI // Re-usable "components" are just functions that declare more UI
void ButtonComponent(Clay_String buttonText) { void ButtonComponent(Clay_String buttonText) {
// Red box button with 8px of padding // Red box button with 8px of padding
CLAY(CLAY_LAYOUT({ .padding = { 8, 8 }}), CLAY_RECTANGLE({ .color = COLOR_RED })) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8)}), CLAY_RECTANGLE({ .color = COLOR_RED })) {
CLAY_TEXT(buttonText, textConfig); CLAY_TEXT(buttonText, textConfig);
} }
} }
@ -259,11 +259,11 @@ CLAY(CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
### Configuring Layout and Styling UI Elements ### Configuring Layout and Styling UI Elements
The layout of clay elements is configured with the `CLAY_LAYOUT()` macro. The layout of clay elements is configured with the `CLAY_LAYOUT()` macro.
```C ```C
CLAY(CLAY_LAYOUT({ .padding = {.x = 8, .y = 8}, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// Children are 8px inset into parent, and laid out top to bottom // Children are 8px inset into parent, and laid out top to bottom
} }
``` ```
This macro isn't magic - all it's doing is wrapping the standard designated initializer syntax and adding the result to an internal array. e.g. `(Clay_LayoutConfig) { .padding = { .x = 8, .y = 8 } ...`. This macro isn't magic - all it's doing is wrapping the standard designated initializer syntax and adding the result to an internal array. e.g. `(Clay_LayoutConfig) { .padding = { .left = 8, .right = 8 } ...`.
See the [Clay_LayoutConfig](#clay_layout) API for the full list of options. See the [Clay_LayoutConfig](#clay_layout) API for the full list of options.
@ -333,7 +333,7 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerI
ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" }; ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };
// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries // HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
CLAY(CLAY_LAYOUT({ .padding = { 8, 8 }}), Clay_OnHover(HandleButtonInteraction, &linkButton)) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8)}), Clay_OnHover(HandleButtonInteraction, &linkButton)) {
CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig); CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig);
} }
``` ```
@ -703,7 +703,7 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerD
ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" }; ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };
// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries // HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
CLAY(CLAY_LAYOUT({ .padding = { 8, 8 }}), Clay_OnHover(HandleButtonInteraction, &buttonData)) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8)}), Clay_OnHover(HandleButtonInteraction, &buttonData)) {
CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig); CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig);
} }
``` ```
@ -749,7 +749,7 @@ Returns a [Clay_ElementId](#clay_elementid) for the provided id string, used for
**Examples** **Examples**
```C ```C
// Define an element with 16px of x and y padding // Define an element with 16px of x and y padding
CLAY(CLAY_ID("Outer"), CLAY_LAYOUT({ .padding = {16, 16} })) { CLAY(CLAY_ID("Outer"), CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16) })) {
// A nested child element // A nested child element
CLAY(CLAY_ID("SideBar"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 })) { CLAY(CLAY_ID("SideBar"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 })) {
// Children laid out top to bottom with a 16 px gap between them // Children laid out top to bottom with a 16 px gap between them
@ -789,7 +789,7 @@ To regenerate the same ID outside of layout declaration when using utility funct
// Tag a button with the Id "Button" // Tag a button with the Id "Button"
CLAY( CLAY(
CLAY_ID("Button"), CLAY_ID("Button"),
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = {16, 16}, .childGap = 16) }) CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16) })
) { ) {
// ...children // ...children
} }
@ -832,7 +832,7 @@ An offset version of [CLAY_ID](#clay_id). Generates a [Clay_ElementId](#clay_ele
Clay_LayoutConfig { Clay_LayoutConfig {
Clay_LayoutDirection layoutDirection = CLAY_LEFT_TO_RIGHT (default) | CLAY_TOP_TO_BOTTOM; Clay_LayoutDirection layoutDirection = CLAY_LEFT_TO_RIGHT (default) | CLAY_TOP_TO_BOTTOM;
Clay_Padding padding { Clay_Padding padding {
float x; float y; u16 left; u16 right; u16 top; u16 bottom;
}; };
uint16_t childGap; uint16_t childGap;
Clay_ChildAlignment childAlignment { Clay_ChildAlignment childAlignment {
@ -863,11 +863,11 @@ _Did you know that "left to right" and "top to bottom" both have 13 letters?_
**`.padding`** - `Clay_Padding` **`.padding`** - `Clay_Padding`
`CLAY_LAYOUT({ .padding = { .x = 16, .y = 16 } })` `CLAY_LAYOUT({ .padding = { .left = 16, .right = 16, .top = 8, .bottom = 8 } })`
Controls horizontal and vertical white-space "padding" around the **outside** of child elements. Controls white-space "padding" around the **outside** of child elements.
<img width="486" alt="Screenshot 2024-08-22 at 10 50 49 AM" src="https://github.com/user-attachments/assets/9311cf10-b8aa-40fe-922a-5dee3663f1a0"> <img width="486" alt="Screenshot 2024-08-22 at 10 50 49 AM" src="https://github.com/user-attachments/assets/b454fa36-92d5-4b1d-bf8b-e4c25428e9de">
--- ---
@ -917,7 +917,7 @@ Controls how final width and height of element are calculated. The same configur
**Example Usage** **Example Usage**
```C ```C
CLAY(CLAY_ID("Button"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = {16, 16}, .childGap = 16) }) { CLAY(CLAY_ID("Button"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16) }) {
// Children will be laid out vertically with 16px of padding around and between // Children will be laid out vertically with 16px of padding around and between
} }
``` ```
@ -1586,17 +1586,17 @@ Controls whether pointer events like hover and click should pass through to cont
```C ```C
// Horizontal container with three option buttons // Horizontal container with three option buttons
CLAY(CLAY_ID("OptionsList"), CLAY_LAYOUT(.childGap = 16)) { CLAY(CLAY_ID("OptionsList"), CLAY_LAYOUT(.childGap = 16)) {
CLAY_RECTANGLE(CLAY_IDI("Option", 1), CLAY_LAYOUT(.padding = {16, 16}), CLAY_RECTANGLE(.color = COLOR_BLUE)) { CLAY_RECTANGLE(CLAY_IDI("Option", 1), CLAY_LAYOUT(.padding = CLAY_PADDING_ALL(16)), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
CLAY_TEXT(CLAY_IDI("OptionText", 1), CLAY_STRING("Option 1"), CLAY_TEXT_CONFIG()); CLAY_TEXT(CLAY_IDI("OptionText", 1), CLAY_STRING("Option 1"), CLAY_TEXT_CONFIG());
} }
CLAY_RECTANGLE(CLAY_IDI("Option", 2), CLAY_LAYOUT(.padding = {16, 16}), CLAY_RECTANGLE(.color = COLOR_BLUE)) { CLAY_RECTANGLE(CLAY_IDI("Option", 2), CLAY_LAYOUT(.padding = CLAY_PADDING_ALL(16)), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
CLAY_TEXT(CLAY_IDI("OptionText", 2), CLAY_STRING("Option 2"), CLAY_TEXT_CONFIG()); CLAY_TEXT(CLAY_IDI("OptionText", 2), CLAY_STRING("Option 2"), CLAY_TEXT_CONFIG());
// Floating tooltip will attach above the "Option 2" container and not affect widths or positions of other elements // Floating tooltip will attach above the "Option 2" container and not affect widths or positions of other elements
CLAY_FLOATING(CLAY_ID("OptionTooltip"), &CLAY_LAYOUT_DEFAULT, CLAY_FLOATING({ .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_TOP } })) { CLAY_FLOATING(CLAY_ID("OptionTooltip"), &CLAY_LAYOUT_DEFAULT, CLAY_FLOATING({ .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_TOP } })) {
CLAY_TEXT(CLAY_IDI("OptionTooltipText", 1), CLAY_STRING("Most popular!"), CLAY_TEXT_CONFIG()); CLAY_TEXT(CLAY_IDI("OptionTooltipText", 1), CLAY_STRING("Most popular!"), CLAY_TEXT_CONFIG());
} }
} }
CLAY_RECTANGLE(CLAY_IDI("Option", 3), CLAY_LAYOUT(.padding = {16, 16}), CLAY_RECTANGLE(.color = COLOR_BLUE)) { CLAY_RECTANGLE(CLAY_IDI("Option", 3), CLAY_LAYOUT(.padding = CLAY_PADDING_ALL(16)), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
CLAY_TEXT(CLAY_IDI("OptionText", 3), CLAY_STRING("Option 3"), CLAY_TEXT_CONFIG()); CLAY_TEXT(CLAY_IDI("OptionText", 3), CLAY_STRING("Option 3"), CLAY_TEXT_CONFIG());
} }
} }

View File

@ -2,7 +2,7 @@ cp ../../clay.h clay.c;
# Intel Mac # Intel Mac
clang -c -DCLAY_IMPLEMENTATION -o clay.o -static -target x86_64-apple-darwin clay.c -fPIC && ar r clay-odin/macos/clay.a clay.o; clang -c -DCLAY_IMPLEMENTATION -o clay.o -static -target x86_64-apple-darwin clay.c -fPIC && ar r clay-odin/macos/clay.a clay.o;
# ARM Mac # ARM Mac
clang -c -DCLAY_IMPLEMENTATION -o clay.o -static clay.c -fPIC && ar r clay-odin/macos-arm64/clay.a clay.o; clang -c -DCLAY_IMPLEMENTATION -g -o clay.o -static clay.c -fPIC && ar r clay-odin/macos-arm64/clay.a clay.o;
# x64 Windows # x64 Windows
clang -c -DCLAY_IMPLEMENTATION -o clay-odin/windows/clay.lib -target x86_64-pc-windows-msvc -fuse-ld=llvm-lib -static clay.c; clang -c -DCLAY_IMPLEMENTATION -o clay-odin/windows/clay.lib -target x86_64-pc-windows-msvc -fuse-ld=llvm-lib -static clay.c;
# Linux # Linux

View File

@ -22,6 +22,12 @@ String :: struct {
chars: [^]c.char, chars: [^]c.char,
} }
StringSlice :: struct {
length: c.int32_t,
chars: [^]c.char,
baseChars: [^]c.char,
}
Vector2 :: [2]c.float Vector2 :: [2]c.float
Dimensions :: struct { Dimensions :: struct {
@ -223,8 +229,10 @@ Sizing :: struct {
} }
Padding :: struct { Padding :: struct {
x: u16, left: u16,
y: u16, right: u16,
top: u16,
bottom: u16,
} }
LayoutDirection :: enum EnumBackingType { LayoutDirection :: enum EnumBackingType {
@ -303,7 +311,7 @@ foreign Clay {
PointerOver :: proc(id: ElementId) -> bool --- PointerOver :: proc(id: ElementId) -> bool ---
GetElementId :: proc(id: String) -> ElementId --- GetElementId :: proc(id: String) -> ElementId ---
GetScrollContainerData :: proc(id: ElementId) -> ScrollContainerData --- GetScrollContainerData :: proc(id: ElementId) -> ScrollContainerData ---
SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: ^String, config: ^TextElementConfig) -> Dimensions) --- SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: StringSlice, config: ^TextElementConfig, userData: uintptr) -> Dimensions, userData: uintptr) ---
RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: i32) -> ^RenderCommand --- RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: i32) -> ^RenderCommand ---
SetDebugModeEnabled :: proc(enabled: bool) --- SetDebugModeEnabled :: proc(enabled: bool) ---
} }
@ -350,6 +358,10 @@ Layout :: proc(config: LayoutConfig) -> TypedConfig {
return {type = ElementConfigType.Layout, config = _StoreLayoutConfig(config) } return {type = ElementConfigType.Layout, config = _StoreLayoutConfig(config) }
} }
PaddingAll :: proc (padding: u16) -> Padding {
return { padding, padding, padding, padding }
}
Rectangle :: proc(config: RectangleElementConfig) -> TypedConfig { Rectangle :: proc(config: RectangleElementConfig) -> TypedConfig {
return {type = ElementConfigType.Rectangle, config = _StoreRectangleElementConfig(config)} return {type = ElementConfigType.Rectangle, config = _StoreRectangleElementConfig(config)}
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -60,7 +60,7 @@ headerTextConfig := clay.TextElementConfig {
LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Color, text: string, image: ^raylib.Texture2D) { LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Color, text: string, image: ^raylib.Texture2D) {
if clay.UI( if clay.UI(
clay.ID("HeroBlob", index), clay.ID("HeroBlob", index),
clay.Layout({sizing = {width = clay.SizingGrow({max = 480})}, padding = clay.Padding{16, 16}, childGap = 16, childAlignment = clay.ChildAlignment{y = .CENTER}}), clay.Layout({sizing = {width = clay.SizingGrow({max = 480})}, padding = clay.PaddingAll(16), childGap = 16, childAlignment = clay.ChildAlignment{y = .CENTER}}),
clay.BorderOutsideRadius({2, color}, 10), clay.BorderOutsideRadius({2, color}, 10),
) { ) {
if clay.UI( if clay.UI(
@ -75,11 +75,11 @@ LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Colo
LandingPageDesktop :: proc() { LandingPageDesktop :: proc() {
if clay.UI( if clay.UI(
clay.ID("LandingPage1Desktop"), clay.ID("LandingPage1Desktop"),
clay.Layout({sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})}, childAlignment = {y = .CENTER}, padding = {x = 50}}), clay.Layout({sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})}, childAlignment = {y = .CENTER}, padding = {left = 50, right = 50}}),
) { ) {
if clay.UI( if clay.UI(
clay.ID("LandingPage1"), clay.ID("LandingPage1"),
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {32, 32}, childGap = 32}), clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(32), childGap = 32}),
clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}), clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}),
) { ) {
if clay.UI(clay.ID("LeftText"), clay.Layout({sizing = {width = clay.SizingPercent(0.55)}, layoutDirection = .TOP_TO_BOTTOM, childGap = 8})) { if clay.UI(clay.ID("LeftText"), clay.Layout({sizing = {width = clay.SizingPercent(0.55)}, layoutDirection = .TOP_TO_BOTTOM, childGap = 8})) {
@ -115,7 +115,7 @@ LandingPageMobile :: proc() {
layoutDirection = .TOP_TO_BOTTOM, layoutDirection = .TOP_TO_BOTTOM,
sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})}, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})},
childAlignment = {x = .CENTER, y = .CENTER}, childAlignment = {x = .CENTER, y = .CENTER},
padding = {16, 32}, padding = {16, 16, 32, 32},
childGap = 32, childGap = 32,
}, },
), ),
@ -148,9 +148,9 @@ FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) {
textConfig := clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_RED}) textConfig := clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_RED})
if clay.UI( if clay.UI(
clay.ID("HFileBoxOuter"), clay.ID("HFileBoxOuter"),
clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {outerPadding, 32}, childGap = 8}), clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {outerPadding, outerPadding, 32, 32}, childGap = 8}),
) { ) {
if clay.UI(clay.ID("HFileIncludeOuter"), clay.Layout({padding = {8, 4}}), clay.Rectangle({color = COLOR_RED, cornerRadius = clay.CornerRadiusAll(8)})) { if clay.UI(clay.ID("HFileIncludeOuter"), clay.Layout({padding = {8, 8, 4, 4}}), clay.Rectangle({color = COLOR_RED, cornerRadius = clay.CornerRadiusAll(8)})) {
clay.Text("#include clay.h", clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_LIGHT})) clay.Text("#include clay.h", clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_LIGHT}))
} }
clay.Text("~2000 lines of C99.", textConfig) clay.Text("~2000 lines of C99.", textConfig)
@ -158,7 +158,7 @@ FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) {
} }
if clay.UI( if clay.UI(
clay.ID("BringYourOwnRendererOuter"), clay.ID("BringYourOwnRendererOuter"),
clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {x = outerPadding, y = 32}, childGap = 8}), clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {outerPadding, outerPadding, 32, 32}, childGap = 8}),
) { ) {
clay.Text("Renderer agnostic.", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = COLOR_ORANGE})) clay.Text("Renderer agnostic.", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = COLOR_ORANGE}))
clay.Text("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML.", textConfig) clay.Text("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML.", textConfig)
@ -217,11 +217,11 @@ DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizi
DeclarativeSyntaxPageDesktop :: proc() { DeclarativeSyntaxPageDesktop :: proc() {
if clay.UI( if clay.UI(
clay.ID("SyntaxPageDesktop"), clay.ID("SyntaxPageDesktop"),
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {x = 50}}), clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {left = 50, right = 50}}),
) { ) {
if clay.UI( if clay.UI(
clay.ID("SyntaxPage"), clay.ID("SyntaxPage"),
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {32, 32}, childGap = 32}), clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(32), childGap = 32}),
clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}), clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}),
) { ) {
DeclarativeSyntaxPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5)) DeclarativeSyntaxPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5))
@ -237,7 +237,7 @@ DeclarativeSyntaxPageMobile :: proc() {
layoutDirection = .TOP_TO_BOTTOM, layoutDirection = .TOP_TO_BOTTOM,
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
childAlignment = {x = .CENTER, y = .CENTER}, childAlignment = {x = .CENTER, y = .CENTER},
padding = {16, 32}, padding = {16, 16, 32, 32},
childGap = 16, childGap = 16,
}, },
), ),
@ -277,14 +277,14 @@ HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementCon
) { ) {
if clay.UI( if clay.UI(
clay.ID("AnimationDemoContainerLeft"), clay.ID("AnimationDemoContainerLeft"),
clay.Layout({sizing = {clay.SizingPercent(0.35 + 0.3 * lerpValue), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {16, 16}}), clay.Layout({sizing = {clay.SizingPercent(0.35 + 0.3 * lerpValue), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(16)}),
clay.Rectangle({color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue)}), clay.Rectangle({color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue)}),
) { ) {
clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT})) clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT}))
} }
if clay.UI( if clay.UI(
clay.ID("AnimationDemoContainerRight"), clay.ID("AnimationDemoContainerRight"),
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {16, 16}}), clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(16)}),
clay.Rectangle({color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue)}), clay.Rectangle({color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue)}),
) { ) {
clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT})) clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT}))
@ -297,7 +297,7 @@ HighPerformancePageDesktop :: proc(lerpValue: f32) {
if clay.UI( if clay.UI(
clay.ID("PerformanceDesktop"), clay.ID("PerformanceDesktop"),
clay.Layout( clay.Layout(
{sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {x = 82, y = 32}, childGap = 64}, {sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {82, 82, 32, 32}, childGap = 64},
), ),
clay.Rectangle({color = COLOR_RED}), clay.Rectangle({color = COLOR_RED}),
) { ) {
@ -313,7 +313,7 @@ HighPerformancePageMobile :: proc(lerpValue: f32) {
layoutDirection = .TOP_TO_BOTTOM, layoutDirection = .TOP_TO_BOTTOM,
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
childAlignment = {x = .CENTER, y = .CENTER}, childAlignment = {x = .CENTER, y = .CENTER},
padding = {x = 16, y = 32}, padding = { 16, 16, 32, 32},
childGap = 32, childGap = 32,
}, },
), ),
@ -325,7 +325,7 @@ HighPerformancePageMobile :: proc(lerpValue: f32) {
RendererButtonActive :: proc(index: i32, text: string) { RendererButtonActive :: proc(index: i32, text: string) {
if clay.UI( if clay.UI(
clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = {16, 16}}), clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = clay.PaddingAll(16)}),
clay.Rectangle({color = COLOR_RED, cornerRadius = clay.CornerRadiusAll(10)}), clay.Rectangle({color = COLOR_RED, cornerRadius = clay.CornerRadiusAll(10)}),
) { ) {
clay.Text(text, clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_LIGHT})) clay.Text(text, clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_LIGHT}))
@ -336,7 +336,7 @@ RendererButtonInactive :: proc(index: u32, text: string) {
if clay.UI(clay.Layout({}), clay.BorderOutsideRadius({2, COLOR_RED}, 10)) { if clay.UI(clay.Layout({}), clay.BorderOutsideRadius({2, COLOR_RED}, 10)) {
if clay.UI( if clay.UI(
clay.ID("RendererButtonInactiveInner", index), clay.ID("RendererButtonInactiveInner", index),
clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = {16, 16}}), clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = clay.PaddingAll(16)}),
clay.Rectangle({color = COLOR_LIGHT, cornerRadius = clay.CornerRadiusAll(10)}), clay.Rectangle({color = COLOR_LIGHT, cornerRadius = clay.CornerRadiusAll(10)}),
) { ) {
clay.Text(text, clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_RED})) clay.Text(text, clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_RED}))
@ -374,11 +374,11 @@ RendererPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.
RendererPageDesktop :: proc() { RendererPageDesktop :: proc() {
if clay.UI( if clay.UI(
clay.ID("RendererPageDesktop"), clay.ID("RendererPageDesktop"),
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {x = 50}}), clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {left = 50, right = 50}}),
) { ) {
if clay.UI( if clay.UI(
clay.ID("RendererPage"), clay.ID("RendererPage"),
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {32, 32}, childGap = 32}), clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(32), childGap = 32}),
clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}), clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}),
) { ) {
RendererPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5)) RendererPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5))
@ -394,7 +394,7 @@ RendererPageMobile :: proc() {
layoutDirection = .TOP_TO_BOTTOM, layoutDirection = .TOP_TO_BOTTOM,
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
childAlignment = {x = .CENTER, y = .CENTER}, childAlignment = {x = .CENTER, y = .CENTER},
padding = {x = 16, y = 32}, padding = {16, 16, 32, 32},
childGap = 32, childGap = 32,
}, },
), ),
@ -423,7 +423,7 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
) { ) {
if clay.UI( if clay.UI(
clay.ID("Header"), clay.ID("Header"),
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFixed(50)}, childAlignment = {y = .CENTER}, childGap = 24, padding = {x = 32}}), clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFixed(50)}, childAlignment = {y = .CENTER}, childGap = 24, padding = {left = 32, right = 32}}),
) { ) {
clay.Text("Clay", &headerTextConfig) clay.Text("Clay", &headerTextConfig)
if clay.UI(clay.Layout({sizing = {width = clay.SizingGrow({})}})) {} if clay.UI(clay.Layout({sizing = {width = clay.SizingGrow({})}})) {}
@ -438,7 +438,7 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
} }
if clay.UI( if clay.UI(
clay.ID("LinkGithubOuter"), clay.ID("LinkGithubOuter"),
clay.Layout({padding = {16, 6}}), clay.Layout({padding = {16, 16, 6, 6}}),
clay.BorderOutsideRadius({2, COLOR_RED}, 10), clay.BorderOutsideRadius({2, COLOR_RED}, 10),
clay.Rectangle({cornerRadius = clay.CornerRadiusAll(10), color = clay.PointerOver(clay.GetElementId(clay.MakeString("LinkGithubOuter"))) ? COLOR_LIGHT_HOVER : COLOR_LIGHT}) clay.Rectangle({cornerRadius = clay.CornerRadiusAll(10), color = clay.PointerOver(clay.GetElementId(clay.MakeString("LinkGithubOuter"))) ? COLOR_LIGHT_HOVER : COLOR_LIGHT})
) { ) {
@ -493,8 +493,8 @@ main :: proc() {
minMemorySize: u32 = clay.MinMemorySize() minMemorySize: u32 = clay.MinMemorySize()
memory := make([^]u8, minMemorySize) memory := make([^]u8, minMemorySize)
arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory) arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
clay.SetMeasureTextFunction(measureText)
clay.Initialize(arena, {cast(f32)raylib.GetScreenWidth(), cast(f32)raylib.GetScreenHeight()}, { handler = errorHandler }) clay.Initialize(arena, {cast(f32)raylib.GetScreenWidth(), cast(f32)raylib.GetScreenHeight()}, { handler = errorHandler })
clay.SetMeasureTextFunction(measureText, 0)
raylib.SetConfigFlags({.VSYNC_HINT, .WINDOW_RESIZABLE, .WINDOW_HIGHDPI, .MSAA_4X_HINT}) raylib.SetConfigFlags({.VSYNC_HINT, .WINDOW_RESIZABLE, .WINDOW_HIGHDPI, .MSAA_4X_HINT})
raylib.InitWindow(windowWidth, windowHeight, "Raylib Odin Example") raylib.InitWindow(windowWidth, windowHeight, "Raylib Odin Example")

View File

@ -16,7 +16,7 @@ clayColorToRaylibColor :: proc(color: clay.Color) -> raylib.Color {
raylibFonts := [10]RaylibFont{} raylibFonts := [10]RaylibFont{}
measureText :: proc "c" (text: ^clay.String, config: ^clay.TextElementConfig) -> clay.Dimensions { measureText :: proc "c" (text: clay.StringSlice, config: ^clay.TextElementConfig, userData: uintptr) -> clay.Dimensions {
// Measure string size for Font // Measure string size for Font
textSize: clay.Dimensions = {0, 0} textSize: clay.Dimensions = {0, 0}

2
bindings/zig/README Normal file
View File

@ -0,0 +1,2 @@
https://codeberg.org/Zettexe/clay-zig
https://github.com/johan0A/clay-zig-bindings

212
clay.h
View File

@ -1,4 +1,4 @@
// VERSION: 0.11 // VERSION: 0.12
/* /*
NOTE: In order to use this library you must define NOTE: In order to use this library you must define
@ -70,6 +70,8 @@
#define CLAY_CORNER_RADIUS(radius) (CLAY__INIT(Clay_CornerRadius) { radius, radius, radius, radius }) #define CLAY_CORNER_RADIUS(radius) (CLAY__INIT(Clay_CornerRadius) { radius, radius, radius, radius })
#define CLAY_PADDING_ALL(padding) CLAY__CONFIG_WRAPPER(Clay_Padding, { padding, padding, padding, padding })
#define CLAY_SIZING_FIT(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_FIT }) #define CLAY_SIZING_FIT(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_FIT })
#define CLAY_SIZING_GROW(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_GROW }) #define CLAY_SIZING_GROW(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_GROW })
@ -189,6 +191,13 @@ CLAY__TYPEDEF(Clay__StringArray, struct {
Clay_String *internalArray; Clay_String *internalArray;
}); });
CLAY__TYPEDEF(Clay_StringSlice, struct {
int32_t length;
const char *chars;
// The source string / char* that this slice was derived from
const char *baseChars;
});
typedef struct Clay_Context Clay_Context; typedef struct Clay_Context Clay_Context;
CLAY__TYPEDEF(Clay_Arena, struct { CLAY__TYPEDEF(Clay_Arena, struct {
@ -289,8 +298,10 @@ CLAY__TYPEDEF(Clay_Sizing, struct {
}); });
CLAY__TYPEDEF(Clay_Padding, struct { CLAY__TYPEDEF(Clay_Padding, struct {
uint16_t x; uint16_t left;
uint16_t y; uint16_t right;
uint16_t top;
uint16_t bottom;
}); });
CLAY__TYPEDEF(Clay_LayoutConfig, struct { CLAY__TYPEDEF(Clay_LayoutConfig, struct {
@ -439,6 +450,13 @@ CLAY__TYPEDEF(Clay_ScrollContainerData, struct {
bool found; bool found;
}); });
CLAY__TYPEDEF(Clay_ElementData, struct
{
Clay_BoundingBox boundingBox;
// Indicates whether an actual Element matched the provided ID or if the default struct was returned.
bool found;
});
CLAY__TYPEDEF(Clay_RenderCommandType, CLAY_PACKED_ENUM { CLAY__TYPEDEF(Clay_RenderCommandType, CLAY_PACKED_ENUM {
CLAY_RENDER_COMMAND_TYPE_NONE, CLAY_RENDER_COMMAND_TYPE_NONE,
CLAY_RENDER_COMMAND_TYPE_RECTANGLE, CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
@ -511,12 +529,13 @@ void Clay_BeginLayout(void);
Clay_RenderCommandArray Clay_EndLayout(void); Clay_RenderCommandArray Clay_EndLayout(void);
Clay_ElementId Clay_GetElementId(Clay_String idString); Clay_ElementId Clay_GetElementId(Clay_String idString);
Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index); Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index);
Clay_ElementData Clay_GetElementData (Clay_ElementId id);
bool Clay_Hovered(void); bool Clay_Hovered(void);
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData), intptr_t userData); void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData), intptr_t userData);
bool Clay_PointerOver(Clay_ElementId elementId); bool Clay_PointerOver(Clay_ElementId elementId);
Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id); Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id);
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config)); void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData), uintptr_t userData);
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId)); void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId, uintptr_t userData), uintptr_t userData);
Clay_RenderCommand * Clay_RenderCommandArray_Get(Clay_RenderCommandArray* array, int32_t index); Clay_RenderCommand * Clay_RenderCommandArray_Get(Clay_RenderCommandArray* array, int32_t index);
void Clay_SetDebugModeEnabled(bool enabled); void Clay_SetDebugModeEnabled(bool enabled);
bool Clay_IsDebugModeEnabled(void); bool Clay_IsDebugModeEnabled(void);
@ -584,6 +603,7 @@ CLAY__TYPEDEF(Clay_BooleanWarnings, struct {
bool maxElementsExceeded; bool maxElementsExceeded;
bool maxRenderCommandsExceeded; bool maxRenderCommandsExceeded;
bool maxTextMeasureCacheExceeded; bool maxTextMeasureCacheExceeded;
bool textMeasurementFunctionNotSet;
}); });
CLAY__TYPEDEF(Clay__Warning, struct { CLAY__TYPEDEF(Clay__Warning, struct {
@ -1394,6 +1414,8 @@ struct Clay_Context {
uint32_t debugSelectedElementId; uint32_t debugSelectedElementId;
uint32_t generation; uint32_t generation;
uintptr_t arenaResetOffset; uintptr_t arenaResetOffset;
uintptr_t mesureTextUserData;
uintptr_t queryScrollOffsetUserData;
Clay_Arena internalArena; Clay_Arena internalArena;
// Layout Elements / Render Commands // Layout Elements / Render Commands
Clay_LayoutElementArray layoutElements; Clay_LayoutElementArray layoutElements;
@ -1467,11 +1489,11 @@ Clay_String Clay__WriteStringToCharBuffer(Clay__CharArray *buffer, Clay_String s
} }
#ifdef CLAY_WASM #ifdef CLAY_WASM
__attribute__((import_module("clay"), import_name("measureTextFunction"))) Clay_Dimensions Clay__MeasureText(Clay_String *text, Clay_TextElementConfig *config); __attribute__((import_module("clay"), import_name("measureTextFunction"))) Clay_Dimensions Clay__MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData);
__attribute__((import_module("clay"), import_name("queryScrollOffsetFunction"))) Clay_Vector2 Clay__QueryScrollOffset(uint32_t elementId); __attribute__((import_module("clay"), import_name("queryScrollOffsetFunction"))) Clay_Vector2 Clay__QueryScrollOffset(uint32_t elementId, uintptr_t userData);
#else #else
Clay_Dimensions (*Clay__MeasureText)(Clay_String *text, Clay_TextElementConfig *config); Clay_Dimensions (*Clay__MeasureText)(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData);
Clay_Vector2 (*Clay__QueryScrollOffset)(uint32_t elementId); Clay_Vector2 (*Clay__QueryScrollOffset)(uint32_t elementId, uintptr_t userData);
#endif #endif
Clay_LayoutElement* Clay__GetOpenLayoutElement(void) { Clay_LayoutElement* Clay__GetOpenLayoutElement(void) {
@ -1612,11 +1634,14 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
Clay_Context* context = Clay_GetCurrentContext(); Clay_Context* context = Clay_GetCurrentContext();
#ifndef CLAY_WASM #ifndef CLAY_WASM
if (!Clay__MeasureText) { if (!Clay__MeasureText) {
context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) { if (!context->booleanWarnings.textMeasurementFunctionNotSet) {
.errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED, context->booleanWarnings.textMeasurementFunctionNotSet = true;
.errorText = CLAY_STRING("Clay's internal MeasureText function is null. You may have forgotten to call Clay_SetMeasureTextFunction(), or passed a NULL function pointer by mistake."), context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
.userData = context->errorHandler.userData }); .errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
return NULL; .errorText = CLAY_STRING("Clay's internal MeasureText function is null. You may have forgotten to call Clay_SetMeasureTextFunction(), or passed a NULL function pointer by mistake."),
.userData = context->errorHandler.userData });
}
return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
} }
#endif #endif
uint32_t id = Clay__HashTextWithConfig(text, config); uint32_t id = Clay__HashTextWithConfig(text, config);
@ -1683,7 +1708,7 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
float lineWidth = 0; float lineWidth = 0;
float measuredWidth = 0; float measuredWidth = 0;
float measuredHeight = 0; float measuredHeight = 0;
float spaceWidth = Clay__MeasureText(&CLAY__SPACECHAR, config).width; float spaceWidth = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = 1, .chars = CLAY__SPACECHAR.chars, .baseChars = CLAY__SPACECHAR.chars }, config, context->mesureTextUserData).width;
Clay__MeasuredWord tempWord = { .next = -1 }; Clay__MeasuredWord tempWord = { .next = -1 };
Clay__MeasuredWord *previousWord = &tempWord; Clay__MeasuredWord *previousWord = &tempWord;
while (end < text->length) { while (end < text->length) {
@ -1700,8 +1725,7 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
char current = text->chars[end]; char current = text->chars[end];
if (current == ' ' || current == '\n') { if (current == ' ' || current == '\n') {
int32_t length = end - start; int32_t length = end - start;
Clay_String word = { .length = length, .chars = &text->chars[start] }; Clay_Dimensions dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = length, .chars = &text->chars[start], .baseChars = text->chars }, config, context->mesureTextUserData);
Clay_Dimensions dimensions = Clay__MeasureText(&word, config);
measuredHeight = CLAY__MAX(measuredHeight, dimensions.height); measuredHeight = CLAY__MAX(measuredHeight, dimensions.height);
if (current == ' ') { if (current == ' ') {
dimensions.width += spaceWidth; dimensions.width += spaceWidth;
@ -1723,8 +1747,7 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
end++; end++;
} }
if (end - start > 0) { if (end - start > 0) {
Clay_String lastWord = { .length = end - start, .chars = &text->chars[start] }; Clay_Dimensions dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = end - start, .chars = &text->chars[start], .baseChars = text->chars }, config, context->mesureTextUserData);
Clay_Dimensions dimensions = Clay__MeasureText(&lastWord, config);
Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = end - start, .width = dimensions.width, .next = -1 }, previousWord); Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = end - start, .width = dimensions.width, .next = -1 }, previousWord);
lineWidth += dimensions.width; lineWidth += dimensions.width;
measuredHeight = CLAY__MAX(measuredHeight, dimensions.height); measuredHeight = CLAY__MAX(measuredHeight, dimensions.height);
@ -1886,7 +1909,7 @@ void Clay__ElementPostConfiguration(void) {
scrollOffset = Clay__ScrollContainerDataInternalArray_Add(&context->scrollContainerDatas, CLAY__INIT(Clay__ScrollContainerDataInternal){.layoutElement = openLayoutElement, .scrollOrigin = {-1,-1}, .elementId = openLayoutElement->id, .openThisFrame = true}); scrollOffset = Clay__ScrollContainerDataInternalArray_Add(&context->scrollContainerDatas, CLAY__INIT(Clay__ScrollContainerDataInternal){.layoutElement = openLayoutElement, .scrollOrigin = {-1,-1}, .elementId = openLayoutElement->id, .openThisFrame = true});
} }
if (context->externalScrollHandlingEnabled) { if (context->externalScrollHandlingEnabled) {
scrollOffset->scrollPosition = Clay__QueryScrollOffset(scrollOffset->elementId); scrollOffset->scrollPosition = Clay__QueryScrollOffset(scrollOffset->elementId, context->queryScrollOffsetUserData);
} }
break; break;
} }
@ -1921,18 +1944,18 @@ void Clay__CloseElement(void) {
// Attach children to the current open element // Attach children to the current open element
openLayoutElement->childrenOrTextContent.children.elements = &context->layoutElementChildren.internalArray[context->layoutElementChildren.length]; openLayoutElement->childrenOrTextContent.children.elements = &context->layoutElementChildren.internalArray[context->layoutElementChildren.length];
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) { if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
openLayoutElement->dimensions.width = (float)layoutConfig->padding.x * 2; openLayoutElement->dimensions.width = (float)(layoutConfig->padding.left + layoutConfig->padding.right);
for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) { for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) {
int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i); int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex); Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
openLayoutElement->dimensions.width += child->dimensions.width; openLayoutElement->dimensions.width += child->dimensions.width;
openLayoutElement->dimensions.height = CLAY__MAX(openLayoutElement->dimensions.height, child->dimensions.height + layoutConfig->padding.y * 2); openLayoutElement->dimensions.height = CLAY__MAX(openLayoutElement->dimensions.height, child->dimensions.height + layoutConfig->padding.top + layoutConfig->padding.bottom);
// Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents // Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
if (!elementHasScrollHorizontal) { if (!elementHasScrollHorizontal) {
openLayoutElement->minDimensions.width += child->minDimensions.width; openLayoutElement->minDimensions.width += child->minDimensions.width;
} }
if (!elementHasScrollVertical) { if (!elementHasScrollVertical) {
openLayoutElement->minDimensions.height = CLAY__MAX(openLayoutElement->minDimensions.height, child->minDimensions.height + layoutConfig->padding.y * 2); openLayoutElement->minDimensions.height = CLAY__MAX(openLayoutElement->minDimensions.height, child->minDimensions.height + layoutConfig->padding.top + layoutConfig->padding.bottom);
} }
Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex); Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
} }
@ -1941,18 +1964,18 @@ void Clay__CloseElement(void) {
openLayoutElement->minDimensions.width += childGap; openLayoutElement->minDimensions.width += childGap;
} }
else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) { else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
openLayoutElement->dimensions.height = (float)layoutConfig->padding.y * 2; openLayoutElement->dimensions.height = (float)(layoutConfig->padding.top + layoutConfig->padding.bottom);
for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) { for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) {
int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i); int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex); Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
openLayoutElement->dimensions.height += child->dimensions.height; openLayoutElement->dimensions.height += child->dimensions.height;
openLayoutElement->dimensions.width = CLAY__MAX(openLayoutElement->dimensions.width, child->dimensions.width + layoutConfig->padding.x * 2); openLayoutElement->dimensions.width = CLAY__MAX(openLayoutElement->dimensions.width, child->dimensions.width + layoutConfig->padding.left + layoutConfig->padding.right);
// Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents // Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
if (!elementHasScrollVertical) { if (!elementHasScrollVertical) {
openLayoutElement->minDimensions.height += child->minDimensions.height; openLayoutElement->minDimensions.height += child->minDimensions.height;
} }
if (!elementHasScrollHorizontal) { if (!elementHasScrollHorizontal) {
openLayoutElement->minDimensions.width = CLAY__MAX(openLayoutElement->minDimensions.width, child->minDimensions.width + layoutConfig->padding.x * 2); openLayoutElement->minDimensions.width = CLAY__MAX(openLayoutElement->minDimensions.width, child->minDimensions.width + layoutConfig->padding.left + layoutConfig->padding.right);
} }
Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex); Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
} }
@ -2105,9 +2128,9 @@ void Clay__InitializePersistentMemory(Clay_Context* context) {
void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Clay__int32_tArray resizableContainerBuffer) { void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Clay__int32_tArray resizableContainerBuffer) {
Clay_Context* context = Clay_GetCurrentContext(); Clay_Context* context = Clay_GetCurrentContext();
Clay__int32_tArray largestContainers = context->openClipElementStack; Clay__int32_tArray largestContainers = context->openClipElementStack;
largestContainers.length = 0;
while (totalSizeToDistribute > 0.1) { while (totalSizeToDistribute > 0.1) {
largestContainers.length = 0;
float largestSize = 0; float largestSize = 0;
float targetSize = 0; float targetSize = 0;
for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) { for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) {
@ -2129,23 +2152,29 @@ void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Cl
} }
} }
if (largestContainers.length == 0) {
return;
}
targetSize = CLAY__MAX(targetSize, (largestSize * largestContainers.length) - totalSizeToDistribute) / largestContainers.length; targetSize = CLAY__MAX(targetSize, (largestSize * largestContainers.length) - totalSizeToDistribute) / largestContainers.length;
for (int32_t childOffset = 0; childOffset < largestContainers.length; childOffset++) { for (int32_t childOffset = 0; childOffset < largestContainers.length; childOffset++) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&largestContainers, childOffset)); int32_t childIndex = Clay__int32_tArray_Get(&largestContainers, childOffset);
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height; float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
float childMinSize = xAxis ? childElement->minDimensions.width : childElement->minDimensions.height; float childMinSize = xAxis ? childElement->minDimensions.width : childElement->minDimensions.height;
float oldChildSize = *childSize; float oldChildSize = *childSize;
*childSize = CLAY__MAX(childMinSize, targetSize); *childSize = CLAY__MAX(childMinSize, targetSize);
totalSizeToDistribute -= (oldChildSize - *childSize); totalSizeToDistribute -= (oldChildSize - *childSize);
if (*childSize == childMinSize) { if (*childSize == childMinSize) {
Clay__int32_tArray_RemoveSwapback(&largestContainers, childOffset); for (int32_t i = 0; i < resizableContainerBuffer.length; i++) {
childOffset--; if (Clay__int32_tArray_Get(&resizableContainerBuffer, i) == childIndex) {
Clay__int32_tArray_RemoveSwapback(&resizableContainerBuffer, i);
break;
}
}
} }
} }
if (largestContainers.length == 0) {
break;
}
} }
} }
@ -2183,8 +2212,8 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
Clay_LayoutConfig *parentStyleConfig = parent->layoutConfig; Clay_LayoutConfig *parentStyleConfig = parent->layoutConfig;
int32_t growContainerCount = 0; int32_t growContainerCount = 0;
float parentSize = xAxis ? parent->dimensions.width : parent->dimensions.height; float parentSize = xAxis ? parent->dimensions.width : parent->dimensions.height;
float parentPadding = (float)(xAxis ? parent->layoutConfig->padding.x : parent->layoutConfig->padding.y); float parentPadding = (float)(xAxis ? (parent->layoutConfig->padding.left + parent->layoutConfig->padding.right) : (parent->layoutConfig->padding.top + parent->layoutConfig->padding.bottom));
float innerContentSize = 0, growContainerContentSize = 0, totalPaddingAndChildGaps = parentPadding * 2; float innerContentSize = 0, growContainerContentSize = 0, totalPaddingAndChildGaps = parentPadding;
bool sizingAlongAxis = (xAxis && parentStyleConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) || (!xAxis && parentStyleConfig->layoutDirection == CLAY_TOP_TO_BOTTOM); bool sizingAlongAxis = (xAxis && parentStyleConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) || (!xAxis && parentStyleConfig->layoutDirection == CLAY_TOP_TO_BOTTOM);
resizableContainerBuffer.length = 0; resizableContainerBuffer.length = 0;
float parentChildGap = parentStyleConfig->childGap; float parentChildGap = parentStyleConfig->childGap;
@ -2228,18 +2257,12 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
*childSize = (parentSize - totalPaddingAndChildGaps) * childSizing.size.percent; *childSize = (parentSize - totalPaddingAndChildGaps) * childSizing.size.percent;
if (sizingAlongAxis) { if (sizingAlongAxis) {
innerContentSize += *childSize; innerContentSize += *childSize;
if (childOffset > 0) {
innerContentSize += parentChildGap; // For children after index 0, the childAxisOffset is the gap from the previous child
totalPaddingAndChildGaps += parentChildGap;
}
} else {
innerContentSize = CLAY__MAX(*childSize, innerContentSize);
} }
} }
} }
if (sizingAlongAxis) { if (sizingAlongAxis) {
float sizeToDistribute = parentSize - parentPadding * 2 - innerContentSize; float sizeToDistribute = parentSize - parentPadding - innerContentSize;
// The content is too large, compress the children as much as possible // The content is too large, compress the children as much as possible
if (sizeToDistribute < 0) { if (sizeToDistribute < 0) {
// If the parent can scroll in the axis direction in this direction, don't compress children, just leave them alone // If the parent can scroll in the axis direction in this direction, don't compress children, just leave them alone
@ -2284,7 +2307,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
} }
// If we're laying out the children of a scroll panel, grow containers expand to the height of the inner content, not the outer container // If we're laying out the children of a scroll panel, grow containers expand to the height of the inner content, not the outer container
float maxSize = parentSize - parentPadding * 2; float maxSize = parentSize - parentPadding;
if (Clay__ElementHasConfig(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER)) { if (Clay__ElementHasConfig(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER)) {
Clay_ScrollElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig; Clay_ScrollElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig;
if (((xAxis && scrollElementConfig->horizontal) || (!xAxis && scrollElementConfig->vertical))) { if (((xAxis && scrollElementConfig->horizontal) || (!xAxis && scrollElementConfig->vertical))) {
@ -2454,19 +2477,16 @@ void Clay__CalculateFinalLayout() {
// DFS node has been visited, this is on the way back up to the root // DFS node has been visited, this is on the way back up to the root
Clay_LayoutConfig *layoutConfig = currentElement->layoutConfig; Clay_LayoutConfig *layoutConfig = currentElement->layoutConfig;
if (layoutConfig->sizing.height.type == CLAY__SIZING_TYPE_PERCENT) {
continue;
}
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) { if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
// Resize any parent containers that have grown in height along their non layout axis // Resize any parent containers that have grown in height along their non layout axis
for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) { for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]); Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
float childHeightWithPadding = CLAY__MAX(childElement->dimensions.height + layoutConfig->padding.y * 2, currentElement->dimensions.height); float childHeightWithPadding = CLAY__MAX(childElement->dimensions.height + layoutConfig->padding.top + layoutConfig->padding.bottom, currentElement->dimensions.height);
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(childHeightWithPadding, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max); currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(childHeightWithPadding, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
} }
} else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) { } else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
// Resizing along the layout axis // Resizing along the layout axis
float contentHeight = (float)layoutConfig->padding.y * 2; float contentHeight = (float)(layoutConfig->padding.top + layoutConfig->padding.bottom);
for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) { for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]); Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
contentHeight += childElement->dimensions.height; contentHeight += childElement->dimensions.height;
@ -2585,7 +2605,7 @@ void Clay__CalculateFinalLayout() {
}); });
} }
} }
Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = rootElement, .position = rootPosition, .nextChildOffset = { .x = (float)rootElement->layoutConfig->padding.x, .y = (float)rootElement->layoutConfig->padding.y } }); Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = rootElement, .position = rootPosition, .nextChildOffset = { .x = (float)rootElement->layoutConfig->padding.left, .y = (float)rootElement->layoutConfig->padding.top } });
context->treeNodeVisited.internalArray[0] = false; context->treeNodeVisited.internalArray[0] = false;
while (dfsBuffer.length > 0) { while (dfsBuffer.length > 0) {
@ -2750,7 +2770,7 @@ void Clay__CalculateFinalLayout() {
contentSize.height = CLAY__MAX(contentSize.height, childElement->dimensions.height); contentSize.height = CLAY__MAX(contentSize.height, childElement->dimensions.height);
} }
contentSize.width += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap); contentSize.width += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
float extraSpace = currentElement->dimensions.width - (float)layoutConfig->padding.x * 2 - contentSize.width; float extraSpace = currentElement->dimensions.width - (float)(layoutConfig->padding.left + layoutConfig->padding.right) - contentSize.width;
switch (layoutConfig->childAlignment.x) { switch (layoutConfig->childAlignment.x) {
case CLAY_ALIGN_X_LEFT: extraSpace = 0; break; case CLAY_ALIGN_X_LEFT: extraSpace = 0; break;
case CLAY_ALIGN_X_CENTER: extraSpace /= 2; break; case CLAY_ALIGN_X_CENTER: extraSpace /= 2; break;
@ -2764,7 +2784,7 @@ void Clay__CalculateFinalLayout() {
contentSize.height += childElement->dimensions.height; contentSize.height += childElement->dimensions.height;
} }
contentSize.height += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap); contentSize.height += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
float extraSpace = currentElement->dimensions.height - (float)layoutConfig->padding.y * 2 - contentSize.height; float extraSpace = currentElement->dimensions.height - (float)(layoutConfig->padding.top + layoutConfig->padding.bottom) - contentSize.height;
switch (layoutConfig->childAlignment.y) { switch (layoutConfig->childAlignment.y) {
case CLAY_ALIGN_Y_TOP: extraSpace = 0; break; case CLAY_ALIGN_Y_TOP: extraSpace = 0; break;
case CLAY_ALIGN_Y_CENTER: extraSpace /= 2; break; case CLAY_ALIGN_Y_CENTER: extraSpace /= 2; break;
@ -2774,7 +2794,7 @@ void Clay__CalculateFinalLayout() {
} }
if (scrollContainerData) { if (scrollContainerData) {
scrollContainerData->contentSize = CLAY__INIT(Clay_Dimensions) { contentSize.width + (float)layoutConfig->padding.x * 2, contentSize.height + (float)layoutConfig->padding.y * 2 }; scrollContainerData->contentSize = CLAY__INIT(Clay_Dimensions) { contentSize.width + (float)(layoutConfig->padding.left + layoutConfig->padding.right), contentSize.height + (float)(layoutConfig->padding.top + layoutConfig->padding.bottom) };
} }
} }
} }
@ -2814,7 +2834,7 @@ void Clay__CalculateFinalLayout() {
if (borderConfig->betweenChildren.width > 0 && borderConfig->betweenChildren.color.a > 0) { if (borderConfig->betweenChildren.width > 0 && borderConfig->betweenChildren.color.a > 0) {
Clay_RectangleElementConfig *rectangleConfig = Clay__StoreRectangleElementConfig(CLAY__INIT(Clay_RectangleElementConfig) {.color = borderConfig->betweenChildren.color}); Clay_RectangleElementConfig *rectangleConfig = Clay__StoreRectangleElementConfig(CLAY__INIT(Clay_RectangleElementConfig) {.color = borderConfig->betweenChildren.color});
float halfGap = layoutConfig->childGap / 2; float halfGap = layoutConfig->childGap / 2;
Clay_Vector2 borderOffset = { (float)layoutConfig->padding.x - halfGap, (float)layoutConfig->padding.y - halfGap }; Clay_Vector2 borderOffset = { (float)layoutConfig->padding.left - halfGap, (float)layoutConfig->padding.top - halfGap };
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) { if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) { for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]); Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
@ -2864,16 +2884,16 @@ void Clay__CalculateFinalLayout() {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]); Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
// Alignment along non layout axis // Alignment along non layout axis
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) { if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
currentElementTreeNode->nextChildOffset.y = currentElement->layoutConfig->padding.y; currentElementTreeNode->nextChildOffset.y = currentElement->layoutConfig->padding.top;
float whiteSpaceAroundChild = currentElement->dimensions.height - (float)currentElement->layoutConfig->padding.y * 2 - childElement->dimensions.height; float whiteSpaceAroundChild = currentElement->dimensions.height - (float)(layoutConfig->padding.top + layoutConfig->padding.bottom) - childElement->dimensions.height;
switch (layoutConfig->childAlignment.y) { switch (layoutConfig->childAlignment.y) {
case CLAY_ALIGN_Y_TOP: break; case CLAY_ALIGN_Y_TOP: break;
case CLAY_ALIGN_Y_CENTER: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild / 2; break; case CLAY_ALIGN_Y_CENTER: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild / 2; break;
case CLAY_ALIGN_Y_BOTTOM: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild; break; case CLAY_ALIGN_Y_BOTTOM: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild; break;
} }
} else { } else {
currentElementTreeNode->nextChildOffset.x = currentElement->layoutConfig->padding.x; currentElementTreeNode->nextChildOffset.x = currentElement->layoutConfig->padding.left;
float whiteSpaceAroundChild = currentElement->dimensions.width - (float)currentElement->layoutConfig->padding.x * 2 - childElement->dimensions.width; float whiteSpaceAroundChild = currentElement->dimensions.width - (float)(layoutConfig->padding.left + layoutConfig->padding.right) - childElement->dimensions.width;
switch (layoutConfig->childAlignment.x) { switch (layoutConfig->childAlignment.x) {
case CLAY_ALIGN_X_LEFT: break; case CLAY_ALIGN_X_LEFT: break;
case CLAY_ALIGN_X_CENTER: currentElementTreeNode->nextChildOffset.x += whiteSpaceAroundChild / 2; break; case CLAY_ALIGN_X_CENTER: currentElementTreeNode->nextChildOffset.x += whiteSpaceAroundChild / 2; break;
@ -2891,7 +2911,7 @@ void Clay__CalculateFinalLayout() {
dfsBuffer.internalArray[newNodeIndex] = CLAY__INIT(Clay__LayoutElementTreeNode) { dfsBuffer.internalArray[newNodeIndex] = CLAY__INIT(Clay__LayoutElementTreeNode) {
.layoutElement = childElement, .layoutElement = childElement,
.position = { childPosition.x, childPosition.y }, .position = { childPosition.x, childPosition.y },
.nextChildOffset = { .x = (float)childElement->layoutConfig->padding.x, .y = (float)childElement->layoutConfig->padding.y }, .nextChildOffset = { .x = (float)childElement->layoutConfig->padding.left, .y = (float)childElement->layoutConfig->padding.top },
}; };
context->treeNodeVisited.internalArray[newNodeIndex] = false; context->treeNodeVisited.internalArray[newNodeIndex] = false;
@ -3046,12 +3066,12 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
// Collisions and offscreen info // Collisions and offscreen info
if (currentElementData) { if (currentElementData) {
if (currentElementData->debugData->collision) { if (currentElementData->debugData->collision) {
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, (CLAY__INIT(Clay_Color){177, 147, 8, 255}), 4)) { CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, (CLAY__INIT(Clay_Color){177, 147, 8, 255}), 4)) {
CLAY_TEXT(CLAY_STRING("Duplicate ID"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 })); CLAY_TEXT(CLAY_STRING("Duplicate ID"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }));
} }
} }
if (offscreen) { if (offscreen) {
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, CLAY__DEBUGVIEW_COLOR_3, 4)) { CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, CLAY__DEBUGVIEW_COLOR_3, 4)) {
CLAY_TEXT(CLAY_STRING("Offscreen"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 })); CLAY_TEXT(CLAY_STRING("Offscreen"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }));
} }
} }
@ -3065,7 +3085,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(elementConfig->type); Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(elementConfig->type);
Clay_Color backgroundColor = config.color; Clay_Color backgroundColor = config.color;
backgroundColor.a = 90; backgroundColor.a = 90;
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) { CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) {
CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = offscreen ? CLAY__DEBUGVIEW_COLOR_3 : CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 })); CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = offscreen ? CLAY__DEBUGVIEW_COLOR_3 : CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
} }
} }
@ -3087,7 +3107,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
} }
} else if (currentElement->childrenOrTextContent.children.length > 0) { } else if (currentElement->childrenOrTextContent.children.length > 0) {
Clay__OpenElement(); Clay__OpenElement();
CLAY_LAYOUT({ .padding = { 8 , 0} }); CLAY_LAYOUT({ .padding = { 8 } });
Clay__ElementPostConfiguration(); Clay__ElementPostConfiguration();
Clay__OpenElement(); Clay__OpenElement();
CLAY_BORDER({ .left = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }}); CLAY_BORDER({ .left = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }});
@ -3157,8 +3177,8 @@ void Clay__RenderDebugViewElementConfigHeader(Clay_String elementId, Clay__Eleme
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(type); Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(type);
Clay_Color backgroundColor = config.color; Clay_Color backgroundColor = config.color;
backgroundColor.a = 90; backgroundColor.a = 90;
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = { .x = CLAY__DEBUGVIEW_OUTER_PADDING }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } })) { CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(CLAY__DEBUGVIEW_OUTER_PADDING), .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } })) {
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) { CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) {
CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 })); CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
} }
CLAY(CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {} CLAY(CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {}
@ -3260,7 +3280,7 @@ void Clay__RenderDebugView() {
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
CLAY_BORDER({ .bottom = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }}) CLAY_BORDER({ .bottom = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }})
) { ) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) { CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
CLAY_TEXT(CLAY_STRING("Clay Debug Tools"), infoTextConfig); CLAY_TEXT(CLAY_STRING("Clay Debug Tools"), infoTextConfig);
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {} CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
// Close button // Close button
@ -3278,7 +3298,7 @@ void Clay__RenderDebugView() {
Clay_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0, 0); Clay_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0, 0);
// Element list // Element list
CLAY(Clay__AttachId(panelContentsId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_FLOATING({ .zIndex = 65001, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH })) { CLAY(Clay__AttachId(panelContentsId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_FLOATING({ .zIndex = 65001, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH })) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = {.x = CLAY__DEBUGVIEW_OUTER_PADDING }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = { CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow); layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow);
} }
} }
@ -3307,7 +3327,7 @@ void Clay__RenderDebugView() {
CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 }),
CLAY_BORDER({ .betweenChildren = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }}) CLAY_BORDER({ .betweenChildren = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }})
) { ) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) { CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
CLAY_TEXT(CLAY_STRING("Layout Config"), infoTextConfig); CLAY_TEXT(CLAY_STRING("Layout Config"), infoTextConfig);
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {} CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
if (selectedItem->elementId.stringId.length != 0) { if (selectedItem->elementId.stringId.length != 0) {
@ -3319,8 +3339,9 @@ void Clay__RenderDebugView() {
} }
} }
} }
Clay_Padding attributeConfigPadding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 8, 8};
// Clay_LayoutConfig debug info // Clay_LayoutConfig debug info
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// .boundingBox // .boundingBox
CLAY_TEXT(CLAY_STRING("Bounding Box"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Bounding Box"), infoTitleConfig);
CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) { CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) {
@ -3351,10 +3372,14 @@ void Clay__RenderDebugView() {
// .padding // .padding
CLAY_TEXT(CLAY_STRING("Padding"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Padding"), infoTitleConfig);
CLAY(CLAY_ID("Clay__DebugViewElementInfoPadding")) { CLAY(CLAY_ID("Clay__DebugViewElementInfoPadding")) {
CLAY_TEXT(CLAY_STRING("{ x: "), infoTextConfig); CLAY_TEXT(CLAY_STRING("{ left: "), infoTextConfig);
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.x), infoTextConfig); CLAY_TEXT(Clay__IntToString(layoutConfig->padding.left), infoTextConfig);
CLAY_TEXT(CLAY_STRING(", y: "), infoTextConfig); CLAY_TEXT(CLAY_STRING(", right: "), infoTextConfig);
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.y), infoTextConfig); CLAY_TEXT(Clay__IntToString(layoutConfig->padding.right), infoTextConfig);
CLAY_TEXT(CLAY_STRING(", top: "), infoTextConfig);
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.top), infoTextConfig);
CLAY_TEXT(CLAY_STRING(", bottom: "), infoTextConfig);
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.bottom), infoTextConfig);
CLAY_TEXT(CLAY_STRING(" }"), infoTextConfig); CLAY_TEXT(CLAY_STRING(" }"), infoTextConfig);
} }
// .childGap // .childGap
@ -3388,7 +3413,7 @@ void Clay__RenderDebugView() {
switch (elementConfig->type) { switch (elementConfig->type) {
case CLAY__ELEMENT_CONFIG_TYPE_RECTANGLE: { case CLAY__ELEMENT_CONFIG_TYPE_RECTANGLE: {
Clay_RectangleElementConfig *rectangleConfig = elementConfig->config.rectangleElementConfig; Clay_RectangleElementConfig *rectangleConfig = elementConfig->config.rectangleElementConfig;
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// .color // .color
CLAY_TEXT(CLAY_STRING("Color"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Color"), infoTitleConfig);
Clay__RenderDebugViewColor(rectangleConfig->color, infoTextConfig); Clay__RenderDebugViewColor(rectangleConfig->color, infoTextConfig);
@ -3400,7 +3425,7 @@ void Clay__RenderDebugView() {
} }
case CLAY__ELEMENT_CONFIG_TYPE_TEXT: { case CLAY__ELEMENT_CONFIG_TYPE_TEXT: {
Clay_TextElementConfig *textConfig = elementConfig->config.textElementConfig; Clay_TextElementConfig *textConfig = elementConfig->config.textElementConfig;
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// .fontSize // .fontSize
CLAY_TEXT(CLAY_STRING("Font Size"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Font Size"), infoTitleConfig);
CLAY_TEXT(Clay__IntToString(textConfig->fontSize), infoTextConfig); CLAY_TEXT(Clay__IntToString(textConfig->fontSize), infoTextConfig);
@ -3430,7 +3455,7 @@ void Clay__RenderDebugView() {
} }
case CLAY__ELEMENT_CONFIG_TYPE_IMAGE: { case CLAY__ELEMENT_CONFIG_TYPE_IMAGE: {
Clay_ImageElementConfig *imageConfig = elementConfig->config.imageElementConfig; Clay_ImageElementConfig *imageConfig = elementConfig->config.imageElementConfig;
CLAY(CLAY_ID("Clay__DebugViewElementInfoImageBody"), CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_ID("Clay__DebugViewElementInfoImageBody"), CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// .sourceDimensions // .sourceDimensions
CLAY_TEXT(CLAY_STRING("Source Dimensions"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Source Dimensions"), infoTitleConfig);
CLAY(CLAY_ID("Clay__DebugViewElementInfoImageDimensions")) { CLAY(CLAY_ID("Clay__DebugViewElementInfoImageDimensions")) {
@ -3448,7 +3473,7 @@ void Clay__RenderDebugView() {
} }
case CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER: { case CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER: {
Clay_ScrollElementConfig *scrollConfig = elementConfig->config.scrollElementConfig; Clay_ScrollElementConfig *scrollConfig = elementConfig->config.scrollElementConfig;
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// .vertical // .vertical
CLAY_TEXT(CLAY_STRING("Vertical"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Vertical"), infoTitleConfig);
CLAY_TEXT(scrollConfig->vertical ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig); CLAY_TEXT(scrollConfig->vertical ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig);
@ -3460,7 +3485,7 @@ void Clay__RenderDebugView() {
} }
case CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER: { case CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER: {
Clay_FloatingElementConfig *floatingConfig = elementConfig->config.floatingElementConfig; Clay_FloatingElementConfig *floatingConfig = elementConfig->config.floatingElementConfig;
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// .offset // .offset
CLAY_TEXT(CLAY_STRING("Offset"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Offset"), infoTitleConfig);
CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) { CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) {
@ -3491,7 +3516,7 @@ void Clay__RenderDebugView() {
} }
case CLAY__ELEMENT_CONFIG_TYPE_BORDER_CONTAINER: { case CLAY__ELEMENT_CONFIG_TYPE_BORDER_CONTAINER: {
Clay_BorderElementConfig *borderConfig = elementConfig->config.borderElementConfig; Clay_BorderElementConfig *borderConfig = elementConfig->config.borderElementConfig;
CLAY(CLAY_ID("Clay__DebugViewElementInfoBorderBody"), CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_ID("Clay__DebugViewElementInfoBorderBody"), CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
// .left // .left
CLAY_TEXT(CLAY_STRING("Left Border"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Left Border"), infoTitleConfig);
Clay__RenderDebugViewBorder(1, borderConfig->left, infoTextConfig); Clay__RenderDebugViewBorder(1, borderConfig->left, infoTextConfig);
@ -3521,14 +3546,14 @@ void Clay__RenderDebugView() {
} else { } else {
CLAY(CLAY_ID("Clay__DebugViewWarningsScrollPane"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .childGap = 6, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_SCROLL({ .horizontal = true, .vertical = true }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) { CLAY(CLAY_ID("Clay__DebugViewWarningsScrollPane"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .childGap = 6, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_SCROLL({ .horizontal = true, .vertical = true }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
Clay_TextElementConfig *warningConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE }); Clay_TextElementConfig *warningConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
CLAY(CLAY_ID("Clay__DebugViewWarningItemHeader"), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) { CLAY(CLAY_ID("Clay__DebugViewWarningItemHeader"), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
CLAY_TEXT(CLAY_STRING("Warnings"), warningConfig); CLAY_TEXT(CLAY_STRING("Warnings"), warningConfig);
} }
CLAY(CLAY_ID("Clay__DebugViewWarningsTopBorder"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {} CLAY(CLAY_ID("Clay__DebugViewWarningsTopBorder"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {}
int32_t previousWarningsLength = context->warnings.length; int32_t previousWarningsLength = context->warnings.length;
for (int32_t i = 0; i < previousWarningsLength; i++) { for (int32_t i = 0; i < previousWarningsLength; i++) {
Clay__Warning warning = context->warnings.internalArray[i]; Clay__Warning warning = context->warnings.internalArray[i];
CLAY(CLAY_IDI("Clay__DebugViewWarningItem", i), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) { CLAY(CLAY_IDI("Clay__DebugViewWarningItem", i), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
CLAY_TEXT(warning.baseMessage, warningConfig); CLAY_TEXT(warning.baseMessage, warningConfig);
if (warning.dynamicMessage.length > 0) { if (warning.dynamicMessage.length > 0) {
CLAY_TEXT(warning.dynamicMessage, warningConfig); CLAY_TEXT(warning.dynamicMessage, warningConfig);
@ -3651,11 +3676,15 @@ Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset
} }
#ifndef CLAY_WASM #ifndef CLAY_WASM
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config)) { void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData), uintptr_t userData) {
Clay_Context* context = Clay_GetCurrentContext();
Clay__MeasureText = measureTextFunction; Clay__MeasureText = measureTextFunction;
context->mesureTextUserData = userData;
} }
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId)) { void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId, uintptr_t userData), uintptr_t userData) {
Clay_Context* context = Clay_GetCurrentContext();
Clay__QueryScrollOffset = queryScrollOffsetFunction; Clay__QueryScrollOffset = queryScrollOffsetFunction;
context->queryScrollOffsetUserData = userData;
} }
#endif #endif
@ -3895,9 +3924,7 @@ void Clay_BeginLayout(void) {
if (context->debugModeEnabled) { if (context->debugModeEnabled) {
rootDimensions.width -= (float)Clay__debugViewWidth; rootDimensions.width -= (float)Clay__debugViewWidth;
} }
context->booleanWarnings.maxElementsExceeded = false; context->booleanWarnings = CLAY__INIT(Clay_BooleanWarnings) CLAY__DEFAULT_STRUCT;
context->booleanWarnings.maxTextMeasureCacheExceeded = false;
context->booleanWarnings.maxRenderCommandsExceeded = false;
Clay__OpenElement(); Clay__OpenElement();
CLAY_ID("Clay__RootContainer"); CLAY_ID("Clay__RootContainer");
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} }); CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} });
@ -3996,6 +4023,19 @@ Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
return CLAY__INIT(Clay_ScrollContainerData) CLAY__DEFAULT_STRUCT; return CLAY__INIT(Clay_ScrollContainerData) CLAY__DEFAULT_STRUCT;
} }
CLAY_WASM_EXPORT("Clay_GetElementData")
Clay_ElementData Clay_GetElementData(Clay_ElementId id){
Clay_LayoutElementHashMapItem * item = Clay__GetHashMapItem(id.id);
if(item == &CLAY__LAYOUT_ELEMENT_HASH_MAP_ITEM_DEFAULT) {
return CLAY__INIT(Clay_ElementData) CLAY__DEFAULT_STRUCT;
}
return CLAY__INIT(Clay_ElementData){
.boundingBox = item->boundingBox,
.found = true
};
}
CLAY_WASM_EXPORT("Clay_SetDebugModeEnabled") CLAY_WASM_EXPORT("Clay_SetDebugModeEnabled")
void Clay_SetDebugModeEnabled(bool enabled) { void Clay_SetDebugModeEnabled(bool enabled) {
Clay_Context* context = Clay_GetCurrentContext(); Clay_Context* context = Clay_GetCurrentContext();

View File

@ -23,6 +23,15 @@ FetchContent_Declare(
) )
FetchContent_MakeAvailable(SDL2_ttf) FetchContent_MakeAvailable(SDL2_ttf)
FetchContent_Declare(
SDL2_image
GIT_REPOSITORY "https://github.com/libsdl-org/SDL_image.git"
GIT_TAG "release-2.8.4"
GIT_PROGRESS TRUE
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(SDL2_image)
add_executable(SDL2_video_demo main.c) add_executable(SDL2_video_demo main.c)
target_compile_options(SDL2_video_demo PUBLIC) target_compile_options(SDL2_video_demo PUBLIC)
@ -32,6 +41,7 @@ target_link_libraries(SDL2_video_demo PUBLIC
SDL2::SDL2main SDL2::SDL2main
SDL2::SDL2-static SDL2::SDL2-static
SDL2_ttf::SDL2_ttf-static SDL2_ttf::SDL2_ttf-static
SDL2_image::SDL2_image-static
) )
if(MSVC) if(MSVC)

View File

@ -10,13 +10,14 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
const int FONT_ID_BODY_16 = 0; const int FONT_ID_BODY_16 = 0;
Clay_Color COLOR_WHITE = { 255, 255, 255, 255}; Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
SDL_Surface *sample_image;
void RenderHeaderButton(Clay_String text) { void RenderHeaderButton(Clay_String text) {
CLAY( CLAY(
CLAY_LAYOUT({ .padding = { 16, 8 }}), CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 }, .color = { 140, 140, 140, 255 },
.cornerRadius = 5 .cornerRadius = 5
@ -31,7 +32,7 @@ void RenderHeaderButton(Clay_String text) {
} }
void RenderDropdownMenuItem(Clay_String text) { void RenderDropdownMenuItem(Clay_String text) {
CLAY(CLAY_LAYOUT({ .padding = { 16, 16 }})) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16)})) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ CLAY_TEXT(text, CLAY_TEXT_CONFIG({
.fontId = FONT_ID_BODY_16, .fontId = FONT_ID_BODY_16,
.fontSize = 16, .fontSize = 16,
@ -91,7 +92,7 @@ static Clay_RenderCommandArray CreateLayout() {
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand, .sizing = layoutExpand,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.childGap = 16 .childGap = 16
}) })
) { ) {
@ -112,9 +113,18 @@ static Clay_RenderCommandArray CreateLayout() {
}) })
) { ) {
// Header buttons go here // Header buttons go here
CLAY(
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_BORDER_ALL({ 2, COLOR_WHITE })
) {
CLAY(
CLAY_LAYOUT({ .padding = { 8, 8, 8, 8 }}),
CLAY_IMAGE({ sample_image, { 23, 42 } })
) {}
}
CLAY( CLAY(
CLAY_ID("FileButton"), CLAY_ID("FileButton"),
CLAY_LAYOUT({ .padding = { 16, 8 }}), CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 }, .color = { 140, 140, 140, 255 },
.cornerRadius = 5 .cornerRadius = 5
@ -179,7 +189,7 @@ static Clay_RenderCommandArray CreateLayout() {
CLAY_RECTANGLE(contentBackgroundConfig), CLAY_RECTANGLE(contentBackgroundConfig),
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.childGap = 8, .childGap = 8,
.sizing = { .sizing = {
.width = CLAY_SIZING_FIXED(250), .width = CLAY_SIZING_FIXED(250),
@ -191,7 +201,7 @@ static Clay_RenderCommandArray CreateLayout() {
Document document = documents.documents[i]; Document document = documents.documents[i];
Clay_LayoutConfig sidebarButtonLayout = { Clay_LayoutConfig sidebarButtonLayout = {
.sizing = { .width = CLAY_SIZING_GROW(0) }, .sizing = { .width = CLAY_SIZING_GROW(0) },
.padding = { 16, 16 } .padding = CLAY_PADDING_ALL(16)
}; };
if (i == selectedDocumentIndex) { if (i == selectedDocumentIndex) {
@ -236,7 +246,7 @@ static Clay_RenderCommandArray CreateLayout() {
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 16, .childGap = 16,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.sizing = layoutExpand .sizing = layoutExpand
}) })
) { ) {
@ -279,17 +289,26 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Error: could not initialize TTF: %s\n", TTF_GetError()); fprintf(stderr, "Error: could not initialize TTF: %s\n", TTF_GetError());
return 1; return 1;
} }
if (IMG_Init(IMG_INIT_PNG) < 0) {
fprintf(stderr, "Error: could not initialize IMG: %s\n", IMG_GetError());
return 1;
}
TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 16); TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 16);
if (!font) { if (!font) {
fprintf(stderr, "Error: could not load font: %s\n", TTF_GetError()); fprintf(stderr, "Error: could not load font: %s\n", TTF_GetError());
return 1; return 1;
} }
SDL2_fonts[FONT_ID_BODY_16] = (SDL2_Font) {
SDL2_Font fonts[1] = {};
fonts[FONT_ID_BODY_16] = (SDL2_Font) {
.fontId = FONT_ID_BODY_16, .fontId = FONT_ID_BODY_16,
.font = font, .font = font,
}; };
sample_image = IMG_Load("resources/sample.png");
SDL_Window *window = NULL; SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL; SDL_Renderer *renderer = NULL;
if (SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_RESIZABLE, &window, &renderer) < 0) { if (SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_RESIZABLE, &window, &renderer) < 0) {
@ -299,12 +318,13 @@ int main(int argc, char *argv[]) {
uint64_t totalMemorySize = Clay_MinMemorySize(); uint64_t totalMemorySize = Clay_MinMemorySize();
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize)); Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
Clay_SetMeasureTextFunction(SDL2_MeasureText);
int windowWidth = 0; int windowWidth = 0;
int windowHeight = 0; int windowHeight = 0;
SDL_GetWindowSize(window, &windowWidth, &windowHeight); SDL_GetWindowSize(window, &windowWidth, &windowHeight);
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)windowWidth, (float)windowHeight }, (Clay_ErrorHandler) { HandleClayErrors }); Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)windowWidth, (float)windowHeight }, (Clay_ErrorHandler) { HandleClayErrors });
Clay_SetMeasureTextFunction(SDL2_MeasureText, (uintptr_t)&fonts);
Uint64 NOW = SDL_GetPerformanceCounter(); Uint64 NOW = SDL_GetPerformanceCounter();
Uint64 LAST = 0; Uint64 LAST = 0;
double deltaTime = 0; double deltaTime = 0;
@ -345,7 +365,7 @@ int main(int argc, char *argv[]) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
Clay_SDL2_Render(renderer, renderCommands); Clay_SDL2_Render(renderer, renderCommands, fonts);
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }
@ -353,6 +373,7 @@ int main(int argc, char *argv[]) {
quit: quit:
SDL_DestroyRenderer(renderer); SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
IMG_Quit();
TTF_Quit(); TTF_Quit();
SDL_Quit(); SDL_Quit();
return 0; return 0;

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

View File

@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 3.27)
# Project setup
project(clay_examples_sdl3_simple_demo C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
include(FetchContent)
set(FETCHCONTENT_QUIET FALSE)
# Download SDL3
FetchContent_Declare(
SDL
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
GIT_TAG preview-3.1.6
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
message(STATUS "Using SDL via FetchContent")
FetchContent_MakeAvailable(SDL)
set_property(DIRECTORY "${sdl_SOURCE_DIR}" PROPERTY EXCLUDE_FROM_ALL TRUE)
# Download SDL_ttf
FetchContent_Declare(
SDL_ttf
GIT_REPOSITORY https://github.com/libsdl-org/SDL_ttf.git
GIT_TAG main # Slightly risky to use main branch, but it's the only one available
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
message(STATUS "Using SDL_ttf via FetchContent")
FetchContent_MakeAvailable(SDL_ttf)
set_property(DIRECTORY "${sdl_ttf_SOURCE_DIR}" PROPERTY EXCLUDE_FROM_ALL TRUE)
# Example executable
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} PRIVATE
SDL3::SDL3
SDL3_ttf::SDL3_ttf
)
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/resources
${CMAKE_CURRENT_BINARY_DIR}/resources
)

View File

@ -0,0 +1,185 @@
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#define CLAY_IMPLEMENTATION
#include "../../clay.h"
#include <stdio.h>
#include "../../renderers/SDL3/clay_renderer_SDL3.c"
static const Uint32 FONT_ID = 0;
static const Clay_Color COLOR_ORANGE = (Clay_Color) {225, 138, 50, 255};
static const Clay_Color COLOR_BLUE = (Clay_Color) {111, 173, 162, 255};
static const Clay_Color COLOR_LIGHT = (Clay_Color) {224, 215, 210, 255};
typedef struct app_state {
SDL_Window *window;
SDL_Renderer *renderer;
} AppState;
static inline Clay_Dimensions SDL_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData)
{
TTF_Font *font = gFonts[config->fontId];
int width, height;
if (!TTF_GetStringSize(font, text.chars, text.length, &width, &height)) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to measure text: %s", SDL_GetError());
}
return (Clay_Dimensions) { (float) width, (float) height };
}
static void Label(Clay_String text)
{
CLAY(CLAY_LAYOUT({ .padding = {16, 8} }), CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE })) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID,
.fontSize = 24,
}));
}
}
static Clay_RenderCommandArray Clay_CreateLayout()
{
Clay_BeginLayout();
CLAY(CLAY_ID("MainContent"),
CLAY_LAYOUT({
.sizing = {
.width = CLAY_SIZING_GROW(),
.height = CLAY_SIZING_GROW(),
},
.childAlignment = {
.x = CLAY_ALIGN_X_CENTER,
.y = CLAY_ALIGN_Y_CENTER,
},
.childGap = 10,
.padding = { 10, 10 },
.layoutDirection = CLAY_TOP_TO_BOTTOM,
}),
CLAY_RECTANGLE({
.color = COLOR_LIGHT,
})
) {
Label(CLAY_STRING("Button 1"));
Label(CLAY_STRING("Button 2"));
Label(CLAY_STRING("Button 3"));
}
return Clay_EndLayout();
}
void HandleClayErrors(Clay_ErrorData errorData) {
printf("%s", errorData.errorText.chars);
}
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
(void) argc;
(void) argv;
if (!TTF_Init()) {
return SDL_APP_FAILURE;
}
AppState *state = SDL_calloc(1, sizeof(AppState));
if (!state) {
return SDL_APP_FAILURE;
}
*appstate = state;
if (!SDL_CreateWindowAndRenderer("Clay Demo", 640, 480, 0, &state->window, &state->renderer)) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to create window and renderer: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
SDL_SetWindowResizable(state->window, true);
TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 24);
if (!font) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to load font: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
gFonts[FONT_ID] = font;
/* Initialize Clay */
uint64_t totalMemorySize = Clay_MinMemorySize();
Clay_Arena clayMemory = (Clay_Arena) {
.memory = SDL_malloc(totalMemorySize),
.capacity = totalMemorySize
};
int width, height;
SDL_GetWindowSize(state->window, &width, &height);
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float) width, (float) height }, (Clay_ErrorHandler) { HandleClayErrors });
Clay_SetMeasureTextFunction(SDL_MeasureText, 0);
*appstate = state;
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
SDL_AppResult ret_val = SDL_APP_CONTINUE;
switch (event->type) {
case SDL_EVENT_QUIT:
ret_val = SDL_APP_SUCCESS;
break;
case SDL_EVENT_WINDOW_RESIZED:
Clay_SetLayoutDimensions((Clay_Dimensions) { (float) event->window.data1, (float) event->window.data2 });
break;
case SDL_EVENT_MOUSE_MOTION:
Clay_SetPointerState((Clay_Vector2) { event->motion.x, event->motion.y },
event->motion.state & SDL_BUTTON_LEFT);
break;
case SDL_EVENT_MOUSE_WHEEL:
Clay_UpdateScrollContainers(true, (Clay_Vector2) { event->motion.xrel, event->motion.yrel }, 0.01f);
break;
default:
break;
};
return ret_val;
}
SDL_AppResult SDL_AppIterate(void *appstate)
{
AppState *state = appstate;
Clay_RenderCommandArray render_commands = Clay_CreateLayout();
SDL_SetRenderDrawColor(state->renderer, 0, 0, 0, 255);
SDL_RenderClear(state->renderer);
SDL_RenderClayCommands(state->renderer, &render_commands);
SDL_RenderPresent(state->renderer);
return SDL_APP_CONTINUE;
}
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
(void) result;
if (result != SDL_APP_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Application failed to run");
}
AppState *state = appstate;
if (state) {
if (state->renderer)
SDL_DestroyRenderer(state->renderer);
if (state->window)
SDL_DestroyWindow(state->window);
SDL_free(state);
}
TTF_Quit();
}

Binary file not shown.

View File

@ -42,7 +42,7 @@ void Layout() {
CLAY_RECTANGLE({ .color = BACKGROUND })) { CLAY_RECTANGLE({ .color = BACKGROUND })) {
CLAY(CLAY_ID("PageMargins"), CLAY(CLAY_ID("PageMargins"),
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) },
.padding = { 70., 50. }, // Some nice looking page margins .padding = { 70, 70, 50, 50 }, // Some nice looking page margins
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 10})) { .childGap = 10})) {
@ -62,7 +62,7 @@ void Layout() {
.color = ACCENT, .color = ACCENT,
.cornerRadius = CLAY_CORNER_RADIUS(12), .cornerRadius = CLAY_CORNER_RADIUS(12),
})) { })) {
CLAY(CLAY_LAYOUT({.padding = { 20., 20. }, .childGap = 4, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({.padding = CLAY_PADDING_ALL(20), .childGap = 4, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
CLAY_TEXT(CLAY_STRING("- High performance"), CLAY_TEXT(CLAY_STRING("- High performance"),
CLAY_TEXT_CONFIG({ .textColor = PRIMARY, .fontSize = 14, .fontFamily = CLAY_STRING("Quicksand SemiBold") })); CLAY_TEXT_CONFIG({ .textColor = PRIMARY, .fontSize = 14, .fontFamily = CLAY_STRING("Quicksand SemiBold") }));
CLAY_TEXT(CLAY_STRING("- Declarative syntax"), CLAY_TEXT(CLAY_STRING("- Declarative syntax"),
@ -77,7 +77,7 @@ void Layout() {
} }
CLAY(CLAY_LAYOUT({ CLAY(CLAY_LAYOUT({
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)}, .sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
.padding = { 10, 10 }, .padding = CLAY_PADDING_ALL(10),
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },
.childGap = 4 .childGap = 4
@ -85,7 +85,7 @@ void Layout() {
// Profile picture // Profile picture
CLAY(CLAY_LAYOUT({ CLAY(CLAY_LAYOUT({
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)}, .sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
.padding = { 30, 0 }, .padding = { 30, 30, 0, 0 },
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }}), CLAY_BORDER_OUTSIDE_RADIUS(2, PRIMARY, 10)) { .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }}), CLAY_BORDER_OUTSIDE_RADIUS(2, PRIMARY, 10)) {
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED(32), CLAY_SIZING_FIXED(32) } }), CLAY_IMAGE({ .sourceDimensions = { 32, 32 }, .path = CLAY_STRING("resources/check.png") })); CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED(32), CLAY_SIZING_FIXED(32) } }), CLAY_IMAGE({ .sourceDimensions = { 32, 32 }, .path = CLAY_STRING("resources/check.png") }));
@ -97,7 +97,7 @@ void Layout() {
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childGap = 10, .layoutDirection = CLAY_TOP_TO_BOTTOM })) { CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childGap = 10, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
CLAY_TEXT(CLAY_STRING("Cairo"), CLAY_TEXT_CONFIG({ .fontFamily = CLAY_STRING("Calistoga"), .fontSize = 24, .textColor = PRIMARY })); CLAY_TEXT(CLAY_STRING("Cairo"), CLAY_TEXT_CONFIG({ .fontFamily = CLAY_STRING("Calistoga"), .fontSize = 24, .textColor = PRIMARY }));
CLAY(CLAY_LAYOUT({ .padding = { 10, 10 } }), CLAY_RECTANGLE({ .color = ACCENT, .cornerRadius = CLAY_CORNER_RADIUS(10) })) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(10) }), CLAY_RECTANGLE({ .color = ACCENT, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {
CLAY_TEXT(CLAY_STRING("Officiis quia quia qui inventore ratione voluptas et. Quidem sunt unde similique. Qui est et exercitationem cumque harum illum. Numquam placeat aliquid quo voluptatem. " CLAY_TEXT(CLAY_STRING("Officiis quia quia qui inventore ratione voluptas et. Quidem sunt unde similique. Qui est et exercitationem cumque harum illum. Numquam placeat aliquid quo voluptatem. "
"Deleniti saepe nihil exercitationem nemo illo. Consequatur beatae repellat provident similique. Provident qui exercitationem deserunt sapiente. Quam qui dolor corporis odit. " "Deleniti saepe nihil exercitationem nemo illo. Consequatur beatae repellat provident similique. Provident qui exercitationem deserunt sapiente. Quam qui dolor corporis odit. "
"Assumenda corrupti sunt culpa pariatur. Vero sit ut minima. In est consequatur minus et cum sint illum aperiam. Qui ipsa quas nisi omnis aut quia nobis. " "Assumenda corrupti sunt culpa pariatur. Vero sit ut minima. In est consequatur minus et cum sint illum aperiam. Qui ipsa quas nisi omnis aut quia nobis. "

View File

@ -314,7 +314,7 @@
const importObject = { const importObject = {
clay: { clay: {
measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig) => { measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig, userData) => {
let stringLength = memoryDataView.getUint32(textToMeasure, true); let stringLength = memoryDataView.getUint32(textToMeasure, true);
let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true); let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true);
let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition); let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition);

View File

@ -314,7 +314,7 @@
const importObject = { const importObject = {
clay: { clay: {
measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig) => { measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig, userData) => {
let stringLength = memoryDataView.getUint32(textToMeasure, true); let stringLength = memoryDataView.getUint32(textToMeasure, true);
let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true); let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true);
let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition); let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition);

View File

@ -41,15 +41,15 @@ Clay_TextElementConfig headerTextConfig = (Clay_TextElementConfig) { .fontId = 2
Clay_TextElementConfig blobTextConfig = (Clay_TextElementConfig) { .fontId = 2, .fontSize = 30, .textColor = {244, 235, 230, 255} }; Clay_TextElementConfig blobTextConfig = (Clay_TextElementConfig) { .fontId = 2, .fontSize = 30, .textColor = {244, 235, 230, 255} };
void LandingPageBlob(int index, int fontSize, Clay_Color color, Clay_String text, Clay_String imageURL) { void LandingPageBlob(int index, int fontSize, Clay_Color color, Clay_String text, Clay_String imageURL) {
CLAY(CLAY_IDI("HeroBlob", index), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 480) }, .padding = {16, 16}, .childGap = 16, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_BORDER_OUTSIDE_RADIUS(2, color, 10)) { CLAY(CLAY_IDI("HeroBlob", index), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 480) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_BORDER_OUTSIDE_RADIUS(2, color, 10)) {
CLAY(CLAY_IDI("CheckImage", index), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED(32) } }), CLAY_IMAGE({ .sourceDimensions = { 128, 128 }, .sourceURL = imageURL })) {} CLAY(CLAY_IDI("CheckImage", index), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED(32) } }), CLAY_IMAGE({ .sourceDimensions = { 128, 128 }, .sourceURL = imageURL })) {}
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = fontSize, .fontId = FONT_ID_BODY_24, .textColor = color })); CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = fontSize, .fontId = FONT_ID_BODY_24, .textColor = color }));
} }
} }
void LandingPageDesktop() { void LandingPageDesktop() {
CLAY(CLAY_ID("LandingPage1Desktop"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(.min = windowHeight - 70) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { .x = 50 } })) { CLAY(CLAY_ID("LandingPage1Desktop"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(.min = windowHeight - 70) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } })) {
CLAY(CLAY_ID("LandingPage1"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { 32, 32 }, .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) { CLAY(CLAY_ID("LandingPage1"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_PERCENT(0.55f) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_PERCENT(0.55f) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance."), CLAY_TEXT_CONFIG({ .fontSize = 56, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED })); CLAY_TEXT(CLAY_STRING("Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance."), CLAY_TEXT_CONFIG({ .fontSize = 56, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } })) {} CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } })) {}
@ -67,7 +67,7 @@ void LandingPageDesktop() {
} }
void LandingPageMobile() { void LandingPageMobile() {
CLAY(CLAY_ID("LandingPage1Mobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(.min = windowHeight - 70) }, .childAlignment = {CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = { 16, 32 }, .childGap = 32 })) { CLAY(CLAY_ID("LandingPage1Mobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(.min = windowHeight - 70) }, .childAlignment = {CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = { 16, 16, 32, 32 }, .childGap = 32 })) {
CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance."), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED })); CLAY_TEXT(CLAY_STRING("Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance."), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } })) {} CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } })) {}
@ -87,14 +87,14 @@ void FeatureBlocksDesktop() {
CLAY(CLAY_ID("FeatureBlocksOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) { CLAY(CLAY_ID("FeatureBlocksOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {
CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) { CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) {
Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED }); Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED });
CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {50, 32}, .childGap = 8 })) { CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {50, 50, 32, 32}, .childGap = 8 })) {
CLAY(CLAY_ID("HFileIncludeOuter"), CLAY_LAYOUT({ .padding = {8, 4} }), CLAY_RECTANGLE({ .color = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) })) { CLAY(CLAY_ID("HFileIncludeOuter"), CLAY_LAYOUT({ .padding = {8, 4} }), CLAY_RECTANGLE({ .color = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) })) {
CLAY_TEXT(CLAY_STRING("#include clay.h"), CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_LIGHT })); CLAY_TEXT(CLAY_STRING("#include clay.h"), CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_LIGHT }));
} }
CLAY_TEXT(CLAY_STRING("~2000 lines of C99."), textConfig); CLAY_TEXT(CLAY_STRING("~2000 lines of C99."), textConfig);
CLAY_TEXT(CLAY_STRING("Zero dependencies, including no C standard library."), textConfig); CLAY_TEXT(CLAY_STRING("Zero dependencies, including no C standard library."), textConfig);
} }
CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 50, .y = 32}, .childGap = 8 })) { CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {50, 50, 32, 32}, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Renderer agnostic."), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = COLOR_ORANGE })); CLAY_TEXT(CLAY_STRING("Renderer agnostic."), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = COLOR_ORANGE }));
CLAY_TEXT(CLAY_STRING("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML."), textConfig); CLAY_TEXT(CLAY_STRING("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML."), textConfig);
CLAY_TEXT(CLAY_STRING("Flexible output for easy compositing in your custom engine or environment."), textConfig); CLAY_TEXT(CLAY_STRING("Flexible output for easy compositing in your custom engine or environment."), textConfig);
@ -106,14 +106,14 @@ void FeatureBlocksDesktop() {
void FeatureBlocksMobile() { void FeatureBlocksMobile() {
CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) { CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) {
Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED }); Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED });
CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {16, 32}, .childGap = 8 })) { CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 8 })) {
CLAY(CLAY_ID("HFileIncludeOuter"), CLAY_LAYOUT({ .padding = {8, 4} }), CLAY_RECTANGLE({ .color = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) })) { CLAY(CLAY_ID("HFileIncludeOuter"), CLAY_LAYOUT({ .padding = {8, 4} }), CLAY_RECTANGLE({ .color = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) })) {
CLAY_TEXT(CLAY_STRING("#include clay.h"), CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_LIGHT })); CLAY_TEXT(CLAY_STRING("#include clay.h"), CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_LIGHT }));
} }
CLAY_TEXT(CLAY_STRING("~2000 lines of C99."), textConfig); CLAY_TEXT(CLAY_STRING("~2000 lines of C99."), textConfig);
CLAY_TEXT(CLAY_STRING("Zero dependencies, including no C standard library."), textConfig); CLAY_TEXT(CLAY_STRING("Zero dependencies, including no C standard library."), textConfig);
} }
CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 16, .y = 32}, .childGap = 8 })) { CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Renderer agnostic."), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = COLOR_ORANGE })); CLAY_TEXT(CLAY_STRING("Renderer agnostic."), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = COLOR_ORANGE }));
CLAY_TEXT(CLAY_STRING("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML."), textConfig); CLAY_TEXT(CLAY_STRING("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML."), textConfig);
CLAY_TEXT(CLAY_STRING("Flexible output for easy compositing in your custom engine or environment."), textConfig); CLAY_TEXT(CLAY_STRING("Flexible output for easy compositing in your custom engine or environment."), textConfig);
@ -122,8 +122,8 @@ void FeatureBlocksMobile() {
} }
void DeclarativeSyntaxPageDesktop() { void DeclarativeSyntaxPageDesktop() {
CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 50} })) { CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } })) {
CLAY(CLAY_ID("SyntaxPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = { 32, 32 }, .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) { CLAY(CLAY_ID("SyntaxPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
CLAY(CLAY_ID("SyntaxPageLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("SyntaxPageLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Declarative Syntax"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED })); CLAY_TEXT(CLAY_STRING("Declarative Syntax"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) } })) {} CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) } })) {}
@ -139,7 +139,7 @@ void DeclarativeSyntaxPageDesktop() {
} }
void DeclarativeSyntaxPageMobile() { void DeclarativeSyntaxPageMobile() {
CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {16, 32}, .childGap = 16 })) { CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 16 })) {
CLAY(CLAY_ID("SyntaxPageLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("SyntaxPageLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Declarative Syntax"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED })); CLAY_TEXT(CLAY_STRING("Declarative Syntax"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) } })) {} CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) } })) {}
@ -165,7 +165,7 @@ Clay_Color ColorLerp(Clay_Color a, Clay_Color b, float amount) {
Clay_String LOREM_IPSUM_TEXT = CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); Clay_String LOREM_IPSUM_TEXT = CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
void HighPerformancePageDesktop(float lerpValue) { void HighPerformancePageDesktop(float lerpValue) {
CLAY(CLAY_ID("PerformanceDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 82, 32}, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) { CLAY(CLAY_ID("PerformanceOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {82, 82, 32, 32}, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
CLAY(CLAY_ID("PerformanceLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("PerformanceLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("High Performance"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT })); CLAY_TEXT(CLAY_STRING("High Performance"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {} CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
@ -175,10 +175,10 @@ void HighPerformancePageDesktop(float lerpValue) {
} }
CLAY(CLAY_ID("PerformanceRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) { CLAY(CLAY_ID("PerformanceRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) {
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) { CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) {
CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.3f + 0.4f * lerpValue), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {32, 32} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) { CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.3f + 0.4f * lerpValue), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) {
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT })); CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
} }
CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {32, 32} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) { CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) {
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT })); CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
} }
} }
@ -187,7 +187,7 @@ void HighPerformancePageDesktop(float lerpValue) {
} }
void HighPerformancePageMobile(float lerpValue) { void HighPerformancePageMobile(float lerpValue) {
CLAY(CLAY_ID("PerformanceMobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 16, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_RED })) { CLAY(CLAY_ID("PerformanceOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
CLAY(CLAY_ID("PerformanceLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("PerformanceLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("High Performance"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT })); CLAY_TEXT(CLAY_STRING("High Performance"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {} CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
@ -197,10 +197,10 @@ void HighPerformancePageMobile(float lerpValue) {
} }
CLAY(CLAY_ID("PerformanceRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) { CLAY(CLAY_ID("PerformanceRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) {
CLAY(CLAY_ID(""), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) { CLAY(CLAY_ID(""), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) {
CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.35f + 0.3f * lerpValue), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) { CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.35f + 0.3f * lerpValue), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(16) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) {
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT })); CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
} }
CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) { CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(16) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) {
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT })); CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
} }
} }
@ -217,7 +217,7 @@ void HandleRendererButtonInteraction(Clay_ElementId elementId, Clay_PointerData
} }
void RendererButtonActive(Clay_String text) { void RendererButtonActive(Clay_String text) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300) }, .padding = {16, 16} }), CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300) }, .padding = CLAY_PADDING_ALL(16) }),
CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_RED_HOVER : COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(10) }) CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_RED_HOVER : COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(10) })
) { ) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT })); CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
@ -225,7 +225,7 @@ void RendererButtonActive(Clay_String text) {
} }
void RendererButtonInactive(Clay_String text, size_t rendererIndex) { void RendererButtonInactive(Clay_String text, size_t rendererIndex) {
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300)}, .padding = {16, 16} }), CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300)}, .padding = CLAY_PADDING_ALL(16) }),
CLAY_BORDER_OUTSIDE_RADIUS(2, COLOR_RED, 10), CLAY_BORDER_OUTSIDE_RADIUS(2, COLOR_RED, 10),
CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT, .cornerRadius = CLAY_CORNER_RADIUS(10), .cursorPointer = true }), CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT, .cornerRadius = CLAY_CORNER_RADIUS(10), .cursorPointer = true }),
Clay_OnHover(HandleRendererButtonInteraction, rendererIndex) Clay_OnHover(HandleRendererButtonInteraction, rendererIndex)
@ -235,8 +235,8 @@ void RendererButtonInactive(Clay_String text, size_t rendererIndex) {
} }
void RendererPageDesktop() { void RendererPageDesktop() {
CLAY(CLAY_ID("RendererPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 50} })) { CLAY(CLAY_ID("RendererPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } })) {
CLAY(CLAY_ID("RendererPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = { 32, 32 }, .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) { CLAY(CLAY_ID("RendererPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
CLAY(CLAY_ID("RendererLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("RendererLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Renderer & Platform Agnostic"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED })); CLAY_TEXT(CLAY_STRING("Renderer & Platform Agnostic"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {} CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
@ -260,7 +260,7 @@ void RendererPageDesktop() {
} }
void RendererPageMobile() { void RendererPageMobile() {
CLAY(CLAY_ID("RendererMobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = {.x = 16, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) { CLAY(CLAY_ID("RendererMobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = { 16, 16, 32, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {
CLAY(CLAY_ID("RendererLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("RendererLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Renderer & Platform Agnostic"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED })); CLAY_TEXT(CLAY_STRING("Renderer & Platform Agnostic"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {} CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
@ -283,7 +283,7 @@ void RendererPageMobile() {
} }
void DebuggerPageDesktop() { void DebuggerPageDesktop() {
CLAY(CLAY_ID("DebuggerDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 82, 32}, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) { CLAY(CLAY_ID("DebuggerDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 82, 82, 32, 32 }, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
CLAY(CLAY_ID("DebuggerLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) { CLAY(CLAY_ID("DebuggerLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
CLAY_TEXT(CLAY_STRING("Integrated Debug Tools"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT })); CLAY_TEXT(CLAY_STRING("Integrated Debug Tools"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
CLAY(CLAY_ID("DebuggerSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {} CLAY(CLAY_ID("DebuggerSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
@ -311,18 +311,18 @@ float animationLerpValue = -1.0f;
Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) { Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
Clay_BeginLayout(); Clay_BeginLayout();
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) } }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) { CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) } }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {
CLAY(CLAY_ID("Header"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(50) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = { 32 } })) { CLAY(CLAY_ID("Header"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(50) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = { 32, 32 } })) {
CLAY_TEXT(CLAY_STRING("Clay"), &headerTextConfig); CLAY_TEXT(CLAY_STRING("Clay"), &headerTextConfig);
CLAY(CLAY_ID("Spacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {} CLAY(CLAY_ID("Spacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {}
if (!mobileScreen) { if (!mobileScreen) {
CLAY(CLAY_ID("LinkExamplesOuter"), CLAY_LAYOUT({ .padding = {8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples"), .color = {0,0,0,0} })) { CLAY(CLAY_ID("LinkExamplesOuter"), CLAY_LAYOUT({ .padding = {8, 8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples"), .color = {0,0,0,0} })) {
CLAY_TEXT(CLAY_STRING("Examples"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })); CLAY_TEXT(CLAY_STRING("Examples"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
} }
CLAY(CLAY_ID("LinkDocsOuter"), CLAY_LAYOUT({ .padding = {8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md"), .color = {0,0,0,0} })) { CLAY(CLAY_ID("LinkDocsOuter"), CLAY_LAYOUT({ .padding = {8, 8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md"), .color = {0,0,0,0} })) {
CLAY_TEXT(CLAY_STRING("Docs"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })); CLAY_TEXT(CLAY_STRING("Docs"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
} }
} }
CLAY(CLAY_LAYOUT({ .padding = {16, 6} }), CLAY(CLAY_LAYOUT({ .padding = {16, 16, 6, 6} }),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.cornerRadius = CLAY_CORNER_RADIUS(10), .cornerRadius = CLAY_CORNER_RADIUS(10),
.link = CLAY_STRING("https://discord.gg/b4FTWkxdvT"), .link = CLAY_STRING("https://discord.gg/b4FTWkxdvT"),
@ -331,7 +331,7 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
) { ) {
CLAY_TEXT(CLAY_STRING("Discord"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })); CLAY_TEXT(CLAY_STRING("Discord"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
} }
CLAY(CLAY_LAYOUT({ .padding = {16, 6} }), CLAY(CLAY_LAYOUT({ .padding = {16, 16, 6, 6} }),
CLAY_RECTANGLE({ .cornerRadius = CLAY_CORNER_RADIUS(10), .link = CLAY_STRING("https://github.com/nicbarker/clay"), .color = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT }), CLAY_RECTANGLE({ .cornerRadius = CLAY_CORNER_RADIUS(10), .link = CLAY_STRING("https://github.com/nicbarker/clay"), .color = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT }),
CLAY_BORDER_OUTSIDE_RADIUS(2, COLOR_RED, 10) CLAY_BORDER_OUTSIDE_RADIUS(2, COLOR_RED, 10)
) { ) {
@ -391,10 +391,10 @@ CLAY_WASM_EXPORT("UpdateDrawFrame") Clay_RenderCommandArray UpdateDrawFrame(floa
windowHeight = height; windowHeight = height;
Clay_SetLayoutDimensions((Clay_Dimensions) { width, height }); Clay_SetLayoutDimensions((Clay_Dimensions) { width, height });
Clay_ScrollContainerData scrollContainerData = Clay_GetScrollContainerData(Clay_GetElementId(CLAY_STRING("OuterScrollContainer"))); Clay_ScrollContainerData scrollContainerData = Clay_GetScrollContainerData(Clay_GetElementId(CLAY_STRING("OuterScrollContainer")));
Clay_LayoutElementHashMapItem *perfPage = Clay__GetHashMapItem(Clay_GetElementId(CLAY_STRING("PerformancePageOuter")).id); Clay_LayoutElementHashMapItem *perfPage = Clay__GetHashMapItem(Clay_GetElementId(CLAY_STRING("PerformanceOuter")).id);
// NaN propagation can cause pain here // NaN propagation can cause pain here
float perfPageYOffset = perfPage->boundingBox.y + scrollContainerData.scrollPosition->y; float perfPageYOffset = perfPage->boundingBox.y + scrollContainerData.scrollPosition->y;
if (deltaTime == deltaTime && perfPageYOffset < height && perfPageYOffset + perfPage->boundingBox.height > 0) { if (deltaTime == deltaTime && (ACTIVE_RENDERER_INDEX == 1 || (perfPageYOffset < height && perfPageYOffset + perfPage->boundingBox.height > 0))) {
animationLerpValue += deltaTime; animationLerpValue += deltaTime;
if (animationLerpValue > 1) { if (animationLerpValue > 1) {
animationLerpValue -= 2; animationLerpValue -= 2;

View File

@ -7,7 +7,7 @@ Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
void RenderHeaderButton(Clay_String text) { void RenderHeaderButton(Clay_String text) {
CLAY( CLAY(
CLAY_LAYOUT({ .padding = { 16, 8 }}), CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 }, .color = { 140, 140, 140, 255 },
.cornerRadius = 5 .cornerRadius = 5
@ -22,7 +22,7 @@ void RenderHeaderButton(Clay_String text) {
} }
void RenderDropdownMenuItem(Clay_String text) { void RenderDropdownMenuItem(Clay_String text) {
CLAY(CLAY_LAYOUT({ .padding = { 16, 16 }})) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16)})) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ CLAY_TEXT(text, CLAY_TEXT_CONFIG({
.fontId = FONT_ID_BODY_16, .fontId = FONT_ID_BODY_16,
.fontSize = 16, .fontSize = 16,
@ -84,7 +84,7 @@ int main(void) {
.width = GetScreenWidth(), .width = GetScreenWidth(),
.height = GetScreenHeight() .height = GetScreenHeight()
}, (Clay_ErrorHandler) { HandleClayErrors }); // This final argument is new since the video was published }, (Clay_ErrorHandler) { HandleClayErrors }); // This final argument is new since the video was published
Clay_SetMeasureTextFunction(Raylib_MeasureText); Clay_SetMeasureTextFunction(Raylib_MeasureText, 0);
Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) { Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) {
.font = LoadFontEx("resources/Roboto-Regular.ttf", 48, 0, 400), .font = LoadFontEx("resources/Roboto-Regular.ttf", 48, 0, 400),
.fontId = FONT_ID_BODY_16 .fontId = FONT_ID_BODY_16
@ -117,7 +117,7 @@ int main(void) {
Clay_RectangleElementConfig contentBackgroundConfig = { Clay_RectangleElementConfig contentBackgroundConfig = {
.color = { 90, 90, 90, 255 }, .color = { 90, 90, 90, 255 },
.cornerRadius = 8 .cornerRadius = CLAY_CORNER_RADIUS(8)
}; };
Clay_BeginLayout(); Clay_BeginLayout();
@ -128,7 +128,7 @@ int main(void) {
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand, .sizing = layoutExpand,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.childGap = 16 .childGap = 16
}) })
) { ) {
@ -141,7 +141,7 @@ int main(void) {
.height = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60),
.width = CLAY_SIZING_GROW(0) .width = CLAY_SIZING_GROW(0)
}, },
.padding = { 16 }, .padding = { 16, 16, 0, 0 },
.childGap = 16, .childGap = 16,
.childAlignment = { .childAlignment = {
.y = CLAY_ALIGN_Y_CENTER .y = CLAY_ALIGN_Y_CENTER
@ -151,10 +151,10 @@ int main(void) {
// Header buttons go here // Header buttons go here
CLAY( CLAY(
CLAY_ID("FileButton"), CLAY_ID("FileButton"),
CLAY_LAYOUT({ .padding = { 16, 8 }}), CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 }, .color = { 140, 140, 140, 255 },
.cornerRadius = 5 .cornerRadius = CLAY_CORNER_RADIUS(5)
}) })
) { ) {
CLAY_TEXT(CLAY_STRING("File"), CLAY_TEXT_CONFIG({ CLAY_TEXT(CLAY_STRING("File"), CLAY_TEXT_CONFIG({
@ -177,7 +177,7 @@ int main(void) {
}, },
}), }),
CLAY_LAYOUT({ CLAY_LAYOUT({
.padding = {0, 8 } .padding = {0, 0, 8, 8 }
}) })
) { ) {
CLAY( CLAY(
@ -189,7 +189,7 @@ int main(void) {
}), }),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.color = { 40, 40, 40, 255 }, .color = { 40, 40, 40, 255 },
.cornerRadius = 8 .cornerRadius = CLAY_CORNER_RADIUS(8)
}) })
) { ) {
// Render dropdown items here // Render dropdown items here
@ -216,7 +216,7 @@ int main(void) {
CLAY_RECTANGLE(contentBackgroundConfig), CLAY_RECTANGLE(contentBackgroundConfig),
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.childGap = 8, .childGap = 8,
.sizing = { .sizing = {
.width = CLAY_SIZING_FIXED(250), .width = CLAY_SIZING_FIXED(250),
@ -228,7 +228,7 @@ int main(void) {
Document document = documents.documents[i]; Document document = documents.documents[i];
Clay_LayoutConfig sidebarButtonLayout = { Clay_LayoutConfig sidebarButtonLayout = {
.sizing = { .width = CLAY_SIZING_GROW(0) }, .sizing = { .width = CLAY_SIZING_GROW(0) },
.padding = { 16, 16 } .padding = CLAY_PADDING_ALL(16)
}; };
if (i == selectedDocumentIndex) { if (i == selectedDocumentIndex) {
@ -236,7 +236,7 @@ int main(void) {
CLAY_LAYOUT(sidebarButtonLayout), CLAY_LAYOUT(sidebarButtonLayout),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.color = { 120, 120, 120, 255 }, .color = { 120, 120, 120, 255 },
.cornerRadius = 8, .cornerRadius = CLAY_CORNER_RADIUS(8),
}) })
) { ) {
CLAY_TEXT(document.title, CLAY_TEXT_CONFIG({ CLAY_TEXT(document.title, CLAY_TEXT_CONFIG({
@ -252,7 +252,7 @@ int main(void) {
Clay_Hovered() Clay_Hovered()
? CLAY_RECTANGLE({ ? CLAY_RECTANGLE({
.color = { 120, 120, 120, 120 }, .color = { 120, 120, 120, 120 },
.cornerRadius = 8 .cornerRadius = CLAY_CORNER_RADIUS(8)
}) })
: 0 : 0
) { ) {
@ -273,7 +273,7 @@ int main(void) {
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 16, .childGap = 16,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.sizing = layoutExpand .sizing = layoutExpand
}) })
) { ) {

View File

@ -7,7 +7,7 @@ Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
void RenderHeaderButton(Clay_String text) { void RenderHeaderButton(Clay_String text) {
CLAY( CLAY(
CLAY_LAYOUT({ .padding = { 16, 8 }}), CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({ CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 }, .color = { 140, 140, 140, 255 },
.cornerRadius = 5 .cornerRadius = 5
@ -22,7 +22,7 @@ void RenderHeaderButton(Clay_String text) {
} }
void RenderDropdownMenuItem(Clay_String text) { void RenderDropdownMenuItem(Clay_String text) {
CLAY(CLAY_LAYOUT({ .padding = { 16, 16 }})) { CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16)})) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ CLAY_TEXT(text, CLAY_TEXT_CONFIG({
.fontId = FONT_ID_BODY_16, .fontId = FONT_ID_BODY_16,
.fontSize = 16, .fontSize = 16,
@ -121,7 +121,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand, .sizing = layoutExpand,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.childGap = 16 .childGap = 16
}) })
) { ) {
@ -134,7 +134,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
CLAY_RECTANGLE(contentBackgroundConfig), CLAY_RECTANGLE(contentBackgroundConfig),
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.childGap = 8, .childGap = 8,
.sizing = { .sizing = {
.width = CLAY_SIZING_FIXED(250), .width = CLAY_SIZING_FIXED(250),
@ -146,7 +146,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
Document document = documents.documents[i]; Document document = documents.documents[i];
Clay_LayoutConfig sidebarButtonLayout = { Clay_LayoutConfig sidebarButtonLayout = {
.sizing = { .width = CLAY_SIZING_GROW() }, .sizing = { .width = CLAY_SIZING_GROW() },
.padding = { 16, 16 } .padding = CLAY_PADDING_ALL(16)
}; };
if (i == *documentIndex) { if (i == *documentIndex) {
@ -194,7 +194,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
CLAY_LAYOUT({ CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM, .layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 16, .childGap = 16,
.padding = { 16, 16 }, .padding = CLAY_PADDING_ALL(16),
.sizing = layoutExpand .sizing = layoutExpand
}) })
) { ) {
@ -247,7 +247,7 @@ int main(void) {
.height = GetScreenHeight() / 2 .height = GetScreenHeight() / 2
}, (Clay_ErrorHandler) { HandleClayErrors }); // This final argument is new since the video was published }, (Clay_ErrorHandler) { HandleClayErrors }); // This final argument is new since the video was published
Clay_SetMeasureTextFunction(Raylib_MeasureText); Clay_SetMeasureTextFunction(Raylib_MeasureText, 0);
Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) { Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) {
.font = LoadFontEx("resources/Roboto-Regular.ttf", 48, 0, 400), .font = LoadFontEx("resources/Roboto-Regular.ttf", 48, 0, 400),
.fontId = FONT_ID_BODY_16 .fontId = FONT_ID_BODY_16

View File

@ -24,12 +24,11 @@ target_compile_options(clay_examples_raylib_sidebar_scrolling_container PUBLIC)
target_include_directories(clay_examples_raylib_sidebar_scrolling_container PUBLIC .) target_include_directories(clay_examples_raylib_sidebar_scrolling_container PUBLIC .)
target_link_libraries(clay_examples_raylib_sidebar_scrolling_container PUBLIC raylib) target_link_libraries(clay_examples_raylib_sidebar_scrolling_container PUBLIC raylib)
if(MSVC) if(MSVC)
set(CMAKE_C_FLAGS_DEBUG "/D CLAY_DEBUG") set(CMAKE_C_FLAGS_DEBUG "/D CLAY_DEBUG")
else() else()
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror -Wno-error=missing-braces -DCLAY_DEBUG") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Werror -DCLAY_DEBUG -fsanitize=address")
set(CMAKE_C_FLAGS_RELEASE "-O3") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
endif() endif()
add_custom_command( add_custom_command(

View File

@ -21,14 +21,14 @@ void HandleHeaderButtonInteraction(Clay_ElementId elementId, Clay_PointerData po
// Examples of re-usable "Components" // Examples of re-usable "Components"
void RenderHeaderButton(Clay_String text) { void RenderHeaderButton(Clay_String text) {
CLAY(CLAY_LAYOUT({ .padding = {16, 8} }), CLAY(CLAY_LAYOUT({ .padding = {16, 16, 8, 8} }),
CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }), CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }),
Clay_OnHover(HandleHeaderButtonInteraction, 1)) { Clay_OnHover(HandleHeaderButtonInteraction, 1)) {
CLAY_TEXT(text, CLAY_TEXT_CONFIG(headerTextConfig)); CLAY_TEXT(text, CLAY_TEXT_CONFIG(headerTextConfig));
} }
} }
Clay_LayoutConfig dropdownTextItemLayout = { .padding = {8, 4} }; Clay_LayoutConfig dropdownTextItemLayout = { .padding = {8, 8, 4, 4} };
Clay_RectangleElementConfig dropdownRectangleConfig = { .color = {180, 180, 180, 255} }; Clay_RectangleElementConfig dropdownRectangleConfig = { .color = {180, 180, 180, 255} };
Clay_TextElementConfig dropdownTextElementConfig = { .fontSize = 24, .textColor = {255,255,255,255} }; Clay_TextElementConfig dropdownTextElementConfig = { .fontSize = 24, .textColor = {255,255,255,255} };
@ -40,9 +40,9 @@ void RenderDropdownTextItem(int index) {
Clay_RenderCommandArray CreateLayout() { Clay_RenderCommandArray CreateLayout() {
Clay_BeginLayout(); Clay_BeginLayout();
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }, .padding = { 16, 16 }, .childGap = 16 }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) { CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }, .padding = { 16, 16, 16, 16 }, .childGap = 16 }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {
CLAY(CLAY_ID("SideBar"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = {16, 16}, .childGap = 16 }), CLAY_RECTANGLE({ .color = {150, 150, 255, 255} })) { CLAY(CLAY_ID("SideBar"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = {16, 16, 16, 16 }, .childGap = 16 }), CLAY_RECTANGLE({ .color = {150, 150, 255, 255} })) {
CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = { 8, 8 }, .childGap = 8, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_RECTANGLE({ .color = {130, 130, 255, 255} })) { CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = { 8, 8, 8, 8 }, .childGap = 8, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_RECTANGLE({ .color = {130, 130, 255, 255} })) {
CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) } }), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {} CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) } }), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {}
CLAY_TEXT(profileText, CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0, 0, 0, 255} })); CLAY_TEXT(profileText, CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0, 0, 0, 255} }));
} }
@ -53,19 +53,19 @@ Clay_RenderCommandArray CreateLayout() {
} }
CLAY(CLAY_ID("RightPanel"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }, .childGap = 16 })) { CLAY(CLAY_ID("RightPanel"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }, .childGap = 16 })) {
CLAY(CLAY_ID("HeaderBar"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT }, .padding = {8, 8}, .childGap = 8 }), CLAY_RECTANGLE({ .color = {180, 180, 180, 255} })) { CLAY(CLAY_ID("HeaderBar"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT }, .padding = {8, 8, 8, 8 }, .childGap = 8 }), CLAY_RECTANGLE({ .color = {180, 180, 180, 255} })) {
RenderHeaderButton(CLAY_STRING("Header Item 1")); RenderHeaderButton(CLAY_STRING("Header Item 1"));
RenderHeaderButton(CLAY_STRING("Header Item 2")); RenderHeaderButton(CLAY_STRING("Header Item 2"));
RenderHeaderButton(CLAY_STRING("Header Item 3")); RenderHeaderButton(CLAY_STRING("Header Item 3"));
} }
CLAY(CLAY_ID("MainContent"), CLAY(CLAY_ID("MainContent"),
CLAY_SCROLL({ .vertical = true }), CLAY_SCROLL({ .vertical = true }),
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {16, 16}, .childGap = 16, .sizing = { CLAY_SIZING_GROW(0) } }), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {16, 16, 16, 16}, .childGap = 16, .sizing = { CLAY_SIZING_GROW(0) } }),
CLAY_RECTANGLE({ .color = {200, 200, 255, 255} })) CLAY_RECTANGLE({ .color = {200, 200, 255, 255} }))
{ {
CLAY(CLAY_ID("FloatingContainer"), CLAY(CLAY_ID("FloatingContainer"),
CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = { 16, 16 }}), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = { 16, 16, 16, 16 }}),
CLAY_FLOATING({ .zIndex = 1, .attachment = { CLAY_ATTACH_POINT_CENTER_TOP, CLAY_ATTACH_POINT_CENTER_TOP }, .offset = {0, -16} }), CLAY_FLOATING({ .zIndex = 1, .attachment = { CLAY_ATTACH_POINT_CENTER_TOP, CLAY_ATTACH_POINT_CENTER_TOP }, .offset = {0, 0} }),
CLAY_BORDER_OUTSIDE({ .color = {80, 80, 80, 255}, .width = 2 }), CLAY_BORDER_OUTSIDE({ .color = {80, 80, 80, 255}, .width = 2 }),
CLAY_RECTANGLE({ .color = {140,80, 200, 200 }}) CLAY_RECTANGLE({ .color = {140,80, 200, 200 }})
) { ) {
@ -75,7 +75,7 @@ Clay_RenderCommandArray CreateLayout() {
CLAY_TEXT(CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt."), CLAY_TEXT(CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt."),
CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {0,0,0,255} })); CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {0,0,0,255} }));
CLAY(CLAY_ID("Photos2"), CLAY_LAYOUT({ .childGap = 16, .padding = { 16, 16 }}), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) { CLAY(CLAY_ID("Photos2"), CLAY_LAYOUT({ .childGap = 16, .padding = { 16, 16, 16, 16 }}), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) {
CLAY(CLAY_ID("Picture4"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {} CLAY(CLAY_ID("Picture4"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
CLAY(CLAY_ID("Picture5"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {} CLAY(CLAY_ID("Picture5"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
CLAY(CLAY_ID("Picture6"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {} CLAY(CLAY_ID("Picture6"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
@ -87,9 +87,9 @@ Clay_RenderCommandArray CreateLayout() {
CLAY_TEXT(CLAY_STRING("Suspendisse in est ante in nibh. Amet venenatis urna cursus eget nunc scelerisque viverra. Elementum sagittis vitae et leo duis ut diam quam nulla. Enim nulla aliquet porttitor lacus. Pellentesque habitant morbi tristique senectus et. Facilisi nullam vehicula ipsum a arcu cursus vitae.\nSem fringilla ut morbi tincidunt. Euismod quis viverra nibh cras pulvinar mattis nunc sed. Velit sed ullamcorper morbi tincidunt ornare massa. Varius quam quisque id diam vel quam. Nulla pellentesque dignissim enim sit amet venenatis. Enim lobortis scelerisque fermentum dui faucibus in. Pretium viverra suspendisse potenti nullam ac tortor vitae. Lectus vestibulum mattis ullamcorper velit sed. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum. Habitant morbi tristique senectus et. Integer vitae justo eget magna fermentum iaculis eu. Semper quis lectus nulla at volutpat diam. Enim praesent elementum facilisis leo. Massa vitae tortor condimentum lacinia quis vel."), CLAY_TEXT(CLAY_STRING("Suspendisse in est ante in nibh. Amet venenatis urna cursus eget nunc scelerisque viverra. Elementum sagittis vitae et leo duis ut diam quam nulla. Enim nulla aliquet porttitor lacus. Pellentesque habitant morbi tristique senectus et. Facilisi nullam vehicula ipsum a arcu cursus vitae.\nSem fringilla ut morbi tincidunt. Euismod quis viverra nibh cras pulvinar mattis nunc sed. Velit sed ullamcorper morbi tincidunt ornare massa. Varius quam quisque id diam vel quam. Nulla pellentesque dignissim enim sit amet venenatis. Enim lobortis scelerisque fermentum dui faucibus in. Pretium viverra suspendisse potenti nullam ac tortor vitae. Lectus vestibulum mattis ullamcorper velit sed. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum. Habitant morbi tristique senectus et. Integer vitae justo eget magna fermentum iaculis eu. Semper quis lectus nulla at volutpat diam. Enim praesent elementum facilisis leo. Massa vitae tortor condimentum lacinia quis vel."),
CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0,0,0,255} })); CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0,0,0,255} }));
CLAY(CLAY_ID("Photos"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) { CLAY(CLAY_ID("Photos"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = {16, 16, 16, 16} }), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) {
CLAY(CLAY_ID("Picture2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {} CLAY(CLAY_ID("Picture2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
CLAY(CLAY_ID("Picture1"), CLAY_LAYOUT({ .childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {8, 8} }), CLAY_RECTANGLE({ .color = {170, 170, 220, 255} })) { CLAY(CLAY_ID("Picture1"), CLAY_LAYOUT({ .childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {8, 8, 8, 8} }), CLAY_RECTANGLE({ .color = {170, 170, 220, 255} })) {
CLAY(CLAY_ID("ProfilePicture2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {} CLAY(CLAY_ID("ProfilePicture2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {}
CLAY_TEXT(CLAY_STRING("Image caption below"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0,0,0,255} })); CLAY_TEXT(CLAY_STRING("Image caption below"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0,0,0,255} }));
} }
@ -104,7 +104,7 @@ Clay_RenderCommandArray CreateLayout() {
CLAY(CLAY_ID("Blob4Floating2"), CLAY_FLOATING({ .zIndex = 1, .parentId = Clay_GetElementId(CLAY_STRING("SidebarBlob4")).id })) { CLAY(CLAY_ID("Blob4Floating2"), CLAY_FLOATING({ .zIndex = 1, .parentId = Clay_GetElementId(CLAY_STRING("SidebarBlob4")).id })) {
CLAY(CLAY_ID("ScrollContainer"), CLAY_LAYOUT({ .sizing = { .height = CLAY_SIZING_FIXED(200) }, .childGap = 2 }), CLAY_SCROLL({ .vertical = true })) { CLAY(CLAY_ID("ScrollContainer"), CLAY_LAYOUT({ .sizing = { .height = CLAY_SIZING_FIXED(200) }, .childGap = 2 }), CLAY_SCROLL({ .vertical = true })) {
CLAY(CLAY_ID("FloatingContainer2"), CLAY_LAYOUT({ }), CLAY_FLOATING({ .zIndex = 1 })) { CLAY(CLAY_ID("FloatingContainer2"), CLAY_LAYOUT({ }), CLAY_FLOATING({ .zIndex = 1 })) {
CLAY(CLAY_ID("FloatingContainerInner"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = {140,80, 200, 200} })) { CLAY(CLAY_ID("FloatingContainerInner"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = {16, 16, 16, 16} }), CLAY_RECTANGLE({ .color = {140,80, 200, 200} })) {
CLAY_TEXT(CLAY_STRING("I'm an inline floating container."), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255,255,255,255} })); CLAY_TEXT(CLAY_STRING("I'm an inline floating container."), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255,255,255,255} }));
} }
} }
@ -218,8 +218,8 @@ void HandleClayErrors(Clay_ErrorData errorData) {
int main(void) { int main(void) {
uint64_t totalMemorySize = Clay_MinMemorySize(); uint64_t totalMemorySize = Clay_MinMemorySize();
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize)); Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
Clay_SetMeasureTextFunction(Raylib_MeasureText);
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() }, (Clay_ErrorHandler) { HandleClayErrors }); Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() }, (Clay_ErrorHandler) { HandleClayErrors });
Clay_SetMeasureTextFunction(Raylib_MeasureText, 0);
Clay_Raylib_Initialize(1024, 768, "Clay - Raylib Renderer Example", FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT); Clay_Raylib_Initialize(1024, 768, "Clay - Raylib Renderer Example", FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT);
profilePicture = LoadTextureFromImage(LoadImage("resources/profile-picture.png")); profilePicture = LoadTextureFromImage(LoadImage("resources/profile-picture.png"));
Raylib_fonts[FONT_ID_BODY_24] = (Raylib_Font) { Raylib_fonts[FONT_ID_BODY_24] = (Raylib_Font) {

View File

@ -1,7 +1,5 @@
Please note, the SDL2 renderer is not 100% feature complete. It is currently missing: Please note, the SDL2 renderer is not 100% feature complete. It is currently missing:
- Border rendering
- Image rendering
- Rounded rectangle corners - Rounded rectangle corners
Note: on Mac OSX, SDL2 for some reason decides to automatically disable momentum scrolling on macbook trackpads. Note: on Mac OSX, SDL2 for some reason decides to automatically disable momentum scrolling on macbook trackpads.
@ -10,4 +8,4 @@ You can re enable it in objective C using:
```C ```C
[[NSUserDefaults standardUserDefaults] setBool: YES [[NSUserDefaults standardUserDefaults] setBool: YES
forKey: @"AppleMomentumScrollSupported"]; forKey: @"AppleMomentumScrollSupported"];
``` ```

View File

@ -1,21 +1,25 @@
#include "../../clay.h" #include "../../clay.h"
#include <SDL.h> #include <SDL.h>
#include <SDL_ttf.h> #include <SDL_ttf.h>
#include <SDL_image.h>
#include <stdio.h> #include <stdio.h>
#define CLAY_COLOR_TO_SDL_COLOR_ARGS(color) color.r, color.g, color.b, color.a
typedef struct typedef struct
{ {
uint32_t fontId; uint32_t fontId;
TTF_Font *font; TTF_Font *font;
} SDL2_Font; } SDL2_Font;
static SDL2_Font SDL2_fonts[1];
static Clay_Dimensions SDL2_MeasureText(Clay_String *text, Clay_TextElementConfig *config) static Clay_Dimensions SDL2_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData)
{ {
TTF_Font *font = SDL2_fonts[config->fontId].font; SDL2_Font *fonts = (SDL2_Font*)userData;
char *chars = (char *)calloc(text->length + 1, 1);
memcpy(chars, text->chars, text->length); TTF_Font *font = fonts[config->fontId].font;
char *chars = (char *)calloc(text.length + 1, 1);
memcpy(chars, text.chars, text.length);
int width = 0; int width = 0;
int height = 0; int height = 0;
if (TTF_SizeUTF8(font, chars, &width, &height) < 0) { if (TTF_SizeUTF8(font, chars, &width, &height) < 0) {
@ -31,7 +35,7 @@ static Clay_Dimensions SDL2_MeasureText(Clay_String *text, Clay_TextElementConfi
SDL_Rect currentClippingRectangle; SDL_Rect currentClippingRectangle;
static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray renderCommands) static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray renderCommands, SDL2_Font *fonts)
{ {
for (uint32_t i = 0; i < renderCommands.length; i++) for (uint32_t i = 0; i < renderCommands.length; i++)
{ {
@ -57,7 +61,7 @@ static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray ren
Clay_String text = renderCommand->text; Clay_String text = renderCommand->text;
char *cloned = (char *)calloc(text.length + 1, 1); char *cloned = (char *)calloc(text.length + 1, 1);
memcpy(cloned, text.chars, text.length); memcpy(cloned, text.chars, text.length);
TTF_Font* font = SDL2_fonts[config->fontId].font; TTF_Font* font = fonts[config->fontId].font;
SDL_Surface *surface = TTF_RenderUTF8_Blended(font, cloned, (SDL_Color) { SDL_Surface *surface = TTF_RenderUTF8_Blended(font, cloned, (SDL_Color) {
.r = (Uint8)config->textColor.r, .r = (Uint8)config->textColor.r,
.g = (Uint8)config->textColor.g, .g = (Uint8)config->textColor.g,
@ -93,10 +97,55 @@ static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray ren
SDL_RenderSetClipRect(renderer, NULL); SDL_RenderSetClipRect(renderer, NULL);
break; break;
} }
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
SDL_Surface *image = (SDL_Surface *)renderCommand->config.imageElementConfig->imageData;
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image);
SDL_Rect destination = (SDL_Rect){
.x = boundingBox.x,
.y = boundingBox.y,
.w = boundingBox.width,
.h = boundingBox.height,
};
SDL_RenderCopy(renderer, texture, NULL, &destination);
break;
}
case CLAY_RENDER_COMMAND_TYPE_BORDER: {
Clay_BorderElementConfig *config = renderCommand->config.borderElementConfig;
if (config->left.width > 0) {
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->left.color));
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x, boundingBox.y + config->cornerRadius.topLeft, config->left.width, boundingBox.height - config->cornerRadius.topLeft - config->cornerRadius.bottomLeft });
}
if (config->right.width > 0) {
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color));
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + boundingBox.width - config->right.width, boundingBox.y + config->cornerRadius.topRight, config->right.width, boundingBox.height - config->cornerRadius.topRight - config->cornerRadius.bottomRight });
}
if (config->right.width > 0) {
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color));
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + boundingBox.width - config->right.width, boundingBox.y + config->cornerRadius.topRight, config->right.width, boundingBox.height - config->cornerRadius.topRight - config->cornerRadius.bottomRight });
}
if (config->top.width > 0) {
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color));
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + config->cornerRadius.topLeft, boundingBox.y, boundingBox.width - config->cornerRadius.topLeft - config->cornerRadius.topRight, config->top.width });
}
if (config->bottom.width > 0) {
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->bottom.color));
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + config->cornerRadius.bottomLeft, boundingBox.y + boundingBox.height - config->bottom.width, boundingBox.width - config->cornerRadius.bottomLeft - config->cornerRadius.bottomRight, config->bottom.width });
}
break;
}
default: { default: {
fprintf(stderr, "Error: unhandled render command: %d\n", renderCommand->commandType); fprintf(stderr, "Error: unhandled render command: %d\n", renderCommand->commandType);
exit(1); exit(1);
} }
} }
} }
} }

6
renderers/SDL3/README Normal file
View File

@ -0,0 +1,6 @@
Please note, the SDL3 renderer is not 100% feature complete. It is currently missing:
- Rounded rectangle corners
- Borders
- Images
- Scroll / Scissor handling

View File

@ -0,0 +1,41 @@
#include "../../clay.h"
#include <SDL3/SDL_main.h>
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
/* This needs to be global because the "MeasureText" callback doesn't have a
* user data parameter */
static TTF_Font *gFonts[1];
static void SDL_RenderClayCommands(SDL_Renderer *renderer, Clay_RenderCommandArray *rcommands)
{
for (size_t i = 0; i < rcommands->length; i++) {
Clay_RenderCommand *rcmd = Clay_RenderCommandArray_Get(rcommands, i);
Clay_BoundingBox bounding_box = rcmd->boundingBox;
const SDL_FRect rect = { bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height };
switch (rcmd->commandType) {
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
Clay_RectangleElementConfig *config = rcmd->config.rectangleElementConfig;
Clay_Color color = config->color;
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_RenderFillRect(renderer, &rect);
} break;
case CLAY_RENDER_COMMAND_TYPE_TEXT: {
Clay_TextElementConfig *config = rcmd->config.textElementConfig;
Clay_String *text = &rcmd->text;
SDL_Color color = { config->textColor.r, config->textColor.g, config->textColor.b, config->textColor.a };
TTF_Font *font = gFonts[config->fontId];
SDL_Surface *surface = TTF_RenderText_Blended(font, text->chars, text->length, color);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_RenderTexture(renderer, texture, NULL, &rect);
SDL_DestroySurface(surface);
SDL_DestroyTexture(texture);
} break;
default:
SDL_Log("Unknown render command type: %d", rcmd->commandType);
}
}
}

View File

@ -83,7 +83,7 @@ static inline char *Clay_Cairo__NullTerminate(Clay_String *str) {
} }
// Measure text using cairo's *toy* text API. // Measure text using cairo's *toy* text API.
static inline Clay_Dimensions Clay_Cairo_MeasureText(Clay_String *str, Clay_TextElementConfig *config) { static inline Clay_Dimensions Clay_Cairo_MeasureText(Clay_String *str, Clay_TextElementConfig *config, uintptr_t userData) {
// Edge case: Clay computes the width of a whitespace character // Edge case: Clay computes the width of a whitespace character
// once. Cairo does not factor in whitespaces when computing text // once. Cairo does not factor in whitespaces when computing text
// extents, this edge-case serves as a short-circuit to introduce // extents, this edge-case serves as a short-circuit to introduce

View File

@ -89,7 +89,7 @@ Ray GetScreenToWorldPointWithZDistance(Vector2 position, Camera camera, int scre
uint32_t measureCalls = 0; uint32_t measureCalls = 0;
static inline Clay_Dimensions Raylib_MeasureText(Clay_String *text, Clay_TextElementConfig *config) { static inline Clay_Dimensions Raylib_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData) {
measureCalls++; measureCalls++;
// Measure string size for Font // Measure string size for Font
Clay_Dimensions textSize = { 0 }; Clay_Dimensions textSize = { 0 };
@ -101,14 +101,14 @@ static inline Clay_Dimensions Raylib_MeasureText(Clay_String *text, Clay_TextEle
Font fontToUse = Raylib_fonts[config->fontId].font; Font fontToUse = Raylib_fonts[config->fontId].font;
float scaleFactor = config->fontSize/(float)fontToUse.baseSize; float scaleFactor = config->fontSize/(float)fontToUse.baseSize;
for (int i = 0; i < text->length; ++i) for (int i = 0; i < text.length; ++i)
{ {
if (text->chars[i] == '\n') { if (text.chars[i] == '\n') {
maxTextWidth = fmax(maxTextWidth, lineTextWidth); maxTextWidth = fmax(maxTextWidth, lineTextWidth);
lineTextWidth = 0; lineTextWidth = 0;
continue; continue;
} }
int index = text->chars[i] - 32; int index = text.chars[i] - 32;
if (fontToUse.glyphs[index].advanceX != 0) lineTextWidth += fontToUse.glyphs[index].advanceX; if (fontToUse.glyphs[index].advanceX != 0) lineTextWidth += fontToUse.glyphs[index].advanceX;
else lineTextWidth += (fontToUse.recs[index].width + fontToUse.glyphs[index].offsetX); else lineTextWidth += (fontToUse.recs[index].width + fontToUse.glyphs[index].offsetX);
} }