[Core] Add Clay_FloatingClipToElement (#413)

This commit is contained in:
Patrick Doane 2025-05-13 18:24:42 -07:00 committed by GitHub
parent b78fd66da8
commit b656dc5253
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

89
clay.h
View file

@ -453,6 +453,14 @@ typedef CLAY_PACKED_ENUM {
CLAY_ATTACH_TO_ROOT, CLAY_ATTACH_TO_ROOT,
} Clay_FloatingAttachToElement; } Clay_FloatingAttachToElement;
// Controls whether or not a floating element is clipped to the same clipping rectangle as the element it's attached to.
typedef CLAY_PACKED_ENUM {
// (default) - The floating element does not inherit clipping.
CLAY_CLIP_TO_NONE,
// The floating element is clipped to the same clipping rectangle as the element it's attached to.
CLAY_CLIP_TO_ATTACHED_PARENT
} Clay_FloatingClipToElement;
// Controls various settings related to "floating" elements, which are elements that "float" above other elements, potentially overlapping their boundaries, // Controls various settings related to "floating" elements, which are elements that "float" above other elements, potentially overlapping their boundaries,
// and not affecting the layout of sibling or parent elements. // and not affecting the layout of sibling or parent elements.
typedef struct { typedef struct {
@ -481,6 +489,10 @@ typedef struct {
// CLAY_ATTACH_TO_ELEMENT_WITH_ID - Attaches this floating element to an element with a specific ID, specified with the .parentId field. positioned based on the .attachPoints and .offset fields. // CLAY_ATTACH_TO_ELEMENT_WITH_ID - Attaches this floating element to an element with a specific ID, specified with the .parentId field. positioned based on the .attachPoints and .offset fields.
// CLAY_ATTACH_TO_ROOT - Attaches this floating element to the root of the layout, which combined with the .offset field provides functionality similar to "absolute positioning". // CLAY_ATTACH_TO_ROOT - Attaches this floating element to the root of the layout, which combined with the .offset field provides functionality similar to "absolute positioning".
Clay_FloatingAttachToElement attachTo; Clay_FloatingAttachToElement attachTo;
// Controls whether or not a floating element is clipped to the same clipping rectangle as the element it's attached to.
// CLAY_CLIP_TO_NONE (default) - The floating element does not inherit clipping.
// CLAY_CLIP_TO_ATTACHED_PARENT - The floating element is clipped to the same clipping rectangle as the element it's attached to.
Clay_FloatingClipToElement clipTo;
} Clay_FloatingElementConfig; } Clay_FloatingElementConfig;
CLAY__WRAPPER_STRUCT(Clay_FloatingElementConfig); CLAY__WRAPPER_STRUCT(Clay_FloatingElementConfig);
@ -2066,6 +2078,9 @@ void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
if (!openLayoutElementId.id) { if (!openLayoutElementId.id) {
openLayoutElementId = Clay__HashString(CLAY_STRING("Clay__FloatingContainer"), context->layoutElementTreeRoots.length, 0); openLayoutElementId = Clay__HashString(CLAY_STRING("Clay__FloatingContainer"), context->layoutElementTreeRoots.length, 0);
} }
if (declaration->floating.clipTo == CLAY_CLIP_TO_NONE) {
clipElementId = 0;
}
int32_t currentElementIndex = Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 1); int32_t currentElementIndex = Clay__int32_tArray_GetValue(&context->openLayoutElementStack, context->openLayoutElementStack.length - 1);
Clay__int32_tArray_Set(&context->layoutElementClipElementIds, currentElementIndex, clipElementId); Clay__int32_tArray_Set(&context->layoutElementClipElementIds, currentElementIndex, clipElementId);
Clay__int32_tArray_Add(&context->openClipElementStack, clipElementId); Clay__int32_tArray_Add(&context->openClipElementStack, clipElementId);
@ -3379,7 +3394,7 @@ void Clay__RenderDebugView(void) {
Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT; Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT;
CLAY({ .id = CLAY_ID("Clay__DebugView"), CLAY({ .id = CLAY_ID("Clay__DebugView"),
.layout = { .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }, .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 }, .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 } } .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({ .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 }) {
@ -3401,7 +3416,7 @@ void Clay__RenderDebugView(void) {
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({ .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_ElementId panelContentsId = Clay__HashString(CLAY_STRING("Clay__DebugViewPaneOuter"), 0, 0);
// Element list // 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 } }) { 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({ .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); layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow);
} }
@ -3624,6 +3639,76 @@ void Clay__RenderDebugView(void) {
CLAY_TEXT(CLAY_STRING("Parent"), infoTitleConfig); CLAY_TEXT(CLAY_STRING("Parent"), infoTitleConfig);
Clay_LayoutElementHashMapItem *hashItem = Clay__GetHashMapItem(floatingConfig->parentId); Clay_LayoutElementHashMapItem *hashItem = Clay__GetHashMapItem(floatingConfig->parentId);
CLAY_TEXT(hashItem->elementId.stringId, infoTextConfig); CLAY_TEXT(hashItem->elementId.stringId, infoTextConfig);
// .attachPoints
CLAY_TEXT(CLAY_STRING("Attach Points"), infoTitleConfig);
CLAY({ .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) {
attachPointElement = CLAY_STRING("LEFT_CENTER");
} else if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_LEFT_BOTTOM) {
attachPointElement = CLAY_STRING("LEFT_BOTTOM");
} else if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_CENTER_TOP) {
attachPointElement = CLAY_STRING("CENTER_TOP");
} else if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_CENTER_CENTER) {
attachPointElement = CLAY_STRING("CENTER_CENTER");
} else if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_CENTER_BOTTOM) {
attachPointElement = CLAY_STRING("CENTER_BOTTOM");
} else if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_RIGHT_TOP) {
attachPointElement = CLAY_STRING("RIGHT_TOP");
} else if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_RIGHT_CENTER) {
attachPointElement = CLAY_STRING("RIGHT_CENTER");
} else if (floatingConfig->attachPoints.element == CLAY_ATTACH_POINT_RIGHT_BOTTOM) {
attachPointElement = CLAY_STRING("RIGHT_BOTTOM");
}
CLAY_TEXT(attachPointElement, infoTextConfig);
Clay_String attachPointParent = CLAY_STRING("LEFT_TOP");
if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_LEFT_CENTER) {
attachPointParent = CLAY_STRING("LEFT_CENTER");
} else if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_LEFT_BOTTOM) {
attachPointParent = CLAY_STRING("LEFT_BOTTOM");
} else if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_CENTER_TOP) {
attachPointParent = CLAY_STRING("CENTER_TOP");
} else if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_CENTER_CENTER) {
attachPointParent = CLAY_STRING("CENTER_CENTER");
} else if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_CENTER_BOTTOM) {
attachPointParent = CLAY_STRING("CENTER_BOTTOM");
} else if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_RIGHT_TOP) {
attachPointParent = CLAY_STRING("RIGHT_TOP");
} else if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_RIGHT_CENTER) {
attachPointParent = CLAY_STRING("RIGHT_CENTER");
} else if (floatingConfig->attachPoints.parent == CLAY_ATTACH_POINT_RIGHT_BOTTOM) {
attachPointParent = CLAY_STRING("RIGHT_BOTTOM");
}
CLAY_TEXT(CLAY_STRING(", parent: "), infoTextConfig);
CLAY_TEXT(attachPointParent, infoTextConfig);
CLAY_TEXT(CLAY_STRING(" }"), infoTextConfig);
}
// .pointerCaptureMode
CLAY_TEXT(CLAY_STRING("Pointer Capture Mode"), infoTitleConfig);
Clay_String pointerCaptureMode = CLAY_STRING("NONE");
if (floatingConfig->pointerCaptureMode == CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH) {
pointerCaptureMode = CLAY_STRING("PASSTHROUGH");
}
CLAY_TEXT(pointerCaptureMode, infoTextConfig);
// .attachTo
CLAY_TEXT(CLAY_STRING("Attach To"), infoTitleConfig);
Clay_String attachTo = CLAY_STRING("NONE");
if (floatingConfig->attachTo == CLAY_ATTACH_TO_PARENT) {
attachTo = CLAY_STRING("PARENT");
} else if (floatingConfig->attachTo == CLAY_ATTACH_TO_ELEMENT_WITH_ID) {
attachTo = CLAY_STRING("ELEMENT_WITH_ID");
} else if (floatingConfig->attachTo == CLAY_ATTACH_TO_ROOT) {
attachTo = CLAY_STRING("ROOT");
}
CLAY_TEXT(attachTo, infoTextConfig);
// .clipTo
CLAY_TEXT(CLAY_STRING("Clip To"), infoTitleConfig);
Clay_String clipTo = CLAY_STRING("ATTACHED_PARENT");
if (floatingConfig->clipTo == CLAY_CLIP_TO_NONE) {
clipTo = CLAY_STRING("NONE");
}
CLAY_TEXT(clipTo, infoTextConfig);
} }
break; break;
} }