mirror of
				https://github.com/nicbarker/clay.git
				synced 2025-11-04 00:26:17 +00:00 
			
		
		
		
	Add callback to inspect elements through pipeline
Also moved ID to Clay__OpenElement, and added the clipped bounding box to ElementData.
This commit is contained in:
		
							parent
							
								
									5bdf287167
								
							
						
					
					
						commit
						14603bf360
					
				
							
								
								
									
										268
									
								
								clay.h
									
									
									
									
									
								
							
							
						
						
									
										268
									
								
								clay.h
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -85,7 +85,7 @@
 | 
			
		|||
// 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_SID_LOCAL(CLAY_STRING(label))
 | 
			
		||||
 | 
			
		||||
#define CLAY_SID_LOCAL(label, index) Clay__HashString(label, Clay__GetParentElementId())
 | 
			
		||||
#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)
 | 
			
		||||
| 
						 | 
				
			
			@ -133,13 +133,19 @@ static inline void Clay__SuppressUnusedLatchDefinitionVariableWarning(void) { (v
 | 
			
		|||
  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_NAMED(ID, ...)                                                                                                                                           \
 | 
			
		||||
    for (                                                                                                                                                   \
 | 
			
		||||
        CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElement(), Clay__ConfigureOpenElement(CLAY__CONFIG_WRAPPER(Clay_ElementDeclaration, __VA_ARGS__)), 0);  \
 | 
			
		||||
        CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElement(ID), Clay__ConfigureOpenElement(CLAY__CONFIG_WRAPPER(Clay_ElementDeclaration, __VA_ARGS__)), 0);  \
 | 
			
		||||
        CLAY__ELEMENT_DEFINITION_LATCH < 1;                                                                                                                 \
 | 
			
		||||
        CLAY__ELEMENT_DEFINITION_LATCH=1, Clay__CloseElement()                                                                                              \
 | 
			
		||||
    )
 | 
			
		||||
    )                                                                                                                                           \
 | 
			
		||||
 | 
			
		||||
#define CLAY(...)                                                                                                                                           \
 | 
			
		||||
    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()                                                                                              \
 | 
			
		||||
    )   
 | 
			
		||||
// 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
 | 
			
		||||
| 
						 | 
				
			
			@ -657,6 +663,8 @@ typedef struct Clay_ScrollContainerData {
 | 
			
		|||
typedef struct Clay_ElementData {
 | 
			
		||||
    // The rectangle that encloses this UI element, with the position relative to the root of the layout.
 | 
			
		||||
    Clay_BoundingBox boundingBox;
 | 
			
		||||
    // Same as boundingBox but clipped by the parent/s if they clip.
 | 
			
		||||
    Clay_BoundingBox visibleBoundingBox;
 | 
			
		||||
    // Indicates whether an actual Element matched the provided ID or if the default struct was returned.
 | 
			
		||||
    bool found;
 | 
			
		||||
} Clay_ElementData;
 | 
			
		||||
| 
						 | 
				
			
			@ -740,9 +748,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.
 | 
			
		||||
| 
						 | 
				
			
			@ -817,6 +822,28 @@ typedef struct {
 | 
			
		|||
    void *userData;
 | 
			
		||||
} Clay_ErrorHandler;
 | 
			
		||||
 | 
			
		||||
typedef CLAY_PACKED_ENUM {
 | 
			
		||||
    // The element has been open
 | 
			
		||||
    CLAY_ELEMENT_STATE_OPEN,
 | 
			
		||||
    // The element has been closed
 | 
			
		||||
    CLAY_ELEMENT_STATE_CLOSED,
 | 
			
		||||
    // The layout configuration for the element has been specified
 | 
			
		||||
    CLAY_ELEMENT_STATE_CONFIGURED,
 | 
			
		||||
    // The element is in its final location and will start finalizing its children
 | 
			
		||||
    CLAY_ELEMENT_STATE_BEGIN_FINALIZE,
 | 
			
		||||
    // The element has finalized all its children
 | 
			
		||||
    CLAY_ELEMENT_STATE_END_FINALIZE
 | 
			
		||||
} Clay_ElementState;
 | 
			
		||||
 | 
			
		||||
typedef void(*Clay_OnElementStateChangeFunction)(void* userData, uint32_t id, Clay_ElementData data, Clay_LayoutConfig* layout, Clay_ElementState state);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    // A user provided function to call when Clay changes the state of an element.
 | 
			
		||||
    Clay_OnElementStateChangeFunction function;
 | 
			
		||||
    // A pointer that will be transparently passed through to the error handler when it is called.
 | 
			
		||||
    void* userData;
 | 
			
		||||
} Clay_OnElementStateChangeHandler;
 | 
			
		||||
 | 
			
		||||
