mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-18 12:18:03 +00:00
Compare commits
8 Commits
70b664aa62
...
357d4ecea7
Author | SHA1 | Date | |
---|---|---|---|
|
357d4ecea7 | ||
|
bec56e68a4 | ||
|
2c8856a91e | ||
|
c0c90250a9 | ||
|
4cfbdf2a0c | ||
|
ea3e29be5c | ||
|
134beca09c | ||
|
b3cdf90d39 |
@ -8,4 +8,5 @@ if(NOT MSVC)
|
||||
add_subdirectory("examples/raylib-sidebar-scrolling-container")
|
||||
add_subdirectory("examples/cairo-pdf-rendering")
|
||||
add_subdirectory("examples/clay-official-website")
|
||||
add_subdirectory("examples/introducing-clay-video-demo")
|
||||
endif()
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
Take a look at the [clay website](https://nicbarker.com/clay) for an example of clay compiled to wasm and running in the browser, or others in the [examples directory](https://github.com/nicbarker/clay/tree/main/examples).
|
||||
|
||||
You can also watch the [introduction video](https://youtu.be/DYWTw19_8r4) for an overview of the motivation behind Clay's development and a short demo of its usage.
|
||||
|
||||
<img width="1394" alt="A screenshot of a code IDE with lots of visual and textual elements" src="https://github.com/user-attachments/assets/9986149a-ee0f-449a-a83e-64a392267e3d">
|
||||
|
||||
_An example GUI application built with clay_
|
||||
|
5
bindings/D/README.md
Normal file
5
bindings/D/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
### D Language Example
|
||||
|
||||
```
|
||||
dmd main.d clay.c
|
||||
```
|
2
bindings/D/clay.c
Normal file
2
bindings/D/clay.c
Normal file
@ -0,0 +1,2 @@
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "../../clay.h"
|
88
bindings/D/main.d
Normal file
88
bindings/D/main.d
Normal file
@ -0,0 +1,88 @@
|
||||
import clay;
|
||||
|
||||
import core.stdc.stdlib;
|
||||
|
||||
__gshared:
|
||||
|
||||
Clay_LayoutConfig layoutElement = { padding: {5} };
|
||||
|
||||
extern(C) void main()
|
||||
{
|
||||
ulong totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = {
|
||||
label: str("Clay Memory Arena"),
|
||||
capacity: totalMemorySize,
|
||||
memory: cast(char*)malloc(totalMemorySize)
|
||||
};
|
||||
|
||||
Clay_Initialize(clayMemory, Clay_Dimensions(1024,768));
|
||||
Clay_BeginLayout();
|
||||
if (ClayBegin( Rectangle(color: Clay_Color(255,255,255,0)), Layout(layoutElement)))
|
||||
{ }
|
||||
ClayEnd();
|
||||
}
|
||||
|
||||
|
||||
// helper functions
|
||||
Clay_String str(string it)
|
||||
{
|
||||
return Clay_String(cast(int)it.length, it.ptr);
|
||||
}
|
||||
|
||||
bool ClayBegin(A...)(A configs)
|
||||
{
|
||||
Clay__OpenElement();
|
||||
foreach(config; configs)
|
||||
{
|
||||
alias T = typeof(config);
|
||||
static if (is(T == Clay_ElementId))
|
||||
{
|
||||
Clay__AttachId(config);
|
||||
}
|
||||
else static if(is(T == Clay_LayoutConfig*))
|
||||
{
|
||||
Clay__AttachLayoutConfig(config);
|
||||
}
|
||||
else static if(is(T == Clay_ElementConfig))
|
||||
{
|
||||
Clay__AttachElementConfig(config.config, config.type);
|
||||
}
|
||||
else static assert(0, "unsupported " ~ typeof(config).stringof);
|
||||
}
|
||||
|
||||
Clay__ElementPostConfiguration();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClayEnd()
|
||||
{
|
||||
Clay__CloseElement();
|
||||
}
|
||||
|
||||
Clay_ElementId Id(string label)
|
||||
{
|
||||
return Clay__HashString(str(label), 0, 0);
|
||||
}
|
||||
|
||||
Clay_LayoutConfig* Layout(lazy Clay_Sizing sizing = Clay_Sizing.init)
|
||||
{
|
||||
Clay_LayoutConfig config;
|
||||
config.sizing = sizing;
|
||||
return Clay__StoreLayoutConfig(config);
|
||||
}
|
||||
|
||||
Clay_LayoutConfig* Layout(Clay_LayoutConfig config)
|
||||
{
|
||||
return Clay__StoreLayoutConfig(config);
|
||||
}
|
||||
|
||||
Clay_ElementConfig Rectangle(lazy Clay_Color color = Clay_Color.init)
|
||||
{
|
||||
Clay_RectangleElementConfig config;
|
||||
config.color = color;
|
||||
|
||||
Clay_ElementConfig ret;
|
||||
ret.type = Clay__ElementConfigType.CLAY__ELEMENT_CONFIG_TYPE_RECTANGLE;
|
||||
ret.config.rectangleElementConfig = Clay__StoreRectangleElementConfig(config);
|
||||
return ret;
|
||||
}
|
2
bindings/rust/README
Normal file
2
bindings/rust/README
Normal file
@ -0,0 +1,2 @@
|
||||
https://github.com/clay-ui-rs/clay
|
||||
https://crates.io/crates/clay-layout
|
93
clay.h
93
clay.h
@ -69,15 +69,15 @@
|
||||
#define CLAY__STRUCT_0_ARGS() {}
|
||||
#define CLAY__STRUCT_OVERRIDE(_0, _1, NAME, ...) NAME
|
||||
|
||||
#define CLAY__SIZING_FIT_INTERNAL(...) CLAY__INIT(Clay_SizingAxis) { .sizeMinMax = CLAY__INIT(Clay_SizingMinMax) __VA_ARGS__, .type = CLAY__SIZING_TYPE_FIT }
|
||||
#define CLAY__SIZING_FIT_INTERNAL(...) CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = CLAY__INIT(Clay_SizingMinMax) __VA_ARGS__ }, .type = CLAY__SIZING_TYPE_FIT }
|
||||
#define CLAY_SIZING_FIT(...) CLAY__SIZING_FIT_INTERNAL(CLAY__STRUCT_OVERRIDE("empty", ##__VA_ARGS__, CLAY__STRUCT_1_ARGS, CLAY__STRUCT_0_ARGS)(__VA_ARGS__))
|
||||
|
||||
#define CLAY__SIZING_GROW_INTERNAL(...) CLAY__INIT(Clay_SizingAxis) { .sizeMinMax = CLAY__INIT(Clay_SizingMinMax) __VA_ARGS__, .type = CLAY__SIZING_TYPE_GROW }
|
||||
#define CLAY__SIZING_GROW_INTERNAL(...) CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = CLAY__INIT(Clay_SizingMinMax) __VA_ARGS__ }, .type = CLAY__SIZING_TYPE_GROW }
|
||||
#define CLAY_SIZING_GROW(...) CLAY__SIZING_GROW_INTERNAL(CLAY__STRUCT_OVERRIDE("empty", ##__VA_ARGS__, CLAY__STRUCT_1_ARGS, CLAY__STRUCT_0_ARGS)(__VA_ARGS__))
|
||||
|
||||
#define CLAY_SIZING_FIXED(fixedSize) CLAY__INIT(Clay_SizingAxis) { .sizeMinMax = { fixedSize, fixedSize }, .type = CLAY__SIZING_TYPE_FIXED }
|
||||
#define CLAY_SIZING_FIXED(fixedSize) CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { fixedSize, fixedSize } }, .type = CLAY__SIZING_TYPE_FIXED }
|
||||
|
||||
#define CLAY_SIZING_PERCENT(percentOfParent) CLAY__INIT(Clay_SizingAxis) { .sizePercent = (percentOfParent), .type = CLAY__SIZING_TYPE_PERCENT }
|
||||
#define CLAY_SIZING_PERCENT(percentOfParent) CLAY__INIT(Clay_SizingAxis) { .size = { .percent = (percentOfParent) }, .type = CLAY__SIZING_TYPE_PERCENT }
|
||||
|
||||
#define CLAY_ID(label) Clay__AttachId(Clay__HashString(CLAY_STRING(label), 0, 0))
|
||||
|
||||
@ -228,9 +228,9 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
Clay_SizingMinMax sizeMinMax;
|
||||
float sizePercent;
|
||||
};
|
||||
Clay_SizingMinMax minMax;
|
||||
float percent;
|
||||
} size;
|
||||
Clay__SizingType type;
|
||||
} Clay_SizingAxis;
|
||||
|
||||
@ -459,17 +459,17 @@ typedef struct
|
||||
|
||||
// Function Forward Declarations ---------------------------------
|
||||
// Public API functions ---
|
||||
uint32_t Clay_MinMemorySize();
|
||||
uint32_t Clay_MinMemorySize(void);
|
||||
Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset);
|
||||
void Clay_SetPointerState(Clay_Vector2 position, bool pointerDown);
|
||||
void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler);
|
||||
void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime);
|
||||
void Clay_SetLayoutDimensions(Clay_Dimensions dimensions);
|
||||
void Clay_BeginLayout();
|
||||
Clay_RenderCommandArray Clay_EndLayout();
|
||||
void Clay_BeginLayout(void);
|
||||
Clay_RenderCommandArray Clay_EndLayout(void);
|
||||
Clay_ElementId Clay_GetElementId(Clay_String idString);
|
||||
Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index);
|
||||
bool Clay_Hovered();
|
||||
bool Clay_Hovered(void);
|
||||
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData), intptr_t userData);
|
||||
Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id);
|
||||
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config));
|
||||
@ -481,10 +481,10 @@ void Clay_SetMaxElementCount(uint32_t maxElementCount);
|
||||
void Clay_SetMaxMeasureTextCacheWordCount(uint32_t maxMeasureTextCacheWordCount);
|
||||
|
||||
// Internal API functions required by macros
|
||||
void Clay__OpenElement();
|
||||
void Clay__CloseElement();
|
||||
void Clay__OpenElement(void);
|
||||
void Clay__CloseElement(void);
|
||||
Clay_LayoutConfig * Clay__StoreLayoutConfig(Clay_LayoutConfig config);
|
||||
void Clay__ElementPostConfiguration();
|
||||
void Clay__ElementPostConfiguration(void);
|
||||
void Clay__AttachId(Clay_ElementId id);
|
||||
void Clay__AttachLayoutConfig(Clay_LayoutConfig *config);
|
||||
void Clay__AttachElementConfig(Clay_ElementConfigUnion config, Clay__ElementConfigType type);
|
||||
@ -496,7 +496,7 @@ Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomElementConf
|
||||
Clay_ScrollElementConfig * Clay__StoreScrollElementConfig(Clay_ScrollElementConfig config);
|
||||
Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderElementConfig config);
|
||||
Clay_ElementId Clay__HashString(Clay_String key, uint32_t offset, uint32_t seed);
|
||||
void Clay__Noop();
|
||||
void Clay__Noop(void);
|
||||
void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig);
|
||||
|
||||
extern Clay_Color Clay__debugViewHighlightColor;
|
||||
@ -528,7 +528,7 @@ uint32_t Clay__maxMeasureTextCacheWordCount = 16384;
|
||||
void Clay__ErrorHandlerFunctionDefault(Clay_ErrorData errorText) {}
|
||||
Clay_ErrorHandler Clay__errorHandler = CLAY__INIT(Clay_ErrorHandler) { .errorHandlerFunction = Clay__ErrorHandlerFunctionDefault };
|
||||
|
||||
void Clay__Noop() {}
|
||||
void Clay__Noop(void) {}
|
||||
|
||||
Clay_String CLAY__SPACECHAR = CLAY__INIT(Clay_String) { .length = 1, .chars = " " };
|
||||
Clay_String CLAY__STRING_DEFAULT = CLAY__INIT(Clay_String) { .length = 0, .chars = NULL };
|
||||
@ -707,7 +707,7 @@ Clay_ElementConfig *Clay__ElementConfigArraySlice_Get(Clay__ElementConfigArraySl
|
||||
#pragma endregion
|
||||
// __GENERATED__ template
|
||||
|
||||
Clay_LayoutConfig CLAY_LAYOUT_DEFAULT = CLAY__INIT(Clay_LayoutConfig){ .sizing = { .width = { .sizeMinMax = {0, CLAY__MAXFLOAT }, .type = CLAY__SIZING_TYPE_FIT }, .height = { .sizeMinMax = {0, CLAY__MAXFLOAT }, .type = CLAY__SIZING_TYPE_FIT } } };
|
||||
Clay_LayoutConfig CLAY_LAYOUT_DEFAULT = CLAY__INIT(Clay_LayoutConfig){ .sizing = { .width = { .size = { .minMax = {0, CLAY__MAXFLOAT } }, .type = CLAY__SIZING_TYPE_FIT }, .height = { .size = { .minMax = {0, CLAY__MAXFLOAT } }, .type = CLAY__SIZING_TYPE_FIT } } };
|
||||
|
||||
// __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_LayoutConfig NAME=Clay__LayoutConfigArray DEFAULT_VALUE=&CLAY_LAYOUT_DEFAULT
|
||||
#pragma region generated
|
||||
@ -1760,7 +1760,7 @@ void Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayoutElement)
|
||||
Clay__StringArray_Add(&Clay__layoutElementIdStrings, elementId.stringId);
|
||||
}
|
||||
|
||||
void Clay__ElementPostConfiguration() {
|
||||
void Clay__ElementPostConfiguration(void) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
@ -1848,7 +1848,7 @@ void Clay__ElementPostConfiguration() {
|
||||
Clay__elementConfigBuffer.length -= openLayoutElement->elementConfigs.length;
|
||||
}
|
||||
|
||||
void Clay__CloseElement() {
|
||||
void Clay__CloseElement(void) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
@ -1910,22 +1910,22 @@ void Clay__CloseElement() {
|
||||
|
||||
// Clamp element min and max width to the values configured in the layout
|
||||
if (layoutConfig->sizing.width.type != CLAY__SIZING_TYPE_PERCENT) {
|
||||
if (layoutConfig->sizing.width.sizeMinMax.max <= 0) { // Set the max size if the user didn't specify, makes calculations easier
|
||||
layoutConfig->sizing.width.sizeMinMax.max = CLAY__MAXFLOAT;
|
||||
if (layoutConfig->sizing.width.size.minMax.max <= 0) { // Set the max size if the user didn't specify, makes calculations easier
|
||||
layoutConfig->sizing.width.size.minMax.max = CLAY__MAXFLOAT;
|
||||
}
|
||||
openLayoutElement->dimensions.width = CLAY__MIN(CLAY__MAX(openLayoutElement->dimensions.width, layoutConfig->sizing.width.sizeMinMax.min), layoutConfig->sizing.width.sizeMinMax.max);
|
||||
openLayoutElement->minDimensions.width = CLAY__MIN(CLAY__MAX(openLayoutElement->minDimensions.width, layoutConfig->sizing.width.sizeMinMax.min), layoutConfig->sizing.width.sizeMinMax.max);
|
||||
openLayoutElement->dimensions.width = CLAY__MIN(CLAY__MAX(openLayoutElement->dimensions.width, layoutConfig->sizing.width.size.minMax.min), layoutConfig->sizing.width.size.minMax.max);
|
||||
openLayoutElement->minDimensions.width = CLAY__MIN(CLAY__MAX(openLayoutElement->minDimensions.width, layoutConfig->sizing.width.size.minMax.min), layoutConfig->sizing.width.size.minMax.max);
|
||||
} else {
|
||||
openLayoutElement->dimensions.width = 0;
|
||||
}
|
||||
|
||||
// Clamp element min and max height to the values configured in the layout
|
||||
if (layoutConfig->sizing.height.type != CLAY__SIZING_TYPE_PERCENT) {
|
||||
if (layoutConfig->sizing.height.sizeMinMax.max <= 0) { // Set the max size if the user didn't specify, makes calculations easier
|
||||
layoutConfig->sizing.height.sizeMinMax.max = CLAY__MAXFLOAT;
|
||||
if (layoutConfig->sizing.height.size.minMax.max <= 0) { // Set the max size if the user didn't specify, makes calculations easier
|
||||
layoutConfig->sizing.height.size.minMax.max = CLAY__MAXFLOAT;
|
||||
}
|
||||
openLayoutElement->dimensions.height = CLAY__MIN(CLAY__MAX(openLayoutElement->dimensions.height, layoutConfig->sizing.height.sizeMinMax.min), layoutConfig->sizing.height.sizeMinMax.max);
|
||||
openLayoutElement->minDimensions.height = CLAY__MIN(CLAY__MAX(openLayoutElement->minDimensions.height, layoutConfig->sizing.height.sizeMinMax.min), layoutConfig->sizing.height.sizeMinMax.max);
|
||||
openLayoutElement->dimensions.height = CLAY__MIN(CLAY__MAX(openLayoutElement->dimensions.height, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
|
||||
openLayoutElement->minDimensions.height = CLAY__MIN(CLAY__MAX(openLayoutElement->minDimensions.height, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
|
||||
} else {
|
||||
openLayoutElement->dimensions.height = 0;
|
||||
}
|
||||
@ -1942,7 +1942,7 @@ void Clay__CloseElement() {
|
||||
}
|
||||
}
|
||||
|
||||
void Clay__OpenElement() {
|
||||
void Clay__OpenElement(void) {
|
||||
if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__booleanWarnings.maxElementsExceeded) {
|
||||
Clay__booleanWarnings.maxElementsExceeded = true;
|
||||
return;
|
||||
@ -2063,7 +2063,7 @@ float Clay__DistributeSizeAmongChildren(bool xAxis, float sizeToDistribute, Clay
|
||||
float childMinSize = xAxis ? childElement->minDimensions.width : childElement->minDimensions.height;
|
||||
bool canDistribute = true;
|
||||
|
||||
if ((sizeToDistribute < 0 && *childSize == childSizing.sizeMinMax.min) || (sizeToDistribute > 0 && *childSize == childSizing.sizeMinMax.max)) {
|
||||
if ((sizeToDistribute < 0 && *childSize == childSizing.size.minMax.min) || (sizeToDistribute > 0 && *childSize == childSizing.size.minMax.max)) {
|
||||
canDistribute = false;
|
||||
}
|
||||
// Currently, we don't support squishing aspect ratio images on their Y axis as it would break ratio
|
||||
@ -2094,7 +2094,7 @@ float Clay__DistributeSizeAmongChildren(bool xAxis, float sizeToDistribute, Clay
|
||||
}
|
||||
|
||||
float oldChildSize = *childSize;
|
||||
*childSize = CLAY__MAX(CLAY__MAX(CLAY__MIN(childSizing.sizeMinMax.max, *childSize + dividedSize), childSizing.sizeMinMax.min), childMinSize);
|
||||
*childSize = CLAY__MAX(CLAY__MAX(CLAY__MIN(childSizing.size.minMax.max, *childSize + dividedSize), childSizing.size.minMax.min), childMinSize);
|
||||
float diff = *childSize - oldChildSize;
|
||||
if (diff > -0.01 && diff < 0.01) {
|
||||
Clay__int32_tArray_RemoveSwapback(&remainingElements, childOffset);
|
||||
@ -2131,8 +2131,8 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||
}
|
||||
}
|
||||
|
||||
rootElement->dimensions.width = CLAY__MIN(CLAY__MAX(rootElement->dimensions.width, rootElement->layoutConfig->sizing.width.sizeMinMax.min), rootElement->layoutConfig->sizing.width.sizeMinMax.max);
|
||||
rootElement->dimensions.height = CLAY__MIN(CLAY__MAX(rootElement->dimensions.height, rootElement->layoutConfig->sizing.height.sizeMinMax.min), rootElement->layoutConfig->sizing.height.sizeMinMax.max);
|
||||
rootElement->dimensions.width = CLAY__MIN(CLAY__MAX(rootElement->dimensions.width, rootElement->layoutConfig->sizing.width.size.minMax.min), rootElement->layoutConfig->sizing.width.size.minMax.max);
|
||||
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 (int i = 0; i < bfsBuffer.length; ++i) {
|
||||
int32_t parentIndex = Clay__int32_tArray_Get(&bfsBuffer, i);
|
||||
@ -2182,7 +2182,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||
Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height;
|
||||
float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
|
||||
if (childSizing.type == CLAY__SIZING_TYPE_PERCENT) {
|
||||
*childSize = (parentSize - totalPaddingAndChildGaps) * childSizing.sizePercent;
|
||||
*childSize = (parentSize - totalPaddingAndChildGaps) * childSizing.size.percent;
|
||||
if (sizingAlongAxis) {
|
||||
innerContentSize += *childSize;
|
||||
if (childOffset > 0) {
|
||||
@ -2254,9 +2254,9 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||
}
|
||||
}
|
||||
if (childSizing.type == CLAY__SIZING_TYPE_FIT) {
|
||||
*childSize = CLAY__MAX(childSizing.sizeMinMax.min, CLAY__MIN(*childSize, maxSize));
|
||||
*childSize = CLAY__MAX(childSizing.size.minMax.min, CLAY__MIN(*childSize, maxSize));
|
||||
} else if (childSizing.type == CLAY__SIZING_TYPE_GROW) {
|
||||
*childSize = CLAY__MIN(maxSize, childSizing.sizeMinMax.max);
|
||||
*childSize = CLAY__MIN(maxSize, childSizing.size.minMax.max);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2419,7 +2419,7 @@ void Clay__CalculateFinalLayout() {
|
||||
for (int j = 0; j < currentElement->children.length; ++j) {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->children.elements[j]);
|
||||
float childHeightWithPadding = CLAY__MAX(childElement->dimensions.height + layoutConfig->padding.y * 2, currentElement->dimensions.height);
|
||||
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(childHeightWithPadding, layoutConfig->sizing.height.sizeMinMax.min), layoutConfig->sizing.height.sizeMinMax.max);
|
||||
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(childHeightWithPadding, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
|
||||
}
|
||||
} else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
|
||||
// Resizing along the layout axis
|
||||
@ -2429,7 +2429,7 @@ void Clay__CalculateFinalLayout() {
|
||||
contentHeight += childElement->dimensions.height;
|
||||
}
|
||||
contentHeight += (float)(CLAY__MAX(currentElement->children.length - 1, 0) * layoutConfig->childGap);
|
||||
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(contentHeight, layoutConfig->sizing.height.sizeMinMax.min), layoutConfig->sizing.height.sizeMinMax.max);
|
||||
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(contentHeight, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3077,16 +3077,16 @@ void Clay__RenderDebugLayoutSizing(Clay_SizingAxis sizing, Clay_TextElementConfi
|
||||
CLAY_TEXT(sizingLabel, infoTextConfig);
|
||||
if (sizing.type == CLAY__SIZING_TYPE_GROW || sizing.type == CLAY__SIZING_TYPE_FIT) {
|
||||
CLAY_TEXT(CLAY_STRING("("), infoTextConfig);
|
||||
if (sizing.sizeMinMax.min != 0) {
|
||||
if (sizing.size.minMax.min != 0) {
|
||||
CLAY_TEXT(CLAY_STRING("min: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(sizing.sizeMinMax.min), infoTextConfig);
|
||||
if (sizing.sizeMinMax.max != CLAY__MAXFLOAT) {
|
||||
CLAY_TEXT(Clay__IntToString(sizing.size.minMax.min), infoTextConfig);
|
||||
if (sizing.size.minMax.max != CLAY__MAXFLOAT) {
|
||||
CLAY_TEXT(CLAY_STRING(", "), infoTextConfig);
|
||||
}
|
||||
}
|
||||
if (sizing.sizeMinMax.max != CLAY__MAXFLOAT) {
|
||||
if (sizing.size.minMax.max != CLAY__MAXFLOAT) {
|
||||
CLAY_TEXT(CLAY_STRING("max: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(sizing.sizeMinMax.max), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(sizing.size.minMax.max), infoTextConfig);
|
||||
}
|
||||
CLAY_TEXT(CLAY_STRING(")"), infoTextConfig);
|
||||
}
|
||||
@ -3477,7 +3477,7 @@ void Clay__RenderDebugView() {
|
||||
// PUBLIC API FROM HERE ---------------------------------------
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_MinMemorySize")
|
||||
uint32_t Clay_MinMemorySize() {
|
||||
uint32_t Clay_MinMemorySize(void) {
|
||||
Clay_Arena fakeArena = CLAY__INIT(Clay_Arena) { .capacity = SIZE_MAX };
|
||||
Clay__InitializePersistentMemory(&fakeArena);
|
||||
Clay__InitializeEphemeralMemory(&fakeArena);
|
||||
@ -3705,7 +3705,7 @@ void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDe
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_BeginLayout")
|
||||
void Clay_BeginLayout() {
|
||||
void Clay_BeginLayout(void) {
|
||||
Clay__InitializeEphemeralMemory(&Clay__internalArena);
|
||||
Clay__generation++;
|
||||
Clay__dynamicElementIndex = 0;
|
||||
@ -3728,8 +3728,7 @@ void Clay_BeginLayout() {
|
||||
Clay_TextElementConfig Clay__DebugView_ErrorTextConfig = CLAY__INIT(Clay_TextElementConfig) {.textColor = {255, 0, 0, 255}, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE };
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_EndLayout")
|
||||
Clay_RenderCommandArray Clay_EndLayout()
|
||||
{
|
||||
Clay_RenderCommandArray Clay_EndLayout(void) {
|
||||
Clay__CloseElement();
|
||||
if (Clay__debugModeEnabled) {
|
||||
Clay__warningsEnabled = false;
|
||||
@ -3754,7 +3753,7 @@ Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index)
|
||||
return Clay__HashString(idString, index, 0);
|
||||
}
|
||||
|
||||
bool Clay_Hovered() {
|
||||
bool Clay_Hovered(void) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return false;
|
||||
}
|
||||
|
34
examples/introducing-clay-video-demo/CMakeLists.txt
Normal file
34
examples/introducing-clay-video-demo/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
cmake_minimum_required(VERSION 3.27)
|
||||
project(clay_examples_introducing_clay_video_demo C)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
# Adding Raylib
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) # don't build the supplied examples
|
||||
set(BUILD_GAMES OFF CACHE BOOL "" FORCE) # don't build the supplied example games
|
||||
|
||||
FetchContent_Declare(
|
||||
raylib
|
||||
GIT_REPOSITORY "https://github.com/raysan5/raylib.git"
|
||||
GIT_TAG "master"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(raylib)
|
||||
|
||||
add_executable(clay_examples_introducing_clay_video_demo main.c)
|
||||
|
||||
target_compile_options(clay_examples_introducing_clay_video_demo PUBLIC)
|
||||
target_include_directories(clay_examples_introducing_clay_video_demo PUBLIC .)
|
||||
|
||||
target_link_libraries(clay_examples_introducing_clay_video_demo PUBLIC raylib)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Werror -DCLAY_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
|
||||
add_custom_command(
|
||||
TARGET clay_examples_introducing_clay_video_demo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources
|
||||
${CMAKE_CURRENT_BINARY_DIR}/resources)
|
305
examples/introducing-clay-video-demo/main.c
Normal file
305
examples/introducing-clay-video-demo/main.c
Normal file
@ -0,0 +1,305 @@
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "../../clay.h"
|
||||
#include "../../renderers/raylib/clay_renderer_raylib.c"
|
||||
|
||||
const int FONT_ID_BODY_16 = 0;
|
||||
Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
|
||||
|
||||
void RenderHeaderButton(Clay_String text) {
|
||||
CLAY(
|
||||
CLAY_LAYOUT({ .padding = { 16, 8 }}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 140, 140, 140, 255 },
|
||||
.cornerRadius = 5
|
||||
})
|
||||
) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 16,
|
||||
.textColor = { 255, 255, 255, 255 }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDropdownMenuItem(Clay_String text) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 16, 16 }})) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 16,
|
||||
.textColor = { 255, 255, 255, 255 }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Clay_String title;
|
||||
Clay_String contents;
|
||||
} Document;
|
||||
|
||||
typedef struct {
|
||||
Document *documents;
|
||||
uint32_t length;
|
||||
} DocumentArray;
|
||||
|
||||
DocumentArray documents = {
|
||||
.documents = (Document[]) {
|
||||
{ .title = CLAY_STRING("Squirrels"), .contents = CLAY_STRING("The Secret Life of Squirrels: Nature's Clever Acrobats\n""Squirrels are often overlooked creatures, dismissed as mere park inhabitants or backyard nuisances. Yet, beneath their fluffy tails and twitching noses lies an intricate world of cunning, agility, and survival tactics that are nothing short of fascinating. As one of the most common mammals in North America, squirrels have adapted to a wide range of environments from bustling urban centers to tranquil forests and have developed a variety of unique behaviors that continue to intrigue scientists and nature enthusiasts alike.\n""\n""Master Tree Climbers\n""At the heart of a squirrel's skill set is its impressive ability to navigate trees with ease. Whether they're darting from branch to branch or leaping across wide gaps, squirrels possess an innate talent for acrobatics. Their powerful hind legs, which are longer than their front legs, give them remarkable jumping power. With a tail that acts as a counterbalance, squirrels can leap distances of up to ten times the length of their body, making them some of the best aerial acrobats in the animal kingdom.\n""But it's not just their agility that makes them exceptional climbers. Squirrels' sharp, curved claws allow them to grip tree bark with precision, while the soft pads on their feet provide traction on slippery surfaces. Their ability to run at high speeds and scale vertical trunks with ease is a testament to the evolutionary adaptations that have made them so successful in their arboreal habitats.\n""\n""Food Hoarders Extraordinaire\n""Squirrels are often seen frantically gathering nuts, seeds, and even fungi in preparation for winter. While this behavior may seem like instinctual hoarding, it is actually a survival strategy that has been honed over millions of years. Known as \"scatter hoarding,\" squirrels store their food in a variety of hidden locations, often burying it deep in the soil or stashing it in hollowed-out tree trunks.\n""Interestingly, squirrels have an incredible memory for the locations of their caches. Research has shown that they can remember thousands of hiding spots, often returning to them months later when food is scarce. However, they don't always recover every stash some forgotten caches eventually sprout into new trees, contributing to forest regeneration. This unintentional role as forest gardeners highlights the ecological importance of squirrels in their ecosystems.\n""\n""The Great Squirrel Debate: Urban vs. Wild\n""While squirrels are most commonly associated with rural or wooded areas, their adaptability has allowed them to thrive in urban environments as well. In cities, squirrels have become adept at finding food sources in places like parks, streets, and even garbage cans. However, their urban counterparts face unique challenges, including traffic, predators, and the lack of natural shelters. Despite these obstacles, squirrels in urban areas are often observed using human infrastructure such as buildings, bridges, and power lines as highways for their acrobatic escapades.\n""There is, however, a growing concern regarding the impact of urban life on squirrel populations. Pollution, deforestation, and the loss of natural habitats are making it more difficult for squirrels to find adequate food and shelter. As a result, conservationists are focusing on creating squirrel-friendly spaces within cities, with the goal of ensuring these resourceful creatures continue to thrive in both rural and urban landscapes.\n""\n""A Symbol of Resilience\n""In many cultures, squirrels are symbols of resourcefulness, adaptability, and preparation. Their ability to thrive in a variety of environments while navigating challenges with agility and grace serves as a reminder of the resilience inherent in nature. Whether you encounter them in a quiet forest, a city park, or your own backyard, squirrels are creatures that never fail to amaze with their endless energy and ingenuity.\n""In the end, squirrels may be small, but they are mighty in their ability to survive and thrive in a world that is constantly changing. So next time you spot one hopping across a branch or darting across your lawn, take a moment to appreciate the remarkable acrobat at work a true marvel of the natural world.\n") },
|
||||
{ .title = CLAY_STRING("Lorem Ipsum"), .contents = CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") },
|
||||
{ .title = CLAY_STRING("Vacuum Instructions"), .contents = CLAY_STRING("Chapter 3: Getting Started - Unpacking and Setup\n""\n""Congratulations on your new SuperClean Pro 5000 vacuum cleaner! In this section, we will guide you through the simple steps to get your vacuum up and running. Before you begin, please ensure that you have all the components listed in the \"Package Contents\" section on page 2.\n""\n""1. Unboxing Your Vacuum\n""Carefully remove the vacuum cleaner from the box. Avoid using sharp objects that could damage the product. Once removed, place the unit on a flat, stable surface to proceed with the setup. Inside the box, you should find:\n""\n"" The main vacuum unit\n"" A telescoping extension wand\n"" A set of specialized cleaning tools (crevice tool, upholstery brush, etc.)\n"" A reusable dust bag (if applicable)\n"" A power cord with a 3-prong plug\n"" A set of quick-start instructions\n""\n""2. Assembling Your Vacuum\n""Begin by attaching the extension wand to the main body of the vacuum cleaner. Line up the connectors and twist the wand into place until you hear a click. Next, select the desired cleaning tool and firmly attach it to the wand's end, ensuring it is securely locked in.\n""\n""For models that require a dust bag, slide the bag into the compartment at the back of the vacuum, making sure it is properly aligned with the internal mechanism. If your vacuum uses a bagless system, ensure the dust container is correctly seated and locked in place before use.\n""\n""3. Powering On\n""To start the vacuum, plug the power cord into a grounded electrical outlet. Once plugged in, locate the power switch, usually positioned on the side of the handle or body of the unit, depending on your model. Press the switch to the \"On\" position, and you should hear the motor begin to hum. If the vacuum does not power on, check that the power cord is securely plugged in, and ensure there are no blockages in the power switch.\n""\n""Note: Before first use, ensure that the vacuum filter (if your model has one) is properly installed. If unsure, refer to \"Section 5: Maintenance\" for filter installation instructions.") },
|
||||
{ .title = CLAY_STRING("Article 4"), .contents = CLAY_STRING("Article 4") },
|
||||
{ .title = CLAY_STRING("Article 5"), .contents = CLAY_STRING("Article 5") },
|
||||
},
|
||||
.length = 5
|
||||
};
|
||||
|
||||
uint32_t selectedDocumentIndex = 0;
|
||||
|
||||
void HandleSidebarInteraction(
|
||||
Clay_ElementId elementId,
|
||||
Clay_PointerData pointerData,
|
||||
intptr_t userData
|
||||
) {
|
||||
// If this button was clicked
|
||||
if (pointerData.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
|
||||
if (userData >= 0 && userData < documents.length) {
|
||||
// Select the corresponding document
|
||||
selectedDocumentIndex = userData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function is new since the video was published
|
||||
void HandleClayErrors(Clay_ErrorData errorData) {
|
||||
printf("%s", errorData.errorText.chars);
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
Clay_Raylib_Initialize(1024, 768, "Introducing Clay Demo", FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT); // Extra parameters to this function are new since the video was published
|
||||
|
||||
uint64_t clayRequiredMemory = Clay_MinMemorySize();
|
||||
printf("%lld", clayRequiredMemory);
|
||||
Clay_Arena clayMemory = (Clay_Arena) {
|
||||
.memory = malloc((size_t)1024 * 1024 * 1024 * 1024),
|
||||
.capacity = clayRequiredMemory
|
||||
};
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) {
|
||||
.width = GetScreenWidth(),
|
||||
.height = GetScreenHeight()
|
||||
}, (Clay_ErrorHandler) { HandleClayErrors }); // This final argument is new since the video was published
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText);
|
||||
Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) {
|
||||
.font = LoadFontEx("resources/Roboto-Regular.ttf", 48, 0, 400),
|
||||
.fontId = FONT_ID_BODY_16
|
||||
};
|
||||
SetTextureFilter(Raylib_fonts[FONT_ID_BODY_16].font.texture, TEXTURE_FILTER_BILINEAR);
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
// Run once per frame
|
||||
Clay_SetLayoutDimensions((Clay_Dimensions) {
|
||||
.width = GetScreenWidth(),
|
||||
.height = GetScreenHeight()
|
||||
});
|
||||
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
Vector2 scrollDelta = GetMouseWheelMoveV();
|
||||
Clay_SetPointerState(
|
||||
(Clay_Vector2) { mousePosition.x, mousePosition.y },
|
||||
IsMouseButtonDown(0)
|
||||
);
|
||||
Clay_UpdateScrollContainers(
|
||||
true,
|
||||
(Clay_Vector2) { scrollDelta.x, scrollDelta.y },
|
||||
GetFrameTime()
|
||||
);
|
||||
|
||||
Clay_Sizing layoutExpand = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
};
|
||||
|
||||
Clay_RectangleElementConfig contentBackgroundConfig = {
|
||||
.color = { 90, 90, 90, 255 },
|
||||
.cornerRadius = 8
|
||||
};
|
||||
|
||||
Clay_BeginLayout();
|
||||
// Build UI here
|
||||
CLAY(
|
||||
CLAY_ID("OuterContainer"),
|
||||
CLAY_RECTANGLE({ .color = { 43, 41, 51, 255 } }),
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = layoutExpand,
|
||||
.padding = { 16, 16 },
|
||||
.childGap = 16
|
||||
})
|
||||
) {
|
||||
// Child elements go inside braces
|
||||
CLAY(
|
||||
CLAY_ID("HeaderBar"),
|
||||
CLAY_RECTANGLE(contentBackgroundConfig),
|
||||
CLAY_LAYOUT({
|
||||
.sizing = {
|
||||
.height = CLAY_SIZING_FIXED(60),
|
||||
.width = CLAY_SIZING_GROW()
|
||||
},
|
||||
.padding = { 16 },
|
||||
.childGap = 16,
|
||||
.childAlignment = {
|
||||
.y = CLAY_ALIGN_Y_CENTER
|
||||
}
|
||||
})
|
||||
) {
|
||||
// Header buttons go here
|
||||
CLAY(
|
||||
CLAY_ID("FileButton"),
|
||||
CLAY_LAYOUT({ .padding = { 16, 8 }}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 140, 140, 140, 255 },
|
||||
.cornerRadius = 5
|
||||
})
|
||||
) {
|
||||
CLAY_TEXT(CLAY_STRING("File"), CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 16,
|
||||
.textColor = { 255, 255, 255, 255 }
|
||||
}));
|
||||
|
||||
bool fileMenuVisible =
|
||||
Clay_PointerOver(Clay_GetElementId(CLAY_STRING("FileButton")))
|
||||
||
|
||||
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(
|
||||
CLAY_ID("FileMenu"),
|
||||
CLAY_FLOATING({
|
||||
.attachment = {
|
||||
.parent = CLAY_ATTACH_POINT_LEFT_BOTTOM
|
||||
},
|
||||
}),
|
||||
CLAY_LAYOUT({
|
||||
.padding = {0, 8 }
|
||||
})
|
||||
) {
|
||||
CLAY(
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(200)
|
||||
},
|
||||
}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 40, 40, 40, 255 },
|
||||
.cornerRadius = 8
|
||||
})
|
||||
) {
|
||||
// Render dropdown items here
|
||||
RenderDropdownMenuItem(CLAY_STRING("New"));
|
||||
RenderDropdownMenuItem(CLAY_STRING("Open"));
|
||||
RenderDropdownMenuItem(CLAY_STRING("Close"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RenderHeaderButton(CLAY_STRING("Edit"));
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }})) {}
|
||||
RenderHeaderButton(CLAY_STRING("Upload"));
|
||||
RenderHeaderButton(CLAY_STRING("Media"));
|
||||
RenderHeaderButton(CLAY_STRING("Support"));
|
||||
}
|
||||
|
||||
CLAY(
|
||||
CLAY_ID("LowerContent"),
|
||||
CLAY_LAYOUT({ .sizing = layoutExpand, .childGap = 16 })
|
||||
) {
|
||||
CLAY(
|
||||
CLAY_ID("Sidebar"),
|
||||
CLAY_RECTANGLE(contentBackgroundConfig),
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.padding = { 16, 16 },
|
||||
.childGap = 8,
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(250),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
}
|
||||
})
|
||||
) {
|
||||
for (int i = 0; i < documents.length; i++) {
|
||||
Document document = documents.documents[i];
|
||||
Clay_LayoutConfig sidebarButtonLayout = {
|
||||
.sizing = { .width = CLAY_SIZING_GROW() },
|
||||
.padding = { 16, 16 }
|
||||
};
|
||||
|
||||
if (i == selectedDocumentIndex) {
|
||||
CLAY(
|
||||
CLAY_LAYOUT(sidebarButtonLayout),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 120, 120, 120, 255 },
|
||||
.cornerRadius = 8,
|
||||
})
|
||||
) {
|
||||
CLAY_TEXT(document.title, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 20,
|
||||
.textColor = { 255, 255, 255, 255 }
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
CLAY(
|
||||
CLAY_LAYOUT(sidebarButtonLayout),
|
||||
Clay_OnHover(HandleSidebarInteraction, i),
|
||||
Clay_Hovered()
|
||||
? CLAY_RECTANGLE({
|
||||
.color = { 120, 120, 120, 120 },
|
||||
.cornerRadius = 8
|
||||
})
|
||||
: 0
|
||||
) {
|
||||
CLAY_TEXT(document.title, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 20,
|
||||
.textColor = { 255, 255, 255, 255 }
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLAY(
|
||||
CLAY_ID("MainContent"),
|
||||
CLAY_RECTANGLE(contentBackgroundConfig),
|
||||
CLAY_SCROLL({ .vertical = true }),
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 16,
|
||||
.padding = { 16, 16 },
|
||||
.sizing = layoutExpand
|
||||
})
|
||||
) {
|
||||
Document selectedDocument = documents.documents[selectedDocumentIndex];
|
||||
CLAY_TEXT(selectedDocument.title, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 24,
|
||||
.textColor = COLOR_WHITE
|
||||
}));
|
||||
CLAY_TEXT(selectedDocument.contents, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 24,
|
||||
.textColor = COLOR_WHITE
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Clay_RenderCommandArray renderCommands = Clay_EndLayout();
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
Clay_Raylib_Render(renderCommands);
|
||||
EndDrawing();
|
||||
}
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user