mirror of
https://github.com/nicbarker/clay.git
synced 2025-05-05 01:48:03 +00:00
Switch .scroll usage to .clip
This commit is contained in:
parent
f9ebeced60
commit
fd281f4f86
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_GetScrollContainerData](#clay_getscrollcontainerdata)
|
||||||
- [Clay_GetElementId](#clay_getelementid)
|
- [Clay_GetElementId](#clay_getelementid)
|
||||||
- [Element Macros](#element-macros)
|
- [Element Macros](#element-macros)
|
||||||
- [CLAY](#clay-1)
|
- [CLAY](#clay)
|
||||||
- [CLAY_ID](#clay_id)
|
- [CLAY_ID](#clay_id)
|
||||||
- [CLAY_IDI](#clay_idi)
|
- [CLAY_IDI](#clay_idi)
|
||||||
- [CLAY_LAYOUT](#clay_layout)
|
- [Data Structures & Defs](#data-structures--definitions)
|
||||||
- [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)
|
|
||||||
- [Clay_String](#clay_string)
|
- [Clay_String](#clay_string)
|
||||||
- [Clay_ElementId](#clay_elementid)
|
- [Clay_ElementId](#clay_elementid)
|
||||||
- [Clay_RenderCommandArray](#clay_rendercommandarray)
|
- [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
|
### 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
|
```C
|
||||||
Clay_Vector2 mousePosition = { x, y };
|
Clay_Vector2 mousePosition = { x, y };
|
||||||
// Reminder: Clay_SetPointerState must be called before Clay_UpdateScrollContainers otherwise it will have no effect
|
// 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
|
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)
|
### 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
|
### Clay_BeginLayout
|
||||||
|
|
||||||
`void 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 },
|
.layout = { .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 },
|
||||||
.backgroundColor = { 200, 200, 100, 255 },
|
.backgroundColor = { 200, 200, 100, 255 },
|
||||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||||
.scroll = { .vertical = true }
|
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
|
||||||
}) {
|
}) {
|
||||||
// child elements
|
// child elements
|
||||||
}
|
}
|
||||||
@ -1034,7 +1057,7 @@ typedef struct {
|
|||||||
Clay_ImageElementConfig image;
|
Clay_ImageElementConfig image;
|
||||||
Clay_FloatingElementConfig floating;
|
Clay_FloatingElementConfig floating;
|
||||||
Clay_CustomElementConfig custom;
|
Clay_CustomElementConfig custom;
|
||||||
Clay_ScrollElementConfig scroll;
|
Clay_ClipElementConfig clip;
|
||||||
Clay_BorderElementConfig border;
|
Clay_BorderElementConfig border;
|
||||||
void *userData;
|
void *userData;
|
||||||
} Clay_ElementDeclaration;
|
} 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({
|
CLAY({
|
||||||
.backgroundColor = { 200, 200, 100, 255 },
|
.backgroundColor = { 200, 200, 100, 255 },
|
||||||
.cornerRadius = CLAY_CORNER_RADIUS(10)
|
.cornerRadius = CLAY_CORNER_RADIUS(10)
|
||||||
CLAY_SCROLL({ .vertical = true })
|
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() }
|
||||||
) {
|
) {
|
||||||
// child elements
|
// child elements
|
||||||
}
|
}
|
||||||
@ -1312,22 +1337,22 @@ Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Clay_ScrollElementConfig
|
### Clay_ClipElementConfig
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
`CLAY({ .scroll = { ...scroll config } }) {}`
|
`CLAY({ .clip = { ...clip config } }) {}`
|
||||||
|
|
||||||
**Notes**
|
**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`.
|
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)**
|
**Struct Definition (Pseudocode)**
|
||||||
|
|
||||||
```C
|
```C
|
||||||
Clay_ScrollElementConfig {
|
Clay_ClipElementConfig {
|
||||||
bool horizontal;
|
bool horizontal;
|
||||||
bool vertical;
|
bool vertical;
|
||||||
};
|
};
|
||||||
@ -1337,30 +1362,30 @@ Clay_ScrollElementConfig {
|
|||||||
|
|
||||||
**`.horizontal`** - `bool`
|
**`.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`
|
**`.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**
|
**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_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)
|
- `commandType = CLAY_RENDER_COMMAND_TYPE_SCISSOR_END`, which disables the previous rectangle mask and is **not** subject to [culling](#visibility-culling)
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
```C
|
```C
|
||||||
CLAY({ .scroll = { .vertical = true } }) {
|
CLAY({ .clip = { .vertical = true } }) {
|
||||||
// Create child content with a fixed height of 5000
|
// Create child content with a fixed height of 5000
|
||||||
CLAY({ .id = CLAY_ID("ScrollInner"), .layout = { .sizing = { .height = CLAY_SIZING_FIXED(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.
|
// The outer dimensions of the inner scroll container content, including the padding of the parent scroll container.
|
||||||
Clay_Dimensions contentDimensions;
|
Clay_Dimensions contentDimensions;
|
||||||
// The config that was originally passed to the scroll element.
|
// 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.
|
// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
|
||||||
bool found;
|
bool found;
|
||||||
} Clay_ScrollContainerData;
|
} 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -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("TopBorder5"), .layout = topBorderConfig, .backgroundColor = COLOR_TOP_BORDER_1 }) {}
|
||||||
CLAY({ .id = CLAY_ID("OuterScrollContainer"),
|
CLAY({ .id = CLAY_ID("OuterScrollContainer"),
|
||||||
.layout = { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM },
|
.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 }
|
.border = { .width = { .betweenChildren = 2 }, .color = COLOR_RED }
|
||||||
}) {
|
}) {
|
||||||
if (mobileScreen) {
|
if (mobileScreen) {
|
||||||
|
@ -127,7 +127,7 @@ Clay_RenderCommandArray CreateLayout(void) {
|
|||||||
.attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
|
.attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
|
||||||
.offset = { .y = -(scrollData.scrollPosition->y / scrollData.contentDimensions.height) * scrollData.scrollContainerDimensions.height },
|
.offset = { .y = -(scrollData.scrollPosition->y / scrollData.contentDimensions.height) * scrollData.scrollContainerDimensions.height },
|
||||||
.zIndex = 1,
|
.zIndex = 1,
|
||||||
.parentId = Clay_GetElementId(CLAY_STRING("MainContent")).id,
|
.parentId = 55,
|
||||||
.attachPoints = { .element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_TOP }
|
.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"),
|
CLAY({ .id = CLAY_ID("MainContent"),
|
||||||
.backgroundColor = contentBackgroundColor,
|
.backgroundColor = contentBackgroundColor,
|
||||||
.scroll = { .vertical = true },
|
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
|
||||||
.layout = {
|
.layout = {
|
||||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||||
.childGap = 16,
|
.childGap = 16,
|
||||||
|
Loading…
Reference in New Issue
Block a user