// Function Forward Declarations ---------------------------------
 | 
			
		||||
 | 
			
		||||
// Public API functions ------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -867,6 +894,8 @@ CLAY_DLL_EXPORT Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString,
 | 
			
		|||
// The returned Clay_ElementData contains a `found` bool that will be true if an element with the provided ID was found.
 | 
			
		||||
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
 | 
			
		||||
CLAY_DLL_EXPORT Clay_ElementData Clay_GetElementData(Clay_ElementId id);
 | 
			
		||||
// Returns the id of the current open element
 | 
			
		||||
CLAY_DLL_EXPORT uint32_t Clay_GetCurrentElementID(void);
 | 
			
		||||
// Returns true if the pointer position provided by Clay_SetPointerState is within the current element's bounding box.
 | 
			
		||||
// Works during element declaration, e.g. CLAY({ .backgroundColor = Clay_Hovered() ? BLUE : RED });
 | 
			
		||||
CLAY_DLL_EXPORT bool Clay_Hovered(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -912,10 +941,14 @@ CLAY_DLL_EXPORT int32_t Clay_GetMaxMeasureTextCacheWordCount(void);
 | 
			
		|||
CLAY_DLL_EXPORT void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount);
 | 
			
		||||
// Resets Clay's internal text measurement cache. Useful if font mappings have changed or fonts have been reloaded.
 | 
			
		||||
CLAY_DLL_EXPORT void Clay_ResetMeasureTextCache(void);
 | 
			
		||||
// Set the callback that will be used to notify the user of elements that have changed state. E.g. CLAY_ELEMENT_STATE_OPEN -> CLAY_ELEMENT_STATE_CLOSED
 | 
			
		||||
CLAY_DLL_EXPORT void Clay_SetOnElementStateChanged(Clay_OnElementStateChangeFunction onElementStateChanged, void* userData);
 | 
			
		||||
// Computes the intersection between the two bounding boxes, if one is CLAY_INFINITE_BOUNDING_BOX the result will be the other.
 | 
			
		||||
// CLAY_DLL_EXPORT Clay_BoundingBox Clay_IntersectBoundingBoxes(Clay_BoundingBox a, Clay_BoundingBox b);
 | 
			
		||||
 | 
			
		||||
// Internal API functions required by macros ----------------------
 | 
			
		||||
 | 
			
		||||
CLAY_DLL_EXPORT void Clay__OpenElement(void);
 | 
			
		||||
CLAY_DLL_EXPORT void Clay__OpenElement(Clay_ElementId id);
 | 
			
		||||
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);
 | 
			
		||||
| 
						 | 
				
			
			@ -1169,13 +1202,13 @@ CLAY__ARRAY_DEFINE(Clay__DebugElementData, Clay__DebugElementDataArray)
 | 
			
		|||
 | 
			
		||||
typedef struct { // todo get this struct into a single cache line
 | 
			
		||||
    Clay_BoundingBox boundingBox;
 | 
			
		||||
    Clay_BoundingBox visibleBoundingBox;
 | 
			
		||||
    Clay_ElementId elementId;
 | 
			
		||||
    Clay_LayoutElement* layoutElement;
 | 
			
		||||
    void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData);
 | 
			
		||||
    intptr_t hoverFunctionUserData;
 | 
			
		||||
    int32_t nextIndex;
 | 
			
		||||
    uint32_t generation;
 | 
			
		||||
    uint32_t idAlias;
 | 
			
		||||
    Clay__DebugElementData *debugData;
 | 
			
		||||
} Clay_LayoutElementHashMapItem;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1233,6 +1266,9 @@ struct Clay_Context {
 | 
			
		|||
    int32_t maxMeasureTextCacheWordCount;
 | 
			
		||||
    bool warningsEnabled;
 | 
			
		||||
    Clay_ErrorHandler errorHandler;
 | 
			
		||||
 | 
			
		||||
    Clay_OnElementStateChangeHandler elementStateChangeHandler;
 | 
			
		||||
 | 
			
		||||
    Clay_BooleanWarnings booleanWarnings;
 | 
			
		||||
    Clay__WarningArray warnings;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1667,7 +1703,7 @@ 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_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);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1717,12 +1753,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 = CLAY__INIT(Clay_LayoutElementHashMapItem) { .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];
 | 
			
		||||
