mirror of
				https://github.com/nicbarker/clay.git
				synced 2025-11-04 08:36:17 +00:00 
			
		
		
		
	[Core] Replace .scroll config with .clip (#376)
This commit is contained in:
		
							parent
							
								
									313964132c
								
							
						
					
					
						commit
						970919e1fb
					
				
							
								
								
									
										87
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								README.md
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -178,18 +178,10 @@ For help starting out or to discuss clay, considering joining [the discord serve
 | 
			
		|||
    - [Clay_GetScrollContainerData](#clay_getscrollcontainerdata)
 | 
			
		||||
    - [Clay_GetElementId](#clay_getelementid)
 | 
			
		||||
  - [Element Macros](#element-macros)
 | 
			
		||||
    - [CLAY](#clay-1)
 | 
			
		||||
    - [CLAY](#clay)
 | 
			
		||||
    - [CLAY_ID](#clay_id)
 | 
			
		||||
    - [CLAY_IDI](#clay_idi)
 | 
			
		||||
    - [CLAY_LAYOUT](#clay_layout)
 | 
			
		||||
    - [CLAY_RECTANGLE](#clay_rectangle)
 | 
			
		||||
    - [CLAY_TEXT](#clay_text)
 | 
			
		||||
    - [CLAY_IMAGE](#clay_image)
 | 
			
		||||
    - [CLAY_SCROLL](#clay_scroll)
 | 
			
		||||
    - [CLAY_BORDER](#clay_border)
 | 
			
		||||
    - [CLAY_FLOATING](#clay_floating)
 | 
			
		||||
    - [CLAY_CUSTOM_ELEMENT](#clay_custom_element)
 | 
			
		||||
  - [Data Structures & Defs](data-structures--definitions)
 | 
			
		||||
  - [Data Structures & Defs](#data-structures--definitions)
 | 
			
		||||
    - [Clay_String](#clay_string)
 | 
			
		||||
    - [Clay_ElementId](#clay_elementid)
 | 
			
		||||
    - [Clay_RenderCommandArray](#clay_rendercommandarray)
 | 
			
		||||
| 
						 | 
				
			
			@ -350,7 +342,11 @@ If this is an issue for you, performing layout twice per frame with the same dat
 | 
			
		|||
 | 
			
		||||
### Scrolling Elements
 | 
			
		||||
 | 
			
		||||
Elements are configured as scrollable with the `CLAY_SCROLL` macro. To make scroll containers respond to mouse wheel and scroll events, two functions need to be called before `BeginLayout()`:
 | 
			
		||||
Elements are configured as scrollable with the `.clip` configuration. Clipping instructs the renderer to not draw any pixels outside the clipped element's boundaries, and by specifying the `.childOffset` field, the clipped element's contents can be shifted around to provide "scrolling" behaviour.
 | 
			
		||||
 | 
			
		||||
You can either calculate scrolling yourself and simply provide the current offset each frame to `.childOffset`, or alternatively, Clay provides a built in mechanism for tracking and updating scroll container offsets, detailed below.
 | 
			
		||||
 | 
			
		||||
To make scroll containers respond to mouse wheel and scroll events, two functions need to be called before `BeginLayout()`:
 | 
			
		||||
```C
 | 
			
		||||
Clay_Vector2 mousePosition = { x, y };
 | 
			
		||||
// Reminder: Clay_SetPointerState must be called before Clay_UpdateScrollContainers otherwise it will have no effect
 | 
			
		||||
| 
						 | 
				
			
			@ -362,9 +358,17 @@ Clay_UpdateScrollContainers(
 | 
			
		|||
    float deltaTime, // Time since last frame in seconds as a float e.g. 8ms is 0.008f
 | 
			
		||||
);
 | 
			
		||||
// ...
 | 
			
		||||
// Clay internally tracks the scroll containers offset, and Clay_GetScrollOffset returns the x,y offset of the currently open element
 | 
			
		||||
CLAY({ .clip = vertical, .childOffset = Clay_GetScrollOffset() }) {
 | 
			
		||||
    // Scrolling contents
 | 
			
		||||
}
 | 
			
		||||
// .childOffset can be provided directly if you would prefer to manage scrolling outside of clay
 | 
			
		||||
CLAY({ .clip = vertical, .childOffset = myData.scrollContainer.offset }) {
 | 
			
		||||
    // Scrolling contents
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
More specific details can be found in the full [Scroll API](#clay_scroll).
 | 
			
		||||
More specific details can be found in the docs for [Clay_UpdateScrollContainers](#clay_updatescrollcontainers), [Clay_SetPointerState](#clay_setpointerstate), [Clay_ClipElementConfig](#clay_clipelementconfig) and [Clay_GetScrollOffset](#clay_getscrolloffset).
 | 
			
		||||
 | 
			
		||||
### Floating Elements ("Absolute" Positioning)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -658,6 +662,25 @@ Touch / drag scrolling only occurs if the `enableDragScrolling` parameter is `tr
 | 
			
		|||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### Clay_GetScrollOffset
 | 
			
		||||
 | 
			
		||||
`Clay_Vector2 Clay_GetScrollOffset()`
 | 
			
		||||
 | 
			
		||||
Returns the internally stored scroll offset for the currently open element.
 | 
			
		||||
 | 
			
		||||
Generally intended for use with [clip elements](#clay_clipelementconfig) and the `.childOffset` field to create scrolling containers.
 | 
			
		||||
 | 
			
		||||
See [Scrolling Elements](#scrolling-elements) for more details.
 | 
			
		||||
 | 
			
		||||
```C
 | 
			
		||||
// Create a horizontally scrolling container
 | 
			
		||||
CLAY({
 | 
			
		||||
    .clip = { .horizontal = true, .childOffset = Clay_GetScrollOffset() }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### Clay_BeginLayout
 | 
			
		||||
 | 
			
		||||
`void Clay_BeginLayout()`
 | 
			
		||||
| 
						 | 
				
			
			@ -767,7 +790,7 @@ CLAY({ .id = CLAY_ID("Outer"), .layout = { .padding = CLAY_PADDING_ALL(16) } })
 | 
			
		|||
        .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
 | 
			
		||||
        .backgroundColor = { 200, 200, 100, 255 },
 | 
			
		||||
        .cornerRadius = CLAY_CORNER_RADIUS(10),
 | 
			
		||||
        .scroll = { .vertical = true }
 | 
			
		||||
        .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
 | 
			
		||||
    }) {
 | 
			
		||||
        // child elements
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,7 +1057,7 @@ typedef struct {
 | 
			
		|||
    Clay_ImageElementConfig image;
 | 
			
		||||
    Clay_FloatingElementConfig floating;
 | 
			
		||||
    Clay_CustomElementConfig custom;
 | 
			
		||||
    Clay_ScrollElementConfig scroll;
 | 
			
		||||
    Clay_ClipElementConfig clip;
 | 
			
		||||
    Clay_BorderElementConfig border;
 | 
			
		||||
    void *userData;
 | 
			
		||||
} Clay_ElementDeclaration;
 | 
			
		||||
| 
						 | 
				
			
			@ -1101,11 +1124,13 @@ Uses [Clay_CustomElementConfig](#clay_customelementconfig). Configures the eleme
 | 
			
		|||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
**`.scroll`** - `Clay_ScrollElementConfig`
 | 
			
		||||
**`.clip`** - `Clay_ClipElementConfig`
 | 
			
		||||
 | 
			
		||||
`CLAY({ .scroll = { .vertical = true } })`
 | 
			
		||||
`CLAY({ .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } })`
 | 
			
		||||
 | 
			
		||||
Uses [Clay_ScrollElementConfig](#clay_scrollelementconfig). Configures the element as a scroll element, which causes child elements to be clipped / masked if they overflow, and together with [Clay_UpdateScrollContainer](#clay_updatescrollcontainers) enables scrolling of child contents.
 | 
			
		||||
Uses [Clay_ClipElementConfig](#clay_scrollelementconfig). Configures the element as a clip element, which causes child elements to be clipped / masked if they overflow, and together with the functions listed in [Scrolling Elements](#scrolling-elements) enables scrolling of child contents.
 | 
			
		||||
 | 
			
		||||
<img width="580" alt="An image demonstrating the concept of clipping which prevents rendering of a child elements pixels if they fall outside the bounds of the parent element." src="https://github.com/user-attachments/assets/2eb83ff9-e186-4ea4-8a87-d90cbc0838b5">
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1140,7 +1165,7 @@ CLAY({ .color = { 200, 200, 100, 255 }, .cornerRadius = CLAY_CORNER_RADIUS(10) }
 | 
			
		|||
CLAY({ 
 | 
			
		||||
    .backgroundColor = { 200, 200, 100, 255 }, 
 | 
			
		||||
    .cornerRadius = CLAY_CORNER_RADIUS(10)
 | 
			
		||||
    CLAY_SCROLL({ .vertical = true })
 | 
			
		||||
    .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
 | 
			
		||||
) {
 | 
			
		||||
    // child elements
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1312,22 +1337,22 @@ Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_
 | 
			
		|||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### Clay_ScrollElementConfig
 | 
			
		||||
### Clay_ClipElementConfig
 | 
			
		||||
 | 
			
		||||
**Usage**
 | 
			
		||||
 | 
			
		||||
`CLAY({ .scroll = { ...scroll config } }) {}`
 | 
			
		||||
`CLAY({ .clip = { ...clip config } }) {}`
 | 
			
		||||
 | 
			
		||||
**Notes**
 | 
			
		||||
 | 
			
		||||
`Clay_ScrollElementConfig` configures the element as a scrolling container, enabling masking of children that extend beyond its boundaries.
 | 
			
		||||
`Clay_ClipElementConfig` configures the element as a clipping container, enabling masking of children that extend beyond its boundaries.
 | 
			
		||||
 | 
			
		||||
Note: In order to process scrolling based on pointer position and mouse wheel or touch interactions, you must call `Clay_SetPointerState()` and `Clay_UpdateScrollContainers()` _before_ calling `BeginLayout`.
 | 
			
		||||
 | 
			
		||||
**Struct Definition (Pseudocode)**
 | 
			
		||||
 | 
			
		||||
```C
 | 
			
		||||
Clay_ScrollElementConfig {
 | 
			
		||||
Clay_ClipElementConfig {
 | 
			
		||||
    bool horizontal;
 | 
			
		||||
    bool vertical;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1337,30 +1362,30 @@ Clay_ScrollElementConfig {
 | 
			
		|||
 | 
			
		||||
**`.horizontal`** - `bool`
 | 
			
		||||
 | 
			
		||||
`CLAY({ .scroll = { .horizontal = true } })`
 | 
			
		||||
`CLAY({ .clip = { .horizontal = true } })`
 | 
			
		||||
 | 
			
		||||
Enables or disables horizontal scrolling for this container element.
 | 
			
		||||
Enables or disables horizontal clipping for this container element.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
**`.vertical`** - `bool`
 | 
			
		||||
 | 
			
		||||
`CLAY({ .scroll = { .vertical = true } })`
 | 
			
		||||
`CLAY({ .clip = { .vertical = true } })`
 | 
			
		||||
 | 
			
		||||
Enables or disables vertical scrolling for this container element.
 | 
			
		||||
Enables or disables vertical clipping for this container element.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
**Rendering**
 | 
			
		||||
 | 
			
		||||
Enabling scroll for an element will result in two additional render commands: 
 | 
			
		||||
Enabling clip for an element will result in two additional render commands: 
 | 
			
		||||
- `commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_START`, which should create a rectangle mask with its `boundingBox` and is **not** subject to [culling](#visibility-culling)
 | 
			
		||||
- `commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_END`, which disables the previous rectangle mask and is **not** subject to [culling](#visibility-culling)
 | 
			
		||||
 | 
			
		||||
**Examples**
 | 
			
		||||
 | 
			
		||||
```C
 | 
			
		||||
CLAY({ .scroll = { .vertical = true } }) {
 | 
			
		||||
CLAY({ .clip = { .vertical = true } }) {
 | 
			
		||||
    // Create child content with a fixed height of 5000
 | 
			
		||||
    CLAY({ .id = CLAY_ID("ScrollInner"), .layout = { .sizing = { .height = CLAY_SIZING_FIXED(5000) } } }) {}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2031,7 +2056,7 @@ typedef struct {
 | 
			
		|||
    // The outer dimensions of the inner scroll container content, including the padding of the parent scroll container.
 | 
			
		||||
    Clay_Dimensions contentDimensions;
 | 
			
		||||
    // The config that was originally passed to the scroll element.
 | 
			
		||||
    Clay_ScrollElementConfig config;
 | 
			
		||||
    Clay_ClipElementConfig config;
 | 
			
		||||
    // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
 | 
			
		||||
    bool found;
 | 
			
		||||
} Clay_ScrollContainerData;
 | 
			
		||||
| 
						 | 
				
			
			@ -2081,9 +2106,9 @@ Dimensions representing the inner width and height of the content _inside_ the s
 | 
			
		|||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
**`.config`** - `Clay_ScrollElementConfig`
 | 
			
		||||
**`.config`** - `Clay_ClipElementConfig`
 | 
			
		||||
 | 
			
		||||
The [Clay_ScrollElementConfig](#clay_scroll) for the matching scroll container element.
 | 
			
		||||
The [Clay_ClipElementConfig](#clay_scroll) for the matching scroll container element.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										159
									
								
								clay.h
									
									
									
									
									
								
							
							
						
						
									
										159
									
								
								clay.h
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -492,11 +492,12 @@ CLAY__WRAPPER_STRUCT(Clay_CustomElementConfig);
 | 
			
		|||
 | 
			
		||||
// Controls the axis on which an element switches to "scrolling", which clips the contents and allows scrolling in that direction.
 | 
			
		||||
typedef struct {
 | 
			
		||||
    bool horizontal; // Clip overflowing elements on the X axis and allow scrolling left and right.
 | 
			
		||||
    bool vertical; // Clip overflowing elements on the YU axis and allow scrolling up and down.
 | 
			
		||||
} Clay_ScrollElementConfig;
 | 
			
		||||
    bool horizontal; // Clip overflowing elements on the X axis.
 | 
			
		||||
    bool vertical; // Clip overflowing elements on the Y axis.
 | 
			
		||||
    Clay_Vector2 childOffset; // Offsets the x,y positions of all child elements. Used primarily for scrolling containers.
 | 
			
		||||
} Clay_ClipElementConfig;
 | 
			
		||||
 | 
			
		||||
CLAY__WRAPPER_STRUCT(Clay_ScrollElementConfig);
 | 
			
		||||
CLAY__WRAPPER_STRUCT(Clay_ClipElementConfig);
 | 
			
		||||
 | 
			
		||||
// Border -----------------------------
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -578,7 +579,7 @@ typedef struct {
 | 
			
		|||
typedef struct {
 | 
			
		||||
    bool horizontal;
 | 
			
		||||
    bool vertical;
 | 
			
		||||
} Clay_ScrollRenderData;
 | 
			
		||||
} Clay_ClipRenderData;
 | 
			
		||||
 | 
			
		||||
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_BORDER
 | 
			
		||||
typedef struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -604,8 +605,8 @@ typedef union {
 | 
			
		|||
    Clay_CustomRenderData custom;
 | 
			
		||||
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_BORDER
 | 
			
		||||
    Clay_BorderRenderData border;
 | 
			
		||||
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_SCROLL
 | 
			
		||||
    Clay_ScrollRenderData scroll;
 | 
			
		||||
    // Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_SCISSOR_START|END
 | 
			
		||||
    Clay_ClipRenderData clip;
 | 
			
		||||
} Clay_RenderData;
 | 
			
		||||
 | 
			
		||||
// Miscellaneous Structs & Enums ---------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -619,8 +620,8 @@ typedef struct {
 | 
			
		|||
    Clay_Dimensions scrollContainerDimensions;
 | 
			
		||||
    // The outer dimensions of the inner scroll container content, including the padding of the parent scroll container.
 | 
			
		||||
    Clay_Dimensions contentDimensions;
 | 
			
		||||
    // The config that was originally passed to the scroll element.
 | 
			
		||||
    Clay_ScrollElementConfig config;
 | 
			
		||||
    // The config that was originally passed to the clip element.
 | 
			
		||||
    Clay_ClipElementConfig config;
 | 
			
		||||
    // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
 | 
			
		||||
    bool found;
 | 
			
		||||
} Clay_ScrollContainerData;
 | 
			
		||||
| 
						 | 
				
			
			@ -730,8 +731,8 @@ typedef struct {
 | 
			
		|||
    Clay_FloatingElementConfig floating;
 | 
			
		||||
    // Used to create CUSTOM render commands, usually to render element types not supported by Clay.
 | 
			
		||||
    Clay_CustomElementConfig custom;
 | 
			
		||||
    // Controls whether an element should clip its contents and allow scrolling rather than expanding to contain them.
 | 
			
		||||
    Clay_ScrollElementConfig scroll;
 | 
			
		||||
    // Controls whether an element should clip its contents, as well as providing child x,y offset configuration for scrolling.
 | 
			
		||||
    Clay_ClipElementConfig clip;
 | 
			
		||||
    // Controls settings related to element borders, and will generate BORDER render commands.
 | 
			
		||||
    Clay_BorderElementConfig border;
 | 
			
		||||
    // A pointer that will be transparently passed through to resulting render commands.
 | 
			
		||||
| 
						 | 
				
			
			@ -816,6 +817,9 @@ CLAY_DLL_EXPORT void Clay_SetCurrentContext(Clay_Context* context);
 | 
			
		|||
// - scrollDelta is the amount to scroll this frame on each axis in pixels.
 | 
			
		||||
// - deltaTime is the time in seconds since the last "frame" (scroll update)
 | 
			
		||||
CLAY_DLL_EXPORT void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime);
 | 
			
		||||
// Returns the internally stored scroll offset for the currently open element.
 | 
			
		||||
// Generally intended for use with clip elements to create scrolling containers.
 | 
			
		||||
CLAY_DLL_EXPORT Clay_Vector2 Clay_GetScrollOffset();
 | 
			
		||||
// Updates the layout dimensions in response to the window or outer container being resized.
 | 
			
		||||
CLAY_DLL_EXPORT void Clay_SetLayoutDimensions(Clay_Dimensions dimensions);
 | 
			
		||||
// Called before starting any layout declarations.
 | 
			
		||||
| 
						 | 
				
			
			@ -1035,7 +1039,7 @@ CLAY__ARRAY_DEFINE(Clay_TextElementConfig, Clay__TextElementConfigArray)
 | 
			
		|||
CLAY__ARRAY_DEFINE(Clay_ImageElementConfig, Clay__ImageElementConfigArray)
 | 
			
		||||
CLAY__ARRAY_DEFINE(Clay_FloatingElementConfig, Clay__FloatingElementConfigArray)
 | 
			
		||||
CLAY__ARRAY_DEFINE(Clay_CustomElementConfig, Clay__CustomElementConfigArray)
 | 
			
		||||
CLAY__ARRAY_DEFINE(Clay_ScrollElementConfig, Clay__ScrollElementConfigArray)
 | 
			
		||||
CLAY__ARRAY_DEFINE(Clay_ClipElementConfig, Clay__ClipElementConfigArray)
 | 
			
		||||
CLAY__ARRAY_DEFINE(Clay_BorderElementConfig, Clay__BorderElementConfigArray)
 | 
			
		||||
CLAY__ARRAY_DEFINE(Clay_String, Clay__StringArray)
 | 
			
		||||
CLAY__ARRAY_DEFINE(Clay_SharedElementConfig, Clay__SharedElementConfigArray)
 | 
			
		||||
| 
						 | 
				
			
			@ -1045,7 +1049,7 @@ typedef CLAY_PACKED_ENUM {
 | 
			
		|||
    CLAY__ELEMENT_CONFIG_TYPE_NONE,
 | 
			
		||||
    CLAY__ELEMENT_CONFIG_TYPE_BORDER,
 | 
			
		||||
    CLAY__ELEMENT_CONFIG_TYPE_FLOATING,
 | 
			
		||||
    CLAY__ELEMENT_CONFIG_TYPE_SCROLL,
 | 
			
		||||
    CLAY__ELEMENT_CONFIG_TYPE_CLIP,
 | 
			
		||||
    CLAY__ELEMENT_CONFIG_TYPE_IMAGE,
 | 
			
		||||
    CLAY__ELEMENT_CONFIG_TYPE_TEXT,
 | 
			
		||||
    CLAY__ELEMENT_CONFIG_TYPE_CUSTOM,
 | 
			
		||||
| 
						 | 
				
			
			@ -1057,7 +1061,7 @@ typedef union {
 | 
			
		|||
    Clay_ImageElementConfig *imageElementConfig;
 | 
			
		||||
    Clay_FloatingElementConfig *floatingElementConfig;
 | 
			
		||||
    Clay_CustomElementConfig *customElementConfig;
 | 
			
		||||
    Clay_ScrollElementConfig *scrollElementConfig;
 | 
			
		||||
    Clay_ClipElementConfig *clipElementConfig;
 | 
			
		||||
    Clay_BorderElementConfig *borderElementConfig;
 | 
			
		||||
    Clay_SharedElementConfig *sharedElementConfig;
 | 
			
		||||
} Clay_ElementConfigUnion;
 | 
			
		||||
| 
						 | 
				
			
			@ -1219,7 +1223,7 @@ struct Clay_Context {
 | 
			
		|||
    Clay__TextElementConfigArray textElementConfigs;
 | 
			
		||||
    Clay__ImageElementConfigArray imageElementConfigs;
 | 
			
		||||
    Clay__FloatingElementConfigArray floatingElementConfigs;
 | 
			
		||||
    Clay__ScrollElementConfigArray scrollElementConfigs;
 | 
			
		||||
    Clay__ClipElementConfigArray clipElementConfigs;
 | 
			
		||||
    Clay__CustomElementConfigArray customElementConfigs;
 | 
			
		||||
    Clay__BorderElementConfigArray borderElementConfigs;
 | 
			
		||||
    Clay__SharedElementConfigArray sharedElementConfigs;
 | 
			
		||||
| 
						 | 
				
			
			@ -1287,7 +1291,7 @@ Clay_TextElementConfig * Clay__StoreTextElementConfig(Clay_TextElementConfig con
 | 
			
		|||
Clay_ImageElementConfig * Clay__StoreImageElementConfig(Clay_ImageElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_ImageElementConfig_DEFAULT : Clay__ImageElementConfigArray_Add(&Clay_GetCurrentContext()->imageElementConfigs, config); }
 | 
			
		||||
Clay_FloatingElementConfig * Clay__StoreFloatingElementConfig(Clay_FloatingElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_FloatingElementConfig_DEFAULT : Clay__FloatingElementConfigArray_Add(&Clay_GetCurrentContext()->floatingElementConfigs, config); }
 | 
			
		||||
Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_CustomElementConfig_DEFAULT : Clay__CustomElementConfigArray_Add(&Clay_GetCurrentContext()->customElementConfigs, config); }
 | 
			
		||||
Clay_ScrollElementConfig * Clay__StoreScrollElementConfig(Clay_ScrollElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_ScrollElementConfig_DEFAULT : Clay__ScrollElementConfigArray_Add(&Clay_GetCurrentContext()->scrollElementConfigs, config); }
 | 
			
		||||
Clay_ClipElementConfig * Clay__StoreClipElementConfig(Clay_ClipElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_ClipElementConfig_DEFAULT : Clay__ClipElementConfigArray_Add(&Clay_GetCurrentContext()->clipElementConfigs, config); }
 | 
			
		||||
Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_BorderElementConfig_DEFAULT : Clay__BorderElementConfigArray_Add(&Clay_GetCurrentContext()->borderElementConfigs, config); }
 | 
			
		||||
Clay_SharedElementConfig * Clay__StoreSharedElementConfig(Clay_SharedElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &Clay_SharedElementConfig_DEFAULT : Clay__SharedElementConfigArray_Add(&Clay_GetCurrentContext()->sharedElementConfigs, config); }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1761,9 +1765,9 @@ void Clay__CloseElement(void) {
 | 
			
		|||
    bool elementHasScrollVertical = false;
 | 
			
		||||
    for (int32_t i = 0; i < openLayoutElement->elementConfigs.length; i++) {
 | 
			
		||||
        Clay_ElementConfig *config = Clay__ElementConfigArraySlice_Get(&openLayoutElement->elementConfigs, i);
 | 
			
		||||
        if (config->type == CLAY__ELEMENT_CONFIG_TYPE_SCROLL) {
 | 
			
		||||
            elementHasScrollHorizontal = config->config.scrollElementConfig->horizontal;
 | 
			
		||||
            elementHasScrollVertical = config->config.scrollElementConfig->vertical;
 | 
			
		||||
        if (config->type == CLAY__ELEMENT_CONFIG_TYPE_CLIP) {
 | 
			
		||||
            elementHasScrollHorizontal = config->config.clipElementConfig->horizontal;
 | 
			
		||||
            elementHasScrollVertical = config->config.clipElementConfig->vertical;
 | 
			
		||||
            context->openClipElementStack.length--;
 | 
			
		||||
            break;
 | 
			
		||||
        } else if (config->type == CLAY__ELEMENT_CONFIG_TYPE_FLOATING) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2074,8 +2078,8 @@ void Clay__ConfigureOpenElementPtr(const Clay_ElementDeclaration *declaration) {
 | 
			
		|||
        openLayoutElementId = Clay__GenerateIdForAnonymousElement(openLayoutElement);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (declaration->scroll.horizontal | declaration->scroll.vertical) {
 | 
			
		||||
        Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .scrollElementConfig = Clay__StoreScrollElementConfig(declaration->scroll) }, CLAY__ELEMENT_CONFIG_TYPE_SCROLL);
 | 
			
		||||
    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
 | 
			
		||||
        Clay__ScrollContainerDataInternal *scrollOffset = CLAY__NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -2118,7 +2122,7 @@ void Clay__InitializeEphemeralMemory(Clay_Context* context) {
 | 
			
		|||
    context->textElementConfigs = Clay__TextElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
    context->imageElementConfigs = Clay__ImageElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
    context->floatingElementConfigs = Clay__FloatingElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
    context->scrollElementConfigs = Clay__ScrollElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
    context->clipElementConfigs = Clay__ClipElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
    context->customElementConfigs = Clay__CustomElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
    context->borderElementConfigs = Clay__BorderElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
    context->sharedElementConfigs = Clay__SharedElementConfigArray_Allocate_Arena(maxElementCount, arena);
 | 
			
		||||
| 
						 | 
				
			
			@ -2257,8 +2261,8 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
 | 
			
		|||
                float sizeToDistribute = parentSize - parentPadding - innerContentSize;
 | 
			
		||||
                // 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
 | 
			
		||||
                    Clay_ScrollElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL).scrollElementConfig;
 | 
			
		||||
                    // If the parent clips content in this axis direction, don't compress children, just leave them alone
 | 
			
		||||
                    Clay_ClipElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
                    if (scrollElementConfig) {
 | 
			
		||||
                        if (((xAxis && scrollElementConfig->horizontal) || (!xAxis && scrollElementConfig->vertical))) {
 | 
			
		||||
                            continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -2359,9 +2363,9 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
 | 
			
		|||
 | 
			
		||||
                    float maxSize = parentSize - parentPadding;
 | 
			
		||||
                    // If we're laying out the children of a scroll panel, grow containers expand to the size of the inner content, not the outer container
 | 
			
		||||
                    if (Clay__ElementHasConfig(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL)) {
 | 
			
		||||
                        Clay_ScrollElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL).scrollElementConfig;
 | 
			
		||||
                        if (((xAxis && scrollElementConfig->horizontal) || (!xAxis && scrollElementConfig->vertical))) {
 | 
			
		||||
                    if (Clay__ElementHasConfig(parent, CLAY__ELEMENT_CONFIG_TYPE_CLIP)) {
 | 
			
		||||
                        Clay_ClipElementConfig *clipElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
                        if (((xAxis && clipElementConfig->horizontal) || (!xAxis && clipElementConfig->vertical))) {
 | 
			
		||||
                            maxSize = CLAY__MAX(maxSize, innerContentSize);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2634,20 +2638,14 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
            if (clipHashMapItem) {
 | 
			
		||||
                // Floating elements that are attached to scrolling contents won't be correctly positioned if external scroll handling is enabled, fix here
 | 
			
		||||
                if (context->externalScrollHandlingEnabled) {
 | 
			
		||||
                    Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(clipHashMapItem->layoutElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL).scrollElementConfig;
 | 
			
		||||
                    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
 | 
			
		||||
                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
 | 
			
		||||
                        if (mapping->layoutElement == clipHashMapItem->layoutElement) {
 | 
			
		||||
                            root->pointerOffset = mapping->scrollPosition;
 | 
			
		||||
                            if (scrollConfig->horizontal) {
 | 
			
		||||
                                rootPosition.x += mapping->scrollPosition.x;
 | 
			
		||||
                            }
 | 
			
		||||
                            if (scrollConfig->vertical) {
 | 
			
		||||
                                rootPosition.y += mapping->scrollPosition.y;
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    Clay_ClipElementConfig *clipConfig = Clay__FindElementConfigWithType(clipHashMapItem->layoutElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
                    if (clipConfig->horizontal) {
 | 
			
		||||
                        rootPosition.x += clipConfig->childOffset.x;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (clipConfig->vertical) {
 | 
			
		||||
                        rootPosition.y += clipConfig->childOffset.y;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand) {
 | 
			
		||||
                    .boundingBox = clipHashMapItem->boundingBox,
 | 
			
		||||
| 
						 | 
				
			
			@ -2683,8 +2681,8 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
 | 
			
		||||
                Clay__ScrollContainerDataInternal *scrollContainerData = CLAY__NULL;
 | 
			
		||||
                // Apply scroll offsets to container
 | 
			
		||||
                if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL)) {
 | 
			
		||||
                    Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL).scrollElementConfig;
 | 
			
		||||
                if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP)) {
 | 
			
		||||
                    Clay_ClipElementConfig *clipConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
 | 
			
		||||
                    // This linear scan could theoretically be slow under very strange conditions, but I can't imagine a real UI with more than a few 10's of scroll containers
 | 
			
		||||
                    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2692,10 +2690,10 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
                        if (mapping->layoutElement == currentElement) {
 | 
			
		||||
                            scrollContainerData = mapping;
 | 
			
		||||
                            mapping->boundingBox = currentElementBoundingBox;
 | 
			
		||||
                            if (scrollConfig->horizontal) {
 | 
			
		||||
                            if (clipConfig->horizontal) {
 | 
			
		||||
                                scrollOffset.x = mapping->scrollPosition.x;
 | 
			
		||||
                            }
 | 
			
		||||
                            if (scrollConfig->vertical) {
 | 
			
		||||
                            if (clipConfig->vertical) {
 | 
			
		||||
                                scrollOffset.y = mapping->scrollPosition.y;
 | 
			
		||||
                            }
 | 
			
		||||
                            if (context->externalScrollHandlingEnabled) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2728,7 +2726,7 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
                        int32_t next = sortedConfigIndexes[i + 1];
 | 
			
		||||
                        Clay__ElementConfigType currentType = Clay__ElementConfigArraySlice_Get(¤tElement->elementConfigs, current)->type;
 | 
			
		||||
                        Clay__ElementConfigType nextType = Clay__ElementConfigArraySlice_Get(¤tElement->elementConfigs, next)->type;
 | 
			
		||||
                        if (nextType == CLAY__ELEMENT_CONFIG_TYPE_SCROLL || currentType == CLAY__ELEMENT_CONFIG_TYPE_BORDER) {
 | 
			
		||||
                        if (nextType == CLAY__ELEMENT_CONFIG_TYPE_CLIP || currentType == CLAY__ELEMENT_CONFIG_TYPE_BORDER) {
 | 
			
		||||
                            sortedConfigIndexes[i] = next;
 | 
			
		||||
                            sortedConfigIndexes[i + 1] = current;
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			@ -2764,12 +2762,12 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
                            shouldRender = false;
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                        case CLAY__ELEMENT_CONFIG_TYPE_SCROLL: {
 | 
			
		||||
                        case CLAY__ELEMENT_CONFIG_TYPE_CLIP: {
 | 
			
		||||
                            renderCommand.commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_START;
 | 
			
		||||
                            renderCommand.renderData = CLAY__INIT(Clay_RenderData) {
 | 
			
		||||
                                .scroll = {
 | 
			
		||||
                                    .horizontal = elementConfig->config.scrollElementConfig->horizontal,
 | 
			
		||||
                                    .vertical = elementConfig->config.scrollElementConfig->vertical,
 | 
			
		||||
                                .clip = {
 | 
			
		||||
                                    .horizontal = elementConfig->config.clipElementConfig->horizontal,
 | 
			
		||||
                                    .vertical = elementConfig->config.clipElementConfig->vertical,
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            break;
 | 
			
		||||
| 
						 | 
				
			
			@ -2912,15 +2910,15 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                // DFS is returning upwards backwards
 | 
			
		||||
                bool closeScrollElement = false;
 | 
			
		||||
                Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL).scrollElementConfig;
 | 
			
		||||
                if (scrollConfig) {
 | 
			
		||||
                    closeScrollElement = true;
 | 
			
		||||
                bool closeClipElement = false;
 | 
			
		||||
                Clay_ClipElementConfig *clipConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
                if (clipConfig) {
 | 
			
		||||
                    closeClipElement = true;
 | 
			
		||||
                    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
 | 
			
		||||
                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
 | 
			
		||||
                        if (mapping->layoutElement == currentElement) {
 | 
			
		||||
                            if (scrollConfig->horizontal) { scrollOffset.x = mapping->scrollPosition.x; }
 | 
			
		||||
                            if (scrollConfig->vertical) { scrollOffset.y = mapping->scrollPosition.y; }
 | 
			
		||||
                            if (clipConfig->horizontal) { scrollOffset.x = mapping->scrollPosition.x; }
 | 
			
		||||
                            if (clipConfig->vertical) { scrollOffset.y = mapping->scrollPosition.y; }
 | 
			
		||||
                            if (context->externalScrollHandlingEnabled) {
 | 
			
		||||
                                scrollOffset = CLAY__INIT(Clay_Vector2) CLAY__DEFAULT_STRUCT;
 | 
			
		||||
                            }
 | 
			
		||||
| 
						 | 
				
			
			@ -2989,7 +2987,7 @@ void Clay__CalculateFinalLayout(void) {
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                // This exists because the scissor needs to end _after_ borders between elements
 | 
			
		||||
                if (closeScrollElement) {
 | 
			
		||||
                if (closeClipElement) {
 | 
			
		||||
                    Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand) {
 | 
			
		||||
                        .id = Clay__HashNumber(currentElement->id, rootElement->childrenOrTextContent.children.length + 11).id,
 | 
			
		||||
                        .commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_END,
 | 
			
		||||
| 
						 | 
				
			
			@ -3077,7 +3075,7 @@ Clay__DebugElementConfigTypeLabelConfig Clay__DebugGetElementConfigTypeLabel(Cla
 | 
			
		|||
        case CLAY__ELEMENT_CONFIG_TYPE_TEXT: return CLAY__INIT(Clay__DebugElementConfigTypeLabelConfig) { CLAY_STRING("Text"), {105,210,231,255} };
 | 
			
		||||
        case CLAY__ELEMENT_CONFIG_TYPE_IMAGE: return CLAY__INIT(Clay__DebugElementConfigTypeLabelConfig) { CLAY_STRING("Image"), {121,189,154,255} };
 | 
			
		||||
        case CLAY__ELEMENT_CONFIG_TYPE_FLOATING: return CLAY__INIT(Clay__DebugElementConfigTypeLabelConfig) { CLAY_STRING("Floating"), {250,105,0,255} };
 | 
			
		||||
        case CLAY__ELEMENT_CONFIG_TYPE_SCROLL: return CLAY__INIT(Clay__DebugElementConfigTypeLabelConfig) {CLAY_STRING("Scroll"), {242, 196, 90, 255} };
 | 
			
		||||
        case CLAY__ELEMENT_CONFIG_TYPE_CLIP: return CLAY__INIT(Clay__DebugElementConfigTypeLabelConfig) {CLAY_STRING("Scroll"), {242, 196, 90, 255} };
 | 
			
		||||
        case CLAY__ELEMENT_CONFIG_TYPE_BORDER: return CLAY__INIT(Clay__DebugElementConfigTypeLabelConfig) {CLAY_STRING("Border"), {108, 91, 123, 255} };
 | 
			
		||||
        case CLAY__ELEMENT_CONFIG_TYPE_CUSTOM: return CLAY__INIT(Clay__DebugElementConfigTypeLabelConfig) { CLAY_STRING("Custom"), {11,72,107,255} };
 | 
			
		||||
        default: break;
 | 
			
		||||
| 
						 | 
				
			
			@ -3384,7 +3382,7 @@ 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)} }, .scroll = { .horizontal = true, .vertical = true } }) {
 | 
			
		||||
        CLAY({ .id = 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, 0);
 | 
			
		||||
                // Element list
 | 
			
		||||
| 
						 | 
				
			
			@ -3415,7 +3413,7 @@ void Clay__RenderDebugView(void) {
 | 
			
		|||
            CLAY({
 | 
			
		||||
                .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .layoutDirection = CLAY_TOP_TO_BOTTOM },
 | 
			
		||||
                .backgroundColor = CLAY__DEBUGVIEW_COLOR_2 ,
 | 
			
		||||
                .scroll = { .vertical = true },
 | 
			
		||||
                .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
 | 
			
		||||
                .border = { .color = CLAY__DEBUGVIEW_COLOR_3, .width = { .betweenChildren = 1 } }
 | 
			
		||||
            }) {
 | 
			
		||||
                CLAY({ .layout = { .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 0, 0 }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} } }) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3571,15 +3569,15 @@ void Clay__RenderDebugView(void) {
 | 
			
		|||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                        case CLAY__ELEMENT_CONFIG_TYPE_SCROLL: {
 | 
			
		||||
                            Clay_ScrollElementConfig *scrollConfig = elementConfig->config.scrollElementConfig;
 | 
			
		||||
                        case CLAY__ELEMENT_CONFIG_TYPE_CLIP: {
 | 
			
		||||
                            Clay_ClipElementConfig *clipConfig = elementConfig->config.clipElementConfig;
 | 
			
		||||
                            CLAY({ .layout = { .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
 | 
			
		||||
                                // .vertical
 | 
			
		||||
                                CLAY_TEXT(CLAY_STRING("Vertical"), infoTitleConfig);
 | 
			
		||||
                                CLAY_TEXT(scrollConfig->vertical ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig);
 | 
			
		||||
                                CLAY_TEXT(clipConfig->vertical ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig);
 | 
			
		||||
                                // .horizontal
 | 
			
		||||
                                CLAY_TEXT(CLAY_STRING("Horizontal"), infoTitleConfig);
 | 
			
		||||
                                CLAY_TEXT(scrollConfig->horizontal ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig);
 | 
			
		||||
                                CLAY_TEXT(clipConfig->horizontal ? CLAY_STRING("true") : CLAY_STRING("false") , infoTextConfig);
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			@ -3641,7 +3639,7 @@ 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, .scroll = { .horizontal = true, .vertical = true } }) {
 | 
			
		||||
            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_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_TEXT(CLAY_STRING("Warnings"), warningConfig);
 | 
			
		||||
| 
						 | 
				
			
			@ -3898,6 +3896,27 @@ void Clay_SetCurrentContext(Clay_Context* context) {
 | 
			
		|||
    Clay__currentContext = context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CLAY_WASM_EXPORT("Clay_GetScrollOffset")
 | 
			
		||||
Clay_Vector2 Clay_GetScrollOffset() {
 | 
			
		||||
    Clay_Context* context = Clay_GetCurrentContext();
 | 
			
		||||
    if (context->booleanWarnings.maxElementsExceeded) {
 | 
			
		||||
        return CLAY__INIT(Clay_Vector2){};
 | 
			
		||||
    }
 | 
			
		||||
    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_ClipElementConfig *clipConfig = Clay__FindElementConfigWithType(openLayoutElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
 | 
			
		||||
        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
 | 
			
		||||
        if (mapping->layoutElement == openLayoutElement) {
 | 
			
		||||
            return mapping->scrollPosition;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return CLAY__INIT(Clay_Vector2){};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CLAY_WASM_EXPORT("Clay_UpdateScrollContainers")
 | 
			
		||||
void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime) {
 | 
			
		||||
    Clay_Context* context = Clay_GetCurrentContext();
 | 
			
		||||
| 
						 | 
				
			
			@ -3962,9 +3981,9 @@ void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDe
 | 
			
		|||
 | 
			
		||||
    if (highestPriorityElementIndex > -1 && highestPriorityScrollData) {
 | 
			
		||||
        Clay_LayoutElement *scrollElement = highestPriorityScrollData->layoutElement;
 | 
			
		||||
        Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(scrollElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL).scrollElementConfig;
 | 
			
		||||
        bool canScrollVertically = scrollConfig->vertical && highestPriorityScrollData->contentSize.height > scrollElement->dimensions.height;
 | 
			
		||||
        bool canScrollHorizontally = scrollConfig->horizontal && highestPriorityScrollData->contentSize.width > scrollElement->dimensions.width;
 | 
			
		||||
        Clay_ClipElementConfig *clipConfig = Clay__FindElementConfigWithType(scrollElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
        bool canScrollVertically = clipConfig->vertical && highestPriorityScrollData->contentSize.height > scrollElement->dimensions.height;
 | 
			
		||||
        bool canScrollHorizontally = clipConfig->horizontal && highestPriorityScrollData->contentSize.width > scrollElement->dimensions.width;
 | 
			
		||||
        // Handle wheel scroll
 | 
			
		||||
        if (canScrollVertically) {
 | 
			
		||||
            highestPriorityScrollData->scrollPosition.y = highestPriorityScrollData->scrollPosition.y + scrollDelta.y * 10;
 | 
			
		||||
| 
						 | 
				
			
			@ -4120,15 +4139,15 @@ Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
 | 
			
		|||
    for (int32_t i = 0; i < context->scrollContainerDatas.length; ++i) {
 | 
			
		||||
        Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
 | 
			
		||||
        if (scrollContainerData->elementId == id.id) {
 | 
			
		||||
            Clay_ScrollElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(scrollContainerData->layoutElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL).scrollElementConfig;
 | 
			
		||||
            if (!scrollElementConfig) { // This can happen on the first frame before a scroll container is declared
 | 
			
		||||
            Clay_ClipElementConfig *clipElementConfig = Clay__FindElementConfigWithType(scrollContainerData->layoutElement, CLAY__ELEMENT_CONFIG_TYPE_CLIP).clipElementConfig;
 | 
			
		||||
            if (!clipElementConfig) { // This can happen on the first frame before a scroll container is declared
 | 
			
		||||
                return CLAY__INIT(Clay_ScrollContainerData) CLAY__DEFAULT_STRUCT;
 | 
			
		||||
            }
 | 
			
		||||
            return CLAY__INIT(Clay_ScrollContainerData) {
 | 
			
		||||
                .scrollPosition = &scrollContainerData->scrollPosition,
 | 
			
		||||
                .scrollContainerDimensions = { scrollContainerData->boundingBox.width, scrollContainerData->boundingBox.height },
 | 
			
		||||
                .contentDimensions = scrollContainerData->contentSize,
 | 
			
		||||
                .config = *scrollElementConfig,
 | 
			
		||||
                .config = *clipElementConfig,
 | 
			
		||||
                .found = true
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -379,7 +379,7 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
 | 
			
		|||
        CLAY({ .id = CLAY_ID("TopBorder5"), .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_1 }) {}
 | 
			
		||||
        CLAY({ .id = CLAY_ID("OuterScrollContainer"),
 | 
			
		||||
            .layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM },
 | 
			
		||||
            .scroll = { .vertical = true },
 | 
			
		||||
            .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
 | 
			
		||||
            .border = { .width = { .betweenChildren = 2 }, .color = COLOR_RED }
 | 
			
		||||
        }) {
 | 
			
		||||
            if (mobileScreen) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ Clay_RenderCommandArray CreateLayout(void) {
 | 
			
		|||
            CLAY({.id = CLAY_ID("MainContent"),
 | 
			
		||||
                .layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {16, 16, 16, 16}, .childGap = 16, .sizing = { .width = CLAY_SIZING_GROW(0) } },
 | 
			
		||||
                .backgroundColor = {200, 200, 255, 255},
 | 
			
		||||
                .scroll = { .vertical = true },
 | 
			
		||||
                .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
 | 
			
		||||
            })
 | 
			
		||||
            {
 | 
			
		||||
                 CLAY({ .id = CLAY_ID("FloatingContainer"),
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ Clay_RenderCommandArray CreateLayout(void) {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        CLAY({ .id = CLAY_ID("Blob4Floating2"), .floating = { .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID, .zIndex = 1, .parentId = Clay_GetElementId(CLAY_STRING("SidebarBlob4")).id } }) {
 | 
			
		||||
            CLAY({ .id = CLAY_ID("ScrollContainer"), .layout = { .sizing = { .height = CLAY_SIZING_FIXED(200) }, .childGap = 2 }, .scroll = { .vertical = true } }) {
 | 
			
		||||
            CLAY({ .id = CLAY_ID("ScrollContainer"), .layout = { .sizing = { .height = CLAY_SIZING_FIXED(200) }, .childGap = 2 }, .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() } }) {
 | 
			
		||||
                CLAY({ .id = CLAY_ID("FloatingContainer2"), .floating = { .attachTo = CLAY_ATTACH_TO_PARENT, .zIndex = 1 } }) {
 | 
			
		||||
                    CLAY({ .id = CLAY_ID("FloatingContainerInner"), .layout = { .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = {16, 16, 16, 16} }, .backgroundColor = {140,80, 200, 200} }) {
 | 
			
		||||
                        CLAY_TEXT(CLAY_STRING("I'm an inline floating container."), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255,255,255,255} }));
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ Clay_RenderCommandArray CreateLayout(void) {
 | 
			
		|||
                    .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
 | 
			
		||||
                    .offset = { .y = -(scrollData.scrollPosition->y / scrollData.contentDimensions.height) * scrollData.scrollContainerDimensions.height },
 | 
			
		||||
                    .zIndex = 1,
 | 
			
		||||
                    .parentId = Clay_GetElementId(CLAY_STRING("MainContent")).id,
 | 
			
		||||
                    .parentId = 55,
 | 
			
		||||
                    .attachPoints = { .element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_TOP }
 | 
			
		||||
                }
 | 
			
		||||
            }) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -235,7 +235,7 @@ Clay_RenderCommandArray ClayVideoDemo_CreateLayout(ClayVideoDemo_Data *data) {
 | 
			
		|||
 | 
			
		||||
            CLAY({ .id = CLAY_ID("MainContent"),
 | 
			
		||||
                .backgroundColor = contentBackgroundColor,
 | 
			
		||||
                .scroll = { .vertical = true },
 | 
			
		||||
                .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
 | 
			
		||||
                .layout = {
 | 
			
		||||
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
 | 
			
		||||
                    .childGap = 16,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue