Compare commits

...

10 Commits

Author SHA1 Message Date
phyxl
8320d44077
Merge d7104efa69 into 814c9392c6 2025-01-14 20:43:12 +08:00
Nic Barker
814c9392c6
[Core] Add API to query element bounding boxes (#199)
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Waiting to run
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Failing after 12s
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Failing after 13s
Co-authored-by: hexmaster111 <hailey@not-an-email-address.fake>
2025-01-14 22:09:06 +13:00
Nic Barker
338852b3ce Fix a bug with the new padding
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Waiting to run
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Failing after 12s
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Failing after 13s
2025-01-14 14:26:30 +13:00
Nic Barker
f1d8a53a32
[Core] [Breaking] Split padding values into left, right, top, bottom (#195) 2025-01-14 10:38:02 +13:00
phyxl
d7104efa69
Merge branch 'main' into feature/terminal-renderer 2025-01-11 22:01:09 -05:00
Phillip Cook
c8341dc0a8 fix typo, remove generated Makefile, correct CMakeLists 2025-01-05 22:22:44 -05:00
Phillip Cook
244395edde rename to ncurses to follow convention, clean up checked in files 2025-01-05 22:19:03 -05:00
Phillip Cook
b0b0e15df5 clean up some files 2025-01-05 21:48:00 -05:00
Phillip Cook
286c0753fd Merge branch 'main' into feature/terminal-renderer 2025-01-05 21:40:03 -05:00
Phillip Cook
77d3fc4e82 implemented ncurses termninal renderer 2025-01-05 21:38:02 -05:00
23 changed files with 675 additions and 158 deletions

View File

@ -9,6 +9,7 @@ add_subdirectory("examples/raylib-sidebar-scrolling-container")
# add_subdirectory("examples/cairo-pdf-rendering") Some issue with github actions populating cairo, disable for now
if(NOT MSVC)
add_subdirectory("examples/clay-official-website")
add_subdirectory("examples/ncurses-sidebar-scrolling-container")
endif()
add_subdirectory("examples/introducing-clay-video-demo")
add_subdirectory("examples/SDL2-video-demo")

View File

@ -94,12 +94,12 @@ Clay_RenderCommandArray CreateLayout() {
Clay_BeginLayout();
// 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_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(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_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.
```C
// Parent element with 8px of padding
CLAY(CLAY_LAYOUT({ .padding = 8 })) {
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8) })) {
// Child element 1
CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 }));
// 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
void ButtonComponent(Clay_String buttonText) {
// 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);
}
}
@ -259,11 +259,11 @@ CLAY(CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
### Configuring Layout and Styling UI Elements
The layout of clay elements is configured with the `CLAY_LAYOUT()` macro.
```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
}
```
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.
@ -333,7 +333,7 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerI
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
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);
}
```
@ -703,7 +703,7 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerD
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
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);
}
```
@ -749,7 +749,7 @@ Returns a [Clay_ElementId](#clay_elementid) for the provided id string, used for
**Examples**
```C
// 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
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
@ -789,7 +789,7 @@ To regenerate the same ID outside of layout declaration when using utility funct
// Tag a button with the Id "Button"
CLAY(
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
}
@ -832,7 +832,7 @@ An offset version of [CLAY_ID](#clay_id). Generates a [Clay_ElementId](#clay_ele
Clay_LayoutConfig {
Clay_LayoutDirection layoutDirection = CLAY_LEFT_TO_RIGHT (default) | CLAY_TOP_TO_BOTTOM;
Clay_Padding padding {
float x; float y;
u16 left; u16 right; u16 top; u16 bottom;
};
uint16_t childGap;
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`
`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**
```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
}
```
@ -1586,17 +1586,17 @@ Controls whether pointer events like hover and click should pass through to cont
```C
// Horizontal container with three option buttons
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_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());
// 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_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());
}
}

View File

@ -223,8 +223,10 @@ Sizing :: struct {
}
Padding :: struct {
x: u16,
y: u16,
left: u16,
right: u16,
top: u16,
bottom: u16,
}
LayoutDirection :: enum EnumBackingType {
@ -350,6 +352,10 @@ Layout :: proc(config: LayoutConfig) -> TypedConfig {
return {type = ElementConfigType.Layout, config = _StoreLayoutConfig(config) }
}
PaddingAll :: proc (padding: u16) -> Padding {
return { padding, padding, padding, padding }
}
Rectangle :: proc(config: RectangleElementConfig) -> TypedConfig {
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) {
if clay.UI(
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),
) {
if clay.UI(
@ -75,11 +75,11 @@ LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Colo
LandingPageDesktop :: proc() {
if clay.UI(
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(
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}}),
) {
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,
sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})},
childAlignment = {x = .CENTER, y = .CENTER},
padding = {16, 32},
padding = {16, 16, 32, 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})
if clay.UI(
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("~2000 lines of C99.", textConfig)
@ -158,7 +158,7 @@ FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) {
}
if clay.UI(
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("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() {
if clay.UI(
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(
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}}),
) {
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,
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
childAlignment = {x = .CENTER, y = .CENTER},
padding = {16, 32},
padding = {16, 16, 32, 32},
childGap = 16,
},
),
@ -277,14 +277,14 @@ HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementCon
) {
if clay.UI(
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.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT}))
}
if clay.UI(
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.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(
clay.ID("PerformanceDesktop"),
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}),
) {
@ -313,7 +313,7 @@ HighPerformancePageMobile :: proc(lerpValue: f32) {
layoutDirection = .TOP_TO_BOTTOM,
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
childAlignment = {x = .CENTER, y = .CENTER},
padding = {x = 16, y = 32},
padding = { 16, 16, 32, 32},
childGap = 32,
},
),
@ -325,7 +325,7 @@ HighPerformancePageMobile :: proc(lerpValue: f32) {
RendererButtonActive :: proc(index: i32, text: string) {
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.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.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.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() {
if clay.UI(
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(
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}}),
) {
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,
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
childAlignment = {x = .CENTER, y = .CENTER},
padding = {x = 16, y = 32},
padding = {16, 16, 32, 32},
childGap = 32,
},
),
@ -423,7 +423,7 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
) {
if clay.UI(
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)
if clay.UI(clay.Layout({sizing = {width = clay.SizingGrow({})}})) {}
@ -438,7 +438,7 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
}
if clay.UI(
clay.ID("LinkGithubOuter"),
clay.Layout({padding = {16, 6}}),
clay.Layout({padding = {16, 16, 6, 6}}),
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})
) {

122
clay.h
View File

@ -70,6 +70,8 @@
#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_GROW(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_GROW })
@ -289,8 +291,10 @@ CLAY__TYPEDEF(Clay_Sizing, struct {
});
CLAY__TYPEDEF(Clay_Padding, struct {
uint16_t x;
uint16_t y;
uint16_t left;
uint16_t right;
uint16_t top;
uint16_t bottom;
});
CLAY__TYPEDEF(Clay_LayoutConfig, struct {
@ -439,6 +443,13 @@ CLAY__TYPEDEF(Clay_ScrollContainerData, struct {
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_RENDER_COMMAND_TYPE_NONE,
CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
@ -511,6 +522,7 @@ void Clay_BeginLayout(void);
Clay_RenderCommandArray Clay_EndLayout(void);
Clay_ElementId Clay_GetElementId(Clay_String idString);
Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index);
Clay_ElementData Clay_GetElementData (Clay_ElementId id);
bool Clay_Hovered(void);
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData), intptr_t userData);
bool Clay_PointerOver(Clay_ElementId elementId);
@ -1921,18 +1933,18 @@ void Clay__CloseElement(void) {
// Attach children to the current open element
openLayoutElement->childrenOrTextContent.children.elements = &context->layoutElementChildren.internalArray[context->layoutElementChildren.length];
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++) {
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);
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
if (!elementHasScrollHorizontal) {
openLayoutElement->minDimensions.width += child->minDimensions.width;
}
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);
}
@ -1941,18 +1953,18 @@ void Clay__CloseElement(void) {
openLayoutElement->minDimensions.width += childGap;
}
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++) {
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);
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
if (!elementHasScrollVertical) {
openLayoutElement->minDimensions.height += child->minDimensions.height;
}
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);
}
@ -2183,8 +2195,8 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
Clay_LayoutConfig *parentStyleConfig = parent->layoutConfig;
int32_t growContainerCount = 0;
float parentSize = xAxis ? parent->dimensions.width : parent->dimensions.height;
float parentPadding = (float)(xAxis ? parent->layoutConfig->padding.x : parent->layoutConfig->padding.y);
float innerContentSize = 0, growContainerContentSize = 0, totalPaddingAndChildGaps = parentPadding * 2;
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;
bool sizingAlongAxis = (xAxis && parentStyleConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) || (!xAxis && parentStyleConfig->layoutDirection == CLAY_TOP_TO_BOTTOM);
resizableContainerBuffer.length = 0;
float parentChildGap = parentStyleConfig->childGap;
@ -2239,7 +2251,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
}
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
if (sizeToDistribute < 0) {
// If the parent can scroll in the axis direction in this direction, don't compress children, just leave them alone
@ -2284,7 +2296,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
float maxSize = parentSize - parentPadding * 2;
float maxSize = parentSize - parentPadding;
if (Clay__ElementHasConfig(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER)) {
Clay_ScrollElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig;
if (((xAxis && scrollElementConfig->horizontal) || (!xAxis && scrollElementConfig->vertical))) {
@ -2461,12 +2473,12 @@ void Clay__CalculateFinalLayout() {
// 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) {
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);
}
} else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
// 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) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
contentHeight += childElement->dimensions.height;
@ -2585,7 +2597,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;
while (dfsBuffer.length > 0) {
@ -2750,7 +2762,7 @@ void Clay__CalculateFinalLayout() {
contentSize.height = CLAY__MAX(contentSize.height, childElement->dimensions.height);
}
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) {
case CLAY_ALIGN_X_LEFT: extraSpace = 0; break;
case CLAY_ALIGN_X_CENTER: extraSpace /= 2; break;
@ -2764,7 +2776,7 @@ void Clay__CalculateFinalLayout() {
contentSize.height += childElement->dimensions.height;
}
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) {
case CLAY_ALIGN_Y_TOP: extraSpace = 0; break;
case CLAY_ALIGN_Y_CENTER: extraSpace /= 2; break;
@ -2774,7 +2786,7 @@ void Clay__CalculateFinalLayout() {
}
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 +2826,7 @@ void Clay__CalculateFinalLayout() {
if (borderConfig->betweenChildren.width > 0 && borderConfig->betweenChildren.color.a > 0) {
Clay_RectangleElementConfig *rectangleConfig = Clay__StoreRectangleElementConfig(CLAY__INIT(Clay_RectangleElementConfig) {.color = borderConfig->betweenChildren.color});
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) {
for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
@ -2864,16 +2876,16 @@ void Clay__CalculateFinalLayout() {
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
// Alignment along non layout axis
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
currentElementTreeNode->nextChildOffset.y = currentElement->layoutConfig->padding.y;
float whiteSpaceAroundChild = currentElement->dimensions.height - (float)currentElement->layoutConfig->padding.y * 2 - childElement->dimensions.height;
currentElementTreeNode->nextChildOffset.y = currentElement->layoutConfig->padding.top;
float whiteSpaceAroundChild = currentElement->dimensions.height - (float)(layoutConfig->padding.top + layoutConfig->padding.bottom) - childElement->dimensions.height;
switch (layoutConfig->childAlignment.y) {
case CLAY_ALIGN_Y_TOP: break;
case CLAY_ALIGN_Y_CENTER: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild / 2; break;
case CLAY_ALIGN_Y_BOTTOM: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild; break;
}
} else {
currentElementTreeNode->nextChildOffset.x = currentElement->layoutConfig->padding.x;
float whiteSpaceAroundChild = currentElement->dimensions.width - (float)currentElement->layoutConfig->padding.x * 2 - childElement->dimensions.width;
currentElementTreeNode->nextChildOffset.x = currentElement->layoutConfig->padding.left;
float whiteSpaceAroundChild = currentElement->dimensions.width - (float)(layoutConfig->padding.left + layoutConfig->padding.right) - childElement->dimensions.width;
switch (layoutConfig->childAlignment.x) {
case CLAY_ALIGN_X_LEFT: break;
case CLAY_ALIGN_X_CENTER: currentElementTreeNode->nextChildOffset.x += whiteSpaceAroundChild / 2; break;
@ -2891,7 +2903,7 @@ void Clay__CalculateFinalLayout() {
dfsBuffer.internalArray[newNodeIndex] = CLAY__INIT(Clay__LayoutElementTreeNode) {
.layoutElement = childElement,
.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;
@ -3046,12 +3058,12 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
// Collisions and offscreen info
if (currentElementData) {
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 }));
}
}
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 }));
}
}
@ -3065,7 +3077,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(elementConfig->type);
Clay_Color backgroundColor = config.color;
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 }));
}
}
@ -3087,7 +3099,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
}
} else if (currentElement->childrenOrTextContent.children.length > 0) {
Clay__OpenElement();
CLAY_LAYOUT({ .padding = { 8 , 0} });
CLAY_LAYOUT({ .padding = { 8 } });
Clay__ElementPostConfiguration();
Clay__OpenElement();
CLAY_BORDER({ .left = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }});
@ -3157,8 +3169,8 @@ void Clay__RenderDebugViewElementConfigHeader(Clay_String elementId, Clay__Eleme
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(type);
Clay_Color backgroundColor = config.color;
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({ .padding = { 8, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) {
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, 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(CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {}
@ -3260,7 +3272,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_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(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
// Close button
@ -3278,7 +3290,7 @@ void Clay__RenderDebugView() {
Clay_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0, 0);
// 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_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);
}
}
@ -3307,7 +3319,7 @@ void Clay__RenderDebugView() {
CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 }),
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(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
if (selectedItem->elementId.stringId.length != 0) {
@ -3319,8 +3331,9 @@ void Clay__RenderDebugView() {
}
}
}
Clay_Padding attributeConfigPadding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 8, 8};
// 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
CLAY_TEXT(CLAY_STRING("Bounding Box"), infoTitleConfig);
CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) {
@ -3351,10 +3364,14 @@ void Clay__RenderDebugView() {
// .padding
CLAY_TEXT(CLAY_STRING("Padding"), infoTitleConfig);
CLAY(CLAY_ID("Clay__DebugViewElementInfoPadding")) {
CLAY_TEXT(CLAY_STRING("{ x: "), infoTextConfig);
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.x), infoTextConfig);
CLAY_TEXT(CLAY_STRING(", y: "), infoTextConfig);
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.y), infoTextConfig);
CLAY_TEXT(CLAY_STRING("{ left: "), infoTextConfig);
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.left), infoTextConfig);
CLAY_TEXT(CLAY_STRING(", right: "), 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);
}
// .childGap
@ -3388,7 +3405,7 @@ void Clay__RenderDebugView() {
switch (elementConfig->type) {
case CLAY__ELEMENT_CONFIG_TYPE_RECTANGLE: {
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
CLAY_TEXT(CLAY_STRING("Color"), infoTitleConfig);
Clay__RenderDebugViewColor(rectangleConfig->color, infoTextConfig);
@ -3400,7 +3417,7 @@ void Clay__RenderDebugView() {
}
case CLAY__ELEMENT_CONFIG_TYPE_TEXT: {
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
CLAY_TEXT(CLAY_STRING("Font Size"), infoTitleConfig);
CLAY_TEXT(Clay__IntToString(textConfig->fontSize), infoTextConfig);
@ -3430,7 +3447,7 @@ void Clay__RenderDebugView() {
}
case CLAY__ELEMENT_CONFIG_TYPE_IMAGE: {
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
CLAY_TEXT(CLAY_STRING("Source Dimensions"), infoTitleConfig);
CLAY(CLAY_ID("Clay__DebugViewElementInfoImageDimensions")) {
@ -3448,7 +3465,7 @@ void Clay__RenderDebugView() {
}
case CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER: {
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
CLAY_TEXT(CLAY_STRING("Vertical"), infoTitleConfig);
CLAY_TEXT(scrollConfig->vertical ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig);
@ -3460,7 +3477,7 @@ void Clay__RenderDebugView() {
}
case CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER: {
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
CLAY_TEXT(CLAY_STRING("Offset"), infoTitleConfig);
CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) {
@ -3491,7 +3508,7 @@ void Clay__RenderDebugView() {
}
case CLAY__ELEMENT_CONFIG_TYPE_BORDER_CONTAINER: {
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
CLAY_TEXT(CLAY_STRING("Left Border"), infoTitleConfig);
Clay__RenderDebugViewBorder(1, borderConfig->left, infoTextConfig);
@ -3521,14 +3538,14 @@ void Clay__RenderDebugView() {
} 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_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(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;
for (int32_t i = 0; i < previousWarningsLength; 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);
if (warning.dynamicMessage.length > 0) {
CLAY_TEXT(warning.dynamicMessage, warningConfig);
@ -3996,6 +4013,19 @@ Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
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")
void Clay_SetDebugModeEnabled(bool enabled) {
Clay_Context* context = Clay_GetCurrentContext();

View File

@ -10,13 +10,12 @@
#include <stdint.h>
#include <stdlib.h>
const int FONT_ID_BODY_16 = 0;
Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
void RenderHeaderButton(Clay_String text) {
CLAY(
CLAY_LAYOUT({ .padding = { 16, 8 }}),
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 },
.cornerRadius = 5
@ -31,7 +30,7 @@ void RenderHeaderButton(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({
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
@ -91,7 +90,7 @@ static Clay_RenderCommandArray CreateLayout() {
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.childGap = 16
})
) {
@ -179,7 +178,7 @@ static Clay_RenderCommandArray CreateLayout() {
CLAY_RECTANGLE(contentBackgroundConfig),
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.childGap = 8,
.sizing = {
.width = CLAY_SIZING_FIXED(250),
@ -191,7 +190,7 @@ static Clay_RenderCommandArray CreateLayout() {
Document document = documents.documents[i];
Clay_LayoutConfig sidebarButtonLayout = {
.sizing = { .width = CLAY_SIZING_GROW(0) },
.padding = { 16, 16 }
.padding = CLAY_PADDING_ALL(16)
};
if (i == selectedDocumentIndex) {
@ -236,7 +235,7 @@ static Clay_RenderCommandArray CreateLayout() {
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 16,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.sizing = layoutExpand
})
) {

View File

@ -42,7 +42,7 @@ void Layout() {
CLAY_RECTANGLE({ .color = BACKGROUND })) {
CLAY(CLAY_ID("PageMargins"),
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,
.childGap = 10})) {
@ -62,7 +62,7 @@ void Layout() {
.color = ACCENT,
.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_CONFIG({ .textColor = PRIMARY, .fontSize = 14, .fontFamily = CLAY_STRING("Quicksand SemiBold") }));
CLAY_TEXT(CLAY_STRING("- Declarative syntax"),
@ -77,7 +77,7 @@ void Layout() {
}
CLAY(CLAY_LAYOUT({
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
.padding = { 10, 10 },
.padding = CLAY_PADDING_ALL(10),
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },
.childGap = 4
@ -85,7 +85,7 @@ void Layout() {
// Profile picture
CLAY(CLAY_LAYOUT({
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
.padding = { 30, 0 },
.padding = { 30, 30, 0, 0 },
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.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") }));
@ -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_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. "
"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. "

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} };
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_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = fontSize, .fontId = FONT_ID_BODY_24, .textColor = color }));
}
}
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("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("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 = 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_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) } })) {}
@ -67,7 +67,7 @@ void LandingPageDesktop() {
}
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_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) } })) {}
@ -87,14 +87,14 @@ void FeatureBlocksDesktop() {
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_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_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("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("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);
@ -106,14 +106,14 @@ void FeatureBlocksDesktop() {
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_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_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("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("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);
@ -122,8 +122,8 @@ void FeatureBlocksMobile() {
}
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("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("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 = 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_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) } })) {}
@ -139,7 +139,7 @@ void DeclarativeSyntaxPageDesktop() {
}
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_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) } })) {}
@ -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.");
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_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) }})) {}
@ -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_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(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 }));
}
}
@ -187,7 +187,7 @@ void HighPerformancePageDesktop(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_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) }})) {}
@ -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(""), 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(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 }));
}
}
@ -217,7 +217,7 @@ void HandleRendererButtonInteraction(Clay_ElementId elementId, Clay_PointerData
}
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_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) {
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_RECTANGLE({ .color = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT, .cornerRadius = CLAY_CORNER_RADIUS(10), .cursorPointer = true }),
Clay_OnHover(HandleRendererButtonInteraction, rendererIndex)
@ -235,8 +235,8 @@ void RendererButtonInactive(Clay_String text, size_t rendererIndex) {
}
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("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("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 = 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_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) }})) {}
@ -260,7 +260,7 @@ void RendererPageDesktop() {
}
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_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) }})) {}
@ -283,7 +283,7 @@ void RendererPageMobile() {
}
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_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) }})) {}
@ -311,18 +311,18 @@ float animationLerpValue = -1.0f;
Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
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("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(CLAY_ID("Spacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {}
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(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(CLAY_LAYOUT({ .padding = {16, 6} }),
CLAY(CLAY_LAYOUT({ .padding = {16, 16, 6, 6} }),
CLAY_RECTANGLE({
.cornerRadius = CLAY_CORNER_RADIUS(10),
.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(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_BORDER_OUTSIDE_RADIUS(2, COLOR_RED, 10)
) {
@ -391,10 +391,10 @@ CLAY_WASM_EXPORT("UpdateDrawFrame") Clay_RenderCommandArray UpdateDrawFrame(floa
windowHeight = height;
Clay_SetLayoutDimensions((Clay_Dimensions) { width, height });
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
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;
if (animationLerpValue > 1) {
animationLerpValue -= 2;

View File

@ -7,7 +7,7 @@ Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
void RenderHeaderButton(Clay_String text) {
CLAY(
CLAY_LAYOUT({ .padding = { 16, 8 }}),
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 },
.cornerRadius = 5
@ -22,7 +22,7 @@ void RenderHeaderButton(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({
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
@ -128,7 +128,7 @@ int main(void) {
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.childGap = 16
})
) {
@ -216,7 +216,7 @@ int main(void) {
CLAY_RECTANGLE(contentBackgroundConfig),
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.childGap = 8,
.sizing = {
.width = CLAY_SIZING_FIXED(250),
@ -228,7 +228,7 @@ int main(void) {
Document document = documents.documents[i];
Clay_LayoutConfig sidebarButtonLayout = {
.sizing = { .width = CLAY_SIZING_GROW(0) },
.padding = { 16, 16 }
.padding = CLAY_PADDING_ALL(16)
};
if (i == selectedDocumentIndex) {
@ -273,7 +273,7 @@ int main(void) {
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 16,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.sizing = layoutExpand
})
) {

View File

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.27)
project(clay_examples_textui_sidebar_scrolling_container C)
set(CMAKE_C_STANDARD 99)
add_executable(clay_examples_textui_sidebar_scrolling_container main.c multi-compilation-unit.c)
target_compile_options(clay_examples_textui_sidebar_scrolling_container PUBLIC)
target_include_directories(clay_examples_textui_sidebar_scrolling_container PUBLIC .)
target_link_libraries(clay_examples_textui_sidebar_scrolling_container PUBLIC ncurses)
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Werror -DCLAY_DEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
add_custom_command(
TARGET clay_examples_textui_sidebar_scrolling_container POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/resources
${CMAKE_CURRENT_BINARY_DIR}/resources)

View File

@ -0,0 +1,39 @@
# textui/console renderer example
## Introduction
This renderer example utilizes ncurses and a mostly implemented library which converts the clay draw commands into ncurses commands.
A console rendering is very limited, and all coordinates are simply rounded via integer division to the coordinate system of a terminal.
## What works
- Rectangles draw approximately correctly with the right color
- Text wraps, and is well placed
- Clicking a location on a scroll bar moves the scrolled area
- Debug mode highlights on click
- Window resize and layout reaction
## What doesn't work
- Image rendering
- Sub character rectangles
- Text fonts and colors
- Clay extensions
- Clay scissor mode
## Reasonable expectations
This renderer is intended to allow for a nearly dependency free implementation of Clay, and nearly all linux distributions have ncurses installed.
This renderer will allow for quick visualization of layouts. There is no graphics acceleration though this example is quite responsive.
The unit of a terminal is a character, not a pixel, so there is only so much detail that can be rendered. The default character size defined in the renderer is 5x8 pixels.
## What could work
- More precise rendering of borders and rectangles, this could be implemented with box-drawing characters: https://en.wikipedia.org/wiki/Box-drawing_characters
- The mouse wheel on some terminals
- Images with an additional dependency on something like kitty: https://sw.kovidgoyal.net/kitty/graphics-protocol/
- Better text coloring by matching the background
## Setup
You'll have to setup an event loop using getch(), and pay attention to the various init functions in main.c
Then it's the regular Clay layout definition and calls to the renderer function.
## Conclusion
The truth is that if you're willing to learn ncurses and how it handles windows you can get a better terminal experience without Clay.
This example shows that for quick terminal apps, Clay could be extremely effective for organizing a user interface in the terminal.
I hope that this renderer helps many people build fun and cool projects by lowering the barrier to a framwork.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,9 @@
#include "../../clay.h"
// NOTE: This file only exists to make sure that clay works when included in multiple translation units.
void SatisfyCompiler() {
CLAY(CLAY_ID("SatisfyCompiler"), CLAY_LAYOUT({})) {
CLAY_TEXT(CLAY_STRING("Test"), CLAY_TEXT_CONFIG({ .fontId = 0, .fontSize = 24 }));
}
}

View File

@ -7,7 +7,7 @@ Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
void RenderHeaderButton(Clay_String text) {
CLAY(
CLAY_LAYOUT({ .padding = { 16, 8 }}),
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
CLAY_RECTANGLE({
.color = { 140, 140, 140, 255 },
.cornerRadius = 5
@ -22,7 +22,7 @@ void RenderHeaderButton(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({
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
@ -121,7 +121,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.childGap = 16
})
) {
@ -134,7 +134,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
CLAY_RECTANGLE(contentBackgroundConfig),
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.childGap = 8,
.sizing = {
.width = CLAY_SIZING_FIXED(250),
@ -146,7 +146,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
Document document = documents.documents[i];
Clay_LayoutConfig sidebarButtonLayout = {
.sizing = { .width = CLAY_SIZING_GROW() },
.padding = { 16, 16 }
.padding = CLAY_PADDING_ALL(16)
};
if (i == *documentIndex) {
@ -194,7 +194,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
CLAY_LAYOUT({
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 16,
.padding = { 16, 16 },
.padding = CLAY_PADDING_ALL(16),
.sizing = layoutExpand
})
) {

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_link_libraries(clay_examples_raylib_sidebar_scrolling_container PUBLIC raylib)
if(MSVC)
set(CMAKE_C_FLAGS_DEBUG "/D CLAY_DEBUG")
else()
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror -Wno-error=missing-braces -DCLAY_DEBUG")
set(CMAKE_C_FLAGS_RELEASE "-O3")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Werror -DCLAY_DEBUG -fsanitize=address")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
endif()
add_custom_command(

View File

@ -21,14 +21,14 @@ void HandleHeaderButtonInteraction(Clay_ElementId elementId, Clay_PointerData po
// Examples of re-usable "Components"
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_OnHover(HandleHeaderButtonInteraction, 1)) {
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_TextElementConfig dropdownTextElementConfig = { .fontSize = 24, .textColor = {255,255,255,255} };
@ -40,9 +40,9 @@ void RenderDropdownTextItem(int index) {
Clay_RenderCommandArray CreateLayout() {
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("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("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("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, 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, 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_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("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 2"));
RenderHeaderButton(CLAY_STRING("Header Item 3"));
}
CLAY(CLAY_ID("MainContent"),
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(CLAY_ID("FloatingContainer"),
CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = { 16, 16 }}),
CLAY_FLOATING({ .zIndex = 1, .attachment = { CLAY_ATTACH_POINT_CENTER_TOP, CLAY_ATTACH_POINT_CENTER_TOP }, .offset = {0, -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, 0} }),
CLAY_BORDER_OUTSIDE({ .color = {80, 80, 80, 255}, .width = 2 }),
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_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("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} })) {}
@ -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_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("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_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("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("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} }));
}
}

View File

@ -0,0 +1,129 @@
//#include <stdio.h>
#include <curses.h>
#define CLAY_IMPLEMENTATION
#include "../../clay.h"
#define HPIXELS_PER_CHAR 5 //these are used to convert between Clay pixel space and terminal character locations
#define VPIXELS_PER_CHAR 8
void Clay_ncurses_Render(WINDOW * win, Clay_RenderCommandArray renderCommands);
void Clay_ncurses_Render(WINDOW * win, Clay_RenderCommandArray renderCommands){
short color_pair = 1; //increment on use, 0 is reserved
short color = 10; //get passed reserved colors
//maybe keep a list of Clay colors and only init a new color if required.
//clear the screen/window
clear();//sets cursor to 0,0
for(int i = 0; i < renderCommands.length; i++){
//handle every command
switch (renderCommands.internalArray[i].commandType){
case CLAY_RENDER_COMMAND_TYPE_NONE:
continue;
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE:
Clay_RectangleElementConfig *rectangle_config = renderCommands.internalArray[i].config.rectangleElementConfig;
init_color(color, rectangle_config->color.r, rectangle_config->color.g, rectangle_config->color.b);
init_pair(color_pair, color, color);
attr_on(color_set(color_pair,0),0);
for(int j = 0; j < renderCommands.internalArray[i].boundingBox.height/VPIXELS_PER_CHAR; j++){
mvhline(renderCommands.internalArray[i].boundingBox.y/VPIXELS_PER_CHAR + j, renderCommands.internalArray[i].boundingBox.x/HPIXELS_PER_CHAR, '#', renderCommands.internalArray[i].boundingBox.width/HPIXELS_PER_CHAR);
}
attr_off(color_set(color_pair,0),0);
color_pair++;
color++;
//TODO render radius corners
break;
case CLAY_RENDER_COMMAND_TYPE_BORDER:
Clay_BorderElementConfig *border_config = renderCommands.internalArray[i].config.borderElementConfig;
//just get a border on there for now
if(border_config->top.width > 0){
init_color(color, border_config->top.color.r, border_config->top.color.g, border_config->top.color.b);
init_pair(color_pair, color, COLOR_CYAN);//TODO get color at target location and init pair with that background
attr_on(color_set(color_pair,0),0);
mvhline(renderCommands.internalArray[i].boundingBox.y/VPIXELS_PER_CHAR, renderCommands.internalArray[i].boundingBox.x/HPIXELS_PER_CHAR + 1, '-', renderCommands.internalArray[i].boundingBox.width/HPIXELS_PER_CHAR - 2);
attr_off(color_set(color_pair,0),0);
color_pair++; //can we just check of the color requested is already there?
color++;
}
if(border_config->bottom.width > 0){
init_color(color, border_config->bottom.color.r, border_config->bottom.color.g, border_config->bottom.color.b);
init_pair(color_pair, color, COLOR_CYAN);//TODO get color at target location and init pair with that background
attr_on(color_set(color_pair,0),0);
mvhline(renderCommands.internalArray[i].boundingBox.y/VPIXELS_PER_CHAR + renderCommands.internalArray[i].boundingBox.height/VPIXELS_PER_CHAR, renderCommands.internalArray[i].boundingBox.x/HPIXELS_PER_CHAR + 1, '-', renderCommands.internalArray[i].boundingBox.width/HPIXELS_PER_CHAR - 2);
attr_off(color_set(color_pair,0),0);
color_pair++;
color++;
}
if(border_config->left.width > 0){
init_color(color, border_config->left.color.r, border_config->left.color.g, border_config->left.color.b);
init_pair(color_pair, color, COLOR_CYAN);//TODO get color at target location and init pair with that background
attr_on(color_set(color_pair,0),0);
mvvline(renderCommands.internalArray[i].boundingBox.y/VPIXELS_PER_CHAR + 1, renderCommands.internalArray[i].boundingBox.x/HPIXELS_PER_CHAR, '|', renderCommands.internalArray[i].boundingBox.height/VPIXELS_PER_CHAR - 1);
attr_off(color_set(color_pair,0),0);
color_pair++;
color++;
}
if(border_config->right.width > 0){
init_color(color, border_config->right.color.r, border_config->right.color.g, border_config->right.color.b);
init_pair(color_pair, color, COLOR_CYAN);//TODO get color at target location and init pair with that background
attr_on(color_set(color_pair,0),0);
mvvline(renderCommands.internalArray[i].boundingBox.y/VPIXELS_PER_CHAR + 1, renderCommands.internalArray[i].boundingBox.x/HPIXELS_PER_CHAR + renderCommands.internalArray[i].boundingBox.width/HPIXELS_PER_CHAR - 1, '|', renderCommands.internalArray[i].boundingBox.height/VPIXELS_PER_CHAR - 1);
attr_off(color_set(color_pair,0),0);
color_pair++;
color++;
}
break;
case CLAY_RENDER_COMMAND_TYPE_TEXT:
Clay_TextElementConfig *text_config = renderCommands.internalArray[i].config.textElementConfig;
attr_on(color_set(0,0),0);
int x = renderCommands.internalArray[i].boundingBox.x/HPIXELS_PER_CHAR;
int y = renderCommands.internalArray[i].boundingBox.y/VPIXELS_PER_CHAR; //text is referenced from bottom corner?
int w = renderCommands.internalArray[i].boundingBox.width/HPIXELS_PER_CHAR;
int h = renderCommands.internalArray[i].boundingBox.height/VPIXELS_PER_CHAR;
int line = 0;
int column = 0;
for (int k = 0; k < renderCommands.internalArray[i].text.length; k++) {
if (column >= w) {
column = 0;
line += 1;
}
mvaddch(y + line, x + column, renderCommands.internalArray[i].text.chars[k]);
column += 1;
}
break;
case CLAY_RENDER_COMMAND_TYPE_IMAGE:
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_START:
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_END:
case CLAY_RENDER_COMMAND_TYPE_CUSTOM:
default: continue;
}
}
attr_on(color_set(0,0),0);
mvwprintw(win, 0, 0, "Number of color pairs used: %i", color_pair);
refresh();//update the screen/window
}
//written by EmmanuelMess: https://github.com/nicbarker/clay/pull/91/commits/7ce74ba46c01f32e4517032e9da76bf54ecf7a43
static inline Clay_Dimensions ncurses_MeasureText(Clay_String *text, Clay_TextElementConfig *config) {
Clay_Dimensions textSize = { 0 };
float maxTextWidth = 0.0f;
float lineTextWidth = 0;
float textHeight = 1;
for (int i = 0; i < text->length; ++i)
{
if (text->chars[i] == '\n') {
maxTextWidth = maxTextWidth > lineTextWidth ? maxTextWidth : lineTextWidth;
lineTextWidth = 0;
textHeight++;
continue;
}
lineTextWidth++;
}
maxTextWidth = maxTextWidth > lineTextWidth ? maxTextWidth : lineTextWidth;
textSize.width = maxTextWidth*HPIXELS_PER_CHAR;
textSize.height = textHeight*VPIXELS_PER_CHAR;
return textSize;
}