diff --git a/CMakeLists.txt b/CMakeLists.txt index cd272e7..3d9f50d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ add_subdirectory("examples/cpp-project-example") # Don't try to compile C99 projects using MSVC if(NOT MSVC) add_subdirectory("examples/raylib-sidebar-scrolling-container") - add_subdirectory("examples/cairo-pdf-rendering") +# add_subdirectory("examples/cairo-pdf-rendering") Some issue with github actions populating cairo, disable for now add_subdirectory("examples/clay-official-website") add_subdirectory("examples/introducing-clay-video-demo") add_subdirectory("examples/SDL2-video-demo") diff --git a/README.md b/README.md index 2d19696..6663a79 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ Clay_RenderCommandArray CreateLayout() { CLAY_RECTANGLE({ .color = COLOR_LIGHT }) ) { CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW() }, .padding = {16, 16}, .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER }), CLAY_RECTANGLE({ .color = COLOR_RED })) { - CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .height = 60, .width = 60 })) {} + CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {} CLAY_TEXT(CLAY_STRING("Clay - UI Library"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255, 255, 255, 255} })); } @@ -1059,11 +1059,11 @@ CLAY(CLAY_IMAGE({ .image = { .format = IMAGE_FORMAT_RGBA, .internalData = &image // Load an image somewhere in your code Image profilePicture = LoadImage("profilePicture.png"); // Declare a reusable image config -Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &profilePicture, .height = 60, .width = 60 }; +Clay_ImageElementConfig imageConfig = (Clay_ImageElementConfig) { .imageData = &profilePicture, .sourceDimensions = {60, 60} }; // Declare an image element using a reusable config CLAY(CLAY_IMAGE(imageConfig)) {} // Declare an image element using an inline config -CLAY(CLAY_IMAGE({ .imageData = &profilePicture, .height = 60, .width = 60 })) {} +CLAY(CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {} // Rendering example Image *imageToRender = renderCommand->elementConfig.imageElementConfig->imageData; ``` diff --git a/bindings/odin/clay-odin/linux/clay.a b/bindings/odin/clay-odin/linux/clay.a index 6dfd1c8..1c5d31b 100644 Binary files a/bindings/odin/clay-odin/linux/clay.a and b/bindings/odin/clay-odin/linux/clay.a differ diff --git a/bindings/odin/clay-odin/macos-arm64/clay.a b/bindings/odin/clay-odin/macos-arm64/clay.a index e7a1779..dc56842 100644 Binary files a/bindings/odin/clay-odin/macos-arm64/clay.a and b/bindings/odin/clay-odin/macos-arm64/clay.a differ diff --git a/bindings/odin/clay-odin/macos/clay.a b/bindings/odin/clay-odin/macos/clay.a index 2642a7d..306731e 100644 Binary files a/bindings/odin/clay-odin/macos/clay.a and b/bindings/odin/clay-odin/macos/clay.a differ diff --git a/bindings/odin/clay-odin/wasm/clay.o b/bindings/odin/clay-odin/wasm/clay.o index 6b65e1a..0dce7de 100644 Binary files a/bindings/odin/clay-odin/wasm/clay.o and b/bindings/odin/clay-odin/wasm/clay.o differ diff --git a/bindings/odin/clay-odin/windows/clay.lib b/bindings/odin/clay-odin/windows/clay.lib index 072a1dc..6a3c8fc 100644 Binary files a/bindings/odin/clay-odin/windows/clay.lib and b/bindings/odin/clay-odin/windows/clay.lib differ diff --git a/clay.h b/clay.h index ec9f5e5..3668650 100644 --- a/clay.h +++ b/clay.h @@ -21,6 +21,14 @@ #ifndef CLAY_HEADER #define CLAY_HEADER +#if !( \ + (defined(__cplusplus) && __cplusplus >= 202002L) || \ + (defined(__STDC__) && __STDC__ == 1 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + defined(_MSC_VER) \ +) +#error "Clay requires C99, C++20, or MSVC" +#endif + #ifdef CLAY_WASM #define CLAY_WASM_EXPORT(name) __attribute__((export_name(name))) #else @@ -2071,72 +2079,48 @@ void Clay__InitializePersistentMemory(Clay_Context* context) { } -CLAY__TYPEDEF(Clay__SizeDistributionType, enum { - CLAY__SIZE_DISTRIBUTION_TYPE_SCROLL_CONTAINER, - CLAY__SIZE_DISTRIBUTION_TYPE_RESIZEABLE_CONTAINER, - CLAY__SIZE_DISTRIBUTION_TYPE_GROW_CONTAINER, -}); - -float Clay__DistributeSizeAmongChildren(bool xAxis, float sizeToDistribute, Clay__int32_tArray resizableContainerBuffer, Clay__SizeDistributionType distributionType) { +void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Clay__int32_tArray resizableContainerBuffer) { Clay_Context* context = Clay_GetCurrentContext(); - Clay__int32_tArray remainingElements = context->openClipElementStack; - remainingElements.length = 0; + Clay__int32_tArray largestContainers = context->openClipElementStack; + largestContainers.length = 0; - for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) { - Clay__int32_tArray_Add(&remainingElements, Clay__int32_tArray_Get(&resizableContainerBuffer, i)); - } + while (totalSizeToDistribute > 0) { + float largestSize = 0; + float targetSize = 0; + for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) { + Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, i)); + float childSize = xAxis ? childElement->dimensions.width : childElement->dimensions.height; + if (childSize == largestSize) { + Clay__int32_tArray_Add(&largestContainers, Clay__int32_tArray_Get(&resizableContainerBuffer, i)); + } else if (childSize > largestSize) { + targetSize = largestSize; + largestSize = childSize; + largestContainers.length = 0; + Clay__int32_tArray_Add(&largestContainers, Clay__int32_tArray_Get(&resizableContainerBuffer, i)); + } + else if (childSize > targetSize) { + targetSize = childSize; + } + } - while (sizeToDistribute != 0 && remainingElements.length > 0) { - float dividedSize = sizeToDistribute / (float)remainingElements.length; - for (int32_t childOffset = 0; childOffset < remainingElements.length; childOffset++) { - Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&remainingElements, childOffset)); - Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height; + targetSize = CLAY__MAX(targetSize, (largestSize * largestContainers.length) - totalSizeToDistribute) / largestContainers.length; + for (int32_t childOffset = 0; childOffset < largestContainers.length; childOffset++) { + Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&largestContainers, childOffset)); float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height; float childMinSize = xAxis ? childElement->minDimensions.width : childElement->minDimensions.height; - bool canDistribute = true; - - 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 - else if (!xAxis && Clay__ElementHasConfig(childElement, CLAY__ELEMENT_CONFIG_TYPE_IMAGE)) { - canDistribute = false; - } - else { - switch (distributionType) { - case CLAY__SIZE_DISTRIBUTION_TYPE_RESIZEABLE_CONTAINER: break; - case CLAY__SIZE_DISTRIBUTION_TYPE_GROW_CONTAINER: if (childSizing.type != CLAY__SIZING_TYPE_GROW) canDistribute = false; break; - case CLAY__SIZE_DISTRIBUTION_TYPE_SCROLL_CONTAINER: { - if (Clay__ElementHasConfig(childElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER)) { - Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(childElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig; - if ((xAxis && !scrollConfig->horizontal) || (!xAxis && !scrollConfig->vertical)) { - Clay__int32_tArray_RemoveSwapback(&remainingElements, childOffset); - childOffset--; - continue; - } - } - } - } - } - - if (!canDistribute) { - Clay__int32_tArray_RemoveSwapback(&remainingElements, childOffset); - childOffset--; - continue; - } - float oldChildSize = *childSize; - *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); + *childSize = CLAY__MAX(childMinSize, targetSize); + totalSizeToDistribute -= (oldChildSize - *childSize); + if (*childSize == childMinSize) { + Clay__int32_tArray_RemoveSwapback(&largestContainers, childOffset); childOffset--; - continue; } - sizeToDistribute -= diff; + } + + if (largestContainers.length == 0) { + break; } } - return (sizeToDistribute > -0.01 && sizeToDistribute < 0.01) ? 0 : sizeToDistribute; } void Clay__SizeContainersAlongAxis(bool xAxis) { @@ -2230,7 +2214,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) { if (sizingAlongAxis) { float sizeToDistribute = parentSize - parentPadding * 2 - innerContentSize; - // If the content is too large, compress the children as much as possible + // The content is too large, compress the children as much as possible if (sizeToDistribute < 0) { // If the parent can scroll in the axis direction in this direction, don't compress children, just leave them alone if (Clay__ElementHasConfig(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER)) { @@ -2240,12 +2224,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) { } } // Scrolling containers preferentially compress before others - sizeToDistribute = Clay__DistributeSizeAmongChildren(xAxis, sizeToDistribute, resizableContainerBuffer, CLAY__SIZE_DISTRIBUTION_TYPE_SCROLL_CONTAINER); - - // If there is still height to make up, remove it from all containers that haven't hit their minimum size - if (sizeToDistribute < 0) { - Clay__DistributeSizeAmongChildren(xAxis, sizeToDistribute, resizableContainerBuffer, CLAY__SIZE_DISTRIBUTION_TYPE_RESIZEABLE_CONTAINER); - } + Clay__CompressChildrenAlongAxis(xAxis, -sizeToDistribute, resizableContainerBuffer); // The content is too small, allow SIZING_GROW containers to expand } else if (sizeToDistribute > 0 && growContainerCount > 0) { float targetSize = (sizeToDistribute + growContainerContentSize) / (float)growContainerCount; diff --git a/examples/clay-official-website/build/clay/index.wasm b/examples/clay-official-website/build/clay/index.wasm index b22f64d..13b03ce 100755 Binary files a/examples/clay-official-website/build/clay/index.wasm and b/examples/clay-official-website/build/clay/index.wasm differ