mirror of
https://github.com/nicbarker/clay.git
synced 2025-11-02 15:56:16 +00:00
Compare commits
44 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd97d8179e | ||
|
|
7216815536 | ||
|
|
83129995f7 | ||
|
|
588b93196c | ||
|
|
382dcde89d | ||
|
|
c6442bd192 | ||
|
|
7874cdb085 | ||
|
|
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
|
||||
281
README.md
281
README.md
|
|
@ -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
|
||||
|
|
@ -59,7 +59,7 @@ Clay_ElementDeclaration sidebarItemConfig = (Clay_ElementDeclaration) {
|
|||
|
||||
// Re-useable components are just normal functions
|
||||
void SidebarItemComponent() {
|
||||
CLAY(sidebarItemConfig) {
|
||||
CLAY(id, sidebarItemConfig) {
|
||||
// children go here...
|
||||
}
|
||||
}
|
||||
|
|
@ -85,14 +85,13 @@ int main() {
|
|||
Clay_BeginLayout();
|
||||
|
||||
// An example of laying out a UI with a fixed width sidebar and flexible width main content
|
||||
CLAY({ .id = CLAY_ID("OuterContainer"), .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }, .backgroundColor = {250,250,255,255} }) {
|
||||
CLAY({
|
||||
.id = CLAY_ID("SideBar"),
|
||||
CLAY(CLAY_ID("OuterContainer"), { .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }, .backgroundColor = {250,250,255,255} }) {
|
||||
CLAY(CLAY_ID("SideBar"), {
|
||||
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 },
|
||||
.backgroundColor = COLOR_LIGHT
|
||||
}) {
|
||||
CLAY({ .id = CLAY_ID("ProfilePictureOuter"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY({ .id = CLAY_ID("ProfilePicture"), .layout = { .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}, .image = { .imageData = &profilePicture } }) {}
|
||||
CLAY(CLAY_ID("ProfilePictureOuter"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY(CLAY_ID("ProfilePicture"), {.layout = { .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}, .image = { .imageData = &profilePicture } }) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay - UI Library"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255, 255, 255, 255} }));
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +100,7 @@ int main() {
|
|||
SidebarItemComponent();
|
||||
}
|
||||
|
||||
CLAY({ .id = CLAY_ID("MainContent"), .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) } }, .backgroundColor = COLOR_LIGHT }) {}
|
||||
CLAY(CLAY_ID("MainContent"), { .layout = { .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) } }, .backgroundColor = COLOR_LIGHT }) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,8 +160,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)
|
||||
|
|
@ -194,16 +193,16 @@ For help starting out or to discuss clay, considering joining [the discord serve
|
|||
## High Level Documentation
|
||||
|
||||
### Building UI Hierarchies
|
||||
Clay UIs are built using the C macro `CLAY({ configuration })`. This macro creates a new empty element in the UI hierarchy, and supports modular customisation of layout, styling and functionality. The `CLAY()` macro can also be _nested_, similar to other declarative UI systems like HTML.
|
||||
Clay UIs are built using the C macro `CLAY(id, { configuration })`. This macro creates a new empty element in the UI hierarchy, and supports modular customisation of layout, styling and functionality. The `CLAY()` macro can also be _nested_, similar to other declarative UI systems like HTML.
|
||||
|
||||
Child elements are added by opening a block: `{}` after calling the `CLAY()` macro (exactly like you would with an `if` statement or `for` loop), and declaring child components inside the braces.
|
||||
```C
|
||||
// Parent element with 8px of padding
|
||||
CLAY({ .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
|
||||
CLAY(CLAY_ID("parent"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
|
||||
// Child element 1
|
||||
CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 }));
|
||||
// Child element 2 with red background
|
||||
CLAY({ .backgroundColor = COLOR_RED }) {
|
||||
CLAY((CLAY_ID("child"), { .backgroundColor = COLOR_RED }) {
|
||||
// etc
|
||||
}
|
||||
}
|
||||
|
|
@ -214,13 +213,13 @@ However, unlike HTML and other declarative DSLs, this macro is just C. As a resu
|
|||
// Re-usable "components" are just functions that declare more UI
|
||||
void ButtonComponent(Clay_String buttonText) {
|
||||
// Red box button with 8px of padding
|
||||
CLAY({ .layout = { .padding = CLAY_PADDING_ALL(8) }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(8) }, .backgroundColor = COLOR_RED }) {
|
||||
CLAY_TEXT(buttonText, textConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Parent element
|
||||
CLAY({ .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY(CLAY_ID("parent"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
// Render a bunch of text elements
|
||||
for (int i = 0; i < textArray.length; i++) {
|
||||
CLAY_TEXT(textArray.elements[i], textConfig);
|
||||
|
|
@ -240,7 +239,7 @@ CLAY({ .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
|||
### Configuring Layout and Styling UI Elements
|
||||
The layout and style of clay elements is configured with the [Clay_ElementDeclaration](#clay_elementdeclaration) struct passed to the `CLAY()` macro.
|
||||
```C
|
||||
CLAY({ .layout = { .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
CLAY(CLAY_ID("box"), { .layout = { .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
|
||||
// Children are 8px inset into parent, and laid out top to bottom
|
||||
}
|
||||
```
|
||||
|
|
@ -257,18 +256,21 @@ Clay_ElementDeclaration reuseableStyle = (Clay_ElementDeclaration) {
|
|||
.cornerRadius = { 12, 12, 12, 12 }
|
||||
};
|
||||
|
||||
CLAY(reuseableStyle) {
|
||||
CLAY(CLAY_ID("box"), reuseableStyle) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Element IDs
|
||||
|
||||
Clay elements can optionally be tagged with a unique identifier using the `.id` field of an element declaration, and with the [CLAY_ID()](#clay_id) convenience macro.
|
||||
The Clay macro by default accepts an ID as its first argument, which is usually provided by the [CLAY_ID()](#clay_id) convenience macro. Elements can also be created with auto generated IDs, by using the [CLAY_AUTO_ID()](#clay-auto-id) macro.
|
||||
|
||||
```C
|
||||
// Will always produce the same ID from the same input string
|
||||
CLAY({ .id = CLAY_ID("OuterContainer") }) {}
|
||||
CLAY(CLAY_ID("OuterContainer"), { ...configuration }) {}
|
||||
|
||||
// Generates a unique ID that may not be the same between two layout calls
|
||||
CLAY_AUTO_ID({ ...configuration }) {}
|
||||
```
|
||||
|
||||
Element IDs have two main use cases. Firstly, tagging an element with an ID allows you to query information about the element later, such as its [mouseover state](#clay_pointerover) or dimensions.
|
||||
|
|
@ -279,11 +281,11 @@ To avoid having to construct dynamic strings at runtime to differentiate ids in
|
|||
```C
|
||||
// This is the equivalent of calling CLAY_ID("Item0"), CLAY_ID("Item1") etc
|
||||
for (int index = 0; index < items.length; index++) {
|
||||
CLAY({ .id = CLAY_IDI("Item", index) }) {}
|
||||
CLAY(CLAY_IDI("Item", index), { ..configuration }) {}
|
||||
}
|
||||
```
|
||||
|
||||
This ID (or, if not provided, an auto generated ID) will be forwarded to the final `Clay_RenderCommandArray` for use in retained mode UIs. Using duplicate IDs may cause some functionality to misbehave (i.e. if you're trying to attach a floating container to a specific element with ID that is duplicated, it may not attach to the one you expect)
|
||||
This ID will be forwarded to the final `Clay_RenderCommandArray` for use in retained mode UIs. Using duplicate IDs may cause some functionality to misbehave (i.e. if you're trying to attach a floating container to a specific element with ID that is duplicated, it may not attach to the one you expect)
|
||||
|
||||
### Mouse, Touch and Pointer Interactions
|
||||
|
||||
|
|
@ -297,7 +299,7 @@ The function `bool Clay_Hovered()` can be called during element construction or
|
|||
|
||||
```C
|
||||
// An orange button that turns blue when hovered
|
||||
CLAY({ .backgroundColor = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }) {
|
||||
CLAY(CLAY_ID("Button"), { .backgroundColor = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }) {
|
||||
bool buttonHovered = Clay_Hovered();
|
||||
CLAY_TEXT(buttonHovered ? CLAY_STRING("Hovered") : CLAY_STRING("Hover me!"), headerTextConfig);
|
||||
}
|
||||
|
|
@ -318,7 +320,7 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerI
|
|||
ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };
|
||||
|
||||
// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
|
||||
CLAY({ .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
|
||||
CLAY(CLAY_ID("Button"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
|
||||
Clay_OnHover(HandleButtonInteraction, &linkButton);
|
||||
CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig);
|
||||
}
|
||||
|
|
@ -360,11 +362,11 @@ Clay_UpdateScrollContainers(
|
|||
);
|
||||
// ...
|
||||
// Clay internally tracks the scroll containers offset, and Clay_GetScrollOffset returns the x,y offset of the currently open element
|
||||
CLAY({ .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
|
||||
CLAY(CLAY_ID("ScrollContainer"), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
|
||||
// Scrolling contents
|
||||
}
|
||||
// .childOffset can be provided directly if you would prefer to manage scrolling outside of clay
|
||||
CLAY({ .clip = { .vertical = true, .childOffset = myData.scrollContainer.offset } }) {
|
||||
CLAY(CLAY_ID("ScrollContainer"), { .clip = { .vertical = true, .childOffset = myData.scrollContainer.offset } }) {
|
||||
// Scrolling contents
|
||||
}
|
||||
```
|
||||
|
|
@ -383,10 +385,10 @@ A classic example use case for floating elements is tooltips and modals.
|
|||
```C
|
||||
// The two text elements will be laid out top to bottom, and the floating container
|
||||
// will be attached to "Outer"
|
||||
CLAY({ .id = CLAY_ID("Outer"), .layout = { .layoutDirection = TOP_TO_BOTTOM } }) {
|
||||
CLAY_TEXT(CLAY_ID("Button"), text, &headerTextConfig);
|
||||
CLAY({ .id = CLAY_ID("Tooltip"), .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } }) {}
|
||||
CLAY_TEXT(CLAY_ID("Button"), text, &headerTextConfig);
|
||||
CLAY(CLAY_ID("Outer"), { .layout = { .layoutDirection = TOP_TO_BOTTOM } }) {
|
||||
CLAY_TEXT(text, &headerTextConfig);
|
||||
CLAY(CLAY_ID("Tooltip"), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } }) {}
|
||||
CLAY_TEXT(text, &headerTextConfig);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -424,14 +426,11 @@ typedef struct {
|
|||
// During init
|
||||
Arena frameArena = (Arena) { .memory = malloc(1024) };
|
||||
|
||||
// ...
|
||||
CLAY(0) {
|
||||
// Custom elements only take a single pointer, so we need to store the data somewhere
|
||||
CustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);
|
||||
*modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };
|
||||
frameArena.offset += sizeof(CustomElementData);
|
||||
CLAY({ .custom = { .customData = modelData } }) {}
|
||||
}
|
||||
// Custom elements only take a single pointer, so we need to store the data somewhere
|
||||
CustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);
|
||||
*modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };
|
||||
frameArena.offset += sizeof(CustomElementData);
|
||||
CLAY(CLAY_ID("3DModelViewer"), { .custom = { .customData = modelData } }) {}
|
||||
|
||||
// Later during your rendering
|
||||
switch (renderCommand->commandType) {
|
||||
|
|
@ -682,7 +681,7 @@ See [Scrolling Elements](#scrolling-elements) for more details.
|
|||
|
||||
```C
|
||||
// Create a horizontally scrolling container
|
||||
CLAY({
|
||||
CLAY(CLAY_ID("ScrollContainer"), {
|
||||
.clip = { .horizontal = true, .childOffset = Clay_GetScrollOffset() }
|
||||
})
|
||||
```
|
||||
|
|
@ -732,9 +731,9 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerD
|
|||
ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };
|
||||
|
||||
// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
|
||||
CLAY({ .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
|
||||
CLAY(CLAY_ID("Button"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
|
||||
Clay_OnHover(HandleButtonInteraction, &buttonData);
|
||||
CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING("Click me!"), &headerTextConfig);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -788,13 +787,40 @@ Returns a [Clay_ElementId](#clay_elementid) for the provided id string, used for
|
|||
**Examples**
|
||||
```C
|
||||
// Define an element with 16px of x and y padding
|
||||
CLAY({ .id = CLAY_ID("Outer"), .layout = { .padding = CLAY_PADDING_ALL(16) } }) {
|
||||
CLAY(CLAY_ID("Outer"), { .layout = { .padding = CLAY_PADDING_ALL(16) } }) {
|
||||
// A nested child element
|
||||
CLAY({ .id = CLAY_ID("SideBar"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
|
||||
CLAY(CLAY_ID("SideBar"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
|
||||
// Children laid out top to bottom with a 16 px gap between them
|
||||
}
|
||||
// A vertical scrolling container with a colored background
|
||||
CLAY({
|
||||
CLAY(CLAY_ID("ScrollContainer"), {
|
||||
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
|
||||
.backgroundColor = { 200, 200, 100, 255 },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
|
||||
}) {
|
||||
// child elements
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### CLAY_AUTO_ID()
|
||||
|
||||
A version of the core [CLAY()](#clay) element creation macro that generates an ID automatically instead of requiring it as the first argument.
|
||||
|
||||
Note that under the hood this ID is generated in the same way as [CLAY_ID_LOCAL()](#clay_id_local), which is based on the element's position in the hierarchy, and may chance between layout calls if elements are added / removed from the hierarchy before the element is defined. As a result, for transitions & retained mode backends to work correctly, IDs should be specified.
|
||||
|
||||
```C
|
||||
// Note that CLAY_AUTO_ID only takes one argument: the configuration
|
||||
CLAY_AUTO_ID({ .layout = { .padding = CLAY_PADDING_ALL(16) } }) {
|
||||
// A nested child element
|
||||
CLAY_AUTO_ID({ .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 } }) {
|
||||
// Children laid out top to bottom with a 16 px gap between them
|
||||
}
|
||||
// A vertical scrolling container with a colored background
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
|
||||
.backgroundColor = { 200, 200, 100, 255 },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||
|
|
@ -931,8 +957,7 @@ To regenerate the same ID outside of layout declaration when using utility funct
|
|||
|
||||
```C
|
||||
// Tag a button with the Id "Button"
|
||||
CLAY({
|
||||
.id = CLAY_ID("Button"),
|
||||
CLAY(CLAY_ID("Button"), {
|
||||
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }
|
||||
}) {
|
||||
// ...children
|
||||
|
|
@ -1065,18 +1090,9 @@ typedef struct {
|
|||
|
||||
**Fields**
|
||||
|
||||
**`.id`** - `Clay_ElementID`
|
||||
|
||||
`CLAY({ .id = CLAY_ID("FileButton") })`
|
||||
|
||||
Uses [Clay_ElementId](#clay_elementid). Tags the element with an ID that can be later used to query data about the element, and gives it a human readable name in the debug tools.
|
||||
IDs are typically generated using the [CLAY_ID](#clay_id), [CLAY_IDI](#clay_idi), [CLAY_ID_LOCAL](#clay_id_local) and [CLAY_IDI_LOCAL](#clay_idi_local) macros.
|
||||
|
||||
---
|
||||
|
||||
**`.layout`** - `Clay_LayoutConfig`
|
||||
|
||||
`CLAY({ .layout = { .padding = { 16, 16, 12, 12 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } })`
|
||||
`CLAY(CLAY_ID("Element"), { .layout = { .padding = { 16, 16, 12, 12 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } })`
|
||||
|
||||
Uses [Clay_LayoutConfig](#clay_layoutconfig). Controls various settings related to _layout_, which can be thought of as "the size and position of this element and its children".
|
||||
|
||||
|
|
@ -1084,7 +1100,7 @@ Uses [Clay_LayoutConfig](#clay_layoutconfig). Controls various settings related
|
|||
|
||||
**`.backgroundColor`** - `Clay_Color`
|
||||
|
||||
`CLAY({ .backgroundColor = {120, 120, 120, 255} } })`
|
||||
`CLAY(CLAY_ID("Element"), { .backgroundColor = {120, 120, 120, 255} } })`
|
||||
|
||||
Uses [Clay_Color](#clay_color). Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.
|
||||
|
||||
|
|
@ -1092,7 +1108,7 @@ Uses [Clay_Color](#clay_color). Conventionally accepts `rgba` float values betwe
|
|||
|
||||
**`.cornerRadius`** - `float`
|
||||
|
||||
`CLAY({ .cornerRadius = { .topLeft = 16, .topRight = 16, .bottomLeft = 16, .bottomRight = 16 } })`
|
||||
`CLAY(CLAY_ID("Element"), { .cornerRadius = { .topLeft = 16, .topRight = 16, .bottomLeft = 16, .bottomRight = 16 } })`
|
||||
|
||||
Defines the radius in pixels for the arc of rectangle corners (`0` is square, `rectangle.width / 2` is circular).
|
||||
|
||||
|
|
@ -1102,7 +1118,7 @@ Note that the `CLAY_CORNER_RADIUS(radius)` function-like macro is available to p
|
|||
|
||||
**`.aspectRatio`** - `Clay_AspectRatioElementConfig`
|
||||
|
||||
`CLAY({ .aspectRatio = 1 })`
|
||||
`CLAY(CLAY_ID("Element"), { .aspectRatio = 1 })`
|
||||
|
||||
Uses [Clay_AspectRatioElementConfig](#clay_aspectratioelementconfig). Configures the element as an aspect ratio scaling element. Especially useful for rendering images, but can also be used to enforce a fixed width / height ratio of other elements.
|
||||
|
||||
|
|
@ -1110,7 +1126,7 @@ Uses [Clay_AspectRatioElementConfig](#clay_aspectratioelementconfig). Configures
|
|||
|
||||
**`.image`** - `Clay_ImageElementConfig`
|
||||
|
||||
`CLAY({ .image = { .imageData = &myImage } })`
|
||||
`CLAY(CLAY_ID("Element"), { .image = { .imageData = &myImage } })`
|
||||
|
||||
Uses [Clay_ImageElementConfig](#clay_imageelementconfig). Configures the element as an image element. Causes a render command with type `IMAGE` to be emitted.
|
||||
|
||||
|
|
@ -1118,7 +1134,7 @@ Uses [Clay_ImageElementConfig](#clay_imageelementconfig). Configures the element
|
|||
|
||||
**`.floating`** - `Clay_FloatingElementConfig`
|
||||
|
||||
`CLAY({ .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } })`
|
||||
`CLAY(CLAY_ID("Element"), { .floating = { .attachTo = CLAY_ATTACH_TO_PARENT } })`
|
||||
|
||||
Uses [Clay_FloatingElementConfig](#clay_floatingelementconfig). Configures the element as an floating element, which allows it to stack "in front" and "on top" of other elements without affecting sibling or parent size or position.
|
||||
|
||||
|
|
@ -1126,7 +1142,7 @@ Uses [Clay_FloatingElementConfig](#clay_floatingelementconfig). Configures the e
|
|||
|
||||
**`.custom`** - `Clay_CustomElementConfig`
|
||||
|
||||
`CLAY({ .custom = { .customData = &my3DModel } })`
|
||||
`CLAY(CLAY_ID("Element"), { .custom = { .customData = &my3DModel } })`
|
||||
|
||||
Uses [Clay_CustomElementConfig](#clay_customelementconfig). Configures the element as a custom element, which allows you to pass custom data through to the renderer. Causes a render command with type `CUSTOM` to be emitted.
|
||||
|
||||
|
|
@ -1134,7 +1150,7 @@ Uses [Clay_CustomElementConfig](#clay_customelementconfig). Configures the eleme
|
|||
|
||||
**`.clip`** - `Clay_ClipElementConfig`
|
||||
|
||||
`CLAY({ .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } })`
|
||||
`CLAY(CLAY_ID("Element"), { .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } })`
|
||||
|
||||
Uses [Clay_ClipElementConfig](#clay_scrollelementconfig). Configures the element as a clip element, which causes child elements to be clipped / masked if they overflow, and together with the functions listed in [Scrolling Elements](#scrolling-elements) enables scrolling of child contents.
|
||||
|
||||
|
|
@ -1144,7 +1160,7 @@ Uses [Clay_ClipElementConfig](#clay_scrollelementconfig). Configures the element
|
|||
|
||||
**`.border`** - `Clay_BorderElementConfig`
|
||||
|
||||
`CLAY({ .border = { .width = { .left = 5 }, .color = COLOR_BLUE } })`
|
||||
`CLAY(CLAY_ID("Element"), { .border = { .width = { .left = 5 }, .color = COLOR_BLUE } })`
|
||||
|
||||
Uses [Clay_BorderElementConfig](#clay_borderelementconfig). Configures the element as a border element, which instructs the renderer to draw coloured border lines along the perimeter of this element's bounding box. Causes a render command with type `BORDER` to be emitted.
|
||||
|
||||
|
|
@ -1152,7 +1168,7 @@ Uses [Clay_BorderElementConfig](#clay_borderelementconfig). Configures the eleme
|
|||
|
||||
**`.userData`** - `void *`
|
||||
|
||||
`CLAY({ .userData = &extraData })`
|
||||
`CLAY(CLAY_ID("Element"), { .userData = &extraData })`
|
||||
|
||||
Transparently passes a pointer through to the corresponding [Clay_RenderCommands](#clay_rendercommand)s generated by this element.
|
||||
|
||||
|
|
@ -1164,13 +1180,13 @@ Transparently passes a pointer through to the corresponding [Clay_RenderCommands
|
|||
// Declare a reusable rectangle config, with a purple color and 10px rounded corners
|
||||
Clay_RectangleElementConfig rectangleConfig = (Clay_RectangleElementConfig) { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) };
|
||||
// Declare a rectangle element using a reusable config
|
||||
CLAY(rectangleConfig)) {}
|
||||
CLAY(CLAY_ID("Box"), rectangleConfig) {}
|
||||
// Declare a retangle element using an inline config
|
||||
CLAY({ .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {
|
||||
CLAY(CLAY_ID("BoxInline"), { .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {
|
||||
// child elements
|
||||
}
|
||||
// Declare a scrolling container with a colored background
|
||||
CLAY({
|
||||
CLAY(CLAY_ID("ScrollingContainer"), {
|
||||
.backgroundColor = { 200, 200, 100, 255 },
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10)
|
||||
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
|
||||
|
|
@ -1210,7 +1226,7 @@ Clay_LayoutConfig {
|
|||
|
||||
**`.layoutDirection`** - `Clay_LayoutDirection`
|
||||
|
||||
`CLAY({ .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } })`
|
||||
`CLAY(CLAY_ID("Element"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } })`
|
||||
|
||||
Controls the axis / direction in which child elements are laid out. Available options are `CLAY_LEFT_TO_RIGHT` (default) and `CLAY_TOP_TO_BOTTOM`.
|
||||
|
||||
|
|
@ -1222,7 +1238,7 @@ _Did you know that "left to right" and "top to bottom" both have 13 letters?_
|
|||
|
||||
**`.padding`** - `Clay_Padding`
|
||||
|
||||
`CLAY({ .layout = { .padding = { .left = 16, .right = 16, .top = 8, .bottom = 8 } } })`
|
||||
`CLAY(CLAY_ID("Element"), { .layout = { .padding = { .left = 16, .right = 16, .top = 8, .bottom = 8 } } })`
|
||||
|
||||
Controls white-space "padding" around the **outside** of child elements.
|
||||
|
||||
|
|
@ -1232,7 +1248,7 @@ Controls white-space "padding" around the **outside** of child elements.
|
|||
|
||||
**`.childGap`** - `uint16_t`
|
||||
|
||||
`CLAY({ .layout = { .childGap = 16 } })`
|
||||
`CLAY(CLAY_ID("Element"), { .layout = { .childGap = 16 } })`
|
||||
|
||||
Controls the white-space **between** child elements as they are laid out. When `.layoutDirection` is `CLAY_LEFT_TO_RIGHT` (default), this will be horizontal space, whereas for `CLAY_TOP_TO_BOTTOM` it will be vertical space.
|
||||
|
||||
|
|
@ -1242,7 +1258,7 @@ Controls the white-space **between** child elements as they are laid out. When `
|
|||
|
||||
**`.childAlignment`** - `Clay_ChildAlignment`
|
||||
|
||||
`CLAY({ .layout = { .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER } } })`
|
||||
`CLAY(CLAY_ID("Element"), { .layout = { .childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER } } })`
|
||||
|
||||
Controls the alignment of children relative to the height and width of the parent container. Available options are:
|
||||
```C
|
||||
|
|
@ -1256,7 +1272,7 @@ Controls the alignment of children relative to the height and width of the paren
|
|||
|
||||
**`.sizing`** - `Clay_Sizing`
|
||||
|
||||
`CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_PERCENT(0.5) } } })`
|
||||
`CLAY(CLAY_ID("Element"), { .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_PERCENT(0.5) } } })`
|
||||
|
||||
Controls how final width and height of element are calculated. The same configurations are available for both the `.width` and `.height` axis. There are several options:
|
||||
|
||||
|
|
@ -1276,7 +1292,7 @@ Controls how final width and height of element are calculated. The same configur
|
|||
**Example Usage**
|
||||
|
||||
```C
|
||||
CLAY({ .id = CLAY_ID("Button"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16) } }) {
|
||||
CLAY(CLAY_ID("Button"), { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16) } }) {
|
||||
// Children will be laid out vertically with 16px of padding around and between
|
||||
}
|
||||
```
|
||||
|
|
@ -1286,7 +1302,7 @@ CLAY({ .id = CLAY_ID("Button"), .layout = { .layoutDirection = CLAY_TOP_TO_BOTTO
|
|||
### Clay_ImageElementConfig
|
||||
**Usage**
|
||||
|
||||
`CLAY({ .image = { ...image config } }) {}`
|
||||
`CLAY(CLAY_ID("Element"), { .image = { ...image config } }) {}`
|
||||
|
||||
**Clay_ImageElementConfig** configures a clay element to render an image as its background.
|
||||
|
||||
|
|
@ -1302,7 +1318,7 @@ Clay_ImageElementConfig {
|
|||
|
||||
**`.imageData`** - `void *`
|
||||
|
||||
`CLAY({ .image = { .imageData = &myImage } }) {}`
|
||||
`CLAY(CLAY_ID("Image"), { .image = { .imageData = &myImage } }) {}`
|
||||
|
||||
`.imageData` is a generic void pointer that can be used to pass through image data to the renderer.
|
||||
|
||||
|
|
@ -1310,7 +1326,7 @@ Clay_ImageElementConfig {
|
|||
// Load an image somewhere in your code
|
||||
YourImage profilePicture = LoadYourImage("profilePicture.png");
|
||||
// Note that when rendering, .imageData will be void* type.
|
||||
CLAY({ .image = { .imageData = &profilePicture } }) {}
|
||||
CLAY(CLAY_ID("Image"), { .image = { .imageData = &profilePicture } }) {}
|
||||
```
|
||||
|
||||
**Examples**
|
||||
|
|
@ -1321,9 +1337,9 @@ YourImage profilePicture = LoadYourImage("profilePicture.png");
|
|||
// Declare a reusable image config
|
||||
Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &profilePicture };
|
||||
// Declare an image element using a reusable config
|
||||
CLAY({ .image = imageConfig }) {}
|
||||
CLAY(CLAY_ID("Image"), { .image = imageConfig }) {}
|
||||
// Declare an image element using an inline config
|
||||
CLAY({ .image = { .imageData = &profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
|
||||
CLAY(CLAY_ID("ImageInline"), { .image = { .imageData = &profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
|
||||
// Rendering example
|
||||
YourImage *imageToRender = renderCommand->elementConfig.imageElementConfig->imageData;
|
||||
```
|
||||
|
|
@ -1338,7 +1354,7 @@ Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_
|
|||
|
||||
**Usage**
|
||||
|
||||
`CLAY({ .aspectRatio = 16.0 / 9.0 }) {}`
|
||||
`CLAY(CLAY_ID("Aspect"), { .aspectRatio = 16.0 / 9.0 }) {}`
|
||||
|
||||
**Clay_AspectRatioElementConfig** configures a clay element to enforce a fixed width / height ratio in its final dimensions. Mostly used for image elements, but can also be used for non image elements.
|
||||
|
||||
|
|
@ -1354,11 +1370,11 @@ Clay_AspectRatioElementConfig {
|
|||
|
||||
**`.aspectRatio`** - `float`
|
||||
|
||||
`CLAY({ .aspectRatio = { .aspectRatio = 16.0 / 9.0 } }) {}`
|
||||
`CLAY(CLAY_ID("Aspect"), { .aspectRatio = { .aspectRatio = 16.0 / 9.0 } }) {}`
|
||||
|
||||
or alternatively, as C will automatically pass the value to the first nested struct field:
|
||||
|
||||
`CLAY({ .aspectRatio = 16.0 / 9.0 }) {}`
|
||||
`CLAY(CLAY_ID("Aspect"), { .aspectRatio = 16.0 / 9.0 }) {}`
|
||||
|
||||
**Examples**
|
||||
|
||||
|
|
@ -1366,7 +1382,7 @@ or alternatively, as C will automatically pass the value to the first nested str
|
|||
// Load an image somewhere in your code
|
||||
YourImage profilePicture = LoadYourImage("profilePicture.png");
|
||||
// Declare an image element that will grow along the X axis while maintaining its original aspect ratio
|
||||
CLAY({
|
||||
CLAY(CLAY_ID("ProfilePicture"), {
|
||||
.layout = { .width = CLAY_SIZING_GROW() },
|
||||
.aspectRatio = profilePicture.width / profilePicture.height,
|
||||
.image = { .imageData = &profilePicture },
|
||||
|
|
@ -1378,7 +1394,7 @@ CLAY({
|
|||
### Clay_ImageElementConfig
|
||||
**Usage**
|
||||
|
||||
`CLAY({ .image = { ...image config } }) {}`
|
||||
`CLAY(CLAY_ID("Image"), { .image = { ...image config } }) {}`
|
||||
|
||||
**Clay_ImageElementConfig** configures a clay element to render an image as its background.
|
||||
|
||||
|
|
@ -1394,7 +1410,7 @@ Clay_ImageElementConfig {
|
|||
|
||||
**`.imageData`** - `void *`
|
||||
|
||||
`CLAY({ .image = { .imageData = &myImage } }) {}`
|
||||
`CLAY(CLAY_ID("Image"), { .image = { .imageData = &myImage } }) {}`
|
||||
|
||||
`.imageData` is a generic void pointer that can be used to pass through image data to the renderer.
|
||||
|
||||
|
|
@ -1402,7 +1418,7 @@ Clay_ImageElementConfig {
|
|||
// Load an image somewhere in your code
|
||||
YourImage profilePicture = LoadYourImage("profilePicture.png");
|
||||
// Note that when rendering, .imageData will be void* type.
|
||||
CLAY({ .image = { .imageData = &profilePicture } }) {}
|
||||
CLAY(CLAY_ID("Image"), { .image = { .imageData = &profilePicture } }) {}
|
||||
```
|
||||
|
||||
Note: for an image to maintain its original aspect ratio when using dynamic scaling, the [.aspectRatio](#clay_aspectratioelementconfig) config option must be used.
|
||||
|
|
@ -1415,9 +1431,9 @@ YourImage profilePicture = LoadYourImage("profilePicture.png");
|
|||
// Declare a reusable image config
|
||||
Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &profilePicture };
|
||||
// Declare an image element using a reusable config
|
||||
CLAY({ .image = imageConfig }) {}
|
||||
CLAY(CLAY_ID("Image"), { .image = imageConfig }) {}
|
||||
// Declare an image element using an inline config
|
||||
CLAY({ .image = { .imageData = &profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
|
||||
CLAY(CLAY_ID("ImageInline"), { .image = { .imageData = &profilePicture }, .aspectRatio = 16.0 / 9.0 }) {}
|
||||
// Rendering example
|
||||
YourImage *imageToRender = renderCommand->elementConfig.imageElementConfig->imageData;
|
||||
```
|
||||
|
|
@ -1432,7 +1448,7 @@ Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_
|
|||
|
||||
**Usage**
|
||||
|
||||
`CLAY({ .clip = { ...clip config } }) {}`
|
||||
`CLAY(CLAY_ID("ScrollBox"), { .clip = { ...clip config } }) {}`
|
||||
|
||||
**Notes**
|
||||
|
||||
|
|
@ -1453,7 +1469,7 @@ Clay_ClipElementConfig {
|
|||
|
||||
**`.horizontal`** - `bool`
|
||||
|
||||
`CLAY({ .clip = { .horizontal = true } })`
|
||||
`CLAY(CLAY_ID("HorizontalScroll"), { .clip = { .horizontal = true } })`
|
||||
|
||||
Enables or disables horizontal clipping for this container element.
|
||||
|
||||
|
|
@ -1461,7 +1477,7 @@ Enables or disables horizontal clipping for this container element.
|
|||
|
||||
**`.vertical`** - `bool`
|
||||
|
||||
`CLAY({ .clip = { .vertical = true } })`
|
||||
`CLAY(LAY_ID("VerticalScroll"), { .clip = { .vertical = true } })`
|
||||
|
||||
Enables or disables vertical clipping for this container element.
|
||||
|
||||
|
|
@ -1476,9 +1492,9 @@ Enabling clip for an element will result in two additional render commands:
|
|||
**Examples**
|
||||
|
||||
```C
|
||||
CLAY({ .clip = { .vertical = true } }) {
|
||||
CLAY(CLAY_ID("ScrollOuter"), { .clip = { .vertical = true } }) {
|
||||
// Create child content with a fixed height of 5000
|
||||
CLAY({ .id = CLAY_ID("ScrollInner"), .layout = { .sizing = { .height = CLAY_SIZING_FIXED(5000) } } }) {}
|
||||
CLAY(CLAY_ID("ScrollInner"), { .layout = { .sizing = { .height = CLAY_SIZING_FIXED(5000) } } }) {}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -1488,7 +1504,7 @@ CLAY({ .clip = { .vertical = true } }) {
|
|||
|
||||
**Usage**
|
||||
|
||||
`CLAY({ .border = { ...border config } }) {}`
|
||||
`CLAY(CLAY_ID("Border"), { .border = { ...border config } }) {}`
|
||||
|
||||
**Notes**
|
||||
|
||||
|
|
@ -1516,7 +1532,7 @@ typedef struct Clay_BorderElementConfig
|
|||
|
||||
**`.color`** - `Clay_Color`
|
||||
|
||||
`CLAY({ .border = { .color = { 255, 0, 0, 255 } } })`
|
||||
`CLAY(CLAY_ID("Border"), { .border = { .color = { 255, 0, 0, 255 } } })`
|
||||
|
||||
Uses [Clay_Color](#clay_color). Specifies the shared color for all borders configured by this element. Conventionally accepts `rgba` float values between 0 and 255, but interpretation is left up to the renderer and does not affect layout.
|
||||
|
||||
|
|
@ -1524,7 +1540,7 @@ Uses [Clay_Color](#clay_color). Specifies the shared color for all borders confi
|
|||
|
||||
**`.width`** - `Clay_BorderWidth`
|
||||
|
||||
`CLAY({ .border = { .width = { .left = 2, .right = 10 } } })`
|
||||
`CLAY(CLAY_ID("Border"), { .border = { .width = { .left = 2, .right = 10 } } })`
|
||||
|
||||
Indicates to the renderer that a border of `.color` should be draw at the specified edges of the bounding box, **inset and overlapping the box contents by `.width`**.
|
||||
|
||||
|
|
@ -1534,7 +1550,7 @@ Note:
|
|||
|
||||
**`.width.betweenChildren`**
|
||||
|
||||
`CLAY({ .border = { .width = { .betweenChildren = 2 } }, .color = COLOR_RED })`
|
||||
`CLAY(CLAY_ID("Border"), { .border = { .width = { .betweenChildren = 2 } }, .color = COLOR_RED })`
|
||||
|
||||
Configures the width and color of borders to be drawn between children. These borders will be vertical lines if the parent uses `.layoutDirection = CLAY_LEFT_TO_RIGHT` and horizontal lines if the parent uses `CLAY_TOP_TO_BOTTOM`. Unlike `.left, .top` etc, this option **will generate additional rectangle render commands representing the borders between children.** As a result, the renderer does not need to specifically implement rendering for these border elements.
|
||||
|
||||
|
|
@ -1544,8 +1560,7 @@ Configures the width and color of borders to be drawn between children. These bo
|
|||
|
||||
```C
|
||||
// 300x300 container with a 1px red border around all the edges
|
||||
CLAY({
|
||||
.id = CLAY_ID("OuterBorder"),
|
||||
CLAY(CLAY_ID("OuterBorder"), {
|
||||
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) } },
|
||||
.border = { .width = { 1, 1, 1, 1, 0 }, .color = COLOR_RED }
|
||||
}) {
|
||||
|
|
@ -1553,16 +1568,14 @@ CLAY({
|
|||
}
|
||||
|
||||
// Container with a 3px yellow bottom border
|
||||
CLAY({
|
||||
.id = CLAY_ID("OuterBorder"),
|
||||
CLAY(CLAY_ID("OuterBorder"), {
|
||||
.border = { .width = { .bottom = 3 }, .color = COLOR_YELLOW }
|
||||
}) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Container with a 5px curved border around the edges, and a 5px blue border between all children laid out top to bottom
|
||||
CLAY({
|
||||
.id = CLAY_ID("OuterBorder"),
|
||||
CLAY(CLAY_ID("OuterBorder"), {
|
||||
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM },
|
||||
.border = { .width = { 5, 5, 5, 5, 5 }, .color = COLOR_BLUE }
|
||||
}) {
|
||||
|
|
@ -1585,7 +1598,7 @@ Rendering of borders and rounded corners is left up to the user. See the provide
|
|||
|
||||
**Usage**
|
||||
|
||||
`CLAY({ .floating = { ...floating config } }) {}`
|
||||
`CLAY(CLAY_ID("Floating"), { .floating = { ...floating config } }) {}`
|
||||
|
||||
**Notes**
|
||||
|
||||
|
|
@ -1636,7 +1649,7 @@ Clay_FloatingElementConfig {
|
|||
|
||||
**`.offset`** - `Clay_Vector2`
|
||||
|
||||
`CLAY({ .floating = { .offset = { -24, -24 } } })`
|
||||
`CLAY(CLAY_ID("Floating"), { .floating = { .offset = { -24, -24 } } })`
|
||||
|
||||
Used to apply a position offset to the floating container _after_ all other layout has been calculated.
|
||||
|
||||
|
|
@ -1644,7 +1657,7 @@ Used to apply a position offset to the floating container _after_ all other layo
|
|||
|
||||
**`.expand`** - `Clay_Dimensions`
|
||||
|
||||
`CLAY({ .floating = { .expand = { 16, 16 } } })`
|
||||
`CLAY(CLAY_ID("Floating"), { .floating = { .expand = { 16, 16 } } })`
|
||||
|
||||
Used to expand the width and height of the floating container _before_ laying out child elements.
|
||||
|
||||
|
|
@ -1652,7 +1665,7 @@ Used to expand the width and height of the floating container _before_ laying ou
|
|||
|
||||
**`.zIndex`** - `float`
|
||||
|
||||
`CLAY({ .floating = { .zIndex = 1 } })`
|
||||
`CLAY(CLAY_ID("Floating"), { .floating = { .zIndex = 1 } })`
|
||||
|
||||
All floating elements (as well as their entire child hierarchies) will be sorted by `.zIndex` order before being converted to render commands. If render commands are drawn in order, elements with higher `.zIndex` values will be drawn on top.
|
||||
|
||||
|
|
@ -1660,41 +1673,41 @@ All floating elements (as well as their entire child hierarchies) will be sorted
|
|||
|
||||
**`.parentId`** - `uint32_t`
|
||||
|
||||
`CLAY({ .floating = { .parentId = Clay_GetElementId("HeaderButton").id } })`
|
||||
`CLAY(CLAY_ID("Floating"), { .floating = { .parentId = Clay_GetElementId("HeaderButton").id } })`
|
||||
|
||||
By default, floating containers will "attach" to the parent element that they are declared inside. However, there are cases where this limitation could cause significant performance or ergonomics problems. `.parentId` allows you to specify a `CLAY_ID().id` to attach the floating container to. The parent element with the matching id can be declared anywhere in the hierarchy, it doesn't need to be declared before or after the floating container in particular.
|
||||
|
||||
Consider the following case:
|
||||
```C
|
||||
// Load an image somewhere in your code
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 1) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 1), { }) {
|
||||
// .. some button contents
|
||||
if (tooltip.attachedButtonIndex == 1) {
|
||||
CLAY({ /* floating config... */ })
|
||||
CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
|
||||
}
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 2) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 2), { }) {
|
||||
// .. some button contents
|
||||
if (tooltip.attachedButtonIndex == 2) {
|
||||
CLAY({ /* floating config... */ })
|
||||
CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
|
||||
}
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 3) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 3), { }) {
|
||||
// .. some button contents
|
||||
if (tooltip.attachedButtonIndex == 3) {
|
||||
CLAY({ /* floating config... */ })
|
||||
CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
|
||||
}
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 4) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 4), { }) {
|
||||
// .. some button contents
|
||||
if (tooltip.attachedButtonIndex == 4) {
|
||||
CLAY({ /* floating config... */ })
|
||||
CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
|
||||
}
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 5) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 5), { }) {
|
||||
// .. some button contents
|
||||
if (tooltip.attachedButtonIndex == 5) {
|
||||
CLAY({ /* floating config... */ })
|
||||
CLAY(CLAY_ID("OptionTooltip"), { /* floating config... */ })
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -1703,24 +1716,24 @@ The definition of the above UI is significantly polluted by the need to conditio
|
|||
|
||||
```C
|
||||
// Load an image somewhere in your code
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 1) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 1), { }) {
|
||||
// .. some button contents
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 2) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 2), { }) {
|
||||
// .. some button contents
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 3) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 3), { }) {
|
||||
// .. some button contents
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 4) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 4), { }) {
|
||||
// .. some button contents
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("SidebarButton", 5) }) {
|
||||
CLAY(CLAY_IDI("SidebarButton", 5), { }) {
|
||||
// .. some button contents
|
||||
}
|
||||
|
||||
// Any other point in the hierarchy
|
||||
CLAY({ .id = CLAY_ID("OptionTooltip"), .floating = { .attachTo = CLAY_ATTACH_TO_ELEMENT_ID, .parentId = CLAY_IDI("SidebarButton", tooltip.attachedButtonIndex).id }) {
|
||||
CLAY(CLAY_ID("OptionTooltip"), { .floating = { .attachTo = CLAY_ATTACH_TO_ELEMENT_ID, .parentId = CLAY_IDI("SidebarButton", tooltip.attachedButtonIndex).id }) {
|
||||
// Tooltip contents...
|
||||
}
|
||||
```
|
||||
|
|
@ -1729,7 +1742,7 @@ CLAY({ .id = CLAY_ID("OptionTooltip"), .floating = { .attachTo = CLAY_ATTACH_TO_
|
|||
|
||||
**`.attachment`** - `Clay_FloatingAttachPoints`
|
||||
|
||||
`CLAY({ .floating = { .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_TOP } } }) {}`
|
||||
`CLAY(CLAY_ID("Floating"), { .floating = { .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_TOP } } }) {}`
|
||||
|
||||
In terms of positioning the floating container, `.attachment` specifies
|
||||
|
||||
|
|
@ -1744,7 +1757,7 @@ For example:
|
|||
|
||||
"Attach the LEFT_CENTER of the floating container to the RIGHT_TOP of the parent"
|
||||
|
||||
`CLAY({ .floating = { .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_TOP } } });`
|
||||
`CLAY(CLAY_ID("Floating"), { .floating = { .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_TOP } } });`
|
||||
|
||||

|
||||
|
||||
|
|
@ -1758,31 +1771,31 @@ Controls whether pointer events like hover and click should pass through to cont
|
|||
|
||||
```C
|
||||
// Horizontal container with three option buttons
|
||||
CLAY({ .id = CLAY_ID("OptionsList"), .layout = { childGap = 16 } }) {
|
||||
CLAY({ .id = CLAY_IDI("Option", 1), .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
|
||||
CLAY(CLAY_ID("OptionsList"), { .layout = { childGap = 16 } }) {
|
||||
CLAY(CLAY_IDI("Option", 1), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Option 1"), CLAY_TEXT_CONFIG());
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("Option", 2), .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
|
||||
CLAY(CLAY_IDI("Option", 2), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Option 2"), CLAY_TEXT_CONFIG());
|
||||
// Floating tooltip will attach above the "Option 2" container and not affect widths or positions of other elements
|
||||
CLAY({ .id = CLAY_ID("OptionTooltip"), .floating = { .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_TOP } } }) {
|
||||
CLAY(CLAY_ID("OptionTooltip"), { .floating = { .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_TOP } } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Most popular!"), CLAY_TEXT_CONFIG());
|
||||
}
|
||||
}
|
||||
CLAY({ .id = CLAY_IDI("Option", 3), .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
|
||||
CLAY(CLAY_IDI("Option", 3), { .layout = { padding = CLAY_PADDING_ALL(16)), .backgroundColor = COLOR_BLUE } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Option 3"), CLAY_TEXT_CONFIG());
|
||||
}
|
||||
}
|
||||
|
||||
// Floating containers can also be declared elsewhere in a layout, to avoid branching or polluting other UI
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
CLAY({ .id = CLAY_IDI("Option", i + 1) }) {
|
||||
CLAY(CLAY_IDI("Option", i + 1), { }) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
// Note the use of "parentId".
|
||||
// Floating tooltip will attach above the "Option 2" container and not affect widths or positions of other elements
|
||||
CLAY({ .id = CLAY_ID("OptionTooltip"), .floating = { .parentId = CLAY_IDI("Option", 2).id, .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_TOP_CENTER } } }) {
|
||||
CLAY(CLAY_ID("OptionTooltip"), { .floating = { .parentId = CLAY_IDI("Option", 2).id, .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_TOP_CENTER } } }) {
|
||||
CLAY_TEXT(CLAY_STRING("Most popular!"), CLAY_TEXT_CONFIG());
|
||||
}
|
||||
```
|
||||
|
|
@ -1799,7 +1812,7 @@ When using `.parentId`, the floating container can be declared anywhere after `B
|
|||
|
||||
**Usage**
|
||||
|
||||
`CLAY({ .custom = { .customData = &something } }) {}`
|
||||
`CLAY(CLAY_ID("Custom"), { .custom = { .customData = &something } }) {}`
|
||||
|
||||
**Notes**
|
||||
|
||||
|
|
@ -1858,7 +1871,7 @@ CLAY(0) {
|
|||
CustomElementData *modelData = (CustomElementData *)(frameArena.memory + frameArena.offset);
|
||||
*modelData = (CustomElementData) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel };
|
||||
frameArena.offset += sizeof(CustomElementData);
|
||||
CLAY({ .custom = { .customData = modelData } }) {}
|
||||
CLAY(CLAY_ID("3DModelViewer"), { .custom = { .customData = modelData } }) {}
|
||||
}
|
||||
|
||||
// Later during your rendering
|
||||
|
|
|
|||
|
|
@ -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} },
|
||||
}) {
|
||||
|
|
|
|||
373
clay.h
373
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);
|
||||
|
|
@ -1137,6 +1146,7 @@ typedef struct {
|
|||
Clay_LayoutConfig *layoutConfig;
|
||||
Clay__ElementConfigArraySlice elementConfigs;
|
||||
uint32_t id;
|
||||
uint16_t floatingChildrenCount;
|
||||
} Clay_LayoutElement;
|
||||
|
||||
CLAY__ARRAY_DEFINE(Clay_LayoutElement, Clay_LayoutElementArray)
|
||||
|
|
@ -1173,7 +1183,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 +1292,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 +1368,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 +1666,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 +1716,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 +1731,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;
|
||||
|
|
@ -1754,9 +1777,10 @@ Clay_LayoutElementHashMapItem *Clay__GetHashMapItem(uint32_t id) {
|
|||
Clay_ElementId Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayoutElement) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
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);
|
||||
uint32_t offset = parentElement->childrenOrTextContent.children.length + parentElement->floatingChildrenCount;
|
||||
Clay_ElementId elementId = Clay__HashNumber(offset, 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 +1819,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 +1850,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 +1873,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;
|
||||
|
||||
|
|
@ -1887,9 +1919,15 @@ void Clay__CloseElement(void) {
|
|||
|
||||
// Close the currently open element
|
||||
int32_t closingElementIndex = Clay__int32_tArray_RemoveSwapback(&context->openLayoutElementStack, (int)context->openLayoutElementStack.length - 1);
|
||||
|
||||
// Get the currently open parent
|
||||
openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
|
||||
if (!elementIsFloating && context->openLayoutElementStack.length > 1) {
|
||||
if (context->openLayoutElementStack.length > 1) {
|
||||
if(elementIsFloating) {
|
||||
openLayoutElement->floatingChildrenCount++;
|
||||
return;
|
||||
}
|
||||
openLayoutElement->childrenOrTextContent.children.length++;
|
||||
Clay__int32_tArray_Add(&context->layoutElementChildrenBuffer, closingElementIndex);
|
||||
}
|
||||
|
|
@ -1967,8 +2005,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 +2054,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 +2068,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 +2079,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 +2131,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 +2152,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 +2225,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 +2261,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 +2566,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 +2744,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 +2800,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 +2974,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 +2988,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 +3197,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 +3228,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 +3239,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 +3268,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 +3282,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 +3293,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 +3322,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 +3334,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 +3376,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 +3396,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 +3425,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 +3440,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 +3461,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 +3480,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 +3502,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 +3529,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 +3549,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 +3575,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 +3601,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 +3613,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 +3652,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 +3674,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 +3695,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 +3707,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 +3723,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 +3796,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 +3821,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 +3875,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 +3995,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 +4039,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 +4224,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 +4254,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. "
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ mkdir -p build/clay \
|
|||
-Wl,--initial-memory=6553600 \
|
||||
-o build/clay/index.wasm \
|
||||
main.c \
|
||||
&& cp index.html build/clay/index.html && cp -r fonts/ build/clay/fonts \
|
||||
&& cp index.html build/clay/index.html && cp -r images/ build/clay/images
|
||||
&& cp index.html build/index.html && cp -r fonts/ build/clay/fonts \
|
||||
&& cp -r images/ build/clay/images
|
||||
|
|
|
|||
|
|
@ -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 "ffd159c2a6106dd5eef338a6702ad15d4d4aa809"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(termbox2)
|
||||
|
||||
FetchContent_Declare(
|
||||
stb
|
||||
GIT_REPOSITORY "https://github.com/nothings/stb.git"
|
||||
GIT_TAG "fede005abaf93d9d7f3a679d1999b2db341b360f"
|
||||
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)
|
||||
794
examples/termbox2-demo/main.c
Normal file
794
examples/termbox2-demo/main.c
Normal file
|
|
@ -0,0 +1,794 @@
|
|||
/*
|
||||
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(CLAY_ID("Termbox Settings"), {
|
||||
.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({
|
||||
.clip = {
|
||||
.vertical = false,
|
||||
.horizontal = true,
|
||||
.childOffset = Clay_GetScrollOffset(),
|
||||
},
|
||||
.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 }
|
||||
}) {
|
||||
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.5 * Clay_Termbox_Cell_Width(), 0 };
|
||||
Clay_UpdateScrollContainers(false, scrollDelta, 1);
|
||||
break;
|
||||
}
|
||||
case TB_KEY_MOUSE_WHEEL_DOWN: {
|
||||
Clay_Vector2 scrollDelta = { -0.5 * Clay_Termbox_Cell_Width(), 0 };
|
||||
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 "ffd159c2a6106dd5eef338a6702ad15d4d4aa809"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(termbox2)
|
||||
|
||||
FetchContent_Declare(
|
||||
stb
|
||||
GIT_REPOSITORY "https://github.com/nothings/stb.git"
|
||||
GIT_TAG "fede005abaf93d9d7f3a679d1999b2db341b360f"
|
||||
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: {
|
||||
|
|
|
|||
1792
renderers/termbox2/clay_renderer_termbox2.c
Normal file
1792
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