mirror of
https://github.com/nicbarker/clay.git
synced 2025-09-18 04:26:18 +00:00
Compare commits
37 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
37675089e3 | ||
![]() |
1cbc56cbf2 | ||
![]() |
0d6969c8c3 | ||
![]() |
958d684b3c | ||
![]() |
f55513493b | ||
![]() |
dabf8214a8 | ||
![]() |
747643e84e | ||
![]() |
5a0d301c60 | ||
![]() |
1bc5105272 | ||
![]() |
61bab7bba6 | ||
![]() |
7f767d2301 | ||
![]() |
2b192409b9 | ||
![]() |
91c6d05774 | ||
![]() |
4aa3d75bef | ||
![]() |
9d38edb989 | ||
![]() |
516e85bdfe | ||
![]() |
0022d12c0c | ||
![]() |
d9d0b6c37b | ||
![]() |
8dfcc944fa | ||
![]() |
a9c1f9a8a7 | ||
![]() |
281f961e3d | ||
![]() |
3433a53a8e | ||
![]() |
4a91cac1b2 | ||
![]() |
ff7917798c | ||
![]() |
f97cb9ea10 | ||
![]() |
74f0ffbe26 | ||
![]() |
a5e212b8de | ||
![]() |
0835781602 | ||
![]() |
13ecd80ee5 | ||
![]() |
c524485c46 | ||
![]() |
b9e27178c0 | ||
![]() |
6f10bf4b3d | ||
![]() |
adb1bd620a | ||
![]() |
dca9f60a6c | ||
![]() |
3ccfa0f8fa | ||
![]() |
35b45d939b | ||
![]() |
6b03a215b7 |
104
.github/workflows/odin-bindings-update.yml
vendored
Normal file
104
.github/workflows/odin-bindings-update.yml
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
name: Odin Bindings Update
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
jobs:
|
||||
check_changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
changed: ${{ steps.check_clay.outputs.changed }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Check if clay.h changed
|
||||
id: check_clay
|
||||
run: |
|
||||
if git diff --name-only HEAD^ HEAD | grep -Fx "clay.h"; then
|
||||
echo "changed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "changed=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
build:
|
||||
needs: check_changes
|
||||
if: needs.check_changes.outputs.changed == 'true'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install clang (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang
|
||||
|
||||
- name: Build libs
|
||||
run: |
|
||||
mkdir -p build
|
||||
mkdir -p artifacts
|
||||
cp clay.h clay.c
|
||||
|
||||
COMMON_FLAGS="-DCLAY_IMPLEMENTATION -fno-ident -frandom-seed=clay"
|
||||
|
||||
if [[ "$(uname)" == "Linux" ]]; then
|
||||
mkdir -p artifacts/linux
|
||||
mkdir -p artifacts/windows
|
||||
mkdir -p artifacts/wasm
|
||||
|
||||
echo "Building for Linux..."
|
||||
clang -c $COMMON_FLAGS -fPIC -ffreestanding -static -target x86_64-unknown-linux-gnu clay.c -o build/linux.o
|
||||
ar rD artifacts/linux/clay.a build/linux.o
|
||||
|
||||
echo "Building for Windows..."
|
||||
clang -c $COMMON_FLAGS -ffreestanding -target x86_64-pc-windows-msvc -fuse-ld=llvm-lib clay.c -o artifacts/windows/clay.lib
|
||||
|
||||
echo "Building for WASM..."
|
||||
clang -c $COMMON_FLAGS -fPIC -target wasm32 -nostdlib -static clay.c -o artifacts/wasm/clay.o
|
||||
elif [[ "$(uname)" == "Darwin" ]]; then
|
||||
mkdir -p artifacts/macos
|
||||
mkdir -p artifacts/macos-arm64
|
||||
echo "Building for macOS (x86_64)..."
|
||||
clang -c $COMMON_FLAGS -fPIC -target x86_64-apple-macos clay.c -o build/macos.o
|
||||
libtool -static -o artifacts/macos/clay.a build/macos.o
|
||||
|
||||
echo "Building for macOS (ARM64)..."
|
||||
clang -c $COMMON_FLAGS -fPIC -target arm64-apple-macos clay.c -o build/macos-arm64.o
|
||||
libtool -static -o artifacts/macos-arm64/clay.a build/macos-arm64.o
|
||||
fi
|
||||
rm -f clay.c build/*.o
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: artifacts-${{ matrix.os }}
|
||||
path: artifacts/
|
||||
|
||||
commit:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
- name: Move artifacts
|
||||
run: |
|
||||
cp -r artifacts-ubuntu-latest/* bindings/odin/clay-odin/
|
||||
cp -r artifacts-macos-latest/* bindings/odin/clay-odin/
|
||||
|
||||
- name: Commit/Push changes
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add bindings/odin/clay-odin/
|
||||
git commit -m "[bindings/odin] Update Odin bindings"
|
||||
git push
|
|
@ -1,4 +1,4 @@
|
|||
# Clay
|
||||
# Clay, A UI Layout Library
|
||||
**_Clay_** (short for **C Layout**) is a high performance 2D UI layout library.
|
||||
|
||||
### Major Features
|
||||
|
@ -161,8 +161,8 @@ For help starting out or to discuss clay, considering joining [the discord serve
|
|||
- [Clay_MinMemorySize](#clay_minmemorysize)
|
||||
- [Clay_CreateArenaWithCapacityAndMemory](#clay_createarenawithcapacityandmemory)
|
||||
- [Clay_SetMeasureTextFunction](#clay_setmeasuretextfunction)
|
||||
- [Clay_ResetMeasureTextCache](#clau_resetmeasuretextcache)
|
||||
- [Clay_SetMaxElementCount](clay_setmaxelementcount)
|
||||
- [Clay_ResetMeasureTextCache](#clay_resetmeasuretextcache)
|
||||
- [Clay_SetMaxElementCount](#clay_setmaxelementcount)
|
||||
- [Clay_SetMaxMeasureTextCacheWordCount](#clay_setmaxmeasuretextcachewordcount)
|
||||
- [Clay_Initialize](#clay_initialize)
|
||||
- [Clay_GetCurrentContext](#clay_getcurrentcontext)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
cp ../../clay.h clay.c;
|
||||
# Intel Mac
|
||||
clang -c -DCLAY_IMPLEMENTATION -o clay.o -ffreestanding -static -target x86_64-apple-darwin clay.c -fPIC -O3 && ar r clay-odin/macos/clay.a clay.o;
|
||||
rm -f clay-odin/macos/clay.a && clang -c -DCLAY_IMPLEMENTATION -o clay.o -ffreestanding -static -target x86_64-apple-darwin clay.c -fPIC -O3 && ar r clay-odin/macos/clay.a clay.o;
|
||||
# ARM Mac
|
||||
clang -c -DCLAY_IMPLEMENTATION -g -o clay.o -static clay.c -fPIC -O3 && ar r clay-odin/macos-arm64/clay.a clay.o;
|
||||
rm -f clay-odin/macos-arm64/clay.a && clang -c -DCLAY_IMPLEMENTATION -g -o clay.o -static clay.c -fPIC -O3 && ar r clay-odin/macos-arm64/clay.a clay.o;
|
||||
# x64 Windows
|
||||
clang -c -DCLAY_IMPLEMENTATION -o clay-odin/windows/clay.lib -ffreestanding -target x86_64-pc-windows-msvc -fuse-ld=llvm-lib -static -O3 clay.c;
|
||||
rm -f clay-odin/windows/clay.lib && clang -c -DCLAY_IMPLEMENTATION -o clay-odin/windows/clay.lib -ffreestanding -target x86_64-pc-windows-msvc -fuse-ld=llvm-lib -static -O3 clay.c;
|
||||
# Linux
|
||||
clang -c -DCLAY_IMPLEMENTATION -o clay.o -ffreestanding -static -target x86_64-unknown-linux-gnu clay.c -fPIC -O3 && ar r clay-odin/linux/clay.a clay.o;
|
||||
rm -f clay-odin/linux/clay.a && clang -c -DCLAY_IMPLEMENTATION -o clay.o -ffreestanding -static -target x86_64-unknown-linux-gnu clay.c -fPIC -O3 && ar r clay-odin/linux/clay.a clay.o;
|
||||
# WASM
|
||||
clang -c -DCLAY_IMPLEMENTATION -o clay-odin/wasm/clay.o -target wasm32 -nostdlib -static -O3 clay.c;
|
||||
rm -f clay-odin/wasm/clay.o && clang -c -DCLAY_IMPLEMENTATION -o clay-odin/wasm/clay.o -target wasm32 -nostdlib -static -O3 clay.c;
|
||||
rm clay.o;
|
||||
rm clay.c;
|
||||
|
|
|
@ -338,7 +338,6 @@ ClayArray :: struct($type: typeid) {
|
|||
}
|
||||
|
||||
ElementDeclaration :: struct {
|
||||
id: ElementId,
|
||||
layout: LayoutConfig,
|
||||
backgroundColor: Color,
|
||||
cornerRadius: CornerRadius,
|
||||
|
@ -378,6 +377,7 @@ Context :: struct {} // opaque structure, only use as a pointer
|
|||
@(link_prefix = "Clay_", default_calling_convention = "c")
|
||||
foreign Clay {
|
||||
_OpenElement :: proc() ---
|
||||
_OpenElementWithId :: proc(id: ElementId) ---
|
||||
_CloseElement :: proc() ---
|
||||
MinMemorySize :: proc() -> u32 ---
|
||||
CreateArenaWithCapacityAndMemory :: proc(capacity: c.size_t, offset: [^]u8) -> Arena ---
|
||||
|
@ -413,7 +413,8 @@ foreign Clay {
|
|||
@(link_prefix = "Clay_", default_calling_convention = "c", private)
|
||||
foreign Clay {
|
||||
_ConfigureOpenElement :: proc(config: ElementDeclaration) ---
|
||||
_HashString :: proc(key: String, offset: u32, seed: u32) -> ElementId ---
|
||||
_HashString :: proc(key: String, seed: u32) -> ElementId ---
|
||||
_HashStringWithOffset :: proc(key: String, index: u32, seed: u32) -> ElementId ---
|
||||
_OpenTextElement :: proc(text: String, textConfig: ^TextElementConfig) ---
|
||||
_StoreTextElementConfig :: proc(config: TextElementConfig) -> ^TextElementConfig ---
|
||||
_GetParentElementId :: proc() -> u32 ---
|
||||
|
@ -425,11 +426,19 @@ ConfigureOpenElement :: proc(config: ElementDeclaration) -> bool {
|
|||
}
|
||||
|
||||
@(deferred_none = _CloseElement)
|
||||
UI :: proc() -> proc (config: ElementDeclaration) -> bool {
|
||||
UI_WithId :: proc(id: ElementId) -> proc (config: ElementDeclaration) -> bool {
|
||||
_OpenElementWithId(id)
|
||||
return ConfigureOpenElement
|
||||
}
|
||||
|
||||
@(deferred_none = _CloseElement)
|
||||
UI_AutoId :: proc() -> proc (config: ElementDeclaration) -> bool {
|
||||
_OpenElement()
|
||||
return ConfigureOpenElement
|
||||
}
|
||||
|
||||
UI :: proc{UI_WithId, UI_AutoId};
|
||||
|
||||
Text :: proc($text: string, config: ^TextElementConfig) {
|
||||
wrapped := MakeString(text)
|
||||
wrapped.isStaticallyAllocated = true
|
||||
|
@ -460,11 +469,11 @@ CornerRadiusAll :: proc(radius: f32) -> CornerRadius {
|
|||
return CornerRadius{radius, radius, radius, radius}
|
||||
}
|
||||
|
||||
SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
|
||||
SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax = {}) -> SizingAxis {
|
||||
return SizingAxis{type = SizingType.Fit, constraints = {sizeMinMax = sizeMinMax}}
|
||||
}
|
||||
|
||||
SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
|
||||
SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax = {}) -> SizingAxis {
|
||||
return SizingAxis{type = SizingType.Grow, constraints = {sizeMinMax = sizeMinMax}}
|
||||
}
|
||||
|
||||
|
@ -481,9 +490,9 @@ MakeString :: proc(label: string) -> String {
|
|||
}
|
||||
|
||||
ID :: proc(label: string, index: u32 = 0) -> ElementId {
|
||||
return _HashString(MakeString(label), index, 0)
|
||||
return _HashString(MakeString(label), index)
|
||||
}
|
||||
|
||||
ID_LOCAL :: proc(label: string, index: u32 = 0) -> ElementId {
|
||||
return _HashString(MakeString(label), index, _GetParentElementId())
|
||||
return _HashStringWithOffset(MakeString(label), index, _GetParentElementId())
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -63,14 +63,12 @@ border2pxRed := clay.BorderElementConfig {
|
|||
}
|
||||
|
||||
LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Color, $text: string, image: ^raylib.Texture2D) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("HeroBlob", index),
|
||||
if clay.UI(clay.ID("HeroBlob", index))({
|
||||
layout = { sizing = { width = clay.SizingGrow({ max = 480 }) }, padding = clay.PaddingAll(16), childGap = 16, childAlignment = clay.ChildAlignment{ y = .Center } },
|
||||
border = border2pxRed,
|
||||
cornerRadius = clay.CornerRadiusAll(10)
|
||||
}) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("CheckImage", index),
|
||||
if clay.UI(clay.ID("CheckImage", index))({
|
||||
layout = { sizing = { width = clay.SizingFixed(32) } },
|
||||
aspectRatio = { 1.0 },
|
||||
image = { imageData = image },
|
||||
|
@ -80,16 +78,14 @@ LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Colo
|
|||
}
|
||||
|
||||
LandingPageDesktop :: proc() {
|
||||
if clay.UI()({
|
||||
id = clay.ID("LandingPage1Desktop"),
|
||||
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("LandingPage1Desktop"))({
|
||||
layout = { sizing = { width = clay.SizingGrow(), height = clay.SizingFit({ min = cast(f32)windowHeight - 70 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } },
|
||||
}) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("LandingPage1"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 },
|
||||
if clay.UI(clay.ID("LandingPage1"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingGrow() }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 },
|
||||
border = { COLOR_RED, { left = 2, right = 2 } },
|
||||
}) {
|
||||
if clay.UI()({ id = clay.ID("LeftText"), layout = { sizing = { width = clay.SizingPercent(0.55) }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
if clay.UI(clay.ID("LeftText"))({ layout = { sizing = { width = clay.SizingPercent(0.55) }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
clay.Text(
|
||||
"Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance.",
|
||||
clay.TextConfig({fontSize = 56, fontId = FONT_ID_TITLE_56, textColor = COLOR_RED}),
|
||||
|
@ -100,8 +96,7 @@ LandingPageDesktop :: proc() {
|
|||
clay.TextConfig({fontSize = 36, fontId = FONT_ID_TITLE_36, textColor = COLOR_ORANGE}),
|
||||
)
|
||||
}
|
||||
if clay.UI()({
|
||||
id = clay.ID("HeroImageOuter"),
|
||||
if clay.UI(clay.ID("HeroImageOuter"))({
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingPercent(0.45) }, childAlignment = { x = .Center }, childGap = 16 },
|
||||
}) {
|
||||
LandingPageBlob(1, 30, FONT_ID_BODY_30, COLOR_BLOB_BORDER_5, "High performance", &checkImage5)
|
||||
|
@ -115,17 +110,16 @@ LandingPageDesktop :: proc() {
|
|||
}
|
||||
|
||||
LandingPageMobile :: proc() {
|
||||
if clay.UI()({
|
||||
id = clay.ID("LandingPage1Mobile"),
|
||||
if clay.UI(clay.ID("LandingPage1Mobile"))({
|
||||
layout = {
|
||||
layoutDirection = .TopToBottom,
|
||||
sizing = { width = clay.SizingGrow({ }), height = clay.SizingFit({ min = cast(f32)windowHeight - 70 }) },
|
||||
sizing = { width = clay.SizingGrow(), height = clay.SizingFit({ min = cast(f32)windowHeight - 70 }) },
|
||||
childAlignment = { x = .Center, y = .Center },
|
||||
padding = { 16, 16, 32, 32 },
|
||||
childGap = 32,
|
||||
},
|
||||
}) {
|
||||
if clay.UI()({ id = clay.ID("LeftText"), layout = { sizing = { width = clay.SizingGrow({ }) }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
if clay.UI(clay.ID("LeftText"))({ layout = { sizing = { width = clay.SizingGrow() }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
clay.Text(
|
||||
"Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance.",
|
||||
clay.TextConfig({fontSize = 48, fontId = FONT_ID_TITLE_48, textColor = COLOR_RED}),
|
||||
|
@ -136,9 +130,8 @@ LandingPageMobile :: proc() {
|
|||
clay.TextConfig({fontSize = 32, fontId = FONT_ID_TITLE_32, textColor = COLOR_ORANGE}),
|
||||
)
|
||||
}
|
||||
if clay.UI()({
|
||||
id = clay.ID("HeroImageOuter"),
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingGrow({ }) }, childAlignment = { x = .Center }, childGap = 16 },
|
||||
if clay.UI(clay.ID("HeroImageOuter"))({
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingGrow() }, childAlignment = { x = .Center }, childGap = 16 },
|
||||
}) {
|
||||
LandingPageBlob(1, 24, FONT_ID_BODY_24, COLOR_BLOB_BORDER_5, "High performance", &checkImage5)
|
||||
LandingPageBlob(2, 24, FONT_ID_BODY_24, COLOR_BLOB_BORDER_4, "Flexbox-style responsive layout", &checkImage4)
|
||||
|
@ -151,18 +144,16 @@ LandingPageMobile :: proc() {
|
|||
|
||||
FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) {
|
||||
textConfig := clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_RED})
|
||||
if clay.UI()({
|
||||
id = clay.ID("HFileBoxOuter"),
|
||||
if clay.UI(clay.ID("HFileBoxOuter"))({
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { width = widthSizing }, childAlignment = { y = .Center }, padding = { outerPadding, outerPadding, 32, 32 }, childGap = 8 },
|
||||
}) {
|
||||
if clay.UI()({ id = clay.ID("HFileIncludeOuter"), layout = { padding = { 8, 8, 4, 4 } }, backgroundColor = COLOR_RED, cornerRadius = clay.CornerRadiusAll(8) }) {
|
||||
if clay.UI(clay.ID("HFileIncludeOuter"))({ layout = { padding = { 8, 8, 4, 4 } }, backgroundColor = 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)
|
||||
clay.Text("Zero dependencies, including no C standard library.", textConfig)
|
||||
}
|
||||
if clay.UI()({
|
||||
id = clay.ID("BringYourOwnRendererOuter"),
|
||||
if clay.UI(clay.ID("BringYourOwnRendererOuter"))({
|
||||
layout = { layoutDirection = .TopToBottom, 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}))
|
||||
|
@ -172,10 +163,9 @@ FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) {
|
|||
}
|
||||
|
||||
FeatureBlocksDesktop :: proc() {
|
||||
if clay.UI()({ id = clay.ID("FeatureBlocksOuter"), layout = { sizing = { width = clay.SizingGrow({}) } } }) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("FeatureBlocksInner"),
|
||||
layout = { sizing = { width = clay.SizingGrow({ }) }, childAlignment = { y = .Center } },
|
||||
if clay.UI(clay.ID("FeatureBlocksOuter"))({ layout = { sizing = { width = clay.SizingGrow({}) } } }) {
|
||||
if clay.UI(clay.ID("FeatureBlocksInner"))({
|
||||
layout = { sizing = { width = clay.SizingGrow() }, childAlignment = { y = .Center } },
|
||||
border = { width = { betweenChildren = 2}, color = COLOR_RED },
|
||||
}) {
|
||||
FeatureBlocks(clay.SizingPercent(0.5), 50)
|
||||
|
@ -184,9 +174,8 @@ FeatureBlocksDesktop :: proc() {
|
|||
}
|
||||
|
||||
FeatureBlocksMobile :: proc() {
|
||||
if clay.UI()({
|
||||
id = clay.ID("FeatureBlocksInner"),
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingGrow({ }) } },
|
||||
if clay.UI(clay.ID("FeatureBlocksInner"))({
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingGrow() } },
|
||||
border = { width = { betweenChildren = 2}, color = COLOR_RED },
|
||||
}) {
|
||||
FeatureBlocks(clay.SizingGrow({}), 16)
|
||||
|
@ -194,9 +183,9 @@ FeatureBlocksMobile :: proc() {
|
|||
}
|
||||
|
||||
DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.SizingAxis) {
|
||||
if clay.UI()({ id = clay.ID("SyntaxPageLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
if clay.UI(clay.ID("SyntaxPageLeftText"))({ layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
clay.Text("Declarative Syntax", clay.TextConfig(titleTextConfig))
|
||||
if clay.UI()({ id = clay.ID("SyntaxSpacer"), layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } } }) {}
|
||||
if clay.UI(clay.ID("SyntaxSpacer"))({ layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } } }) {}
|
||||
clay.Text(
|
||||
"Flexible and readable declarative syntax with nested UI element hierarchies.",
|
||||
clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_RED}),
|
||||
|
@ -210,9 +199,8 @@ DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizi
|
|||
clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_RED}),
|
||||
)
|
||||
}
|
||||
if clay.UI()({ id = clay.ID("SyntaxPageRightImage"), layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("SyntaxPageRightImageInner"),
|
||||
if clay.UI(clay.ID("SyntaxPageRightImage"))({ layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) {
|
||||
if clay.UI(clay.ID("SyntaxPageRightImageInner"))({
|
||||
layout = { sizing = { width = clay.SizingGrow({ max = 568 }) } },
|
||||
aspectRatio = { 1136.0 / 1194.0 },
|
||||
image = { imageData = &syntaxImage },
|
||||
|
@ -221,13 +209,11 @@ DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizi
|
|||
}
|
||||
|
||||
DeclarativeSyntaxPageDesktop :: proc() {
|
||||
if clay.UI()({
|
||||
id = clay.ID("SyntaxPageDesktop"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } },
|
||||
if clay.UI(clay.ID("SyntaxPageDesktop"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } },
|
||||
}) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("SyntaxPage"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 },
|
||||
if clay.UI(clay.ID("SyntaxPage"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingGrow() }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 },
|
||||
border = border2pxRed,
|
||||
}) {
|
||||
DeclarativeSyntaxPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5))
|
||||
|
@ -236,11 +222,10 @@ DeclarativeSyntaxPageDesktop :: proc() {
|
|||
}
|
||||
|
||||
DeclarativeSyntaxPageMobile :: proc() {
|
||||
if clay.UI()({
|
||||
id = clay.ID("SyntaxPageMobile"),
|
||||
if clay.UI(clay.ID("SyntaxPageMobile"))({
|
||||
layout = {
|
||||
layoutDirection = .TopToBottom,
|
||||
sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) },
|
||||
sizing = { clay.SizingGrow(), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) },
|
||||
childAlignment = { x = .Center, y = .Center },
|
||||
padding = { 16, 16, 32, 32 },
|
||||
childGap = 16,
|
||||
|
@ -257,7 +242,7 @@ ColorLerp :: proc(a: clay.Color, b: clay.Color, amount: f32) -> clay.Color {
|
|||
LOREM_IPSUM_TEXT :: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
|
||||
|
||||
HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementConfig, widthSizing: clay.SizingAxis) {
|
||||
if clay.UI()({ id = clay.ID("PerformanceLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
if clay.UI(clay.ID("PerformanceLeftText"))({ layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
clay.Text("High Performance", clay.TextConfig(titleTextConfig))
|
||||
if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } }}) {}
|
||||
clay.Text(
|
||||
|
@ -273,22 +258,19 @@ HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementCon
|
|||
clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_36, textColor = COLOR_LIGHT}),
|
||||
)
|
||||
}
|
||||
if clay.UI()({ id = clay.ID("PerformanceRightImageOuter"), layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("PerformanceRightBorder"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(400) } },
|
||||
if clay.UI(clay.ID("PerformanceRightImageOuter"))({ layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) {
|
||||
if clay.UI(clay.ID("PerformanceRightBorder"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingFixed(400) } },
|
||||
border = { COLOR_LIGHT, {2, 2, 2, 2, 2} },
|
||||
}) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("AnimationDemoContainerLeft"),
|
||||
layout = { sizing = { clay.SizingPercent(0.35 + 0.3 * lerpValue), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(16) },
|
||||
if clay.UI(clay.ID("AnimationDemoContainerLeft"))({
|
||||
layout = { sizing = { clay.SizingPercent(0.35 + 0.3 * lerpValue), clay.SizingGrow() }, childAlignment = { y = .Center }, padding = clay.PaddingAll(16) },
|
||||
backgroundColor = 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()({
|
||||
id = clay.ID("AnimationDemoContainerRight"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(16) },
|
||||
if clay.UI(clay.ID("AnimationDemoContainerRight"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingGrow() }, childAlignment = { y = .Center }, padding = clay.PaddingAll(16) },
|
||||
backgroundColor = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue),
|
||||
}) {
|
||||
clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT}))
|
||||
|
@ -298,9 +280,8 @@ HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementCon
|
|||
}
|
||||
|
||||
HighPerformancePageDesktop :: proc(lerpValue: f32) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("PerformanceDesktop"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { 82, 82, 32, 32 }, childGap = 64 },
|
||||
if clay.UI(clay.ID("PerformanceDesktop"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { 82, 82, 32, 32 }, childGap = 64 },
|
||||
backgroundColor = COLOR_RED,
|
||||
}) {
|
||||
HighPerformancePage(lerpValue, {fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_LIGHT}, clay.SizingPercent(0.5))
|
||||
|
@ -308,11 +289,10 @@ HighPerformancePageDesktop :: proc(lerpValue: f32) {
|
|||
}
|
||||
|
||||
HighPerformancePageMobile :: proc(lerpValue: f32) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("PerformanceMobile"),
|
||||
if clay.UI(clay.ID("PerformanceMobile"))({
|
||||
layout = {
|
||||
layoutDirection = .TopToBottom,
|
||||
sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) },
|
||||
sizing = { clay.SizingGrow(), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) },
|
||||
childAlignment = { x = .Center, y = .Center },
|
||||
padding = { 16, 16, 32, 32 },
|
||||
childGap = 32,
|
||||
|
@ -335,8 +315,7 @@ RendererButtonActive :: proc(index: i32, $text: string) {
|
|||
|
||||
RendererButtonInactive :: proc(index: u32, $text: string) {
|
||||
if clay.UI()({ border = border2pxRed }) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("RendererButtonInactiveInner", index),
|
||||
if clay.UI(clay.ID("RendererButtonInactiveInner", index))({
|
||||
layout = { sizing = { width = clay.SizingFixed(300) }, padding = clay.PaddingAll(16) },
|
||||
backgroundColor = COLOR_LIGHT,
|
||||
cornerRadius = clay.CornerRadiusAll(10)
|
||||
|
@ -347,7 +326,7 @@ RendererButtonInactive :: proc(index: u32, $text: string) {
|
|||
}
|
||||
|
||||
RendererPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.SizingAxis) {
|
||||
if clay.UI()({ id = clay.ID("RendererLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
if clay.UI(clay.ID("RendererLeftText"))({ layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) {
|
||||
clay.Text("Renderer & Platform Agnostic", clay.TextConfig(titleTextConfig))
|
||||
if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } } }) {}
|
||||
clay.Text(
|
||||
|
@ -363,8 +342,7 @@ RendererPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.
|
|||
clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_36, textColor = COLOR_RED}),
|
||||
)
|
||||
}
|
||||
if clay.UI()({
|
||||
id = clay.ID("RendererRightText"),
|
||||
if clay.UI(clay.ID("RendererRightText"))({
|
||||
layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center }, layoutDirection = .TopToBottom, childGap = 16 },
|
||||
}) {
|
||||
clay.Text("Try changing renderer!", clay.TextConfig({fontSize = 36, fontId = FONT_ID_BODY_36, textColor = COLOR_ORANGE}))
|
||||
|
@ -374,13 +352,11 @@ RendererPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.
|
|||
}
|
||||
|
||||
RendererPageDesktop :: proc() {
|
||||
if clay.UI()({
|
||||
id = clay.ID("RendererPageDesktop"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } },
|
||||
if clay.UI(clay.ID("RendererPageDesktop"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } },
|
||||
}) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("RendererPage"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 },
|
||||
if clay.UI(clay.ID("RendererPage"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingGrow() }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 },
|
||||
border = { COLOR_RED, { left = 2, right = 2 } },
|
||||
}) {
|
||||
RendererPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5))
|
||||
|
@ -389,11 +365,10 @@ RendererPageDesktop :: proc() {
|
|||
}
|
||||
|
||||
RendererPageMobile :: proc() {
|
||||
if clay.UI()({
|
||||
id = clay.ID("RendererMobile"),
|
||||
if clay.UI(clay.ID("RendererMobile"))({
|
||||
layout = {
|
||||
layoutDirection = .TopToBottom,
|
||||
sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) },
|
||||
sizing = { clay.SizingGrow(), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) },
|
||||
childAlignment = { x = .Center, y = .Center },
|
||||
padding = { 16, 16, 32, 32 },
|
||||
childGap = 32,
|
||||
|
@ -416,28 +391,25 @@ animationLerpValue: f32 = -1.0
|
|||
createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
|
||||
mobileScreen := windowWidth < 750
|
||||
clay.BeginLayout()
|
||||
if clay.UI()({
|
||||
id = clay.ID("OuterContainer"),
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) } },
|
||||
if clay.UI(clay.ID("OuterContainer"))({
|
||||
layout = { layoutDirection = .TopToBottom, sizing = { clay.SizingGrow(), clay.SizingGrow() } },
|
||||
backgroundColor = COLOR_LIGHT,
|
||||
}) {
|
||||
if clay.UI()({
|
||||
id = clay.ID("Header"),
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(50) }, childAlignment = { y = .Center }, childGap = 24, padding = { left = 32, right = 32 } },
|
||||
if clay.UI(clay.ID("Header"))({
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingFixed(50) }, childAlignment = { y = .Center }, childGap = 24, padding = { left = 32, right = 32 } },
|
||||
}) {
|
||||
clay.Text("Clay", &headerTextConfig)
|
||||
if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({ }) } } }) {}
|
||||
if clay.UI()({ layout = { sizing = { width = clay.SizingGrow() } } }) {}
|
||||
|
||||
if (!mobileScreen) {
|
||||
if clay.UI()({ id = clay.ID("LinkExamplesOuter"), backgroundColor = {0, 0, 0, 0} }) {
|
||||
if clay.UI(clay.ID("LinkExamplesOuter"))({ backgroundColor = {0, 0, 0, 0} }) {
|
||||
clay.Text("Examples", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = {61, 26, 5, 255}}))
|
||||
}
|
||||
if clay.UI()({ id = clay.ID("LinkDocsOuter"), backgroundColor = {0, 0, 0, 0} }) {
|
||||
if clay.UI(clay.ID("LinkDocsOuter"))({ backgroundColor = {0, 0, 0, 0} }) {
|
||||
clay.Text("Docs", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = {61, 26, 5, 255}}))
|
||||
}
|
||||
}
|
||||
if clay.UI()({
|
||||
id = clay.ID("LinkGithubOuter"),
|
||||
if clay.UI(clay.ID("LinkGithubOuter"))({
|
||||
layout = { padding = { 16, 16, 6, 6 } },
|
||||
border = border2pxRed,
|
||||
backgroundColor = clay.Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT,
|
||||
|
@ -446,15 +418,14 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
|
|||
clay.Text("Github", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = {61, 26, 5, 255}}))
|
||||
}
|
||||
}
|
||||
if clay.UI()({ id = clay.ID("TopBorder1"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_5 } ) {}
|
||||
if clay.UI()({ id = clay.ID("TopBorder2"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_4 } ) {}
|
||||
if clay.UI()({ id = clay.ID("TopBorder3"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_3 } ) {}
|
||||
if clay.UI()({ id = clay.ID("TopBorder4"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_2 } ) {}
|
||||
if clay.UI()({ id = clay.ID("TopBorder5"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_1 } ) {}
|
||||
if clay.UI()({
|
||||
id = clay.ID("ScrollContainerBackgroundRectangle"),
|
||||
if clay.UI(clay.ID("TopBorder1"))({ layout = { sizing = { clay.SizingGrow(), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_5 } ) {}
|
||||
if clay.UI(clay.ID("TopBorder2"))({ layout = { sizing = { clay.SizingGrow(), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_4 } ) {}
|
||||
if clay.UI(clay.ID("TopBorder3"))({ layout = { sizing = { clay.SizingGrow(), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_3 } ) {}
|
||||
if clay.UI(clay.ID("TopBorder4"))({ layout = { sizing = { clay.SizingGrow(), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_2 } ) {}
|
||||
if clay.UI(clay.ID("TopBorder5"))({ layout = { sizing = { clay.SizingGrow(), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_1 } ) {}
|
||||
if clay.UI(clay.ID("ScrollContainerBackgroundRectangle"))({
|
||||
clip = { vertical = true, childOffset = clay.GetScrollOffset() },
|
||||
layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, layoutDirection = clay.LayoutDirection.TopToBottom },
|
||||
layout = { sizing = { clay.SizingGrow(), clay.SizingGrow() }, layoutDirection = clay.LayoutDirection.TopToBottom },
|
||||
backgroundColor = COLOR_LIGHT,
|
||||
border = { COLOR_RED, { betweenChildren = 2} },
|
||||
}) {
|
||||
|
|
361
clay.h
361
clay.h
|
@ -31,7 +31,8 @@
|
|||
#if !( \
|
||||
(defined(__cplusplus) && __cplusplus >= 202002L) || \
|
||||
(defined(__STDC__) && __STDC__ == 1 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
|
||||
defined(_MSC_VER) \
|
||||
defined(_MSC_VER) || \
|
||||
defined(__OBJC__) \
|
||||
)
|
||||
#error "Clay requires C99, C++20, or MSVC"
|
||||
#endif
|
||||
|
@ -72,24 +73,24 @@
|
|||
#define CLAY_SIZING_PERCENT(percentOfParent) (CLAY__INIT(Clay_SizingAxis) { .size = { .percent = (percentOfParent) }, .type = CLAY__SIZING_TYPE_PERCENT })
|
||||
|
||||
// Note: If a compile error led you here, you might be trying to use CLAY_ID with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SID instead.
|
||||
#define CLAY_ID(label) CLAY_IDI(label, 0)
|
||||
#define CLAY_ID(label) CLAY_SID(CLAY_STRING(label))
|
||||
|
||||
#define CLAY_SID(label) CLAY_SIDI(label, 0)
|
||||
#define CLAY_SID(label) Clay__HashString(label, 0)
|
||||
|
||||
// Note: If a compile error led you here, you might be trying to use CLAY_IDI with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SIDI instead.
|
||||
#define CLAY_IDI(label, index) CLAY_SIDI(CLAY_STRING(label), index)
|
||||
|
||||
#define CLAY_SIDI(label, index) Clay__HashString(label, index, 0)
|
||||
#define CLAY_SIDI(label, index) Clay__HashStringWithOffset(label, index, 0)
|
||||
|
||||
// Note: If a compile error led you here, you might be trying to use CLAY_ID_LOCAL with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SID_LOCAL instead.
|
||||
#define CLAY_ID_LOCAL(label) CLAY_IDI_LOCAL(label, 0)
|
||||
#define CLAY_ID_LOCAL(label) CLAY_SID_LOCAL(CLAY_STRING(label))
|
||||
|
||||
#define CLAY_SID_LOCAL(label) CLAY_SIDI_LOCAL(label, 0)
|
||||
#define CLAY_SID_LOCAL(label) Clay__HashString(label, Clay__GetParentElementId())
|
||||
|
||||
// Note: If a compile error led you here, you might be trying to use CLAY_IDI_LOCAL with something other than a string literal. To construct an ID with a dynamic string, use CLAY_SIDI_LOCAL instead.
|
||||
#define CLAY_IDI_LOCAL(label, index) CLAY_SIDI_LOCAL(CLAY_STRING(label), index)
|
||||
|
||||
#define CLAY_SIDI_LOCAL(label, index) Clay__HashString(label, index, Clay__GetParentElementId())
|
||||
#define CLAY_SIDI_LOCAL(label, index) Clay__HashStringWithOffset(label, index, Clay__GetParentElementId())
|
||||
|
||||
#define CLAY__STRING_LENGTH(s) ((sizeof(s) / sizeof((s)[0])) - sizeof((s)[0]))
|
||||
|
||||
|
@ -120,25 +121,32 @@ static inline void Clay__SuppressUnusedLatchDefinitionVariableWarning(void) { (v
|
|||
|
||||
Into calls like this:
|
||||
|
||||
Clay_OpenElement();
|
||||
Clay_ConfigureOpenElement((Clay_ElementDeclaration) {
|
||||
Clay__OpenElement();
|
||||
Clay__ConfigureOpenElement((Clay_ElementDeclaration) {
|
||||
.id = CLAY_ID("Container"),
|
||||
.backgroundColor = { 255, 200, 200, 255 }
|
||||
});
|
||||
...children declared here
|
||||
Clay_CloseElement();
|
||||
Clay__CloseElement();
|
||||
|
||||
The for loop will only ever run a single iteration, putting Clay__CloseElement() in the increment of the loop
|
||||
means that it will run after the body - where the children are declared. It just exists to make sure you don't forget
|
||||
to call Clay_CloseElement().
|
||||
*/
|
||||
#define CLAY(...) \
|
||||
#define CLAY_AUTO_ID(...) \
|
||||
for ( \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElement(), Clay__ConfigureOpenElement(CLAY__CONFIG_WRAPPER(Clay_ElementDeclaration, __VA_ARGS__)), 0); \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH < 1; \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH=1, Clay__CloseElement() \
|
||||
)
|
||||
|
||||
#define CLAY(id, ...) \
|
||||
for ( \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElementWithId(id), Clay__ConfigureOpenElement(CLAY__CONFIG_WRAPPER(Clay_ElementDeclaration, __VA_ARGS__)), 0); \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH < 1; \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH=1, Clay__CloseElement() \
|
||||
)
|
||||
|
||||
// These macros exist to allow the CLAY() macro to be called both with an inline struct definition, such as
|
||||
// CLAY({ .id = something... });
|
||||
// As well as by passing a predefined declaration struct
|
||||
|
@ -739,9 +747,6 @@ typedef struct Clay_PointerData {
|
|||
} Clay_PointerData;
|
||||
|
||||
typedef struct Clay_ElementDeclaration {
|
||||
// Primarily created via the CLAY_ID(), CLAY_IDI(), CLAY_ID_LOCAL() and CLAY_IDI_LOCAL() macros.
|
||||
// Represents a hashed string ID used for identifying and finding specific clay UI elements, required by functions such as Clay_PointerOver() and Clay_GetElementData().
|
||||
Clay_ElementId id;
|
||||
// Controls various settings that affect the size and position of an element, as well as the sizes and positions of any child elements.
|
||||
Clay_LayoutConfig layout;
|
||||
// Controls the background color of the resulting element.
|
||||
|
@ -788,6 +793,8 @@ typedef CLAY_PACKED_ENUM {
|
|||
CLAY_ERROR_TYPE_PERCENTAGE_OVER_1,
|
||||
// Clay encountered an internal error. It would be wonderful if you could report this so we can fix it!
|
||||
CLAY_ERROR_TYPE_INTERNAL_ERROR,
|
||||
// Clay__OpenElement was called more times than Clay__CloseElement, so there were still remaining open elements when the layout ended.
|
||||
CLAY_ERROR_TYPE_UNBALANCED_OPEN_CLOSE,
|
||||
} Clay_ErrorType;
|
||||
|
||||
// Data to identify the error that clay has encountered.
|
||||
|
@ -915,10 +922,12 @@ CLAY_DLL_EXPORT void Clay_ResetMeasureTextCache(void);
|
|||
// Internal API functions required by macros ----------------------
|
||||
|
||||
CLAY_DLL_EXPORT void Clay__OpenElement(void);
|
||||
CLAY_DLL_EXPORT void Clay__OpenElementWithId(Clay_ElementId elementId);
|
||||
CLAY_DLL_EXPORT void Clay__ConfigureOpenElement(const Clay_ElementDeclaration config);
|
||||
CLAY_DLL_EXPORT void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *config);
|
||||
CLAY_DLL_EXPORT void Clay__CloseElement(void);
|
||||
CLAY_DLL_EXPORT Clay_ElementId Clay__HashString(Clay_String key, uint32_t offset, uint32_t seed);
|
||||
CLAY_DLL_EXPORT Clay_ElementId Clay__HashString(Clay_String key, uint32_t seed);
|
||||
CLAY_DLL_EXPORT Clay_ElementId Clay__HashStringWithOffset(Clay_String key, uint32_t offset, uint32_t seed);
|
||||
CLAY_DLL_EXPORT void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig);
|
||||
CLAY_DLL_EXPORT Clay_TextElementConfig *Clay__StoreTextElementConfig(Clay_TextElementConfig config);
|
||||
CLAY_DLL_EXPORT uint32_t Clay__GetParentElementId(void);
|
||||
|
@ -1173,7 +1182,6 @@ typedef struct { // todo get this struct into a single cache line
|
|||
intptr_t hoverFunctionUserData;
|
||||
int32_t nextIndex;
|
||||
uint32_t generation;
|
||||
uint32_t idAlias;
|
||||
Clay__DebugElementData *debugData;
|
||||
} Clay_LayoutElementHashMapItem;
|
||||
|
||||
|
@ -1283,15 +1291,12 @@ struct Clay_Context {
|
|||
|
||||
Clay_Context* Clay__Context_Allocate_Arena(Clay_Arena *arena) {
|
||||
size_t totalSizeBytes = sizeof(Clay_Context);
|
||||
uintptr_t memoryAddress = (uintptr_t)arena->memory;
|
||||
// Make sure the memory address passed in for clay to use is cache line aligned
|
||||
uintptr_t nextAllocOffset = (memoryAddress % 64);
|
||||
if (nextAllocOffset + totalSizeBytes > arena->capacity)
|
||||
if (totalSizeBytes > arena->capacity)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
arena->nextAllocation = nextAllocOffset + totalSizeBytes;
|
||||
return (Clay_Context*)(memoryAddress + nextAllocOffset);
|
||||
arena->nextAllocation += totalSizeBytes;
|
||||
return (Clay_Context*)(arena->memory);
|
||||
}
|
||||
|
||||
Clay_String Clay__WriteStringToCharBuffer(Clay__charArray *buffer, Clay_String string) {
|
||||
|
@ -1362,7 +1367,22 @@ Clay_ElementId Clay__HashNumber(const uint32_t offset, const uint32_t seed) {
|
|||
return CLAY__INIT(Clay_ElementId) { .id = hash + 1, .offset = offset, .baseId = seed, .stringId = CLAY__STRING_DEFAULT }; // Reserve the hash result of zero as "null id"
|
||||
}
|
||||
|
||||
Clay_ElementId Clay__HashString(Clay_String key, const uint32_t offset, const uint32_t seed) {
|
||||
Clay_ElementId Clay__HashString(Clay_String key, const uint32_t seed) {
|
||||
uint32_t hash = seed;
|
||||
|
||||
for (int32_t i = 0; i < key.length; i++) {
|
||||
hash += key.chars[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return CLAY__INIT(Clay_ElementId) { .id = hash + 1, .offset = 0, .baseId = hash + 1, .stringId = key }; // Reserve the hash result of zero as "null id"
|
||||
}
|
||||
|
||||
Clay_ElementId Clay__HashStringWithOffset(Clay_String key, const uint32_t offset, const uint32_t seed) {
|
||||
uint32_t hash = 0;
|
||||
uint32_t base = seed;
|
||||
|
||||
|
@ -1645,7 +1665,10 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
|||
char current = text->chars[end];
|
||||
if (current == ' ' || current == '\n') {
|
||||
int32_t length = end - start;
|
||||
Clay_Dimensions dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = length, .chars = &text->chars[start], .baseChars = text->chars }, config, context->measureTextUserData);
|
||||
Clay_Dimensions dimensions = CLAY__DEFAULT_STRUCT;
|
||||
if (length > 0) {
|
||||
dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) {.length = length, .chars = &text->chars[start], .baseChars = text->chars}, config, context->measureTextUserData);
|
||||
}
|
||||
measured->minWidth = CLAY__MAX(dimensions.width, measured->minWidth);
|
||||
measuredHeight = CLAY__MAX(measuredHeight, dimensions.height);
|
||||
if (current == ' ') {
|
||||
|
@ -1692,12 +1715,12 @@ bool Clay__PointIsInsideRect(Clay_Vector2 point, Clay_BoundingBox rect) {
|
|||
return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height;
|
||||
}
|
||||
|
||||
Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement, uint32_t idAlias) {
|
||||
Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
if (context->layoutElementsHashMapInternal.length == context->layoutElementsHashMapInternal.capacity - 1) {
|
||||
return NULL;
|
||||
}
|
||||
Clay_LayoutElementHashMapItem item = { .elementId = elementId, .layoutElement = layoutElement, .nextIndex = -1, .generation = context->generation + 1, .idAlias = idAlias };
|
||||
Clay_LayoutElementHashMapItem item = { .elementId = elementId, .layoutElement = layoutElement, .nextIndex = -1, .generation = context->generation + 1 };
|
||||
uint32_t hashBucket = elementId.id % context->layoutElementsHashMap.capacity;
|
||||
int32_t hashItemPrevious = -1;
|
||||
int32_t hashItemIndex = context->layoutElementsHashMap.internalArray[hashBucket];
|
||||
|
@ -1707,7 +1730,6 @@ Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Cl
|
|||
item.nextIndex = hashItem->nextIndex;
|
||||
if (hashItem->generation <= context->generation) { // First collision - assume this is the "same" element
|
||||
hashItem->elementId = elementId; // Make sure to copy this across. If the stringId reference has changed, we should update the hash item to use the new one.
|
||||
hashItem->idAlias = idAlias;
|
||||
hashItem->generation = context->generation + 1;
|
||||
hashItem->layoutElement = layoutElement;
|
||||
hashItem->debugData->collision = false;
|
||||
|
@ -1756,7 +1778,7 @@ Clay_ElementId Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayou
|
|||
Clay_LayoutElement *parentElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2));
|
||||
Clay_ElementId elementId = Clay__HashNumber(parentElement->childrenOrTextContent.children.length, parentElement->id);
|
||||
openLayoutElement->id = elementId.id;
|
||||
Clay__AddHashMapItem(elementId, openLayoutElement, 0);
|
||||
Clay__AddHashMapItem(elementId, openLayoutElement);
|
||||
Clay__StringArray_Add(&context->layoutElementIdStrings, elementId.stringId);
|
||||
return elementId;
|
||||
}
|
||||
|
@ -1795,13 +1817,17 @@ void Clay__CloseElement(void) {
|
|||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
Clay_LayoutConfig *layoutConfig = openLayoutElement->layoutConfig;
|
||||
bool elementHasScrollHorizontal = false;
|
||||
bool elementHasScrollVertical = false;
|
||||
if (!layoutConfig) {
|
||||
openLayoutElement->layoutConfig = &Clay_LayoutConfig_DEFAULT;
|
||||
layoutConfig = &Clay_LayoutConfig_DEFAULT;
|
||||
}
|
||||
bool elementHasClipHorizontal = false;
|
||||
bool elementHasClipVertical = false;
|
||||
for (int32_t i = 0; i < openLayoutElement->elementConfigs.length; i++) {
|
||||
Clay_ElementConfig *config = Clay__ElementConfigArraySlice_Get(&openLayoutElement->elementConfigs, i);
|
||||
if (config->type == CLAY__ELEMENT_CONFIG_TYPE_CLIP) {
|
||||
elementHasScrollHorizontal = config->config.clipElementConfig->horizontal;
|
||||
elementHasScrollVertical = config->config.clipElementConfig->vertical;
|
||||
elementHasClipHorizontal = config->config.clipElementConfig->horizontal;
|
||||
elementHasClipVertical = config->config.clipElementConfig->vertical;
|
||||
context->openClipElementStack.length--;
|
||||
break;
|
||||
} else if (config->type == CLAY__ELEMENT_CONFIG_TYPE_FLOATING) {
|
||||
|
@ -1822,19 +1848,21 @@ void Clay__CloseElement(void) {
|
|||
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 + topBottomPadding);
|
||||
// Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
|
||||
if (!elementHasScrollHorizontal) {
|
||||
// Minimum size of child elements doesn't matter to clip containers as they can shrink and hide their contents
|
||||
if (!elementHasClipHorizontal) {
|
||||
openLayoutElement->minDimensions.width += child->minDimensions.width;
|
||||
}
|
||||
if (!elementHasScrollVertical) {
|
||||
if (!elementHasClipVertical) {
|
||||
openLayoutElement->minDimensions.height = CLAY__MAX(openLayoutElement->minDimensions.height, child->minDimensions.height + topBottomPadding);
|
||||
}
|
||||
Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
|
||||
}
|
||||
float childGap = (float)(CLAY__MAX(openLayoutElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
|
||||
openLayoutElement->dimensions.width += childGap; // TODO this is technically a bug with childgap and scroll containers
|
||||
openLayoutElement->dimensions.width += childGap;
|
||||
if (!elementHasClipHorizontal) {
|
||||
openLayoutElement->minDimensions.width += childGap;
|
||||
}
|
||||
}
|
||||
else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
|
||||
openLayoutElement->dimensions.height = topBottomPadding;
|
||||
openLayoutElement->minDimensions.height = topBottomPadding;
|
||||
|
@ -1843,19 +1871,21 @@ void Clay__CloseElement(void) {
|
|||
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 + leftRightPadding);
|
||||
// Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
|
||||
if (!elementHasScrollVertical) {
|
||||
// Minimum size of child elements doesn't matter to clip containers as they can shrink and hide their contents
|
||||
if (!elementHasClipVertical) {
|
||||
openLayoutElement->minDimensions.height += child->minDimensions.height;
|
||||
}
|
||||
if (!elementHasScrollHorizontal) {
|
||||
if (!elementHasClipHorizontal) {
|
||||
openLayoutElement->minDimensions.width = CLAY__MAX(openLayoutElement->minDimensions.width, child->minDimensions.width + leftRightPadding);
|
||||
}
|
||||
Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
|
||||
}
|
||||
float childGap = (float)(CLAY__MAX(openLayoutElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
|
||||
openLayoutElement->dimensions.height += childGap; // TODO this is technically a bug with childgap and scroll containers
|
||||
openLayoutElement->dimensions.height += childGap;
|
||||
if (!elementHasClipVertical) {
|
||||
openLayoutElement->minDimensions.height += childGap;
|
||||
}
|
||||
}
|
||||
|
||||
context->layoutElementChildrenBuffer.length -= openLayoutElement->childrenOrTextContent.children.length;
|
||||
|
||||
|
@ -1967,8 +1997,28 @@ void Clay__OpenElement(void) {
|
|||
return;
|
||||
}
|
||||
Clay_LayoutElement layoutElement = CLAY__DEFAULT_STRUCT;
|
||||
Clay_LayoutElementArray_Add(&context->layoutElements, layoutElement);
|
||||
Clay_LayoutElement* openLayoutElement = Clay_LayoutElementArray_Add(&context->layoutElements, layoutElement);
|
||||
Clay__int32_tArray_Add(&context->openLayoutElementStack, context->layoutElements.length - 1);
|
||||
Clay__GenerateIdForAnonymousElement(openLayoutElement);
|
||||
if (context->openClipElementStack.length > 0) {
|
||||
Clay__int32_tArray_Set(&context->layoutElementClipElementIds, context->layoutElements.length - 1, Clay__int32_tArray_GetValue(&context->openClipElementStack, (int)context->openClipElementStack.length - 1));
|
||||
} else {
|
||||
Clay__int32_tArray_Set(&context->layoutElementClipElementIds, context->layoutElements.length - 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Clay__OpenElementWithId(Clay_ElementId elementId) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
if (context->layoutElements.length == context->layoutElements.capacity - 1 || context->booleanWarnings.maxElementsExceeded) {
|
||||
context->booleanWarnings.maxElementsExceeded = true;
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement layoutElement = CLAY__DEFAULT_STRUCT;
|
||||
layoutElement.id = elementId.id;
|
||||
Clay_LayoutElement * openLayoutElement = Clay_LayoutElementArray_Add(&context->layoutElements, layoutElement);
|
||||
Clay__int32_tArray_Add(&context->openLayoutElementStack, context->layoutElements.length - 1);
|
||||
Clay__AddHashMapItem(elementId, openLayoutElement);
|
||||
Clay__StringArray_Add(&context->layoutElementIdStrings, elementId.stringId);
|
||||
if (context->openClipElementStack.length > 0) {
|
||||
Clay__int32_tArray_Set(&context->layoutElementClipElementIds, context->layoutElements.length - 1, Clay__int32_tArray_GetValue(&context->openClipElementStack, (int)context->openClipElementStack.length - 1));
|
||||
} else {
|
||||
|
@ -1996,7 +2046,7 @@ void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig)
|
|||
Clay__MeasureTextCacheItem *textMeasured = Clay__MeasureTextCached(&text, textConfig);
|
||||
Clay_ElementId elementId = Clay__HashNumber(parentElement->childrenOrTextContent.children.length, parentElement->id);
|
||||
textElement->id = elementId.id;
|
||||
Clay__AddHashMapItem(elementId, textElement, 0);
|
||||
Clay__AddHashMapItem(elementId, textElement);
|
||||
Clay__StringArray_Add(&context->layoutElementIdStrings, elementId.stringId);
|
||||
Clay_Dimensions textDimensions = { .width = textMeasured->unwrappedDimensions.width, .height = textConfig->lineHeight > 0 ? (float)textConfig->lineHeight : textMeasured->unwrappedDimensions.height };
|
||||
textElement->dimensions = textDimensions;
|
||||
|
@ -2010,19 +2060,6 @@ void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig)
|
|||
parentElement->childrenOrTextContent.children.length++;
|
||||
}
|
||||
|
||||
Clay_ElementId Clay__AttachId(Clay_ElementId elementId) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
if (context->booleanWarnings.maxElementsExceeded) {
|
||||
return Clay_ElementId_DEFAULT;
|
||||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
uint32_t idAlias = openLayoutElement->id;
|
||||
openLayoutElement->id = elementId.id;
|
||||
Clay__AddHashMapItem(elementId, openLayoutElement, idAlias);
|
||||
Clay__StringArray_Set(&context->layoutElementIdStrings, context->layoutElements.length - 1, elementId.stringId);
|
||||
return elementId;
|
||||
}
|
||||
|
||||
void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
|
@ -2034,8 +2071,6 @@ void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
|
|||
.userData = context->errorHandler.userData });
|
||||
}
|
||||
|
||||
Clay_ElementId openLayoutElementId = declaration->id;
|
||||
|
||||
openLayoutElement->elementConfigs.internalArray = &context->elementConfigs.internalArray[context->elementConfigs.length];
|
||||
Clay_SharedElementConfig *sharedConfig = NULL;
|
||||
if (declaration->backgroundColor.a > 0) {
|
||||
|
@ -2088,10 +2123,7 @@ void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
|
|||
clipElementId = Clay__int32_tArray_GetValue(&context->layoutElementClipElementIds, (int32_t)(parentItem->layoutElement - context->layoutElements.internalArray));
|
||||
}
|
||||
} else if (declaration->floating.attachTo == CLAY_ATTACH_TO_ROOT) {
|
||||
floatingConfig.parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0, 0).id;
|
||||
}
|
||||
if (!openLayoutElementId.id) {
|
||||
openLayoutElementId = Clay__HashString(CLAY_STRING("Clay__FloatingContainer"), context->layoutElementTreeRoots.length, 0);
|
||||
floatingConfig.parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0).id;
|
||||
}
|
||||
if (declaration->floating.clipTo == CLAY_CLIP_TO_NONE) {
|
||||
clipElementId = 0;
|
||||
|
@ -2112,12 +2144,6 @@ void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
|
|||
Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .customElementConfig = Clay__StoreCustomElementConfig(declaration->custom) }, CLAY__ELEMENT_CONFIG_TYPE_CUSTOM);
|
||||
}
|
||||
|
||||
if (openLayoutElementId.id != 0) {
|
||||
Clay__AttachId(openLayoutElementId);
|
||||
} else if (openLayoutElement->id == 0) {
|
||||
openLayoutElementId = Clay__GenerateIdForAnonymousElement(openLayoutElement);
|
||||
}
|
||||
|
||||
if (declaration->clip.horizontal | declaration->clip.vertical) {
|
||||
Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .clipElementConfig = Clay__StoreClipElementConfig(declaration->clip) }, CLAY__ELEMENT_CONFIG_TYPE_CLIP);
|
||||
Clay__int32_tArray_Add(&context->openClipElementStack, (int)openLayoutElement->id);
|
||||
|
@ -2191,7 +2217,7 @@ void Clay__InitializePersistentMemory(Clay_Context* context) {
|
|||
int32_t maxMeasureTextCacheWordCount = context->maxMeasureTextCacheWordCount;
|
||||
Clay_Arena *arena = &context->internalArena;
|
||||
|
||||
context->scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(10, arena);
|
||||
context->scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(100, arena);
|
||||
context->layoutElementsHashMapInternal = Clay__LayoutElementHashMapItemArray_Allocate_Arena(maxElementCount, arena);
|
||||
context->layoutElementsHashMap = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
|
||||
context->measureTextHashMapInternal = Clay__MeasureTextCacheItemArray_Allocate_Arena(maxElementCount, arena);
|
||||
|
@ -2227,17 +2253,37 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
|||
Clay_LayoutElementHashMapItem *parentItem = Clay__GetHashMapItem(floatingElementConfig->parentId);
|
||||
if (parentItem && parentItem != &Clay_LayoutElementHashMapItem_DEFAULT) {
|
||||
Clay_LayoutElement *parentLayoutElement = parentItem->layoutElement;
|
||||
if (rootElement->layoutConfig->sizing.width.type == CLAY__SIZING_TYPE_GROW) {
|
||||
switch (rootElement->layoutConfig->sizing.width.type) {
|
||||
case CLAY__SIZING_TYPE_GROW: {
|
||||
rootElement->dimensions.width = parentLayoutElement->dimensions.width;
|
||||
break;
|
||||
}
|
||||
if (rootElement->layoutConfig->sizing.height.type == CLAY__SIZING_TYPE_GROW) {
|
||||
case CLAY__SIZING_TYPE_PERCENT: {
|
||||
rootElement->dimensions.width = parentLayoutElement->dimensions.width * rootElement->layoutConfig->sizing.width.size.percent;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
switch (rootElement->layoutConfig->sizing.height.type) {
|
||||
case CLAY__SIZING_TYPE_GROW: {
|
||||
rootElement->dimensions.height = parentLayoutElement->dimensions.height;
|
||||
break;
|
||||
}
|
||||
case CLAY__SIZING_TYPE_PERCENT: {
|
||||
rootElement->dimensions.height = parentLayoutElement->dimensions.height * rootElement->layoutConfig->sizing.height.size.percent;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rootElement->layoutConfig->sizing.width.type != CLAY__SIZING_TYPE_PERCENT) {
|
||||
rootElement->dimensions.width = CLAY__MIN(CLAY__MAX(rootElement->dimensions.width, rootElement->layoutConfig->sizing.width.size.minMax.min), rootElement->layoutConfig->sizing.width.size.minMax.max);
|
||||
}
|
||||
if (rootElement->layoutConfig->sizing.height.type != CLAY__SIZING_TYPE_PERCENT) {
|
||||
rootElement->dimensions.height = CLAY__MIN(CLAY__MAX(rootElement->dimensions.height, rootElement->layoutConfig->sizing.height.size.minMax.min), rootElement->layoutConfig->sizing.height.size.minMax.max);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < bfsBuffer.length; ++i) {
|
||||
int32_t parentIndex = Clay__int32_tArray_GetValue(&bfsBuffer, i);
|
||||
|
@ -2512,7 +2558,7 @@ void Clay__CalculateFinalLayout(void) {
|
|||
// measuredWord->length == 0 means a newline character
|
||||
else if (measuredWord->length == 0 || lineWidth + measuredWord->width > containerElement->dimensions.width) {
|
||||
// Wrapped text lines list has overflowed, just render out the line
|
||||
bool finalCharIsSpace = textElementData->text.chars[lineStartOffset + lineLengthChars - 1] == ' ';
|
||||
bool finalCharIsSpace = textElementData->text.chars[CLAY__MAX(lineStartOffset + lineLengthChars - 1, 0)] == ' ';
|
||||
Clay__WrappedTextLineArray_Add(&context->wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { { lineWidth + (finalCharIsSpace ? -spaceWidth : 0), lineHeight }, { .length = lineLengthChars + (finalCharIsSpace ? -1 : 0), .chars = &textElementData->text.chars[lineStartOffset] } });
|
||||
textElementData->wrappedLines.length++;
|
||||
if (lineLengthChars == 0 || measuredWord->length == 0) {
|
||||
|
@ -2690,7 +2736,6 @@ void Clay__CalculateFinalLayout(void) {
|
|||
if (clipConfig->vertical) {
|
||||
rootPosition.y += clipConfig->childOffset.y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand) {
|
||||
.boundingBox = clipHashMapItem->boundingBox,
|
||||
|
@ -2747,12 +2792,6 @@ void Clay__CalculateFinalLayout(void) {
|
|||
Clay_LayoutElementHashMapItem *hashMapItem = Clay__GetHashMapItem(currentElement->id);
|
||||
if (hashMapItem) {
|
||||
hashMapItem->boundingBox = currentElementBoundingBox;
|
||||
if (hashMapItem->idAlias) {
|
||||
Clay_LayoutElementHashMapItem *hashMapItemAlias = Clay__GetHashMapItem(hashMapItem->idAlias);
|
||||
if (hashMapItemAlias) {
|
||||
hashMapItemAlias->boundingBox = currentElementBoundingBox;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t sortedConfigIndexes[20];
|
||||
|
@ -2927,6 +2966,7 @@ void Clay__CalculateFinalLayout(void) {
|
|||
default: break;
|
||||
}
|
||||
currentElementTreeNode->nextChildOffset.x += extraSpace;
|
||||
extraSpace = CLAY__MAX(0, extraSpace);
|
||||
} else {
|
||||
for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
|
||||
|
@ -2940,6 +2980,7 @@ void Clay__CalculateFinalLayout(void) {
|
|||
case CLAY_ALIGN_Y_CENTER: extraSpace /= 2; break;
|
||||
default: break;
|
||||
}
|
||||
extraSpace = CLAY__MAX(0, extraSpace);
|
||||
currentElementTreeNode->nextChildOffset.y += extraSpace;
|
||||
}
|
||||
|
||||
|
@ -3148,8 +3189,8 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
Clay__int32_tArray_Add(&dfsBuffer, (int32_t)root->layoutElementIndex);
|
||||
context->treeNodeVisited.internalArray[0] = false;
|
||||
if (rootIndex > 0) {
|
||||
CLAY({ .id = CLAY_IDI("Clay__DebugView_EmptyRowOuter", rootIndex), .layout = { .sizing = {.width = CLAY_SIZING_GROW(0)}, .padding = {CLAY__DEBUGVIEW_INDENT_WIDTH / 2, 0, 0, 0} } }) {
|
||||
CLAY({ .id = CLAY_IDI("Clay__DebugView_EmptyRow", rootIndex), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED((float)CLAY__DEBUGVIEW_ROW_HEIGHT) }}, .border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { .top = 1 } } }) {}
|
||||
CLAY(CLAY_IDI("Clay__DebugView_EmptyRowOuter", rootIndex), { .layout = { .sizing = {.width = CLAY_SIZING_GROW(0)}, .padding = {CLAY__DEBUGVIEW_INDENT_WIDTH / 2, 0, 0, 0} } }) {
|
||||
CLAY(CLAY_IDI("Clay__DebugView_EmptyRow", rootIndex), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED((float)CLAY__DEBUGVIEW_ROW_HEIGHT) }}, .border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { .top = 1 } } }) {}
|
||||
}
|
||||
layoutData.rowCount++;
|
||||
}
|
||||
|
@ -3179,11 +3220,10 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
if (context->debugSelectedElementId == currentElement->id) {
|
||||
layoutData.selectedElementRowIndex = layoutData.rowCount;
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("Clay__DebugView_ElementOuter", currentElement->id), .layout = Clay__DebugView_ScrollViewItemLayoutConfig }) {
|
||||
CLAY(CLAY_IDI("Clay__DebugView_ElementOuter", currentElement->id), { .layout = Clay__DebugView_ScrollViewItemLayoutConfig }) {
|
||||
// Collapse icon / button
|
||||
if (!(Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT) || currentElement->childrenOrTextContent.children.length == 0)) {
|
||||
CLAY({
|
||||
.id = CLAY_IDI("Clay__DebugView_CollapseElement", currentElement->id),
|
||||
CLAY(CLAY_IDI("Clay__DebugView_CollapseElement", currentElement->id), {
|
||||
.layout = { .sizing = {CLAY_SIZING_FIXED(16), CLAY_SIZING_FIXED(16)}, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
.border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = {1, 1, 1, 1, 0} },
|
||||
|
@ -3191,19 +3231,19 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
CLAY_TEXT((currentElementData && currentElementData->debugData->collapsed) ? CLAY_STRING("+") : CLAY_STRING("-"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
} else { // Square dot for empty containers
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_FIXED(16), CLAY_SIZING_FIXED(16)}, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER } } }) {
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_FIXED(8), CLAY_SIZING_FIXED(8)} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_3, .cornerRadius = CLAY_CORNER_RADIUS(2) }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_FIXED(16), CLAY_SIZING_FIXED(16)}, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER } } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_FIXED(8), CLAY_SIZING_FIXED(8)} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_3, .cornerRadius = CLAY_CORNER_RADIUS(2) }) {}
|
||||
}
|
||||
}
|
||||
// Collisions and offscreen info
|
||||
if (currentElementData) {
|
||||
if (currentElementData->debugData->collision) {
|
||||
CLAY({ .layout = { .padding = { 8, 8, 2, 2 }}, .border = { .color = {177, 147, 8, 255}, .width = {1, 1, 1, 1, 0} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = { 8, 8, 2, 2 }}, .border = { .color = {177, 147, 8, 255}, .width = {1, 1, 1, 1, 0} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Duplicate ID"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
if (offscreen) {
|
||||
CLAY({ .layout = { .padding = { 8, 8, 2, 2 } }, .border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { 1, 1, 1, 1, 0} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = { 8, 8, 2, 2 } }, .border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { 1, 1, 1, 1, 0} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Offscreen"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
|
@ -3220,12 +3260,12 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
Clay_Color backgroundColor = elementConfig->config.sharedElementConfig->backgroundColor;
|
||||
Clay_CornerRadius radius = elementConfig->config.sharedElementConfig->cornerRadius;
|
||||
if (backgroundColor.a > 0) {
|
||||
CLAY({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = labelColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = labelColor, .width = { 1, 1, 1, 1, 0} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = labelColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = labelColor, .width = { 1, 1, 1, 1, 0} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Color"), CLAY_TEXT_CONFIG({ .textColor = offscreen ? CLAY__DEBUGVIEW_COLOR_3 : CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
if (radius.bottomLeft > 0) {
|
||||
CLAY({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = labelColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = labelColor, .width = { 1, 1, 1, 1, 0 } } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = labelColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = labelColor, .width = { 1, 1, 1, 1, 0 } } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Radius"), CLAY_TEXT_CONFIG({ .textColor = offscreen ? CLAY__DEBUGVIEW_COLOR_3 : CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
|
@ -3234,7 +3274,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(elementConfig->type);
|
||||
Clay_Color backgroundColor = config.color;
|
||||
backgroundColor.a = 90;
|
||||
CLAY({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = config.color, .width = { 1, 1, 1, 1, 0 } } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = config.color, .width = { 1, 1, 1, 1, 0 } } }) {
|
||||
CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = offscreen ? CLAY__DEBUGVIEW_COLOR_3 : CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
|
@ -3245,8 +3285,8 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
layoutData.rowCount++;
|
||||
Clay__TextElementData *textElementData = currentElement->childrenOrTextContent.textElementData;
|
||||
Clay_TextElementConfig *rawTextConfig = offscreen ? CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }) : &Clay__DebugView_TextNameConfig;
|
||||
CLAY({ .layout = { .sizing = { .height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } } }) {
|
||||
CLAY({ .layout = { .sizing = {.width = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_INDENT_WIDTH + 16) } } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { .height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {.width = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_INDENT_WIDTH + 16) } } }) {}
|
||||
CLAY_TEXT(CLAY_STRING("\""), rawTextConfig);
|
||||
CLAY_TEXT(textElementData->text.length > 40 ? (CLAY__INIT(Clay_String) { .length = 40, .chars = textElementData->text.chars }) : textElementData->text, rawTextConfig);
|
||||
if (textElementData->text.length > 40) {
|
||||
|
@ -3274,7 +3314,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
}
|
||||
|
||||
if (context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
|
||||
Clay_ElementId collapseButtonId = Clay__HashString(CLAY_STRING("Clay__DebugView_CollapseElement"), 0, 0);
|
||||
Clay_ElementId collapseButtonId = Clay__HashString(CLAY_STRING("Clay__DebugView_CollapseElement"), 0);
|
||||
for (int32_t i = (int)context->pointerOverIds.length - 1; i >= 0; i--) {
|
||||
Clay_ElementId *elementId = Clay_ElementIdArray_Get(&context->pointerOverIds, i);
|
||||
if (elementId->baseId == collapseButtonId.baseId) {
|
||||
|
@ -3286,8 +3326,8 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
|||
}
|
||||
|
||||
if (highlightedElementId) {
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugView_ElementHighlight"), .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .floating = { .parentId = highlightedElementId, .zIndex = 32767, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH, .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID } }) {
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugView_ElementHighlightRectangle"), .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .backgroundColor = Clay__debugViewHighlightColor }) {}
|
||||
CLAY(CLAY_ID("Clay__DebugView_ElementHighlight"), { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .floating = { .parentId = highlightedElementId, .zIndex = 32767, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH, .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID } }) {
|
||||
CLAY(CLAY_ID("Clay__DebugView_ElementHighlightRectangle"), { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .backgroundColor = Clay__debugViewHighlightColor }) {}
|
||||
}
|
||||
}
|
||||
return layoutData;
|
||||
|
@ -3328,17 +3368,17 @@ void Clay__RenderDebugViewElementConfigHeader(Clay_String elementId, Clay__Eleme
|
|||
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(type);
|
||||
Clay_Color backgroundColor = config.color;
|
||||
backgroundColor.a = 90;
|
||||
CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(CLAY__DEBUGVIEW_OUTER_PADDING), .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } } }) {
|
||||
CLAY({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = config.color, .width = { 1, 1, 1, 1, 0 } } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(CLAY__DEBUGVIEW_OUTER_PADDING), .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = { 8, 8, 2, 2 } }, .backgroundColor = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = config.color, .width = { 1, 1, 1, 1, 0 } } }) {
|
||||
CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
CLAY_TEXT(elementId, CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE }));
|
||||
}
|
||||
}
|
||||
|
||||
void Clay__RenderDebugViewColor(Clay_Color color, Clay_TextElementConfig *textConfig) {
|
||||
CLAY({ .layout = { .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ r: "), textConfig);
|
||||
CLAY_TEXT(Clay__IntToString(color.r), textConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", g: "), textConfig);
|
||||
|
@ -3348,13 +3388,13 @@ void Clay__RenderDebugViewColor(Clay_Color color, Clay_TextElementConfig *textCo
|
|||
CLAY_TEXT(CLAY_STRING(", a: "), textConfig);
|
||||
CLAY_TEXT(Clay__IntToString(color.a), textConfig);
|
||||
CLAY_TEXT(CLAY_STRING(" }"), textConfig);
|
||||
CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_FIXED(10) } } }) {}
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 8), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 8)} }, .backgroundColor = color, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = CLAY__DEBUGVIEW_COLOR_4, .width = { 1, 1, 1, 1, 0 } } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { .width = CLAY_SIZING_FIXED(10) } } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 8), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 8)} }, .backgroundColor = color, .cornerRadius = CLAY_CORNER_RADIUS(4), .border = { .color = CLAY__DEBUGVIEW_COLOR_4, .width = { 1, 1, 1, 1, 0 } } }) {}
|
||||
}
|
||||
}
|
||||
|
||||
void Clay__RenderDebugViewCornerRadius(Clay_CornerRadius cornerRadius, Clay_TextElementConfig *textConfig) {
|
||||
CLAY({ .layout = { .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ topLeft: "), textConfig);
|
||||
CLAY_TEXT(Clay__IntToString(cornerRadius.topLeft), textConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", topRight: "), textConfig);
|
||||
|
@ -3377,7 +3417,7 @@ void HandleDebugViewCloseButtonInteraction(Clay_ElementId elementId, Clay_Pointe
|
|||
|
||||
void Clay__RenderDebugView(void) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
Clay_ElementId closeButtonId = Clay__HashString(CLAY_STRING("Clay__DebugViewTopHeaderCloseButtonOuter"), 0, 0);
|
||||
Clay_ElementId closeButtonId = Clay__HashString(CLAY_STRING("Clay__DebugViewTopHeaderCloseButtonOuter"), 0);
|
||||
if (context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
|
||||
for (int32_t i = 0; i < context->pointerOverIds.length; ++i) {
|
||||
Clay_ElementId *elementId = Clay_ElementIdArray_Get(&context->pointerOverIds, i);
|
||||
|
@ -3392,7 +3432,7 @@ void Clay__RenderDebugView(void) {
|
|||
uint32_t initialElementsLength = context->layoutElements.length;
|
||||
Clay_TextElementConfig *infoTextConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
|
||||
Clay_TextElementConfig *infoTitleConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
|
||||
Clay_ElementId scrollId = Clay__HashString(CLAY_STRING("Clay__DebugViewOuterScrollPane"), 0, 0);
|
||||
Clay_ElementId scrollId = Clay__HashString(CLAY_STRING("Clay__DebugViewOuterScrollPane"), 0);
|
||||
float scrollYOffset = 0;
|
||||
bool pointerInDebugView = context->pointerInfo.position.y < context->layoutDimensions.height - 300;
|
||||
for (int32_t i = 0; i < context->scrollContainerDatas.length; ++i) {
|
||||
|
@ -3413,16 +3453,16 @@ void Clay__RenderDebugView(void) {
|
|||
highlightedRow = -1;
|
||||
}
|
||||
Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT;
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugView"),
|
||||
CLAY(CLAY_ID("Clay__DebugView"), {
|
||||
.layout = { .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM },
|
||||
.floating = { .zIndex = 32765, .attachPoints = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_CENTER }, .attachTo = CLAY_ATTACH_TO_ROOT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT },
|
||||
.border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { .bottom = 1 } }
|
||||
}) {
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_2 }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_2 }) {
|
||||
CLAY_TEXT(CLAY_STRING("Clay Debug Tools"), infoTextConfig);
|
||||
CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
// Close button
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = {CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10)}, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} },
|
||||
.backgroundColor = {217,91,67,80},
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
|
@ -3432,18 +3472,18 @@ void Clay__RenderDebugView(void) {
|
|||
CLAY_TEXT(CLAY_STRING("x"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(1)} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_3 } ) {}
|
||||
CLAY({ .id = scrollId, .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .clip = { .horizontal = true, .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }, .backgroundColor = ((initialElementsLength + initialRootsLength) & 1) == 0 ? CLAY__DEBUGVIEW_COLOR_2 : CLAY__DEBUGVIEW_COLOR_1 }) {
|
||||
Clay_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0, 0);
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(1)} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_3 } ) {}
|
||||
CLAY(scrollId, { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .clip = { .horizontal = true, .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }, .backgroundColor = ((initialElementsLength + initialRootsLength) & 1) == 0 ? CLAY__DEBUGVIEW_COLOR_2 : CLAY__DEBUGVIEW_COLOR_1 }) {
|
||||
Clay_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0);
|
||||
// Element list
|
||||
CLAY({ .id = panelContentsId, .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .floating = { .zIndex = 32766, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH, .attachTo = CLAY_ATTACH_TO_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT } }) {
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = { CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY(panelContentsId, { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .floating = { .zIndex = 32766, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH, .attachTo = CLAY_ATTACH_TO_PARENT, .clipTo = CLAY_CLIP_TO_ATTACHED_PARENT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = { CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow);
|
||||
}
|
||||
}
|
||||
float contentWidth = Clay__GetHashMapItem(panelContentsId.id)->layoutElement->dimensions.width;
|
||||
CLAY({ .layout = { .sizing = {.width = CLAY_SIZING_FIXED(contentWidth) }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {.width = CLAY_SIZING_FIXED(contentWidth) }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {}
|
||||
for (int32_t i = 0; i < layoutData.rowCount; i++) {
|
||||
Clay_Color rowColor = (i & 1) == 0 ? CLAY__DEBUGVIEW_COLOR_2 : CLAY__DEBUGVIEW_COLOR_1;
|
||||
if (i == layoutData.selectedElementRowIndex) {
|
||||
|
@ -3454,22 +3494,22 @@ void Clay__RenderDebugView(void) {
|
|||
rowColor.g *= 1.25f;
|
||||
rowColor.b *= 1.25f;
|
||||
}
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }, .backgroundColor = rowColor } ) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }, .backgroundColor = rowColor } ) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
CLAY({ .layout = { .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_3 }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_3 }) {}
|
||||
if (context->debugSelectedElementId != 0) {
|
||||
Clay_LayoutElementHashMapItem *selectedItem = Clay__GetHashMapItem(context->debugSelectedElementId);
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .layoutDirection = CLAY_TOP_TO_BOTTOM },
|
||||
.backgroundColor = CLAY__DEBUGVIEW_COLOR_2 ,
|
||||
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
|
||||
.border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { .betweenChildren = 1 } }
|
||||
}) {
|
||||
CLAY({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Layout Config"), infoTextConfig);
|
||||
CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
if (selectedItem->elementId.stringId.length != 0) {
|
||||
CLAY_TEXT(selectedItem->elementId.stringId, infoTitleConfig);
|
||||
if (selectedItem->elementId.offset != 0) {
|
||||
|
@ -3481,10 +3521,10 @@ void Clay__RenderDebugView(void) {
|
|||
}
|
||||
Clay_Padding attributeConfigPadding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 8, 8};
|
||||
// Clay_LayoutConfig debug info
|
||||
CLAY({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
// .boundingBox
|
||||
CLAY_TEXT(CLAY_STRING("Bounding Box"), infoTitleConfig);
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ x: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(selectedItem->boundingBox.x), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", y: "), infoTextConfig);
|
||||
|
@ -3501,17 +3541,17 @@ void Clay__RenderDebugView(void) {
|
|||
CLAY_TEXT(layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM ? CLAY_STRING("TOP_TO_BOTTOM") : CLAY_STRING("LEFT_TO_RIGHT"), infoTextConfig);
|
||||
// .sizing
|
||||
CLAY_TEXT(CLAY_STRING("Sizing"), infoTitleConfig);
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("width: "), infoTextConfig);
|
||||
Clay__RenderDebugLayoutSizing(layoutConfig->sizing.width, infoTextConfig);
|
||||
}
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("height: "), infoTextConfig);
|
||||
Clay__RenderDebugLayoutSizing(layoutConfig->sizing.height, infoTextConfig);
|
||||
}
|
||||
// .padding
|
||||
CLAY_TEXT(CLAY_STRING("Padding"), infoTitleConfig);
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugViewElementInfoPadding") }) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoPadding"), { }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ left: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.left), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", right: "), infoTextConfig);
|
||||
|
@ -3527,7 +3567,7 @@ void Clay__RenderDebugView(void) {
|
|||
CLAY_TEXT(Clay__IntToString(layoutConfig->childGap), infoTextConfig);
|
||||
// .childAlignment
|
||||
CLAY_TEXT(CLAY_STRING("Child Alignment"), infoTitleConfig);
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ x: "), infoTextConfig);
|
||||
Clay_String alignX = CLAY_STRING("LEFT");
|
||||
if (layoutConfig->childAlignment.x == CLAY_ALIGN_X_CENTER) {
|
||||
|
@ -3553,7 +3593,7 @@ void Clay__RenderDebugView(void) {
|
|||
switch (elementConfig->type) {
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_SHARED: {
|
||||
Clay_SharedElementConfig *sharedConfig = elementConfig->config.sharedElementConfig;
|
||||
CLAY({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM }}) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM }}) {
|
||||
// .backgroundColor
|
||||
CLAY_TEXT(CLAY_STRING("Background Color"), infoTitleConfig);
|
||||
Clay__RenderDebugViewColor(sharedConfig->backgroundColor, infoTextConfig);
|
||||
|
@ -3565,7 +3605,7 @@ void Clay__RenderDebugView(void) {
|
|||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_TEXT: {
|
||||
Clay_TextElementConfig *textConfig = elementConfig->config.textElementConfig;
|
||||
CLAY({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY_AUTO_ID({ .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);
|
||||
|
@ -3604,10 +3644,19 @@ void Clay__RenderDebugView(void) {
|
|||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_ASPECT: {
|
||||
Clay_AspectRatioElementConfig *aspectRatioConfig = elementConfig->config.aspectRatioElementConfig;
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugViewElementInfoAspectRatioBody"), .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoAspectRatioBody"), { .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Aspect Ratio"), infoTitleConfig);
|
||||
// Aspect Ratio
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoAspectRatio"), { }) {
|
||||
CLAY_TEXT(Clay__IntToString(aspectRatioConfig->aspectRatio), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING("."), infoTextConfig);
|
||||
float frac = aspectRatioConfig->aspectRatio - (int)(aspectRatioConfig->aspectRatio);
|
||||
frac *= 100;
|
||||
if ((int)frac < 10) {
|
||||
CLAY_TEXT(CLAY_STRING("0"), infoTextConfig);
|
||||
}
|
||||
CLAY_TEXT(Clay__IntToString(frac), infoTextConfig);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3617,16 +3666,16 @@ void Clay__RenderDebugView(void) {
|
|||
if (Clay__ElementHasConfig(selectedItem->layoutElement, CLAY__ELEMENT_CONFIG_TYPE_ASPECT)) {
|
||||
aspectConfig = *Clay__FindElementConfigWithType(selectedItem->layoutElement, CLAY__ELEMENT_CONFIG_TYPE_ASPECT).aspectRatioElementConfig;
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugViewElementInfoImageBody"), .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoImageBody"), { .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
// Image Preview
|
||||
CLAY_TEXT(CLAY_STRING("Preview"), infoTitleConfig);
|
||||
CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(64, 128), .height = CLAY_SIZING_GROW(64, 128) }}, .aspectRatio = aspectConfig, .image = *imageConfig }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(64, 128), .height = CLAY_SIZING_GROW(64, 128) }}, .aspectRatio = aspectConfig, .image = *imageConfig }) {}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_CLIP: {
|
||||
Clay_ClipElementConfig *clipConfig = elementConfig->config.clipElementConfig;
|
||||
CLAY({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
// .vertical
|
||||
CLAY_TEXT(CLAY_STRING("Vertical"), infoTitleConfig);
|
||||
CLAY_TEXT(clipConfig->vertical ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig);
|
||||
|
@ -3638,10 +3687,10 @@ void Clay__RenderDebugView(void) {
|
|||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_FLOATING: {
|
||||
Clay_FloatingElementConfig *floatingConfig = elementConfig->config.floatingElementConfig;
|
||||
CLAY({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
// .offset
|
||||
CLAY_TEXT(CLAY_STRING("Offset"), infoTitleConfig);
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ x: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(floatingConfig->offset.x), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", y: "), infoTextConfig);
|
||||
|
@ -3650,7 +3699,7 @@ void Clay__RenderDebugView(void) {
|
|||
}
|
||||
// .expand
|
||||
CLAY_TEXT(CLAY_STRING("Expand"), infoTitleConfig);
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ width: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(floatingConfig->expand.width), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", height: "), infoTextConfig);
|
||||
|
@ -3666,7 +3715,7 @@ void Clay__RenderDebugView(void) {
|
|||
CLAY_TEXT(hashItem->elementId.stringId, infoTextConfig);
|
||||
// .attachPoints
|
||||
CLAY_TEXT(CLAY_STRING("Attach Points"), infoTitleConfig);
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ element: "), infoTextConfig);
|
||||
Clay_String attachPointElement = CLAY_STRING("LEFT_TOP");
|
||||
if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_LEFT_CENTER) {
|
||||
|
@ -3739,9 +3788,9 @@ void Clay__RenderDebugView(void) {
|
|||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_BORDER: {
|
||||
Clay_BorderElementConfig *borderConfig = elementConfig->config.borderElementConfig;
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugViewElementInfoBorderBody"), .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoBorderBody"), { .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Border Widths"), infoTitleConfig);
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_LEFT_TO_RIGHT } }) {
|
||||
CLAY_TEXT(CLAY_STRING("{ left: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(borderConfig->width.left), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", right: "), infoTextConfig);
|
||||
|
@ -3764,16 +3813,16 @@ void Clay__RenderDebugView(void) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugViewWarningsScrollPane"), .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .childGap = 6, .layoutDirection = CLAY_TOP_TO_BOTTOM }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_2, .clip = { .horizontal = true, .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningsScrollPane"), { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .childGap = 6, .layoutDirection = CLAY_TOP_TO_BOTTOM }, .backgroundColor = CLAY__DEBUGVIEW_COLOR_2, .clip = { .horizontal = true, .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
|
||||
Clay_TextElementConfig *warningConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugViewWarningItemHeader"), .layout = { .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningItemHeader"), { .layout = { .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Warnings"), warningConfig);
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("Clay__DebugViewWarningsTopBorder"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }, .backgroundColor = {200, 200, 200, 255} }) {}
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningsTopBorder"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }, .backgroundColor = {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({ .id = CLAY_IDI("Clay__DebugViewWarningItem", i), .layout = { .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY(CLAY_IDI("Clay__DebugViewWarningItem", i), { .layout = { .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
|
||||
CLAY_TEXT(warning.baseMessage, warningConfig);
|
||||
if (warning.dynamicMessage.length > 0) {
|
||||
CLAY_TEXT(warning.dynamicMessage, warningConfig);
|
||||
|
@ -3818,7 +3867,7 @@ Clay__Warning *Clay__WarningArray_Add(Clay__WarningArray *array, Clay__Warning i
|
|||
void* Clay__Array_Allocate_Arena(int32_t capacity, uint32_t itemSize, Clay_Arena *arena)
|
||||
{
|
||||
size_t totalSizeBytes = capacity * itemSize;
|
||||
uintptr_t nextAllocOffset = arena->nextAllocation + (64 - (arena->nextAllocation % 64));
|
||||
uintptr_t nextAllocOffset = arena->nextAllocation + ((64 - (arena->nextAllocation % 64)) & 63);
|
||||
if (nextAllocOffset + totalSizeBytes <= arena->capacity) {
|
||||
arena->nextAllocation = nextAllocOffset + totalSizeBytes;
|
||||
return (void*)((uintptr_t)arena->memory + (uintptr_t)nextAllocOffset);
|
||||
|
@ -3938,16 +3987,12 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
|
|||
Clay_BoundingBox elementBox = mapItem->boundingBox;
|
||||
elementBox.x -= root->pointerOffset.x;
|
||||
elementBox.y -= root->pointerOffset.y;
|
||||
if ((Clay__PointIsInsideRect(position, elementBox)) && (clipElementId == 0 || (Clay__PointIsInsideRect(position, clipItem->boundingBox)))) {
|
||||
if ((Clay__PointIsInsideRect(position, elementBox)) && (clipElementId == 0 || (Clay__PointIsInsideRect(position, clipItem->boundingBox)) || context->externalScrollHandlingEnabled)) {
|
||||
if (mapItem->onHoverFunction) {
|
||||
mapItem->onHoverFunction(mapItem->elementId, context->pointerInfo, mapItem->hoverFunctionUserData);
|
||||
}
|
||||
Clay_ElementIdArray_Add(&context->pointerOverIds, mapItem->elementId);
|
||||
found = true;
|
||||
|
||||
if (mapItem->idAlias != 0) {
|
||||
Clay_ElementIdArray_Add(&context->pointerOverIds, CLAY__INIT(Clay_ElementId) { .id = mapItem->idAlias });
|
||||
}
|
||||
}
|
||||
if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT)) {
|
||||
dfsBuffer.length--;
|
||||
|
@ -3986,6 +4031,10 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
|
|||
|
||||
CLAY_WASM_EXPORT("Clay_Initialize")
|
||||
Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler) {
|
||||
// Cacheline align memory passed in
|
||||
uintptr_t baseOffset = 64 - ((uintptr_t)arena.memory % 64);
|
||||
baseOffset = baseOffset == 64 ? 0 : baseOffset;
|
||||
arena.memory += baseOffset;
|
||||
Clay_Context *context = Clay__Context_Allocate_Arena(&arena);
|
||||
if (context == NULL) return NULL;
|
||||
// DEFAULTS
|
||||
|
@ -4167,9 +4216,8 @@ void Clay_BeginLayout(void) {
|
|||
rootDimensions.width -= (float)Clay__debugViewWidth;
|
||||
}
|
||||
context->booleanWarnings = CLAY__INIT(Clay_BooleanWarnings) CLAY__DEFAULT_STRUCT;
|
||||
Clay__OpenElement();
|
||||
Clay__OpenElementWithId(CLAY_ID("Clay__RootContainer"));
|
||||
Clay__ConfigureOpenElement(CLAY__INIT(Clay_ElementDeclaration) {
|
||||
.id = CLAY_ID("Clay__RootContainer"),
|
||||
.layout = { .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} }
|
||||
});
|
||||
Clay__int32_tArray_Add(&context->openLayoutElementStack, 0);
|
||||
|
@ -4198,20 +4246,25 @@ Clay_RenderCommandArray Clay_EndLayout(void) {
|
|||
.renderData = { .text = { .stringContents = CLAY__INIT(Clay_StringSlice) { .length = message.length, .chars = message.chars, .baseChars = message.chars }, .textColor = {255, 0, 0, 255}, .fontSize = 16 } },
|
||||
.commandType = CLAY_RENDER_COMMAND_TYPE_TEXT
|
||||
});
|
||||
} else {
|
||||
Clay__CalculateFinalLayout();
|
||||
}
|
||||
if (context->openLayoutElementStack.length > 1) {
|
||||
context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_UNBALANCED_OPEN_CLOSE,
|
||||
.errorText = CLAY_STRING("There were still open layout elements when EndLayout was called. This results from an unequal number of calls to Clay__OpenElement and Clay__CloseElement."),
|
||||
.userData = context->errorHandler.userData });
|
||||
}
|
||||
Clay__CalculateFinalLayout();
|
||||
return context->renderCommands;
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_GetElementId")
|
||||
Clay_ElementId Clay_GetElementId(Clay_String idString) {
|
||||
return Clay__HashString(idString, 0, 0);
|
||||
return Clay__HashString(idString, 0);
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_GetElementIdWithIndex")
|
||||
Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index) {
|
||||
return Clay__HashString(idString, index, 0);
|
||||
return Clay__HashStringWithOffset(idString, index, 0);
|
||||
}
|
||||
|
||||
bool Clay_Hovered(void) {
|
||||
|
|
|
@ -32,6 +32,7 @@ static inline Clay_Dimensions SDL_MeasureText(Clay_StringSlice text, Clay_TextEl
|
|||
TTF_Font *font = fonts[config->fontId];
|
||||
int width, height;
|
||||
|
||||
TTF_SetFontSize(font, config->fontSize);
|
||||
if (!TTF_GetStringSize(font, text.chars, text.length, &width, &height)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to measure text: %s", SDL_GetError());
|
||||
}
|
||||
|
@ -52,7 +53,7 @@ Clay_RenderCommandArray ClayImageSample_CreateLayout() {
|
|||
.height = CLAY_SIZING_GROW(0)
|
||||
};
|
||||
|
||||
CLAY({ .id = CLAY_ID("OuterContainer"),
|
||||
CLAY(CLAY_ID("OuterContainer"), {
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = layoutExpand,
|
||||
|
@ -60,17 +61,13 @@ Clay_RenderCommandArray ClayImageSample_CreateLayout() {
|
|||
.childGap = 16
|
||||
}
|
||||
}) {
|
||||
CLAY({
|
||||
.id = CLAY_ID("SampleImage"),
|
||||
CLAY(CLAY_ID("SampleImage"), {
|
||||
.layout = {
|
||||
.sizing = layoutExpand
|
||||
},
|
||||
.aspectRatio = { 23.0 / 42.0 },
|
||||
.image = {
|
||||
.imageData = sample_image,
|
||||
.sourceDimensions = {
|
||||
.width = 23,
|
||||
.height = 42
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -40,12 +40,12 @@ void Layout() {
|
|||
static Clay_Color BACKGROUND = { 0xF4, 0xEB, 0xE6, 255 };
|
||||
static Clay_Color ACCENT = { 0xFA, 0xE0, 0xD4, 255 };
|
||||
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM },
|
||||
.backgroundColor = BACKGROUND
|
||||
}) {
|
||||
CLAY({ .id = CLAY_ID("PageMargins"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) },
|
||||
CLAY(CLAY_ID("PageMargins"), { .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) },
|
||||
.padding = { 70, 70, 50, 50 }, // Some nice looking page margins
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 10}
|
||||
|
@ -54,9 +54,9 @@ void Layout() {
|
|||
CLAY_TEXT(CLAY_STRING("Features Overview"), CLAY_TEXT_CONFIG({ .fontId = FONT_CALLISTOGA, .textColor = PRIMARY, .fontSize = 24 }));
|
||||
|
||||
// Feature Box
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(0) }, .childGap = 10 }}) {
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(0) }}, .backgroundColor = ACCENT, .cornerRadius = CLAY_CORNER_RADIUS(12) }) {
|
||||
CLAY({ .layout = {.padding = CLAY_PADDING_ALL(20), .childGap = 4, .layoutDirection = CLAY_TOP_TO_BOTTOM }}) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(0) }, .childGap = 10 }}) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(0) }}, .backgroundColor = ACCENT, .cornerRadius = CLAY_CORNER_RADIUS(12) }) {
|
||||
CLAY_AUTO_ID({ .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, .fontId = FONT_QUICKSAND }));
|
||||
CLAY_TEXT(CLAY_STRING("- Declarative syntax"),
|
||||
|
@ -69,7 +69,7 @@ void Layout() {
|
|||
CLAY_TEXT_CONFIG({ .textColor = PRIMARY, .fontSize = 14, .fontId = FONT_QUICKSAND }));
|
||||
}
|
||||
}
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(10),
|
||||
|
@ -81,23 +81,23 @@ void Layout() {
|
|||
.cornerRadius = CLAY_CORNER_RADIUS(8)
|
||||
}) {
|
||||
// Profile picture
|
||||
CLAY({ .layout = {
|
||||
CLAY_AUTO_ID({ .layout = {
|
||||
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
|
||||
.padding = { 30, 30, 0, 0 },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }},
|
||||
.border = { .color = PRIMARY, .width = 2, 2, 2, 2 }, .cornerRadius = 10
|
||||
}) {
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_FIXED(32), CLAY_SIZING_FIXED(32) } }, .image = { .sourceDimensions = { 32, 32 }, .imageData = "resources/check.png" }});
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_FIXED(32), CLAY_SIZING_FIXED(32) } }, .image = { .imageData = "resources/check.png" }});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(16) } }});
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(16) } }});
|
||||
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childGap = 10, .layoutDirection = CLAY_TOP_TO_BOTTOM }}) {
|
||||
CLAY_AUTO_ID({ .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({ .fontId = FONT_CALLISTOGA, .fontSize = 24, .textColor = PRIMARY }));
|
||||
CLAY({ .layout = { .padding = CLAY_PADDING_ALL(10) }, .backgroundColor = ACCENT, .cornerRadius = 10 }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(10) }, .backgroundColor = ACCENT, .cornerRadius = 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. "
|
||||
|
|
|
@ -166,6 +166,7 @@
|
|||
{ name: 'link', ...stringDefinition },
|
||||
{ name: 'cursorPointer', type: 'uint8_t' },
|
||||
{ name: 'disablePointerEvents', type: 'uint8_t' },
|
||||
{ name: 'padding', type: 'uint16_t'}
|
||||
]};
|
||||
let renderCommandDefinition = {
|
||||
name: 'Clay_RenderCommand',
|
||||
|
@ -425,10 +426,13 @@
|
|||
if (!elementCache[renderCommand.id.value]) {
|
||||
let elementType = 'div';
|
||||
switch (renderCommand.commandType.value & 0xff) {
|
||||
case CLAY_RENDER_COMMAND_TYPE_TEXT:
|
||||
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
|
||||
// if (readStructAtAddress(renderCommand.renderData.rectangle.value, rectangleRenderDataDefinition).link.length.value > 0) { TODO reimplement links
|
||||
// elementType = 'a';
|
||||
// }
|
||||
if (renderCommand.userData.value !== 0) {
|
||||
if (readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition).link.length.value > 0) {
|
||||
elementType = 'a';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
|
||||
|
@ -549,7 +553,6 @@
|
|||
}
|
||||
case (CLAY_RENDER_COMMAND_TYPE_TEXT): {
|
||||
let config = renderCommand.renderData.text;
|
||||
let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition);
|
||||
let configMemory = JSON.stringify(config);
|
||||
let stringContents = new Uint8Array(memoryDataView.buffer.slice(config.stringContents.chars.value, config.stringContents.chars.value + config.stringContents.length.value));
|
||||
if (configMemory !== elementData.previousMemoryConfig) {
|
||||
|
@ -559,7 +562,23 @@
|
|||
element.style.color = `rgba(${textColor.r.value}, ${textColor.g.value}, ${textColor.b.value}, ${textColor.a.value})`;
|
||||
element.style.fontFamily = fontsById[config.fontId.value];
|
||||
element.style.fontSize = fontSize + 'px';
|
||||
if (renderCommand.userData.value !== 0) {
|
||||
let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition);
|
||||
element.style.pointerEvents = customData.disablePointerEvents.value ? 'none' : 'all';
|
||||
let linkContents = customData.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(customData.link.chars.value, customData.link.chars.value + customData.link.length.value))) : 0;
|
||||
memoryDataView.setUint32(0, renderCommand.id.value, true);
|
||||
if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) {
|
||||
window.location.href = linkContents;
|
||||
}
|
||||
if (linkContents.length > 0) {
|
||||
element.href = linkContents;
|
||||
}
|
||||
|
||||
if (linkContents.length > 0 || customData.cursorPointer.value) {
|
||||
element.style.pointerEvents = 'all';
|
||||
element.style.cursor = 'pointer';
|
||||
}
|
||||
}
|
||||
elementData.previousMemoryConfig = configMemory;
|
||||
}
|
||||
if (stringContents.length !== elementData.previousMemoryText.length || MemoryIsDifferent(stringContents, elementData.previousMemoryText, stringContents.length)) {
|
||||
|
|
Binary file not shown.
|
@ -166,6 +166,7 @@
|
|||
{ name: 'link', ...stringDefinition },
|
||||
{ name: 'cursorPointer', type: 'uint8_t' },
|
||||
{ name: 'disablePointerEvents', type: 'uint8_t' },
|
||||
{ name: 'padding', type: 'uint16_t'}
|
||||
]};
|
||||
let renderCommandDefinition = {
|
||||
name: 'Clay_RenderCommand',
|
||||
|
@ -425,10 +426,13 @@
|
|||
if (!elementCache[renderCommand.id.value]) {
|
||||
let elementType = 'div';
|
||||
switch (renderCommand.commandType.value & 0xff) {
|
||||
case CLAY_RENDER_COMMAND_TYPE_TEXT:
|
||||
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
|
||||
// if (readStructAtAddress(renderCommand.renderData.rectangle.value, rectangleRenderDataDefinition).link.length.value > 0) { TODO reimplement links
|
||||
// elementType = 'a';
|
||||
// }
|
||||
if (renderCommand.userData.value !== 0) {
|
||||
if (readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition).link.length.value > 0) {
|
||||
elementType = 'a';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
|
||||
|
@ -549,7 +553,6 @@
|
|||
}
|
||||
case (CLAY_RENDER_COMMAND_TYPE_TEXT): {
|
||||
let config = renderCommand.renderData.text;
|
||||
let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition);
|
||||
let configMemory = JSON.stringify(config);
|
||||
let stringContents = new Uint8Array(memoryDataView.buffer.slice(config.stringContents.chars.value, config.stringContents.chars.value + config.stringContents.length.value));
|
||||
if (configMemory !== elementData.previousMemoryConfig) {
|
||||
|
@ -559,7 +562,23 @@
|
|||
element.style.color = `rgba(${textColor.r.value}, ${textColor.g.value}, ${textColor.b.value}, ${textColor.a.value})`;
|
||||
element.style.fontFamily = fontsById[config.fontId.value];
|
||||
element.style.fontSize = fontSize + 'px';
|
||||
if (renderCommand.userData.value !== 0) {
|
||||
let customData = readStructAtAddress(renderCommand.userData.value, customHTMLDataDefinition);
|
||||
element.style.pointerEvents = customData.disablePointerEvents.value ? 'none' : 'all';
|
||||
let linkContents = customData.link.length.value > 0 ? textDecoder.decode(new Uint8Array(memoryDataView.buffer.slice(customData.link.chars.value, customData.link.chars.value + customData.link.length.value))) : 0;
|
||||
memoryDataView.setUint32(0, renderCommand.id.value, true);
|
||||
if (linkContents.length > 0 && (window.mouseDownThisFrame || window.touchDown) && instance.exports.Clay_PointerOver(0)) {
|
||||
window.location.href = linkContents;
|
||||
}
|
||||
if (linkContents.length > 0) {
|
||||
element.href = linkContents;
|
||||
}
|
||||
|
||||
if (linkContents.length > 0 || customData.cursorPointer.value) {
|
||||
element.style.pointerEvents = 'all';
|
||||
element.style.cursor = 'pointer';
|
||||
}
|
||||
}
|
||||
elementData.previousMemoryConfig = configMemory;
|
||||
}
|
||||
if (stringContents.length !== elementData.previousMemoryText.length || MemoryIsDifferent(stringContents, elementData.previousMemoryText, stringContents.length)) {
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct {
|
|||
|
||||
Arena frameArena = {};
|
||||
|
||||
typedef struct {
|
||||
typedef struct d {
|
||||
Clay_String link;
|
||||
bool cursorPointer;
|
||||
bool disablePointerEvents;
|
||||
|
@ -65,21 +65,21 @@ Clay_String* FrameAllocateString(Clay_String string) {
|
|||
}
|
||||
|
||||
void LandingPageBlob(int index, int fontSize, Clay_Color color, Clay_String text, Clay_String imageURL) {
|
||||
CLAY({ .id = CLAY_IDI("HeroBlob", index), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 480) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }, .border = { .color = color, .width = { 2, 2, 2, 2 }}, .cornerRadius = CLAY_CORNER_RADIUS(10) }) {
|
||||
CLAY({ .id = CLAY_IDI("CheckImage", index), .layout = { .sizing = { CLAY_SIZING_FIXED(32) } }, .aspectRatio = { 1 }, .image = { .imageData = FrameAllocateString(imageURL) } }) {}
|
||||
CLAY(CLAY_IDI("HeroBlob", index), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 480) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }, .border = { .color = color, .width = { 2, 2, 2, 2 }}, .cornerRadius = CLAY_CORNER_RADIUS(10) }) {
|
||||
CLAY(CLAY_IDI("CheckImage", index), { .layout = { .sizing = { CLAY_SIZING_FIXED(32) } }, .aspectRatio = { 1 }, .image = { .imageData = FrameAllocateString(imageURL) } }) {}
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = fontSize, .fontId = FONT_ID_BODY_24, .textColor = color }));
|
||||
}
|
||||
}
|
||||
|
||||
void LandingPageDesktop() {
|
||||
CLAY({ .id = CLAY_ID("LandingPage1Desktop"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(.min = windowHeight - 70) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } } }) {
|
||||
CLAY({ .id = CLAY_ID("LandingPage1"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }, .border = { .width = { .left = 2, .right = 2 }, .color = COLOR_RED } }) {
|
||||
CLAY({ .id = CLAY_ID("LeftText"), .layout = { .sizing = { .width = CLAY_SIZING_PERCENT(0.55f) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("LandingPage1Desktop"), { .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"), { .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }, .border = { .width = { .left = 2, .right = 2 }, .color = COLOR_RED } }) {
|
||||
CLAY(CLAY_ID("LeftText"), { .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({ .id = CLAY_ID("LandingPageSpacer"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } } }) {}
|
||||
CLAY(CLAY_ID("LandingPageSpacer"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } } }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay is laying out this webpage right now!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("HeroImageOuter"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_PERCENT(0.45f) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 } }) {
|
||||
CLAY(CLAY_ID("HeroImageOuter"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_PERCENT(0.45f) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 } }) {
|
||||
LandingPageBlob(1, 32, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), CLAY_STRING("/clay/images/check_5.png"));
|
||||
LandingPageBlob(2, 32, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), CLAY_STRING("/clay/images/check_4.png"));
|
||||
LandingPageBlob(3, 32, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), CLAY_STRING("/clay/images/check_3.png"));
|
||||
|
@ -91,13 +91,13 @@ void LandingPageDesktop() {
|
|||
}
|
||||
|
||||
void LandingPageMobile() {
|
||||
CLAY({ .id = CLAY_ID("LandingPage1Mobile"), .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({ .id = CLAY_ID("LeftText"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("LandingPage1Mobile"), { .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"), { .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({ .id = CLAY_ID("LandingPageSpacer"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } } }) {}
|
||||
CLAY(CLAY_ID("LandingPageSpacer"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } } }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay is laying out this webpage right now!"), CLAY_TEXT_CONFIG({ .fontSize = 32, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("HeroImageOuter"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 } }) {
|
||||
CLAY(CLAY_ID("HeroImageOuter"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 } }) {
|
||||
LandingPageBlob(1, 28, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), CLAY_STRING("/clay/images/check_5.png"));
|
||||
LandingPageBlob(2, 28, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), CLAY_STRING("/clay/images/check_4.png"));
|
||||
LandingPageBlob(3, 28, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), CLAY_STRING("/clay/images/check_3.png"));
|
||||
|
@ -108,17 +108,17 @@ void LandingPageMobile() {
|
|||
}
|
||||
|
||||
void FeatureBlocksDesktop() {
|
||||
CLAY({ .id = CLAY_ID("FeatureBlocksOuter"), .layout = { .sizing = { CLAY_SIZING_GROW(0) } } }) {
|
||||
CLAY({ .id = CLAY_ID("FeatureBlocksInner"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }, .border = { .width = { .betweenChildren = 2 }, .color = COLOR_RED } }) {
|
||||
CLAY(CLAY_ID("FeatureBlocksOuter"), { .layout = { .sizing = { CLAY_SIZING_GROW(0) } } }) {
|
||||
CLAY(CLAY_ID("FeatureBlocksInner"), { .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }, .border = { .width = { .betweenChildren = 2 }, .color = COLOR_RED } }) {
|
||||
Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED });
|
||||
CLAY({ .id = CLAY_ID("HFileBoxOuter"), .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({ .id = CLAY_ID("HFileIncludeOuter"), .layout = { .padding = {8, 4} }, .backgroundColor = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) }) {
|
||||
CLAY(CLAY_ID("HFileBoxOuter"), { .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"), { .layout = { .padding = {8, 4} }, .backgroundColor = 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({ .id = CLAY_ID("BringYourOwnRendererOuter"), .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("BringYourOwnRendererOuter"), { .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);
|
||||
|
@ -128,16 +128,16 @@ void FeatureBlocksDesktop() {
|
|||
}
|
||||
|
||||
void FeatureBlocksMobile() {
|
||||
CLAY({ .id = CLAY_ID("FeatureBlocksInner"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) } }, .border = { .width = { .betweenChildren = 2 }, .color = COLOR_RED } }) {
|
||||
CLAY(CLAY_ID("FeatureBlocksInner"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) } }, .border = { .width = { .betweenChildren = 2 }, .color = COLOR_RED } }) {
|
||||
Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED });
|
||||
CLAY({ .id = CLAY_ID("HFileBoxOuter"), .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({ .id = CLAY_ID("HFileIncludeOuter"), .layout = { .padding = {8, 4} }, .backgroundColor = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) }) {
|
||||
CLAY(CLAY_ID("HFileBoxOuter"), { .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"), { .layout = { .padding = {8, 4} }, .backgroundColor = 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({ .id = CLAY_ID("BringYourOwnRendererOuter"), .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("BringYourOwnRendererOuter"), { .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);
|
||||
|
@ -146,33 +146,33 @@ void FeatureBlocksMobile() {
|
|||
}
|
||||
|
||||
void DeclarativeSyntaxPageDesktop() {
|
||||
CLAY({ .id = CLAY_ID("SyntaxPageDesktop"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } } }) {
|
||||
CLAY({ .id = CLAY_ID("SyntaxPage"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }, .border = { .width = { .left = 2, .right = 2 }, .color = COLOR_RED }}) {
|
||||
CLAY({ .id = CLAY_ID("SyntaxPageLeftText"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("SyntaxPageDesktop"), { .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"), { .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }, .border = { .width = { .left = 2, .right = 2 }, .color = COLOR_RED }}) {
|
||||
CLAY(CLAY_ID("SyntaxPageLeftText"), { .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({ .id = CLAY_ID("SyntaxSpacer"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) } } }) {}
|
||||
CLAY(CLAY_ID("SyntaxSpacer"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) } } }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Flexible and readable declarative syntax with nested UI element hierarchies."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Mix elements with standard C code like loops, conditionals and functions."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Create your own library of re-usable components from UI primitives like text, images and rectangles."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("SyntaxPageRightImage"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY({ .id = CLAY_ID("SyntaxPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .aspectRatio = { 1136.0 / 1194.0 }, .image = { .imageData = FrameAllocateString(CLAY_STRING("/clay/images/declarative.png")) } }) {}
|
||||
CLAY(CLAY_ID("SyntaxPageRightImage"), { .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY(CLAY_ID("SyntaxPageRightImageInner"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .aspectRatio = { 1136.0 / 1194.0 }, .image = { .imageData = FrameAllocateString(CLAY_STRING("/clay/images/declarative.png")) } }) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeclarativeSyntaxPageMobile() {
|
||||
CLAY({ .id = CLAY_ID("SyntaxPageDesktop"), .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({ .id = CLAY_ID("SyntaxPageLeftText"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("SyntaxPageDesktop"), { .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"), { .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({ .id = CLAY_ID("SyntaxSpacer"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) } } }) {}
|
||||
CLAY(CLAY_ID("SyntaxSpacer"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) } } }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Flexible and readable declarative syntax with nested UI element hierarchies."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Mix elements with standard C code like loops, conditionals and functions."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Create your own library of re-usable components from UI primitives like text, images and rectangles."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("SyntaxPageRightImage"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY({ .id = CLAY_ID("SyntaxPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .aspectRatio = { 1136.0 / 1194.0 }, .image = { .imageData = FrameAllocateString(CLAY_STRING("/clay/images/declarative.png")) } }) {}
|
||||
CLAY(CLAY_ID("SyntaxPageRightImage"), { .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY(CLAY_ID("SyntaxPageRightImageInner"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 568) } }, .aspectRatio = { 1136.0 / 1194.0 }, .image = { .imageData = FrameAllocateString(CLAY_STRING("/clay/images/declarative.png")) } }) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,20 +189,20 @@ 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({ .id = CLAY_ID("PerformanceOuter"), .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 }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY({ .id = CLAY_ID("PerformanceLeftText"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("PerformanceOuter"), { .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 }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY(CLAY_ID("PerformanceLeftText"), { .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({ .id = CLAY_ID("PerformanceSpacer"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY(CLAY_ID("PerformanceSpacer"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Fast enough to recompute your entire UI every frame."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Small memory footprint (3.5mb default) with static allocation & reuse. No malloc / free."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Simplify animations and reactive UI design by avoiding the standard performance hacks."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("PerformanceRightImageOuter"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }, .border = { .width = {2, 2, 2, 2}, .color = COLOR_LIGHT } }) {
|
||||
CLAY({ .id = CLAY_ID("AnimationDemoContainerLeft"), .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) }, .backgroundColor = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) }) {
|
||||
CLAY(CLAY_ID("PerformanceRightImageOuter"), { .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }, .border = { .width = {2, 2, 2, 2}, .color = COLOR_LIGHT } }) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerLeft"), { .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) }, .backgroundColor = 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({ .id = CLAY_ID("AnimationDemoContainerRight"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32) }, .backgroundColor = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) }) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerRight"), { .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32) }, .backgroundColor = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) }) {
|
||||
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
}
|
||||
|
@ -211,20 +211,20 @@ void HighPerformancePageDesktop(float lerpValue) {
|
|||
}
|
||||
|
||||
void HighPerformancePageMobile(float lerpValue) {
|
||||
CLAY({ .id = CLAY_ID("PerformanceOuter"), .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 }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY({ .id = CLAY_ID("PerformanceLeftText"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("PerformanceOuter"), { .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 }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY(CLAY_ID("PerformanceLeftText"), { .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({ .id = CLAY_ID("PerformanceSpacer"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY(CLAY_ID("PerformanceSpacer"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Fast enough to recompute your entire UI every frame."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Small memory footprint (3.5mb default) with static allocation & reuse. No malloc / free."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Simplify animations and reactive UI design by avoiding the standard performance hacks."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("PerformanceRightImageOuter"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY({ .id = CLAY_ID(""), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }, .border = { .width = { 2, 2, 2, 2 }, .color = COLOR_LIGHT }}) {
|
||||
CLAY({ .id = CLAY_ID("AnimationDemoContainerLeft"), .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) }, .backgroundColor = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) }) {
|
||||
CLAY(CLAY_ID("PerformanceRightImageOuter"), { .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }, .border = { .width = { 2, 2, 2, 2 }, .color = COLOR_LIGHT }}) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerLeft"), { .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) }, .backgroundColor = 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({ .id = CLAY_ID("AnimationDemoContainerRight"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(16) }, .backgroundColor = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) }) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerRight"), { .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(16) }, .backgroundColor = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) }) {
|
||||
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ void HandleRendererButtonInteraction(Clay_ElementId elementId, Clay_PointerData
|
|||
}
|
||||
|
||||
void RendererButtonActive(Clay_String text) {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = {CLAY_SIZING_FIXED(300) }, .padding = CLAY_PADDING_ALL(16) },
|
||||
.backgroundColor = Clay_Hovered() ? COLOR_RED_HOVER : COLOR_RED,
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||
|
@ -252,7 +252,7 @@ void RendererButtonActive(Clay_String text) {
|
|||
}
|
||||
|
||||
void RendererButtonInactive(Clay_String text, size_t rendererIndex) {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = {CLAY_SIZING_FIXED(300)}, .padding = CLAY_PADDING_ALL(16) },
|
||||
.border = { .width = {2, 2, 2, 2}, .color = COLOR_RED },
|
||||
.backgroundColor = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT,
|
||||
|
@ -265,18 +265,18 @@ void RendererButtonInactive(Clay_String text, size_t rendererIndex) {
|
|||
}
|
||||
|
||||
void RendererPageDesktop() {
|
||||
CLAY({ .id = CLAY_ID("RendererPageDesktop"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } } }) {
|
||||
CLAY({ .id = CLAY_ID("RendererPage"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }, .border = { .width = { .left = 2, .right = 2 }, .color = COLOR_RED } }) {
|
||||
CLAY({ .id = CLAY_ID("RendererLeftText"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("RendererPageDesktop"), { .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"), { .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }, .border = { .width = { .left = 2, .right = 2 }, .color = COLOR_RED } }) {
|
||||
CLAY(CLAY_ID("RendererLeftText"), { .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({ .id = CLAY_ID("RendererSpacerLeft"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY(CLAY_ID("RendererSpacerLeft"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay outputs a sorted array of primitive render commands, such as RECTANGLE, TEXT or IMAGE."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Write your own renderer in a few hundred lines of code, or use the provided examples for Raylib, WebGL canvas and more."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("There's even an HTML renderer - you're looking at it right now!"), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("RendererRightText"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.5) }, .childAlignment = {CLAY_ALIGN_X_CENTER}, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
|
||||
CLAY(CLAY_ID("RendererRightText"), { .layout = { .sizing = { CLAY_SIZING_PERCENT(0.5) }, .childAlignment = {CLAY_ALIGN_X_CENTER}, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Try changing renderer!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_BODY_36, .textColor = COLOR_ORANGE }));
|
||||
CLAY({ .id = CLAY_ID("RendererSpacerRight"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 32) } } }) {}
|
||||
CLAY(CLAY_ID("RendererSpacerRight"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 32) } } }) {}
|
||||
if (ACTIVE_RENDERER_INDEX == 0) {
|
||||
RendererButtonActive(CLAY_STRING("HTML Renderer"));
|
||||
RendererButtonInactive(CLAY_STRING("Canvas Renderer"), 1);
|
||||
|
@ -290,17 +290,17 @@ void RendererPageDesktop() {
|
|||
}
|
||||
|
||||
void RendererPageMobile() {
|
||||
CLAY({ .id = CLAY_ID("RendererMobile"), .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 }, .backgroundColor = COLOR_LIGHT }) {
|
||||
CLAY({ .id = CLAY_ID("RendererLeftText"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("RendererMobile"), { .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 }, .backgroundColor = COLOR_LIGHT }) {
|
||||
CLAY(CLAY_ID("RendererLeftText"), { .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({ .id = CLAY_ID("RendererSpacerLeft"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY(CLAY_ID("RendererSpacerLeft"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay outputs a sorted array of primitive render commands, such as RECTANGLE, TEXT or IMAGE."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Write your own renderer in a few hundred lines of code, or use the provided examples for Raylib, WebGL canvas and more."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("There's even an HTML renderer - you're looking at it right now!"), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("RendererRightText"), .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
|
||||
CLAY(CLAY_ID("RendererRightText"), { .layout = { .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Try changing renderer!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_BODY_36, .textColor = COLOR_ORANGE }));
|
||||
CLAY({ .id = CLAY_ID("RendererSpacerRight"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 32) }} }) {}
|
||||
CLAY(CLAY_ID("RendererSpacerRight"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 32) }} }) {}
|
||||
if (ACTIVE_RENDERER_INDEX == 0) {
|
||||
RendererButtonActive(CLAY_STRING("HTML Renderer"));
|
||||
RendererButtonInactive(CLAY_STRING("Canvas Renderer"), 1);
|
||||
|
@ -313,17 +313,17 @@ void RendererPageMobile() {
|
|||
}
|
||||
|
||||
void DebuggerPageDesktop() {
|
||||
CLAY({ .id = CLAY_ID("DebuggerDesktop"), .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 }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY({ .id = CLAY_ID("DebuggerLeftText"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 } }) {
|
||||
CLAY(CLAY_ID("DebuggerDesktop"), { .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 }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY(CLAY_ID("DebuggerLeftText"), { .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({ .id = CLAY_ID("DebuggerSpacer"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY(CLAY_ID("DebuggerSpacer"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 16) }} }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay includes built in \"Chrome Inspector\"-style debug tooling."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("View your layout hierarchy and config in real time."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY({ .id = CLAY_ID("DebuggerPageSpacer"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } } }) {}
|
||||
CLAY(CLAY_ID("DebuggerPageSpacer"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } } }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Press the \"d\" key to try it out now!"), CLAY_TEXT_CONFIG({ .fontSize = 32, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("DebuggerRightImageOuter"), .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY({ .id = CLAY_ID("DebuggerPageRightImageInner"), .layout = { .sizing = { CLAY_SIZING_GROW(.max = 558) } }, .aspectRatio = { 1620.0 / 1474.0 }, .image = {.imageData = FrameAllocateString(CLAY_STRING("/clay/images/debugger.png")) } }) {}
|
||||
CLAY(CLAY_ID("DebuggerRightImageOuter"), { .layout = { .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} } }) {
|
||||
CLAY(CLAY_ID("DebuggerPageRightImageInner"), { .layout = { .sizing = { CLAY_SIZING_GROW(.max = 558) } }, .aspectRatio = { 1620.0 / 1474.0 }, .image = {.imageData = FrameAllocateString(CLAY_STRING("/clay/images/debugger.png")) } }) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -340,44 +340,55 @@ float animationLerpValue = -1.0f;
|
|||
|
||||
Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
|
||||
Clay_BeginLayout();
|
||||
CLAY({ .id = CLAY_ID("OuterContainer"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) } }, .backgroundColor = COLOR_LIGHT }) {
|
||||
CLAY({ .id = CLAY_ID("Header"), .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(50) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = { 32, 32 } } }) {
|
||||
CLAY(CLAY_ID("OuterContainer"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) } }, .backgroundColor = COLOR_LIGHT }) {
|
||||
CLAY(CLAY_ID("Header"), { .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({ .id = CLAY_ID("Spacer"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
CLAY(CLAY_ID("Spacer"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
|
||||
if (!mobileScreen) {
|
||||
CLAY({ .id = CLAY_ID("LinkExamplesOuter"), .layout = { .padding = {8, 8} }, .userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples") }) }) {
|
||||
CLAY_TEXT(CLAY_STRING("Examples"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
CLAY(CLAY_ID("LinkExamplesOuter"), { .layout = { .padding = {8, 8} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Examples"), CLAY_TEXT_CONFIG({
|
||||
.userData = FrameAllocateCustomData((CustomHTMLData) {
|
||||
.link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples")
|
||||
}),
|
||||
.fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
}
|
||||
CLAY({ .id = CLAY_ID("LinkDocsOuter"), .layout = { .padding = {8, 8} }, .userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md") }) }) {
|
||||
CLAY_TEXT(CLAY_STRING("Docs"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
CLAY(CLAY_ID("LinkDocsOuter"), { .layout = { .padding = {8, 8} } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Docs"), CLAY_TEXT_CONFIG({
|
||||
.userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md") }),
|
||||
.fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} })
|
||||
);
|
||||
}
|
||||
}
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .padding = {16, 16, 6, 6} },
|
||||
.backgroundColor = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT,
|
||||
.border = { .width = {2, 2, 2, 2}, .color = COLOR_RED },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||
.userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples") }),
|
||||
.userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://discord.gg/b4FTWkxdvT") }),
|
||||
}) {
|
||||
CLAY_TEXT(CLAY_STRING("Discord"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
CLAY_TEXT(CLAY_STRING("Discord"), CLAY_TEXT_CONFIG({
|
||||
.userData = FrameAllocateCustomData((CustomHTMLData) { .disablePointerEvents = true }),
|
||||
.fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
}
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .padding = {16, 16, 6, 6} },
|
||||
.backgroundColor = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT,
|
||||
.border = { .width = {2, 2, 2, 2}, .color = COLOR_RED },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||
.userData = FrameAllocateCustomData((CustomHTMLData) { .link = CLAY_STRING("https://github.com/nicbarker/clay") }),
|
||||
}) {
|
||||
CLAY_TEXT(CLAY_STRING("Github"), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
CLAY_TEXT(CLAY_STRING("Github"), CLAY_TEXT_CONFIG({
|
||||
.userData = FrameAllocateCustomData((CustomHTMLData) { .disablePointerEvents = true }),
|
||||
.fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
}
|
||||
}
|
||||
Clay_LayoutConfig topBorderConfig = (Clay_LayoutConfig) { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(4) }};
|
||||
CLAY({ .id = CLAY_ID("TopBorder1"), .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_5 }) {}
|
||||
CLAY({ .id = CLAY_ID("TopBorder2"), .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_4 }) {}
|
||||
CLAY({ .id = CLAY_ID("TopBorder3"), .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_3 }) {}
|
||||
CLAY({ .id = CLAY_ID("TopBorder4"), .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_2 }) {}
|
||||
CLAY({ .id = CLAY_ID("TopBorder5"), .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_1 }) {}
|
||||
CLAY({ .id = CLAY_ID("OuterScrollContainer"),
|
||||
CLAY(CLAY_ID("TopBorder1"), { .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_5 }) {}
|
||||
CLAY(CLAY_ID("TopBorder2"), { .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_4 }) {}
|
||||
CLAY(CLAY_ID("TopBorder3"), { .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_3 }) {}
|
||||
CLAY(CLAY_ID("TopBorder4"), { .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_2 }) {}
|
||||
CLAY(CLAY_ID("TopBorder5"), { .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_1 }) {}
|
||||
CLAY(CLAY_ID("OuterScrollContainer"), {
|
||||
.layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM },
|
||||
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
|
||||
.border = { .width = { .betweenChildren = 2 }, .color = COLOR_RED }
|
||||
|
@ -408,8 +419,7 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
|
|||
scrollbarColor = (Clay_Color){225, 138, 50, 160};
|
||||
}
|
||||
float scrollHeight = scrollData.scrollContainerDimensions.height - 12;
|
||||
CLAY({
|
||||
.id = CLAY_ID("ScrollBar"),
|
||||
CLAY(CLAY_ID("ScrollBar"), {
|
||||
.floating = { .offset = { .x = -6, .y = -(scrollData.scrollPosition->y / scrollData.contentDimensions.height) * scrollHeight + 6}, .zIndex = 1, .parentId = Clay_GetElementId(CLAY_STRING("OuterScrollContainer")).id, .attachPoints = {.element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_TOP }, .attachTo = CLAY_ATTACH_TO_PARENT },
|
||||
.layout = { .sizing = {CLAY_SIZING_FIXED(10), CLAY_SIZING_FIXED((scrollHeight / scrollData.contentDimensions.height) * scrollHeight)} },
|
||||
.backgroundColor = scrollbarColor,
|
||||
|
|
|
@ -13,7 +13,7 @@ int main(void) {
|
|||
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, (char *)malloc(totalMemorySize));
|
||||
Clay_Initialize(clayMemory, Clay_Dimensions {1024,768}, Clay_ErrorHandler { HandleClayErrors });
|
||||
Clay_BeginLayout();
|
||||
CLAY({ .layout = layoutElement, .backgroundColor = {255,255,255,0} }) {
|
||||
CLAY_AUTO_ID({ .layout = layoutElement, .backgroundColor = {255,255,255,0} }) {
|
||||
CLAY_TEXT(CLAY_STRING(""), CLAY_TEXT_CONFIG({ .fontId = 0 }));
|
||||
}
|
||||
Clay_EndLayout();
|
||||
|
|
|
@ -18,7 +18,7 @@ Clay_Color COLOR_WHITE = { 255, 255, 255, 255 };
|
|||
Clay_Color COLOR_BLACK = { 0, 0, 0, 255 };
|
||||
|
||||
void RenderHeaderButton(Clay_String text) {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .padding = { 8, 8, 4, 4 } },
|
||||
.backgroundColor = COLOR_BLACK,
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4)
|
||||
|
@ -212,8 +212,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
};
|
||||
|
||||
// Build UI here
|
||||
CLAY({
|
||||
.id = CLAY_ID("OuterContainer"),
|
||||
CLAY(CLAY_ID("OuterContainer"), {
|
||||
.backgroundColor = COLOR_WHITE,
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
|
@ -223,8 +222,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
}
|
||||
}) {
|
||||
// Child elements go inside braces
|
||||
CLAY({
|
||||
.id = CLAY_ID("HeaderBar"),
|
||||
CLAY(CLAY_ID("HeaderBar"), {
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.height = CLAY_SIZING_FIXED(30),
|
||||
|
@ -235,8 +233,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
},
|
||||
}) {
|
||||
// Header buttons go here
|
||||
CLAY({
|
||||
.id = CLAY_ID("FileButton"),
|
||||
CLAY(CLAY_ID("FileButton"), {
|
||||
.layout = {
|
||||
.padding = { 8, 8, 4, 4 }
|
||||
},
|
||||
|
@ -252,18 +249,16 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
);
|
||||
}
|
||||
RenderHeaderButton(CLAY_STRING("Edit"));
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0) } } }) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_GROW(0) } } }) {}
|
||||
RenderHeaderButton(CLAY_STRING("Upload"));
|
||||
RenderHeaderButton(CLAY_STRING("Media"));
|
||||
RenderHeaderButton(CLAY_STRING("Support"));
|
||||
}
|
||||
|
||||
CLAY({
|
||||
.id = CLAY_ID("LowerContent"),
|
||||
CLAY(CLAY_ID("LowerContent"), {
|
||||
.layout = { .sizing = layoutExpand, .childGap = 8 },
|
||||
}) {
|
||||
CLAY({
|
||||
.id = CLAY_ID("Sidebar"),
|
||||
CLAY(CLAY_ID("Sidebar"), {
|
||||
.border = contentBorders,
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
.layout = {
|
||||
|
@ -284,7 +279,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
};
|
||||
|
||||
if (i == selectedDocumentIndex) {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = sidebarButtonLayout,
|
||||
.backgroundColor = COLOR_BLACK,
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4)
|
||||
|
@ -298,7 +293,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
);
|
||||
}
|
||||
} else {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = sidebarButtonLayout,
|
||||
.backgroundColor = (Clay_Color){ 0, 0, 0, Clay_Hovered() ? 120 : 0 },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
|
@ -316,8 +311,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
}
|
||||
}
|
||||
|
||||
CLAY({
|
||||
.id = CLAY_ID("MainContent"),
|
||||
CLAY(CLAY_ID("MainContent"), {
|
||||
.border = contentBorders,
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
|
||||
|
@ -329,7 +323,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
}
|
||||
}) {
|
||||
Document selectedDocument = documents.documents[selectedDocumentIndex];
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
.childGap = 4,
|
||||
|
@ -340,7 +334,7 @@ Clay_RenderCommandArray ClayVideoDemoPlaydate_CreateLayout(int selectedDocumentI
|
|||
selectedDocument.title,
|
||||
CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY, .textColor = COLOR_BLACK })
|
||||
);
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(32),
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,7 @@
|
|||
// NOTE: This file only exists to make sure that clay works when included in multiple translation units.
|
||||
|
||||
void SatisfyCompiler(void) {
|
||||
CLAY({ .id = CLAY_ID("SatisfyCompiler") }) {
|
||||
CLAY(CLAY_ID("SatisfyCompiler"), { }) {
|
||||
CLAY_TEXT(CLAY_STRING("Test"), CLAY_TEXT_CONFIG({ .fontId = 0, .fontSize = 24 }));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ const int FONT_ID_BODY_16 = 0;
|
|||
Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
|
||||
|
||||
void RenderHeaderButton(Clay_String text) {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .padding = { 16, 16, 8, 8 }},
|
||||
.backgroundColor = { 140, 140, 140, 255 },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(5)
|
||||
|
@ -19,7 +19,7 @@ void RenderHeaderButton(Clay_String text) {
|
|||
}
|
||||
|
||||
void RenderDropdownMenuItem(Clay_String text) {
|
||||
CLAY({.layout = { .padding = CLAY_PADDING_ALL(16)}}) {
|
||||
CLAY_AUTO_ID({.layout = { .padding = CLAY_PADDING_ALL(16)}}) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 16,
|
||||
|
@ -102,7 +102,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
Clay_Color contentBackgroundColor = { 90, 90, 90, 255 };
|
||||
|
||||
// Build UI here
|
||||
CLAY({ .id = CLAY_ID("OuterContainer"),
|
||||
CLAY(CLAY_ID("OuterContainer"), {
|
||||
.backgroundColor = {43, 41, 51, 255 },
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
|
@ -112,7 +112,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
}
|
||||
}) {
|
||||
// Child elements go inside braces
|
||||
CLAY({ .id = CLAY_ID("HeaderBar"),
|
||||
CLAY(CLAY_ID("HeaderBar"), {
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.height = CLAY_SIZING_FIXED(60),
|
||||
|
@ -128,7 +128,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
.cornerRadius = CLAY_CORNER_RADIUS(8)
|
||||
}) {
|
||||
// Header buttons go here
|
||||
CLAY({ .id = CLAY_ID("FileButton"),
|
||||
CLAY(CLAY_ID("FileButton"), {
|
||||
.layout = { .padding = { 16, 16, 8, 8 }},
|
||||
.backgroundColor = {140, 140, 140, 255 },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(5)
|
||||
|
@ -145,7 +145,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
Clay_PointerOver(Clay_GetElementId(CLAY_STRING("FileMenu")));
|
||||
|
||||
if (fileMenuVisible) { // Below has been changed slightly to fix the small bug where the menu would dismiss when mousing over the top gap
|
||||
CLAY({ .id = CLAY_ID("FileMenu"),
|
||||
CLAY(CLAY_ID("FileMenu"), {
|
||||
.floating = {
|
||||
.attachTo = CLAY_ATTACH_TO_PARENT,
|
||||
.attachPoints = {
|
||||
|
@ -156,7 +156,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
.padding = {0, 0, 8, 8 }
|
||||
}
|
||||
}) {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = {
|
||||
|
@ -175,18 +175,16 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
}
|
||||
}
|
||||
RenderHeaderButton(CLAY_STRING("Edit"));
|
||||
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0) }}}) {}
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = { CLAY_SIZING_GROW(0) }}}) {}
|
||||
RenderHeaderButton(CLAY_STRING("Upload"));
|
||||
RenderHeaderButton(CLAY_STRING("Media"));
|
||||
RenderHeaderButton(CLAY_STRING("Support"));
|
||||
}
|
||||
|
||||
CLAY({
|
||||
.id = CLAY_ID("LowerContent"),
|
||||
CLAY(CLAY_ID("LowerContent"), {
|
||||
.layout = { .sizing = layoutExpand, .childGap = 16 }
|
||||
}) {
|
||||
CLAY({
|
||||
.id = CLAY_ID("Sidebar"),
|
||||
CLAY(CLAY_ID("Sidebar"), {
|
||||
.backgroundColor = contentBackgroundColor,
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
|
@ -206,7 +204,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
};
|
||||
|
||||
if (i == data->selectedDocumentIndex) {
|
||||
CLAY({
|
||||
CLAY_AUTO_ID({
|
||||
.layout = sidebarButtonLayout,
|
||||
.backgroundColor = {120, 120, 120, 255 },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(8)
|
||||
|
@ -221,7 +219,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
SidebarClickData *clickData = (SidebarClickData *)(data->frameArena.memory + data->frameArena.offset);
|
||||
*clickData = (SidebarClickData) { .requestedDocumentIndex = i, .selectedDocumentIndex = &data->selectedDocumentIndex };
|
||||
data->frameArena.offset += sizeof(SidebarClickData);
|
||||
CLAY({ .layout = sidebarButtonLayout, .backgroundColor = (Clay_Color) { 120, 120, 120, Clay_Hovered() ? 120 : 0 }, .cornerRadius = CLAY_CORNER_RADIUS(8) }) {
|
||||
CLAY_AUTO_ID({ .layout = sidebarButtonLayout, .backgroundColor = (Clay_Color) { 120, 120, 120, Clay_Hovered() ? 120 : 0 }, .cornerRadius = CLAY_CORNER_RADIUS(8) }) {
|
||||
Clay_OnHover(HandleSidebarInteraction, (intptr_t)clickData);
|
||||
CLAY_TEXT(document.title, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
|
@ -233,7 +231,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
|
|||
}
|
||||
}
|
||||
|
||||
CLAY({ .id = CLAY_ID("MainContent"),
|
||||
CLAY(CLAY_ID("MainContent"), {
|
||||
.backgroundColor = contentBackgroundColor,
|
||||
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
|
||||
.layout = {
|
||||
|
|
|
@ -33,7 +33,7 @@ Clay_RenderCommandArray CornerRadiusTest(){
|
|||
.width = CLAY_SIZING_GROW(0),
|
||||
.height = CLAY_SIZING_GROW(0)
|
||||
};
|
||||
CLAY({ .id = CLAY_ID("OuterContainer"),
|
||||
CLAY(CLAY_ID("OuterContainer"), {
|
||||
.backgroundColor = {43, 41, 51, 255},
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
|
@ -43,7 +43,7 @@ Clay_RenderCommandArray CornerRadiusTest(){
|
|||
}
|
||||
}) {
|
||||
for(int i = 0; i < 6; ++i){
|
||||
CLAY({ .id = CLAY_IDI("Row", i),
|
||||
CLAY(CLAY_IDI("Row", i), {
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
.sizing = layoutExpand,
|
||||
|
@ -52,7 +52,7 @@ Clay_RenderCommandArray CornerRadiusTest(){
|
|||
}
|
||||
}) {
|
||||
for(int j = 0; j < 6; ++j){
|
||||
CLAY({ .id = CLAY_IDI("Tile", i*6+j),
|
||||
CLAY(CLAY_IDI("Tile", i*6+j), {
|
||||
.backgroundColor = {120, 140, 255, 128},
|
||||
.cornerRadius = {(i%3)*15, (j%3)*15, (i/2)*15, (j/2)*15},
|
||||
.border = {
|
||||
|
|
36
examples/termbox2-demo/CMakeLists.txt
Normal file
36
examples/termbox2-demo/CMakeLists.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
project(clay_examples_termbox2_demo C)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
|
||||
FetchContent_Declare(
|
||||
termbox2
|
||||
GIT_REPOSITORY "https://github.com/termbox/termbox2.git"
|
||||
GIT_TAG "9c9281a9a4c971a2be57f8645e828ec99fd555e8"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(termbox2)
|
||||
|
||||
FetchContent_Declare(
|
||||
stb
|
||||
GIT_REPOSITORY "https://github.com/nothings/stb.git"
|
||||
GIT_TAG "f58f558c120e9b32c217290b80bad1a0729fbb2c"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(stb)
|
||||
|
||||
add_executable(clay_examples_termbox2_demo main.c)
|
||||
|
||||
target_compile_options(clay_examples_termbox2_demo PUBLIC)
|
||||
target_include_directories(clay_examples_termbox2_demo PUBLIC . PRIVATE ${termbox2_SOURCE_DIR} PRIVATE ${stb_SOURCE_DIR})
|
||||
target_link_libraries(clay_examples_termbox2_demo PRIVATE m) # Used by stb_image.h
|
||||
|
||||
add_custom_command(
|
||||
TARGET clay_examples_termbox2_demo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources
|
||||
${CMAKE_CURRENT_BINARY_DIR}/resources)
|
789
examples/termbox2-demo/main.c
Normal file
789
examples/termbox2-demo/main.c
Normal file
|
@ -0,0 +1,789 @@
|
|||
/*
|
||||
Unlicense
|
||||
|
||||
Copyright (c) 2025 Mivirl
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
*/
|
||||
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "../../clay.h"
|
||||
#include "../../renderers/termbox2/clay_renderer_termbox2.c"
|
||||
|
||||
#define TB_IMPL
|
||||
#include "termbox2.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include "stb_image_resize2.h"
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Internal state
|
||||
|
||||
// If the program should exit the main render/interaction loop
|
||||
bool end_loop = false;
|
||||
|
||||
// If the debug tools should be displayed
|
||||
bool debugMode = false;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Clay components
|
||||
|
||||
void component_text_pair(const char *key, const char *value)
|
||||
{
|
||||
size_t keylen = strlen(key);
|
||||
size_t vallen = strlen(value);
|
||||
Clay_String keytext = (Clay_String) {
|
||||
.length = keylen,
|
||||
.chars = key,
|
||||
};
|
||||
Clay_String valtext = (Clay_String) {
|
||||
.length = vallen,
|
||||
.chars = value,
|
||||
};
|
||||
Clay_TextElementConfig *textconfig =
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff } });
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = {
|
||||
.size.minMax = {
|
||||
.min = strlen("Border chars CLAY_TB_IMAGE_MODE_UNICODE_FAST") * Clay_Termbox_Cell_Width(),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}) {
|
||||
CLAY_TEXT(keytext, textconfig);
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = CLAY_SIZING_GROW(1) } }) { }
|
||||
CLAY_TEXT(valtext, textconfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void component_termbox_settings(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.floating = {
|
||||
.attachTo = CLAY_ATTACH_TO_PARENT,
|
||||
.zIndex = 1,
|
||||
.attachPoints = { CLAY_ATTACH_POINT_CENTER_CENTER, CLAY_ATTACH_POINT_CENTER_TOP },
|
||||
.offset = { 0, 0 }
|
||||
},
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
.padding = {
|
||||
6 * Clay_Termbox_Cell_Width(),
|
||||
6 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
}
|
||||
},
|
||||
.border = {
|
||||
.width = CLAY_BORDER_ALL(1),
|
||||
.color = { 0x00, 0x00, 0x00, 0xff }
|
||||
},
|
||||
.backgroundColor = { 0x7f, 0x00, 0x00, 0x7f }
|
||||
}) {
|
||||
const char *color_mode = NULL;
|
||||
switch (clay_tb_color_mode) {
|
||||
case TB_OUTPUT_NORMAL: {
|
||||
color_mode = "TB_OUTPUT_NORMAL";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_256: {
|
||||
color_mode = "TB_OUTPUT_256";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_216: {
|
||||
color_mode = "TB_OUTPUT_216";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_GRAYSCALE: {
|
||||
color_mode = "TB_OUTPUT_GRAYSCALE";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_TRUECOLOR: {
|
||||
color_mode = "TB_OUTPUT_TRUECOLOR";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_OUTPUT_NOCOLOR: {
|
||||
color_mode = "CLAY_TB_OUTPUT_NOCOLOR";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
color_mode = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *border_mode = NULL;
|
||||
switch (clay_tb_border_mode) {
|
||||
case CLAY_TB_BORDER_MODE_ROUND: {
|
||||
border_mode = "CLAY_TB_BORDER_MODE_ROUND";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_MODE_MINIMUM: {
|
||||
border_mode = "CLAY_TB_BORDER_MODE_MINIMUM";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
border_mode = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *border_chars = NULL;
|
||||
switch (clay_tb_border_chars) {
|
||||
case CLAY_TB_BORDER_CHARS_ASCII: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_ASCII";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_CHARS_UNICODE: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_UNICODE";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_CHARS_BLANK: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_BLANK";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_CHARS_NONE: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_NONE";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
border_chars = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *image_mode = NULL;
|
||||
switch (clay_tb_image_mode) {
|
||||
case CLAY_TB_IMAGE_MODE_PLACEHOLDER: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_PLACEHOLDER";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_BG: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_BG";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII_FG: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FG";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII_FG_FAST: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FG_FAST";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII_FAST: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FAST";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_UNICODE: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_UNICODE";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_UNICODE_FAST: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_UNICODE_FAST";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
image_mode = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *transparency = NULL;
|
||||
if (clay_tb_transparency) {
|
||||
transparency = "true";
|
||||
} else {
|
||||
transparency = "false";
|
||||
}
|
||||
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM },
|
||||
}) {
|
||||
component_text_pair("Color mode", color_mode);
|
||||
component_text_pair("Border mode", border_mode);
|
||||
component_text_pair("Border chars", border_chars);
|
||||
component_text_pair("Image mode", image_mode);
|
||||
component_text_pair("Transparency", transparency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void component_color_palette(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.childGap = 16,
|
||||
.padding = {
|
||||
2 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
}
|
||||
},
|
||||
.border = {
|
||||
.width = CLAY_BORDER_OUTSIDE(2),
|
||||
.color = { 0x00, 0x00, 0x00, 0xff }
|
||||
},
|
||||
.backgroundColor = { 0x7f, 0x7f, 0x7f, 0xff }
|
||||
}) {
|
||||
for (int type = 0; type < 2; ++type) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout ={
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
.childGap = Clay_Termbox_Cell_Height()
|
||||
},
|
||||
}) {
|
||||
for (float ri = 0; ri < 4; ri += 1) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout ={
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
.childGap = Clay_Termbox_Cell_Width()
|
||||
},
|
||||
}) {
|
||||
for (float r = ri * 0x44; r < (ri + 1) * 0x44; r += 0x22) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout ={
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
},
|
||||
}) {
|
||||
for (float g = 0; g < 0xff; g += 0x22) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout ={
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
},
|
||||
}) {
|
||||
for (float b = 0; b < 0xff; b += 0x22) {
|
||||
Clay_Color color = { r, g, b, 0x7f };
|
||||
|
||||
Clay_LayoutConfig layout = (Clay_LayoutConfig) {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(2 * Clay_Termbox_Cell_Width()),
|
||||
.height = CLAY_SIZING_FIXED(1 * Clay_Termbox_Cell_Height())
|
||||
}
|
||||
};
|
||||
if (0 == type) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = layout,
|
||||
.backgroundColor = color
|
||||
}) {}
|
||||
} else if (1 == type) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = layout,
|
||||
}) {
|
||||
CLAY_TEXT(CLAY_STRING("#"), CLAY_TEXT_CONFIG({ .textColor = color }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void component_unicode_text(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
.padding = {
|
||||
2 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
}
|
||||
},
|
||||
.backgroundColor = { 0xcc, 0xbb, 0xaa, 0xff },
|
||||
.border = {
|
||||
// This border should still be displayed in CLAY_TB_BORDER_MODE_ROUND mode
|
||||
.width = {
|
||||
0.75 * Clay_Termbox_Cell_Width(),
|
||||
0.75 * Clay_Termbox_Cell_Width(),
|
||||
0.75 * Clay_Termbox_Cell_Height(),
|
||||
0.75 * Clay_Termbox_Cell_Height(),
|
||||
},
|
||||
.color = { 0x33, 0x33, 0x33, 0xff },
|
||||
},
|
||||
}) {
|
||||
CLAY_TEXT(
|
||||
CLAY_STRING("Non-ascii character tests:\n"
|
||||
"\n"
|
||||
"(from https://www.w3.org/2001/06/utf-8-test/UTF-8-demo.html)\n"
|
||||
" Mathematics and Sciences:\n"
|
||||
" ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β),\n"
|
||||
" ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B),\n"
|
||||
" 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm\n"
|
||||
"\n"
|
||||
" Compact font selection example text:\n"
|
||||
" ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789\n"
|
||||
" abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ\n"
|
||||
" –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд\n"
|
||||
" ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi<>⑀₂ἠḂӥẄɐː⍎אԱა\n"
|
||||
"\n"
|
||||
"(from https://blog.denisbider.com/2015/09/when-monospace-fonts-arent-unicode.html):\n"
|
||||
" aeioucsz\n"
|
||||
" áéíóúčšž\n"
|
||||
" 台北1234\n"
|
||||
" QRS12\n"
|
||||
" アイウ1234\n"
|
||||
"\n"
|
||||
"(from https://stackoverflow.com/a/1644280)\n"
|
||||
" ٩(-̮̮̃-̃)۶ ٩(●̮̮̃•̃)۶ ٩(͡๏̯͡๏)۶ ٩(-̮̮̃•̃)."
|
||||
),
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0x11, 0x11, 0x11, 0xff } })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void component_keybinds(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
.padding = {
|
||||
4 * Clay_Termbox_Cell_Width(),
|
||||
4 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
}
|
||||
},
|
||||
.backgroundColor = { 0x00, 0x7f, 0x7f, 0xff }
|
||||
}) {
|
||||
CLAY_TEXT(
|
||||
CLAY_STRING(
|
||||
"Termbox2 renderer test\n"
|
||||
"\n"
|
||||
"Keybinds:\n"
|
||||
" c/C - Cycle through color modes\n"
|
||||
" b/B - Cycle through border modes\n"
|
||||
" h/H - Cycle through border characters\n"
|
||||
" i/I - Cycle through image modes\n"
|
||||
" t/T - Toggle transparency\n"
|
||||
" d/D - Toggle debug mode\n"
|
||||
" q/Q - Quit\n"
|
||||
),
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff }})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void component_image(clay_tb_image *image, int width)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = (0 == width) ? CLAY_SIZING_GROW() : CLAY_SIZING_FIXED(width),
|
||||
},
|
||||
},
|
||||
.image = {
|
||||
.imageData = image,
|
||||
},
|
||||
.aspectRatio = { 512.0 / 406.0 }
|
||||
}) { }
|
||||
}
|
||||
|
||||
void component_mouse_data(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
},
|
||||
},
|
||||
}) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
Clay_Vector2 mouse_position = context->pointerInfo.position;
|
||||
|
||||
Clay_LayoutConfig layout = (Clay_LayoutConfig) {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(2 * Clay_Termbox_Cell_Width()),
|
||||
.height = CLAY_SIZING_FIXED(1 * Clay_Termbox_Cell_Height())
|
||||
}
|
||||
};
|
||||
|
||||
float v = 255 * mouse_position.x / Clay_Termbox_Width();
|
||||
v = (0 > v) ? 0 : v;
|
||||
v = (255 < v) ? 255 : v;
|
||||
Clay_Color color = (Clay_Color) { v, v, v, 0xff };
|
||||
|
||||
CLAY_AUTO_ID({
|
||||
.layout = layout,
|
||||
.backgroundColor = color
|
||||
}) {}
|
||||
|
||||
v = 255 * mouse_position.y / Clay_Termbox_Height();
|
||||
v = (0 > v) ? 0 : v;
|
||||
v = (255 < v) ? 255 : v;
|
||||
color = (Clay_Color) { v, v, v, 0xff };
|
||||
|
||||
|
||||
CLAY_AUTO_ID({
|
||||
.layout = layout,
|
||||
.backgroundColor = color
|
||||
}) {}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void component_bordered_text(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIT(450),
|
||||
.height = CLAY_SIZING_FIT(),
|
||||
},
|
||||
.padding = CLAY_PADDING_ALL(32)
|
||||
},
|
||||
.backgroundColor = { 0x24, 0x55, 0x34, 0xff },
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.border = { .width = { 1, 1, 1, 1, 1 }, .color = { 0xaa, 0x00, 0x00, 0xff } },
|
||||
}) {
|
||||
CLAY_TEXT(
|
||||
CLAY_STRING("Test"), CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff } }));
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.border = { .width = { 1, 1, 1, 1, 1 }, .color = { 0x00, 0xaa, 0x00, 0xff } },
|
||||
}) {
|
||||
CLAY_TEXT(CLAY_STRING("of the border width"),
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff } }));
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.border = { .width = { 1, 1, 1, 1, 1 }, .color = { 0x00, 0x00, 0xaa, 0xff } },
|
||||
}) {
|
||||
CLAY_TEXT(CLAY_STRING("and overlap for multiple lines\nof text"),
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff } }));
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.border = { .width = { 1, 1, 1, 1, 1 }, .color = { 0x00, 0x00, 0xaa, 0xff } },
|
||||
}) {
|
||||
CLAY_TEXT(CLAY_STRING("this text\nis long enough\nto display all\n borders\naround it"),
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff } }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Clay_RenderCommandArray CreateLayout(clay_tb_image *image1, clay_tb_image *image2)
|
||||
{
|
||||
Clay_BeginLayout();
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
},
|
||||
.childAlignment = {
|
||||
.x = CLAY_ALIGN_X_CENTER,
|
||||
.y = CLAY_ALIGN_Y_CENTER
|
||||
},
|
||||
.childGap = 64
|
||||
},
|
||||
.backgroundColor = { 0x24, 0x24, 0x24, 0xff }
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.childAlignment = {
|
||||
.x = CLAY_ALIGN_X_RIGHT,
|
||||
},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
},
|
||||
}) {
|
||||
component_keybinds();
|
||||
component_unicode_text();
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 32,
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
},
|
||||
}) {
|
||||
component_termbox_settings();
|
||||
component_image(image1, 150);
|
||||
component_image(image2, 0);
|
||||
component_mouse_data();
|
||||
component_bordered_text();
|
||||
}
|
||||
|
||||
component_color_palette();
|
||||
}
|
||||
return Clay_EndLayout();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Interactive functions
|
||||
|
||||
void handle_clay_errors(Clay_ErrorData errorData)
|
||||
{
|
||||
Clay_Termbox_Close();
|
||||
fprintf(stderr, "%s", errorData.errorText.chars);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
Process events received from termbox2 and handle interaction
|
||||
*/
|
||||
void handle_termbox_events(void)
|
||||
{
|
||||
// Wait up to 100ms for an event (key/mouse press, terminal resize) before continuing
|
||||
// If an event is already available, this doesn't wait. Will not wait due to the previous call
|
||||
// to termbox_waitfor_event. Increasing the wait time reduces load without reducing
|
||||
// responsiveness (but will of course prevent other code from running on this thread while it's
|
||||
// waiting)
|
||||
struct tb_event evt;
|
||||
int ms_to_wait = 0;
|
||||
int err = tb_peek_event(&evt, ms_to_wait);
|
||||
|
||||
switch (err) {
|
||||
default:
|
||||
case TB_ERR_NO_EVENT: {
|
||||
break;
|
||||
}
|
||||
case TB_ERR_POLL: {
|
||||
if (EINTR != tb_last_errno()) {
|
||||
Clay_Termbox_Close();
|
||||
fprintf(stderr, "Failed to read event from TTY\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TB_OK: {
|
||||
switch (evt.type) {
|
||||
case TB_EVENT_RESIZE: {
|
||||
Clay_SetLayoutDimensions((Clay_Dimensions) {
|
||||
Clay_Termbox_Width(),
|
||||
Clay_Termbox_Height()
|
||||
});
|
||||
break;
|
||||
}
|
||||
case TB_EVENT_KEY: {
|
||||
if (TB_KEY_CTRL_C == evt.key) {
|
||||
end_loop = true;
|
||||
break;
|
||||
}
|
||||
switch (evt.ch) {
|
||||
case 'q':
|
||||
case 'Q': {
|
||||
end_loop = true;
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
case 'D': {
|
||||
debugMode = !debugMode;
|
||||
Clay_SetDebugModeEnabled(debugMode);
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
int new_mode = clay_tb_color_mode - 1;
|
||||
new_mode = (0 <= new_mode) ? new_mode : TB_OUTPUT_TRUECOLOR;
|
||||
Clay_Termbox_Set_Color_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'C': {
|
||||
int new_mode = (clay_tb_color_mode + 1) % (TB_OUTPUT_TRUECOLOR + 1);
|
||||
Clay_Termbox_Set_Color_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
enum border_mode new_mode = clay_tb_border_mode - 1;
|
||||
new_mode = (CLAY_TB_BORDER_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_BORDER_MODE_MINIMUM;
|
||||
Clay_Termbox_Set_Border_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'B': {
|
||||
enum border_mode new_mode = (clay_tb_border_mode + 1)
|
||||
% (CLAY_TB_BORDER_MODE_MINIMUM + 1);
|
||||
new_mode = (CLAY_TB_BORDER_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_BORDER_MODE_ROUND;
|
||||
Clay_Termbox_Set_Border_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
enum border_chars new_chars = clay_tb_border_chars - 1;
|
||||
new_chars = (CLAY_TB_BORDER_CHARS_DEFAULT < new_chars)
|
||||
? new_chars
|
||||
: CLAY_TB_BORDER_CHARS_NONE;
|
||||
Clay_Termbox_Set_Border_Chars(new_chars);
|
||||
break;
|
||||
}
|
||||
case 'H': {
|
||||
enum border_chars new_chars
|
||||
= (clay_tb_border_chars + 1) % (CLAY_TB_BORDER_CHARS_NONE + 1);
|
||||
new_chars = (CLAY_TB_BORDER_CHARS_DEFAULT < new_chars)
|
||||
? new_chars
|
||||
: CLAY_TB_BORDER_CHARS_ASCII;
|
||||
Clay_Termbox_Set_Border_Chars(new_chars);
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
enum image_mode new_mode = clay_tb_image_mode - 1;
|
||||
new_mode = (CLAY_TB_IMAGE_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_IMAGE_MODE_UNICODE_FAST;
|
||||
Clay_Termbox_Set_Image_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'I': {
|
||||
enum image_mode new_mode = (clay_tb_image_mode + 1)
|
||||
% (CLAY_TB_IMAGE_MODE_UNICODE_FAST + 1);
|
||||
new_mode = (CLAY_TB_IMAGE_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_IMAGE_MODE_PLACEHOLDER;
|
||||
Clay_Termbox_Set_Image_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
case 'T': {
|
||||
Clay_Termbox_Set_Transparency(!clay_tb_transparency);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TB_EVENT_MOUSE: {
|
||||
Clay_Vector2 mousePosition = {
|
||||
(float)evt.x * Clay_Termbox_Cell_Width(),
|
||||
(float)evt.y * Clay_Termbox_Cell_Height()
|
||||
};
|
||||
|
||||
// Mouse release events may not be produced by all terminals, and will
|
||||
// be sent during hover, so can't be used to detect when the mouse has
|
||||
// been released
|
||||
|
||||
switch (evt.key) {
|
||||
case TB_KEY_MOUSE_LEFT: {
|
||||
Clay_SetPointerState(mousePosition, true);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_RIGHT: {
|
||||
Clay_SetPointerState(mousePosition, false);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_MIDDLE: {
|
||||
Clay_SetPointerState(mousePosition, false);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_RELEASE: {
|
||||
Clay_SetPointerState(mousePosition, false);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_WHEEL_UP: {
|
||||
Clay_Vector2 scrollDelta = { 0, 1 * Clay_Termbox_Cell_Height() };
|
||||
Clay_UpdateScrollContainers(false, scrollDelta, 1);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_WHEEL_DOWN: {
|
||||
Clay_Vector2 scrollDelta = { 0, -1 * Clay_Termbox_Cell_Height() };
|
||||
Clay_UpdateScrollContainers(false, scrollDelta, 1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
clay_tb_image shark_image1 = Clay_Termbox_Image_Load_File("resources/512px-Shark_antwerp_zoo.jpeg");
|
||||
clay_tb_image shark_image2 = Clay_Termbox_Image_Load_File("resources/512px-Shark_antwerp_zoo.jpeg");
|
||||
if (NULL == shark_image1.pixel_data) { exit(1); }
|
||||
if (NULL == shark_image2.pixel_data) { exit(1); }
|
||||
|
||||
int num_elements = 3 * 8192;
|
||||
Clay_SetMaxElementCount(num_elements);
|
||||
|
||||
uint64_t size = Clay_MinMemorySize();
|
||||
void *memory = malloc(size);
|
||||
if (NULL == memory) { exit(1); }
|
||||
|
||||
Clay_Arena clay_arena = Clay_CreateArenaWithCapacityAndMemory(size, memory);
|
||||
|
||||
Clay_Termbox_Initialize(
|
||||
TB_OUTPUT_256, CLAY_TB_BORDER_MODE_DEFAULT, CLAY_TB_BORDER_CHARS_DEFAULT, CLAY_TB_IMAGE_MODE_DEFAULT, false);
|
||||
|
||||
Clay_Initialize(clay_arena, (Clay_Dimensions) { Clay_Termbox_Width(), Clay_Termbox_Height() },
|
||||
(Clay_ErrorHandler) { handle_clay_errors, NULL });
|
||||
|
||||
Clay_SetMeasureTextFunction(Clay_Termbox_MeasureText, NULL);
|
||||
|
||||
// Initial render before waiting for events
|
||||
Clay_RenderCommandArray commands = CreateLayout(&shark_image1, &shark_image2);
|
||||
Clay_Termbox_Render(commands);
|
||||
tb_present();
|
||||
|
||||
while (!end_loop) {
|
||||
// Block until event is available. Optional, but reduces load since this demo is purely
|
||||
// synchronous to user input.
|
||||
Clay_Termbox_Waitfor_Event();
|
||||
|
||||
handle_termbox_events();
|
||||
|
||||
commands = CreateLayout(&shark_image1, &shark_image2);
|
||||
|
||||
tb_clear();
|
||||
Clay_Termbox_Render(commands);
|
||||
tb_present();
|
||||
}
|
||||
|
||||
Clay_Termbox_Close();
|
||||
Clay_Termbox_Image_Free(&shark_image1);
|
||||
Clay_Termbox_Image_Free(&shark_image2);
|
||||
free(memory);
|
||||
return 0;
|
||||
}
|
72
examples/termbox2-demo/readme.md
Normal file
72
examples/termbox2-demo/readme.md
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Termbox2 renderer demo
|
||||
|
||||
Terminal-based renderer using [termbox2](https://github.com/termbox/termbox2)
|
||||
|
||||
This demo shows a color palette and a few different components. It allows
|
||||
changing configuration settings for colors, border size rounding mode,
|
||||
characters used for borders, and transparency.
|
||||
|
||||
```
|
||||
Keybinds:
|
||||
c/C - Cycle through color modes
|
||||
b/B - Cycle through border modes
|
||||
h/H - Cycle through border characters
|
||||
i/I - Cycle through image modes
|
||||
t/T - Toggle transparency
|
||||
d/D - Toggle debug mode
|
||||
q/Q - Quit
|
||||
```
|
||||
|
||||
Configuration can be also be overriden by environment variables:
|
||||
- `CLAY_TB_COLOR_MODE`
|
||||
- `NORMAL`
|
||||
- `256`
|
||||
- `216`
|
||||
- `GRAYSCALE`
|
||||
- `TRUECOLOR`
|
||||
- `NOCOLOR`
|
||||
- `CLAY_TB_BORDER_CHARS`
|
||||
- `DEFAULT`
|
||||
- `ASCII`
|
||||
- `UNICODE`
|
||||
- `NONE`
|
||||
- `CLAY_TB_IMAGE_MODE`
|
||||
- `DEFAULT`
|
||||
- `PLACEHOLDER`
|
||||
- `BG`
|
||||
- `ASCII_FG`
|
||||
- `ASCII`
|
||||
- `UNICODE`
|
||||
- `ASCII_FG_FAST`
|
||||
- `ASCII_FAST`
|
||||
- `UNICODE_FAST`
|
||||
- `CLAY_TB_TRANSPARENCY`
|
||||
- `1`
|
||||
- `0`
|
||||
- `CLAY_TB_CELL_PIXELS`
|
||||
- `widthxheight`
|
||||
|
||||
## Building
|
||||
|
||||
Build the binary with cmake
|
||||
|
||||
```sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
Then run the executable:
|
||||
|
||||
```sh
|
||||
./clay_examples_termbox2_demo
|
||||
```
|
||||
|
||||
## Attributions
|
||||
|
||||
Resources used:
|
||||
- `512px-Shark_antwerp_zoo.jpeg`
|
||||
- Retrieved from <https://commons.wikimedia.org/wiki/File:Shark_antwerp_zoo.jpg>
|
||||
- License: [Creative Commons Attribution 3.0 Unported](https://creativecommons.org/licenses/by/3.0/deed.en)
|
||||
- No changes made
|
BIN
examples/termbox2-demo/resources/512px-Shark_antwerp_zoo.jpeg
Normal file
BIN
examples/termbox2-demo/resources/512px-Shark_antwerp_zoo.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
38
examples/termbox2-image-demo/CMakeLists.txt
Normal file
38
examples/termbox2-image-demo/CMakeLists.txt
Normal file
|
@ -0,0 +1,38 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
project(clay_examples_termbox2_image_demo C)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3")
|
||||
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
|
||||
FetchContent_Declare(
|
||||
termbox2
|
||||
GIT_REPOSITORY "https://github.com/termbox/termbox2.git"
|
||||
GIT_TAG "9c9281a9a4c971a2be57f8645e828ec99fd555e8"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(termbox2)
|
||||
|
||||
FetchContent_Declare(
|
||||
stb
|
||||
GIT_REPOSITORY "https://github.com/nothings/stb.git"
|
||||
GIT_TAG "f58f558c120e9b32c217290b80bad1a0729fbb2c"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(stb)
|
||||
|
||||
add_executable(clay_examples_termbox2_image_demo main.c)
|
||||
|
||||
target_compile_options(clay_examples_termbox2_image_demo PUBLIC)
|
||||
target_include_directories(clay_examples_termbox2_image_demo PUBLIC . PRIVATE ${termbox2_SOURCE_DIR} PRIVATE ${stb_SOURCE_DIR})
|
||||
target_link_libraries(clay_examples_termbox2_image_demo PRIVATE m) # Used by stb_image.h
|
||||
|
||||
add_custom_command(
|
||||
TARGET clay_examples_termbox2_image_demo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources
|
||||
${CMAKE_CURRENT_BINARY_DIR}/resources)
|
707
examples/termbox2-image-demo/main.c
Normal file
707
examples/termbox2-image-demo/main.c
Normal file
|
@ -0,0 +1,707 @@
|
|||
/*
|
||||
Unlicense
|
||||
|
||||
Copyright (c) 2025 Mivirl
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
*/
|
||||
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "../../clay.h"
|
||||
#include "../../renderers/termbox2/clay_renderer_termbox2.c"
|
||||
|
||||
#define TB_IMPL
|
||||
#include "termbox2.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include "stb_image_resize2.h"
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Data structures
|
||||
|
||||
struct img_group {
|
||||
clay_tb_image thumbnail;
|
||||
clay_tb_image image;
|
||||
clay_tb_image image_1;
|
||||
clay_tb_image image_2;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
typedef struct img_group img_group;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Internal state
|
||||
|
||||
// If the program should exit the main render/interaction loop
|
||||
bool end_loop = false;
|
||||
|
||||
// If the debug tools should be displayed
|
||||
bool debugMode = false;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Internal utility functions
|
||||
|
||||
img_group img_group_load(const char *filename)
|
||||
{
|
||||
img_group rv;
|
||||
rv.thumbnail = Clay_Termbox_Image_Load_File(filename);
|
||||
rv.image = Clay_Termbox_Image_Load_File(filename);
|
||||
rv.image_1 = Clay_Termbox_Image_Load_File(filename);
|
||||
rv.image_2 = Clay_Termbox_Image_Load_File(filename);
|
||||
if (NULL == rv.thumbnail.pixel_data
|
||||
|| NULL == rv.image.pixel_data
|
||||
|| NULL == rv.image_1.pixel_data
|
||||
|| NULL == rv.image_2.pixel_data) {
|
||||
exit(1);
|
||||
}
|
||||
rv.width = rv.image.pixel_width;
|
||||
rv.height = rv.image.pixel_height;
|
||||
return rv;
|
||||
}
|
||||
void img_group_free(img_group *img)
|
||||
{
|
||||
Clay_Termbox_Image_Free(&img->thumbnail);
|
||||
Clay_Termbox_Image_Free(&img->image);
|
||||
Clay_Termbox_Image_Free(&img->image_1);
|
||||
Clay_Termbox_Image_Free(&img->image_2);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Clay components
|
||||
|
||||
void component_text_pair(const char *key, const char *value)
|
||||
{
|
||||
size_t keylen = strlen(key);
|
||||
size_t vallen = strlen(value);
|
||||
Clay_String keytext = (Clay_String) {
|
||||
.length = keylen,
|
||||
.chars = key,
|
||||
};
|
||||
Clay_String valtext = (Clay_String) {
|
||||
.length = vallen,
|
||||
.chars = value,
|
||||
};
|
||||
Clay_TextElementConfig *textconfig =
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff } });
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = {
|
||||
.size.minMax = {
|
||||
.min = strlen("Border chars CLAY_TB_IMAGE_MODE_UNICODE_FAST") * Clay_Termbox_Cell_Width(),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}) {
|
||||
CLAY_TEXT(keytext, textconfig);
|
||||
CLAY_AUTO_ID({ .layout = { .sizing = CLAY_SIZING_GROW(1) } }) { }
|
||||
CLAY_TEXT(valtext, textconfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void component_termbox_settings(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
.padding = {
|
||||
6 * Clay_Termbox_Cell_Width(),
|
||||
6 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
}
|
||||
},
|
||||
.border = {
|
||||
.width = CLAY_BORDER_ALL(1),
|
||||
.color = { 0x00, 0x00, 0x00, 0xff }
|
||||
},
|
||||
.backgroundColor = { 0x7f, 0x00, 0x00, 0x7f }
|
||||
}) {
|
||||
const char *color_mode = NULL;
|
||||
switch (clay_tb_color_mode) {
|
||||
case TB_OUTPUT_NORMAL: {
|
||||
color_mode = "TB_OUTPUT_NORMAL";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_256: {
|
||||
color_mode = "TB_OUTPUT_256";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_216: {
|
||||
color_mode = "TB_OUTPUT_216";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_GRAYSCALE: {
|
||||
color_mode = "TB_OUTPUT_GRAYSCALE";
|
||||
break;
|
||||
}
|
||||
case TB_OUTPUT_TRUECOLOR: {
|
||||
color_mode = "TB_OUTPUT_TRUECOLOR";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_OUTPUT_NOCOLOR: {
|
||||
color_mode = "CLAY_TB_OUTPUT_NOCOLOR";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
color_mode = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *border_mode = NULL;
|
||||
switch (clay_tb_border_mode) {
|
||||
case CLAY_TB_BORDER_MODE_ROUND: {
|
||||
border_mode = "CLAY_TB_BORDER_MODE_ROUND";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_MODE_MINIMUM: {
|
||||
border_mode = "CLAY_TB_BORDER_MODE_MINIMUM";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
border_mode = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *border_chars = NULL;
|
||||
switch (clay_tb_border_chars) {
|
||||
case CLAY_TB_BORDER_CHARS_ASCII: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_ASCII";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_CHARS_UNICODE: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_UNICODE";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_CHARS_BLANK: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_BLANK";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_BORDER_CHARS_NONE: {
|
||||
border_chars = "CLAY_TB_BORDER_CHARS_NONE";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
border_chars = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *image_mode = NULL;
|
||||
switch (clay_tb_image_mode) {
|
||||
case CLAY_TB_IMAGE_MODE_PLACEHOLDER: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_PLACEHOLDER";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_BG: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_BG";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII_FG: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FG";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII_FG_FAST: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FG_FAST";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_ASCII_FAST: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FAST";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_UNICODE: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_UNICODE";
|
||||
break;
|
||||
}
|
||||
case CLAY_TB_IMAGE_MODE_UNICODE_FAST: {
|
||||
image_mode = "CLAY_TB_IMAGE_MODE_UNICODE_FAST";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
image_mode = "INVALID";
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *transparency = NULL;
|
||||
if (clay_tb_transparency) {
|
||||
transparency = "true";
|
||||
} else {
|
||||
transparency = "false";
|
||||
}
|
||||
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM },
|
||||
}) {
|
||||
component_text_pair("Color mode", color_mode);
|
||||
component_text_pair("Border mode", border_mode);
|
||||
component_text_pair("Border chars", border_chars);
|
||||
component_text_pair("Image mode", image_mode);
|
||||
component_text_pair("Transparency", transparency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void component_keybinds(void)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = CLAY_SIZING_FIT(),
|
||||
.padding = {
|
||||
4 * Clay_Termbox_Cell_Width(),
|
||||
4 * Clay_Termbox_Cell_Width(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
2 * Clay_Termbox_Cell_Height(),
|
||||
}
|
||||
},
|
||||
.backgroundColor = { 0x00, 0x7f, 0x7f, 0xff }
|
||||
}) {
|
||||
CLAY_TEXT(
|
||||
CLAY_STRING(
|
||||
"Termbox2 renderer test\n"
|
||||
"\n"
|
||||
"Keybinds:\n"
|
||||
" up/down arrows - Change selected image\n"
|
||||
" c/C - Cycle through color modes\n"
|
||||
" b/B - Cycle through border modes\n"
|
||||
" h/H - Cycle through border characters\n"
|
||||
" i/I - Cycle through image modes\n"
|
||||
" t/T - Toggle transparency\n"
|
||||
" d/D - Toggle debug mode\n"
|
||||
" q/Q - Quit\n"
|
||||
),
|
||||
CLAY_TEXT_CONFIG({ .textColor = { 0xff, 0xff, 0xff, 0xff }})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void component_image(img_group *img_pair)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childAlignment = {
|
||||
.x = CLAY_ALIGN_X_CENTER,
|
||||
.y = CLAY_ALIGN_Y_CENTER
|
||||
},
|
||||
.childGap = 1 * Clay_Termbox_Cell_Height()
|
||||
},
|
||||
.backgroundColor = { 0x24, 0x24, 0x24, 0xff }
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
},
|
||||
},
|
||||
.image = {
|
||||
.imageData = &img_pair->image,
|
||||
},
|
||||
.aspectRatio = { (float)img_pair->width / img_pair->height }
|
||||
}) { }
|
||||
component_keybinds();
|
||||
}
|
||||
}
|
||||
|
||||
void component_image_small(img_group **img_pairs, int count, int selected_index)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_PERCENT(0.25),
|
||||
},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 20,
|
||||
.childAlignment = {
|
||||
.x = CLAY_ALIGN_X_CENTER,
|
||||
.y = CLAY_ALIGN_Y_CENTER
|
||||
},
|
||||
},
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_PERCENT(0.7),
|
||||
},
|
||||
},
|
||||
.image = {
|
||||
.imageData = &img_pairs[selected_index]->image_1,
|
||||
},
|
||||
.aspectRatio = { (float)img_pairs[selected_index]->width / img_pairs[selected_index]->height }
|
||||
}) { }
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
},
|
||||
},
|
||||
.image = {
|
||||
.imageData = &img_pairs[selected_index]->image_2,
|
||||
},
|
||||
.aspectRatio = { (float)img_pairs[selected_index]->width / img_pairs[selected_index]->height }
|
||||
}) { }
|
||||
component_termbox_settings();
|
||||
}
|
||||
}
|
||||
|
||||
void component_thumbnails(img_group **img_pairs, int count, int selected_index)
|
||||
{
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_PERCENT(0.1),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 20
|
||||
},
|
||||
.backgroundColor = { 0x42, 0x42, 0x42, 0xff }
|
||||
}) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Clay_BorderElementConfig border;
|
||||
if (i == selected_index) {
|
||||
border = (Clay_BorderElementConfig) {
|
||||
.width =CLAY_BORDER_OUTSIDE(10),
|
||||
.color = { 0x00, 0x30, 0xc0, 0x8f }
|
||||
};
|
||||
} else {
|
||||
border = (Clay_BorderElementConfig) {
|
||||
.width = CLAY_BORDER_OUTSIDE(0),
|
||||
};
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
},
|
||||
},
|
||||
.border = border,
|
||||
.image = {
|
||||
.imageData = &img_pairs[i]->thumbnail,
|
||||
},
|
||||
.aspectRatio = { (float)img_pairs[i]->width / img_pairs[i]->height }
|
||||
}) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int selected_thumbnail = 0;
|
||||
const int thumbnail_count = 5;
|
||||
Clay_RenderCommandArray CreateLayout(struct img_group **imgs)
|
||||
{
|
||||
Clay_BeginLayout();
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
},
|
||||
.childAlignment = {
|
||||
.x = CLAY_ALIGN_X_LEFT,
|
||||
.y = CLAY_ALIGN_Y_CENTER
|
||||
},
|
||||
.childGap = 64
|
||||
},
|
||||
.backgroundColor = { 0x24, 0x24, 0x24, 0xff }
|
||||
}) {
|
||||
component_thumbnails(imgs, thumbnail_count, selected_thumbnail);
|
||||
component_image_small(imgs, thumbnail_count, selected_thumbnail);
|
||||
component_image(imgs[selected_thumbnail]);
|
||||
}
|
||||
return Clay_EndLayout();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -- Interactive functions
|
||||
|
||||
void handle_clay_errors(Clay_ErrorData errorData)
|
||||
{
|
||||
Clay_Termbox_Close();
|
||||
fprintf(stderr, "%s", errorData.errorText.chars);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
Process events received from termbox2 and handle interaction
|
||||
*/
|
||||
void handle_termbox_events(void)
|
||||
{
|
||||
// Wait up to 100ms for an event (key/mouse press, terminal resize) before continuing
|
||||
// If an event is already available, this doesn't wait. Will not wait due to the previous call
|
||||
// to termbox_waitfor_event. Increasing the wait time reduces load without reducing
|
||||
// responsiveness (but will of course prevent other code from running on this thread while it's
|
||||
// waiting)
|
||||
struct tb_event evt;
|
||||
int ms_to_wait = 0;
|
||||
int err = tb_peek_event(&evt, ms_to_wait);
|
||||
|
||||
switch (err) {
|
||||
default:
|
||||
case TB_ERR_NO_EVENT: {
|
||||
break;
|
||||
}
|
||||
case TB_ERR_POLL: {
|
||||
if (EINTR != tb_last_errno()) {
|
||||
Clay_Termbox_Close();
|
||||
fprintf(stderr, "Failed to read event from TTY\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TB_OK: {
|
||||
switch (evt.type) {
|
||||
case TB_EVENT_RESIZE: {
|
||||
Clay_SetLayoutDimensions((Clay_Dimensions) {
|
||||
Clay_Termbox_Width(),
|
||||
Clay_Termbox_Height()
|
||||
});
|
||||
break;
|
||||
}
|
||||
case TB_EVENT_KEY: {
|
||||
if (TB_KEY_CTRL_C == evt.key) {
|
||||
end_loop = true;
|
||||
break;
|
||||
}
|
||||
if (0 != evt.ch) {
|
||||
switch (evt.ch) {
|
||||
case 'q':
|
||||
case 'Q': {
|
||||
end_loop = true;
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
case 'D': {
|
||||
debugMode = !debugMode;
|
||||
Clay_SetDebugModeEnabled(debugMode);
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
int new_mode = clay_tb_color_mode - 1;
|
||||
new_mode = (0 <= new_mode) ? new_mode : TB_OUTPUT_TRUECOLOR;
|
||||
Clay_Termbox_Set_Color_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'C': {
|
||||
int new_mode = (clay_tb_color_mode + 1) % (TB_OUTPUT_TRUECOLOR + 1);
|
||||
Clay_Termbox_Set_Color_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
enum border_mode new_mode = clay_tb_border_mode - 1;
|
||||
new_mode = (CLAY_TB_BORDER_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_BORDER_MODE_MINIMUM;
|
||||
Clay_Termbox_Set_Border_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'B': {
|
||||
enum border_mode new_mode = (clay_tb_border_mode + 1)
|
||||
% (CLAY_TB_BORDER_MODE_MINIMUM + 1);
|
||||
new_mode = (CLAY_TB_BORDER_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_BORDER_MODE_ROUND;
|
||||
Clay_Termbox_Set_Border_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
enum border_chars new_chars = clay_tb_border_chars - 1;
|
||||
new_chars = (CLAY_TB_BORDER_CHARS_DEFAULT < new_chars)
|
||||
? new_chars
|
||||
: CLAY_TB_BORDER_CHARS_NONE;
|
||||
Clay_Termbox_Set_Border_Chars(new_chars);
|
||||
break;
|
||||
}
|
||||
case 'H': {
|
||||
enum border_chars new_chars
|
||||
= (clay_tb_border_chars + 1) % (CLAY_TB_BORDER_CHARS_NONE + 1);
|
||||
new_chars = (CLAY_TB_BORDER_CHARS_DEFAULT < new_chars)
|
||||
? new_chars
|
||||
: CLAY_TB_BORDER_CHARS_ASCII;
|
||||
Clay_Termbox_Set_Border_Chars(new_chars);
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
enum image_mode new_mode = clay_tb_image_mode - 1;
|
||||
new_mode = (CLAY_TB_IMAGE_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_IMAGE_MODE_UNICODE_FAST;
|
||||
Clay_Termbox_Set_Image_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 'I': {
|
||||
enum image_mode new_mode = (clay_tb_image_mode + 1)
|
||||
% (CLAY_TB_IMAGE_MODE_UNICODE_FAST + 1);
|
||||
new_mode = (CLAY_TB_IMAGE_MODE_DEFAULT < new_mode)
|
||||
? new_mode
|
||||
: CLAY_TB_IMAGE_MODE_PLACEHOLDER;
|
||||
Clay_Termbox_Set_Image_Mode(new_mode);
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
case 'T': {
|
||||
Clay_Termbox_Set_Transparency(!clay_tb_transparency);
|
||||
}
|
||||
}
|
||||
} else if (0 != evt.key) {
|
||||
switch (evt.key) {
|
||||
case TB_KEY_ARROW_UP: {
|
||||
selected_thumbnail = (selected_thumbnail > 0) ? selected_thumbnail - 1 : 0;
|
||||
break;
|
||||
}
|
||||
case TB_KEY_ARROW_DOWN: {
|
||||
selected_thumbnail = (selected_thumbnail < thumbnail_count - 1) ? selected_thumbnail + 1 : thumbnail_count - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TB_EVENT_MOUSE: {
|
||||
Clay_Vector2 mousePosition = {
|
||||
(float)evt.x * Clay_Termbox_Cell_Width(),
|
||||
(float)evt.y * Clay_Termbox_Cell_Height()
|
||||
};
|
||||
|
||||
// Mouse release events may not be produced by all terminals, and will
|
||||
// be sent during hover, so can't be used to detect when the mouse has
|
||||
// been released
|
||||
|
||||
switch (evt.key) {
|
||||
case TB_KEY_MOUSE_LEFT: {
|
||||
Clay_SetPointerState(mousePosition, true);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_RIGHT: {
|
||||
Clay_SetPointerState(mousePosition, false);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_MIDDLE: {
|
||||
Clay_SetPointerState(mousePosition, false);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_RELEASE: {
|
||||
Clay_SetPointerState(mousePosition, false);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_WHEEL_UP: {
|
||||
Clay_Vector2 scrollDelta = { 0, 1 * Clay_Termbox_Cell_Height() };
|
||||
Clay_UpdateScrollContainers(false, scrollDelta, 1);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_WHEEL_DOWN: {
|
||||
Clay_Vector2 scrollDelta = { 0, -1 * Clay_Termbox_Cell_Height() };
|
||||
Clay_UpdateScrollContainers(false, scrollDelta, 1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
img_group *imgs[thumbnail_count];
|
||||
img_group img_shark = img_group_load("resources/512px-Shark_antwerp_zoo.jpeg");
|
||||
img_group img_castle = img_group_load("resources/512px-Balmoral_Castle_30_July_2011.jpeg");
|
||||
img_group img_dog = img_group_load("resources/512px-German_Shepherd_(aka_Alsatian_and_Alsatian_Wolf_Dog),_Deutscher_Schäferhund_(Folder_(IV)_22.jpeg");
|
||||
img_group img_rosa = img_group_load("resources/512px-Rosa_Cubana_2018-09-21_1610.jpeg");
|
||||
img_group img_vorderer = img_group_load("resources/512px-Vorderer_Graben_10_Bamberg_20190830_001.jpeg");
|
||||
imgs[0] = &img_shark;
|
||||
imgs[1] = &img_castle;
|
||||
imgs[2] = &img_dog;
|
||||
imgs[3] = &img_rosa;
|
||||
imgs[4] = &img_vorderer;
|
||||
|
||||
int num_elements = 3 * 8192;
|
||||
Clay_SetMaxElementCount(num_elements);
|
||||
|
||||
uint64_t size = Clay_MinMemorySize();
|
||||
void *memory = malloc(size);
|
||||
if (NULL == memory) { exit(1); }
|
||||
|
||||
Clay_Arena clay_arena = Clay_CreateArenaWithCapacityAndMemory(size, memory);
|
||||
|
||||
Clay_Termbox_Initialize(
|
||||
TB_OUTPUT_256, CLAY_TB_BORDER_MODE_DEFAULT, CLAY_TB_BORDER_CHARS_DEFAULT, CLAY_TB_IMAGE_MODE_DEFAULT, false);
|
||||
|
||||
Clay_Initialize(clay_arena, (Clay_Dimensions) { Clay_Termbox_Width(), Clay_Termbox_Height() },
|
||||
(Clay_ErrorHandler) { handle_clay_errors, NULL });
|
||||
|
||||
Clay_SetMeasureTextFunction(Clay_Termbox_MeasureText, NULL);
|
||||
|
||||
// Initial render before waiting for events
|
||||
Clay_RenderCommandArray commands = CreateLayout(imgs);
|
||||
Clay_Termbox_Render(commands);
|
||||
tb_present();
|
||||
|
||||
while (!end_loop) {
|
||||
// Block until event is available. Optional, but reduces load since this demo is purely
|
||||
// synchronous to user input.
|
||||
Clay_Termbox_Waitfor_Event();
|
||||
|
||||
handle_termbox_events();
|
||||
|
||||
commands = CreateLayout(imgs);
|
||||
|
||||
Clay_Termbox_Render(commands);
|
||||
tb_present();
|
||||
}
|
||||
|
||||
Clay_Termbox_Close();
|
||||
img_group_free(&img_shark);
|
||||
img_group_free(&img_castle);
|
||||
img_group_free(&img_dog);
|
||||
img_group_free(&img_rosa);
|
||||
img_group_free(&img_vorderer);
|
||||
free(memory);
|
||||
return 0;
|
||||
}
|
88
examples/termbox2-image-demo/readme.md
Normal file
88
examples/termbox2-image-demo/readme.md
Normal file
|
@ -0,0 +1,88 @@
|
|||
# Termbox2 renderer demo
|
||||
|
||||
Terminal-based renderer using [termbox2](https://github.com/termbox/termbox2)
|
||||
|
||||
This demo shows a color palette and a few different components. It allows
|
||||
changing configuration settings for colors, border size rounding mode,
|
||||
characters used for borders, and transparency.
|
||||
|
||||
```
|
||||
Keybinds:
|
||||
c/C - Cycle through color modes
|
||||
b/B - Cycle through border modes
|
||||
h/H - Cycle through border characters
|
||||
i/I - Cycle through image modes
|
||||
t/T - Toggle transparency
|
||||
d/D - Toggle debug mode
|
||||
q/Q - Quit
|
||||
```
|
||||
|
||||
Configuration can be also be overriden by environment variables:
|
||||
- `CLAY_TB_COLOR_MODE`
|
||||
- `NORMAL`
|
||||
- `256`
|
||||
- `216`
|
||||
- `GRAYSCALE`
|
||||
- `TRUECOLOR`
|
||||
- `NOCOLOR`
|
||||
- `CLAY_TB_BORDER_CHARS`
|
||||
- `DEFAULT`
|
||||
- `ASCII`
|
||||
- `UNICODE`
|
||||
- `NONE`
|
||||
- `CLAY_TB_IMAGE_MODE`
|
||||
- `DEFAULT`
|
||||
- `PLACEHOLDER`
|
||||
- `BG`
|
||||
- `ASCII_FG`
|
||||
- `ASCII`
|
||||
- `UNICODE`
|
||||
- `ASCII_FG_FAST`
|
||||
- `ASCII_FAST`
|
||||
- `UNICODE_FAST`
|
||||
- `CLAY_TB_TRANSPARENCY`
|
||||
- `1`
|
||||
- `0`
|
||||
- `CLAY_TB_CELL_PIXELS`
|
||||
- `widthxheight`
|
||||
|
||||
## Building
|
||||
|
||||
Build the binary with cmake
|
||||
|
||||
```sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
Then run the executable:
|
||||
|
||||
```sh
|
||||
./clay_examples_termbox2_demo
|
||||
```
|
||||
|
||||
## Attributions
|
||||
|
||||
Resources used:
|
||||
- `512px-Shark_antwerp_zoo.jpeg`
|
||||
- Retrieved from <https://commons.wikimedia.org/wiki/File:Shark_antwerp_zoo.jpg>
|
||||
- License: [Creative Commons Attribution 3.0 Unported](https://creativecommons.org/licenses/by/3.0/)
|
||||
- No changes made
|
||||
- `512px-Balmoral_Castle_30_July_2011.jpg`
|
||||
- Retrieved from <https://commons.wikimedia.org/wiki/File:Balmoral_Castle_30_July_2011.jpg>
|
||||
- License: [Creative Commons Attribution-ShareAlike 3.0 Unported](https://creativecommons.org/licenses/by-sa/3.0/)
|
||||
- No changes made
|
||||
- `512px-German_Shepherd_(aka_Alsatian_and_Alsatian_Wolf_Dog),_Deutscher_Schäferhund_(Folder_(IV)_22.jpeg`
|
||||
- Retrieved from <https://commons.wikimedia.org/wiki/File:German_Shepherd_(aka_Alsatian_and_Alsatian_Wolf_Dog),_Deutscher_Sch%C3%A4ferhund_(Folder_(IV)_22.JPG>
|
||||
- License: [Creative Commons Attribution-ShareAlike 3.0 Unported](https://creativecommons.org/licenses/by-sa/3.0/)
|
||||
- No changes made
|
||||
- `512px-Rosa_Cubana_2018-09-21_1610.jpeg`
|
||||
- Retrieved from <https://commons.wikimedia.org/wiki/File:Rosa_Cubana_2018-09-21_1610.jpg>
|
||||
- License: [Creative Commons Attribution-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||
- No changes made
|
||||
- `512px-Vorderer_Graben_10_Bamberg_20190830_001.jpeg`
|
||||
- Retrieved from <https://commons.wikimedia.org/wiki/File:Vorderer_Graben_10_Bamberg_20190830_001.jpg>
|
||||
- License: [Creative Commons Attribution-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||
- No changes made
|
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
|
@ -23,6 +23,7 @@ static Clay_Dimensions SDL2_MeasureText(Clay_StringSlice text, Clay_TextElementC
|
|||
SDL2_Font *fonts = (SDL2_Font*)userData;
|
||||
|
||||
TTF_Font *font = fonts[config->fontId].font;
|
||||
TTF_SetFontSize(font, config->fontSize);
|
||||
char *chars = (char *)calloc(text.length + 1, 1);
|
||||
memcpy(chars, text.chars, text.length);
|
||||
int width = 0;
|
||||
|
@ -294,6 +295,7 @@ static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray ren
|
|||
char *cloned = (char *)calloc(config->stringContents.length + 1, 1);
|
||||
memcpy(cloned, config->stringContents.chars, config->stringContents.length);
|
||||
TTF_Font* font = fonts[config->fontId].font;
|
||||
TTF_SetFontSize(font, config->fontSize);
|
||||
SDL_Surface *surface = TTF_RenderUTF8_Blended(font, cloned, (SDL_Color) {
|
||||
.r = (Uint8)config->textColor.r,
|
||||
.g = (Uint8)config->textColor.g,
|
||||
|
|
|
@ -164,6 +164,7 @@ static void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Cla
|
|||
case CLAY_RENDER_COMMAND_TYPE_TEXT: {
|
||||
Clay_TextRenderData *config = &rcmd->renderData.text;
|
||||
TTF_Font *font = rendererData->fonts[config->fontId];
|
||||
TTF_SetFontSize(font, config->fontSize);
|
||||
TTF_Text *text = TTF_CreateText(rendererData->textEngine, font, config->stringContents.chars, config->stringContents.length);
|
||||
TTF_SetTextColor(text, config->textColor.r, config->textColor.g, config->textColor.b, config->textColor.a);
|
||||
TTF_DrawRendererText(text, rect.x, rect.y);
|
||||
|
@ -184,11 +185,11 @@ static void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Cla
|
|||
if (config->width.left > 0) {
|
||||
const float starting_y = rect.y + clampedRadii.topLeft;
|
||||
const float length = rect.h - clampedRadii.topLeft - clampedRadii.bottomLeft;
|
||||
SDL_FRect line = { rect.x, starting_y, config->width.left, length };
|
||||
SDL_FRect line = { rect.x - 1, starting_y, config->width.left, length };
|
||||
SDL_RenderFillRect(rendererData->renderer, &line);
|
||||
}
|
||||
if (config->width.right > 0) {
|
||||
const float starting_x = rect.x + rect.w - (float)config->width.right;
|
||||
const float starting_x = rect.x + rect.w - (float)config->width.right + 1;
|
||||
const float starting_y = rect.y + clampedRadii.topRight;
|
||||
const float length = rect.h - clampedRadii.topRight - clampedRadii.bottomRight;
|
||||
SDL_FRect line = { starting_x, starting_y, config->width.right, length };
|
||||
|
@ -197,12 +198,12 @@ static void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Cla
|
|||
if (config->width.top > 0) {
|
||||
const float starting_x = rect.x + clampedRadii.topLeft;
|
||||
const float length = rect.w - clampedRadii.topLeft - clampedRadii.topRight;
|
||||
SDL_FRect line = { starting_x, rect.y, length, config->width.top };
|
||||
SDL_FRect line = { starting_x, rect.y - 1, length, config->width.top };
|
||||
SDL_RenderFillRect(rendererData->renderer, &line);
|
||||
}
|
||||
if (config->width.bottom > 0) {
|
||||
const float starting_x = rect.x + clampedRadii.bottomLeft;
|
||||
const float starting_y = rect.y + rect.h - (float)config->width.bottom;
|
||||
const float starting_y = rect.y + rect.h - (float)config->width.bottom + 1;
|
||||
const float length = rect.w - clampedRadii.bottomLeft - clampedRadii.bottomRight;
|
||||
SDL_FRect line = { starting_x, starting_y, length, config->width.bottom };
|
||||
SDL_SetRenderDrawColor(rendererData->renderer, config->color.r, config->color.g, config->color.b, config->color.a);
|
||||
|
@ -211,25 +212,25 @@ static void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Cla
|
|||
//corners
|
||||
if (config->cornerRadius.topLeft > 0) {
|
||||
const float centerX = rect.x + clampedRadii.topLeft -1;
|
||||
const float centerY = rect.y + clampedRadii.topLeft;
|
||||
const float centerY = rect.y + clampedRadii.topLeft - 1;
|
||||
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.topLeft,
|
||||
180.0f, 270.0f, config->width.top, config->color);
|
||||
}
|
||||
if (config->cornerRadius.topRight > 0) {
|
||||
const float centerX = rect.x + rect.w - clampedRadii.topRight -1;
|
||||
const float centerY = rect.y + clampedRadii.topRight;
|
||||
const float centerX = rect.x + rect.w - clampedRadii.topRight;
|
||||
const float centerY = rect.y + clampedRadii.topRight - 1;
|
||||
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.topRight,
|
||||
270.0f, 360.0f, config->width.top, config->color);
|
||||
}
|
||||
if (config->cornerRadius.bottomLeft > 0) {
|
||||
const float centerX = rect.x + clampedRadii.bottomLeft -1;
|
||||
const float centerY = rect.y + rect.h - clampedRadii.bottomLeft -1;
|
||||
const float centerY = rect.y + rect.h - clampedRadii.bottomLeft;
|
||||
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.bottomLeft,
|
||||
90.0f, 180.0f, config->width.bottom, config->color);
|
||||
}
|
||||
if (config->cornerRadius.bottomRight > 0) {
|
||||
const float centerX = rect.x + rect.w - clampedRadii.bottomRight -1; //TODO: why need to -1 in all calculations???
|
||||
const float centerY = rect.y + rect.h - clampedRadii.bottomRight -1;
|
||||
const float centerX = rect.x + rect.w - clampedRadii.bottomRight;
|
||||
const float centerY = rect.y + rect.h - clampedRadii.bottomRight;
|
||||
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.bottomRight,
|
||||
0.0f, 90.0f, config->width.bottom, config->color);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,15 @@
|
|||
Unfortunately Clay does not currently provide feedback on whether a mouse
|
||||
click was handled or not.
|
||||
|
||||
--- if you want to use images with clay, you should pass a pointer to a
|
||||
sclay_image to the CLAY macro, like this:
|
||||
CLAY({
|
||||
...
|
||||
.image = { .imageData = &(sclay_image){ .view = view, .sampler = 0 } },
|
||||
})
|
||||
Using 0 as a sampler uses the sokol default sampler with linear interpolation.
|
||||
The image should be created using sg_make_image from sokol_gfx.
|
||||
|
||||
--- finally, on application shutdown, call
|
||||
|
||||
sclay_shutdown()
|
||||
|
@ -101,6 +110,15 @@
|
|||
|
||||
typedef int sclay_font_t;
|
||||
|
||||
typedef struct sclay_image {
|
||||
sg_view view;
|
||||
sg_sampler sampler;
|
||||
struct {
|
||||
float u0, v0, u1, v1;
|
||||
} uv;
|
||||
} sclay_image;
|
||||
|
||||
|
||||
void sclay_setup();
|
||||
void sclay_shutdown();
|
||||
|
||||
|
@ -227,13 +245,14 @@ Clay_Dimensions sclay_measure_text(Clay_StringSlice text, Clay_TextElementConfig
|
|||
sclay_font_t *fonts = (sclay_font_t *)userData;
|
||||
if(!fonts) return (Clay_Dimensions){ 0 };
|
||||
fonsSetFont(_sclay.fonts, fonts[config->fontId]);
|
||||
fonsSetSize(_sclay.fonts, config->fontSize);
|
||||
fonsSetSpacing(_sclay.fonts, config->letterSpacing);
|
||||
fonsSetSize(_sclay.fonts, config->fontSize * _sclay.dpi_scale);
|
||||
fonsSetSpacing(_sclay.fonts, config->letterSpacing * _sclay.dpi_scale);
|
||||
fonsSetAlign(_sclay.fonts, FONS_ALIGN_LEFT | FONS_ALIGN_TOP);
|
||||
float ascent, descent, lineh;
|
||||
fonsVertMetrics(_sclay.fonts, &ascent, &descent, &lineh);
|
||||
return (Clay_Dimensions) {
|
||||
.width = fonsTextBounds(_sclay.fonts, 0, 0, text.chars, text.chars + text.length, NULL),
|
||||
.height = ascent - descent
|
||||
.width = fonsTextBounds(_sclay.fonts, 0, 0, text.chars, text.chars + text.length, NULL) / _sclay.dpi_scale,
|
||||
.height = (ascent - descent) / _sclay.dpi_scale
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -246,6 +265,15 @@ static void _draw_rect(float x, float y, float w, float h){
|
|||
sgl_v2f(x+w, y+h);
|
||||
}
|
||||
|
||||
static void _draw_rect_textured(float x, float y, float w, float h, float u0, float v0, float u1, float v1){
|
||||
sgl_v2f_t2f(x, y, u0, v0);
|
||||
sgl_v2f_t2f(x, y, u0, v0);
|
||||
sgl_v2f_t2f(x+w, y, u1, v0);
|
||||
sgl_v2f_t2f(x, y+h, u0, v1);
|
||||
sgl_v2f_t2f(x+w, y+h, u1, v1);
|
||||
sgl_v2f_t2f(x+w, y+h, u1, v1);
|
||||
}
|
||||
|
||||
static float _SIN[16] = {
|
||||
0.000000f, 0.104528f, 0.207912f, 0.309017f,
|
||||
0.406737f, 0.500000f, 0.587785f, 0.669131f,
|
||||
|
@ -265,6 +293,23 @@ static void _draw_corner(float x, float y, float rx, float ry){
|
|||
sgl_v2f(x+(rx*_SIN[0]), y+(ry*_SIN[15]));
|
||||
}
|
||||
|
||||
static void _draw_corner_textured(float x, float y, float rx, float ry, float bx, float by, float bw, float bh, float u0, float v0, float u1, float v1) {
|
||||
x -= rx;
|
||||
y -= ry;
|
||||
#define MAP_U(x) (u0+(((x)-bx)/bw)*(u1-u0))
|
||||
#define MAP_V(y) (v0+(((y)-by)/bh)*(v1-v0))
|
||||
sgl_v2f_t2f(x, y, MAP_U(x), MAP_V(y));
|
||||
for(int i = 0; i < 16; ++i){
|
||||
sgl_v2f_t2f(x, y, MAP_U(x), MAP_V(y));
|
||||
float px = x+(rx*_SIN[15-i]);
|
||||
float py = y+(ry*_SIN[i]);
|
||||
sgl_v2f_t2f(px, py, MAP_U(px), MAP_V(py));
|
||||
}
|
||||
sgl_v2f_t2f(x+(rx*_SIN[0]), y+(ry*_SIN[15]), MAP_U(x+(rx*_SIN[0])), MAP_V(y+(ry*_SIN[15])));
|
||||
#undef MAP_U
|
||||
#undef MAP_V
|
||||
}
|
||||
|
||||
/* rx,ry = radius ix,iy = inner radius */
|
||||
static void _draw_corner_border(float x, float y, float rx, float ry, float ix, float iy){
|
||||
x -= rx;
|
||||
|
@ -389,7 +434,108 @@ void sclay_render(Clay_RenderCommandArray renderCommands, sclay_font_t *fonts) {
|
|||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
|
||||
//TODO
|
||||
Clay_ImageRenderData *config = &renderCommand->renderData.image;
|
||||
sclay_image* img = (sclay_image*)config->imageData;
|
||||
// by default, u1 and v1 are 1. if we pass 0.
|
||||
// note, we are modifying a copy !
|
||||
float u0 = img->uv.u0;
|
||||
float v0 = img->uv.v0;
|
||||
float u1 = img->uv.u1;
|
||||
float v1 = img->uv.v1;
|
||||
if (u1 == 0.f) {
|
||||
u1 = 1.f;
|
||||
}
|
||||
if (v1 == 0.f) {
|
||||
v1 = 1.f;
|
||||
}
|
||||
|
||||
int untinted = config->backgroundColor.r == 0 && config->backgroundColor.g == 0 && config->backgroundColor.b == 0 && config->backgroundColor.a == 0;
|
||||
float cr = untinted ? 1.f : (config->backgroundColor.r / 255.0f);
|
||||
float gr = untinted ? 1.f : (config->backgroundColor.g / 255.0f);
|
||||
float br = untinted ? 1.f : (config->backgroundColor.b / 255.0f);
|
||||
float ar = untinted ? 1.f : (config->backgroundColor.a / 255.0f);
|
||||
|
||||
sgl_c4f(cr, gr, br, ar);
|
||||
|
||||
Clay_CornerRadius r = config->cornerRadius;
|
||||
|
||||
sgl_enable_texture();
|
||||
sgl_texture(img->view, img->sampler);
|
||||
|
||||
sgl_begin_triangle_strip();
|
||||
if(r.topLeft > 0 || r.topRight > 0){
|
||||
_draw_corner_textured(bbox.x, bbox.y, -r.topLeft, -r.topLeft, bbox.x, bbox.y, bbox.width, bbox.height, u0, v0, u1, v1);
|
||||
_draw_corner_textured(bbox.x+bbox.width, bbox.y, r.topRight, -r.topRight, bbox.x, bbox.y, bbox.width, bbox.height, u0, v0, u1, v1);
|
||||
_draw_rect_textured(bbox.x+r.topLeft, bbox.y,
|
||||
bbox.width-r.topLeft-r.topRight, CLAY__MAX(r.topLeft, r.topRight),
|
||||
u0 + (r.topLeft/bbox.width)*(u1-u0), v0, u1 - (r.topRight/bbox.width)*(u1-u0), v0 + (CLAY__MAX(r.topLeft, r.topRight)/bbox.height)*(v1-v0));
|
||||
}
|
||||
if(r.bottomLeft > 0 || r.bottomRight > 0){
|
||||
_draw_corner_textured(bbox.x, bbox.y+bbox.height, -r.bottomLeft, r.bottomLeft, bbox.x, bbox.y, bbox.width, bbox.height, u0, v0, u1, v1);
|
||||
_draw_corner_textured(bbox.x+bbox.width, bbox.y+bbox.height, r.bottomRight, r.bottomRight, bbox.x, bbox.y, bbox.width, bbox.height, u0, v0, u1, v1);
|
||||
_draw_rect_textured(bbox.x+r.bottomLeft,
|
||||
bbox.y+bbox.height-CLAY__MAX(r.bottomLeft, r.bottomRight),
|
||||
bbox.width-r.bottomLeft-r.bottomRight, CLAY__MAX(r.bottomLeft, r.bottomRight),
|
||||
u0 + (r.bottomLeft/bbox.width)*(u1-u0), v1 - (CLAY__MAX(r.bottomLeft, r.bottomRight)/bbox.height)*(v1-v0), u1 - (r.bottomRight/bbox.width)*(u1-u0), v1);
|
||||
}
|
||||
if(r.topLeft < r.bottomLeft){
|
||||
if(r.topLeft < r.topRight){
|
||||
_draw_rect_textured(bbox.x, bbox.y+r.topLeft, r.topLeft, bbox.height-r.topLeft-r.bottomLeft,
|
||||
u0, v0 + (r.topLeft/bbox.height)*(v1-v0), u0 + (r.topLeft/bbox.width)*(u1-u0), v1 - (r.bottomLeft/bbox.height)*(v1-v0));
|
||||
_draw_rect_textured(bbox.x+r.topLeft, bbox.y+r.topRight,
|
||||
r.bottomLeft-r.topLeft, bbox.height-r.topRight-r.bottomLeft,
|
||||
u0 + (r.topLeft/bbox.width)*(u1-u0), v0 + (r.topRight/bbox.height)*(v1-v0), u0 + (r.topLeft/bbox.width)*(u1-u0), v1 - (r.bottomLeft/bbox.height)*(v1-v0));
|
||||
} else {
|
||||
_draw_rect_textured(bbox.x, bbox.y+r.topLeft, r.bottomLeft, bbox.height-r.topLeft-r.bottomLeft,
|
||||
u0, v0 + (r.topLeft/bbox.height)*(v1-v0), u0 + (r.bottomLeft/bbox.width)*(u1-u0), v1 - (r.bottomLeft/bbox.height)*(v1-v0));
|
||||
}
|
||||
} else {
|
||||
if(r.bottomLeft < r.bottomRight){
|
||||
_draw_rect_textured(bbox.x, bbox.y+r.topLeft, r.bottomLeft, bbox.height-r.topLeft-r.bottomLeft,
|
||||
u0, v0 + (r.topLeft/bbox.height)*(v1-v0), u0 + (r.bottomLeft/bbox.width)*(u1-u0), v1 - (r.bottomLeft/bbox.height)*(v1-v0));
|
||||
_draw_rect_textured(bbox.x+r.bottomLeft, bbox.y+r.topLeft,
|
||||
r.topLeft-r.bottomLeft, bbox.height-r.topLeft-r.bottomRight,
|
||||
u0 + (r.bottomLeft/bbox.width)*(u1-u0), v0 + (r.topLeft/bbox.height)*(v1-v0), u0 + (r.topLeft/bbox.width)*(u1-u0), v1 - (r.bottomRight/bbox.height)*(v1-v0));
|
||||
} else {
|
||||
_draw_rect_textured(bbox.x, bbox.y+r.topLeft, r.topLeft, bbox.height-r.topLeft-r.bottomLeft,
|
||||
u0, v0 + (r.topLeft/bbox.height)*(v1-v0), u0 + (r.topLeft/bbox.width)*(u1-u0), v1 - (r.bottomLeft/bbox.height)*(v1-v0));
|
||||
}
|
||||
}
|
||||
if(r.topRight < r.bottomRight){
|
||||
if(r.topRight < r.topLeft){
|
||||
_draw_rect_textured(bbox.x+bbox.width-r.bottomRight, bbox.y+r.topLeft,
|
||||
r.bottomRight-r.topRight, bbox.height-r.topLeft-r.bottomRight,
|
||||
u1 - (r.bottomRight/bbox.width)*(u1-u0), v0 + (r.topLeft/bbox.height)*(v1-v0), u1 - (r.topRight/bbox.width)*(u1-u0), v1 - (r.bottomRight/bbox.height)*(v1-v0));
|
||||
_draw_rect_textured(bbox.x+bbox.width-r.topRight, bbox.y+r.topRight,
|
||||
r.topRight, bbox.height-r.topRight-r.bottomRight,
|
||||
u1 - (r.topRight/bbox.width)*(u1-u0), v0 + (r.topRight/bbox.height)*(v1-v0), u1, v1 - (r.bottomRight/bbox.height)*(v1-v0));
|
||||
} else {
|
||||
_draw_rect_textured(bbox.x+bbox.width-r.bottomRight, bbox.y+r.topRight,
|
||||
r.bottomRight, bbox.height-r.topRight-r.bottomRight,
|
||||
u1 - (r.bottomRight/bbox.width)*(u1-u0), v0 + (r.topRight/bbox.height)*(v1-v0), u1, v1 - (r.bottomRight/bbox.height)*(v1-v0));
|
||||
}
|
||||
} else {
|
||||
if(r.bottomRight < r.bottomLeft){
|
||||
_draw_rect_textured(bbox.x+bbox.width-r.topRight, bbox.y+r.topRight,
|
||||
r.topRight-r.bottomRight, bbox.height-r.topRight-r.bottomLeft,
|
||||
u1 - (r.topRight/bbox.width)*(u1-u0), v0 + (r.topRight/bbox.height)*(v1-v0), u1 - (r.bottomRight/bbox.width)*(u1-u0), v1 - (r.bottomLeft/bbox.height)*(v1-v0));
|
||||
_draw_rect_textured(bbox.x+bbox.width-r.bottomRight, bbox.y+r.topRight,
|
||||
r.bottomRight, bbox.height-r.topRight-r.bottomRight,
|
||||
u1 - (r.bottomRight/bbox.width)*(u1-u0), v0 + (r.topRight/bbox.height)*(v1-v0), u1, v1 - (r.bottomRight/bbox.height)*(v1-v0));
|
||||
} else {
|
||||
_draw_rect_textured(bbox.x+bbox.width-r.topRight, bbox.y+r.topRight,
|
||||
r.topRight, bbox.height-r.topRight-r.bottomRight,
|
||||
u1 - (r.topRight/bbox.width)*(u1-u0), v0 + (r.topRight/bbox.height)*(v1-v0), u1, v1 - (r.bottomRight/bbox.height)*(v1-v0));
|
||||
}
|
||||
}
|
||||
_draw_rect_textured(bbox.x+CLAY__MAX(r.topLeft, r.bottomLeft),
|
||||
bbox.y+CLAY__MAX(r.topLeft, r.topRight),
|
||||
bbox.width-CLAY__MAX(r.topLeft, r.bottomLeft)-CLAY__MAX(r.topRight, r.bottomRight),
|
||||
bbox.height-CLAY__MAX(r.topLeft, r.topRight)-CLAY__MAX(r.bottomLeft, r.bottomRight),
|
||||
u0+CLAY__MAX(r.topLeft,r.bottomLeft)/bbox.width*(u1-u0), v0+CLAY__MAX(r.topLeft,r.topRight)/bbox.height*(v1-v0),
|
||||
u1-CLAY__MAX(r.topRight,r.bottomRight)/bbox.width*(u1-u0), v1-CLAY__MAX(r.bottomLeft,r.bottomRight)/bbox.height*(v1-v0));
|
||||
sgl_end();
|
||||
sgl_disable_texture();
|
||||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_BORDER: {
|
||||
|
|
1776
renderers/termbox2/clay_renderer_termbox2.c
Normal file
1776
renderers/termbox2/clay_renderer_termbox2.c
Normal file
File diff suppressed because it is too large
Load diff
2863
renderers/termbox2/image_character_masks.h
Normal file
2863
renderers/termbox2/image_character_masks.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue