mirror of
https://github.com/nicbarker/clay.git
synced 2025-05-12 13:28:07 +00:00
Compare commits
31 Commits
6b81e4822f
...
f02af6b61b
Author | SHA1 | Date | |
---|---|---|---|
|
f02af6b61b | ||
|
9e13524b52 | ||
|
01d3ab127f | ||
|
326325ffaf | ||
|
e8025cc254 | ||
|
8e7e30dda6 | ||
|
9d3fba39be | ||
|
4961f2153e | ||
|
a093730da2 | ||
|
cd82ce6fcf | ||
|
814c9392c6 | ||
|
338852b3ce | ||
|
f1d8a53a32 | ||
|
afba9f0de6 | ||
|
3a4455aa83 | ||
|
208c7cb3a0 | ||
|
c2c445e455 | ||
|
9e7595b873 | ||
|
32d1a31dfe | ||
|
b2b50724e2 | ||
|
12b3280dab | ||
|
d81c9e1de5 | ||
|
7142a427bb | ||
|
d7ee448ed5 | ||
|
7ecd5adbce | ||
|
2fcb4cc76e | ||
|
44fb89c8b6 | ||
|
bc9ef8b02d | ||
|
0989aeee06 | ||
|
e11a394c25 | ||
|
670f707997 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ cmake-build-release/
|
||||
.idea/
|
||||
node_modules/
|
||||
*.dSYM
|
||||
.vs/
|
@ -3,15 +3,18 @@ project(clay)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
add_subdirectory("examples/cpp-project-example")
|
||||
if(APPLE)
|
||||
enable_language(OBJC)
|
||||
endif()
|
||||
|
||||
# Don't try to compile C99 projects using MSVC
|
||||
if(NOT MSVC)
|
||||
add_subdirectory("examples/raylib-sidebar-scrolling-container")
|
||||
add_subdirectory("examples/cpp-project-example")
|
||||
add_subdirectory("examples/raylib-multi-context")
|
||||
add_subdirectory("examples/raylib-sidebar-scrolling-container")
|
||||
# add_subdirectory("examples/cairo-pdf-rendering") Some issue with github actions populating cairo, disable for now
|
||||
if(NOT MSVC)
|
||||
add_subdirectory("examples/clay-official-website")
|
||||
add_subdirectory("examples/SDL3-simple-demo")
|
||||
endif()
|
||||
add_subdirectory("examples/introducing-clay-video-demo")
|
||||
add_subdirectory("examples/SDL2-video-demo")
|
||||
add_subdirectory("examples/GLFW-video-demo")
|
||||
endif()
|
||||
|
184
README.md
184
README.md
@ -81,7 +81,7 @@ const Clay_Color COLOR_ORANGE = (Clay_Color) {225, 138, 50, 255};
|
||||
|
||||
// Layout config is just a struct that can be declared statically, or inline
|
||||
Clay_LayoutConfig sidebarItemLayout = (Clay_LayoutConfig) {
|
||||
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(50) },
|
||||
.sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) },
|
||||
};
|
||||
|
||||
// Re-useable components are just normal functions
|
||||
@ -94,12 +94,12 @@ Clay_RenderCommandArray CreateLayout() {
|
||||
Clay_BeginLayout();
|
||||
|
||||
// An example of laying out a UI with a fixed width sidebar and flexible width main content
|
||||
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(), CLAY_SIZING_GROW()}, .padding = {16, 16}, .childGap = 16 }), CLAY_RECTANGLE({ .color = {250,250,255,255} })) {
|
||||
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }), CLAY_RECTANGLE({ .color = {250,250,255,255} })) {
|
||||
CLAY(CLAY_ID("SideBar"),
|
||||
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW() }, .padding = {16, 16}, .childGap = 16 }),
|
||||
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16 }),
|
||||
CLAY_RECTANGLE({ .color = COLOR_LIGHT })
|
||||
) {
|
||||
CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW() }, .padding = {16, 16}, .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay - UI Library"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255, 255, 255, 255} }));
|
||||
}
|
||||
@ -110,7 +110,7 @@ Clay_RenderCommandArray CreateLayout() {
|
||||
}
|
||||
}
|
||||
|
||||
CLAY(CLAY_ID("MainContent"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }}), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {}
|
||||
CLAY(CLAY_ID("MainContent"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }}), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {}
|
||||
}
|
||||
// ...
|
||||
});
|
||||
@ -151,6 +151,65 @@ In summary, the general order of steps is:
|
||||
|
||||
For help starting out or to discuss clay, considering joining [the discord server.](https://discord.gg/b4FTWkxdvT)
|
||||
|
||||
## Summary
|
||||
|
||||
- [High Level Documentation](#high-level-documentation)
|
||||
- [Building UI Hierarchies](#building-ui-hierarchies)
|
||||
- [Configuring Layout and Styling UI Elements](#configuring-layout-and-styling-ui-elements)
|
||||
- [Element IDs](#element-ids)
|
||||
- [Mouse, Touch and Pointer Interactions](#mouse-touch-and-pointer-interactions)
|
||||
- [Scrolling Elements](#scrolling-elements)
|
||||
- [Floating Elements](#floating-elements-absolute-positioning)
|
||||
- [Custom Elements](#laying-out-your-own-custom-elements)
|
||||
- [Retained Mode Rendering](#retained-mode-rendering)
|
||||
- [Visibility Culling](#visibility-culling)
|
||||
- [Preprocessor Directives](#preprocessor-directives)
|
||||
- [Bindings](#bindings-for-non-c)
|
||||
- [Debug Tools](#debug-tools)
|
||||
- [API](#api)
|
||||
- [Naming Conventions](#naming-conventions)
|
||||
- [Public Functions](#public-functions)
|
||||
- [Lifecycle](#lifecycle-for-public-functions)
|
||||
- [Clay_MinMemorySize](#clay_minmemorysize)
|
||||
- [Clay_CreateArenaWithCapacityAndMemory](#clay_createarenawithcapacityandmemory)
|
||||
- [Clay_SetMeasureTextFunction](#clay_setmeasuretextfunction)
|
||||
- [Clay_ResetMeasureTextCache](#clau_resetmeasuretextcache)
|
||||
- [Clay_SetMaxElementCount](clay_setmaxelementcount)
|
||||
- [Clay_SetMaxMeasureTextCacheWordCount](#clay_setmaxmeasuretextcachewordcount)
|
||||
- [Clay_Initialize](#clay_initialize)
|
||||
- [Clay_GetCurrentContext](#clay_getcurrentcontext)
|
||||
- [Clay_SetCurrentContext](#clay_setcurrentcontext)
|
||||
- [Clay_SetLayoutDimensions](#clay_setlayoutdimensions)
|
||||
- [Clay_SetPointerState](#clay_setpointerstate)
|
||||
- [Clay_UpdateScrollContainers](#clay_updatescrollcontainers)
|
||||
- [Clay_BeginLayout](#clay_beginlayout)
|
||||
- [Clay_EndLayout](#clay_endlayout)
|
||||
- [Clay_Hovered](#clay_hovered)
|
||||
- [Clay_OnHover](#clay_onhover)
|
||||
- [Clay_PointerOver](#clay_pointerover)
|
||||
- [Clay_GetScrollContainerData](#clay_getscrollcontainerdata)
|
||||
- [Clay_GetElementId](#clay_getelementid)
|
||||
- [Element Macros](#element-macros)
|
||||
- [CLAY](#clay-1)
|
||||
- [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)
|
||||
- [Clay_String](#clay_string)
|
||||
- [Clay_ElementId](#clay_elementid)
|
||||
- [Clay_RenderCommandArray](#clay_rendercommandarray)
|
||||
- [Clay_RenderCommand](#clay_rendercommand)
|
||||
- [Clay_ScrollContainerData](#clay_scrollcontainerdata)
|
||||
- [Clay_ErrorHandler](#clay_errorhandler)
|
||||
- [Clay_ErrorData](#clay_errordata)
|
||||
|
||||
## High Level Documentation
|
||||
|
||||
### Building UI Hierarchies
|
||||
@ -159,7 +218,7 @@ Clay UIs are built using the C macro `CLAY()`. This macro creates a new empty el
|
||||
Child elements are added by opening a block: `{}` after calling the `CLAY()` macro (exactly like you would with an `if` statement or `for` loop), and declaring child components inside the braces.
|
||||
```C
|
||||
// Parent element with 8px of padding
|
||||
CLAY(CLAY_LAYOUT({ .padding = 8 })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8) })) {
|
||||
// Child element 1
|
||||
CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 }));
|
||||
// Child element 2 with red background
|
||||
@ -174,7 +233,7 @@ However, unlike HTML and other declarative DSLs, these macros are just C. As a r
|
||||
// Re-usable "components" are just functions that declare more UI
|
||||
void ButtonComponent(Clay_String buttonText) {
|
||||
// Red box button with 8px of padding
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8 }}), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8)}), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY_TEXT(buttonText, textConfig);
|
||||
}
|
||||
}
|
||||
@ -187,7 +246,7 @@ CLAY(CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
}
|
||||
// Only render this element if we're on a mobile screen
|
||||
if (isMobileScreen) {
|
||||
CLAY() {
|
||||
CLAY(0) {
|
||||
// etc
|
||||
}
|
||||
}
|
||||
@ -200,11 +259,11 @@ CLAY(CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
### Configuring Layout and Styling UI Elements
|
||||
The layout of clay elements is configured with the `CLAY_LAYOUT()` macro.
|
||||
```C
|
||||
CLAY(CLAY_LAYOUT({ .padding = {.x = 8, .y = 8}, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
// Children are 8px inset into parent, and laid out top to bottom
|
||||
}
|
||||
```
|
||||
This macro isn't magic - all it's doing is wrapping the standard designated initializer syntax and adding the result to an internal array. e.g. `(Clay_LayoutConfig) { .padding = { .x = 8, .y = 8 } ...`.
|
||||
This macro isn't magic - all it's doing is wrapping the standard designated initializer syntax and adding the result to an internal array. e.g. `(Clay_LayoutConfig) { .padding = { .left = 8, .right = 8 } ...`.
|
||||
|
||||
See the [Clay_LayoutConfig](#clay_layout) API for the full list of options.
|
||||
|
||||
@ -274,7 +333,7 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerI
|
||||
ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };
|
||||
|
||||
// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8 }}), Clay_OnHover(HandleButtonInteraction, &linkButton)) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8)}), Clay_OnHover(HandleButtonInteraction, &linkButton)) {
|
||||
CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig);
|
||||
}
|
||||
```
|
||||
@ -362,7 +421,7 @@ typedef struct t_CustomElementData {
|
||||
Model myModel = Load3DModel(filePath);
|
||||
CustomElement modelElement = (CustomElement) { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel }
|
||||
// ...
|
||||
CLAY() {
|
||||
CLAY(0) {
|
||||
// This config is type safe and contains the CustomElementData struct
|
||||
CLAY(CLAY_CUSTOM_ELEMENT({ .customData = { .type = CUSTOM_ELEMENT_TYPE_MODEL, .model = myModel } })) {}
|
||||
}
|
||||
@ -425,8 +484,7 @@ Clay is usable out of the box as a `.h` include in both C99 and C++20 with desig
|
||||
There are also supported bindings for other languages, including:
|
||||
|
||||
- [Odin Bindings](https://github.com/nicbarker/clay/tree/main/bindings/odin)
|
||||
|
||||
Unfortunately clay does **not** support Microsoft C11 or C17 via MSVC at this time.
|
||||
- [Rust Bindings](https://github.com/clay-ui-rs/clay)
|
||||
|
||||
### Debug Tools
|
||||
|
||||
@ -490,18 +548,24 @@ render(renderCommands2);
|
||||
**Each Frame**
|
||||
`Clay_SetLayoutDimensions` -> `Clay_SetPointerState` -> `Clay_UpdateScrollContainers` -> `Clay_BeginLayout` -> `CLAY() etc...` -> `Clay_EndLayout`
|
||||
|
||||
---
|
||||
|
||||
### Clay_MinMemorySize
|
||||
|
||||
`uint32_t Clay_MinMemorySize()`
|
||||
|
||||
Returns the minimum amount of memory **in bytes** that clay needs to accomodate the current [CLAY_MAX_ELEMENT_COUNT](#preprocessor-directives).
|
||||
|
||||
---
|
||||
|
||||
### Clay_CreateArenaWithCapacityAndMemory
|
||||
|
||||
`Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset)`
|
||||
|
||||
Creates a `Clay_Arena` struct with the given capacity and base memory pointer, which can be passed to [Clay_Initialize](#clay_initialize).
|
||||
|
||||
---
|
||||
|
||||
### Clay_SetMeasureTextFunction
|
||||
|
||||
`void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config))`
|
||||
@ -512,6 +576,16 @@ Takes a pointer to a function that can be used to measure the `width, height` di
|
||||
|
||||
**Note 2: It is essential that this function is as fast as possible.** For text heavy use-cases this function is called many times, and despite the fact that clay caches text measurements internally, it can easily become the dominant overall layout cost if the provided function is slow. **This is on the hot path!**
|
||||
|
||||
---
|
||||
|
||||
### Clay_ResetMeasureTextCache
|
||||
|
||||
`void Clay_ResetMeasureTextCache(void)`
|
||||
|
||||
Clay caches measurements from the provided MeasureTextFunction, and this will be sufficient for the majority of use-cases. However, if the measurements can depend on external factors that clay does not know about, like DPI changes, then the cached values may be incorrect. When one of these external factors changes, Clay_ResetMeasureTextCache can be called to force clay to recalculate all string measurements in the next frame.
|
||||
|
||||
---
|
||||
|
||||
### Clay_SetMaxElementCount
|
||||
|
||||
`void Clay_SetMaxElementCount(uint32_t maxElementCount)`
|
||||
@ -520,6 +594,8 @@ Sets the internal maximum element count that will be used in subsequent [Clay_In
|
||||
|
||||
**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**
|
||||
|
||||
---
|
||||
|
||||
### Clay_SetMaxMeasureTextCacheWordCount
|
||||
|
||||
`void Clay_SetMaxMeasureTextCacheWordCount(uint32_t maxMeasureTextCacheWordCount)`
|
||||
@ -528,6 +604,8 @@ Sets the internal text measurement cache size that will be used in subsequent [C
|
||||
|
||||
**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**
|
||||
|
||||
---
|
||||
|
||||
### Clay_Initialize
|
||||
|
||||
`Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler)`
|
||||
@ -536,30 +614,40 @@ Initializes the internal memory mapping, sets the internal dimensions for layout
|
||||
|
||||
Reference: [Clay_Arena](#clay_createarenawithcapacityandmemory), [Clay_ErrorHandler](#clay_errorhandler), [Clay_SetCurrentContext](#clay_setcurrentcontext)
|
||||
|
||||
---
|
||||
|
||||
### Clay_SetCurrentContext
|
||||
|
||||
`void Clay_SetCurrentContext(Clay_Context* context)`
|
||||
|
||||
Sets the context that subsequent clay commands will operate on. You can get this reference from [Clay_Initialize](#clay_initialize) or [Clay_GetCurrentContext](#clay_getcurrentcontext). See [Running more than one Clay instance](#running-more-than-one-clay-instance).
|
||||
|
||||
---
|
||||
|
||||
### Clay_GetCurrentContext
|
||||
|
||||
`Clay_Context* Clay_GetCurrentContext()`
|
||||
|
||||
Returns the context that clay commands are currently operating on, or null if no context has been set. See [Running more than one Clay instance](#running-more-than-one-clay-instance).
|
||||
|
||||
---
|
||||
|
||||
### Clay_SetLayoutDimensions
|
||||
|
||||
`void Clay_SetLayoutDimensions(Clay_Dimensions dimensions)`
|
||||
|
||||
Sets the internal layout dimensions. Cheap enough to be called every frame with your screen dimensions to automatically respond to window resizing, etc.
|
||||
|
||||
---
|
||||
|
||||
### Clay_SetPointerState
|
||||
|
||||
`void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown)`
|
||||
|
||||
Sets the internal pointer position and state (i.e. current mouse / touch position) and recalculates overlap info, which is used for mouseover / click calculation (via [Clay_PointerOver](#clay_pointerover) and updating scroll containers with [Clay_UpdateScrollContainers](#clay_updatescrollcontainers). **isPointerDown should represent the current state this frame, e.g. it should be `true` for the entire duration the left mouse button is held down.** Clay has internal handling for detecting click / touch start & end.
|
||||
|
||||
---
|
||||
|
||||
### Clay_UpdateScrollContainers
|
||||
|
||||
`void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime)`
|
||||
@ -570,24 +658,32 @@ Touch / drag scrolling only occurs if the `enableDragScrolling` parameter is `tr
|
||||
|
||||
`deltaTime` is the time **in seconds** since the last frame (e.g. 0.016 is **16 milliseconds**), and is used to normalize & smooth scrolling across different refresh rates.
|
||||
|
||||
---
|
||||
|
||||
### Clay_BeginLayout
|
||||
|
||||
`void Clay_BeginLayout()`
|
||||
|
||||
Prepares clay to calculate a new layout. Called each frame / layout **before** any of the [Element Macros](#element-macros).
|
||||
|
||||
---
|
||||
|
||||
### Clay_EndLayout
|
||||
|
||||
`Clay_RenderCommandArray Clay_EndLayout()`
|
||||
|
||||
Ends declaration of element macros and calculates the results of the current layout. Renders a [Clay_RenderCommandArray](#clay_rendercommandarray) containing the results of the layout calculation.
|
||||
|
||||
---
|
||||
|
||||
### Clay_Hovered
|
||||
|
||||
`bool Clay_Hovered()`
|
||||
|
||||
Called **during** layout declaration, and returns `true` if the pointer position previously set with `Clay_SetPointerState` is inside the bounding box of the currently open element. Note: this is based on the element's position from the **last** frame.
|
||||
|
||||
---
|
||||
|
||||
### Clay_OnHover
|
||||
|
||||
`void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData), intptr_t userData)`
|
||||
@ -607,11 +703,13 @@ void HandleButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerD
|
||||
ButtonData linkButton = (ButtonData) { .link = "https://github.com/nicbarker/clay" };
|
||||
|
||||
// HandleButtonInteraction will be called for each frame the mouse / pointer / touch is inside the button boundaries
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8 }}), Clay_OnHover(HandleButtonInteraction, &buttonData)) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(8)}), Clay_OnHover(HandleButtonInteraction, &buttonData)) {
|
||||
CLAY_TEXT(CLAY_STRING("Button"), &headerTextConfig);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Clay_PointerOver
|
||||
|
||||
`bool Clay_PointerOver(Clay_ElementId id)`
|
||||
@ -624,6 +722,8 @@ Returns `true` if the pointer position previously set with `Clay_SetPointerState
|
||||
|
||||
Returns [Clay_ScrollContainerData](#clay_scrollcontainerdata) for the scroll container matching the provided ID. This function allows imperative manipulation of scroll position, allowing you to build things such as scroll bars, buttons that "jump" to somewhere in a scroll container, etc.
|
||||
|
||||
---
|
||||
|
||||
### Clay_GetElementId
|
||||
|
||||
`Clay_ElementId Clay_GetElementId(Clay_String idString)`
|
||||
@ -644,11 +744,12 @@ Returns a [Clay_ElementId](#clay_elementid) for the provided id string, used for
|
||||
**Notes**
|
||||
|
||||
**CLAY** opens a generic empty container, that is configurable and supports nested children.
|
||||
**CLAY** requires at least 1 parameter, so if you want to create an element without any configuration, use `CLAY(0)`.
|
||||
|
||||
**Examples**
|
||||
```C
|
||||
// Define an element with 16px of x and y padding
|
||||
CLAY(CLAY_ID("Outer"), CLAY_LAYOUT({ .padding = {16, 16} })) {
|
||||
CLAY(CLAY_ID("Outer"), CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16) })) {
|
||||
// A nested child element
|
||||
CLAY(CLAY_ID("SideBar"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 })) {
|
||||
// Children laid out top to bottom with a 16 px gap between them
|
||||
@ -664,6 +765,8 @@ CLAY(CLAY_ID("Outer"), CLAY_LAYOUT({ .padding = {16, 16} })) {
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### CLAY_ID
|
||||
|
||||
**Usage**
|
||||
@ -686,7 +789,7 @@ To regenerate the same ID outside of layout declaration when using utility funct
|
||||
// Tag a button with the Id "Button"
|
||||
CLAY(
|
||||
CLAY_ID("Button"),
|
||||
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW() }, .padding = {16, 16}, .childGap = 16) })
|
||||
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16) })
|
||||
) {
|
||||
// ...children
|
||||
}
|
||||
@ -698,12 +801,16 @@ if (buttonIsHovered && leftMouseButtonPressed) {
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### CLAY_IDI()
|
||||
|
||||
`Clay_ElementId CLAY_IDI(char *label, int index)`
|
||||
|
||||
An offset version of [CLAY_ID](#clay_id). Generates a [Clay_ElementId](#clay_elementid) string id from the provided `char *label`, combined with the `int index`. Used for generating ids for sequential elements (such as in a `for` loop) without having to construct dynamic strings at runtime.
|
||||
|
||||
---
|
||||
|
||||
### CLAY_LAYOUT
|
||||
|
||||
**Usage**
|
||||
@ -725,7 +832,7 @@ An offset version of [CLAY_ID](#clay_id). Generates a [Clay_ElementId](#clay_ele
|
||||
Clay_LayoutConfig {
|
||||
Clay_LayoutDirection layoutDirection = CLAY_LEFT_TO_RIGHT (default) | CLAY_TOP_TO_BOTTOM;
|
||||
Clay_Padding padding {
|
||||
float x; float y;
|
||||
u16 left; u16 right; u16 top; u16 bottom;
|
||||
};
|
||||
uint16_t childGap;
|
||||
Clay_ChildAlignment childAlignment {
|
||||
@ -733,8 +840,8 @@ Clay_LayoutConfig {
|
||||
.y = CLAY_ALIGN_Y_TOP (default) | CLAY_ALIGN_Y_CENTER | CLAY_ALIGN_Y_BOTTOM;
|
||||
};
|
||||
Clay_Sizing sizing { // Recommended to use the provided macros here - see #sizing for more in depth explanation
|
||||
.width = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(width) | CLAY_SIZING_PERCENT(float percent)
|
||||
.height = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(height) | CLAY_SIZING_PERCENT(float percent)
|
||||
.width = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float width) | CLAY_SIZING_PERCENT(float percent)
|
||||
.height = CLAY_SIZING_FIT(float min, float max) (default) | CLAY_SIZING_GROW(float min, float max) | CLAY_SIZING_FIXED(float height) | CLAY_SIZING_PERCENT(float percent)
|
||||
}; // See CLAY_SIZING_GROW() etc for more details
|
||||
};
|
||||
```
|
||||
@ -756,11 +863,11 @@ _Did you know that "left to right" and "top to bottom" both have 13 letters?_
|
||||
|
||||
**`.padding`** - `Clay_Padding`
|
||||
|
||||
`CLAY_LAYOUT({ .padding = { .x = 16, .y = 16 } })`
|
||||
`CLAY_LAYOUT({ .padding = { .left = 16, .right = 16, .top = 8, .bottom = 8 } })`
|
||||
|
||||
Controls horizontal and vertical white-space "padding" around the **outside** of child elements.
|
||||
Controls white-space "padding" around the **outside** of child elements.
|
||||
|
||||
<img width="486" alt="Screenshot 2024-08-22 at 10 50 49 AM" src="https://github.com/user-attachments/assets/9311cf10-b8aa-40fe-922a-5dee3663f1a0">
|
||||
<img width="486" alt="Screenshot 2024-08-22 at 10 50 49 AM" src="https://github.com/user-attachments/assets/b454fa36-92d5-4b1d-bf8b-e4c25428e9de">
|
||||
|
||||
---
|
||||
|
||||
@ -810,11 +917,13 @@ Controls how final width and height of element are calculated. The same configur
|
||||
**Example Usage**
|
||||
|
||||
```C
|
||||
CLAY(CLAY_ID("Button"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW() }, .padding = {16, 16}, .childGap = 16) }) {
|
||||
CLAY(CLAY_ID("Button"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = CLAY_PADDING_ALL(16, .childGap = 16) }) {
|
||||
// Children will be laid out vertically with 16px of padding around and between
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### CLAY_RECTANGLE
|
||||
**Usage**
|
||||
|
||||
@ -896,6 +1005,8 @@ CLAY(
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### CLAY_TEXT
|
||||
**Usage**
|
||||
|
||||
@ -1017,6 +1128,8 @@ Element is subject to [culling](#visibility-culling). Otherwise, multiple `Clay_
|
||||
|
||||
`Clay_RenderCommand.textContent` will be populated with a `Clay_String` _slice_ of the original string passed in (i.e. wrapping doesn't reallocate, it just returns a `Clay_String` pointing to the start of the new line with a `length`)
|
||||
|
||||
---
|
||||
|
||||
### CLAY_IMAGE
|
||||
**Usage**
|
||||
|
||||
@ -1114,6 +1227,8 @@ Image *imageToRender = renderCommand->elementConfig.imageElementConfig->imageDat
|
||||
|
||||
Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand`s with `commandType = CLAY_RENDER_COMMAND_TYPE_IMAGE` will be created. The user will need to access `renderCommand->elementConfig.imageElementConfig->imageData` to retrieve image data referenced during layout creation. It's also up to the user to decide how / if they wish to blend `rectangleElementConfig->color` with the image.
|
||||
|
||||
---
|
||||
|
||||
### CLAY_SCROLL
|
||||
**Usage**
|
||||
|
||||
@ -1173,6 +1288,8 @@ CLAY(CLAY_SCROLL(.vertical = true)) {
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### CLAY_BORDER
|
||||
**Usage**
|
||||
|
||||
@ -1290,6 +1407,8 @@ CLAY(
|
||||
Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_RenderCommand` with `commandType = CLAY_RENDER_COMMAND_TYPE_BORDER` representing the container will be created.
|
||||
Rendering of borders and rounded corners is left up to the user. See the provided [Raylib Renderer](https://github.com/nicbarker/clay/tree/main/renderers/raylib) for examples of how to draw borders using line and curve primitives.
|
||||
|
||||
---
|
||||
|
||||
### CLAY_FLOATING
|
||||
**Usage**
|
||||
|
||||
@ -1467,17 +1586,17 @@ Controls whether pointer events like hover and click should pass through to cont
|
||||
```C
|
||||
// Horizontal container with three option buttons
|
||||
CLAY(CLAY_ID("OptionsList"), CLAY_LAYOUT(.childGap = 16)) {
|
||||
CLAY_RECTANGLE(CLAY_IDI("Option", 1), CLAY_LAYOUT(.padding = {16, 16}), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
|
||||
CLAY_RECTANGLE(CLAY_IDI("Option", 1), CLAY_LAYOUT(.padding = CLAY_PADDING_ALL(16)), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
|
||||
CLAY_TEXT(CLAY_IDI("OptionText", 1), CLAY_STRING("Option 1"), CLAY_TEXT_CONFIG());
|
||||
}
|
||||
CLAY_RECTANGLE(CLAY_IDI("Option", 2), CLAY_LAYOUT(.padding = {16, 16}), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
|
||||
CLAY_RECTANGLE(CLAY_IDI("Option", 2), CLAY_LAYOUT(.padding = CLAY_PADDING_ALL(16)), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
|
||||
CLAY_TEXT(CLAY_IDI("OptionText", 2), CLAY_STRING("Option 2"), CLAY_TEXT_CONFIG());
|
||||
// Floating tooltip will attach above the "Option 2" container and not affect widths or positions of other elements
|
||||
CLAY_FLOATING(CLAY_ID("OptionTooltip"), &CLAY_LAYOUT_DEFAULT, CLAY_FLOATING({ .zIndex = 1, .attachment = { .element = CLAY_ATTACH_POINT_CENTER_BOTTOM, .parent = CLAY_ATTACH_POINT_CENTER_TOP } })) {
|
||||
CLAY_TEXT(CLAY_IDI("OptionTooltipText", 1), CLAY_STRING("Most popular!"), CLAY_TEXT_CONFIG());
|
||||
}
|
||||
}
|
||||
CLAY_RECTANGLE(CLAY_IDI("Option", 3), CLAY_LAYOUT(.padding = {16, 16}), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
|
||||
CLAY_RECTANGLE(CLAY_IDI("Option", 3), CLAY_LAYOUT(.padding = CLAY_PADDING_ALL(16)), CLAY_RECTANGLE(.color = COLOR_BLUE)) {
|
||||
CLAY_TEXT(CLAY_IDI("OptionText", 3), CLAY_STRING("Option 3"), CLAY_TEXT_CONFIG());
|
||||
}
|
||||
}
|
||||
@ -1501,6 +1620,8 @@ When using `.parentId`, the floating container can be declared anywhere after `B
|
||||
|
||||
`CLAY_FLOATING` elements will not generate any render commands.
|
||||
|
||||
---
|
||||
|
||||
### CLAY_CUSTOM_ELEMENT
|
||||
**Usage**
|
||||
|
||||
@ -1627,6 +1748,8 @@ The number of characters in the string, _not including an optional null terminat
|
||||
|
||||
A pointer to the contents of the string. This data is not guaranteed to be null terminated, so if you are passing it to code that expects standard null terminated C strings, you will need to copy the data and append a null terminator.
|
||||
|
||||
---
|
||||
|
||||
### Clay_ElementId
|
||||
|
||||
```C
|
||||
@ -1664,6 +1787,7 @@ If this id was generated using [CLAY_IDI](#clay_idi), `.baseId` is the hash of t
|
||||
|
||||
Stores the original string that was passed in when [CLAY_ID](#clay_id) or [CLAY_IDI](#clay_idi) were called.
|
||||
|
||||
---
|
||||
|
||||
### Clay_RenderCommandArray
|
||||
|
||||
@ -1697,6 +1821,8 @@ Represents the total number of `Clay_RenderCommand` elements stored consecutivel
|
||||
|
||||
An array of [Clay_RenderCommand](#clay_rendercommand)s representing the calculated layout. If there was at least one render command, this array will contain elements from `.internalArray[0]` to `.internalArray[.length - 1]`.
|
||||
|
||||
---
|
||||
|
||||
### Clay_RenderCommand
|
||||
|
||||
```C
|
||||
@ -1763,6 +1889,8 @@ Only used if `.commandType == CLAY_RENDER_COMMAND_TYPE_TEXT`. A `Clay_String` co
|
||||
|
||||
The id that was originally used with the element macro that created this render command. See [CLAY_ID](#clay_id) for details.
|
||||
|
||||
---
|
||||
|
||||
### Clay_ScrollContainerData
|
||||
|
||||
```C
|
||||
@ -1812,6 +1940,8 @@ Dimensions representing the inner width and height of the content _inside_ the s
|
||||
|
||||
The [Clay_ScrollElementConfig](#clay_scroll) for the matching scroll container element.
|
||||
|
||||
---
|
||||
|
||||
### Clay_PointerData
|
||||
|
||||
```C
|
||||
|
@ -2,7 +2,7 @@ cp ../../clay.h clay.c;
|
||||
# Intel Mac
|
||||
clang -c -DCLAY_IMPLEMENTATION -o clay.o -static -target x86_64-apple-darwin clay.c -fPIC && ar r clay-odin/macos/clay.a clay.o;
|
||||
# ARM Mac
|
||||
clang -c -DCLAY_IMPLEMENTATION -o clay.o -static clay.c -fPIC && ar r clay-odin/macos-arm64/clay.a clay.o;
|
||||
clang -c -DCLAY_IMPLEMENTATION -g -o clay.o -static clay.c -fPIC && ar r clay-odin/macos-arm64/clay.a clay.o;
|
||||
# x64 Windows
|
||||
clang -c -DCLAY_IMPLEMENTATION -o clay-odin/windows/clay.lib -target x86_64-pc-windows-msvc -fuse-ld=llvm-lib -static clay.c;
|
||||
# Linux
|
||||
|
@ -22,6 +22,12 @@ String :: struct {
|
||||
chars: [^]c.char,
|
||||
}
|
||||
|
||||
StringSlice :: struct {
|
||||
length: c.int32_t,
|
||||
chars: [^]c.char,
|
||||
baseChars: [^]c.char,
|
||||
}
|
||||
|
||||
Vector2 :: [2]c.float
|
||||
|
||||
Dimensions :: struct {
|
||||
@ -223,8 +229,10 @@ Sizing :: struct {
|
||||
}
|
||||
|
||||
Padding :: struct {
|
||||
x: u16,
|
||||
y: u16,
|
||||
left: u16,
|
||||
right: u16,
|
||||
top: u16,
|
||||
bottom: u16,
|
||||
}
|
||||
|
||||
LayoutDirection :: enum EnumBackingType {
|
||||
@ -303,7 +311,7 @@ foreign Clay {
|
||||
PointerOver :: proc(id: ElementId) -> bool ---
|
||||
GetElementId :: proc(id: String) -> ElementId ---
|
||||
GetScrollContainerData :: proc(id: ElementId) -> ScrollContainerData ---
|
||||
SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: ^String, config: ^TextElementConfig) -> Dimensions) ---
|
||||
SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: StringSlice, config: ^TextElementConfig, userData: uintptr) -> Dimensions, userData: uintptr) ---
|
||||
RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: i32) -> ^RenderCommand ---
|
||||
SetDebugModeEnabled :: proc(enabled: bool) ---
|
||||
}
|
||||
@ -350,6 +358,10 @@ Layout :: proc(config: LayoutConfig) -> TypedConfig {
|
||||
return {type = ElementConfigType.Layout, config = _StoreLayoutConfig(config) }
|
||||
}
|
||||
|
||||
PaddingAll :: proc (padding: u16) -> Padding {
|
||||
return { padding, padding, padding, padding }
|
||||
}
|
||||
|
||||
Rectangle :: proc(config: RectangleElementConfig) -> TypedConfig {
|
||||
return {type = ElementConfigType.Rectangle, config = _StoreRectangleElementConfig(config)}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -60,7 +60,7 @@ headerTextConfig := clay.TextElementConfig {
|
||||
LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Color, text: string, image: ^raylib.Texture2D) {
|
||||
if clay.UI(
|
||||
clay.ID("HeroBlob", index),
|
||||
clay.Layout({sizing = {width = clay.SizingGrow({max = 480})}, padding = clay.Padding{16, 16}, childGap = 16, childAlignment = clay.ChildAlignment{y = .CENTER}}),
|
||||
clay.Layout({sizing = {width = clay.SizingGrow({max = 480})}, padding = clay.PaddingAll(16), childGap = 16, childAlignment = clay.ChildAlignment{y = .CENTER}}),
|
||||
clay.BorderOutsideRadius({2, color}, 10),
|
||||
) {
|
||||
if clay.UI(
|
||||
@ -75,11 +75,11 @@ LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Colo
|
||||
LandingPageDesktop :: proc() {
|
||||
if clay.UI(
|
||||
clay.ID("LandingPage1Desktop"),
|
||||
clay.Layout({sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})}, childAlignment = {y = .CENTER}, padding = {x = 50}}),
|
||||
clay.Layout({sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})}, childAlignment = {y = .CENTER}, padding = {left = 50, right = 50}}),
|
||||
) {
|
||||
if clay.UI(
|
||||
clay.ID("LandingPage1"),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {32, 32}, childGap = 32}),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(32), childGap = 32}),
|
||||
clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}),
|
||||
) {
|
||||
if clay.UI(clay.ID("LeftText"), clay.Layout({sizing = {width = clay.SizingPercent(0.55)}, layoutDirection = .TOP_TO_BOTTOM, childGap = 8})) {
|
||||
@ -115,7 +115,7 @@ LandingPageMobile :: proc() {
|
||||
layoutDirection = .TOP_TO_BOTTOM,
|
||||
sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({min = cast(f32)windowHeight - 70})},
|
||||
childAlignment = {x = .CENTER, y = .CENTER},
|
||||
padding = {16, 32},
|
||||
padding = {16, 16, 32, 32},
|
||||
childGap = 32,
|
||||
},
|
||||
),
|
||||
@ -148,9 +148,9 @@ FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) {
|
||||
textConfig := clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_RED})
|
||||
if clay.UI(
|
||||
clay.ID("HFileBoxOuter"),
|
||||
clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {outerPadding, 32}, childGap = 8}),
|
||||
clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {outerPadding, outerPadding, 32, 32}, childGap = 8}),
|
||||
) {
|
||||
if clay.UI(clay.ID("HFileIncludeOuter"), clay.Layout({padding = {8, 4}}), clay.Rectangle({color = COLOR_RED, cornerRadius = clay.CornerRadiusAll(8)})) {
|
||||
if clay.UI(clay.ID("HFileIncludeOuter"), clay.Layout({padding = {8, 8, 4, 4}}), clay.Rectangle({color = COLOR_RED, cornerRadius = clay.CornerRadiusAll(8)})) {
|
||||
clay.Text("#include clay.h", clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_LIGHT}))
|
||||
}
|
||||
clay.Text("~2000 lines of C99.", textConfig)
|
||||
@ -158,7 +158,7 @@ FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) {
|
||||
}
|
||||
if clay.UI(
|
||||
clay.ID("BringYourOwnRendererOuter"),
|
||||
clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {x = outerPadding, y = 32}, childGap = 8}),
|
||||
clay.Layout({layoutDirection = .TOP_TO_BOTTOM, sizing = {width = widthSizing}, childAlignment = {y = .CENTER}, padding = {outerPadding, outerPadding, 32, 32}, childGap = 8}),
|
||||
) {
|
||||
clay.Text("Renderer agnostic.", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = COLOR_ORANGE}))
|
||||
clay.Text("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML.", textConfig)
|
||||
@ -217,11 +217,11 @@ DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizi
|
||||
DeclarativeSyntaxPageDesktop :: proc() {
|
||||
if clay.UI(
|
||||
clay.ID("SyntaxPageDesktop"),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {x = 50}}),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {left = 50, right = 50}}),
|
||||
) {
|
||||
if clay.UI(
|
||||
clay.ID("SyntaxPage"),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {32, 32}, childGap = 32}),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(32), childGap = 32}),
|
||||
clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}),
|
||||
) {
|
||||
DeclarativeSyntaxPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5))
|
||||
@ -237,7 +237,7 @@ DeclarativeSyntaxPageMobile :: proc() {
|
||||
layoutDirection = .TOP_TO_BOTTOM,
|
||||
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
|
||||
childAlignment = {x = .CENTER, y = .CENTER},
|
||||
padding = {16, 32},
|
||||
padding = {16, 16, 32, 32},
|
||||
childGap = 16,
|
||||
},
|
||||
),
|
||||
@ -277,14 +277,14 @@ HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementCon
|
||||
) {
|
||||
if clay.UI(
|
||||
clay.ID("AnimationDemoContainerLeft"),
|
||||
clay.Layout({sizing = {clay.SizingPercent(0.35 + 0.3 * lerpValue), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {16, 16}}),
|
||||
clay.Layout({sizing = {clay.SizingPercent(0.35 + 0.3 * lerpValue), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(16)}),
|
||||
clay.Rectangle({color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue)}),
|
||||
) {
|
||||
clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT}))
|
||||
}
|
||||
if clay.UI(
|
||||
clay.ID("AnimationDemoContainerRight"),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {16, 16}}),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(16)}),
|
||||
clay.Rectangle({color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue)}),
|
||||
) {
|
||||
clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT}))
|
||||
@ -297,7 +297,7 @@ HighPerformancePageDesktop :: proc(lerpValue: f32) {
|
||||
if clay.UI(
|
||||
clay.ID("PerformanceDesktop"),
|
||||
clay.Layout(
|
||||
{sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {x = 82, y = 32}, childGap = 64},
|
||||
{sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {82, 82, 32, 32}, childGap = 64},
|
||||
),
|
||||
clay.Rectangle({color = COLOR_RED}),
|
||||
) {
|
||||
@ -313,7 +313,7 @@ HighPerformancePageMobile :: proc(lerpValue: f32) {
|
||||
layoutDirection = .TOP_TO_BOTTOM,
|
||||
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
|
||||
childAlignment = {x = .CENTER, y = .CENTER},
|
||||
padding = {x = 16, y = 32},
|
||||
padding = { 16, 16, 32, 32},
|
||||
childGap = 32,
|
||||
},
|
||||
),
|
||||
@ -325,7 +325,7 @@ HighPerformancePageMobile :: proc(lerpValue: f32) {
|
||||
|
||||
RendererButtonActive :: proc(index: i32, text: string) {
|
||||
if clay.UI(
|
||||
clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = {16, 16}}),
|
||||
clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = clay.PaddingAll(16)}),
|
||||
clay.Rectangle({color = COLOR_RED, cornerRadius = clay.CornerRadiusAll(10)}),
|
||||
) {
|
||||
clay.Text(text, clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_LIGHT}))
|
||||
@ -336,7 +336,7 @@ RendererButtonInactive :: proc(index: u32, text: string) {
|
||||
if clay.UI(clay.Layout({}), clay.BorderOutsideRadius({2, COLOR_RED}, 10)) {
|
||||
if clay.UI(
|
||||
clay.ID("RendererButtonInactiveInner", index),
|
||||
clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = {16, 16}}),
|
||||
clay.Layout({sizing = {width = clay.SizingFixed(300)}, padding = clay.PaddingAll(16)}),
|
||||
clay.Rectangle({color = COLOR_LIGHT, cornerRadius = clay.CornerRadiusAll(10)}),
|
||||
) {
|
||||
clay.Text(text, clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_RED}))
|
||||
@ -374,11 +374,11 @@ RendererPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.
|
||||
RendererPageDesktop :: proc() {
|
||||
if clay.UI(
|
||||
clay.ID("RendererPageDesktop"),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {x = 50}}),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})}, childAlignment = {y = .CENTER}, padding = {left = 50, right = 50}}),
|
||||
) {
|
||||
if clay.UI(
|
||||
clay.ID("RendererPage"),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = {32, 32}, childGap = 32}),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingGrow({})}, childAlignment = {y = .CENTER}, padding = clay.PaddingAll(32), childGap = 32}),
|
||||
clay.Border({left = {2, COLOR_RED}, right = {2, COLOR_RED}}),
|
||||
) {
|
||||
RendererPage({fontSize = 52, fontId = FONT_ID_TITLE_52, textColor = COLOR_RED}, clay.SizingPercent(0.5))
|
||||
@ -394,7 +394,7 @@ RendererPageMobile :: proc() {
|
||||
layoutDirection = .TOP_TO_BOTTOM,
|
||||
sizing = {clay.SizingGrow({}), clay.SizingFit({min = cast(f32)windowHeight - 50})},
|
||||
childAlignment = {x = .CENTER, y = .CENTER},
|
||||
padding = {x = 16, y = 32},
|
||||
padding = {16, 16, 32, 32},
|
||||
childGap = 32,
|
||||
},
|
||||
),
|
||||
@ -423,7 +423,7 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
|
||||
) {
|
||||
if clay.UI(
|
||||
clay.ID("Header"),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFixed(50)}, childAlignment = {y = .CENTER}, childGap = 24, padding = {x = 32}}),
|
||||
clay.Layout({sizing = {clay.SizingGrow({}), clay.SizingFixed(50)}, childAlignment = {y = .CENTER}, childGap = 24, padding = {left = 32, right = 32}}),
|
||||
) {
|
||||
clay.Text("Clay", &headerTextConfig)
|
||||
if clay.UI(clay.Layout({sizing = {width = clay.SizingGrow({})}})) {}
|
||||
@ -438,7 +438,7 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) {
|
||||
}
|
||||
if clay.UI(
|
||||
clay.ID("LinkGithubOuter"),
|
||||
clay.Layout({padding = {16, 6}}),
|
||||
clay.Layout({padding = {16, 16, 6, 6}}),
|
||||
clay.BorderOutsideRadius({2, COLOR_RED}, 10),
|
||||
clay.Rectangle({cornerRadius = clay.CornerRadiusAll(10), color = clay.PointerOver(clay.GetElementId(clay.MakeString("LinkGithubOuter"))) ? COLOR_LIGHT_HOVER : COLOR_LIGHT})
|
||||
) {
|
||||
@ -493,8 +493,8 @@ main :: proc() {
|
||||
minMemorySize: u32 = clay.MinMemorySize()
|
||||
memory := make([^]u8, minMemorySize)
|
||||
arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
|
||||
clay.SetMeasureTextFunction(measureText)
|
||||
clay.Initialize(arena, {cast(f32)raylib.GetScreenWidth(), cast(f32)raylib.GetScreenHeight()}, { handler = errorHandler })
|
||||
clay.SetMeasureTextFunction(measureText, 0)
|
||||
|
||||
raylib.SetConfigFlags({.VSYNC_HINT, .WINDOW_RESIZABLE, .WINDOW_HIGHDPI, .MSAA_4X_HINT})
|
||||
raylib.InitWindow(windowWidth, windowHeight, "Raylib Odin Example")
|
||||
|
@ -16,7 +16,7 @@ clayColorToRaylibColor :: proc(color: clay.Color) -> raylib.Color {
|
||||
|
||||
raylibFonts := [10]RaylibFont{}
|
||||
|
||||
measureText :: proc "c" (text: ^clay.String, config: ^clay.TextElementConfig) -> clay.Dimensions {
|
||||
measureText :: proc "c" (text: clay.StringSlice, config: ^clay.TextElementConfig, userData: uintptr) -> clay.Dimensions {
|
||||
// Measure string size for Font
|
||||
textSize: clay.Dimensions = {0, 0}
|
||||
|
||||
|
2
bindings/zig/README
Normal file
2
bindings/zig/README
Normal file
@ -0,0 +1,2 @@
|
||||
https://codeberg.org/Zettexe/clay-zig
|
||||
https://github.com/johan0A/clay-zig-bindings
|
334
clay.h
334
clay.h
@ -1,4 +1,4 @@
|
||||
// VERSION: 0.11
|
||||
// VERSION: 0.12
|
||||
|
||||
/*
|
||||
NOTE: In order to use this library you must define
|
||||
@ -70,15 +70,11 @@
|
||||
|
||||
#define CLAY_CORNER_RADIUS(radius) (CLAY__INIT(Clay_CornerRadius) { radius, radius, radius, radius })
|
||||
|
||||
#define CLAY__STRUCT_1_ARGS(a) a
|
||||
#define CLAY__STRUCT_0_ARGS() CLAY__DEFAULT_STRUCT
|
||||
#define CLAY__STRUCT_OVERRIDE(_0, _1, NAME, ...) NAME
|
||||
#define CLAY_PADDING_ALL(padding) CLAY__CONFIG_WRAPPER(Clay_Padding, { padding, padding, padding, padding })
|
||||
|
||||
#define CLAY__SIZING_FIT_INTERNAL(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = __VA_ARGS__ }, .type = CLAY__SIZING_TYPE_FIT })
|
||||
#define CLAY_SIZING_FIT(...) CLAY__SIZING_FIT_INTERNAL(CLAY__STRUCT_OVERRIDE("empty", ##__VA_ARGS__, CLAY__STRUCT_1_ARGS, CLAY__STRUCT_0_ARGS)(__VA_ARGS__))
|
||||
#define CLAY_SIZING_FIT(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_FIT })
|
||||
|
||||
#define CLAY__SIZING_GROW_INTERNAL(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = __VA_ARGS__ }, .type = CLAY__SIZING_TYPE_GROW })
|
||||
#define CLAY_SIZING_GROW(...) CLAY__SIZING_GROW_INTERNAL(CLAY__STRUCT_OVERRIDE("empty", ##__VA_ARGS__, CLAY__STRUCT_1_ARGS, CLAY__STRUCT_0_ARGS)(__VA_ARGS__))
|
||||
#define CLAY_SIZING_GROW(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_GROW })
|
||||
|
||||
#define CLAY_SIZING_FIXED(fixedSize) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { fixedSize, fixedSize } }, .type = CLAY__SIZING_TYPE_FIXED })
|
||||
|
||||
@ -99,6 +95,8 @@
|
||||
// Note: If an error led you here, it's because CLAY_STRING can only be used with string literals, i.e. CLAY_STRING("SomeString") and not CLAY_STRING(yourString)
|
||||
#define CLAY_STRING(string) (CLAY__INIT(Clay_String) { .length = CLAY__STRING_LENGTH(CLAY__ENSURE_STRING_LITERAL(string)), .chars = (string) })
|
||||
|
||||
#define CLAY_STRING_CONST(string) { .length = CLAY__STRING_LENGTH(CLAY__ENSURE_STRING_LITERAL(string)), .chars = (string) }
|
||||
|
||||
static uint8_t CLAY__ELEMENT_DEFINITION_LATCH;
|
||||
|
||||
// Publicly visible layout element macros -----------------------------------------------------
|
||||
@ -128,7 +126,7 @@ static uint8_t CLAY__ELEMENT_DEFINITION_LATCH;
|
||||
*/
|
||||
#define CLAY(...) \
|
||||
for (\
|
||||
CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElement(), ##__VA_ARGS__, Clay__ElementPostConfiguration(), 0); \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElement(), __VA_ARGS__, Clay__ElementPostConfiguration(), 0); \
|
||||
CLAY__ELEMENT_DEFINITION_LATCH < 1; \
|
||||
++CLAY__ELEMENT_DEFINITION_LATCH, Clay__CloseElement() \
|
||||
)
|
||||
@ -193,6 +191,13 @@ CLAY__TYPEDEF(Clay__StringArray, struct {
|
||||
Clay_String *internalArray;
|
||||
});
|
||||
|
||||
CLAY__TYPEDEF(Clay_StringSlice, struct {
|
||||
int32_t length;
|
||||
const char *chars;
|
||||
// The source string / char* that this slice was derived from
|
||||
const char *baseChars;
|
||||
});
|
||||
|
||||
typedef struct Clay_Context Clay_Context;
|
||||
|
||||
CLAY__TYPEDEF(Clay_Arena, struct {
|
||||
@ -293,8 +298,10 @@ CLAY__TYPEDEF(Clay_Sizing, struct {
|
||||
});
|
||||
|
||||
CLAY__TYPEDEF(Clay_Padding, struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t left;
|
||||
uint16_t right;
|
||||
uint16_t top;
|
||||
uint16_t bottom;
|
||||
});
|
||||
|
||||
CLAY__TYPEDEF(Clay_LayoutConfig, struct {
|
||||
@ -403,14 +410,18 @@ CLAY__TYPEDEF(Clay_Border, struct {
|
||||
Clay_Color color;
|
||||
});
|
||||
|
||||
CLAY__TYPEDEF(Clay_BorderElementConfig, struct {
|
||||
struct Clay_BorderElementConfig {
|
||||
Clay_Border left;
|
||||
Clay_Border right;
|
||||
Clay_Border top;
|
||||
Clay_Border bottom;
|
||||
Clay_Border betweenChildren;
|
||||
Clay_CornerRadius cornerRadius;
|
||||
});
|
||||
#ifdef CLAY_EXTEND_CONFIG_BORDER
|
||||
CLAY_EXTEND_CONFIG_BORDER
|
||||
#endif
|
||||
};
|
||||
CLAY__TYPEDEF(Clay_BorderElementConfig, struct Clay_BorderElementConfig);
|
||||
|
||||
CLAY__TYPEDEF(Clay_ElementConfigUnion, union {
|
||||
Clay_RectangleElementConfig *rectangleElementConfig;
|
||||
@ -439,6 +450,13 @@ CLAY__TYPEDEF(Clay_ScrollContainerData, struct {
|
||||
bool found;
|
||||
});
|
||||
|
||||
CLAY__TYPEDEF(Clay_ElementData, struct
|
||||
{
|
||||
Clay_BoundingBox boundingBox;
|
||||
// Indicates whether an actual Element matched the provided ID or if the default struct was returned.
|
||||
bool found;
|
||||
});
|
||||
|
||||
CLAY__TYPEDEF(Clay_RenderCommandType, CLAY_PACKED_ENUM {
|
||||
CLAY_RENDER_COMMAND_TYPE_NONE,
|
||||
CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
|
||||
@ -511,12 +529,13 @@ void Clay_BeginLayout(void);
|
||||
Clay_RenderCommandArray Clay_EndLayout(void);
|
||||
Clay_ElementId Clay_GetElementId(Clay_String idString);
|
||||
Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index);
|
||||
Clay_ElementData Clay_GetElementData (Clay_ElementId id);
|
||||
bool Clay_Hovered(void);
|
||||
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData), intptr_t userData);
|
||||
bool Clay_PointerOver(Clay_ElementId elementId);
|
||||
Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id);
|
||||
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config));
|
||||
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId));
|
||||
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData), uintptr_t userData);
|
||||
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId, uintptr_t userData), uintptr_t userData);
|
||||
Clay_RenderCommand * Clay_RenderCommandArray_Get(Clay_RenderCommandArray* array, int32_t index);
|
||||
void Clay_SetDebugModeEnabled(bool enabled);
|
||||
bool Clay_IsDebugModeEnabled(void);
|
||||
@ -525,6 +544,7 @@ int32_t Clay_GetMaxElementCount(void);
|
||||
void Clay_SetMaxElementCount(int32_t maxElementCount);
|
||||
int32_t Clay_GetMaxMeasureTextCacheWordCount(void);
|
||||
void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount);
|
||||
void Clay_ResetMeasureTextCache(void);
|
||||
|
||||
// Internal API functions required by macros
|
||||
void Clay__OpenElement(void);
|
||||
@ -583,6 +603,7 @@ CLAY__TYPEDEF(Clay_BooleanWarnings, struct {
|
||||
bool maxElementsExceeded;
|
||||
bool maxRenderCommandsExceeded;
|
||||
bool maxTextMeasureCacheExceeded;
|
||||
bool textMeasurementFunctionNotSet;
|
||||
});
|
||||
|
||||
CLAY__TYPEDEF(Clay__Warning, struct {
|
||||
@ -1213,6 +1234,7 @@ Clay__MeasuredWord *Clay__MeasuredWordArray_Add(Clay__MeasuredWordArray *array,
|
||||
CLAY__TYPEDEF(Clay__MeasureTextCacheItem, struct {
|
||||
Clay_Dimensions unwrappedDimensions;
|
||||
int32_t measuredWordsStartIndex;
|
||||
bool containsNewlines;
|
||||
// Hash map data
|
||||
uint32_t id;
|
||||
int32_t nextIndex;
|
||||
@ -1330,7 +1352,7 @@ CLAY__TYPEDEF(Clay__LayoutElementTreeRoot, struct {
|
||||
|
||||
Clay__LayoutElementTreeRoot CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT = CLAY__DEFAULT_STRUCT;
|
||||
|
||||
// __GENERATED__ template array_define,array_allocate,array_add,array_get TYPE=Clay__LayoutElementTreeRoot NAME=Clay__LayoutElementTreeRootArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT
|
||||
// __GENERATED__ template array_define,array_allocate,array_add,array_get,array_set TYPE=Clay__LayoutElementTreeRoot NAME=Clay__LayoutElementTreeRootArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT
|
||||
#pragma region generated
|
||||
CLAY__TYPEDEF(Clay__LayoutElementTreeRootArray, struct
|
||||
{
|
||||
@ -1351,6 +1373,12 @@ Clay__LayoutElementTreeRoot *Clay__LayoutElementTreeRootArray_Add(Clay__LayoutEl
|
||||
Clay__LayoutElementTreeRoot *Clay__LayoutElementTreeRootArray_Get(Clay__LayoutElementTreeRootArray *array, int32_t index) {
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT;
|
||||
}
|
||||
void Clay__LayoutElementTreeRootArray_Set(Clay__LayoutElementTreeRootArray *array, int32_t index, Clay__LayoutElementTreeRoot value) {
|
||||
if (Clay__Array_RangeCheck(index, array->capacity)) {
|
||||
array->internalArray[index] = value;
|
||||
array->length = index < array->length ? array->length : index + 1;
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
// __GENERATED__ template
|
||||
|
||||
@ -1385,7 +1413,9 @@ struct Clay_Context {
|
||||
bool externalScrollHandlingEnabled;
|
||||
uint32_t debugSelectedElementId;
|
||||
uint32_t generation;
|
||||
uint64_t arenaResetOffset;
|
||||
uintptr_t arenaResetOffset;
|
||||
uintptr_t mesureTextUserData;
|
||||
uintptr_t queryScrollOffsetUserData;
|
||||
Clay_Arena internalArena;
|
||||
// Layout Elements / Render Commands
|
||||
Clay_LayoutElementArray layoutElements;
|
||||
@ -1459,11 +1489,11 @@ Clay_String Clay__WriteStringToCharBuffer(Clay__CharArray *buffer, Clay_String s
|
||||
}
|
||||
|
||||
#ifdef CLAY_WASM
|
||||
__attribute__((import_module("clay"), import_name("measureTextFunction"))) Clay_Dimensions Clay__MeasureText(Clay_String *text, Clay_TextElementConfig *config);
|
||||
__attribute__((import_module("clay"), import_name("queryScrollOffsetFunction"))) Clay_Vector2 Clay__QueryScrollOffset(uint32_t elementId);
|
||||
__attribute__((import_module("clay"), import_name("measureTextFunction"))) Clay_Dimensions Clay__MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData);
|
||||
__attribute__((import_module("clay"), import_name("queryScrollOffsetFunction"))) Clay_Vector2 Clay__QueryScrollOffset(uint32_t elementId, uintptr_t userData);
|
||||
#else
|
||||
Clay_Dimensions (*Clay__MeasureText)(Clay_String *text, Clay_TextElementConfig *config);
|
||||
Clay_Vector2 (*Clay__QueryScrollOffset)(uint32_t elementId);
|
||||
Clay_Dimensions (*Clay__MeasureText)(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData);
|
||||
Clay_Vector2 (*Clay__QueryScrollOffset)(uint32_t elementId, uintptr_t userData);
|
||||
#endif
|
||||
|
||||
Clay_LayoutElement* Clay__GetOpenLayoutElement(void) {
|
||||
@ -1604,11 +1634,14 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
#ifndef CLAY_WASM
|
||||
if (!Clay__MeasureText) {
|
||||
if (!context->booleanWarnings.textMeasurementFunctionNotSet) {
|
||||
context->booleanWarnings.textMeasurementFunctionNotSet = true;
|
||||
context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
|
||||
.errorText = CLAY_STRING("Clay's internal MeasureText function is null. You may have forgotten to call Clay_SetMeasureTextFunction(), or passed a NULL function pointer by mistake."),
|
||||
.userData = context->errorHandler.userData });
|
||||
return NULL;
|
||||
}
|
||||
return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
uint32_t id = Clay__HashTextWithConfig(text, config);
|
||||
@ -1672,9 +1705,10 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
|
||||
int32_t start = 0;
|
||||
int32_t end = 0;
|
||||
float lineWidth = 0;
|
||||
float measuredWidth = 0;
|
||||
float measuredHeight = 0;
|
||||
float spaceWidth = Clay__MeasureText(&CLAY__SPACECHAR, config).width;
|
||||
float spaceWidth = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = 1, .chars = CLAY__SPACECHAR.chars, .baseChars = CLAY__SPACECHAR.chars }, config, context->mesureTextUserData).width;
|
||||
Clay__MeasuredWord tempWord = { .next = -1 };
|
||||
Clay__MeasuredWord *previousWord = &tempWord;
|
||||
while (end < text->length) {
|
||||
@ -1691,31 +1725,35 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
char current = text->chars[end];
|
||||
if (current == ' ' || current == '\n') {
|
||||
int32_t length = end - start;
|
||||
Clay_String word = { .length = length, .chars = &text->chars[start] };
|
||||
Clay_Dimensions dimensions = Clay__MeasureText(&word, config);
|
||||
Clay_Dimensions dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = length, .chars = &text->chars[start], .baseChars = text->chars }, config, context->mesureTextUserData);
|
||||
measuredHeight = CLAY__MAX(measuredHeight, dimensions.height);
|
||||
if (current == ' ') {
|
||||
dimensions.width += spaceWidth;
|
||||
previousWord = Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = length + 1, .width = dimensions.width, .next = -1 }, previousWord);
|
||||
lineWidth += dimensions.width;
|
||||
}
|
||||
if (current == '\n') {
|
||||
if (length > 1) {
|
||||
if (length > 0) {
|
||||
previousWord = Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = length, .width = dimensions.width, .next = -1 }, previousWord);
|
||||
}
|
||||
previousWord = Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = end + 1, .length = 0, .width = 0, .next = -1 }, previousWord);
|
||||
lineWidth += dimensions.width;
|
||||
measuredWidth = CLAY__MAX(lineWidth, measuredWidth);
|
||||
measured->containsNewlines = true;
|
||||
lineWidth = 0;
|
||||
}
|
||||
measuredWidth += dimensions.width;
|
||||
measuredHeight = dimensions.height;
|
||||
start = end + 1;
|
||||
}
|
||||
end++;
|
||||
}
|
||||
if (end - start > 0) {
|
||||
Clay_String lastWord = { .length = end - start, .chars = &text->chars[start] };
|
||||
Clay_Dimensions dimensions = Clay__MeasureText(&lastWord, config);
|
||||
Clay_Dimensions dimensions = Clay__MeasureText(CLAY__INIT(Clay_StringSlice) { .length = end - start, .chars = &text->chars[start], .baseChars = text->chars }, config, context->mesureTextUserData);
|
||||
Clay__AddMeasuredWord(CLAY__INIT(Clay__MeasuredWord) { .startOffset = start, .length = end - start, .width = dimensions.width, .next = -1 }, previousWord);
|
||||
measuredWidth += dimensions.width;
|
||||
measuredHeight = dimensions.height;
|
||||
lineWidth += dimensions.width;
|
||||
measuredHeight = CLAY__MAX(measuredHeight, dimensions.height);
|
||||
}
|
||||
measuredWidth = CLAY__MAX(lineWidth, measuredWidth);
|
||||
|
||||
measured->measuredWordsStartIndex = tempWord.next;
|
||||
measured->unwrappedDimensions.width = measuredWidth;
|
||||
measured->unwrappedDimensions.height = measuredHeight;
|
||||
@ -1871,7 +1909,7 @@ void Clay__ElementPostConfiguration(void) {
|
||||
scrollOffset = Clay__ScrollContainerDataInternalArray_Add(&context->scrollContainerDatas, CLAY__INIT(Clay__ScrollContainerDataInternal){.layoutElement = openLayoutElement, .scrollOrigin = {-1,-1}, .elementId = openLayoutElement->id, .openThisFrame = true});
|
||||
}
|
||||
if (context->externalScrollHandlingEnabled) {
|
||||
scrollOffset->scrollPosition = Clay__QueryScrollOffset(scrollOffset->elementId);
|
||||
scrollOffset->scrollPosition = Clay__QueryScrollOffset(scrollOffset->elementId, context->queryScrollOffsetUserData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1906,18 +1944,18 @@ void Clay__CloseElement(void) {
|
||||
// Attach children to the current open element
|
||||
openLayoutElement->childrenOrTextContent.children.elements = &context->layoutElementChildren.internalArray[context->layoutElementChildren.length];
|
||||
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
|
||||
openLayoutElement->dimensions.width = (float)layoutConfig->padding.x * 2;
|
||||
openLayoutElement->dimensions.width = (float)(layoutConfig->padding.left + layoutConfig->padding.right);
|
||||
for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) {
|
||||
int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
|
||||
Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
|
||||
openLayoutElement->dimensions.width += child->dimensions.width;
|
||||
openLayoutElement->dimensions.height = CLAY__MAX(openLayoutElement->dimensions.height, child->dimensions.height + layoutConfig->padding.y * 2);
|
||||
openLayoutElement->dimensions.height = CLAY__MAX(openLayoutElement->dimensions.height, child->dimensions.height + layoutConfig->padding.top + layoutConfig->padding.bottom);
|
||||
// Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
|
||||
if (!elementHasScrollHorizontal) {
|
||||
openLayoutElement->minDimensions.width += child->minDimensions.width;
|
||||
}
|
||||
if (!elementHasScrollVertical) {
|
||||
openLayoutElement->minDimensions.height = CLAY__MAX(openLayoutElement->minDimensions.height, child->minDimensions.height + layoutConfig->padding.y * 2);
|
||||
openLayoutElement->minDimensions.height = CLAY__MAX(openLayoutElement->minDimensions.height, child->minDimensions.height + layoutConfig->padding.top + layoutConfig->padding.bottom);
|
||||
}
|
||||
Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
|
||||
}
|
||||
@ -1926,18 +1964,18 @@ void Clay__CloseElement(void) {
|
||||
openLayoutElement->minDimensions.width += childGap;
|
||||
}
|
||||
else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
|
||||
openLayoutElement->dimensions.height = (float)layoutConfig->padding.y * 2;
|
||||
openLayoutElement->dimensions.height = (float)(layoutConfig->padding.top + layoutConfig->padding.bottom);
|
||||
for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) {
|
||||
int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
|
||||
Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
|
||||
openLayoutElement->dimensions.height += child->dimensions.height;
|
||||
openLayoutElement->dimensions.width = CLAY__MAX(openLayoutElement->dimensions.width, child->dimensions.width + layoutConfig->padding.x * 2);
|
||||
openLayoutElement->dimensions.width = CLAY__MAX(openLayoutElement->dimensions.width, child->dimensions.width + layoutConfig->padding.left + layoutConfig->padding.right);
|
||||
// Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
|
||||
if (!elementHasScrollVertical) {
|
||||
openLayoutElement->minDimensions.height += child->minDimensions.height;
|
||||
}
|
||||
if (!elementHasScrollHorizontal) {
|
||||
openLayoutElement->minDimensions.width = CLAY__MAX(openLayoutElement->minDimensions.width, child->minDimensions.width + layoutConfig->padding.x * 2);
|
||||
openLayoutElement->minDimensions.width = CLAY__MAX(openLayoutElement->minDimensions.width, child->minDimensions.width + layoutConfig->padding.left + layoutConfig->padding.right);
|
||||
}
|
||||
Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
|
||||
}
|
||||
@ -2090,15 +2128,18 @@ void Clay__InitializePersistentMemory(Clay_Context* context) {
|
||||
void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Clay__int32_tArray resizableContainerBuffer) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
Clay__int32_tArray largestContainers = context->openClipElementStack;
|
||||
largestContainers.length = 0;
|
||||
|
||||
while (totalSizeToDistribute > 0) {
|
||||
while (totalSizeToDistribute > 0.1) {
|
||||
largestContainers.length = 0;
|
||||
float largestSize = 0;
|
||||
float targetSize = 0;
|
||||
for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, i));
|
||||
if (!xAxis && Clay__ElementHasConfig(childElement, CLAY__ELEMENT_CONFIG_TYPE_IMAGE)) {
|
||||
continue;
|
||||
}
|
||||
float childSize = xAxis ? childElement->dimensions.width : childElement->dimensions.height;
|
||||
if (childSize == largestSize) {
|
||||
if ((childSize - largestSize) < 0.1 && (childSize - largestSize) > -0.1) {
|
||||
Clay__int32_tArray_Add(&largestContainers, Clay__int32_tArray_Get(&resizableContainerBuffer, i));
|
||||
} else if (childSize > largestSize) {
|
||||
targetSize = largestSize;
|
||||
@ -2111,25 +2152,31 @@ void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Cl
|
||||
}
|
||||
}
|
||||
|
||||
if (largestContainers.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
targetSize = CLAY__MAX(targetSize, (largestSize * largestContainers.length) - totalSizeToDistribute) / largestContainers.length;
|
||||
|
||||
for (int32_t childOffset = 0; childOffset < largestContainers.length; childOffset++) {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&largestContainers, childOffset));
|
||||
int32_t childIndex = Clay__int32_tArray_Get(&largestContainers, childOffset);
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
|
||||
float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
|
||||
float childMinSize = xAxis ? childElement->minDimensions.width : childElement->minDimensions.height;
|
||||
float oldChildSize = *childSize;
|
||||
*childSize = CLAY__MAX(childMinSize, targetSize);
|
||||
totalSizeToDistribute -= (oldChildSize - *childSize);
|
||||
if (*childSize == childMinSize) {
|
||||
Clay__int32_tArray_RemoveSwapback(&largestContainers, childOffset);
|
||||
childOffset--;
|
||||
}
|
||||
}
|
||||
|
||||
if (largestContainers.length == 0) {
|
||||
for (int32_t i = 0; i < resizableContainerBuffer.length; i++) {
|
||||
if (Clay__int32_tArray_Get(&resizableContainerBuffer, i) == childIndex) {
|
||||
Clay__int32_tArray_RemoveSwapback(&resizableContainerBuffer, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
@ -2165,8 +2212,8 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||
Clay_LayoutConfig *parentStyleConfig = parent->layoutConfig;
|
||||
int32_t growContainerCount = 0;
|
||||
float parentSize = xAxis ? parent->dimensions.width : parent->dimensions.height;
|
||||
float parentPadding = (float)(xAxis ? parent->layoutConfig->padding.x : parent->layoutConfig->padding.y);
|
||||
float innerContentSize = 0, growContainerContentSize = 0, totalPaddingAndChildGaps = parentPadding * 2;
|
||||
float parentPadding = (float)(xAxis ? (parent->layoutConfig->padding.left + parent->layoutConfig->padding.right) : (parent->layoutConfig->padding.top + parent->layoutConfig->padding.bottom));
|
||||
float innerContentSize = 0, growContainerContentSize = 0, totalPaddingAndChildGaps = parentPadding;
|
||||
bool sizingAlongAxis = (xAxis && parentStyleConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) || (!xAxis && parentStyleConfig->layoutDirection == CLAY_TOP_TO_BOTTOM);
|
||||
resizableContainerBuffer.length = 0;
|
||||
float parentChildGap = parentStyleConfig->childGap;
|
||||
@ -2221,7 +2268,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||
}
|
||||
|
||||
if (sizingAlongAxis) {
|
||||
float sizeToDistribute = parentSize - parentPadding * 2 - innerContentSize;
|
||||
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
|
||||
@ -2266,7 +2313,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
|
||||
}
|
||||
|
||||
// If we're laying out the children of a scroll panel, grow containers expand to the height of the inner content, not the outer container
|
||||
float maxSize = parentSize - parentPadding * 2;
|
||||
float maxSize = parentSize - parentPadding;
|
||||
if (Clay__ElementHasConfig(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER)) {
|
||||
Clay_ScrollElementConfig *scrollElementConfig = Clay__FindElementConfigWithType(parent, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig;
|
||||
if (((xAxis && scrollElementConfig->horizontal) || (!xAxis && scrollElementConfig->vertical))) {
|
||||
@ -2358,7 +2405,7 @@ void Clay__CalculateFinalLayout() {
|
||||
float lineHeight = textConfig->lineHeight > 0 ? (float)textConfig->lineHeight : textElementData->preferredDimensions.height;
|
||||
int32_t lineLengthChars = 0;
|
||||
int32_t lineStartOffset = 0;
|
||||
if (textElementData->preferredDimensions.width <= containerElement->dimensions.width) {
|
||||
if (!measureTextCacheItem->containsNewlines && textElementData->preferredDimensions.width <= containerElement->dimensions.width) {
|
||||
Clay__WrappedTextLineArray_Add(&context->wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { containerElement->dimensions, textElementData->text });
|
||||
textElementData->wrappedLines.length++;
|
||||
continue;
|
||||
@ -2443,12 +2490,12 @@ void Clay__CalculateFinalLayout() {
|
||||
// Resize any parent containers that have grown in height along their non layout axis
|
||||
for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
|
||||
float childHeightWithPadding = CLAY__MAX(childElement->dimensions.height + layoutConfig->padding.y * 2, currentElement->dimensions.height);
|
||||
float childHeightWithPadding = CLAY__MAX(childElement->dimensions.height + layoutConfig->padding.top + layoutConfig->padding.bottom, currentElement->dimensions.height);
|
||||
currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(childHeightWithPadding, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
|
||||
}
|
||||
} else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
|
||||
// Resizing along the layout axis
|
||||
float contentHeight = (float)layoutConfig->padding.y * 2;
|
||||
float contentHeight = (float)(layoutConfig->padding.top + layoutConfig->padding.bottom);
|
||||
for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
|
||||
contentHeight += childElement->dimensions.height;
|
||||
@ -2461,6 +2508,20 @@ void Clay__CalculateFinalLayout() {
|
||||
// Calculate sizing along the Y axis
|
||||
Clay__SizeContainersAlongAxis(false);
|
||||
|
||||
// Sort tree roots by z-index
|
||||
int32_t sortMax = context->layoutElementTreeRoots.length - 1;
|
||||
while (sortMax > 0) { // todo dumb bubble sort
|
||||
for (int32_t i = 0; i < sortMax; ++i) {
|
||||
Clay__LayoutElementTreeRoot current = *Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, i);
|
||||
Clay__LayoutElementTreeRoot next = *Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, i + 1);
|
||||
if (next.zIndex < current.zIndex) {
|
||||
Clay__LayoutElementTreeRootArray_Set(&context->layoutElementTreeRoots, i, next);
|
||||
Clay__LayoutElementTreeRootArray_Set(&context->layoutElementTreeRoots, i + 1, current);
|
||||
}
|
||||
}
|
||||
sortMax--;
|
||||
}
|
||||
|
||||
// Calculate final positions and generate render commands
|
||||
context->renderCommands.length = 0;
|
||||
dfsBuffer.length = 0;
|
||||
@ -2553,7 +2614,7 @@ void Clay__CalculateFinalLayout() {
|
||||
});
|
||||
}
|
||||
}
|
||||
Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = rootElement, .position = rootPosition, .nextChildOffset = { .x = (float)rootElement->layoutConfig->padding.x, .y = (float)rootElement->layoutConfig->padding.y } });
|
||||
Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = rootElement, .position = rootPosition, .nextChildOffset = { .x = (float)rootElement->layoutConfig->padding.left, .y = (float)rootElement->layoutConfig->padding.top } });
|
||||
|
||||
context->treeNodeVisited.internalArray[0] = false;
|
||||
while (dfsBuffer.length > 0) {
|
||||
@ -2610,7 +2671,7 @@ void Clay__CalculateFinalLayout() {
|
||||
for (int32_t elementConfigIndex = 0; elementConfigIndex < currentElement->elementConfigs.length; ++elementConfigIndex) {
|
||||
sortedConfigIndexes[elementConfigIndex] = elementConfigIndex;
|
||||
}
|
||||
int32_t sortMax = currentElement->elementConfigs.length - 1;
|
||||
sortMax = currentElement->elementConfigs.length - 1;
|
||||
while (sortMax > 0) { // todo dumb bubble sort
|
||||
for (int32_t i = 0; i < sortMax; ++i) {
|
||||
int32_t current = sortedConfigIndexes[i];
|
||||
@ -2718,7 +2779,7 @@ void Clay__CalculateFinalLayout() {
|
||||
contentSize.height = CLAY__MAX(contentSize.height, childElement->dimensions.height);
|
||||
}
|
||||
contentSize.width += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
|
||||
float extraSpace = currentElement->dimensions.width - (float)layoutConfig->padding.x * 2 - contentSize.width;
|
||||
float extraSpace = currentElement->dimensions.width - (float)(layoutConfig->padding.left + layoutConfig->padding.right) - contentSize.width;
|
||||
switch (layoutConfig->childAlignment.x) {
|
||||
case CLAY_ALIGN_X_LEFT: extraSpace = 0; break;
|
||||
case CLAY_ALIGN_X_CENTER: extraSpace /= 2; break;
|
||||
@ -2732,7 +2793,7 @@ void Clay__CalculateFinalLayout() {
|
||||
contentSize.height += childElement->dimensions.height;
|
||||
}
|
||||
contentSize.height += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
|
||||
float extraSpace = currentElement->dimensions.height - (float)layoutConfig->padding.y * 2 - contentSize.height;
|
||||
float extraSpace = currentElement->dimensions.height - (float)(layoutConfig->padding.top + layoutConfig->padding.bottom) - contentSize.height;
|
||||
switch (layoutConfig->childAlignment.y) {
|
||||
case CLAY_ALIGN_Y_TOP: extraSpace = 0; break;
|
||||
case CLAY_ALIGN_Y_CENTER: extraSpace /= 2; break;
|
||||
@ -2742,7 +2803,7 @@ void Clay__CalculateFinalLayout() {
|
||||
}
|
||||
|
||||
if (scrollContainerData) {
|
||||
scrollContainerData->contentSize = CLAY__INIT(Clay_Dimensions) { contentSize.width + (float)layoutConfig->padding.x * 2, contentSize.height + (float)layoutConfig->padding.y * 2 };
|
||||
scrollContainerData->contentSize = CLAY__INIT(Clay_Dimensions) { contentSize.width + (float)(layoutConfig->padding.left + layoutConfig->padding.right), contentSize.height + (float)(layoutConfig->padding.top + layoutConfig->padding.bottom) };
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2781,7 +2842,8 @@ void Clay__CalculateFinalLayout() {
|
||||
Clay__AddRenderCommand(renderCommand);
|
||||
if (borderConfig->betweenChildren.width > 0 && borderConfig->betweenChildren.color.a > 0) {
|
||||
Clay_RectangleElementConfig *rectangleConfig = Clay__StoreRectangleElementConfig(CLAY__INIT(Clay_RectangleElementConfig) {.color = borderConfig->betweenChildren.color});
|
||||
Clay_Vector2 borderOffset = { (float)layoutConfig->padding.x, (float)layoutConfig->padding.y };
|
||||
float halfGap = layoutConfig->childGap / 2;
|
||||
Clay_Vector2 borderOffset = { (float)layoutConfig->padding.left - halfGap, (float)layoutConfig->padding.top - halfGap };
|
||||
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
|
||||
for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
|
||||
@ -2793,7 +2855,7 @@ void Clay__CalculateFinalLayout() {
|
||||
.commandType = CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
|
||||
});
|
||||
}
|
||||
borderOffset.x += (childElement->dimensions.width + (float)layoutConfig->childGap / 2);
|
||||
borderOffset.x += (childElement->dimensions.width + (float)layoutConfig->childGap);
|
||||
}
|
||||
} else {
|
||||
for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
|
||||
@ -2806,7 +2868,7 @@ void Clay__CalculateFinalLayout() {
|
||||
.commandType = CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
|
||||
});
|
||||
}
|
||||
borderOffset.y += (childElement->dimensions.height + (float)layoutConfig->childGap / 2);
|
||||
borderOffset.y += (childElement->dimensions.height + (float)layoutConfig->childGap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2831,16 +2893,16 @@ void Clay__CalculateFinalLayout() {
|
||||
Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
|
||||
// Alignment along non layout axis
|
||||
if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
|
||||
currentElementTreeNode->nextChildOffset.y = currentElement->layoutConfig->padding.y;
|
||||
float whiteSpaceAroundChild = currentElement->dimensions.height - (float)currentElement->layoutConfig->padding.y * 2 - childElement->dimensions.height;
|
||||
currentElementTreeNode->nextChildOffset.y = currentElement->layoutConfig->padding.top;
|
||||
float whiteSpaceAroundChild = currentElement->dimensions.height - (float)(layoutConfig->padding.top + layoutConfig->padding.bottom) - childElement->dimensions.height;
|
||||
switch (layoutConfig->childAlignment.y) {
|
||||
case CLAY_ALIGN_Y_TOP: break;
|
||||
case CLAY_ALIGN_Y_CENTER: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild / 2; break;
|
||||
case CLAY_ALIGN_Y_BOTTOM: currentElementTreeNode->nextChildOffset.y += whiteSpaceAroundChild; break;
|
||||
}
|
||||
} else {
|
||||
currentElementTreeNode->nextChildOffset.x = currentElement->layoutConfig->padding.x;
|
||||
float whiteSpaceAroundChild = currentElement->dimensions.width - (float)currentElement->layoutConfig->padding.x * 2 - childElement->dimensions.width;
|
||||
currentElementTreeNode->nextChildOffset.x = currentElement->layoutConfig->padding.left;
|
||||
float whiteSpaceAroundChild = currentElement->dimensions.width - (float)(layoutConfig->padding.left + layoutConfig->padding.right) - childElement->dimensions.width;
|
||||
switch (layoutConfig->childAlignment.x) {
|
||||
case CLAY_ALIGN_X_LEFT: break;
|
||||
case CLAY_ALIGN_X_CENTER: currentElementTreeNode->nextChildOffset.x += whiteSpaceAroundChild / 2; break;
|
||||
@ -2858,7 +2920,7 @@ void Clay__CalculateFinalLayout() {
|
||||
dfsBuffer.internalArray[newNodeIndex] = CLAY__INIT(Clay__LayoutElementTreeNode) {
|
||||
.layoutElement = childElement,
|
||||
.position = { childPosition.x, childPosition.y },
|
||||
.nextChildOffset = { .x = (float)childElement->layoutConfig->padding.x, .y = (float)childElement->layoutConfig->padding.y },
|
||||
.nextChildOffset = { .x = (float)childElement->layoutConfig->padding.left, .y = (float)childElement->layoutConfig->padding.top },
|
||||
};
|
||||
context->treeNodeVisited.internalArray[newNodeIndex] = false;
|
||||
|
||||
@ -2965,8 +3027,8 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
||||
Clay__int32_tArray_Add(&dfsBuffer, (int32_t)root->layoutElementIndex);
|
||||
context->treeNodeVisited.internalArray[0] = false;
|
||||
if (rootIndex > 0) {
|
||||
CLAY(CLAY_IDI("Clay__DebugView_EmptyRowOuter", rootIndex), CLAY_LAYOUT({ .sizing = {.width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)}, .padding = {CLAY__DEBUGVIEW_INDENT_WIDTH / 2, 0} })) {
|
||||
CLAY(CLAY_IDI("Clay__DebugView_EmptyRow", rootIndex), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), .height = CLAY_SIZING_FIXED((float)CLAY__DEBUGVIEW_ROW_HEIGHT) }}), CLAY_BORDER({ .top = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 } })) {}
|
||||
CLAY(CLAY_IDI("Clay__DebugView_EmptyRowOuter", rootIndex), CLAY_LAYOUT({ .sizing = {.width = CLAY_SIZING_GROW(0)}, .padding = {CLAY__DEBUGVIEW_INDENT_WIDTH / 2, 0} })) {
|
||||
CLAY(CLAY_IDI("Clay__DebugView_EmptyRow", rootIndex), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED((float)CLAY__DEBUGVIEW_ROW_HEIGHT) }}), CLAY_BORDER({ .top = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 } })) {}
|
||||
}
|
||||
layoutData.rowCount++;
|
||||
}
|
||||
@ -3013,12 +3075,12 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
||||
// Collisions and offscreen info
|
||||
if (currentElementData) {
|
||||
if (currentElementData->debugData->collision) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, (CLAY__INIT(Clay_Color){177, 147, 8, 255}), 4)) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, (CLAY__INIT(Clay_Color){177, 147, 8, 255}), 4)) {
|
||||
CLAY_TEXT(CLAY_STRING("Duplicate ID"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
if (offscreen) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, CLAY__DEBUGVIEW_COLOR_3, 4)) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_BORDER_OUTSIDE_RADIUS(1, CLAY__DEBUGVIEW_COLOR_3, 4)) {
|
||||
CLAY_TEXT(CLAY_STRING("Offscreen"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
@ -3032,7 +3094,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
||||
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(elementConfig->type);
|
||||
Clay_Color backgroundColor = config.color;
|
||||
backgroundColor.a = 90;
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) {
|
||||
CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = offscreen ? CLAY__DEBUGVIEW_COLOR_3 : CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
@ -3054,7 +3116,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
||||
}
|
||||
} else if (currentElement->childrenOrTextContent.children.length > 0) {
|
||||
Clay__OpenElement();
|
||||
CLAY_LAYOUT({ .padding = { 8 , 0} });
|
||||
CLAY_LAYOUT({ .padding = { 8 } });
|
||||
Clay__ElementPostConfiguration();
|
||||
Clay__OpenElement();
|
||||
CLAY_BORDER({ .left = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }});
|
||||
@ -3088,8 +3150,8 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
|
||||
}
|
||||
|
||||
if (highlightedElementId) {
|
||||
CLAY(CLAY_ID("Clay__DebugView_ElementHighlight"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)} }), CLAY_FLOATING({ .zIndex = 65535, .parentId = highlightedElementId })) {
|
||||
CLAY(CLAY_ID("Clay__DebugView_ElementHighlightRectangle"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)} }), CLAY_RECTANGLE({.color = Clay__debugViewHighlightColor })) {}
|
||||
CLAY(CLAY_ID("Clay__DebugView_ElementHighlight"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_FLOATING({ .zIndex = 65535, .parentId = highlightedElementId })) {
|
||||
CLAY(CLAY_ID("Clay__DebugView_ElementHighlightRectangle"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_RECTANGLE({.color = Clay__debugViewHighlightColor })) {}
|
||||
}
|
||||
}
|
||||
return layoutData;
|
||||
@ -3124,11 +3186,11 @@ void Clay__RenderDebugViewElementConfigHeader(Clay_String elementId, Clay__Eleme
|
||||
Clay__DebugElementConfigTypeLabelConfig config = Clay__DebugGetElementConfigTypeLabel(type);
|
||||
Clay_Color backgroundColor = config.color;
|
||||
backgroundColor.a = 90;
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = { .x = CLAY__DEBUGVIEW_OUTER_PADDING }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0)}, .padding = CLAY_PADDING_ALL(CLAY__DEBUGVIEW_OUTER_PADDING), .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 8, 8, 2, 2 } }), CLAY_RECTANGLE({ .color = backgroundColor, .cornerRadius = CLAY_CORNER_RADIUS(4) }), CLAY_BORDER_OUTSIDE_RADIUS(1, config.color, 4)) {
|
||||
CLAY_TEXT(config.label, CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT) } })) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {}
|
||||
CLAY_TEXT(elementId, CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE }));
|
||||
}
|
||||
}
|
||||
@ -3203,16 +3265,19 @@ void Clay__RenderDebugView() {
|
||||
Clay_TextElementConfig *infoTitleConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
|
||||
Clay_ElementId scrollId = Clay__HashString(CLAY_STRING("Clay__DebugViewOuterScrollPane"), 0, 0);
|
||||
float scrollYOffset = 0;
|
||||
bool pointerInDebugView = context->pointerInfo.position.y < context->layoutDimensions.height - 300;
|
||||
for (int32_t i = 0; i < context->scrollContainerDatas.length; ++i) {
|
||||
Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
|
||||
if (scrollContainerData->elementId == scrollId.id) {
|
||||
if (!context->externalScrollHandlingEnabled) {
|
||||
scrollYOffset = scrollContainerData->scrollPosition.y;
|
||||
} else {
|
||||
pointerInDebugView = context->pointerInfo.position.y + scrollContainerData->scrollPosition.y < context->layoutDimensions.height - 300;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
int32_t highlightedRow = context->pointerInfo.position.y < context->layoutDimensions.height - 300
|
||||
int32_t highlightedRow = pointerInDebugView
|
||||
? (int32_t)((context->pointerInfo.position.y - scrollYOffset) / (float)CLAY__DEBUGVIEW_ROW_HEIGHT) - 1
|
||||
: -1;
|
||||
if (context->pointerInfo.position.x < context->layoutDimensions.width - (float)Clay__debugViewWidth) {
|
||||
@ -3220,13 +3285,13 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT;
|
||||
CLAY(CLAY_ID("Clay__DebugView"),
|
||||
CLAY_FLOATING({ .parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0, 0).id, .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_CENTER }}),
|
||||
CLAY_FLOATING({ .zIndex = 65000, .parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0, 0).id, .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_CENTER }}),
|
||||
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
|
||||
CLAY_BORDER({ .bottom = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }})
|
||||
) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Clay Debug Tools"), infoTextConfig);
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY__DEFAULT_STRUCT } })) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
|
||||
// Close button
|
||||
CLAY(CLAY_BORDER_OUTSIDE_RADIUS(1, (CLAY__INIT(Clay_Color){217,91,67,255}), 4),
|
||||
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT - 10)}, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} }),
|
||||
@ -3236,13 +3301,13 @@ void Clay__RenderDebugView() {
|
||||
CLAY_TEXT(CLAY_STRING("x"), CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16 }));
|
||||
}
|
||||
}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_3 })) {}
|
||||
CLAY(Clay__AttachId(scrollId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)} }), CLAY_SCROLL({ .horizontal = true, .vertical = true })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_RECTANGLE({ .color = ((initialElementsLength + initialRootsLength) & 1) == 0 ? CLAY__DEBUGVIEW_COLOR_2 : CLAY__DEBUGVIEW_COLOR_1 })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_3 })) {}
|
||||
CLAY(Clay__AttachId(scrollId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_SCROLL({ .horizontal = true, .vertical = true })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_RECTANGLE({ .color = ((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
|
||||
CLAY(Clay__AttachId(panelContentsId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)} }), CLAY_FLOATING({ .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)}, .padding = {.x = CLAY__DEBUGVIEW_OUTER_PADDING }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(Clay__AttachId(panelContentsId), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)} }), CLAY_FLOATING({ .zIndex = 65001, .pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0)}, .padding = { CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING }, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
layoutData = Clay__RenderDebugLayoutElementsList((int32_t)initialRootsLength, highlightedRow);
|
||||
}
|
||||
}
|
||||
@ -3258,22 +3323,22 @@ void Clay__RenderDebugView() {
|
||||
rowColor.g *= 1.25f;
|
||||
rowColor.b *= 1.25f;
|
||||
}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_RECTANGLE({ .color = rowColor })) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_RECTANGLE({ .color = rowColor })) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {.width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_3 })) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_3 })) {}
|
||||
if (context->debugSelectedElementId != 0) {
|
||||
Clay_LayoutElementHashMapItem *selectedItem = Clay__GetHashMapItem(context->debugSelectedElementId);
|
||||
CLAY(
|
||||
CLAY_SCROLL({ .vertical = true }),
|
||||
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(300)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
|
||||
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
|
||||
CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 }),
|
||||
CLAY_BORDER({ .betweenChildren = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }})
|
||||
) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT + 8)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
|
||||
CLAY_TEXT(CLAY_STRING("Layout Config"), infoTextConfig);
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY__DEFAULT_STRUCT } })) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {}
|
||||
if (selectedItem->elementId.stringId.length != 0) {
|
||||
CLAY_TEXT(selectedItem->elementId.stringId, infoTitleConfig);
|
||||
if (selectedItem->elementId.offset != 0) {
|
||||
@ -3283,8 +3348,9 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
}
|
||||
}
|
||||
Clay_Padding attributeConfigPadding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING, 8, 8};
|
||||
// Clay_LayoutConfig debug info
|
||||
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
// .boundingBox
|
||||
CLAY_TEXT(CLAY_STRING("Bounding Box"), infoTitleConfig);
|
||||
CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) {
|
||||
@ -3315,10 +3381,14 @@ void Clay__RenderDebugView() {
|
||||
// .padding
|
||||
CLAY_TEXT(CLAY_STRING("Padding"), infoTitleConfig);
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoPadding")) {
|
||||
CLAY_TEXT(CLAY_STRING("{ x: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.x), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", y: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.y), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING("{ left: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.left), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", right: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.right), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", top: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.top), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(", bottom: "), infoTextConfig);
|
||||
CLAY_TEXT(Clay__IntToString(layoutConfig->padding.bottom), infoTextConfig);
|
||||
CLAY_TEXT(CLAY_STRING(" }"), infoTextConfig);
|
||||
}
|
||||
// .childGap
|
||||
@ -3352,7 +3422,7 @@ void Clay__RenderDebugView() {
|
||||
switch (elementConfig->type) {
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_RECTANGLE: {
|
||||
Clay_RectangleElementConfig *rectangleConfig = elementConfig->config.rectangleElementConfig;
|
||||
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
// .color
|
||||
CLAY_TEXT(CLAY_STRING("Color"), infoTitleConfig);
|
||||
Clay__RenderDebugViewColor(rectangleConfig->color, infoTextConfig);
|
||||
@ -3364,7 +3434,7 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_TEXT: {
|
||||
Clay_TextElementConfig *textConfig = elementConfig->config.textElementConfig;
|
||||
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
// .fontSize
|
||||
CLAY_TEXT(CLAY_STRING("Font Size"), infoTitleConfig);
|
||||
CLAY_TEXT(Clay__IntToString(textConfig->fontSize), infoTextConfig);
|
||||
@ -3394,7 +3464,7 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_IMAGE: {
|
||||
Clay_ImageElementConfig *imageConfig = elementConfig->config.imageElementConfig;
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoImageBody"), CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoImageBody"), CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
// .sourceDimensions
|
||||
CLAY_TEXT(CLAY_STRING("Source Dimensions"), infoTitleConfig);
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoImageDimensions")) {
|
||||
@ -3406,13 +3476,13 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
// Image Preview
|
||||
CLAY_TEXT(CLAY_STRING("Preview"), infoTitleConfig);
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = imageConfig->sourceDimensions.width }), CLAY__DEFAULT_STRUCT }}), Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .imageElementConfig = imageConfig }, CLAY__ELEMENT_CONFIG_TYPE_IMAGE)) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0, imageConfig->sourceDimensions.width) }}), Clay__AttachElementConfig(CLAY__INIT(Clay_ElementConfigUnion) { .imageElementConfig = imageConfig }, CLAY__ELEMENT_CONFIG_TYPE_IMAGE)) {}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER: {
|
||||
Clay_ScrollElementConfig *scrollConfig = elementConfig->config.scrollElementConfig;
|
||||
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(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);
|
||||
@ -3424,7 +3494,7 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER: {
|
||||
Clay_FloatingElementConfig *floatingConfig = elementConfig->config.floatingElementConfig;
|
||||
CLAY(CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
// .offset
|
||||
CLAY_TEXT(CLAY_STRING("Offset"), infoTitleConfig);
|
||||
CLAY(CLAY_LAYOUT(CLAY__DEFAULT_STRUCT)) {
|
||||
@ -3455,7 +3525,7 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
case CLAY__ELEMENT_CONFIG_TYPE_BORDER_CONTAINER: {
|
||||
Clay_BorderElementConfig *borderConfig = elementConfig->config.borderElementConfig;
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoBorderBody"), CLAY_LAYOUT({ .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 8}, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewElementInfoBorderBody"), CLAY_LAYOUT({ .padding = attributeConfigPadding, .childGap = 8, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
// .left
|
||||
CLAY_TEXT(CLAY_STRING("Left Border"), infoTitleConfig);
|
||||
Clay__RenderDebugViewBorder(1, borderConfig->left, infoTextConfig);
|
||||
@ -3483,16 +3553,16 @@ void Clay__RenderDebugView() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningsScrollPane"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(300)}, .childGap = 6, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_SCROLL({ .horizontal = true, .vertical = true }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningsScrollPane"), CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(300)}, .childGap = 6, .layoutDirection = CLAY_TOP_TO_BOTTOM }), CLAY_SCROLL({ .horizontal = true, .vertical = true }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
|
||||
Clay_TextElementConfig *warningConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningItemHeader"), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningItemHeader"), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
|
||||
CLAY_TEXT(CLAY_STRING("Warnings"), warningConfig);
|
||||
}
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningsTopBorder"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {}
|
||||
int32_t previousWarningsLength = (int)context->warnings.length;
|
||||
CLAY(CLAY_ID("Clay__DebugViewWarningsTopBorder"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {}
|
||||
int32_t previousWarningsLength = context->warnings.length;
|
||||
for (int32_t i = 0; i < previousWarningsLength; i++) {
|
||||
Clay__Warning warning = context->warnings.internalArray[i];
|
||||
CLAY(CLAY_IDI("Clay__DebugViewWarningItem", i), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
|
||||
CLAY(CLAY_IDI("Clay__DebugViewWarningItem", i), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, CLAY__DEBUGVIEW_OUTER_PADDING}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
|
||||
CLAY_TEXT(warning.baseMessage, warningConfig);
|
||||
if (warning.dynamicMessage.length > 0) {
|
||||
CLAY_TEXT(warning.dynamicMessage, warningConfig);
|
||||
@ -3590,7 +3660,7 @@ uint32_t Clay_MinMemorySize(void) {
|
||||
.maxMeasureTextCacheWordCount = Clay__defaultMaxMeasureTextWordCacheCount,
|
||||
.internalArena = {
|
||||
.capacity = SIZE_MAX,
|
||||
.memory = (char*)&fakeContext,
|
||||
.memory = NULL,
|
||||
}
|
||||
};
|
||||
Clay_Context* currentContext = Clay_GetCurrentContext();
|
||||
@ -3615,11 +3685,15 @@ Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset
|
||||
}
|
||||
|
||||
#ifndef CLAY_WASM
|
||||
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config)) {
|
||||
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData), uintptr_t userData) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
Clay__MeasureText = measureTextFunction;
|
||||
context->mesureTextUserData = userData;
|
||||
}
|
||||
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId)) {
|
||||
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId, uintptr_t userData), uintptr_t userData) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
Clay__QueryScrollOffset = queryScrollOffsetFunction;
|
||||
context->queryScrollOffsetUserData = userData;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3859,9 +3933,7 @@ void Clay_BeginLayout(void) {
|
||||
if (context->debugModeEnabled) {
|
||||
rootDimensions.width -= (float)Clay__debugViewWidth;
|
||||
}
|
||||
context->booleanWarnings.maxElementsExceeded = false;
|
||||
context->booleanWarnings.maxTextMeasureCacheExceeded = false;
|
||||
context->booleanWarnings.maxRenderCommandsExceeded = false;
|
||||
context->booleanWarnings = CLAY__INIT(Clay_BooleanWarnings) CLAY__DEFAULT_STRUCT;
|
||||
Clay__OpenElement();
|
||||
CLAY_ID("Clay__RootContainer");
|
||||
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} });
|
||||
@ -3960,6 +4032,19 @@ Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
|
||||
return CLAY__INIT(Clay_ScrollContainerData) CLAY__DEFAULT_STRUCT;
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_GetElementData")
|
||||
Clay_ElementData Clay_GetElementData(Clay_ElementId id){
|
||||
Clay_LayoutElementHashMapItem * item = Clay__GetHashMapItem(id.id);
|
||||
if(item == &CLAY__LAYOUT_ELEMENT_HASH_MAP_ITEM_DEFAULT) {
|
||||
return CLAY__INIT(Clay_ElementData) CLAY__DEFAULT_STRUCT;
|
||||
}
|
||||
|
||||
return CLAY__INIT(Clay_ElementData){
|
||||
.boundingBox = item->boundingBox,
|
||||
.found = true
|
||||
};
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_SetDebugModeEnabled")
|
||||
void Clay_SetDebugModeEnabled(bool enabled) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
@ -4016,6 +4101,21 @@ void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount)
|
||||
}
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_ResetMeasureTextCache")
|
||||
void Clay_ResetMeasureTextCache(void) {
|
||||
Clay_Context* context = Clay_GetCurrentContext();
|
||||
context->measureTextHashMapInternal.length = 0;
|
||||
context->measureTextHashMapInternalFreeList.length = 0;
|
||||
context->measureTextHashMap.length = 0;
|
||||
context->measuredWords.length = 0;
|
||||
context->measuredWordsFreeList.length = 0;
|
||||
|
||||
for (int32_t i = 0; i < context->measureTextHashMap.capacity; ++i) {
|
||||
context->measureTextHashMap.internalArray[i] = 0;
|
||||
}
|
||||
context->measureTextHashMapInternal.length = 1; // Reserve the 0 value to mean "no next element"
|
||||
}
|
||||
|
||||
#endif // CLAY_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
|
@ -307,7 +307,6 @@ int main(void) {
|
||||
fprintf(stderr, "Error: could not create NanoVG context\n");
|
||||
return 1;
|
||||
}
|
||||
Clay_NanoVG_RenderInit(nvg);
|
||||
|
||||
FONT_ID_BODY_16 = nvgCreateFont(nvg, "roboto-regular", "resources/Roboto-Regular.ttf");
|
||||
if (FONT_ID_BODY_16 < 0) {
|
||||
@ -318,7 +317,8 @@ int main(void) {
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
|
||||
|
||||
Clay_SetMeasureTextFunction(Clay_NanoVG_MeasureText);
|
||||
|
||||
Clay_SetMeasureTextFunction(Clay_NanoVG_MeasureText, (uintptr_t)nvg);
|
||||
|
||||
int windowWidth = 0;
|
||||
int windowHeight = 0;
|
||||
|
@ -23,6 +23,15 @@ FetchContent_Declare(
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL2_ttf)
|
||||
|
||||
FetchContent_Declare(
|
||||
SDL2_image
|
||||
GIT_REPOSITORY "https://github.com/libsdl-org/SDL_image.git"
|
||||
GIT_TAG "release-2.8.4"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL2_image)
|
||||
|
||||
add_executable(SDL2_video_demo main.c)
|
||||
|
||||
target_compile_options(SDL2_video_demo PUBLIC)
|
||||
@ -32,10 +41,15 @@ target_link_libraries(SDL2_video_demo PUBLIC
|
||||
SDL2::SDL2main
|
||||
SDL2::SDL2-static
|
||||
SDL2_ttf::SDL2_ttf-static
|
||||
SDL2_image::SDL2_image-static
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS_DEBUG "/D CLAY_DEBUG")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror -Wno-error=missing-braces -DCLAY_DEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET SDL2_video_demo POST_BUILD
|
||||
|
@ -10,13 +10,14 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
const int FONT_ID_BODY_16 = 0;
|
||||
Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
|
||||
|
||||
SDL_Surface *sample_image;
|
||||
|
||||
void RenderHeaderButton(Clay_String text) {
|
||||
CLAY(
|
||||
CLAY_LAYOUT({ .padding = { 16, 8 }}),
|
||||
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 140, 140, 140, 255 },
|
||||
.cornerRadius = 5
|
||||
@ -31,7 +32,7 @@ void RenderHeaderButton(Clay_String text) {
|
||||
}
|
||||
|
||||
void RenderDropdownMenuItem(Clay_String text) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 16, 16 }})) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16)})) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 16,
|
||||
@ -74,8 +75,8 @@ void HandleSidebarInteraction(
|
||||
static Clay_RenderCommandArray CreateLayout() {
|
||||
Clay_BeginLayout();
|
||||
Clay_Sizing layoutExpand = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
.width = CLAY_SIZING_GROW(0),
|
||||
.height = CLAY_SIZING_GROW(0)
|
||||
};
|
||||
|
||||
Clay_RectangleElementConfig contentBackgroundConfig = {
|
||||
@ -91,7 +92,7 @@ static Clay_RenderCommandArray CreateLayout() {
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = layoutExpand,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.childGap = 16
|
||||
})
|
||||
) {
|
||||
@ -102,7 +103,7 @@ static Clay_RenderCommandArray CreateLayout() {
|
||||
CLAY_LAYOUT({
|
||||
.sizing = {
|
||||
.height = CLAY_SIZING_FIXED(60),
|
||||
.width = CLAY_SIZING_GROW()
|
||||
.width = CLAY_SIZING_GROW(0)
|
||||
},
|
||||
.padding = { 16 },
|
||||
.childGap = 16,
|
||||
@ -112,9 +113,18 @@ static Clay_RenderCommandArray CreateLayout() {
|
||||
})
|
||||
) {
|
||||
// Header buttons go here
|
||||
CLAY(
|
||||
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
|
||||
CLAY_BORDER_ALL({ 2, COLOR_WHITE })
|
||||
) {
|
||||
CLAY(
|
||||
CLAY_LAYOUT({ .padding = { 8, 8, 8, 8 }}),
|
||||
CLAY_IMAGE({ sample_image, { 23, 42 } })
|
||||
) {}
|
||||
}
|
||||
CLAY(
|
||||
CLAY_ID("FileButton"),
|
||||
CLAY_LAYOUT({ .padding = { 16, 8 }}),
|
||||
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 140, 140, 140, 255 },
|
||||
.cornerRadius = 5
|
||||
@ -164,7 +174,7 @@ static Clay_RenderCommandArray CreateLayout() {
|
||||
}
|
||||
}
|
||||
RenderHeaderButton(CLAY_STRING("Edit"));
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }})) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }})) {}
|
||||
RenderHeaderButton(CLAY_STRING("Upload"));
|
||||
RenderHeaderButton(CLAY_STRING("Media"));
|
||||
RenderHeaderButton(CLAY_STRING("Support"));
|
||||
@ -179,19 +189,19 @@ static Clay_RenderCommandArray CreateLayout() {
|
||||
CLAY_RECTANGLE(contentBackgroundConfig),
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.childGap = 8,
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(250),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
.height = CLAY_SIZING_GROW(0)
|
||||
}
|
||||
})
|
||||
) {
|
||||
for (int i = 0; i < documents.length; i++) {
|
||||
Document document = documents.documents[i];
|
||||
Clay_LayoutConfig sidebarButtonLayout = {
|
||||
.sizing = { .width = CLAY_SIZING_GROW() },
|
||||
.padding = { 16, 16 }
|
||||
.sizing = { .width = CLAY_SIZING_GROW(0) },
|
||||
.padding = CLAY_PADDING_ALL(16)
|
||||
};
|
||||
|
||||
if (i == selectedDocumentIndex) {
|
||||
@ -236,7 +246,7 @@ static Clay_RenderCommandArray CreateLayout() {
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 16,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.sizing = layoutExpand
|
||||
})
|
||||
) {
|
||||
@ -262,7 +272,7 @@ void HandleClayErrors(Clay_ErrorData errorData) {
|
||||
printf("%s", errorData.errorText.chars);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int main(int argc, char *argv[]) {
|
||||
documents.documents = (Document[]) {
|
||||
{ .title = CLAY_STRING("Squirrels"), .contents = CLAY_STRING("The Secret Life of Squirrels: Nature's Clever Acrobats\n""Squirrels are often overlooked creatures, dismissed as mere park inhabitants or backyard nuisances. Yet, beneath their fluffy tails and twitching noses lies an intricate world of cunning, agility, and survival tactics that are nothing short of fascinating. As one of the most common mammals in North America, squirrels have adapted to a wide range of environments from bustling urban centers to tranquil forests and have developed a variety of unique behaviors that continue to intrigue scientists and nature enthusiasts alike.\n""\n""Master Tree Climbers\n""At the heart of a squirrel's skill set is its impressive ability to navigate trees with ease. Whether they're darting from branch to branch or leaping across wide gaps, squirrels possess an innate talent for acrobatics. Their powerful hind legs, which are longer than their front legs, give them remarkable jumping power. With a tail that acts as a counterbalance, squirrels can leap distances of up to ten times the length of their body, making them some of the best aerial acrobats in the animal kingdom.\n""But it's not just their agility that makes them exceptional climbers. Squirrels' sharp, curved claws allow them to grip tree bark with precision, while the soft pads on their feet provide traction on slippery surfaces. Their ability to run at high speeds and scale vertical trunks with ease is a testament to the evolutionary adaptations that have made them so successful in their arboreal habitats.\n""\n""Food Hoarders Extraordinaire\n""Squirrels are often seen frantically gathering nuts, seeds, and even fungi in preparation for winter. While this behavior may seem like instinctual hoarding, it is actually a survival strategy that has been honed over millions of years. Known as \"scatter hoarding,\" squirrels store their food in a variety of hidden locations, often burying it deep in the soil or stashing it in hollowed-out tree trunks.\n""Interestingly, squirrels have an incredible memory for the locations of their caches. Research has shown that they can remember thousands of hiding spots, often returning to them months later when food is scarce. However, they don't always recover every stash some forgotten caches eventually sprout into new trees, contributing to forest regeneration. This unintentional role as forest gardeners highlights the ecological importance of squirrels in their ecosystems.\n""\n""The Great Squirrel Debate: Urban vs. Wild\n""While squirrels are most commonly associated with rural or wooded areas, their adaptability has allowed them to thrive in urban environments as well. In cities, squirrels have become adept at finding food sources in places like parks, streets, and even garbage cans. However, their urban counterparts face unique challenges, including traffic, predators, and the lack of natural shelters. Despite these obstacles, squirrels in urban areas are often observed using human infrastructure such as buildings, bridges, and power lines as highways for their acrobatic escapades.\n""There is, however, a growing concern regarding the impact of urban life on squirrel populations. Pollution, deforestation, and the loss of natural habitats are making it more difficult for squirrels to find adequate food and shelter. As a result, conservationists are focusing on creating squirrel-friendly spaces within cities, with the goal of ensuring these resourceful creatures continue to thrive in both rural and urban landscapes.\n""\n""A Symbol of Resilience\n""In many cultures, squirrels are symbols of resourcefulness, adaptability, and preparation. Their ability to thrive in a variety of environments while navigating challenges with agility and grace serves as a reminder of the resilience inherent in nature. Whether you encounter them in a quiet forest, a city park, or your own backyard, squirrels are creatures that never fail to amaze with their endless energy and ingenuity.\n""In the end, squirrels may be small, but they are mighty in their ability to survive and thrive in a world that is constantly changing. So next time you spot one hopping across a branch or darting across your lawn, take a moment to appreciate the remarkable acrobat at work a true marvel of the natural world.\n") },
|
||||
{ .title = CLAY_STRING("Lorem Ipsum"), .contents = CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") },
|
||||
@ -279,17 +289,26 @@ int main(void) {
|
||||
fprintf(stderr, "Error: could not initialize TTF: %s\n", TTF_GetError());
|
||||
return 1;
|
||||
}
|
||||
if (IMG_Init(IMG_INIT_PNG) < 0) {
|
||||
fprintf(stderr, "Error: could not initialize IMG: %s\n", IMG_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 16);
|
||||
if (!font) {
|
||||
fprintf(stderr, "Error: could not load font: %s\n", TTF_GetError());
|
||||
return 1;
|
||||
}
|
||||
SDL2_fonts[FONT_ID_BODY_16] = (SDL2_Font) {
|
||||
|
||||
SDL2_Font fonts[1] = {};
|
||||
|
||||
fonts[FONT_ID_BODY_16] = (SDL2_Font) {
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.font = font,
|
||||
};
|
||||
|
||||
sample_image = IMG_Load("resources/sample.png");
|
||||
|
||||
SDL_Window *window = NULL;
|
||||
SDL_Renderer *renderer = NULL;
|
||||
if (SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_RESIZABLE, &window, &renderer) < 0) {
|
||||
@ -299,12 +318,13 @@ int main(void) {
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
|
||||
|
||||
Clay_SetMeasureTextFunction(SDL2_MeasureText);
|
||||
|
||||
int windowWidth = 0;
|
||||
int windowHeight = 0;
|
||||
SDL_GetWindowSize(window, &windowWidth, &windowHeight);
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)windowWidth, (float)windowHeight }, (Clay_ErrorHandler) { HandleClayErrors });
|
||||
|
||||
Clay_SetMeasureTextFunction(SDL2_MeasureText, (uintptr_t)&fonts);
|
||||
|
||||
Uint64 NOW = SDL_GetPerformanceCounter();
|
||||
Uint64 LAST = 0;
|
||||
double deltaTime = 0;
|
||||
@ -345,7 +365,7 @@ int main(void) {
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
Clay_SDL2_Render(renderer, renderCommands);
|
||||
Clay_SDL2_Render(renderer, renderCommands, fonts);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
@ -353,6 +373,7 @@ int main(void) {
|
||||
quit:
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
IMG_Quit();
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
|
BIN
examples/SDL2-video-demo/resources/sample.png
Normal file
BIN
examples/SDL2-video-demo/resources/sample.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 850 B |
49
examples/SDL3-simple-demo/CMakeLists.txt
Normal file
49
examples/SDL3-simple-demo/CMakeLists.txt
Normal file
@ -0,0 +1,49 @@
|
||||
cmake_minimum_required(VERSION 3.27)
|
||||
|
||||
# Project setup
|
||||
project(clay_examples_sdl3_simple_demo C)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
|
||||
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
|
||||
# Download SDL3
|
||||
FetchContent_Declare(
|
||||
SDL
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||
GIT_TAG preview-3.1.6
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
message(STATUS "Using SDL via FetchContent")
|
||||
FetchContent_MakeAvailable(SDL)
|
||||
set_property(DIRECTORY "${sdl_SOURCE_DIR}" PROPERTY EXCLUDE_FROM_ALL TRUE)
|
||||
|
||||
# Download SDL_ttf
|
||||
FetchContent_Declare(
|
||||
SDL_ttf
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_ttf.git
|
||||
GIT_TAG main # Slightly risky to use main branch, but it's the only one available
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
message(STATUS "Using SDL_ttf via FetchContent")
|
||||
FetchContent_MakeAvailable(SDL_ttf)
|
||||
set_property(DIRECTORY "${sdl_ttf_SOURCE_DIR}" PROPERTY EXCLUDE_FROM_ALL TRUE)
|
||||
|
||||
# Example executable
|
||||
add_executable(${PROJECT_NAME} main.c)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
SDL3::SDL3
|
||||
SDL3_ttf::SDL3_ttf
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources
|
||||
${CMAKE_CURRENT_BINARY_DIR}/resources
|
||||
)
|
185
examples/SDL3-simple-demo/main.c
Normal file
185
examples/SDL3-simple-demo/main.c
Normal file
@ -0,0 +1,185 @@
|
||||
#define SDL_MAIN_USE_CALLBACKS
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_ttf/SDL_ttf.h>
|
||||
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "../../clay.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../renderers/SDL3/clay_renderer_SDL3.c"
|
||||
|
||||
static const Uint32 FONT_ID = 0;
|
||||
|
||||
static const Clay_Color COLOR_ORANGE = (Clay_Color) {225, 138, 50, 255};
|
||||
static const Clay_Color COLOR_BLUE = (Clay_Color) {111, 173, 162, 255};
|
||||
static const Clay_Color COLOR_LIGHT = (Clay_Color) {224, 215, 210, 255};
|
||||
|
||||
typedef struct app_state {
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
} AppState;
|
||||
|
||||
static inline Clay_Dimensions SDL_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData)
|
||||
{
|
||||
TTF_Font *font = gFonts[config->fontId];
|
||||
int width, height;
|
||||
|
||||
if (!TTF_GetStringSize(font, text.chars, text.length, &width, &height)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to measure text: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
return (Clay_Dimensions) { (float) width, (float) height };
|
||||
}
|
||||
|
||||
static void Label(Clay_String text)
|
||||
{
|
||||
CLAY(CLAY_LAYOUT({ .padding = {16, 8} }), CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE })) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
|
||||
.textColor = { 255, 255, 255, 255 },
|
||||
.fontId = FONT_ID,
|
||||
.fontSize = 24,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
static Clay_RenderCommandArray Clay_CreateLayout()
|
||||
{
|
||||
Clay_BeginLayout();
|
||||
CLAY(CLAY_ID("MainContent"),
|
||||
CLAY_LAYOUT({
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
.height = CLAY_SIZING_GROW(),
|
||||
},
|
||||
.childAlignment = {
|
||||
.x = CLAY_ALIGN_X_CENTER,
|
||||
.y = CLAY_ALIGN_Y_CENTER,
|
||||
},
|
||||
.childGap = 10,
|
||||
.padding = { 10, 10 },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = COLOR_LIGHT,
|
||||
})
|
||||
) {
|
||||
Label(CLAY_STRING("Button 1"));
|
||||
Label(CLAY_STRING("Button 2"));
|
||||
Label(CLAY_STRING("Button 3"));
|
||||
}
|
||||
return Clay_EndLayout();
|
||||
}
|
||||
|
||||
void HandleClayErrors(Clay_ErrorData errorData) {
|
||||
printf("%s", errorData.errorText.chars);
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
if (!TTF_Init()) {
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
AppState *state = SDL_calloc(1, sizeof(AppState));
|
||||
if (!state) {
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
*appstate = state;
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("Clay Demo", 640, 480, 0, &state->window, &state->renderer)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to create window and renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetWindowResizable(state->window, true);
|
||||
|
||||
TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 24);
|
||||
if (!font) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to load font: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
gFonts[FONT_ID] = font;
|
||||
|
||||
/* Initialize Clay */
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = (Clay_Arena) {
|
||||
.memory = SDL_malloc(totalMemorySize),
|
||||
.capacity = totalMemorySize
|
||||
};
|
||||
|
||||
int width, height;
|
||||
SDL_GetWindowSize(state->window, &width, &height);
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float) width, (float) height }, (Clay_ErrorHandler) { HandleClayErrors });
|
||||
Clay_SetMeasureTextFunction(SDL_MeasureText, 0);
|
||||
|
||||
*appstate = state;
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
SDL_AppResult ret_val = SDL_APP_CONTINUE;
|
||||
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
ret_val = SDL_APP_SUCCESS;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
Clay_SetLayoutDimensions((Clay_Dimensions) { (float) event->window.data1, (float) event->window.data2 });
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
Clay_SetPointerState((Clay_Vector2) { event->motion.x, event->motion.y },
|
||||
event->motion.state & SDL_BUTTON_LEFT);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
Clay_UpdateScrollContainers(true, (Clay_Vector2) { event->motion.xrel, event->motion.yrel }, 0.01f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
AppState *state = appstate;
|
||||
|
||||
Clay_RenderCommandArray render_commands = Clay_CreateLayout();
|
||||
|
||||
SDL_SetRenderDrawColor(state->renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(state->renderer);
|
||||
|
||||
SDL_RenderClayCommands(state->renderer, &render_commands);
|
||||
|
||||
SDL_RenderPresent(state->renderer);
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
(void) result;
|
||||
|
||||
if (result != SDL_APP_SUCCESS) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Application failed to run");
|
||||
}
|
||||
|
||||
AppState *state = appstate;
|
||||
|
||||
if (state) {
|
||||
if (state->renderer)
|
||||
SDL_DestroyRenderer(state->renderer);
|
||||
|
||||
if (state->window)
|
||||
SDL_DestroyWindow(state->window);
|
||||
|
||||
SDL_free(state);
|
||||
}
|
||||
TTF_Quit();
|
||||
}
|
BIN
examples/SDL3-simple-demo/resources/Roboto-Regular.ttf
Normal file
BIN
examples/SDL3-simple-demo/resources/Roboto-Regular.ttf
Normal file
Binary file not shown.
@ -37,12 +37,12 @@ void Layout() {
|
||||
static Clay_Color BACKGROUND = { 0xF4, 0xEB, 0xE6, 255 };
|
||||
static Clay_Color ACCENT = { 0xFA, 0xE0, 0xD4, 255 };
|
||||
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() },
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM }),
|
||||
CLAY_RECTANGLE({ .color = BACKGROUND })) {
|
||||
CLAY(CLAY_ID("PageMargins"),
|
||||
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() },
|
||||
.padding = { 70., 50. }, // Some nice looking page margins
|
||||
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) },
|
||||
.padding = { 70, 70, 50, 50 }, // Some nice looking page margins
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 10})) {
|
||||
|
||||
@ -57,12 +57,12 @@ void Layout() {
|
||||
));
|
||||
|
||||
// Feature Box
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT() }, .childGap = 10 })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT() }}), CLAY_RECTANGLE({
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(0) }, .childGap = 10 })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(0) }}), CLAY_RECTANGLE({
|
||||
.color = ACCENT,
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(12),
|
||||
})) {
|
||||
CLAY(CLAY_LAYOUT({.padding = { 20., 20. }, .childGap = 4, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_LAYOUT({.padding = CLAY_PADDING_ALL(20), .childGap = 4, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY_TEXT(CLAY_STRING("- High performance"),
|
||||
CLAY_TEXT_CONFIG({ .textColor = PRIMARY, .fontSize = 14, .fontFamily = CLAY_STRING("Quicksand SemiBold") }));
|
||||
CLAY_TEXT(CLAY_STRING("- Declarative syntax"),
|
||||
@ -76,16 +76,16 @@ void Layout() {
|
||||
}
|
||||
}
|
||||
CLAY(CLAY_LAYOUT({
|
||||
.sizing = {CLAY_SIZING_FIT(), CLAY_SIZING_GROW()},
|
||||
.padding = { 10, 10 },
|
||||
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(10),
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER },
|
||||
.childGap = 4
|
||||
}), CLAY_RECTANGLE({ .color = ACCENT, .cornerRadius = CLAY_CORNER_RADIUS(8) })) {
|
||||
// Profile picture
|
||||
CLAY(CLAY_LAYOUT({
|
||||
.sizing = {CLAY_SIZING_FIT(), CLAY_SIZING_GROW()},
|
||||
.padding = { 30, 0 },
|
||||
.sizing = {CLAY_SIZING_FIT(0), CLAY_SIZING_GROW(0)},
|
||||
.padding = { 30, 30, 0, 0 },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER }}), CLAY_BORDER_OUTSIDE_RADIUS(2, PRIMARY, 10)) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED(32), CLAY_SIZING_FIXED(32) } }), CLAY_IMAGE({ .sourceDimensions = { 32, 32 }, .path = CLAY_STRING("resources/check.png") }));
|
||||
@ -93,11 +93,11 @@ void Layout() {
|
||||
}
|
||||
}
|
||||
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIXED(16) } }));
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(16) } }));
|
||||
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .childGap = 10, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childGap = 10, .layoutDirection = CLAY_TOP_TO_BOTTOM })) {
|
||||
CLAY_TEXT(CLAY_STRING("Cairo"), CLAY_TEXT_CONFIG({ .fontFamily = CLAY_STRING("Calistoga"), .fontSize = 24, .textColor = PRIMARY }));
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 10, 10 } }), CLAY_RECTANGLE({ .color = ACCENT, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(10) }), CLAY_RECTANGLE({ .color = ACCENT, .cornerRadius = CLAY_CORNER_RADIUS(10) })) {
|
||||
CLAY_TEXT(CLAY_STRING("Officiis quia quia qui inventore ratione voluptas et. Quidem sunt unde similique. Qui est et exercitationem cumque harum illum. Numquam placeat aliquid quo voluptatem. "
|
||||
"Deleniti saepe nihil exercitationem nemo illo. Consequatur beatae repellat provident similique. Provident qui exercitationem deserunt sapiente. Quam qui dolor corporis odit. "
|
||||
"Assumenda corrupti sunt culpa pariatur. Vero sit ut minima. In est consequatur minus et cum sint illum aperiam. Qui ipsa quas nisi omnis aut quia nobis. "
|
||||
|
@ -314,7 +314,7 @@
|
||||
|
||||
const importObject = {
|
||||
clay: {
|
||||
measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig) => {
|
||||
measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig, userData) => {
|
||||
let stringLength = memoryDataView.getUint32(textToMeasure, true);
|
||||
let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true);
|
||||
let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition);
|
||||
|
Binary file not shown.
@ -314,7 +314,7 @@
|
||||
|
||||
const importObject = {
|
||||
clay: {
|
||||
measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig) => {
|
||||
measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig, userData) => {
|
||||
let stringLength = memoryDataView.getUint32(textToMeasure, true);
|
||||
let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true);
|
||||
let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition);
|
||||
|
@ -41,18 +41,18 @@ Clay_TextElementConfig headerTextConfig = (Clay_TextElementConfig) { .fontId = 2
|
||||
Clay_TextElementConfig blobTextConfig = (Clay_TextElementConfig) { .fontId = 2, .fontSize = 30, .textColor = {244, 235, 230, 255} };
|
||||
|
||||
void LandingPageBlob(int index, int fontSize, Clay_Color color, Clay_String text, Clay_String imageURL) {
|
||||
CLAY(CLAY_IDI("HeroBlob", index), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 480 }) }, .padding = {16, 16}, .childGap = 16, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_BORDER_OUTSIDE_RADIUS(2, color, 10)) {
|
||||
CLAY(CLAY_IDI("HeroBlob", index), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 480) }, .padding = CLAY_PADDING_ALL(16), .childGap = 16, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_BORDER_OUTSIDE_RADIUS(2, color, 10)) {
|
||||
CLAY(CLAY_IDI("CheckImage", index), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED(32) } }), CLAY_IMAGE({ .sourceDimensions = { 128, 128 }, .sourceURL = imageURL })) {}
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .fontSize = fontSize, .fontId = FONT_ID_BODY_24, .textColor = color }));
|
||||
}
|
||||
}
|
||||
|
||||
void LandingPageDesktop() {
|
||||
CLAY(CLAY_ID("LandingPage1Desktop"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT({ .min = windowHeight - 70 }) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { .x = 50 } })) {
|
||||
CLAY(CLAY_ID("LandingPage1"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { 32, 32 }, .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("LandingPage1Desktop"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(.min = windowHeight - 70) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } })) {
|
||||
CLAY(CLAY_ID("LandingPage1"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_PERCENT(0.55f) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance."), CLAY_TEXT_CONFIG({ .fontSize = 56, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
|
||||
CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(32) } })) {}
|
||||
CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } })) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay is laying out this webpage right now!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE }));
|
||||
}
|
||||
CLAY(CLAY_ID("HeroImageOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_PERCENT(0.45f) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 })) {
|
||||
@ -67,13 +67,13 @@ void LandingPageDesktop() {
|
||||
}
|
||||
|
||||
void LandingPageMobile() {
|
||||
CLAY(CLAY_ID("LandingPage1Mobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT({ .min = windowHeight - 70 }) }, .childAlignment = {CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = { 16, 32 }, .childGap = 32 })) {
|
||||
CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW() }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("LandingPage1Mobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(.min = windowHeight - 70) }, .childAlignment = {CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = { 16, 16, 32, 32 }, .childGap = 32 })) {
|
||||
CLAY(CLAY_ID("LeftText"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance."), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
|
||||
CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(32) } })) {}
|
||||
CLAY(CLAY_ID("LandingPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } })) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay is laying out this webpage right now!"), CLAY_TEXT_CONFIG({ .fontSize = 32, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE }));
|
||||
}
|
||||
CLAY(CLAY_ID("HeroImageOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW() }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 })) {
|
||||
CLAY(CLAY_ID("HeroImageOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { CLAY_ALIGN_X_CENTER }, .childGap = 16 })) {
|
||||
LandingPageBlob(1, 28, COLOR_BLOB_BORDER_5, CLAY_STRING("High performance"), CLAY_STRING("/clay/images/check_5.png"));
|
||||
LandingPageBlob(2, 28, COLOR_BLOB_BORDER_4, CLAY_STRING("Flexbox-style responsive layout"), CLAY_STRING("/clay/images/check_4.png"));
|
||||
LandingPageBlob(3, 28, COLOR_BLOB_BORDER_3, CLAY_STRING("Declarative syntax"), CLAY_STRING("/clay/images/check_3.png"));
|
||||
@ -84,17 +84,17 @@ void LandingPageMobile() {
|
||||
}
|
||||
|
||||
void FeatureBlocksDesktop() {
|
||||
CLAY(CLAY_ID("FeatureBlocksOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() } })) {
|
||||
CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("FeatureBlocksOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) } })) {
|
||||
CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) {
|
||||
Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED });
|
||||
CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {50, 32}, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {50, 50, 32, 32}, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("HFileIncludeOuter"), CLAY_LAYOUT({ .padding = {8, 4} }), CLAY_RECTANGLE({ .color = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) })) {
|
||||
CLAY_TEXT(CLAY_STRING("#include clay.h"), CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY_TEXT(CLAY_STRING("~2000 lines of C99."), textConfig);
|
||||
CLAY_TEXT(CLAY_STRING("Zero dependencies, including no C standard library."), textConfig);
|
||||
}
|
||||
CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 50, .y = 32}, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_PERCENT(0.5f) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {50, 50, 32, 32}, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Renderer agnostic."), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = COLOR_ORANGE }));
|
||||
CLAY_TEXT(CLAY_STRING("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML."), textConfig);
|
||||
CLAY_TEXT(CLAY_STRING("Flexible output for easy compositing in your custom engine or environment."), textConfig);
|
||||
@ -104,16 +104,16 @@ void FeatureBlocksDesktop() {
|
||||
}
|
||||
|
||||
void FeatureBlocksMobile() {
|
||||
CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW() } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("FeatureBlocksInner"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) } }), CLAY_BORDER({ .betweenChildren = { .width = 2, .color = COLOR_RED } })) {
|
||||
Clay_TextElementConfig *textConfig = CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_RED });
|
||||
CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW() }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {16, 32}, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("HFileBoxOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("HFileIncludeOuter"), CLAY_LAYOUT({ .padding = {8, 4} }), CLAY_RECTANGLE({ .color = COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(8) })) {
|
||||
CLAY_TEXT(CLAY_STRING("#include clay.h"), CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_BODY_24, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY_TEXT(CLAY_STRING("~2000 lines of C99."), textConfig);
|
||||
CLAY_TEXT(CLAY_STRING("Zero dependencies, including no C standard library."), textConfig);
|
||||
}
|
||||
CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW() }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 16, .y = 32}, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("BringYourOwnRendererOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Renderer agnostic."), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = COLOR_ORANGE }));
|
||||
CLAY_TEXT(CLAY_STRING("Layout with clay, then render with Raylib, WebGL Canvas or even as HTML."), textConfig);
|
||||
CLAY_TEXT(CLAY_STRING("Flexible output for easy compositing in your custom engine or environment."), textConfig);
|
||||
@ -122,33 +122,33 @@ void FeatureBlocksMobile() {
|
||||
}
|
||||
|
||||
void DeclarativeSyntaxPageDesktop() {
|
||||
CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT({ .min = windowHeight - 50 }) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 50} })) {
|
||||
CLAY(CLAY_ID("SyntaxPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = { 32, 32 }, .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } })) {
|
||||
CLAY(CLAY_ID("SyntaxPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("SyntaxPageLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Declarative Syntax"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
|
||||
CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 16 }) } })) {}
|
||||
CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) } })) {}
|
||||
CLAY_TEXT(CLAY_STRING("Flexible and readable declarative syntax with nested UI element hierarchies."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Mix elements with standard C code like loops, conditionals and functions."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Create your own library of re-usable components from UI primitives like text, images and rectangles."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY(CLAY_ID("SyntaxPageRightImage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} })) {
|
||||
CLAY(CLAY_ID("SyntaxPageRightImageInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 568 }) } }), CLAY_IMAGE({ .sourceDimensions = {1136, 1194}, .sourceURL = CLAY_STRING("/clay/images/declarative.png") })) {}
|
||||
CLAY(CLAY_ID("SyntaxPageRightImageInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 568) } }), CLAY_IMAGE({ .sourceDimensions = {1136, 1194}, .sourceURL = CLAY_STRING("/clay/images/declarative.png") })) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeclarativeSyntaxPageMobile() {
|
||||
CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT({ .min = windowHeight - 50 }) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {16, 32}, .childGap = 16 })) {
|
||||
CLAY(CLAY_ID("SyntaxPageLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("SyntaxPageDesktop"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 16 })) {
|
||||
CLAY(CLAY_ID("SyntaxPageLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Declarative Syntax"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
|
||||
CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 16 }) } })) {}
|
||||
CLAY(CLAY_ID("SyntaxSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) } })) {}
|
||||
CLAY_TEXT(CLAY_STRING("Flexible and readable declarative syntax with nested UI element hierarchies."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Mix elements with standard C code like loops, conditionals and functions."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Create your own library of re-usable components from UI primitives like text, images and rectangles."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY(CLAY_ID("SyntaxPageRightImage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} })) {
|
||||
CLAY(CLAY_ID("SyntaxPageRightImageInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 568 }) } }), CLAY_IMAGE({ .sourceDimensions = {1136, 1194}, .sourceURL = CLAY_STRING("/clay/images/declarative.png") } )) {}
|
||||
CLAY(CLAY_ID("SyntaxPageRightImage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER} })) {
|
||||
CLAY(CLAY_ID("SyntaxPageRightImageInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 568) } }), CLAY_IMAGE({ .sourceDimensions = {1136, 1194}, .sourceURL = CLAY_STRING("/clay/images/declarative.png") } )) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,20 +165,20 @@ Clay_Color ColorLerp(Clay_Color a, Clay_Color b, float amount) {
|
||||
Clay_String LOREM_IPSUM_TEXT = CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
|
||||
|
||||
void HighPerformancePageDesktop(float lerpValue) {
|
||||
CLAY(CLAY_ID("PerformancePageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT({ .min = windowHeight - 50 }) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 82, 32}, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("PerformanceOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {82, 82, 32, 32}, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("PerformanceLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("High Performance"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 16 }) }})) {}
|
||||
CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
|
||||
CLAY_TEXT(CLAY_STRING("Fast enough to recompute your entire UI every frame."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Small memory footprint (3.5mb default) with static allocation & reuse. No malloc / free."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Simplify animations and reactive UI design by avoiding the standard performance hacks."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY(CLAY_ID("PerformanceRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.3f + 0.4f * lerpValue), CLAY_SIZING_GROW() }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {32, 32} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.3f + 0.4f * lerpValue), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) {
|
||||
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {32, 32} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(32) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) {
|
||||
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
}
|
||||
@ -187,20 +187,20 @@ void HighPerformancePageDesktop(float lerpValue) {
|
||||
}
|
||||
|
||||
void HighPerformancePageMobile(float lerpValue) {
|
||||
CLAY(CLAY_ID("PerformancePageOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT({ .min = windowHeight - 50 }) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 16, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("PerformanceLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("PerformanceOuter"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}, .padding = {16, 16, 32, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("PerformanceLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("High Performance"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 16 }) }})) {}
|
||||
CLAY(CLAY_ID("PerformanceSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
|
||||
CLAY_TEXT(CLAY_STRING("Fast enough to recompute your entire UI every frame."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Small memory footprint (3.5mb default) with static allocation & reuse. No malloc / free."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("Simplify animations and reactive UI design by avoiding the standard performance hacks."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY(CLAY_ID("PerformanceRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) {
|
||||
CLAY(CLAY_ID(""), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.35f + 0.3f * lerpValue), CLAY_SIZING_GROW() }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) {
|
||||
CLAY(CLAY_ID("PerformanceRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) {
|
||||
CLAY(CLAY_ID(""), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(400) } }), CLAY_BORDER_ALL({ .width = 2, .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.35f + 0.3f * lerpValue), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(16) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue) })) {
|
||||
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) {
|
||||
CLAY(CLAY_ID("AnimationDemoContainerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER}, .padding = CLAY_PADDING_ALL(16) }), CLAY_RECTANGLE({ .color = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue) })) {
|
||||
CLAY_TEXT(LOREM_IPSUM_TEXT, CLAY_TEXT_CONFIG({ .fontSize = 24, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
}
|
||||
}
|
||||
@ -217,7 +217,7 @@ void HandleRendererButtonInteraction(Clay_ElementId elementId, Clay_PointerData
|
||||
}
|
||||
|
||||
void RendererButtonActive(Clay_String text) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300) }, .padding = {16, 16} }),
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300) }, .padding = CLAY_PADDING_ALL(16) }),
|
||||
CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_RED_HOVER : COLOR_RED, .cornerRadius = CLAY_CORNER_RADIUS(10) })
|
||||
) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
@ -225,7 +225,7 @@ void RendererButtonActive(Clay_String text) {
|
||||
}
|
||||
|
||||
void RendererButtonInactive(Clay_String text, size_t rendererIndex) {
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300)}, .padding = {16, 16} }),
|
||||
CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(300)}, .padding = CLAY_PADDING_ALL(16) }),
|
||||
CLAY_BORDER_OUTSIDE_RADIUS(2, COLOR_RED, 10),
|
||||
CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT, .cornerRadius = CLAY_CORNER_RADIUS(10), .cursorPointer = true }),
|
||||
Clay_OnHover(HandleRendererButtonInteraction, rendererIndex)
|
||||
@ -235,18 +235,18 @@ void RendererButtonInactive(Clay_String text, size_t rendererIndex) {
|
||||
}
|
||||
|
||||
void RendererPageDesktop() {
|
||||
CLAY(CLAY_ID("RendererPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT({ .min = windowHeight - 50 }) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 50} })) {
|
||||
CLAY(CLAY_ID("RendererPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = { 32, 32 }, .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("RendererPageDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 50, 50 } })) {
|
||||
CLAY(CLAY_ID("RendererPage"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .padding = CLAY_PADDING_ALL(32), .childGap = 32 }), CLAY_BORDER({ .left = { 2, COLOR_RED }, .right = { 2, COLOR_RED } })) {
|
||||
CLAY(CLAY_ID("RendererLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Renderer & Platform Agnostic"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
|
||||
CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 16 }) }})) {}
|
||||
CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay outputs a sorted array of primitive render commands, such as RECTANGLE, TEXT or IMAGE."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Write your own renderer in a few hundred lines of code, or use the provided examples for Raylib, WebGL canvas and more."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("There's even an HTML renderer - you're looking at it right now!"), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY(CLAY_ID("RendererRightText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .childAlignment = {CLAY_ALIGN_X_CENTER}, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Try changing renderer!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_BODY_36, .textColor = COLOR_ORANGE }));
|
||||
CLAY(CLAY_ID("RendererSpacerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 32 }) } })) {}
|
||||
CLAY(CLAY_ID("RendererSpacerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 32) } })) {}
|
||||
if (ACTIVE_RENDERER_INDEX == 0) {
|
||||
RendererButtonActive(CLAY_STRING("HTML Renderer"));
|
||||
RendererButtonInactive(CLAY_STRING("Canvas Renderer"), 1);
|
||||
@ -260,17 +260,17 @@ void RendererPageDesktop() {
|
||||
}
|
||||
|
||||
void RendererPageMobile() {
|
||||
CLAY(CLAY_ID("RendererMobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT({ .min = windowHeight - 50 }) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = {.x = 16, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("RendererLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY(CLAY_ID("RendererMobile"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {.x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER}, .padding = { 16, 16, 32, 32}, .childGap = 32 }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("RendererLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Renderer & Platform Agnostic"), CLAY_TEXT_CONFIG({ .fontSize = 48, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_RED }));
|
||||
CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 16 }) }})) {}
|
||||
CLAY(CLAY_ID("RendererSpacerLeft"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay outputs a sorted array of primitive render commands, such as RECTANGLE, TEXT or IMAGE."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("Write your own renderer in a few hundred lines of code, or use the provided examples for Raylib, WebGL canvas and more."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
CLAY_TEXT(CLAY_STRING("There's even an HTML renderer - you're looking at it right now!"), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_RED }));
|
||||
}
|
||||
CLAY(CLAY_ID("RendererRightText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 })) {
|
||||
CLAY(CLAY_ID("RendererRightText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 16 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Try changing renderer!"), CLAY_TEXT_CONFIG({ .fontSize = 36, .fontId = FONT_ID_BODY_36, .textColor = COLOR_ORANGE }));
|
||||
CLAY(CLAY_ID("RendererSpacerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 32}) }})) {}
|
||||
CLAY(CLAY_ID("RendererSpacerRight"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 32) }})) {}
|
||||
if (ACTIVE_RENDERER_INDEX == 0) {
|
||||
RendererButtonActive(CLAY_STRING("HTML Renderer"));
|
||||
RendererButtonInactive(CLAY_STRING("Canvas Renderer"), 1);
|
||||
@ -283,17 +283,17 @@ void RendererPageMobile() {
|
||||
}
|
||||
|
||||
void DebuggerPageDesktop() {
|
||||
CLAY(CLAY_ID("DebuggerDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIT({ .min = windowHeight - 50 }) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = {.x = 82, 32}, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("DebuggerDesktop"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIT(.min = windowHeight - 50) }, .childAlignment = {0, CLAY_ALIGN_Y_CENTER}, .padding = { 82, 82, 32, 32 }, .childGap = 64 }), CLAY_RECTANGLE({ .color = COLOR_RED })) {
|
||||
CLAY(CLAY_ID("DebuggerLeftText"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.5) }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .childGap = 8 })) {
|
||||
CLAY_TEXT(CLAY_STRING("Integrated Debug Tools"), CLAY_TEXT_CONFIG({ .fontSize = 52, .fontId = FONT_ID_TITLE_56, .textColor = COLOR_LIGHT }));
|
||||
CLAY(CLAY_ID("DebuggerSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 16 }) }})) {}
|
||||
CLAY(CLAY_ID("DebuggerSpacer"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 16) }})) {}
|
||||
CLAY_TEXT(CLAY_STRING("Clay includes built in \"Chrome Inspector\"-style debug tooling."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY_TEXT(CLAY_STRING("View your layout hierarchy and config in real time."), CLAY_TEXT_CONFIG({ .fontSize = 28, .fontId = FONT_ID_BODY_36, .textColor = COLOR_LIGHT }));
|
||||
CLAY(CLAY_ID("DebuggerPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(32) } })) {}
|
||||
CLAY(CLAY_ID("DebuggerPageSpacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(32) } })) {}
|
||||
CLAY_TEXT(CLAY_STRING("Press the \"d\" key to try it out now!"), CLAY_TEXT_CONFIG({ .fontSize = 32, .fontId = FONT_ID_TITLE_36, .textColor = COLOR_ORANGE }));
|
||||
}
|
||||
CLAY(CLAY_ID("DebuggerRightImageOuter"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_PERCENT(0.50) }, .childAlignment = {CLAY_ALIGN_X_CENTER} })) {
|
||||
CLAY(CLAY_ID("DebuggerPageRightImageInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW({ .max = 558 }) } }), CLAY_IMAGE({ .sourceDimensions = {1620, 1474}, .sourceURL = CLAY_STRING("/clay/images/debugger.png") })) {}
|
||||
CLAY(CLAY_ID("DebuggerPageRightImageInner"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(.max = 558) } }), CLAY_IMAGE({ .sourceDimensions = {1620, 1474}, .sourceURL = CLAY_STRING("/clay/images/debugger.png") })) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,19 +310,19 @@ float animationLerpValue = -1.0f;
|
||||
|
||||
Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
|
||||
Clay_BeginLayout();
|
||||
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() } }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("Header"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIXED(50) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = { 32 } })) {
|
||||
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) } }), CLAY_RECTANGLE({ .color = COLOR_LIGHT })) {
|
||||
CLAY(CLAY_ID("Header"), CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(50) }, .childAlignment = { 0, CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = { 32, 32 } })) {
|
||||
CLAY_TEXT(CLAY_STRING("Clay"), &headerTextConfig);
|
||||
CLAY(CLAY_ID("Spacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW() } })) {}
|
||||
CLAY(CLAY_ID("Spacer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) } })) {}
|
||||
if (!mobileScreen) {
|
||||
CLAY(CLAY_ID("LinkExamplesOuter"), CLAY_LAYOUT({ .padding = {8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples"), .color = {0,0,0,0} })) {
|
||||
CLAY(CLAY_ID("LinkExamplesOuter"), CLAY_LAYOUT({ .padding = {8, 8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/tree/main/examples"), .color = {0,0,0,0} })) {
|
||||
CLAY_TEXT(CLAY_STRING("Examples"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
}
|
||||
CLAY(CLAY_ID("LinkDocsOuter"), CLAY_LAYOUT({ .padding = {8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md"), .color = {0,0,0,0} })) {
|
||||
CLAY(CLAY_ID("LinkDocsOuter"), CLAY_LAYOUT({ .padding = {8, 8} }), CLAY_RECTANGLE({ .link = CLAY_STRING("https://github.com/nicbarker/clay/blob/main/README.md"), .color = {0,0,0,0} })) {
|
||||
CLAY_TEXT(CLAY_STRING("Docs"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
}
|
||||
}
|
||||
CLAY(CLAY_LAYOUT({ .padding = {16, 6} }),
|
||||
CLAY(CLAY_LAYOUT({ .padding = {16, 16, 6, 6} }),
|
||||
CLAY_RECTANGLE({
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||
.link = CLAY_STRING("https://discord.gg/b4FTWkxdvT"),
|
||||
@ -331,21 +331,21 @@ Clay_RenderCommandArray CreateLayout(bool mobileScreen, float lerpValue) {
|
||||
) {
|
||||
CLAY_TEXT(CLAY_STRING("Discord"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
}
|
||||
CLAY(CLAY_LAYOUT({ .padding = {16, 6} }),
|
||||
CLAY(CLAY_LAYOUT({ .padding = {16, 16, 6, 6} }),
|
||||
CLAY_RECTANGLE({ .cornerRadius = CLAY_CORNER_RADIUS(10), .link = CLAY_STRING("https://github.com/nicbarker/clay"), .color = Clay_Hovered() ? COLOR_LIGHT_HOVER : COLOR_LIGHT }),
|
||||
CLAY_BORDER_OUTSIDE_RADIUS(2, COLOR_RED, 10)
|
||||
) {
|
||||
CLAY_TEXT(CLAY_STRING("Github"), CLAY_TEXT_CONFIG({ .disablePointerEvents = true, .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {61, 26, 5, 255} }));
|
||||
}
|
||||
}
|
||||
Clay_LayoutConfig topBorderConfig = (Clay_LayoutConfig) { .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIXED(4) }};
|
||||
Clay_LayoutConfig topBorderConfig = (Clay_LayoutConfig) { .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_FIXED(4) }};
|
||||
CLAY(CLAY_ID("TopBorder1"), CLAY_LAYOUT(topBorderConfig), CLAY_RECTANGLE({ .color = COLOR_TOP_BORDER_5 })) {}
|
||||
CLAY(CLAY_ID("TopBorder2"), CLAY_LAYOUT(topBorderConfig), CLAY_RECTANGLE({ .color = COLOR_TOP_BORDER_4 })) {}
|
||||
CLAY(CLAY_ID("TopBorder3"), CLAY_LAYOUT(topBorderConfig), CLAY_RECTANGLE({ .color = COLOR_TOP_BORDER_3 })) {}
|
||||
CLAY(CLAY_ID("TopBorder4"), CLAY_LAYOUT(topBorderConfig), CLAY_RECTANGLE({ .color = COLOR_TOP_BORDER_2 })) {}
|
||||
CLAY(CLAY_ID("TopBorder5"), CLAY_LAYOUT(topBorderConfig), CLAY_RECTANGLE({ .color = COLOR_TOP_BORDER_1 })) {}
|
||||
CLAY(CLAY_ID("OuterScrollContainer"),
|
||||
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_GROW() }, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
|
||||
CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0), CLAY_SIZING_GROW(0) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
|
||||
CLAY_SCROLL({ .vertical = true }),
|
||||
CLAY_BORDER({ .betweenChildren = {2, COLOR_RED} })
|
||||
) {
|
||||
@ -391,10 +391,10 @@ CLAY_WASM_EXPORT("UpdateDrawFrame") Clay_RenderCommandArray UpdateDrawFrame(floa
|
||||
windowHeight = height;
|
||||
Clay_SetLayoutDimensions((Clay_Dimensions) { width, height });
|
||||
Clay_ScrollContainerData scrollContainerData = Clay_GetScrollContainerData(Clay_GetElementId(CLAY_STRING("OuterScrollContainer")));
|
||||
Clay_LayoutElementHashMapItem *perfPage = Clay__GetHashMapItem(Clay_GetElementId(CLAY_STRING("PerformancePageOuter")).id);
|
||||
Clay_LayoutElementHashMapItem *perfPage = Clay__GetHashMapItem(Clay_GetElementId(CLAY_STRING("PerformanceOuter")).id);
|
||||
// NaN propagation can cause pain here
|
||||
float perfPageYOffset = perfPage->boundingBox.y + scrollContainerData.scrollPosition->y;
|
||||
if (deltaTime == deltaTime && perfPageYOffset < height && perfPageYOffset + perfPage->boundingBox.height > 0) {
|
||||
if (deltaTime == deltaTime && (ACTIVE_RENDERER_INDEX == 1 || (perfPageYOffset < height && perfPageYOffset + perfPage->boundingBox.height > 0))) {
|
||||
animationLerpValue += deltaTime;
|
||||
if (animationLerpValue > 1) {
|
||||
animationLerpValue -= 2;
|
||||
|
@ -2,11 +2,15 @@ cmake_minimum_required(VERSION 3.27)
|
||||
project(clay_examples_cpp_project_example CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -g")
|
||||
endif()
|
||||
|
||||
add_executable(clay_examples_cpp_project_example main.cpp)
|
||||
|
||||
target_include_directories(clay_examples_cpp_project_example PUBLIC .)
|
||||
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Werror -Wall")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
endif()
|
||||
|
@ -25,8 +25,12 @@ target_include_directories(clay_examples_introducing_clay_video_demo PUBLIC .)
|
||||
|
||||
target_link_libraries(clay_examples_introducing_clay_video_demo PUBLIC raylib)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS_DEBUG "/D CLAY_DEBUG")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror -Wno-error=missing-braces -DCLAY_DEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET clay_examples_introducing_clay_video_demo POST_BUILD
|
||||
|
@ -7,7 +7,7 @@ Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
|
||||
|
||||
void RenderHeaderButton(Clay_String text) {
|
||||
CLAY(
|
||||
CLAY_LAYOUT({ .padding = { 16, 8 }}),
|
||||
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 140, 140, 140, 255 },
|
||||
.cornerRadius = 5
|
||||
@ -22,7 +22,7 @@ void RenderHeaderButton(Clay_String text) {
|
||||
}
|
||||
|
||||
void RenderDropdownMenuItem(Clay_String text) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 16, 16 }})) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16)})) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 16,
|
||||
@ -84,7 +84,7 @@ int main(void) {
|
||||
.width = GetScreenWidth(),
|
||||
.height = GetScreenHeight()
|
||||
}, (Clay_ErrorHandler) { HandleClayErrors }); // This final argument is new since the video was published
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText);
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText, 0);
|
||||
Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) {
|
||||
.font = LoadFontEx("resources/Roboto-Regular.ttf", 48, 0, 400),
|
||||
.fontId = FONT_ID_BODY_16
|
||||
@ -111,8 +111,8 @@ int main(void) {
|
||||
);
|
||||
|
||||
Clay_Sizing layoutExpand = {
|
||||
.width = CLAY_SIZING_GROW(),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
.width = CLAY_SIZING_GROW(0),
|
||||
.height = CLAY_SIZING_GROW(0)
|
||||
};
|
||||
|
||||
Clay_RectangleElementConfig contentBackgroundConfig = {
|
||||
@ -128,7 +128,7 @@ int main(void) {
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = layoutExpand,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.childGap = 16
|
||||
})
|
||||
) {
|
||||
@ -139,7 +139,7 @@ int main(void) {
|
||||
CLAY_LAYOUT({
|
||||
.sizing = {
|
||||
.height = CLAY_SIZING_FIXED(60),
|
||||
.width = CLAY_SIZING_GROW()
|
||||
.width = CLAY_SIZING_GROW(0)
|
||||
},
|
||||
.padding = { 16 },
|
||||
.childGap = 16,
|
||||
@ -201,7 +201,7 @@ int main(void) {
|
||||
}
|
||||
}
|
||||
RenderHeaderButton(CLAY_STRING("Edit"));
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW() }})) {}
|
||||
CLAY(CLAY_LAYOUT({ .sizing = { CLAY_SIZING_GROW(0) }})) {}
|
||||
RenderHeaderButton(CLAY_STRING("Upload"));
|
||||
RenderHeaderButton(CLAY_STRING("Media"));
|
||||
RenderHeaderButton(CLAY_STRING("Support"));
|
||||
@ -216,19 +216,19 @@ int main(void) {
|
||||
CLAY_RECTANGLE(contentBackgroundConfig),
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.childGap = 8,
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(250),
|
||||
.height = CLAY_SIZING_GROW()
|
||||
.height = CLAY_SIZING_GROW(0)
|
||||
}
|
||||
})
|
||||
) {
|
||||
for (int i = 0; i < documents.length; i++) {
|
||||
Document document = documents.documents[i];
|
||||
Clay_LayoutConfig sidebarButtonLayout = {
|
||||
.sizing = { .width = CLAY_SIZING_GROW() },
|
||||
.padding = { 16, 16 }
|
||||
.sizing = { .width = CLAY_SIZING_GROW(0) },
|
||||
.padding = CLAY_PADDING_ALL(16)
|
||||
};
|
||||
|
||||
if (i == selectedDocumentIndex) {
|
||||
@ -273,7 +273,7 @@ int main(void) {
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 16,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.sizing = layoutExpand
|
||||
})
|
||||
) {
|
||||
|
@ -7,7 +7,7 @@ Clay_Color COLOR_WHITE = { 255, 255, 255, 255};
|
||||
|
||||
void RenderHeaderButton(Clay_String text) {
|
||||
CLAY(
|
||||
CLAY_LAYOUT({ .padding = { 16, 8 }}),
|
||||
CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = { 140, 140, 140, 255 },
|
||||
.cornerRadius = 5
|
||||
@ -22,7 +22,7 @@ void RenderHeaderButton(Clay_String text) {
|
||||
}
|
||||
|
||||
void RenderDropdownMenuItem(Clay_String text) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = { 16, 16 }})) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = CLAY_PADDING_ALL(16)})) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG({
|
||||
.fontId = FONT_ID_BODY_16,
|
||||
.fontSize = 16,
|
||||
@ -121,7 +121,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.sizing = layoutExpand,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.childGap = 16
|
||||
})
|
||||
) {
|
||||
@ -134,7 +134,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
|
||||
CLAY_RECTANGLE(contentBackgroundConfig),
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.childGap = 8,
|
||||
.sizing = {
|
||||
.width = CLAY_SIZING_FIXED(250),
|
||||
@ -146,7 +146,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
|
||||
Document document = documents.documents[i];
|
||||
Clay_LayoutConfig sidebarButtonLayout = {
|
||||
.sizing = { .width = CLAY_SIZING_GROW() },
|
||||
.padding = { 16, 16 }
|
||||
.padding = CLAY_PADDING_ALL(16)
|
||||
};
|
||||
|
||||
if (i == *documentIndex) {
|
||||
@ -194,7 +194,7 @@ Clay_RenderCommandArray CreateLayout(Clay_Context* context, float yOffset, int32
|
||||
CLAY_LAYOUT({
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.childGap = 16,
|
||||
.padding = { 16, 16 },
|
||||
.padding = CLAY_PADDING_ALL(16),
|
||||
.sizing = layoutExpand
|
||||
})
|
||||
) {
|
||||
@ -247,7 +247,7 @@ int main(void) {
|
||||
.height = GetScreenHeight() / 2
|
||||
}, (Clay_ErrorHandler) { HandleClayErrors }); // This final argument is new since the video was published
|
||||
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText);
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText, 0);
|
||||
Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) {
|
||||
.font = LoadFontEx("resources/Roboto-Regular.ttf", 48, 0, 400),
|
||||
.fontId = FONT_ID_BODY_16
|
||||
|
@ -24,9 +24,12 @@ target_compile_options(clay_examples_raylib_sidebar_scrolling_container PUBLIC)
|
||||
target_include_directories(clay_examples_raylib_sidebar_scrolling_container PUBLIC .)
|
||||
|
||||
target_link_libraries(clay_examples_raylib_sidebar_scrolling_container PUBLIC raylib)
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror -Wno-error=missing-braces -DCLAY_DEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3")
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS_DEBUG "/D CLAY_DEBUG")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Werror -DCLAY_DEBUG -fsanitize=address")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET clay_examples_raylib_sidebar_scrolling_container POST_BUILD
|
||||
|
@ -10,7 +10,7 @@ const uint32_t FONT_ID_BODY_16 = 1;
|
||||
Texture2D profilePicture;
|
||||
#define RAYLIB_VECTOR2_TO_CLAY_VECTOR2(vector) (Clay_Vector2) { .x = vector.x, .y = vector.y }
|
||||
|
||||
Clay_String profileText = {.length = 101, .chars = "Profile Page one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen" };
|
||||
Clay_String profileText = CLAY_STRING_CONST("Profile Page one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen");
|
||||
Clay_TextElementConfig headerTextConfig = { .fontId = 1, .fontSize = 16, .textColor = {0,0,0,255} };
|
||||
|
||||
void HandleHeaderButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData) {
|
||||
@ -21,14 +21,14 @@ void HandleHeaderButtonInteraction(Clay_ElementId elementId, Clay_PointerData po
|
||||
|
||||
// Examples of re-usable "Components"
|
||||
void RenderHeaderButton(Clay_String text) {
|
||||
CLAY(CLAY_LAYOUT({ .padding = {16, 8} }),
|
||||
CLAY(CLAY_LAYOUT({ .padding = {16, 16, 8, 8} }),
|
||||
CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }),
|
||||
Clay_OnHover(HandleHeaderButtonInteraction, 1)) {
|
||||
CLAY_TEXT(text, CLAY_TEXT_CONFIG(headerTextConfig));
|
||||
}
|
||||
}
|
||||
|
||||
Clay_LayoutConfig dropdownTextItemLayout = { .padding = {8, 4} };
|
||||
Clay_LayoutConfig dropdownTextItemLayout = { .padding = {8, 8, 4, 4} };
|
||||
Clay_RectangleElementConfig dropdownRectangleConfig = { .color = {180, 180, 180, 255} };
|
||||
Clay_TextElementConfig dropdownTextElementConfig = { .fontSize = 24, .textColor = {255,255,255,255} };
|
||||
|
||||
@ -40,32 +40,32 @@ void RenderDropdownTextItem(int index) {
|
||||
|
||||
Clay_RenderCommandArray CreateLayout() {
|
||||
Clay_BeginLayout();
|
||||
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .padding = { 16, 16 }, .childGap = 16 }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {
|
||||
CLAY(CLAY_ID("SideBar"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW() }, .padding = {16, 16}, .childGap = 16 }), CLAY_RECTANGLE({ .color = {150, 150, 255, 255} })) {
|
||||
CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW() }, .padding = { 8, 8 }, .childGap = 8, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_RECTANGLE({ .color = {130, 130, 255, 255} })) {
|
||||
CLAY(CLAY_ID("OuterContainer"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }, .padding = { 16, 16, 16, 16 }, .childGap = 16 }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {
|
||||
CLAY(CLAY_ID("SideBar"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_GROW(0) }, .padding = {16, 16, 16, 16 }, .childGap = 16 }), CLAY_RECTANGLE({ .color = {150, 150, 255, 255} })) {
|
||||
CLAY(CLAY_ID("ProfilePictureOuter"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .padding = { 8, 8, 8, 8 }, .childGap = 8, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER } }), CLAY_RECTANGLE({ .color = {130, 130, 255, 255} })) {
|
||||
CLAY(CLAY_ID("ProfilePicture"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) } }), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {}
|
||||
CLAY_TEXT(profileText, CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0, 0, 0, 255} }));
|
||||
}
|
||||
CLAY(CLAY_ID("SidebarBlob1"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
CLAY(CLAY_ID("SidebarBlob2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
CLAY(CLAY_ID("SidebarBlob3"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
CLAY(CLAY_ID("SidebarBlob4"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
CLAY(CLAY_ID("SidebarBlob1"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
CLAY(CLAY_ID("SidebarBlob2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
CLAY(CLAY_ID("SidebarBlob3"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
CLAY(CLAY_ID("SidebarBlob4"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(50) }}), CLAY_RECTANGLE({ .color = {110, 110, 255, 255} })) {}
|
||||
}
|
||||
|
||||
CLAY(CLAY_ID("RightPanel"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .childGap = 16 })) {
|
||||
CLAY(CLAY_ID("HeaderBar"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW() }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT }, .padding = {8, 8}, .childGap = 8 }), CLAY_RECTANGLE({ .color = {180, 180, 180, 255} })) {
|
||||
CLAY(CLAY_ID("RightPanel"), CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }, .childGap = 16 })) {
|
||||
CLAY(CLAY_ID("HeaderBar"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { .x = CLAY_ALIGN_X_RIGHT }, .padding = {8, 8, 8, 8 }, .childGap = 8 }), CLAY_RECTANGLE({ .color = {180, 180, 180, 255} })) {
|
||||
RenderHeaderButton(CLAY_STRING("Header Item 1"));
|
||||
RenderHeaderButton(CLAY_STRING("Header Item 2"));
|
||||
RenderHeaderButton(CLAY_STRING("Header Item 3"));
|
||||
}
|
||||
CLAY(CLAY_ID("MainContent"),
|
||||
CLAY_SCROLL({ .vertical = true }),
|
||||
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {16, 16}, .childGap = 16, .sizing = { CLAY_SIZING_GROW() } }),
|
||||
CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {16, 16, 16, 16}, .childGap = 16, .sizing = { CLAY_SIZING_GROW(0) } }),
|
||||
CLAY_RECTANGLE({ .color = {200, 200, 255, 255} }))
|
||||
{
|
||||
CLAY(CLAY_ID("FloatingContainer"),
|
||||
CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = { 16, 16 }}),
|
||||
CLAY_FLOATING({ .zIndex = 1, .attachment = { CLAY_ATTACH_POINT_CENTER_TOP, CLAY_ATTACH_POINT_CENTER_TOP }, .offset = {0, -16} }),
|
||||
CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = { 16, 16, 16, 16 }}),
|
||||
CLAY_FLOATING({ .zIndex = 1, .attachment = { CLAY_ATTACH_POINT_CENTER_TOP, CLAY_ATTACH_POINT_CENTER_TOP }, .offset = {0, 0} }),
|
||||
CLAY_BORDER_OUTSIDE({ .color = {80, 80, 80, 255}, .width = 2 }),
|
||||
CLAY_RECTANGLE({ .color = {140,80, 200, 200 }})
|
||||
) {
|
||||
@ -75,7 +75,7 @@ Clay_RenderCommandArray CreateLayout() {
|
||||
CLAY_TEXT(CLAY_STRING("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt."),
|
||||
CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {0,0,0,255} }));
|
||||
|
||||
CLAY(CLAY_ID("Photos2"), CLAY_LAYOUT({ .childGap = 16, .padding = { 16, 16 }}), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) {
|
||||
CLAY(CLAY_ID("Photos2"), CLAY_LAYOUT({ .childGap = 16, .padding = { 16, 16, 16, 16 }}), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) {
|
||||
CLAY(CLAY_ID("Picture4"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
|
||||
CLAY(CLAY_ID("Picture5"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
|
||||
CLAY(CLAY_ID("Picture6"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
|
||||
@ -87,9 +87,9 @@ Clay_RenderCommandArray CreateLayout() {
|
||||
CLAY_TEXT(CLAY_STRING("Suspendisse in est ante in nibh. Amet venenatis urna cursus eget nunc scelerisque viverra. Elementum sagittis vitae et leo duis ut diam quam nulla. Enim nulla aliquet porttitor lacus. Pellentesque habitant morbi tristique senectus et. Facilisi nullam vehicula ipsum a arcu cursus vitae.\nSem fringilla ut morbi tincidunt. Euismod quis viverra nibh cras pulvinar mattis nunc sed. Velit sed ullamcorper morbi tincidunt ornare massa. Varius quam quisque id diam vel quam. Nulla pellentesque dignissim enim sit amet venenatis. Enim lobortis scelerisque fermentum dui faucibus in. Pretium viverra suspendisse potenti nullam ac tortor vitae. Lectus vestibulum mattis ullamcorper velit sed. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum. Habitant morbi tristique senectus et. Integer vitae justo eget magna fermentum iaculis eu. Semper quis lectus nulla at volutpat diam. Enim praesent elementum facilisis leo. Massa vitae tortor condimentum lacinia quis vel."),
|
||||
CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0,0,0,255} }));
|
||||
|
||||
CLAY(CLAY_ID("Photos"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW() }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) {
|
||||
CLAY(CLAY_ID("Photos"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(0) }, .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }, .childGap = 16, .padding = {16, 16, 16, 16} }), CLAY_RECTANGLE({ .color = {180, 180, 220, 255} })) {
|
||||
CLAY(CLAY_ID("Picture2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(120), .height = CLAY_SIZING_FIXED(120) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {120, 120} })) {}
|
||||
CLAY(CLAY_ID("Picture1"), CLAY_LAYOUT({ .childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {8, 8} }), CLAY_RECTANGLE({ .color = {170, 170, 220, 255} })) {
|
||||
CLAY(CLAY_ID("Picture1"), CLAY_LAYOUT({ .childAlignment = { .x = CLAY_ALIGN_X_CENTER }, .layoutDirection = CLAY_TOP_TO_BOTTOM, .padding = {8, 8, 8, 8} }), CLAY_RECTANGLE({ .color = {170, 170, 220, 255} })) {
|
||||
CLAY(CLAY_ID("ProfilePicture2"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(60), .height = CLAY_SIZING_FIXED(60) }}), CLAY_IMAGE({ .imageData = &profilePicture, .sourceDimensions = {60, 60} })) {}
|
||||
CLAY_TEXT(CLAY_STRING("Image caption below"), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {0,0,0,255} }));
|
||||
}
|
||||
@ -104,7 +104,7 @@ Clay_RenderCommandArray CreateLayout() {
|
||||
CLAY(CLAY_ID("Blob4Floating2"), CLAY_FLOATING({ .zIndex = 1, .parentId = Clay_GetElementId(CLAY_STRING("SidebarBlob4")).id })) {
|
||||
CLAY(CLAY_ID("ScrollContainer"), CLAY_LAYOUT({ .sizing = { .height = CLAY_SIZING_FIXED(200) }, .childGap = 2 }), CLAY_SCROLL({ .vertical = true })) {
|
||||
CLAY(CLAY_ID("FloatingContainer2"), CLAY_LAYOUT({ }), CLAY_FLOATING({ .zIndex = 1 })) {
|
||||
CLAY(CLAY_ID("FloatingContainerInner"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = {16, 16} }), CLAY_RECTANGLE({ .color = {140,80, 200, 200} })) {
|
||||
CLAY(CLAY_ID("FloatingContainerInner"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_FIXED(300), .height = CLAY_SIZING_FIXED(300) }, .padding = {16, 16, 16, 16} }), CLAY_RECTANGLE({ .color = {140,80, 200, 200} })) {
|
||||
CLAY_TEXT(CLAY_STRING("I'm an inline floating container."), CLAY_TEXT_CONFIG({ .fontSize = 24, .textColor = {255,255,255,255} }));
|
||||
}
|
||||
}
|
||||
@ -218,8 +218,8 @@ void HandleClayErrors(Clay_ErrorData errorData) {
|
||||
int main(void) {
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText);
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() }, (Clay_ErrorHandler) { HandleClayErrors });
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText, 0);
|
||||
Clay_Raylib_Initialize(1024, 768, "Clay - Raylib Renderer Example", FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT);
|
||||
profilePicture = LoadTextureFromImage(LoadImage("resources/profile-picture.png"));
|
||||
Raylib_fonts[FONT_ID_BODY_24] = (Raylib_Font) {
|
||||
|
@ -4,22 +4,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static NVGcontext *NVG;
|
||||
|
||||
static void Clay_NanoVG_RenderInit(NVGcontext *nvg)
|
||||
static Clay_Dimensions Clay_NanoVG_MeasureText(Clay_StringSlice text, Clay_TextElementConfig* config, uintptr_t user)
|
||||
{
|
||||
NVG = nvg;
|
||||
}
|
||||
|
||||
static Clay_Dimensions Clay_NanoVG_MeasureText(Clay_String* text, Clay_TextElementConfig* config)
|
||||
{
|
||||
nvgFontFaceId(NVG, config->fontId);
|
||||
nvgFontSize(NVG, config->fontSize);
|
||||
nvgTextLineHeight(NVG, config->lineHeight);
|
||||
nvgTextLetterSpacing(NVG, config->letterSpacing);
|
||||
nvgTextAlign(NVG, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
|
||||
NVGcontext* nvg = (NVGcontext*)user;
|
||||
nvgFontFaceId(nvg, config->fontId);
|
||||
nvgFontSize(nvg, config->fontSize);
|
||||
nvgTextLineHeight(nvg, config->lineHeight);
|
||||
nvgTextLetterSpacing(nvg, config->letterSpacing);
|
||||
nvgTextAlign(nvg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
|
||||
float bounds[4];
|
||||
nvgTextBounds(NVG, 0, 0, text->chars, text->chars + text->length, bounds);
|
||||
nvgTextBounds(nvg, 0, 0, text.chars, text.chars + text.length, bounds);
|
||||
return (Clay_Dimensions) {
|
||||
.width = bounds[2],
|
||||
.height = bounds[3],
|
||||
|
@ -1,7 +1,5 @@
|
||||
Please note, the SDL2 renderer is not 100% feature complete. It is currently missing:
|
||||
|
||||
- Border rendering
|
||||
- Image rendering
|
||||
- Rounded rectangle corners
|
||||
|
||||
Note: on Mac OSX, SDL2 for some reason decides to automatically disable momentum scrolling on macbook trackpads.
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include "../../clay.h"
|
||||
#include <SDL.h>
|
||||
#include <SDL_ttf.h>
|
||||
#include <SDL_image.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CLAY_COLOR_TO_SDL_COLOR_ARGS(color) color.r, color.g, color.b, color.a
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -8,13 +12,14 @@ typedef struct
|
||||
TTF_Font *font;
|
||||
} SDL2_Font;
|
||||
|
||||
static SDL2_Font SDL2_fonts[1];
|
||||
|
||||
static Clay_Dimensions SDL2_MeasureText(Clay_String *text, Clay_TextElementConfig *config)
|
||||
static Clay_Dimensions SDL2_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData)
|
||||
{
|
||||
TTF_Font *font = SDL2_fonts[config->fontId].font;
|
||||
char *chars = (char *)calloc(text->length + 1, 1);
|
||||
memcpy(chars, text->chars, text->length);
|
||||
SDL2_Font *fonts = (SDL2_Font*)userData;
|
||||
|
||||
TTF_Font *font = fonts[config->fontId].font;
|
||||
char *chars = (char *)calloc(text.length + 1, 1);
|
||||
memcpy(chars, text.chars, text.length);
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
if (TTF_SizeUTF8(font, chars, &width, &height) < 0) {
|
||||
@ -30,7 +35,7 @@ static Clay_Dimensions SDL2_MeasureText(Clay_String *text, Clay_TextElementConfi
|
||||
|
||||
SDL_Rect currentClippingRectangle;
|
||||
|
||||
static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray renderCommands)
|
||||
static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray renderCommands, SDL2_Font *fonts)
|
||||
{
|
||||
for (uint32_t i = 0; i < renderCommands.length; i++)
|
||||
{
|
||||
@ -56,7 +61,7 @@ static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray ren
|
||||
Clay_String text = renderCommand->text;
|
||||
char *cloned = (char *)calloc(text.length + 1, 1);
|
||||
memcpy(cloned, text.chars, text.length);
|
||||
TTF_Font* font = SDL2_fonts[config->fontId].font;
|
||||
TTF_Font* font = fonts[config->fontId].font;
|
||||
SDL_Surface *surface = TTF_RenderUTF8_Blended(font, cloned, (SDL_Color) {
|
||||
.r = (Uint8)config->textColor.r,
|
||||
.g = (Uint8)config->textColor.g,
|
||||
@ -92,6 +97,51 @@ static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray ren
|
||||
SDL_RenderSetClipRect(renderer, NULL);
|
||||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
|
||||
SDL_Surface *image = (SDL_Surface *)renderCommand->config.imageElementConfig->imageData;
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image);
|
||||
|
||||
SDL_Rect destination = (SDL_Rect){
|
||||
.x = boundingBox.x,
|
||||
.y = boundingBox.y,
|
||||
.w = boundingBox.width,
|
||||
.h = boundingBox.height,
|
||||
};
|
||||
|
||||
SDL_RenderCopy(renderer, texture, NULL, &destination);
|
||||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_BORDER: {
|
||||
Clay_BorderElementConfig *config = renderCommand->config.borderElementConfig;
|
||||
|
||||
if (config->left.width > 0) {
|
||||
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->left.color));
|
||||
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x, boundingBox.y + config->cornerRadius.topLeft, config->left.width, boundingBox.height - config->cornerRadius.topLeft - config->cornerRadius.bottomLeft });
|
||||
}
|
||||
|
||||
if (config->right.width > 0) {
|
||||
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color));
|
||||
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + boundingBox.width - config->right.width, boundingBox.y + config->cornerRadius.topRight, config->right.width, boundingBox.height - config->cornerRadius.topRight - config->cornerRadius.bottomRight });
|
||||
}
|
||||
|
||||
if (config->right.width > 0) {
|
||||
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color));
|
||||
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + boundingBox.width - config->right.width, boundingBox.y + config->cornerRadius.topRight, config->right.width, boundingBox.height - config->cornerRadius.topRight - config->cornerRadius.bottomRight });
|
||||
}
|
||||
|
||||
if (config->top.width > 0) {
|
||||
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color));
|
||||
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + config->cornerRadius.topLeft, boundingBox.y, boundingBox.width - config->cornerRadius.topLeft - config->cornerRadius.topRight, config->top.width });
|
||||
}
|
||||
|
||||
if (config->bottom.width > 0) {
|
||||
SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->bottom.color));
|
||||
SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + config->cornerRadius.bottomLeft, boundingBox.y + boundingBox.height - config->bottom.width, boundingBox.width - config->cornerRadius.bottomLeft - config->cornerRadius.bottomRight, config->bottom.width });
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
fprintf(stderr, "Error: unhandled render command: %d\n", renderCommand->commandType);
|
||||
exit(1);
|
||||
|
6
renderers/SDL3/README
Normal file
6
renderers/SDL3/README
Normal file
@ -0,0 +1,6 @@
|
||||
Please note, the SDL3 renderer is not 100% feature complete. It is currently missing:
|
||||
|
||||
- Rounded rectangle corners
|
||||
- Borders
|
||||
- Images
|
||||
- Scroll / Scissor handling
|
41
renderers/SDL3/clay_renderer_SDL3.c
Normal file
41
renderers/SDL3/clay_renderer_SDL3.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "../../clay.h"
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_ttf/SDL_ttf.h>
|
||||
|
||||
/* This needs to be global because the "MeasureText" callback doesn't have a
|
||||
* user data parameter */
|
||||
static TTF_Font *gFonts[1];
|
||||
|
||||
static void SDL_RenderClayCommands(SDL_Renderer *renderer, Clay_RenderCommandArray *rcommands)
|
||||
{
|
||||
for (size_t i = 0; i < rcommands->length; i++) {
|
||||
Clay_RenderCommand *rcmd = Clay_RenderCommandArray_Get(rcommands, i);
|
||||
Clay_BoundingBox bounding_box = rcmd->boundingBox;
|
||||
const SDL_FRect rect = { bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height };
|
||||
|
||||
switch (rcmd->commandType) {
|
||||
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
|
||||
Clay_RectangleElementConfig *config = rcmd->config.rectangleElementConfig;
|
||||
Clay_Color color = config->color;
|
||||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
} break;
|
||||
case CLAY_RENDER_COMMAND_TYPE_TEXT: {
|
||||
Clay_TextElementConfig *config = rcmd->config.textElementConfig;
|
||||
Clay_String *text = &rcmd->text;
|
||||
SDL_Color color = { config->textColor.r, config->textColor.g, config->textColor.b, config->textColor.a };
|
||||
|
||||
TTF_Font *font = gFonts[config->fontId];
|
||||
SDL_Surface *surface = TTF_RenderText_Blended(font, text->chars, text->length, color);
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
SDL_RenderTexture(renderer, texture, NULL, &rect);
|
||||
|
||||
SDL_DestroySurface(surface);
|
||||
SDL_DestroyTexture(texture);
|
||||
} break;
|
||||
default:
|
||||
SDL_Log("Unknown render command type: %d", rcmd->commandType);
|
||||
}
|
||||
}
|
||||
}
|
@ -83,7 +83,7 @@ static inline char *Clay_Cairo__NullTerminate(Clay_String *str) {
|
||||
}
|
||||
|
||||
// Measure text using cairo's *toy* text API.
|
||||
static inline Clay_Dimensions Clay_Cairo_MeasureText(Clay_String *str, Clay_TextElementConfig *config) {
|
||||
static inline Clay_Dimensions Clay_Cairo_MeasureText(Clay_String *str, Clay_TextElementConfig *config, uintptr_t userData) {
|
||||
// Edge case: Clay computes the width of a whitespace character
|
||||
// once. Cairo does not factor in whitespaces when computing text
|
||||
// extents, this edge-case serves as a short-circuit to introduce
|
||||
|
@ -89,7 +89,7 @@ Ray GetScreenToWorldPointWithZDistance(Vector2 position, Camera camera, int scre
|
||||
|
||||
uint32_t measureCalls = 0;
|
||||
|
||||
static inline Clay_Dimensions Raylib_MeasureText(Clay_String *text, Clay_TextElementConfig *config) {
|
||||
static inline Clay_Dimensions Raylib_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, uintptr_t userData) {
|
||||
measureCalls++;
|
||||
// Measure string size for Font
|
||||
Clay_Dimensions textSize = { 0 };
|
||||
@ -101,14 +101,14 @@ static inline Clay_Dimensions Raylib_MeasureText(Clay_String *text, Clay_TextEle
|
||||
Font fontToUse = Raylib_fonts[config->fontId].font;
|
||||
float scaleFactor = config->fontSize/(float)fontToUse.baseSize;
|
||||
|
||||
for (int i = 0; i < text->length; ++i)
|
||||
for (int i = 0; i < text.length; ++i)
|
||||
{
|
||||
if (text->chars[i] == '\n') {
|
||||
if (text.chars[i] == '\n') {
|
||||
maxTextWidth = fmax(maxTextWidth, lineTextWidth);
|
||||
lineTextWidth = 0;
|
||||
continue;
|
||||
}
|
||||
int index = text->chars[i] - 32;
|
||||
int index = text.chars[i] - 32;
|
||||
if (fontToUse.glyphs[index].advanceX != 0) lineTextWidth += fontToUse.glyphs[index].advanceX;
|
||||
else lineTextWidth += (fontToUse.recs[index].width + fontToUse.glyphs[index].offsetX);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user