mirror of
https://github.com/nicbarker/clay.git
synced 2025-05-03 17:08:06 +00:00
Compare commits
16 Commits
99de23a1f8
...
cc07dcf3af
Author | SHA1 | Date | |
---|---|---|---|
|
cc07dcf3af | ||
|
356724ed20 | ||
|
afba9f0de6 | ||
|
3a4455aa83 | ||
|
208c7cb3a0 | ||
|
c2c445e455 | ||
|
9e7595b873 | ||
|
32d1a31dfe | ||
|
b2b50724e2 | ||
|
337fc1dc92 | ||
|
9af4b6384d | ||
|
faf2f926b8 | ||
|
5fea1e748d | ||
|
13402c62ab | ||
|
9b8fd94170 | ||
|
b2e7eb2ee6 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,4 @@
|
||||
cmake-build-debug/
|
||||
cmake-build-release/
|
||||
cmake-build-*/
|
||||
build/
|
||||
.DS_Store
|
||||
.idea/
|
||||
|
@ -9,6 +9,9 @@ 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/introducing-clay-video-demo")
|
||||
add_subdirectory("examples/SDL2-video-demo")
|
||||
add_subdirectory("examples/minimal-imgui")
|
||||
endif()
|
||||
add_subdirectory("examples/introducing-clay-video-demo")
|
||||
add_subdirectory("examples/SDL2-video-demo")
|
||||
|
15
README.md
15
README.md
@ -173,9 +173,12 @@ For help starting out or to discuss clay, considering joining [the discord serve
|
||||
- [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)
|
||||
@ -575,6 +578,14 @@ Takes a pointer to a function that can be used to measure the `width, height` di
|
||||
|
||||
---
|
||||
|
||||
### 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)`
|
||||
@ -603,12 +614,16 @@ 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()`
|
||||
|
66
clay.h
66
clay.h
@ -399,7 +399,7 @@ 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;
|
||||
@ -409,7 +409,8 @@ CLAY__TYPEDEF(Clay_BorderElementConfig, struct {
|
||||
#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;
|
||||
@ -524,6 +525,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);
|
||||
@ -1212,6 +1214,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;
|
||||
@ -1390,7 +1393,7 @@ struct Clay_Context {
|
||||
bool externalScrollHandlingEnabled;
|
||||
uint32_t debugSelectedElementId;
|
||||
uint32_t generation;
|
||||
uint64_t arenaResetOffset;
|
||||
uintptr_t arenaResetOffset;
|
||||
Clay_Arena internalArena;
|
||||
// Layout Elements / Render Commands
|
||||
Clay_LayoutElementArray layoutElements;
|
||||
@ -1677,6 +1680,7 @@ 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;
|
||||
@ -1698,18 +1702,22 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
int32_t length = end - start;
|
||||
Clay_String word = { .length = length, .chars = &text->chars[start] };
|
||||
Clay_Dimensions dimensions = Clay__MeasureText(&word, config);
|
||||
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++;
|
||||
@ -1718,9 +1726,11 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
Clay_String lastWord = { .length = end - start, .chars = &text->chars[start] };
|
||||
Clay_Dimensions dimensions = Clay__MeasureText(&lastWord, config);
|
||||
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;
|
||||
@ -2102,6 +2112,9 @@ void Clay__CompressChildrenAlongAxis(bool xAxis, float totalSizeToDistribute, Cl
|
||||
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) < 0.1 && (childSize - largestSize) > -0.1) {
|
||||
Clay__int32_tArray_Add(&largestContainers, Clay__int32_tArray_Get(&resizableContainerBuffer, i));
|
||||
@ -2363,7 +2376,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;
|
||||
@ -2471,9 +2484,9 @@ void Clay__CalculateFinalLayout() {
|
||||
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__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);
|
||||
}
|
||||
}
|
||||
@ -2800,7 +2813,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.x - halfGap, (float)layoutConfig->padding.y - 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]);
|
||||
@ -2812,7 +2826,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) {
|
||||
@ -2825,7 +2839,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3222,16 +3236,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) {
|
||||
@ -3609,7 +3626,7 @@ uint32_t Clay_MinMemorySize(void) {
|
||||
.maxMeasureTextCacheWordCount = Clay__defaultMaxMeasureTextWordCacheCount,
|
||||
.internalArena = {
|
||||
.capacity = SIZE_MAX,
|
||||
.memory = (char*)&fakeContext,
|
||||
.memory = NULL,
|
||||
}
|
||||
};
|
||||
Clay_Context* currentContext = Clay_GetCurrentContext();
|
||||
@ -4035,6 +4052,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
|
||||
|
||||
/*
|
||||
|
Binary file not shown.
50
examples/minimal-imgui/CMakeLists.txt
Normal file
50
examples/minimal-imgui/CMakeLists.txt
Normal file
@ -0,0 +1,50 @@
|
||||
cmake_minimum_required(VERSION 3.27)
|
||||
project(minimal_imgui)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||
|
||||
#add_subdirectory(3rd_party)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
sokol
|
||||
GIT_REPOSITORY "https://github.com/floooh/sokol.git"
|
||||
GIT_COMMIT "789d97071d17cbab4e3835a0b0b8b379e98c114f"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
|
||||
FetchContent_Declare(
|
||||
imgui
|
||||
GIT_REPOSITORY "https://github.com/ocornut/imgui.git"
|
||||
GIT_TAG "v1.91.6"
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(sokol imgui)
|
||||
|
||||
add_executable(minimal_imgui
|
||||
main.cpp
|
||||
${imgui_SOURCE_DIR}/imgui.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_demo.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_draw.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_tables.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||
)
|
||||
|
||||
target_compile_options(minimal_imgui PUBLIC)
|
||||
target_include_directories(minimal_imgui PUBLIC .)
|
||||
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "-DCLAY_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
target_include_directories(minimal_imgui PUBLIC ${sokol_SOURCE_DIR} ${imgui_SOURCE_DIR})
|
||||
if(WIN32)
|
||||
target_link_libraries(minimal_imgui PUBLIC kernel32 user32 shell32 gdi32)
|
||||
elseif(APPLE)
|
||||
target_link_libraries(minimal_imgui PUBLIC "-framework Cocoa" "-framework QuartzCore" "-framework OpenGL")
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_link_libraries(minimal_imgui PUBLIC X11 Xi Xcursor GL dl pthread m)
|
||||
endif()
|
196
examples/minimal-imgui/main.cpp
Normal file
196
examples/minimal-imgui/main.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "../../clay.h"
|
||||
|
||||
#define SOKOL_IMPL
|
||||
#define SOKOL_NO_ENTRY
|
||||
#define SOKOL_GLCORE
|
||||
#include "sokol_app.h"
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_glue.h"
|
||||
#include "sokol_log.h"
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include "imgui.h"
|
||||
#define SOKOL_IMGUI_IMPL
|
||||
#include "util/sokol_imgui.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define SCREEN_WIDTH 800
|
||||
#define SCREEN_HEIGHT 600
|
||||
|
||||
sg_pass_action pass_action = {};
|
||||
|
||||
static const uint32_t FONT_ID_BODY_24 = 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};
|
||||
|
||||
void init();
|
||||
void frame();
|
||||
void cleanup();
|
||||
void input(const sapp_event* event);
|
||||
|
||||
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_BODY_24,
|
||||
.fontSize = 24,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
static Clay_RenderCommandArray 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,
|
||||
}
|
||||
}),
|
||||
CLAY_RECTANGLE({
|
||||
.color = COLOR_LIGHT,
|
||||
})
|
||||
) {
|
||||
Label(CLAY_STRING("Hello, World!"));
|
||||
}
|
||||
return Clay_EndLayout();
|
||||
}
|
||||
|
||||
Clay_Dimensions measureText(Clay_String *text, Clay_TextElementConfig *config);
|
||||
void render(Clay_RenderCommandArray renderCommands);
|
||||
|
||||
int main(int argc, char** args) {
|
||||
//-----------------------------------------------------------------------
|
||||
// Setup Clay
|
||||
//-----------------------------------------------------------------------
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = (Clay_Arena) {
|
||||
.label = CLAY_STRING("Clay Memory Arena"),
|
||||
.capacity = totalMemorySize,
|
||||
.memory = (char*)malloc(totalMemorySize),
|
||||
};
|
||||
|
||||
Clay_SetMeasureTextFunction(measureText);
|
||||
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { SCREEN_WIDTH, SCREEN_HEIGHT });
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Setup Sokol
|
||||
//-----------------------------------------------------------------------
|
||||
sapp_desc desc = {0};
|
||||
desc.init_cb = init;
|
||||
desc.frame_cb = frame;
|
||||
desc.cleanup_cb = cleanup,
|
||||
desc.event_cb = input,
|
||||
desc.width = SCREEN_WIDTH,
|
||||
desc.height = SCREEN_HEIGHT,
|
||||
desc.window_title = "sokol + puredoom",
|
||||
desc.icon.sokol_default = true,
|
||||
desc.logger.func = slog_func;
|
||||
sapp_run(&desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init() {
|
||||
sg_desc desc = {0};
|
||||
desc.environment = sglue_environment();
|
||||
desc.logger.func = slog_func;
|
||||
sg_setup(&desc);
|
||||
|
||||
pass_action.colors[0] = (sg_color_attachment_action){ .load_action=SG_LOADACTION_CLEAR, .clear_value={0.2f, 0.1f, 0.3f, 1.0f} };
|
||||
|
||||
simgui_desc_t simgui_desc = {0};
|
||||
simgui_setup(&simgui_desc);
|
||||
}
|
||||
|
||||
void frame() {
|
||||
// const double dt = sapp_frame_duration();
|
||||
|
||||
const int width = sapp_width();
|
||||
const int height = sapp_height();
|
||||
simgui_new_frame({ width, height, sapp_frame_duration(), sapp_dpi_scale() });
|
||||
|
||||
// imgui
|
||||
{
|
||||
// ImGui::ShowDemoWindow();
|
||||
ImGui::SetNextWindowSize(ImVec2{SCREEN_WIDTH, SCREEN_HEIGHT});
|
||||
ImGui::SetNextWindowPos(ImVec2{0, 0});
|
||||
ImGui::Begin("Text rendering", NULL, ImGuiWindowFlags_NoBackground|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoSavedSettings);
|
||||
|
||||
Clay_RenderCommandArray renderCommands = CreateLayout();
|
||||
render(renderCommands);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
sg_begin_pass({ .action = pass_action, .swapchain = sglue_swapchain() });
|
||||
simgui_render();
|
||||
sg_end_pass();
|
||||
sg_commit();
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
simgui_shutdown();
|
||||
sg_shutdown();
|
||||
}
|
||||
|
||||
void input(const sapp_event* event) {
|
||||
simgui_handle_event(event);
|
||||
}
|
||||
|
||||
Clay_Dimensions measureText(Clay_String *text, Clay_TextElementConfig *config)
|
||||
{
|
||||
ImVec2 size = ImGui::CalcTextSize(text->chars, nullptr);
|
||||
return (Clay_Dimensions) {
|
||||
.width = size.x,
|
||||
.height = size.y,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void render(Clay_RenderCommandArray renderCommands)
|
||||
{
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
|
||||
for (uint32_t i = 0; i < renderCommands.length; i++)
|
||||
{
|
||||
Clay_RenderCommand *renderCommand = Clay_RenderCommandArray_Get(&renderCommands, i);
|
||||
Clay_BoundingBox boundingBox = renderCommand->boundingBox;
|
||||
switch (renderCommand->commandType)
|
||||
{
|
||||
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
|
||||
Clay_RectangleElementConfig *config = renderCommand->config.rectangleElementConfig;
|
||||
Clay_Color color = config->color;
|
||||
|
||||
draw_list->AddRectFilled(p+ImVec2(boundingBox.x, boundingBox.y), p+ImVec2(boundingBox.x+boundingBox.width, boundingBox.y+boundingBox.height), ImColor(color.r/255.0f, color.g/255.0f, color.b/255.0f, color.a/255.0f));
|
||||
|
||||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_TEXT: {
|
||||
Clay_TextElementConfig *config = renderCommand->config.textElementConfig;
|
||||
|
||||
draw_list->AddText(p+ImVec2(boundingBox.x, boundingBox.y), ImColor(config->textColor.r/255.0f, config->textColor.g/255.0f, config->textColor.b/255.0f, config->textColor.a/255.0f), renderCommand->text.chars);
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
fprintf(stderr, "Error: unhandled render command: %d\n", renderCommand->commandType);
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user