Compare commits

...

7 commits

Author SHA1 Message Date
fgungor 1d64bd094b
Merge aa525c10b6 into fd97d8179e 2025-10-26 11:00:38 -07:00
Daniel Mayovskiy fd97d8179e
[Renderers/termbox] fixed horizontal text culling bug (#525)
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Has been cancelled
Odin Bindings Update / check_changes (push) Has been cancelled
Odin Bindings Update / build (macos-latest) (push) Has been cancelled
Odin Bindings Update / build (ubuntu-latest) (push) Has been cancelled
Odin Bindings Update / commit (push) Has been cancelled
2025-10-23 12:58:39 +11:00
Daniel Mayovskiy 7216815536
Fixed termbox2 demo build, added scroll functionality (#523) 2025-10-23 12:57:11 +11:00
Thomas Anderson 83129995f7
[Examples/official-website] updated paths in build.sh 2025-10-23 12:56:20 +11:00
fgungor aa525c10b6
Merge branch 'main' into clay_is_clipped 2025-09-20 01:55:24 +02:00
Fatih Gungor 80eb444863 fix: build (do not use auto) 2025-09-13 16:23:38 +02:00
Fatih Gungor 3fcf08d0ac feat: check whether current open element is clipped 2025-09-13 16:11:06 +02:00
5 changed files with 74 additions and 8 deletions

45
clay.h
View file

@ -890,6 +890,8 @@ CLAY_DLL_EXPORT Clay_ElementIdArray Clay_GetPointerOverIds(void);
// An imperative function that returns true if the pointer position provided by Clay_SetPointerState is within the element with the provided ID's bounding box. // An imperative function that returns true if the pointer position provided by Clay_SetPointerState is within the element with the provided ID's bounding box.
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings. // This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
CLAY_DLL_EXPORT Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id); CLAY_DLL_EXPORT Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id);
// Returns whether the element with the provided ID is clipped by a clip region
CLAY_DLL_EXPORT bool Clay_IsClipped(Clay_ElementId id);
// Binds a callback function that Clay will call to determine the dimensions of a given string slice. // Binds a callback function that Clay will call to determine the dimensions of a given string slice.
// - measureTextFunction is a user provided function that adheres to the interface Clay_Dimensions (Clay_StringSlice text, Clay_TextElementConfig *config, void *userData); // - measureTextFunction is a user provided function that adheres to the interface Clay_Dimensions (Clay_StringSlice text, Clay_TextElementConfig *config, void *userData);
// - userData is a pointer that will be transparently passed through when the measureTextFunction is called. // - userData is a pointer that will be transparently passed through when the measureTextFunction is called.
@ -1716,6 +1718,28 @@ bool Clay__PointIsInsideRect(Clay_Vector2 point, Clay_BoundingBox rect) {
return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height; return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height;
} }
bool Clay__RectIsOutsideRect(Clay_BoundingBox rectA, Clay_BoundingBox rectB) {
// Compute the edges of both rectangles
const float leftA = rectA.x;
const float rightA = rectA.x + rectA.width;
const float topA = rectA.y;
const float bottomA = rectA.y + rectA.height;
const float leftB = rectB.x;
const float rightB = rectB.x + rectB.width;
const float topB = rectB.y;
const float bottomB = rectB.y + rectB.height;
// Check if 'a' is completely outside 'b'
if (rightA <= leftB) return true; // a is left of b
if (leftA >= rightB) return true; // a is right of b
if (bottomA <= topB) return true; // a is above b
if (topA >= bottomB) return true; // a is below b
// Otherwise, they overlap (so not completely outside)
return false;
}
Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement) { Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement) {
Clay_Context* context = Clay_GetCurrentContext(); Clay_Context* context = Clay_GetCurrentContext();
if (context->layoutElementsHashMapInternal.length == context->layoutElementsHashMapInternal.capacity - 1) { if (context->layoutElementsHashMapInternal.length == context->layoutElementsHashMapInternal.capacity - 1) {
@ -4340,6 +4364,27 @@ Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
return CLAY__INIT(Clay_ScrollContainerData) CLAY__DEFAULT_STRUCT; return CLAY__INIT(Clay_ScrollContainerData) CLAY__DEFAULT_STRUCT;
} }
CLAY_WASM_EXPORT("Clay_GetScrollContainerData")
bool Clay_IsClipped(Clay_ElementId id) {
Clay_Context* context = Clay_GetCurrentContext();
if (context->openClipElementStack.length == 0) {
return false;
}
const int32_t clipElementId =
Clay__int32_tArray_GetValue(&context->openClipElementStack, context->openClipElementStack.length - 1);
if (clipElementId == 0)
return false;
const Clay_LayoutElementHashMapItem *clipItem = Clay__GetHashMapItem(clipElementId);
const Clay_ElementData elementData = Clay_GetElementData(id);
if (Clay__RectIsOutsideRect(elementData.boundingBox, clipItem->boundingBox)) {
return true;
}
return false;
}
CLAY_WASM_EXPORT("Clay_GetElementData") CLAY_WASM_EXPORT("Clay_GetElementData")
Clay_ElementData Clay_GetElementData(Clay_ElementId id){ Clay_ElementData Clay_GetElementData(Clay_ElementId id){
Clay_LayoutElementHashMapItem * item = Clay__GetHashMapItem(id.id); Clay_LayoutElementHashMapItem * item = Clay__GetHashMapItem(id.id);

View file

@ -15,5 +15,5 @@ mkdir -p build/clay \
-Wl,--initial-memory=6553600 \ -Wl,--initial-memory=6553600 \
-o build/clay/index.wasm \ -o build/clay/index.wasm \
main.c \ main.c \
&& cp index.html build/clay/index.html && cp -r fonts/ build/clay/fonts \ && cp index.html build/index.html && cp -r fonts/ build/clay/fonts \
&& cp index.html build/clay/index.html && cp -r images/ build/clay/images && cp -r images/ build/clay/images

View file

@ -8,7 +8,7 @@ set(FETCHCONTENT_QUIET FALSE)
FetchContent_Declare( FetchContent_Declare(
termbox2 termbox2
GIT_REPOSITORY "https://github.com/termbox/termbox2.git" GIT_REPOSITORY "https://github.com/termbox/termbox2.git"
GIT_TAG "9c9281a9a4c971a2be57f8645e828ec99fd555e8" GIT_TAG "ffd159c2a6106dd5eef338a6702ad15d4d4aa809"
GIT_PROGRESS TRUE GIT_PROGRESS TRUE
GIT_SHALLOW TRUE GIT_SHALLOW TRUE
) )
@ -17,7 +17,7 @@ FetchContent_MakeAvailable(termbox2)
FetchContent_Declare( FetchContent_Declare(
stb stb
GIT_REPOSITORY "https://github.com/nothings/stb.git" GIT_REPOSITORY "https://github.com/nothings/stb.git"
GIT_TAG "f58f558c120e9b32c217290b80bad1a0729fbb2c" GIT_TAG "fede005abaf93d9d7f3a679d1999b2db341b360f"
GIT_PROGRESS TRUE GIT_PROGRESS TRUE
GIT_SHALLOW TRUE GIT_SHALLOW TRUE
) )

View file

@ -90,7 +90,7 @@ void component_text_pair(const char *key, const char *value)
void component_termbox_settings(void) void component_termbox_settings(void)
{ {
CLAY_AUTO_ID({ CLAY(CLAY_ID("Termbox Settings"), {
.floating = { .floating = {
.attachTo = CLAY_ATTACH_TO_PARENT, .attachTo = CLAY_ATTACH_TO_PARENT,
.zIndex = 1, .zIndex = 1,
@ -509,13 +509,18 @@ Clay_RenderCommandArray CreateLayout(clay_tb_image *image1, clay_tb_image *image
{ {
Clay_BeginLayout(); Clay_BeginLayout();
CLAY_AUTO_ID({ CLAY_AUTO_ID({
.clip = {
.vertical = false,
.horizontal = true,
.childOffset = Clay_GetScrollOffset(),
},
.layout = { .layout = {
.sizing = { .sizing = {
.width = CLAY_SIZING_GROW(), .width = CLAY_SIZING_GROW(),
.height = CLAY_SIZING_GROW() .height = CLAY_SIZING_GROW()
}, },
.childAlignment = { .childAlignment = {
.x = CLAY_ALIGN_X_CENTER, .x = CLAY_ALIGN_X_LEFT,
.y = CLAY_ALIGN_Y_CENTER .y = CLAY_ALIGN_Y_CENTER
}, },
.childGap = 64 .childGap = 64
@ -714,12 +719,12 @@ void handle_termbox_events(void)
break; break;
} }
case TB_KEY_MOUSE_WHEEL_UP: { case TB_KEY_MOUSE_WHEEL_UP: {
Clay_Vector2 scrollDelta = { 0, 1 * Clay_Termbox_Cell_Height() }; Clay_Vector2 scrollDelta = { 0.5 * Clay_Termbox_Cell_Width(), 0 };
Clay_UpdateScrollContainers(false, scrollDelta, 1); Clay_UpdateScrollContainers(false, scrollDelta, 1);
break; break;
} }
case TB_KEY_MOUSE_WHEEL_DOWN: { case TB_KEY_MOUSE_WHEEL_DOWN: {
Clay_Vector2 scrollDelta = { 0, -1 * Clay_Termbox_Cell_Height() }; Clay_Vector2 scrollDelta = { -0.5 * Clay_Termbox_Cell_Width(), 0 };
Clay_UpdateScrollContainers(false, scrollDelta, 1); Clay_UpdateScrollContainers(false, scrollDelta, 1);
break; break;
} }

View file

@ -3,6 +3,8 @@
Copyright (c) 2025 Mivirl Copyright (c) 2025 Mivirl
altered by Godje (Sep 2025)
This software is provided 'as-is', without any express or implied warranty. This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the In no event will the authors be held liable for any damages arising from the
use of this software. use of this software.
@ -1616,6 +1618,20 @@ void Clay_Termbox_Render(Clay_RenderCommandArray commands)
Clay_StringSlice *text = &render_data.stringContents; Clay_StringSlice *text = &render_data.stringContents;
int32_t i = 0; int32_t i = 0;
// culling text characters that are outside of the layout
int h_clip = 0 - cell_box.x;
while(h_clip > 0 && i < text->length){
uint32_t ch = ' ';
int codepoint_length = tb_utf8_char_to_unicode(&ch, text->chars + i);
if (0 > codepoint_length) {
clay_tb_assert(false, "Invalid utf8");
}
i += codepoint_length;
h_clip -= 1;
}
// printing the rest of the characters
for (int y = box_begin_y; y < box_end_y; ++y) { for (int y = box_begin_y; y < box_end_y; ++y) {
for (int x = box_begin_x; x < box_end_x;) { for (int x = box_begin_x; x < box_end_x;) {
uint32_t ch = ' '; uint32_t ch = ' ';