mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-19 20:58:03 +00:00
Improve size distribution when shrinking
This commit is contained in:
parent
fd45553aff
commit
ffc3b13d23
95
clay.h
95
clay.h
@ -2103,65 +2103,50 @@ CLAY__TYPEDEF(Clay__SizeDistributionType, enum {
|
|||||||
CLAY__SIZE_DISTRIBUTION_TYPE_GROW_CONTAINER,
|
CLAY__SIZE_DISTRIBUTION_TYPE_GROW_CONTAINER,
|
||||||
});
|
});
|
||||||
|
|
||||||
float Clay__DistributeSizeAmongChildren(bool xAxis, float sizeToDistribute, Clay__int32_tArray resizableContainerBuffer, Clay__SizeDistributionType distributionType) {
|
float Clay__DistributeSizeAmongChildren(bool xAxis, float totalSizeToDistribute, Clay__int32_tArray resizableContainerBuffer, Clay__SizeDistributionType distributionType) {
|
||||||
Clay__int32_tArray remainingElements = Clay__openClipElementStack;
|
Clay__int32_tArray largestContainers = Clay__openClipElementStack;
|
||||||
remainingElements.length = 0;
|
largestContainers.length = 0;
|
||||||
|
|
||||||
for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) {
|
while (totalSizeToDistribute > 0) {
|
||||||
Clay__int32_tArray_Add(&remainingElements, Clay__int32_tArray_Get(&resizableContainerBuffer, i));
|
float largestSize = 0;
|
||||||
}
|
float targetSize = 0;
|
||||||
|
for (uint32_t i = 0; i < resizableContainerBuffer.length; ++i) {
|
||||||
|
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__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) {
|
||||||
|
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) {
|
targetSize = CLAY__MAX(targetSize, (largestSize * largestContainers.length) - totalSizeToDistribute) / largestContainers.length;
|
||||||
float dividedSize = sizeToDistribute / (float)remainingElements.length;
|
|
||||||
for (int32_t childOffset = 0; childOffset < remainingElements.length; childOffset++) {
|
for (uint32_t childOffset = 0; childOffset < largestContainers.length; childOffset++) {
|
||||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&remainingElements, childOffset));
|
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements,
|
||||||
Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height;
|
Clay__int32_tArray_Get(&largestContainers,
|
||||||
|
childOffset));
|
||||||
float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
|
float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
|
||||||
float childMinSize = xAxis ? childElement->minDimensions.width : childElement->minDimensions.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;
|
float oldChildSize = *childSize;
|
||||||
*childSize = CLAY__MAX(CLAY__MAX(CLAY__MIN(childSizing.size.minMax.max, *childSize + dividedSize), childSizing.size.minMax.min), childMinSize);
|
*childSize = CLAY__MAX(childMinSize, targetSize);
|
||||||
float diff = *childSize - oldChildSize;
|
totalSizeToDistribute -= (oldChildSize - *childSize);
|
||||||
if (diff > -0.01 && diff < 0.01) {
|
if (*childSize == childMinSize) {
|
||||||
Clay__int32_tArray_RemoveSwapback(&remainingElements, childOffset);
|
Clay__int32_tArray_RemoveSwapback(&largestContainers, childOffset);
|
||||||
childOffset--;
|
childOffset--;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
sizeToDistribute -= diff;
|
}
|
||||||
|
|
||||||
|
if (largestContainers.length == 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (sizeToDistribute > -0.01 && sizeToDistribute < 0.01) ? 0 : sizeToDistribute;
|
return (totalSizeToDistribute > -0.01 && totalSizeToDistribute < 0.01) ? 0 : totalSizeToDistribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clay__SizeContainersAlongAxis(bool xAxis) {
|
void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||||
@ -2264,12 +2249,12 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Scrolling containers preferentially compress before others
|
// Scrolling containers preferentially compress before others
|
||||||
sizeToDistribute = Clay__DistributeSizeAmongChildren(xAxis, sizeToDistribute, resizableContainerBuffer, CLAY__SIZE_DISTRIBUTION_TYPE_SCROLL_CONTAINER);
|
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 there is still height to make up, remove it from all containers that haven't hit their minimum size
|
||||||
if (sizeToDistribute < 0) {
|
// if (sizeToDistribute < 0) {
|
||||||
Clay__DistributeSizeAmongChildren(xAxis, sizeToDistribute, resizableContainerBuffer, CLAY__SIZE_DISTRIBUTION_TYPE_RESIZEABLE_CONTAINER);
|
// Clay__DistributeSizeAmongChildren(xAxis, sizeToDistribute, resizableContainerBuffer, CLAY__SIZE_DISTRIBUTION_TYPE_RESIZEABLE_CONTAINER);
|
||||||
}
|
// }
|
||||||
// The content is too small, allow SIZING_GROW containers to expand
|
// The content is too small, allow SIZING_GROW containers to expand
|
||||||
} else if (sizeToDistribute > 0 && growContainerCount > 0) {
|
} else if (sizeToDistribute > 0 && growContainerCount > 0) {
|
||||||
float targetSize = (sizeToDistribute + growContainerContentSize) / (float)growContainerCount;
|
float targetSize = (sizeToDistribute + growContainerContentSize) / (float)growContainerCount;
|
||||||
|
Loading…
Reference in New Issue
Block a user