| 
						 | 
				
			
			@ -1732,7 +1768,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -1741,7 +1776,7 @@ Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Cl
 | 
			
		|||
            } else { // Multiple collisions this frame - two elements have the same ID
 | 
			
		||||
                context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
 | 
			
		||||
                    .errorType = CLAY_ERROR_TYPE_DUPLICATE_ID,
 | 
			
		||||
                    .errorText = CLAY_STRING("An element with this ID was already previously declared during this layout."),
 | 
			
		||||
                    .errorText = CLAY_STRING("An element with this ID was already previously declared during this layout.\n"),
 | 
			
		||||
                    .userData = context->errorHandler.userData });
 | 
			
		||||
                if (context->debugModeEnabled) {
 | 
			
		||||
                    hashItem->debugData->collision = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -1781,7 +1816,7 @@ Clay_ElementId Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayou
 | 
			
		|||
    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);
 | 
			
		||||
    openLayoutElement->id = elementId.id;
 | 
			
		||||
    Clay__AddHashMapItem(elementId, openLayoutElement, 0);
 | 
			
		||||
    Clay__AddHashMapItem(elementId, openLayoutElement);
 | 
			
		||||
    Clay__StringArray_Add(&context->layoutElementIdStrings, elementId.stringId);
 | 
			
		||||
    return elementId;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1914,6 +1949,12 @@ void Clay__CloseElement(void) {
 | 
			
		|||
 | 
			
		||||
    bool elementIsFloating = Clay__ElementHasConfig(openLayoutElement, CLAY__ELEMENT_CONFIG_TYPE_FLOATING);
 | 
			
		||||
 | 
			
		||||
    if (context->elementStateChangeHandler.function) {
 | 
			
		||||
        Clay_ElementData data = Clay_GetElementData({ openLayoutElement->id });
 | 
			
		||||
 | 
			
		||||
        context->elementStateChangeHandler.function(context->elementStateChangeHandler.userData, openLayoutElement->id, data, openLayoutElement->layoutConfig, CLAY_ELEMENT_STATE_CLOSED);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Close the currently open element
 | 
			
		||||
    int32_t closingElementIndex = Clay__int32_tArray_RemoveSwapback(&context->openLayoutElementStack, (int)context->openLayoutElementStack.length - 1);
 | 
			
		||||
    openLayoutElement = Clay__GetOpenLayoutElement();
 | 
			
		||||
| 
						 | 
				
			
			@ -1989,20 +2030,48 @@ bool Clay__MemCmp(const char *s1, const char *s2, int32_t length);
 | 
			
		|||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void Clay__OpenElement(void) {
 | 
			
		||||
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();
 | 
			
		||||
    openLayoutElement->id = elementId.id;
 | 
			
		||||
    Clay__AddHashMapItem(elementId, openLayoutElement);
 | 
			
		||||
    Clay__StringArray_Set(&context->layoutElementIdStrings, context->layoutElements.length - 1, elementId.stringId);
 | 
			
		||||
    return elementId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
 | 
			
		||||
void Clay__OpenElement(Clay_ElementId id) {
 | 
			
		||||
    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;
 | 
			
		||||
    Clay_LayoutElementArray_Add(&context->layoutElements, layoutElement);
 | 
			
		||||
    Clay_LayoutElement* openLayoutElement = Clay_LayoutElementArray_Add(&context->layoutElements, CLAY__DEFAULT_STRUCT);
 | 
			
		||||
    Clay__int32_tArray_Add(&context->openLayoutElementStack, context->layoutElements.length - 1);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (id.id != 0) {
 | 
			
		||||
        Clay__AttachId(id);
 | 
			
		||||
    } else {
 | 
			
		||||
        Clay__GenerateIdForAnonymousElement(openLayoutElement);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (context->elementStateChangeHandler.function) {
 | 
			
		||||
        Clay_ElementData data = Clay_GetElementData({ openLayoutElement->id });
 | 
			
		||||
 | 
			
		||||
        context->elementStateChangeHandler.function(context->elementStateChangeHandler.userData, openLayoutElement->id, data, openLayoutElement->layoutConfig, CLAY_ELEMENT_STATE_OPEN);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2025,7 +2094,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -2039,19 +2108,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();
 | 
			
		||||
| 
						 | 
				
			
			@ -2063,8 +2119,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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2119,9 +2173,6 @@ void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
 | 
			
		|||
            } else if (declaration->floating.attachTo == CLAY_ATTACH_TO_ROOT) {
 | 
			
		||||
                floatingConfig.parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0).id;
 | 
			
		||||
            }
 | 
			
		||||
            if (!openLayoutElementId.id) {
 | 
			
		||||
                openLayoutElementId = Clay__HashStringWithOffset(CLAY_STRING("Clay__FloatingContainer"), context->layoutElementTreeRoots.length, 0);
 | 
			
		||||
            }
 | 
			
		||||
            if (declaration->floating.clipTo == CLAY_CLIP_TO_NONE) {
 | 
			
		||||
                clipElementId = 0;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -2141,13 +2192,7 @@ 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) {
 | 
			
		||||
    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);
 | 
			
		||||
        // Retrieve or create cached data to track scroll position across frames
 | 
			
		||||
| 
						 | 
				
			
			@ -2170,6 +2215,12 @@ void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
 | 
			
		|||
    if (!Clay__MemCmp((char *)(&declaration->border.width), (char *)(&Clay__BorderWidth_DEFAULT), sizeof(Clay_BorderWidth))) {
 | 
			
		||||
        Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .borderElementConfig = Clay__StoreBorderElementConfig(declaration->border) }, CLAY__ELEMENT_CONFIG_TYPE_BORDER);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (context->elementStateChangeHandler.function) {
 | 
			
		||||
        Clay_ElementData data = Clay_GetElementData({ openLayoutElement->id });
 | 
			
		||||
 | 
			
		||||
        context->elementStateChangeHandler.function(context->elementStateChangeHandler.userData, openLayoutElement->id, data, openLayoutElement->layoutConfig, CLAY_ELEMENT_STATE_CONFIGURED);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clay__ConfigureOpenElement(const Clay_ElementDeclaration declaration) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2221,7 +2272,7 @@ void Clay__InitializePersistentMemory(Clay_Context* context) {
 | 
			
		|||
    int32_t maxMeasureTextCacheWordCount = context->maxMeasureTextCacheWordCount;
 | 
			
		||||
    Clay_Arena *arena = &context->internalArena;
 | 
			
		||||
 | 
			
		||||
    context->scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(100, arena);
 | 
			
		||||
    context->scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(10, 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);
 | 
			
		||||
| 
						 | 
				
			
			@ -2817,11 +2868,16 @@ 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;
 | 
			
		||||
                        }
 | 
			
		||||
                    hashMapItem->visibleBoundingBox = currentElementBoundingBox;
 | 
			
		||||
 | 
			
		||||
                    if (context->scissorDataStack.length > 0) {
 | 
			
		||||
                        hashMapItem->visibleBoundingBox = Clay__ClipBoundingBox(
 | 
			
		||||
                            Clay__ScissorDataArray_GetValue(
 | 
			
		||||
                                &context->scissorDataStack,
 | 
			
		||||
                                context->scissorDataStack.length - 1
 | 
			
		||||
                            ).boundingBox,
 | 
			
		||||
                            currentElementBoundingBox
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2844,6 +2900,11 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
                    sortMax--;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (context->elementStateChangeHandler.function) {
 | 
			
		||||
                    Clay_ElementData data = Clay_GetElementData({ currentElement->id });
 | 
			
		||||
                    context->elementStateChangeHandler.function(context->elementStateChangeHandler.userData, currentElement->id, data, currentElement->layoutConfig, CLAY_ELEMENT_STATE_BEGIN_FINALIZE);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                bool emitRectangle = false;
 | 
			
		||||
                // Create the render commands for this element
 | 
			
		||||
                Clay_SharedElementConfig *sharedConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SHARED).sharedElementConfig;
 | 
			
		||||
| 
						 | 
				
			
			@ -3041,12 +3102,27 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                Clay_LayoutElementHashMapItem* currentElementData = Clay__GetHashMapItem(currentElement->id);
 | 
			
		||||
                Clay_BoundingBox currentElementBoundingBox = currentElementData->boundingBox;
 | 
			
		||||
 | 
			
		||||
                if (context->elementStateChangeHandler.function) {
 | 
			
		||||
                    Clay_ElementData data = CLAY__DEFAULT_STRUCT;
 | 
			
		||||
 | 
			
		||||
                    if (currentElementData) {
 | 
			
		||||
                        data.boundingBox = currentElementData->boundingBox;
 | 
			
		||||
                        data.visibleBoundingBox = currentElementData->visibleBoundingBox;
 | 
			
		||||
                        data.found = true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    context->elementStateChangeHandler.function(context->elementStateChangeHandler.userData, currentElement->id, data, currentElement->layoutConfig, CLAY_ELEMENT_STATE_END_FINALIZE);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // DFS is returning upwards backwards
 | 
			
		||||
                bool closeClipElement = false;
 | 
			
		||||
                Clay_ClipElementConfig *clipConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
                if (clipConfig) {
 | 
			
		||||
                    Clay_LayoutElementHashMapItem *currentElementData = Clay__GetHashMapItem(currentElement->id);
 | 
			
		||||
                    closeClipElement = !Clay__ElementIsOffscreen(¤tElementData->boundingBox);
 | 
			
		||||
 | 
			
		||||
                    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
 | 
			
		||||
                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
 | 
			
		||||
                        if (mapping->layoutElement == currentElement) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3060,9 +3136,6 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
                if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_BORDER)) {
 | 
			
		||||
                    Clay_LayoutElementHashMapItem *currentElementData = Clay__GetHashMapItem(currentElement->id);
 | 
			
		||||
                    Clay_BoundingBox currentElementBoundingBox = currentElementData->boundingBox;
 | 
			
		||||
 | 
			
		||||
                    // Culling - Don't bother to generate render commands for rectangles entirely outside the screen - this won't stop their children from being rendered if they overflow
 | 
			
		||||
                    if (!Clay__ElementIsOffscreen(¤tElementBoundingBox)) {
 | 
			
		||||
                        Clay_SharedElementConfig *sharedConfig = Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SHARED) ? Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SHARED).sharedElementConfig : &Clay_SharedElementConfig_DEFAULT;
 | 
			
		||||
| 
						 | 
				
			
			@ -3253,8 +3326,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_NAMED(CLAY_IDI("Clay__DebugView_EmptyRowOuter", rootIndex), { .layout = { .sizing = {.width = CLAY_SIZING_GROW(0)}, .padding = {CLAY__DEBUGVIEW_INDENT_WIDTH / 2, 0, 0, 0} } }) {
 | 
			
		||||
                CLAY_NAMED(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++;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -3284,11 +3357,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_NAMED(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_NAMED(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} },
 | 
			
		||||
| 
						 | 
				
			
			@ -3360,11 +3432,11 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
 | 
			
		|||
                    CLAY_TEXT(CLAY_STRING("\""), rawTextConfig);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (currentElement->childrenOrTextContent.children.length > 0) {
 | 
			
		||||
                Clay__OpenElement();
 | 
			
		||||
                Clay__OpenElement(CLAY__INIT(Clay_ElementId) CLAY__DEFAULT_STRUCT);
 | 
			
		||||
                Clay__ConfigureOpenElement(CLAY__INIT(Clay_ElementDeclaration) { .layout = { .padding = { .left = 8 } } });
 | 
			
		||||
                Clay__OpenElement();
 | 
			
		||||
                Clay__OpenElement(CLAY__INIT(Clay_ElementId) CLAY__DEFAULT_STRUCT);
 | 
			
		||||
                Clay__ConfigureOpenElement(CLAY__INIT(Clay_ElementDeclaration) { .layout = { .padding = { .left = CLAY__DEBUGVIEW_INDENT_WIDTH }}, .border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { .left = 1 } }});
 | 
			
		||||
                Clay__OpenElement();
 | 
			
		||||
                Clay__OpenElement(CLAY__INIT(Clay_ElementId) CLAY__DEFAULT_STRUCT);
 | 
			
		||||
                Clay__ConfigureOpenElement(CLAY__INIT(Clay_ElementDeclaration) { .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM } });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3391,8 +3463,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_NAMED(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_NAMED(CLAY_ID("Clay__DebugView_ElementHighlightRectangle"), {.layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }, .backgroundColor = Clay__debugViewHighlightColor }) {}
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return layoutData;
 | 
			
		||||
| 
						 | 
				
			
			@ -3518,11 +3590,14 @@ void Clay__RenderDebugView(void) {
 | 
			
		|||
        highlightedRow = -1;
 | 
			
		||||
    }
 | 
			
		||||
    Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT;
 | 
			
		||||
    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 },
 | 
			
		||||
        .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_NAMED(
 | 
			
		||||
        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_TEXT(CLAY_STRING("Clay Debug Tools"), infoTextConfig);
 | 
			
		||||
            CLAY({ .layout = { .sizing = { .width = CLAY_SIZING_GROW(0) } } }) {}
 | 
			
		||||
| 
						 | 
				
			
			@ -3538,11 +3613,11 @@ void Clay__RenderDebugView(void) {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
        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_NAMED(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);
 | 
			
		||||
                // 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_NAMED(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 } }) {
 | 
			
		||||
                        layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -3616,7 +3691,7 @@ void Clay__RenderDebugView(void) {
 | 
			
		|||
                    }
 | 
			
		||||
                    // .padding
 | 
			
		||||
                    CLAY_TEXT(CLAY_STRING("Padding"), infoTitleConfig);
 | 
			
		||||
                    CLAY({ .id = CLAY_ID("Clay__DebugViewElementInfoPadding") }) {
 | 
			
		||||
                    CLAY_NAMED(CLAY_ID("Clay__DebugViewElementInfoPadding")) {
 | 
			
		||||
                        CLAY_TEXT(CLAY_STRING("{ left: "), infoTextConfig);
 | 
			
		||||
                        CLAY_TEXT(Clay__IntToString(layoutConfig->padding.left), infoTextConfig);
 | 
			
		||||
                        CLAY_TEXT(CLAY_STRING(", right: "), infoTextConfig);
 | 
			
		||||
| 
						 | 
				
			
			@ -3709,10 +3784,10 @@ 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_NAMED(CLAY_ID("Clay__DebugViewElementInfoAspectRatioBody"), { .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
 | 
			
		||||
                                CLAY_TEXT(CLAY_STRING("Aspect Ratio"), infoTitleConfig);
 | 
			
		||||
                                // Aspect Ratio
 | 
			
		||||
                                CLAY({ .id = CLAY_ID("Clay__DebugViewElementInfoAspectRatio") }) {
 | 
			
		||||
                                CLAY_NAMED(CLAY_ID("Clay__DebugViewElementInfoAspectRatio")) {
 | 
			
		||||
                                    CLAY_TEXT(Clay__IntToString(aspectRatioConfig->aspectRatio), infoTextConfig);
 | 
			
		||||
                                    CLAY_TEXT(CLAY_STRING("."), infoTextConfig);
 | 
			
		||||
                                    float frac = aspectRatioConfig->aspectRatio - (int)(aspectRatioConfig->aspectRatio);
 | 
			
		||||
| 
						 | 
				
			
			@ -3731,7 +3806,7 @@ 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_NAMED(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 }) {}
 | 
			
		||||
| 
						 | 
				
			
			@ -3853,7 +3928,7 @@ 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_NAMED(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_TEXT(CLAY_STRING("{ left: "), infoTextConfig);
 | 
			
		||||
| 
						 | 
				
			
			@ -3878,16 +3953,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_NAMED(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_NAMED(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_NAMED(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_NAMED(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);
 | 
			
		||||
| 
						 | 
				
			
			@ -3974,6 +4049,12 @@ bool Clay__Array_AddCapacityCheck(int32_t length, int32_t capacity)
 | 
			
		|||
 | 
			
		||||
// PUBLIC API FROM HERE ---------------------------------------
 | 
			
		||||
 | 
			
		||||
CLAY_WASM_EXPORT("Clay_SetOnElementStateChanged")
 | 
			
		||||
void Clay_SetOnElementStateChanged(Clay_OnElementStateChangeFunction onElementStateChanged, void* userData) {
 | 
			
		||||
    Clay_Context* context = Clay_GetCurrentContext();
 | 
			
		||||
    context->elementStateChangeHandler = CLAY__INIT(Clay_OnElementStateChangeHandler) { .function = onElementStateChanged, .userData = userData };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CLAY_WASM_EXPORT("Clay_MinMemorySize")
 | 
			
		||||
uint32_t Clay_MinMemorySize(void) {
 | 
			
		||||
    Clay_Context fakeContext = {
 | 
			
		||||
| 
						 | 
				
			
			@ -4058,10 +4139,6 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
 | 
			
		|||
                    }
 | 
			
		||||
                    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--;
 | 
			
		||||
| 
						 | 
				
			
			@ -4285,9 +4362,8 @@ void Clay_BeginLayout(void) {
 | 
			
		|||
        rootDimensions.width -= (float)Clay__debugViewWidth;
 | 
			
		||||
    }
 | 
			
		||||
    context->booleanWarnings = CLAY__INIT(Clay_BooleanWarnings) CLAY__DEFAULT_STRUCT;
 | 
			
		||||
    Clay__OpenElement();
 | 
			
		||||
    Clay__OpenElement(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);
 | 
			
		||||
| 
						 | 
				
			
			@ -4332,18 +4408,23 @@ Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index)
 | 
			
		|||
    return Clay__HashStringWithOffset(idString, index, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Clay_Hovered(void) {
 | 
			
		||||
CLAY_WASM_EXPORT("Clay_GetCurrentElementID")
 | 
			
		||||
uint32_t Clay_GetCurrentElementID(void) {
 | 
			
		||||
    Clay_Context* context = Clay_GetCurrentContext();
 | 
			
		||||
    if (context->booleanWarnings.maxElementsExceeded) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
 | 
			
		||||
    // If the element has no id attached at this point, we need to generate one
 | 
			
		||||
    if (openLayoutElement->id == 0) {
 | 
			
		||||
        Clay__GenerateIdForAnonymousElement(openLayoutElement);
 | 
			
		||||
    }
 | 
			
		||||
    Clay_LayoutElement* openLayoutElement = Clay__GetOpenLayoutElement();
 | 
			
		||||
 | 
			
		||||
    return openLayoutElement->id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Clay_Hovered(void) {
 | 
			
		||||
    Clay_Context* context = Clay_GetCurrentContext();
 | 
			
		||||
    uint32_t id = Clay_GetCurrentElementID();
 | 
			
		||||
 | 
			
		||||
    for (int32_t i = 0; i < context->pointerOverIds.length; ++i) {
 | 
			
		||||
        if (Clay_ElementIdArray_Get(&context->pointerOverIds, i)->id == openLayoutElement->id) {
 | 
			
		||||
        if (Clay_ElementIdArray_Get(&context->pointerOverIds, i)->id == id) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -4406,6 +4487,7 @@ Clay_ElementData Clay_GetElementData(Clay_ElementId id){
 | 
			
		|||
 | 
			
		||||
    return CLAY__INIT(Clay_ElementData){
 | 
			
		||||
        .boundingBox = item->boundingBox,
 | 
			
		||||
        .visibleBoundingBox = item->visibleBoundingBox,
 | 
			
		||||
        .found = true
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue