Somehow I deleted the example .c3 file. Fixed project settings, I forgot I can't drag and drop when it comes to relative project files.

This commit is contained in:
Jefferey Schlueter 2025-01-29 12:04:40 -05:00
parent 91295a2a9a
commit 9dc9e4992c
3 changed files with 293 additions and 701 deletions

View File

@ -0,0 +1,292 @@
module videoexample;
import clay;
import raylib;
const uint FONT_ID_BODY_16 = 0;
fn void errorHandler(ErrorData errorData)
{
// std::io::printfn("ERROR: \"%s\"", errorData.errorText.chars);
}
fn void renderDropdownMenuItem(String text) {
@clay(
clay::layout({ .padding = clay::paddingUni(16)})
) {
clay::text(
text, clay::textConfig({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
}));
};
}
fn void renderHeaderButton(String text) {
@clay(
clay::layout({ .padding = { 16, 16, 8, 8 }}),
clay::rectangle({
.color = { 140, 140, 140, 255 },
.cornerRadius = clay::cornerRadiusUni(5)
})
) {
clay::text(text, clay::textConfig({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
}));
};
}
fn void handleSidebarInteraction(
ElementId elementId,
PointerData pointerData,
iptr userData
) {
// If this button was clicked
if (pointerData.state == PointerState.RELEASED_THIS_FRAME) {
if (userData >= 0 && userData < ALL_DOCUMENTS.len) {
// Select the corresponding document
selectedDocumentIndex = (uint)userData;
}
}
}
struct Document {
String title;
String contents;
}
const Document[*] ALL_DOCUMENTS = {
{ "Squirrels", "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" },
{ "Lorem Ipsum", "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." },
{ "Vacuum Instructions", "Chapter 3: Getting Started - Unpacking and Setup\n""\n""Congratulations on your new SuperClean Pro 5000 vacuum cleaner! In this section, we will guide you through the simple steps to get your vacuum up and running. Before you begin, please ensure that you have all the components listed in the \"Package Contents\" section on page 2.\n""\n""1. Unboxing Your Vacuum\n""Carefully remove the vacuum cleaner from the box. Avoid using sharp objects that could damage the product. Once removed, place the unit on a flat, stable surface to proceed with the setup. Inside the box, you should find:\n""\n"" The main vacuum unit\n"" A telescoping extension wand\n"" A set of specialized cleaning tools (crevice tool, upholstery brush, etc.)\n"" A reusable dust bag (if applicable)\n"" A power cord with a 3-prong plug\n"" A set of quick-start instructions\n""\n""2. Assembling Your Vacuum\n""Begin by attaching the extension wand to the main body of the vacuum cleaner. Line up the connectors and twist the wand into place until you hear a click. Next, select the desired cleaning tool and firmly attach it to the wand's end, ensuring it is securely locked in.\n""\n""For models that require a dust bag, slide the bag into the compartment at the back of the vacuum, making sure it is properly aligned with the internal mechanism. If your vacuum uses a bagless system, ensure the dust container is correctly seated and locked in place before use.\n""\n""3. Powering On\n""To start the vacuum, plug the power cord into a grounded electrical outlet. Once plugged in, locate the power switch, usually positioned on the side of the handle or body of the unit, depending on your model. Press the switch to the \"On\" position, and you should hear the motor begin to hum. If the vacuum does not power on, check that the power cord is securely plugged in, and ensure there are no blockages in the power switch.\n""\n""Note: Before first use, ensure that the vacuum filter (if your model has one) is properly installed. If unsure, refer to \"Section 5: Maintenance\" for filter installation instructions." },
{ "Article 4", "Article 4" },
{ "Article 5", "Article 5" }
};
uint selectedDocumentIndex = 0;
RectangleElementConfig contentBackgroundConfig = {
{ 90, 90, 90, 255 },
clay::@cornerRadiusUniCT(8)
};
Sizing layoutExpand = Sizing{ clay::sizingGrow(), clay::sizingGrow() };
LayoutConfig sidebarButtonLayout = LayoutConfig{
.sizing = { .width = clay::sizingGrow() },
.padding = clay::paddingCT(16, 16, 16, 16)
};
bool isDebugModeEnabled = false;
fn void main() @public
{
raylib::setConfigFlags(raylib::FLAG_VSYNC_HINT | raylib::FLAG_WINDOW_RESIZABLE | raylib::FLAG_WINDOW_HIGHDPI | raylib::FLAG_MSAA_4X_HINT);
raylib::initWindow(1024, 768, "Introducing Clay C3-Demo");
defer raylib::closeWindow();
uint clayRequiredMemory = clay::minMemorySize();
Arena clayMemory = clay::createArena(clayRequiredMemory, malloc(clayRequiredMemory));
clay::initialize(clayMemory, { raylib::getScreenWidth(), raylib::getScreenHeight() }, { &errorHandler, 0 });
clay::setMeasureTextFunction(&clay::renderer::raylibMeasureText);
clay::renderer::raylibFonts[FONT_ID_BODY_16] = {
FONT_ID_BODY_16,
raylib::loadFontEx("resources/Lexend-Regular.ttf", 48, null, 400)
};
raylib::setTextureFilter(
clay::renderer::raylibFonts[FONT_ID_BODY_16].font.texture,
TextureFilter.BILINEAR
);
while (!raylib::windowShouldClose()) {
clay::setLayoutDimensions({raylib::getScreenWidth(), raylib::getScreenHeight()});
Vector2 mouse_position = raylib::getMousePosition();
Vector2 scroll_delta = raylib::getMouseWheelMoveV();
clay::setPointerState({mouse_position.x, mouse_position.y}, raylib::isMouseButtonDown(MouseButton.LEFT));
clay::updateScrollContainer(true, {scroll_delta.x, scroll_delta.y}, raylib::getFrameTime());
if (raylib::isKeyReleased(raylib::KEY_D)) { isDebugModeEnabled = !isDebugModeEnabled; clay::setDebugModeEnabled(isDebugModeEnabled); }
clay::beginLayout();
@clay(
clay::id("OuterContainer"),
clay::rectangle({ .color = { 43, 41, 51, 255 } }),
clay::layout({
.sizing = layoutExpand,
.padding = clay::paddingUni(16),
.childGap = 16,
.layoutDirection = LayoutDirection.TOP_TO_BOTTOM,
})
) {
@clay(
clay::id("HeaderBar"),
clay::rectangle(contentBackgroundConfig),
clay::layout({
.sizing = {
.height = clay::sizingFixed(60),
.width = clay::sizingGrow()
},
.padding = { 16, 16, 0, 0 },
.childGap = 16,
.childAlignment = {
.y = AlignY.CENTER
}
})
) {
// Header buttons go here
@clay(
clay::id("FileButton"),
clay::layout({ .padding = { 16, 16, 8, 8 }}),
clay::rectangle({
.color = { 140, 140, 140, 255 },
.cornerRadius = clay::cornerRadiusUni(5)
})
) {
clay::text("File", clay::textConfig({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 16,
}));
bool fileMenuVisible =
clay::pointerOver(clay::getElementId("FileButton"))
||
clay::pointerOver(clay::getElementId("FileMenu"));
if (fileMenuVisible) { // Below has been changed slightly to fix the small bug where the menu would dismiss when mousing over the top gap
@clay(
clay::id("FileMenu"),
clay::floating({
.attachment = {
.parent = AttachPoint.LEFT_BOTTOM
},
}),
clay::layout({
.padding = {0, 0, 8, 8 }
})
) {
@clay(
clay::layout({
.sizing = {
.width = clay::sizingFixed(200)
},
.layoutDirection = LayoutDirection.TOP_TO_BOTTOM,
}),
clay::rectangle({
.color = { 40, 40, 40, 255 },
.cornerRadius = clay::cornerRadiusUni(8)
})
) {
// Render dropdown items here
renderDropdownMenuItem("New");
renderDropdownMenuItem("Open");
renderDropdownMenuItem("Close");
};
};
}
};
renderHeaderButton("Edit");
@clay(clay::layout({ .sizing = { .width = clay::sizingGrow() }})) {};
renderHeaderButton("Upload");
renderHeaderButton("Media");
renderHeaderButton("Support");
};
@clay(
clay::id("LowerContent"),
clay::layout({ .sizing = layoutExpand, .childGap = 16 })
) {
@clay(
clay::id("Sidebar"),
contentBackgroundConfig,
clay::layout({
.sizing = {
.width = clay::sizingFixed(250),
.height = clay::sizingGrow()
},
.padding = clay::paddingUni(16),
.childGap = 8,
.layoutDirection = LayoutDirection.TOP_TO_BOTTOM,
})
) {
for (int i = 0; i < ALL_DOCUMENTS.len; i++) {
Document document = ALL_DOCUMENTS[i];
if (i == selectedDocumentIndex) {
@clay(
clay::layout(sidebarButtonLayout),
clay::rectangle({
.color = { 120, 120, 120, 255 },
.cornerRadius = clay::cornerRadiusUni(8),
})
) {
clay::text(document.title, clay::textConfig({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 20,
}));
};
} else {
@clay(
clay::layout(sidebarButtonLayout),
clay::onHover(&handleSidebarInteraction, i),
clay::@bodyIf(
clay::hovered(),
clay::rectangle({
.color = { 120, 120, 120, 120 },
.cornerRadius = clay::cornerRadiusUni(8)
})
),
) {
clay::text(document.title, clay::textConfig({
.textColor = { 255, 255, 255, 255 },
.fontId = FONT_ID_BODY_16,
.fontSize = 20,
}));
};
}
}
};
@clay(
clay::id("MainContent"),
clay::rectangle(contentBackgroundConfig),
clay::scroll({ .vertical = true }),
clay::layout({
.layoutDirection = LayoutDirection.TOP_TO_BOTTOM,
.childGap = 14,
.padding = clay::paddingUni(16),
.sizing = layoutExpand,
}),
) {
Document document = ALL_DOCUMENTS[selectedDocumentIndex];
clay::text(document.title, clay::textConfig({
.fontId = FONT_ID_BODY_16,
.fontSize = 24,
.textColor = {255, 255, 255, 255},
}));
clay::text(document.contents, clay::textConfig({
.fontId = FONT_ID_BODY_16,
.fontSize = 24,
.textColor = {255, 255, 255, 255},
}));
};
};
};
RenderCommandArray renderCommands = clay::endLayout();
raylib::beginDrawing();
raylib::clearBackground(raylib::WHITE);
clay::renderer::raylibRender(renderCommands);
raylib::endDrawing();
}
}

View File

@ -2,6 +2,7 @@
"langrev": "1",
"authors": [ "Jefferey Schlueter <jefferey.l.schlueter@gmail.com>" ],
"version": "0.1.0",
"dependency-search-paths": [ "lib" ],
"targets": {
// TODO: found out how to stop this from outputting a .lib and .pdb in addition to the .exe (they don't do anything)
@ -10,7 +11,6 @@
"c-sources": [ "c-lang/source/clay.c" ],
"cflags": "-DCLAY_IMPLEMENTATION", // makes the clay source actually define things
"type": "executable",
"dependency-search-paths": [ "lib" ],
"dependencies": [ "raylib55" ],
"sources": [ "source/clay.c3", "source/clay-raylib-renderer.c3", "examples/video-example.c3" ],
// "link-libc": false, // TODO; leads to duplicate definitions (eg math_nolibc)

View File

@ -1,700 +0,0 @@
// TODO: including additional structures required for Clay_Context led to bloat
// module clay;
// // import std::core::cinterop ;
// import clay::carray;
// // =======================
// // ===== USER MACROS =====
// // =======================
// macro @clay(...; @body()) @builtin
// {
// clay::openElement();
// $for (var $i = 0; $i < $vacount; $i++)
// $vaexpr[$i]; // If you get an error here consisder the @body[...]() macros
// $endfor
// clay::elementPostConfiguration();
// @body();
// clay::closeElement();
// }
// macro text(String text, TextElementConfig *config) { clay::openTextElement({text.len, text}, config); }
// <*Provides you conditional calls (eg #booleanCondition ? #doA : 0) within the condifuration of @clay(...)*>
// macro @bodyIf(#condition, #ifRes) { if (#condition) { #ifRes; } }
// <*Provides you conditional calls (eg #booleanCondition ? #doA : #doB) within the condifuration of @clay(...)*>
// macro @bodyIfElse(#condition, #ifRes, #elseRes) { if (#condition) { #ifRes; } else { #elseRes; } }
// // <*Facilitates non-method calls (eg { #doWhatever }, { #booleanExpression ? #doA : #doB}, etc.) within the parameters of @clay(...)*>
// // macro @inline(; @body()) { @body(); }
// <*attaches a RectangleElementConfig to the clay element when called within @clay(...)*>
// macro rectangle(RectangleElementConfig config) { clay::attachElementConfig({ .rectangleElementConfig = clay::storeRectangleElementConfig(config) }, clay::ELEMENT_CONFIG_TYPE_RECTANGLE ); }
// <*attaches a LayoutConfig to the clay element when called within @clay(...)*>
// macro layout(LayoutConfig config) { clay::attachLayoutConfig( clay::storeLayoutConfig(config) ); }
// <*attaches a LayoutConfig to the clay element when called within @clay(...)*>
// macro scroll(ScrollElementConfig config) { clay::attachElementConfig({ .scrollElementConfig = clay::storeScrollElementConfig(config) }, clay::ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER ); }
// <*attaches a FloatingElementConfig to the clay element when called within @clay(...)*>
// macro floating(FloatingElementConfig config) { clay::attachElementConfig({ .floatingElementConfig = clay::storeFloatingElementConfig(config) }, clay::ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER ); }
// <*attaches a BorderElementConfig to the clay element when called within @clay(...)*>
// macro @borderRadiusUni(uint #width, ClayColor #color, float #cornerRadius = 0) { clay::attachElementConfig({ .borderElementConfig = clay::storeBorderElementConfig({ .left = { #width, #color }, .right = { #width, #color }, .top = { #width, #color }, .bottom = { #width, #color }, .#cornerRadius = {#cornerRadius, #cornerRadius, #cornerRadius, #cornerRadius}})}, clay::ELEMENT_CONFIG_TYPE_BORDER_CONTAINER); }
// macro id(String idString) { clay::attachId(clay::hashString({idString.len, idString}, 0, 0)); }
// macro TextElementConfig* textConfig(TextElementConfig config) { return clay::storeTextElementConfig(config); }
// macro SizingAxis sizingFit(float min = 0, float max = float.max) { return { .size.minMax = {min, max}, .type = SizingType.FIT }; }
// macro SizingAxis sizingGrow() { return { .size.minMax = {0, 0}, .type = SizingType.GROW }; }
// macro SizingAxis sizingFixed(float pixels) { return { .size.minMax = {pixels, pixels}, .type = SizingType.FIXED }; }
// macro SizingAxis sizingPercent(float percent) { return { .size.percent = percent, .type = SizingType.PERCENT }; }
// macro Padding paddingUni(ushort uniform) { return {uniform, uniform, uniform, uniform}; }
// macro Padding padding(ushort horizontal, ushort vertical) { return {horizontal, horizontal, vertical, vertical}; }
// macro CornerRadius cornerRadiusUni(float uniform) { return {uniform, uniform, uniform, uniform}; }
// macro SizingAxis sizingFitCT(float $min = 0, float $max = float.max) { return { .size.minMax = {$min, $max}, .type = SizingType.FIT }; }
// macro SizingAxis sizingFixedCT(float $pixels) { return { .size.minMax = {$pixels, $pixels}, .type = SizingType.FIXED }; }
// macro SizingAxis sizingPercentCT(float $percent) { return { .size.percent = $percent, .type = SizingType.PERCENT }; }
// macro Padding paddingCT(ushort $a, ushort $b, ushort $c, ushort $d) { return { $a, $b, $c, $d }; }
// macro CornerRadius @cornerRadiusUniCT(float #uniform) { return {#uniform, #uniform, #uniform, #uniform}; }
// // ===================
// // ===== STRUCTS =====
// // ===================
// struct ClayString
// {
// int length;
// char *chars;
// }
// def ClayStringArray = carray::Array(<ClayString>) @private;
// struct Arena
// {
// uint128 nextAllocation;
// uint128 capacity;
// char *memory;
// }
// struct Dimensions
// {
// float width, height;
// }
// struct ClayVector2
// {
// float x, y;
// }
// struct ClayColor
// {
// float r, g, b, a;
// }
// struct ClayBoundingBox
// {
// float x, y, width, height;
// }
// struct ElementId
// {
// uint id;
// uint offset;
// uint baseId;
// ClayString stringId;
// }
// struct CornerRadius
// {
// float topLeft;
// float topRight;
// float bottomLeft;
// float bottomRight;
// }
// // ===== Element Configs =====
// distinct ElementConfigType @private = char;
// const ElementConfigType ELEMENT_CONFIG_TYPE_NONE @private = 0;
// const ElementConfigType ELEMENT_CONFIG_TYPE_RECTANGLE @private = 1;
// const ElementConfigType ELEMENT_CONFIG_TYPE_BORDER_CONTAINER @private = 2;
// const ElementConfigType ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER @private = 4;
// const ElementConfigType ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER @private = 8;
// const ElementConfigType ELEMENT_CONFIG_TYPE_IMAGE @private = 16;
// const ElementConfigType ELEMENT_CONFIG_TYPE_TEXT @private = 32;
// const ElementConfigType ELEMENT_CONFIG_TYPE_CUSTOM @private = 64;
// enum LayoutDirection : char @export
// {
// LEFT_TO_RIGHT,
// TOP_TO_BOTTOM,
// }
// enum AlignX : char @export
// {
// LEFT,
// RIGHT,
// CENTER,
// }
// enum AlignY : char @export
// {
// TOP,
// BOTTOM,
// CENTER,
// }
// enum SizingType : char @export
// {
// FIT,
// GROW,
// PERCENT,
// FIXED,
// }
// struct ChildAlignment
// {
// AlignX x;
// AlignY y;
// }
// struct SizingMinMax
// {
// float min;
// float max;
// }
// struct SizingAxis
// {
// union size
// {
// SizingMinMax minMax;
// float percent;
// }
// SizingType type;
// }
// struct Sizing
// {
// SizingAxis width;
// SizingAxis height;
// }
// struct Padding
// {
// ushort left;
// ushort right;
// ushort top;
// ushort bottom;
// }
// struct LayoutConfig
// {
// Sizing sizing;
// Padding padding;
// ushort childGap;
// ChildAlignment childAlignment;
// LayoutDirection layoutDirection;
// }
// struct RectangleElementConfig
// {
// ClayColor color;
// CornerRadius cornerRadius;
// // #ifdef CLAY_EXTEND_CONFIG_RECTANGLE
// // CLAY_EXTEND_CONFIG_RECTANGLE
// // #endif
// }
// enum WrapMode @export
// {
// WORDS,
// NEWLINES,
// NONE,
// }
// struct TextElementConfig
// {
// ClayColor textColor;
// ushort fontId;
// ushort fontSize;
// ushort letterSpacing;
// ushort lineHeight;
// WrapMode wrapMode;
// // #ifdef CLAY_EXTEND_CONFIG_TEXT
// // CLAY_EXTEND_CONFIG_TEXT
// // #endif
// }
// struct ImageElementConfig
// {
// void *imageData;
// Dimensions sourceDimensions;
// // #ifdef CLAY_EXTEND_CONFIG_IMAGE
// // CLAY_EXTEND_CONFIG_IMAGE
// // #endif
// }
// enum AttachPoint : char @export
// {
// LEFT_TOP,
// LEFT_CENTER,
// LEFT_BOTTOM,
// CENTER_TOP,
// CENTER_CENTER,
// CENTER_BOTTOM,
// RIGHT_TOP,
// RIGHT_CENTER,
// RIGHT_BOTTOM,
// }
// struct FloatingAttachPoints
// {
// AttachPoint element;
// AttachPoint parent;
// }
// enum PointerCaptureMode @export
// {
// CAPTURE,
// // MODE_PASSTHROUGH,
// PARENT,
// }
// struct FloatingElementConfig
// {
// ClayVector2 offset;
// Dimensions expand;
// ushort zIndex;
// uint parentId;
// FloatingAttachPoints attachment;
// PointerCaptureMode pointerCaptureMode;
// }
// struct CustomElementConfig
// {
// // #ifndef CLAY_EXTEND_CONFIG_CUSTOM
// void *customData;
// // #else
// // CLAY_EXTEND_CONFIG_CUSTOM
// // #endif
// }
// struct ScrollElementConfig
// {
// bool horizontal;
// bool vertical;
// }
// // Border
// struct Border
// {
// uint width;
// ClayColor color;
// }
// struct BorderElementConfig
// {
// Border left;
// Border right;
// Border top;
// Border bottom;
// Border betweenChildren;
// CornerRadius cornerRadius;
// // #ifdef CLAY_EXTEND_CONFIG_BORDER
// // CLAY_EXTEND_CONFIG_BORDER
// // #endif
// }
// union ElementConfigUnion
// {
// RectangleElementConfig *rectangleElementConfig;
// TextElementConfig *textElementConfig;
// ImageElementConfig *imageElementConfig;
// FloatingElementConfig *floatingElementConfig;
// CustomElementConfig *customElementConfig;
// ScrollElementConfig *scrollElementConfig;
// BorderElementConfig *borderElementConfig;
// }
// struct ElementConfig
// {
// ElementConfigType type;
// ElementConfigUnion config;
// }
// // Miscellaneous Structs & Enums ---------------------------------
// struct ScrollContainerData
// {
// // Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
// // Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
// ClayVector2 *scrollPosition;
// Dimensions scrollContainerDimensions;
// Dimensions contentDimensions;
// ScrollElementConfig config;
// // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
// bool found;
// }
// <*
// @
// *>
// struct ElementData
// {
// ClayBoundingBox boundingBox;
// // Indicates whether an actual Element matched the provided ID or if the default struct was returned.
// bool found;
// }
// enum RenderCommandType : char @export
// {
// NONE,
// RECTANGLE,
// BORDER,
// TEXT,
// IMAGE,
// SCISSOR_START,
// SCISSOR_END,
// CUSTOM,
// }
// struct RenderCommand
// {
// ClayBoundingBox boundingBox;
// ElementConfigUnion config;
// ClayString text;
// uint id;
// RenderCommandType commandType;
// }
// def RenderCommandArray = carray::Array(<RenderCommand>);
// enum PointerState @export
// {
// PRESSED_THIS_FRAME,
// PRESSED,
// RELEASED_THIS_FRAME,
// RELEASED,
// }
// struct PointerData
// {
// ClayVector2 position;
// PointerState state;
// }
// enum ErrorType @export
// {
// TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
// ARENA_CAPACITY_EXCEEDED,
// ELEMENTS_CAPACITY_EXCEEDED,
// TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
// DUPLICATE_ID,
// FLOATING_CONTAINER_PARENT_NOT_FOUND,
// INTERNAL_ERROR,
// }
// struct ErrorData
// {
// ErrorType errorType;
// ClayString errorText;
// uint128 userData;
// }
// def ErrorHandleFunc = fn void(ErrorData errorText);
// struct ErrorHandler
// {
// ErrorHandleFunc errorHandler;
// uint128 userData;
// }
// struct BooleanWarnings
// {
// bool maxElementsExceeded;
// bool maxRenderCommandsExceeded;
// bool maxTextMeasureCacheExceeded;
// }
// struct Warning
// {
// ClayString baseMessage;
// ClayString dynamicMessage;
// }
// def WarningArray = carray::Array(<Warning>);
// struct LayoutElementChildren
// {
// int *elements;
// ushort length;
// }
// struct LayoutElement
// {
// union childrenOrTextContent {
// LayoutElementChildren children;
// TextElementData *textElementData;
// }
// Dimensions dimensions;
// Dimensions minDimensions;
// LayoutConfig *layoutConfig;
// ElementConfigArraySlice elementConfigs;
// uint configsEnabled;
// uint id;
// }
// struct WrappedTextLine
// {
// Dimensions dimensions;
// ClayString line;
// }
// struct WrappedTextLineArraySlice
// {
// int length;
// WrappedTextLine *internalArray;
// }
// struct TextElementData
// {
// ClayString text;
// Dimensions preferredDimensions;
// int elementIndex;
// WrappedTextLineArraySlice wrappedLines;
// }
// struct ElementConfigArraySlice
// {
// int length;
// ElementConfig *internalArray;
// }
// def DebugElementData = bool[<2>];
// struct LayoutElementHashMapItem
// {
// ClayBoundingBox boundingBox;
// ElementId elementId;
// LayoutElement* layoutElement;
// OnHoverEvent onHoverFunction;
// int128 hoverFunctionUserData;
// int nextIndex;
// uint128 generation;
// DebugElementData *debugData;
// }
// struct LayoutElementTreeRoot @private
// {
// int layoutElementIndex;
// uint parentId; // This can be zero in the case of the root layout tree
// uint clipElementId; // This can be zero if there is no clip element
// int zIndex;
// ClayVector2 pointerOffset; // Only used when scroll containers are managed externally
// }
// struct LayoutElementTreeNode @private
// {
// LayoutElement *layoutElement;
// ClayVector2 position;
// ClayVector2 nextChildOffset;
// }
// struct MeasuredWord @private
// {
// int startOffset;
// int length;
// float width;
// int next;
// }
// struct MeasureTextCacheItem @private
// {
// Dimensions unwrappedDimensions;
// int measuredWordsStartIndex;
// bool containsNewlines;
// // Hash map data
// uint id;
// int nextIndex;
// uint generation;
// }
// def LayoutElementArray = carray::Array(<LayoutElement>);
// def CIntArray = carray::Array(<int>);
// def TextElementDataArray = carray::Array(<TextElementData>);
// def RectangleElementConfigArray = carray::Array(<RectangleElementConfig>);
// def TextElementConfigArray = carray::Array(<TextElementConfig>);
// def ImageElementConfigArray = carray::Array(<ImageElementConfig>);
// def FloatingElementConfigArray = carray::Array(<FloatingElementConfig>);
// def ScrollElementConfigArray = carray::Array(<ScrollElementConfig>);
// def CustomElementConfigArray = carray::Array(<CustomElementConfig>);
// def BorderElementConfigArray = carray::Array(<BorderElementConfig>);
// def LayoutElementPointerArray = carray::Array(<LayoutElement*>);
// def LayoutConfigArray = carray::Array(<LayoutConfig>);
// def ElementConfigArray = carray::Array(<ElementConfig>);
// def WrappedTextLineArray = carray::Array(<WrappedTextLine>);
// def LayoutElementTreeNodeArray = carray::Array(<LayoutElementTreeNode>);
// def LayoutElementTreeRootArray = carray::Array(<LayoutElementTreeRoot>);
// def LayoutElementHashMapItemArray = carray::Array(<LayoutElementHashMapItem>);
// def MeasureTextCacheItemArray = carray::Array(<MeasureTextCacheItem>);
// def MeasuredWordArray = carray::Array(<MeasuredWord>);
// def ElementIdArray = carray::Array(<ElementId>);
// def ScrollContainerDataInternalArray = carray::Array(<ScrollContainerData>);
// def BoolArray = carray::Array(<bool>);
// def CharArray = carray::Array(<char>);
// def DebugElementDataArray = carray::Array(<DebugElementData>);
// struct Context @extern ("Clay_Context")
// {
// int maxElementCount;
// int maxMeasureTextCacheWordCount;
// bool warningsEnabled;
// ErrorHandler errorHandler;
// BooleanWarnings booleanWarnings;
// WarningArray warnings;
// PointerData pointerInfo;
// Dimensions layoutDimensions;
// ElementId dynamicElementIndexBaseHash;
// uint dynamicElementIndex;
// bool debugModeEnabled;
// bool disableCulling;
// bool externalScrollHandlingEnabled;
// uint debugSelectedElementId;
// uint generation;
// uint128 arenaResetOffset;
// Arena internalArena;
// // Layout Elements / Render Commands
// LayoutElementArray layoutElements;
// RenderCommandArray renderCommands;
// CIntArray openLayoutElementStack;
// CIntArray layoutElementChildren;
// CIntArray layoutElementChildrenBuffer;
// TextElementDataArray textElementData;
// LayoutElementPointerArray imageElementPointers;
// CIntArray reusableElementIndexBuffer;
// CIntArray layoutElementClipElementIds;
// // Configs
// LayoutConfigArray layoutConfigs;
// ElementConfigArray elementConfigBuffer;
// ElementConfigArray elementConfigs;
// RectangleElementConfigArray rectangleElementConfigs;
// TextElementConfigArray textElementConfigs;
// ImageElementConfigArray imageElementConfigs;
// FloatingElementConfigArray floatingElementConfigs;
// ScrollElementConfigArray scrollElementConfigs;
// CustomElementConfigArray customElementConfigs;
// BorderElementConfigArray borderElementConfigs;
// // Misc Data Structures
// ClayStringArray layoutElementIdStrings;
// WrappedTextLineArray wrappedTextLines;
// LayoutElementTreeNodeArray layoutElementTreeNodeArray1;
// LayoutElementTreeRootArray layoutElementTreeRoots;
// LayoutElementHashMapItemArray layoutElementsHashMapInternal;
// CIntArray layoutElementsHashMap;
// MeasureTextCacheItemArray measureTextHashMapInternal;
// CIntArray measureTextHashMapInternalFreeList;
// CIntArray measureTextHashMap;
// MeasuredWordArray measuredWords;
// CIntArray measuredWordsFreeList;
// CIntArray openClipElementStack;
// ElementIdArray pointerOverIds;
// ScrollContainerDataInternalArray scrollContainerDatas;
// BoolArray treeNodeVisited;
// CharArray dynamicStringData;
// DebugElementDataArray debugElementData;
// }
// def OnHoverEvent = fn void(ElementId elementId, PointerData pointerData, iptr userData);
// def MeasureTextFunc = fn Dimensions(ClayString *text, TextElementConfig *config);
// def QueryScrollOffsetFunc = fn ClayVector2(uint elementId);
// // =====================
// // ===== FUNCTIONS =====
// // =====================
// // ===== Public Clay API C3 Functions (String replacement) =====
// fn ElementId getElementIdWithIndex(String idString, uint index) @export @inline
// { return __getElementIdWithIndex({idString.len, idString}, (uint)index); }
// fn ElementId getElementId(String idString) @export @inline
// { return __getElementId({idString.len, idString}); }
// // ===== Public Clay API Functions =====
// extern fn uint minMemorySize() @extern("Clay_MinMemorySize") @wasm @export;
// extern fn Arena createArena(uint capacity, void* offset) @extern("Clay_CreateArenaWithCapacityAndMemory") @wasm @export;
// extern fn void setPointerState(ClayVector2 position, bool pointerDown) @extern("Clay_SetPointerState") @export;
// extern fn Context* initialize(Arena arena, Dimensions layoutDimensions, ErrorHandler errorHandler) @extern("Clay_Initialize") @wasm @export;
// extern fn Context* getCurrentContext() @extern("Clay_GetCurrentContext") @export;
// extern fn void setCurrentContext(Context* context) @extern("Clay_SetCurrentContext") @export;
// extern fn void updateScrollContainer(bool enableDragScrolling, ClayVector2 scrollDelta, float deltaTime) @extern("Clay_UpdateScrollContainers") @export;
// extern fn void setLayoutDimensions (Dimensions dimensions) @extern("Clay_SetLayoutDimensions") @export;
// extern fn ElementData getElementData(ElementId id) @extern("Clay_GetElementData") @export;
// extern fn bool hovered() @extern("Clay_Hovered") @export;
// extern fn void onHover(OnHoverEvent onHover, iptr userData) @extern("Clay_OnHover") @export;
// extern fn bool pointerOver(ElementId elementId) @extern("Clay_PointerOver") @wasm @export;
// extern fn ScrollContainerData getScrollContainerData(ElementId id) @extern("Clay_GetScrollContainerData") @export;
// extern fn void setMeasureTextFunction(MeasureTextFunc measureText) @extern("Clay_SetMeasureTextFunction") @export;
// extern fn void setQueryScrollOffsetFunction(QueryScrollOffsetFunc queryScrollOffset) @extern("Clay_SetQueryScrollOffsetFunction") @export;
// extern fn RenderCommand * RenderCommandArray.get(RenderCommandArray* array, int index) @extern("Clay_RenderCommandArray_Get") @export;
// extern fn void setDebugModeEnabled(bool enabled) @extern("Clay_SetDebugModeEnabled") @export;
// extern fn bool isDebugModeEnabled() @extern("Clay_IsDebugModeEnabled") @export;
// extern fn void setCullingEnabled(bool enabled) @extern("Clay_SetCullingEnabled") @export;
// extern fn int getMaxMeasuredTextCachedWordCount() @extern("Clay_GetMaxElementCount") @export;
// extern fn void setMaxElementCount(int maxElementCount) @extern("Clay_SetMaxElementCount") @export;
// extern fn int getMaxElementCount() @extern("Clay_GetMaxMeasureTextCacheWordCount") @export;
// extern fn void setMaxMeasureTextCacheWordCount(int maxMeasureTextCacheWordCount) @extern("Clay_SetMaxMeasureTextCacheWordCount") @export;
// extern fn void resetMeasureTextCache() @extern("Clay_ResetMeasureTextCache") @export;
// extern fn void beginLayout() @extern("Clay_BeginLayout") @export;
// extern fn RenderCommandArray endLayout() @extern("Clay_EndLayout") @export;
// // ===== (NEW) Internal Clay API Functions (String replacement) =====
// extern fn ElementId __getElementIdWithIndex(ClayString idString, uint index) @extern("Clay_GetElementIdWithIndex") @export @private;
// extern fn ElementId __getElementId(ClayString idString) @extern("Clay_GetElementId") @export @private;
// // ===== Internal Clay API Functions =====
// extern fn void openElement() @extern ("Clay__OpenElement") @export @private;
// extern fn void closeElement() @extern("Clay__CloseElement") @export @private;
// extern fn void openTextElement(ClayString text, TextElementConfig *textConfig) @extern("Clay__OpenTextElement") @export @private;
// extern fn void elementPostConfiguration() @extern("Clay__ElementPostConfiguration") @export @private;
// extern fn LayoutConfig * storeLayoutConfig(LayoutConfig config) @extern("Clay__StoreLayoutConfig") @export @private;
// extern fn void attachId(ElementId id) @extern("Clay__AttachId") @export @private;
// extern fn void attachLayoutConfig(LayoutConfig *config) @extern("Clay__AttachLayoutConfig") @export @private;
// extern fn void attachElementConfig(ElementConfigUnion config, ElementConfigType type) @extern("Clay__AttachElementConfig") @export @private;
// extern fn RectangleElementConfig * storeRectangleElementConfig(RectangleElementConfig config) @extern("Clay__StoreRectangleElementConfig") @export @private;
// extern fn TextElementConfig * storeTextElementConfig(TextElementConfig config) @extern("Clay__StoreTextElementConfig") @export @private;
// extern fn ImageElementConfig * storeImageElementConfig(ImageElementConfig config) @extern("Clay__StoreImageElementConfig") @export @private;
// extern fn FloatingElementConfig * storeFloatingElementConfig(FloatingElementConfig config) @extern("Clay__StoreFloatingElementConfig") @export @private;
// extern fn CustomElementConfig * storeCustomElementConfig(CustomElementConfig config) @extern("Clay__StoreCustomElementConfig") @export @private;
// extern fn ScrollElementConfig * storeScrollElementConfig(ScrollElementConfig config) @extern("Clay__StoreScrollElementConfig") @export @private;
// extern fn BorderElementConfig * storeBorderElementConfig(BorderElementConfig config) @extern("Clay__StoreBorderElementConfig") @export @private;
// extern fn ElementId hashString(ClayString key, uint offset, uint seed) @extern("Clay__HashString") @export @private;
// extern fn uint getParentElementId() @extern("Clay__GetParentElementId") @export @private;
// // ==========================================================================
// // ===== An internal module for wrapping Struct Array's defined in Clay =====
// // ==========================================================================
// module clay::carray(<ElementType>);
// struct Array {
// int capacity;
// int length;
// ElementType *data;
// }