mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-20 13:18:03 +00:00
Implement scrollbar example
This commit is contained in:
parent
09fc980434
commit
fd86e2fe73
120
clay.h
120
clay.h
@ -785,51 +785,41 @@ typedef struct
|
|||||||
uint32_t elementId;
|
uint32_t elementId;
|
||||||
bool openThisFrame;
|
bool openThisFrame;
|
||||||
bool pointerScrollActive;
|
bool pointerScrollActive;
|
||||||
} Clay__ScrollContainerData;
|
} Clay__ScrollContainerDataInternal;
|
||||||
|
|
||||||
Clay__ScrollContainerData CLAY__SCROLL_CONTAINER_DEFAULT = (Clay__ScrollContainerData) {};
|
Clay__ScrollContainerDataInternal CLAY__SCROLL_CONTAINER_DEFAULT = (Clay__ScrollContainerDataInternal) {};
|
||||||
|
|
||||||
// __GENERATED__ template array_define TYPE=Clay__ScrollContainerData NAME=Clay__ScrollContainerDataArray
|
// __GENERATED__ template define,array_add,array_get TYPE=Clay__ScrollContainerDataInternal NAME=Clay__ScrollContainerDataInternalArray DEFAULT_VALUE=&CLAY__SCROLL_CONTAINER_DEFAULT
|
||||||
#pragma region generated
|
#pragma region generated
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
Clay__ScrollContainerData *internalArray;
|
Clay__ScrollContainerDataInternal *internalArray;
|
||||||
} Clay__ScrollContainerDataArray;
|
} Clay__ScrollContainerDataInternalArray;
|
||||||
|
|
||||||
Clay__ScrollContainerDataArray Clay__ScrollContainerDataArray_Allocate_Arena(uint32_t capacity, Clay_Arena *arena) {
|
Clay__ScrollContainerDataInternalArray Clay__ScrollContainerDataInternalArray_Allocate_Arena(uint32_t capacity, Clay_Arena *arena) {
|
||||||
return (Clay__ScrollContainerDataArray){.capacity = capacity, .length = 0, .internalArray = (Clay__ScrollContainerData *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__ScrollContainerData), CLAY__ALIGNMENT(Clay__ScrollContainerData), arena)};
|
return (Clay__ScrollContainerDataInternalArray){.capacity = capacity, .length = 0, .internalArray = (Clay__ScrollContainerDataInternal *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__ScrollContainerDataInternal), CLAY__ALIGNMENT(Clay__ScrollContainerDataInternal), arena)};
|
||||||
}
|
}
|
||||||
#pragma endregion
|
Clay__ScrollContainerDataInternal *Clay__ScrollContainerDataInternalArray_Add(Clay__ScrollContainerDataInternalArray *array, Clay__ScrollContainerDataInternal item) {
|
||||||
// __GENERATED__ template
|
|
||||||
|
|
||||||
// __GENERATED__ template array_add TYPE=Clay__ScrollContainerData NAME=Clay__ScrollContainerDataArray DEFAULT_VALUE=&CLAY__SCROLL_CONTAINER_DEFAULT
|
|
||||||
#pragma region generated
|
|
||||||
Clay__ScrollContainerData *Clay__ScrollContainerDataArray_Add(Clay__ScrollContainerDataArray *array, Clay__ScrollContainerData item) {
|
|
||||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||||
array->internalArray[array->length++] = item;
|
array->internalArray[array->length++] = item;
|
||||||
return &array->internalArray[array->length - 1];
|
return &array->internalArray[array->length - 1];
|
||||||
}
|
}
|
||||||
return &CLAY__SCROLL_CONTAINER_DEFAULT;
|
return &CLAY__SCROLL_CONTAINER_DEFAULT;
|
||||||
}
|
}
|
||||||
#pragma endregion
|
Clay__ScrollContainerDataInternal *Clay__ScrollContainerDataInternalArray_Get(Clay__ScrollContainerDataInternalArray *array, int index) {
|
||||||
// __GENERATED__ template
|
|
||||||
|
|
||||||
// __GENERATED__ template array_get TYPE=Clay__ScrollContainerData NAME=Clay__ScrollContainerDataArray DEFAULT_VALUE=&CLAY__SCROLL_CONTAINER_DEFAULT
|
|
||||||
#pragma region generated
|
|
||||||
Clay__ScrollContainerData *Clay__ScrollContainerDataArray_Get(Clay__ScrollContainerDataArray *array, int index) {
|
|
||||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__SCROLL_CONTAINER_DEFAULT;
|
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__SCROLL_CONTAINER_DEFAULT;
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
// __GENERATED__ template
|
// __GENERATED__ template
|
||||||
|
|
||||||
// __GENERATED__ template array_remove_swapback TYPE=Clay__ScrollContainerData NAME=Clay__ScrollContainerDataArray DEFAULT_VALUE=CLAY__SCROLL_CONTAINER_DEFAULT
|
// __GENERATED__ template array_remove_swapback TYPE=Clay__ScrollContainerDataInternal NAME=Clay__ScrollContainerDataInternalArray DEFAULT_VALUE=CLAY__SCROLL_CONTAINER_DEFAULT
|
||||||
#pragma region generated
|
#pragma region generated
|
||||||
Clay__ScrollContainerData Clay__ScrollContainerDataArray_RemoveSwapback(Clay__ScrollContainerDataArray *array, int index) {
|
Clay__ScrollContainerDataInternal Clay__ScrollContainerDataInternalArray_RemoveSwapback(Clay__ScrollContainerDataInternalArray *array, int index) {
|
||||||
if (Clay__Array_RangeCheck(index, array->length)) {
|
if (Clay__Array_RangeCheck(index, array->length)) {
|
||||||
array->length--;
|
array->length--;
|
||||||
Clay__ScrollContainerData removed = array->internalArray[index];
|
Clay__ScrollContainerDataInternal removed = array->internalArray[index];
|
||||||
array->internalArray[index] = array->internalArray[array->length];
|
array->internalArray[index] = array->internalArray[array->length];
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
@ -1068,7 +1058,7 @@ Clay__MeasureTextCacheItemArray Clay__measureTextHashMapInternal;
|
|||||||
Clay__int32_tArray Clay__measureTextHashMap;
|
Clay__int32_tArray Clay__measureTextHashMap;
|
||||||
Clay__int32_tArray Clay__openClipElementStack;
|
Clay__int32_tArray Clay__openClipElementStack;
|
||||||
Clay__int32_tArray Clay__pointerOverIds;
|
Clay__int32_tArray Clay__pointerOverIds;
|
||||||
Clay__ScrollContainerDataArray Clay__scrollContainerOffsets;
|
Clay__ScrollContainerDataInternalArray Clay__scrollContainerDatas;
|
||||||
Clay__BoolArray Clay__treeNodeVisited;
|
Clay__BoolArray Clay__treeNodeVisited;
|
||||||
|
|
||||||
#if CLAY_WASM
|
#if CLAY_WASM
|
||||||
@ -1272,9 +1262,9 @@ void Clay__OpenCustomElement(uint32_t id, Clay_LayoutConfig *layoutConfig, Clay_
|
|||||||
Clay_LayoutElement *Clay__OpenScrollElement(uint32_t id, Clay_LayoutConfig *layoutConfig, Clay_ScrollContainerElementConfig *scrollConfig) {
|
Clay_LayoutElement *Clay__OpenScrollElement(uint32_t id, Clay_LayoutConfig *layoutConfig, Clay_ScrollContainerElementConfig *scrollConfig) {
|
||||||
Clay_LayoutElement *scrollElement = Clay__OpenElement(id, CLAY__LAYOUT_ELEMENT_TYPE_SCROLL_CONTAINER, layoutConfig, (Clay_ElementConfigUnion){ .scrollElementConfig = scrollConfig });
|
Clay_LayoutElement *scrollElement = Clay__OpenElement(id, CLAY__LAYOUT_ELEMENT_TYPE_SCROLL_CONTAINER, layoutConfig, (Clay_ElementConfigUnion){ .scrollElementConfig = scrollConfig });
|
||||||
Clay__int32_tArray_Add(&Clay__openClipElementStack, (int)scrollElement->id);
|
Clay__int32_tArray_Add(&Clay__openClipElementStack, (int)scrollElement->id);
|
||||||
Clay__ScrollContainerData *scrollOffset = CLAY__NULL;
|
Clay__ScrollContainerDataInternal *scrollOffset = CLAY__NULL;
|
||||||
for (int i = 0; i < Clay__scrollContainerOffsets.length; i++) {
|
for (int i = 0; i < Clay__scrollContainerDatas.length; i++) {
|
||||||
Clay__ScrollContainerData *mapping = Clay__ScrollContainerDataArray_Get(&Clay__scrollContainerOffsets, i);
|
Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
|
||||||
if (id == mapping->elementId) {
|
if (id == mapping->elementId) {
|
||||||
scrollOffset = mapping;
|
scrollOffset = mapping;
|
||||||
scrollOffset->layoutElement = scrollElement;
|
scrollOffset->layoutElement = scrollElement;
|
||||||
@ -1282,7 +1272,7 @@ Clay_LayoutElement *Clay__OpenScrollElement(uint32_t id, Clay_LayoutConfig *layo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!scrollOffset) {
|
if (!scrollOffset) {
|
||||||
Clay__ScrollContainerDataArray_Add(&Clay__scrollContainerOffsets, (Clay__ScrollContainerData){.elementId = id, .layoutElement = scrollElement, .scrollOrigin = {-1,-1}, .openThisFrame = true});
|
Clay__ScrollContainerDataInternalArray_Add(&Clay__scrollContainerDatas, (Clay__ScrollContainerDataInternal){.elementId = id, .layoutElement = scrollElement, .scrollOrigin = {-1,-1}, .openThisFrame = true});
|
||||||
}
|
}
|
||||||
return scrollElement;
|
return scrollElement;
|
||||||
}
|
}
|
||||||
@ -1427,7 +1417,7 @@ void Clay__InitializeEphemeralMemory(Clay_Arena *arena) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay__InitializePersistentMemory(Clay_Arena *arena) {
|
void Clay__InitializePersistentMemory(Clay_Arena *arena) {
|
||||||
Clay__scrollContainerOffsets = Clay__ScrollContainerDataArray_Allocate_Arena(10, arena);
|
Clay__scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(10, arena);
|
||||||
Clay__layoutElementsHashMapInternal = Clay__LayoutElementHashMapItemArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__layoutElementsHashMapInternal = Clay__LayoutElementHashMapItemArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
Clay__layoutElementsHashMap = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__layoutElementsHashMap = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
Clay__measureTextHashMapInternal = Clay__MeasureTextCacheItemArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__measureTextHashMapInternal = Clay__MeasureTextCacheItemArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
@ -1504,6 +1494,21 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
|||||||
Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&Clay__layoutElementTreeRoots, rootIndex);
|
Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&Clay__layoutElementTreeRoots, rootIndex);
|
||||||
Clay_LayoutElement *rootElement = root->layoutElement;
|
Clay_LayoutElement *rootElement = root->layoutElement;
|
||||||
Clay__LayoutElementPointerArray_Add(&bfsBuffer, root->layoutElement);
|
Clay__LayoutElementPointerArray_Add(&bfsBuffer, root->layoutElement);
|
||||||
|
|
||||||
|
// Size floating containers to their parents
|
||||||
|
if (rootElement->elementType == CLAY__LAYOUT_ELEMENT_TYPE_FLOATING_CONTAINER) {
|
||||||
|
Clay_LayoutElementHashMapItem *parentItem = Clay__GetHashMapItem(rootElement->elementConfig.floatingElementConfig->parentId);
|
||||||
|
if (parentItem) {
|
||||||
|
Clay_LayoutElement *parentLayoutElement = parentItem->layoutElement;
|
||||||
|
if (rootElement->layoutConfig->sizing.width.type == CLAY__SIZING_TYPE_GROW) {
|
||||||
|
rootElement->dimensions.width = parentLayoutElement->dimensions.width - (float)parentLayoutElement->layoutConfig->padding.x * 2;
|
||||||
|
}
|
||||||
|
if (rootElement->layoutConfig->sizing.height.type == CLAY__SIZING_TYPE_GROW) {
|
||||||
|
rootElement->dimensions.height = parentLayoutElement->dimensions.height - (float)parentLayoutElement->layoutConfig->padding.x * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rootElement->dimensions.width = CLAY__MIN(CLAY__MAX(rootElement->dimensions.width, rootElement->layoutConfig->sizing.width.sizeMinMax.min), rootElement->layoutConfig->sizing.width.sizeMinMax.max);
|
rootElement->dimensions.width = CLAY__MIN(CLAY__MAX(rootElement->dimensions.width, rootElement->layoutConfig->sizing.width.sizeMinMax.min), rootElement->layoutConfig->sizing.width.sizeMinMax.max);
|
||||||
rootElement->dimensions.height = CLAY__MIN(CLAY__MAX(rootElement->dimensions.height, rootElement->layoutConfig->sizing.height.sizeMinMax.min), rootElement->layoutConfig->sizing.height.sizeMinMax.max);
|
rootElement->dimensions.height = CLAY__MIN(CLAY__MAX(rootElement->dimensions.height, rootElement->layoutConfig->sizing.height.sizeMinMax.min), rootElement->layoutConfig->sizing.height.sizeMinMax.max);
|
||||||
|
|
||||||
@ -1609,13 +1614,6 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay__CalculateFinalLayout(int screenWidth, int screenHeight) {
|
void Clay__CalculateFinalLayout(int screenWidth, int screenHeight) {
|
||||||
// layoutElementsHashMap has non-linear access pattern so just resetting .length won't zero out the data.
|
|
||||||
// Need to zero it all out here
|
|
||||||
for (int i = 0; i < Clay__layoutElementsHashMap.capacity; ++i) {
|
|
||||||
Clay__layoutElementsHashMap.internalArray[i] = -1;
|
|
||||||
}
|
|
||||||
Clay__layoutElementsHashMapInternal.length = 0;
|
|
||||||
|
|
||||||
// Calculate sizing along the X axis
|
// Calculate sizing along the X axis
|
||||||
Clay__SizeContainersAlongAxis(true);
|
Clay__SizeContainersAlongAxis(true);
|
||||||
|
|
||||||
@ -1759,6 +1757,13 @@ void Clay__CalculateFinalLayout(int screenWidth, int screenHeight) {
|
|||||||
// Calculate sizing along the Y axis
|
// Calculate sizing along the Y axis
|
||||||
Clay__SizeContainersAlongAxis(false);
|
Clay__SizeContainersAlongAxis(false);
|
||||||
|
|
||||||
|
// layoutElementsHashMap has non-linear access pattern so just resetting .length won't zero out the data.
|
||||||
|
// Need to zero it all out here
|
||||||
|
for (int i = 0; i < Clay__layoutElementsHashMap.capacity; ++i) {
|
||||||
|
Clay__layoutElementsHashMap.internalArray[i] = -1;
|
||||||
|
}
|
||||||
|
Clay__layoutElementsHashMapInternal.length = 0;
|
||||||
|
|
||||||
// Calculate final positions and generate render commands
|
// Calculate final positions and generate render commands
|
||||||
Clay__renderCommands.length = 0;
|
Clay__renderCommands.length = 0;
|
||||||
dfsBuffer.length = 0;
|
dfsBuffer.length = 0;
|
||||||
@ -1855,7 +1860,7 @@ void Clay__CalculateFinalLayout(int screenWidth, int screenHeight) {
|
|||||||
currentElementBoundingBox.height += expand.height * 2;
|
currentElementBoundingBox.height += expand.height * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clay__ScrollContainerData *scrollContainerData = CLAY__NULL;
|
Clay__ScrollContainerDataInternal *scrollContainerData = CLAY__NULL;
|
||||||
// Apply scroll offsets to container
|
// Apply scroll offsets to container
|
||||||
if (currentElement->elementType == CLAY__LAYOUT_ELEMENT_TYPE_SCROLL_CONTAINER) {
|
if (currentElement->elementType == CLAY__LAYOUT_ELEMENT_TYPE_SCROLL_CONTAINER) {
|
||||||
Clay_RenderCommandArray_Add(&Clay__renderCommands, (Clay_RenderCommand) {
|
Clay_RenderCommandArray_Add(&Clay__renderCommands, (Clay_RenderCommand) {
|
||||||
@ -1865,8 +1870,8 @@ void Clay__CalculateFinalLayout(int screenWidth, int screenHeight) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 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
|
// 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 (int i = 0; i < Clay__scrollContainerOffsets.length; i++) {
|
for (int i = 0; i < Clay__scrollContainerDatas.length; i++) {
|
||||||
Clay__ScrollContainerData *mapping = Clay__ScrollContainerDataArray_Get(&Clay__scrollContainerOffsets, i);
|
Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
|
||||||
if (mapping->layoutElement == currentElement) {
|
if (mapping->layoutElement == currentElement) {
|
||||||
scrollContainerData = mapping;
|
scrollContainerData = mapping;
|
||||||
mapping->boundingBox = currentElementBoundingBox;
|
mapping->boundingBox = currentElementBoundingBox;
|
||||||
@ -2144,18 +2149,18 @@ CLAY_WASM_EXPORT("Clay_UpdateScrollContainers")
|
|||||||
void Clay_UpdateScrollContainers(bool isPointerActive, Clay_Vector2 scrollDelta, float deltaTime) {
|
void Clay_UpdateScrollContainers(bool isPointerActive, Clay_Vector2 scrollDelta, float deltaTime) {
|
||||||
// Don't apply scroll events to ancestors of the inner element
|
// Don't apply scroll events to ancestors of the inner element
|
||||||
int32_t highestPriorityElementIndex = -1;
|
int32_t highestPriorityElementIndex = -1;
|
||||||
Clay__ScrollContainerData *highestPriorityScrollData = CLAY__NULL;
|
Clay__ScrollContainerDataInternal *highestPriorityScrollData = CLAY__NULL;
|
||||||
for (int i = 0; i < Clay__scrollContainerOffsets.length; i++) {
|
for (int i = 0; i < Clay__scrollContainerDatas.length; i++) {
|
||||||
Clay__ScrollContainerData *scrollData = Clay__ScrollContainerDataArray_Get(&Clay__scrollContainerOffsets, i);
|
Clay__ScrollContainerDataInternal *scrollData = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
|
||||||
if (!scrollData->openThisFrame) {
|
if (!scrollData->openThisFrame) {
|
||||||
Clay__ScrollContainerDataArray_RemoveSwapback(&Clay__scrollContainerOffsets, i);
|
Clay__ScrollContainerDataInternalArray_RemoveSwapback(&Clay__scrollContainerDatas, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
scrollData->openThisFrame = false;
|
scrollData->openThisFrame = false;
|
||||||
Clay_LayoutElementHashMapItem *hashMapItem = Clay__GetHashMapItem(scrollData->elementId);
|
Clay_LayoutElementHashMapItem *hashMapItem = Clay__GetHashMapItem(scrollData->elementId);
|
||||||
// Element isn't rendered this frame but scroll offset has been retained
|
// Element isn't rendered this frame but scroll offset has been retained
|
||||||
if (!hashMapItem) {
|
if (!hashMapItem) {
|
||||||
Clay__ScrollContainerDataArray_RemoveSwapback(&Clay__scrollContainerOffsets, i);
|
Clay__ScrollContainerDataInternalArray_RemoveSwapback(&Clay__scrollContainerDatas, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2279,6 +2284,35 @@ bool Clay_PointerOver(uint32_t id) { // TODO return priority for separating mult
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
|
||||||
|
// Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
|
||||||
|
Clay_Vector2 *scrollPosition;
|
||||||
|
Clay_Dimensions scrollContainerDimensions;
|
||||||
|
Clay_Dimensions contentDimensions;
|
||||||
|
Clay_ScrollContainerElementConfig config;
|
||||||
|
// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
|
||||||
|
bool found;
|
||||||
|
} Clay_ScrollContainerData;
|
||||||
|
|
||||||
|
CLAY_WASM_EXPORT("Clay_GetScrollContainerData")
|
||||||
|
Clay_ScrollContainerData Clay_GetScrollContainerData(uint32_t id) {
|
||||||
|
for (int i = 0; i < Clay__scrollContainerDatas.length; ++i) {
|
||||||
|
Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
|
||||||
|
if (scrollContainerData->elementId == id) {
|
||||||
|
return (Clay_ScrollContainerData) {
|
||||||
|
.scrollPosition = &scrollContainerData->scrollPosition,
|
||||||
|
.scrollContainerDimensions = (Clay_Dimensions) { scrollContainerData->boundingBox.width, scrollContainerData->boundingBox.height },
|
||||||
|
.contentDimensions = scrollContainerData->contentSize,
|
||||||
|
.config = *scrollContainerData->layoutElement->elementConfig.scrollElementConfig,
|
||||||
|
.found = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (Clay_ScrollContainerData){};
|
||||||
|
}
|
||||||
|
|
||||||
#endif //CLAY_IMPLEMENTATION
|
#endif //CLAY_IMPLEMENTATION
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -93,7 +93,7 @@ Clay_RenderCommandArray CreateLayout() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
//
|
|
||||||
CLAY_FLOATING_CONTAINER(CLAY_ID("Blob4Floating"), &CLAY_LAYOUT_DEFAULT, CLAY_FLOATING_CONFIG(.zIndex = 1, .parentId = CLAY_ID("SidebarBlob4")), {
|
CLAY_FLOATING_CONTAINER(CLAY_ID("Blob4Floating"), &CLAY_LAYOUT_DEFAULT, CLAY_FLOATING_CONFIG(.zIndex = 1, .parentId = CLAY_ID("SidebarBlob4")), {
|
||||||
CLAY_SCROLL_CONTAINER(CLAY_ID("ScrollContainer"), CLAY_LAYOUT(.sizing = { .height = CLAY_SIZING_FIXED(200) }, .childGap = 2), CLAY_SCROLL_CONFIG(.vertical = true), {
|
CLAY_SCROLL_CONTAINER(CLAY_ID("ScrollContainer"), CLAY_LAYOUT(.sizing = { .height = CLAY_SIZING_FIXED(200) }, .childGap = 2), CLAY_SCROLL_CONFIG(.vertical = true), {
|
||||||
CLAY_FLOATING_CONTAINER(CLAY_ID("FloatingContainer"), CLAY_LAYOUT(), CLAY_FLOATING_CONFIG(.zIndex = 1), {
|
CLAY_FLOATING_CONTAINER(CLAY_ID("FloatingContainer"), CLAY_LAYOUT(), CLAY_FLOATING_CONFIG(.zIndex = 1), {
|
||||||
@ -108,11 +108,22 @@ Clay_RenderCommandArray CreateLayout() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Clay_ScrollContainerData scrollData = Clay_GetScrollContainerData(CLAY_ID("MainContent"));
|
||||||
|
CLAY_FLOATING_CONTAINER(CLAY_ID("ScrollBar"), &CLAY_LAYOUT_DEFAULT, CLAY_FLOATING_CONFIG(.offset = { .y = -(scrollData.scrollPosition->y / scrollData.contentDimensions.height) * scrollData.scrollContainerDimensions.height }, .zIndex = 1, .parentId = CLAY_ID("MainContent"), .attachment = {.element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_TOP}), {
|
||||||
|
CLAY_RECTANGLE(CLAY_ID("ScrollBarButton"), CLAY_LAYOUT(.sizing = {CLAY_SIZING_FIXED(12), CLAY_SIZING_FIXED((scrollData.scrollContainerDimensions.height / scrollData.contentDimensions.height) * scrollData.scrollContainerDimensions.height)}), CLAY_RECTANGLE_CONFIG(.cornerRadius = 6, .color = Clay_PointerOver(CLAY_ID("ScrollBar")) ? (Clay_Color){100, 100, 140, 150} : (Clay_Color){120, 120, 160, 150}), {});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return Clay_EndLayout(GetScreenWidth(), GetScreenHeight());
|
return Clay_EndLayout(GetScreenWidth(), GetScreenHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
int display_size_changed = 0;
|
typedef struct
|
||||||
|
{
|
||||||
|
Clay_Vector2 clickOrigin;
|
||||||
|
Clay_Vector2 positionOrigin;
|
||||||
|
bool mouseDown;
|
||||||
|
} ScrollbarData;
|
||||||
|
|
||||||
|
ScrollbarData scrollbarData = (ScrollbarData) {};
|
||||||
|
|
||||||
void UpdateDrawFrame(void)
|
void UpdateDrawFrame(void)
|
||||||
{
|
{
|
||||||
@ -122,8 +133,34 @@ void UpdateDrawFrame(void)
|
|||||||
mouseWheelY = mouseWheelDelta.y;
|
mouseWheelY = mouseWheelDelta.y;
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Handle scroll containers
|
// Handle scroll containers
|
||||||
Clay_SetPointerPosition(RAYLIB_VECTOR2_TO_CLAY_VECTOR2(GetMousePosition()));
|
Clay_Vector2 mousePosition = RAYLIB_VECTOR2_TO_CLAY_VECTOR2(GetMousePosition());
|
||||||
Clay_UpdateScrollContainers(IsMouseButtonDown(0), (Clay_Vector2) {mouseWheelX, mouseWheelY}, GetFrameTime());
|
Clay_SetPointerPosition(mousePosition);
|
||||||
|
if (!IsMouseButtonDown(0)) {
|
||||||
|
scrollbarData.mouseDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsMouseButtonDown(0) && !scrollbarData.mouseDown && Clay_PointerOver(CLAY_ID("ScrollBar"))) {
|
||||||
|
Clay_ScrollContainerData scrollContainerData = Clay_GetScrollContainerData(CLAY_ID("MainContent"));
|
||||||
|
scrollbarData.clickOrigin = mousePosition;
|
||||||
|
scrollbarData.positionOrigin = *scrollContainerData.scrollPosition;
|
||||||
|
scrollbarData.mouseDown = true;
|
||||||
|
} else if (scrollbarData.mouseDown) {
|
||||||
|
Clay_ScrollContainerData scrollContainerData = Clay_GetScrollContainerData(CLAY_ID("MainContent"));
|
||||||
|
if (scrollContainerData.contentDimensions.height > 0) {
|
||||||
|
Clay_Vector2 ratio = (Clay_Vector2) {
|
||||||
|
scrollContainerData.contentDimensions.width / scrollContainerData.scrollContainerDimensions.width,
|
||||||
|
scrollContainerData.contentDimensions.height / scrollContainerData.scrollContainerDimensions.height,
|
||||||
|
};
|
||||||
|
if (scrollContainerData.config.vertical) {
|
||||||
|
scrollContainerData.scrollPosition->y = scrollbarData.positionOrigin.y + (scrollbarData.clickOrigin.y - mousePosition.y) * ratio.y;
|
||||||
|
}
|
||||||
|
if (scrollContainerData.config.horizontal) {
|
||||||
|
scrollContainerData.scrollPosition->x = scrollbarData.positionOrigin.x + (scrollbarData.clickOrigin.x - mousePosition.x) * ratio.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Clay_UpdateScrollContainers(false, (Clay_Vector2) {mouseWheelX, mouseWheelY}, GetFrameTime());
|
||||||
// Generate the auto layout for rendering
|
// Generate the auto layout for rendering
|
||||||
double currentTime = GetTime();
|
double currentTime = GetTime();
|
||||||
Clay_RenderCommandArray renderCommands = CreateLayout();
|
Clay_RenderCommandArray renderCommands = CreateLayout();
|
||||||
|
Loading…
Reference in New Issue
Block a user