-
-
Notifications
You must be signed in to change notification settings - Fork 391
/
Copy pathclay.h
4085 lines (3719 loc) · 241 KB
/
clay.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// VERSION: 0.12
/*
NOTE: In order to use this library you must define
the following macro in exactly one file, _before_ including clay.h:
#define CLAY_IMPLEMENTATION
#include "clay.h"
See the examples folder for details.
*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
// SIMD includes on supported platforms
#if !defined(CLAY_DISABLE_SIMD) && (defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64))
#include <emmintrin.h>
#elif !defined(CLAY_DISABLE_SIMD) && defined(__aarch64__)
#include <arm_neon.h>
#endif
// -----------------------------------------
// HEADER DECLARATIONS ---------------------
// -----------------------------------------
#ifndef CLAY_HEADER
#define CLAY_HEADER
#if !( \
(defined(__cplusplus) && __cplusplus >= 202002L) || \
(defined(__STDC__) && __STDC__ == 1 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
defined(_MSC_VER) \
)
#error "Clay requires C99, C++20, or MSVC"
#endif
#ifdef CLAY_WASM
#define CLAY_WASM_EXPORT(name) __attribute__((export_name(name)))
#else
#define CLAY_WASM_EXPORT(null)
#endif
// Public Macro API ------------------------
#define CLAY__MAX(x, y) (((x) > (y)) ? (x) : (y))
#define CLAY__MIN(x, y) (((x) < (y)) ? (x) : (y))
#define CLAY_TEXT_CONFIG(...) Clay__StoreTextElementConfig(CLAY__CONFIG_WRAPPER(Clay_TextElementConfig, __VA_ARGS__))
#define CLAY_BORDER_OUTSIDE(widthValue) {widthValue, widthValue, widthValue, widthValue, 0}
#define CLAY_BORDER_ALL(widthValue) {widthValue, widthValue, widthValue, widthValue, widthValue}
#define CLAY_CORNER_RADIUS(radius) (CLAY__INIT(Clay_CornerRadius) { radius, radius, radius, radius })
#define CLAY_PADDING_ALL(padding) CLAY__CONFIG_WRAPPER(Clay_Padding, { padding, padding, padding, padding })
#define CLAY_SIZING_FIT(...) (CLAY__INIT(Clay_SizingAxis) { .size = { .minMax = { __VA_ARGS__ } }, .type = CLAY__SIZING_TYPE_FIT })
#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 })
#define CLAY_SIZING_PERCENT(percentOfParent) (CLAY__INIT(Clay_SizingAxis) { .size = { .percent = (percentOfParent) }, .type = CLAY__SIZING_TYPE_PERCENT })
#define CLAY_ID(label) CLAY_IDI(label, 0)
#define CLAY_IDI(label, index) Clay__HashString(CLAY_STRING(label), index, 0)
#define CLAY_ID_LOCAL(label) CLAY_IDI_LOCAL(label, 0)
#define CLAY_IDI_LOCAL(label, index) Clay__HashString(CLAY_STRING(label), index, Clay__GetParentElementId())
#define CLAY__STRING_LENGTH(s) ((sizeof(s) / sizeof((s)[0])) - sizeof((s)[0]))
#define CLAY__ENSURE_STRING_LITERAL(x) ("" x "")
// 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 -----------------------------------------------------
/* This macro looks scary on the surface, but is actually quite simple.
It turns a macro call like this:
CLAY({
.id = CLAY_ID("Container"),
.backgroundColor = { 255, 200, 200, 255 }
}) {
...children declared here
}
Into calls like this:
Clay_OpenElement();
Clay_ConfigureOpenElement((Clay_ElementDeclaration) {
.id = CLAY_ID("Container"),
.backgroundColor = { 255, 200, 200, 255 }
});
...children declared here
Clay_CloseElement();
The for loop will only ever run a single iteration, putting Clay__CloseElement() in the increment of the loop
means that it will run after the body - where the children are declared. It just exists to make sure you don't forget
to call Clay_CloseElement().
*/
#define CLAY(...) \
for ( \
CLAY__ELEMENT_DEFINITION_LATCH = (Clay__OpenElement(), Clay__ConfigureOpenElement(CLAY__CONFIG_WRAPPER(Clay_ElementDeclaration, __VA_ARGS__)), 0); \
CLAY__ELEMENT_DEFINITION_LATCH < 1; \
++CLAY__ELEMENT_DEFINITION_LATCH, Clay__CloseElement() \
)
// These macros exist to allow the CLAY() macro to be called both with an inline struct definition, such as
// CLAY({ .id = something... });
// As well as by passing a predefined declaration struct
// Clay_ElementDeclaration declarationStruct = ...
// CLAY(declarationStruct);
#define CLAY__WRAPPER_TYPE(type) Clay__##type##Wrapper
#define CLAY__WRAPPER_STRUCT(type) typedef struct { type wrapped; } CLAY__WRAPPER_TYPE(type)
#define CLAY__CONFIG_WRAPPER(type, ...) (CLAY__INIT(CLAY__WRAPPER_TYPE(type)) { __VA_ARGS__ }).wrapped
#define CLAY_TEXT(text, textConfig) Clay__OpenTextElement(text, textConfig)
#ifdef __cplusplus
#define CLAY__INIT(type) type
#define CLAY_PACKED_ENUM enum : uint8_t
#define CLAY__DEFAULT_STRUCT {}
#else
#define CLAY__INIT(type) (type)
#if defined(_MSC_VER) && !defined(__clang__)
#define CLAY_PACKED_ENUM __pragma(pack(push, 1)) enum __pragma(pack(pop))
#else
#define CLAY_PACKED_ENUM enum __attribute__((__packed__))
#endif
#if __STDC_VERSION__ >= 202311L
#define CLAY__DEFAULT_STRUCT {}
#else
#define CLAY__DEFAULT_STRUCT {0}
#endif
#endif // __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
// Utility Structs -------------------------
// Note: Clay_String is not guaranteed to be null terminated. It may be if created from a literal C string,
// but it is also used to represent slices.
typedef struct {
int32_t length;
// The underlying character memory. Note: this will not be copied and will not extend the lifetime of the underlying memory.
const char *chars;
} Clay_String;
// Clay_StringSlice is used to represent non owning string slices, and includes
// a baseChars field which points to the string this slice is derived from.
typedef struct {
int32_t length;
const char *chars;
const char *baseChars; // The source string / char* that this slice was derived from
} Clay_StringSlice;
typedef struct Clay_Context Clay_Context;
// Clay_Arena is a memory arena structure that is used by clay to manage its internal allocations.
// Rather than creating it by hand, it's easier to use Clay_CreateArenaWithCapacityAndMemory()
typedef struct {
uintptr_t nextAllocation;
size_t capacity;
char *memory;
} Clay_Arena;
typedef struct {
float width, height;
} Clay_Dimensions;
typedef struct {
float x, y;
} Clay_Vector2;
// Internally clay conventionally represents colors as 0-255, but interpretation is up to the renderer.
typedef struct {
float r, g, b, a;
} Clay_Color;
typedef struct {
float x, y, width, height;
} Clay_BoundingBox;
// Primarily created via the CLAY_ID(), CLAY_IDI(), CLAY_ID_LOCAL() and CLAY_IDI_LOCAL() macros.
// Represents a hashed string ID used for identifying and finding specific clay UI elements, required
// by functions such as Clay_PointerOver() and Clay_GetElementData().
typedef struct {
uint32_t id; // The resulting hash generated from the other fields.
uint32_t offset; // A numerical offset applied after computing the hash from stringId.
uint32_t baseId; // A base hash value to start from, for example the parent element ID is used when calculating CLAY_ID_LOCAL().
Clay_String stringId; // The string id to hash.
} Clay_ElementId;
// Controls the "radius", or corner rounding of elements, including rectangles, borders and images.
// The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
typedef struct {
float topLeft;
float topRight;
float bottomLeft;
float bottomRight;
} Clay_CornerRadius;
// Element Configs ---------------------------
// Controls the direction in which child elements will be automatically laid out.
typedef CLAY_PACKED_ENUM {
// (Default) Lays out child elements from left to right with increasing x.
CLAY_LEFT_TO_RIGHT,
// Lays out child elements from top to bottom with increasing y.
CLAY_TOP_TO_BOTTOM,
} Clay_LayoutDirection;
// Controls the alignment along the x axis (horizontal) of child elements.
typedef CLAY_PACKED_ENUM {
// (Default) Aligns child elements to the left hand side of this element, offset by padding.width.left
CLAY_ALIGN_X_LEFT,
// Aligns child elements to the right hand side of this element, offset by padding.width.right
CLAY_ALIGN_X_RIGHT,
// Aligns child elements horizontally to the center of this element
CLAY_ALIGN_X_CENTER,
} Clay_LayoutAlignmentX;
// Controls the alignment along the y axis (vertical) of child elements.
typedef CLAY_PACKED_ENUM {
// (Default) Aligns child elements to the top of this element, offset by padding.width.top
CLAY_ALIGN_Y_TOP,
// Aligns child elements to the bottom of this element, offset by padding.width.bottom
CLAY_ALIGN_Y_BOTTOM,
// Aligns child elements vertiically to the center of this element
CLAY_ALIGN_Y_CENTER,
} Clay_LayoutAlignmentY;
// Controls how the element takes up space inside its parent container.
typedef CLAY_PACKED_ENUM {
// (default) Wraps tightly to the size of the element's contents.
CLAY__SIZING_TYPE_FIT,
// Expands along this axis to fill available space in the parent element, sharing it with other GROW elements.
CLAY__SIZING_TYPE_GROW,
// Expects 0-1 range. Clamps the axis size to a percent of the parent container's axis size minus padding and child gaps.
CLAY__SIZING_TYPE_PERCENT,
// Clamps the axis size to an exact size in pixels.
CLAY__SIZING_TYPE_FIXED,
} Clay__SizingType;
// Controls how child elements are aligned on each axis.
typedef struct {
Clay_LayoutAlignmentX x; // Controls alignment of children along the x axis.
Clay_LayoutAlignmentY y; // Controls alignment of children along the y axis.
} Clay_ChildAlignment;
// Controls the minimum and maximum size in pixels that this element is allowed to grow or shrink to,
// overriding sizing types such as FIT or GROW.
typedef struct {
float min; // The smallest final size of the element on this axis will be this value in pixels.
float max; // The largest final size of the element on this axis will be this value in pixels.
} Clay_SizingMinMax;
// Controls the sizing of this element along one axis inside its parent container.
typedef struct {
union {
Clay_SizingMinMax minMax; // Controls the minimum and maximum size in pixels that this element is allowed to grow or shrink to, overriding sizing types such as FIT or GROW.
float percent; // Expects 0-1 range. Clamps the axis size to a percent of the parent container's axis size minus padding and child gaps.
} size;
Clay__SizingType type; // Controls how the element takes up space inside its parent container.
} Clay_SizingAxis;
// Controls the sizing of this element along one axis inside its parent container.
typedef struct {
Clay_SizingAxis width; // Controls the width sizing of the element, along the x axis.
Clay_SizingAxis height; // Controls the height sizing of the element, along the y axis.
} Clay_Sizing;
// Controls "padding" in pixels, which is a gap between the bounding box of this element and where its children
// will be placed.
typedef struct {
uint16_t left;
uint16_t right;
uint16_t top;
uint16_t bottom;
} Clay_Padding;
CLAY__WRAPPER_STRUCT(Clay_Padding);
// Controls various settings that affect the size and position of an element, as well as the sizes and positions
// of any child elements.
typedef struct {
Clay_Sizing sizing; // Controls the sizing of this element inside it's parent container, including FIT, GROW, PERCENT and FIXED sizing.
Clay_Padding padding; // Controls "padding" in pixels, which is a gap between the bounding box of this element and where its children will be placed.
uint16_t childGap; // Controls the gap in pixels between child elements along the layout axis (horizontal gap for LEFT_TO_RIGHT, vertical gap for TOP_TO_BOTTOM).
Clay_ChildAlignment childAlignment; // Controls how child elements are aligned on each axis.
Clay_LayoutDirection layoutDirection; // Controls the direction in which child elements will be automatically laid out.
} Clay_LayoutConfig;
CLAY__WRAPPER_STRUCT(Clay_LayoutConfig);
extern Clay_LayoutConfig CLAY_LAYOUT_DEFAULT;
// Controls how text "wraps", that is how it is broken into multiple lines when there is insufficient horizontal space.
typedef CLAY_PACKED_ENUM {
// (default) breaks on whitespace characters.
CLAY_TEXT_WRAP_WORDS,
// Don't break on space characters, only on newlines.
CLAY_TEXT_WRAP_NEWLINES,
// Disable text wrapping entirely.
CLAY_TEXT_WRAP_NONE,
} Clay_TextElementConfigWrapMode;
// Controls how wrapped lines of text are horizontally aligned within the outer text bounding box.
typedef CLAY_PACKED_ENUM {
// (default) Horizontally aligns wrapped lines of text to the left hand side of their bounding box.
CLAY_TEXT_ALIGN_LEFT,
// Horizontally aligns wrapped lines of text to the center of their bounding box.
CLAY_TEXT_ALIGN_CENTER,
// Horizontally aligns wrapped lines of text to the right hand side of their bounding box.
CLAY_TEXT_ALIGN_RIGHT,
} Clay_TextAlignment;
// Controls various functionality related to text elements.
typedef struct {
// The RGBA color of the font to render, conventionally specified as 0-255.
Clay_Color textColor;
// An integer transparently passed to Clay_MeasureText to identify the font to use.
// The debug view will pass fontId = 0 for its internal text.
uint16_t fontId;
// Controls the size of the font. Handled by the function provided to Clay_MeasureText.
uint16_t fontSize;
// Controls extra horizontal spacing between characters. Handled by the function provided to Clay_MeasureText.
uint16_t letterSpacing;
// Controls additional vertical space between wrapped lines of text.
uint16_t lineHeight;
// Controls how text "wraps", that is how it is broken into multiple lines when there is insufficient horizontal space.
// CLAY_TEXT_WRAP_WORDS (default) breaks on whitespace characters.
// CLAY_TEXT_WRAP_NEWLINES doesn't break on space characters, only on newlines.
// CLAY_TEXT_WRAP_NONE disables wrapping entirely.
Clay_TextElementConfigWrapMode wrapMode;
// Controls how wrapped lines of text are horizontally aligned within the outer text bounding box.
// CLAY_TEXT_ALIGN_LEFT (default) - Horizontally aligns wrapped lines of text to the left hand side of their bounding box.
// CLAY_TEXT_ALIGN_CENTER - Horizontally aligns wrapped lines of text to the center of their bounding box.
// CLAY_TEXT_ALIGN_RIGHT - Horizontally aligns wrapped lines of text to the right hand side of their bounding box.
Clay_TextAlignment textAlignment;
// When set to true, clay will hash the entire text contents of this string as an identifier for its internal
// text measurement cache, rather than just the pointer and length. This will incur significant performance cost for
// long bodies of text.
bool hashStringContents;
} Clay_TextElementConfig;
CLAY__WRAPPER_STRUCT(Clay_TextElementConfig);
// Image --------------------------------
// Controls various settings related to image elements.
typedef struct {
void* imageData; // A transparent pointer used to pass image data through to the renderer.
Clay_Dimensions sourceDimensions; // The original dimensions of the source image, used to control aspect ratio.
} Clay_ImageElementConfig;
CLAY__WRAPPER_STRUCT(Clay_ImageElementConfig);
// Floating -----------------------------
// Controls where a floating element is offset relative to its parent element.
// Note: see https://github.com/user-attachments/assets/b8c6dfaa-c1b1-41a4-be55-013473e4a6ce for a visual explanation.
typedef CLAY_PACKED_ENUM {
CLAY_ATTACH_POINT_LEFT_TOP,
CLAY_ATTACH_POINT_LEFT_CENTER,
CLAY_ATTACH_POINT_LEFT_BOTTOM,
CLAY_ATTACH_POINT_CENTER_TOP,
CLAY_ATTACH_POINT_CENTER_CENTER,
CLAY_ATTACH_POINT_CENTER_BOTTOM,
CLAY_ATTACH_POINT_RIGHT_TOP,
CLAY_ATTACH_POINT_RIGHT_CENTER,
CLAY_ATTACH_POINT_RIGHT_BOTTOM,
} Clay_FloatingAttachPointType;
// Controls where a floating element is offset relative to its parent element.
typedef struct {
Clay_FloatingAttachPointType element; // Controls the origin point on a floating element that attaches to its parent.
Clay_FloatingAttachPointType parent; // Controls the origin point on the parent element that the floating element attaches to.
} Clay_FloatingAttachPoints;
// Controls how mouse pointer events like hover and click are captured or passed through to elements underneath a floating element.
typedef CLAY_PACKED_ENUM {
// (default) "Capture" the pointer event and don't allow events like hover and click to pass through to elements underneath.
CLAY_POINTER_CAPTURE_MODE_CAPTURE,
// CLAY_POINTER_CAPTURE_MODE_PARENT, TODO pass pointer through to attached parent
// Transparently pass through pointer events like hover and click to elements underneath the floating element.
CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
} Clay_PointerCaptureMode;
// Controls which element a floating element is "attached" to (i.e. relative offset from).
typedef CLAY_PACKED_ENUM {
// (default) Disables floating for this element.
CLAY_ATTACH_TO_NONE,
// Attaches this floating element to its parent, positioned based on the .attachPoints and .offset fields.
CLAY_ATTACH_TO_PARENT,
// Attaches this floating element to an element with a specific ID, specified with the .parentId field. positioned based on the .attachPoints and .offset fields.
CLAY_ATTACH_TO_ELEMENT_WITH_ID,
// Attaches this floating element to the root of the layout, which combined with the .offset field provides functionality similar to "absolute positioning".
CLAY_ATTACH_TO_ROOT,
} Clay_FloatingAttachToElement;
// Controls various settings related to "floating" elements, which are elements that "float" above other elements, potentially overlapping their boundaries,
// and not affecting the layout of sibling or parent elements.
typedef struct {
// Offsets this floating element by the provided x,y coordinates from its attachPoints.
Clay_Vector2 offset;
// Expands the boundaries of the outer floating element without affecting its children.
Clay_Dimensions expand;
// When used in conjunction with .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID, attaches this floating element to the element in the hierarchy with the provided ID.
// Hint: attach the ID to the other element with .id = CLAY_ID("yourId"), and specify the id the same way, with .parentId = CLAY_ID("yourId").id
uint32_t parentId;
// Controls the z index of this floating element and all its children. Floating elements are sorted in ascending z order before output.
// zIndex is also passed to the renderer for all elements contained within this floating element.
int16_t zIndex;
// Controls how mouse pointer events like hover and click are captured or passed through to elements underneath / behind a floating element.
// Enum is of the form CLAY_ATTACH_POINT_foo_bar. See Clay_FloatingAttachPoints for more details.
// Note: see <img src="https://github.com/user-attachments/assets/b8c6dfaa-c1b1-41a4-be55-013473e4a6ce />
// and <img src="https://github.com/user-attachments/assets/ebe75e0d-1904-46b0-982d-418f929d1516 /> for a visual explanation.
Clay_FloatingAttachPoints attachPoints;
// Controls how mouse pointer events like hover and click are captured or passed through to elements underneath a floating element.
// CLAY_POINTER_CAPTURE_MODE_CAPTURE (default) - "Capture" the pointer event and don't allow events like hover and click to pass through to elements underneath.
// CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH - Transparently pass through pointer events like hover and click to elements underneath the floating element.
Clay_PointerCaptureMode pointerCaptureMode;
// Controls which element a floating element is "attached" to (i.e. relative offset from).
// CLAY_ATTACH_TO_NONE (default) - Disables floating for this element.
// CLAY_ATTACH_TO_PARENT - Attaches this floating element to its parent, positioned based on the .attachPoints and .offset fields.
// CLAY_ATTACH_TO_ELEMENT_WITH_ID - Attaches this floating element to an element with a specific ID, specified with the .parentId field. positioned based on the .attachPoints and .offset fields.
// CLAY_ATTACH_TO_ROOT - Attaches this floating element to the root of the layout, which combined with the .offset field provides functionality similar to "absolute positioning".
Clay_FloatingAttachToElement attachTo;
} Clay_FloatingElementConfig;
CLAY__WRAPPER_STRUCT(Clay_FloatingElementConfig);
// Custom -----------------------------
// Controls various settings related to custom elements.
typedef struct {
// A transparent pointer through which you can pass custom data to the renderer.
// Generates CUSTOM render commands.
void* customData;
} Clay_CustomElementConfig;
CLAY__WRAPPER_STRUCT(Clay_CustomElementConfig);
// Scroll -----------------------------
// Controls the axis on which an element switches to "scrolling", which clips the contents and allows scrolling in that direction.
typedef struct {
bool horizontal; // Clip overflowing elements on the X axis and allow scrolling left and right.
bool vertical; // Clip overflowing elements on the YU axis and allow scrolling up and down.
} Clay_ScrollElementConfig;
CLAY__WRAPPER_STRUCT(Clay_ScrollElementConfig);
// Border -----------------------------
// Controls the widths of individual element borders.
typedef struct {
uint16_t left;
uint16_t right;
uint16_t top;
uint16_t bottom;
// Creates borders between each child element, depending on the .layoutDirection.
// e.g. for LEFT_TO_RIGHT, borders will be vertical lines, and for TOP_TO_BOTTOM borders will be horizontal lines.
// .betweenChildren borders will result in individual RECTANGLE render commands being generated.
uint16_t betweenChildren;
} Clay_BorderWidth;
// Controls settings related to element borders.
typedef struct {
Clay_Color color; // Controls the color of all borders with width > 0. Conventionally represented as 0-255, but interpretation is up to the renderer.
Clay_BorderWidth width; // Controls the widths of individual borders. At least one of these should be > 0 for a BORDER render command to be generated.
} Clay_BorderElementConfig;
CLAY__WRAPPER_STRUCT(Clay_BorderElementConfig);
// Render Command Data -----------------------------
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_TEXT
typedef struct {
// A string slice containing the text to be rendered.
// Note: this is not guaranteed to be null terminated.
Clay_StringSlice stringContents;
// Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
Clay_Color textColor;
// An integer representing the font to use to render this text, transparently passed through from the text declaration.
uint16_t fontId;
uint16_t fontSize;
// Specifies the extra whitespace gap in pixels between each character.
uint16_t letterSpacing;
// The height of the bounding box for this line of text.
uint16_t lineHeight;
} Clay_TextRenderData;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_RECTANGLE
typedef struct {
// The solid background color to fill this rectangle with. Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
Clay_Color backgroundColor;
// Controls the "radius", or corner rounding of elements, including rectangles, borders and images.
// The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
Clay_CornerRadius cornerRadius;
} Clay_RectangleRenderData;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_IMAGE
typedef struct {
// The tint color for this image. Note that the default value is 0,0,0,0 and should likely be interpreted
// as "untinted".
// Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
Clay_Color backgroundColor;
// Controls the "radius", or corner rounding of this image.
// The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
Clay_CornerRadius cornerRadius;
// The original dimensions of the source image, used to control aspect ratio.
Clay_Dimensions sourceDimensions;
// A pointer transparently passed through from the original element definition, typically used to represent image data.
void* imageData;
} Clay_ImageRenderData;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_CUSTOM
typedef struct {
// Passed through from .backgroundColor in the original element declaration.
// Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
Clay_Color backgroundColor;
// Controls the "radius", or corner rounding of this custom element.
// The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
Clay_CornerRadius cornerRadius;
// A pointer transparently passed through from the original element definition.
void* customData;
} Clay_CustomRenderData;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_SCISSOR_START || commandType == CLAY_RENDER_COMMAND_TYPE_SCISSOR_END
typedef struct {
bool horizontal;
bool vertical;
} Clay_ScrollRenderData;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_BORDER
typedef struct {
// Controls a shared color for all this element's borders.
// Conventionally represented as 0-255 for each channel, but interpretation is up to the renderer.
Clay_Color color;
// Specifies the "radius", or corner rounding of this border element.
// The rounding is determined by drawing a circle inset into the element corner by (radius, radius) pixels.
Clay_CornerRadius cornerRadius;
// Controls individual border side widths.
Clay_BorderWidth width;
} Clay_BorderRenderData;
// A struct union containing data specific to this command's .commandType
typedef union {
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_RECTANGLE
Clay_RectangleRenderData rectangle;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_TEXT
Clay_TextRenderData text;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_IMAGE
Clay_ImageRenderData image;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_CUSTOM
Clay_CustomRenderData custom;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_BORDER
Clay_BorderRenderData border;
// Render command data when commandType == CLAY_RENDER_COMMAND_TYPE_SCROLL
Clay_ScrollRenderData scroll;
} Clay_RenderData;
// Miscellaneous Structs & Enums ---------------------------------
// Data representing the current internal state of a scrolling element.
typedef struct {
// Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
// Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
Clay_Vector2 *scrollPosition;
// The bounding box of the scroll element.
Clay_Dimensions scrollContainerDimensions;
// The outer dimensions of the inner scroll container content, including the padding of the parent scroll container.
Clay_Dimensions contentDimensions;
// The config that was originally passed to the scroll element.
Clay_ScrollElementConfig config;
// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
bool found;
} Clay_ScrollContainerData;
// Bounding box and other data for a specific UI element.
typedef struct {
// The rectangle that encloses this UI element, with the position relative to the root of the layout.
Clay_BoundingBox boundingBox;
// Indicates whether an actual Element matched the provided ID or if the default struct was returned.
bool found;
} Clay_ElementData;
// Used by renderers to determine specific handling for each render command.
typedef CLAY_PACKED_ENUM {
// This command type should be skipped.
CLAY_RENDER_COMMAND_TYPE_NONE,
// The renderer should draw a solid color rectangle.
CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
// The renderer should draw a colored border inset into the bounding box.
CLAY_RENDER_COMMAND_TYPE_BORDER,
// The renderer should draw text.
CLAY_RENDER_COMMAND_TYPE_TEXT,
// The renderer should draw an image.
CLAY_RENDER_COMMAND_TYPE_IMAGE,
// The renderer should begin clipping all future draw commands, only rendering content that falls within the provided boundingBox.
CLAY_RENDER_COMMAND_TYPE_SCISSOR_START,
// The renderer should finish any previously active clipping, and begin rendering elements in full again.
CLAY_RENDER_COMMAND_TYPE_SCISSOR_END,
// The renderer should provide a custom implementation for handling this render command based on its .customData
CLAY_RENDER_COMMAND_TYPE_CUSTOM,
} Clay_RenderCommandType;
typedef struct {
// A rectangular box that fully encloses this UI element, with the position relative to the root of the layout.
Clay_BoundingBox boundingBox;
// A struct union containing data specific to this command's commandType.
Clay_RenderData renderData;
// A pointer transparently passed through from the original element declaration.
void *userData;
// The id of this element, transparently passed through from the original element declaration.
uint32_t id;
// The z order required for drawing this command correctly.
// Note: the render command array is already sorted in ascending order, and will produce correct results if drawn in naive order.
// This field is intended for use in batching renderers for improved performance.
int16_t zIndex;
// Specifies how to handle rendering of this command.
// CLAY_RENDER_COMMAND_TYPE_RECTANGLE - The renderer should draw a solid color rectangle.
// CLAY_RENDER_COMMAND_TYPE_BORDER - The renderer should draw a colored border inset into the bounding box.
// CLAY_RENDER_COMMAND_TYPE_TEXT - The renderer should draw text.
// CLAY_RENDER_COMMAND_TYPE_IMAGE - The renderer should draw an image.
// CLAY_RENDER_COMMAND_TYPE_SCISSOR_START - The renderer should begin clipping all future draw commands, only rendering content that falls within the provided boundingBox.
// CLAY_RENDER_COMMAND_TYPE_SCISSOR_END - The renderer should finish any previously active clipping, and begin rendering elements in full again.
// CLAY_RENDER_COMMAND_TYPE_CUSTOM - The renderer should provide a custom implementation for handling this render command based on its .customData
Clay_RenderCommandType commandType;
} Clay_RenderCommand;
// A sized array of render commands.
typedef struct {
// The underlying max capacity of the array, not necessarily all initialized.
int32_t capacity;
// The number of initialized elements in this array. Used for loops and iteration.
int32_t length;
// A pointer to the first element in the internal array.
Clay_RenderCommand* internalArray;
} Clay_RenderCommandArray;
// Represents the current state of interaction with clay this frame.
typedef CLAY_PACKED_ENUM {
// A left mouse click, or touch occurred this frame.
CLAY_POINTER_DATA_PRESSED_THIS_FRAME,
// The left mouse button click or touch happened at some point in the past, and is still currently held down this frame.
CLAY_POINTER_DATA_PRESSED,
// The left mouse button click or touch was released this frame.
CLAY_POINTER_DATA_RELEASED_THIS_FRAME,
// The left mouse button click or touch is not currently down / was released at some point in the past.
CLAY_POINTER_DATA_RELEASED,
} Clay_PointerDataInteractionState;
// Information on the current state of pointer interactions this frame.
typedef struct {
// The position of the mouse / touch / pointer relative to the root of the layout.
Clay_Vector2 position;
// Represents the current state of interaction with clay this frame.
// CLAY_POINTER_DATA_PRESSED_THIS_FRAME - A left mouse click, or touch occurred this frame.
// CLAY_POINTER_DATA_PRESSED - The left mouse button click or touch happened at some point in the past, and is still currently held down this frame.
// CLAY_POINTER_DATA_RELEASED_THIS_FRAME - The left mouse button click or touch was released this frame.
// CLAY_POINTER_DATA_RELEASED - The left mouse button click or touch is not currently down / was released at some point in the past.
Clay_PointerDataInteractionState state;
} Clay_PointerData;
typedef struct {
// Primarily created via the CLAY_ID(), CLAY_IDI(), CLAY_ID_LOCAL() and CLAY_IDI_LOCAL() macros.
// Represents a hashed string ID used for identifying and finding specific clay UI elements, required by functions such as Clay_PointerOver() and Clay_GetElementData().
Clay_ElementId id;
// Controls various settings that affect the size and position of an element, as well as the sizes and positions of any child elements.
Clay_LayoutConfig layout;
// Controls the background color of the resulting element.
// By convention specified as 0-255, but interpretation is up to the renderer.
// If no other config is specified, .backgroundColor will generate a RECTANGLE render command, otherwise it will be passed as a property to IMAGE or CUSTOM render commands.
Clay_Color backgroundColor;
// Controls the "radius", or corner rounding of elements, including rectangles, borders and images.
Clay_CornerRadius cornerRadius;
// Controls settings related to image elements.
Clay_ImageElementConfig image;
// Controls whether and how an element "floats", which means it layers over the top of other elements in z order, and doesn't affect the position and size of siblings or parent elements.
// Note: in order to activate floating, .floating.attachTo must be set to something other than the default value.
Clay_FloatingElementConfig floating;
// Used to create CUSTOM render commands, usually to render element types not supported by Clay.
Clay_CustomElementConfig custom;
// Controls whether an element should clip its contents and allow scrolling rather than expanding to contain them.
Clay_ScrollElementConfig scroll;
// Controls settings related to element borders, and will generate BORDER render commands.
Clay_BorderElementConfig border;
// A pointer that will be transparently passed through to resulting render commands.
void *userData;
} Clay_ElementDeclaration;
CLAY__WRAPPER_STRUCT(Clay_ElementDeclaration);
// Represents the type of error clay encountered while computing layout.
typedef CLAY_PACKED_ENUM {
// A text measurement function wasn't provided using Clay_SetMeasureTextFunction(), or the provided function was null.
CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
// Clay attempted to allocate its internal data structures but ran out of space.
// The arena passed to Clay_Initialize was created with a capacity smaller than that required by Clay_MinMemorySize().
CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
// Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxElementCount().
CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
// Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxMeasureTextCacheWordCount().
CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
// Two elements were declared with exactly the same ID within one layout.
CLAY_ERROR_TYPE_DUPLICATE_ID,
// A floating element was declared using CLAY_ATTACH_TO_ELEMENT_ID and either an invalid .parentId was provided or no element with the provided .parentId was found.
CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND,
// An element was declared that using CLAY_SIZING_PERCENT but the percentage value was over 1. Percentage values are expected to be in the 0-1 range.
CLAY_ERROR_TYPE_PERCENTAGE_OVER_1,
// Clay encountered an internal error. It would be wonderful if you could report this so we can fix it!
CLAY_ERROR_TYPE_INTERNAL_ERROR,
} Clay_ErrorType;
// Data to identify the error that clay has encountered.
typedef struct {
// Represents the type of error clay encountered while computing layout.
// CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED - A text measurement function wasn't provided using Clay_SetMeasureTextFunction(), or the provided function was null.
// CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED - Clay attempted to allocate its internal data structures but ran out of space. The arena passed to Clay_Initialize was created with a capacity smaller than that required by Clay_MinMemorySize().
// CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED - Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxElementCount().
// CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED - Clay ran out of capacity in its internal array for storing elements. This limit can be increased with Clay_SetMaxMeasureTextCacheWordCount().
// CLAY_ERROR_TYPE_DUPLICATE_ID - Two elements were declared with exactly the same ID within one layout.
// CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND - A floating element was declared using CLAY_ATTACH_TO_ELEMENT_ID and either an invalid .parentId was provided or no element with the provided .parentId was found.
// CLAY_ERROR_TYPE_PERCENTAGE_OVER_1 - An element was declared that using CLAY_SIZING_PERCENT but the percentage value was over 1. Percentage values are expected to be in the 0-1 range.
// CLAY_ERROR_TYPE_INTERNAL_ERROR - Clay encountered an internal error. It would be wonderful if you could report this so we can fix it!
Clay_ErrorType errorType;
// A string containing human-readable error text that explains the error in more detail.
Clay_String errorText;
// A transparent pointer passed through from when the error handler was first provided.
void *userData;
} Clay_ErrorData;
// A wrapper struct around Clay's error handler function.
typedef struct {
// A user provided function to call when Clay encounters an error during layout.
void (*errorHandlerFunction)(Clay_ErrorData errorText);
// A pointer that will be transparently passed through to the error handler when it is called.
void *userData;
} Clay_ErrorHandler;
// Function Forward Declarations ---------------------------------
// Public API functions ------------------------------------------
// Returns the size, in bytes, of the minimum amount of memory Clay requires to operate at its current settings.
uint32_t Clay_MinMemorySize(void);
// Creates an arena for clay to use for its internal allocations, given a certain capacity in bytes and a pointer to an allocation of at least that size.
// Intended to be used with Clay_MinMemorySize in the following way:
// uint32_t minMemoryRequired = Clay_MinMemorySize();
// Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(minMemoryRequired, malloc(minMemoryRequired));
Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *memory);
// Sets the state of the "pointer" (i.e. the mouse or touch) in Clay's internal data. Used for detecting and responding to mouse events in the debug view,
// as well as for Clay_Hovered() and scroll element handling.
void Clay_SetPointerState(Clay_Vector2 position, bool pointerDown);
// Initialize Clay's internal arena and setup required data before layout can begin. Only needs to be called once.
// - arena can be created using Clay_CreateArenaWithCapacityAndMemory()
// - layoutDimensions are the initial bounding dimensions of the layout (i.e. the screen width and height for a full screen layout)
// - errorHandler is used by Clay to inform you if something has gone wrong in configuration or layout.
Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler);
// Returns the Context that clay is currently using. Used when using multiple instances of clay simultaneously.
Clay_Context* Clay_GetCurrentContext(void);
// Sets the context that clay will use to compute the layout.
// Used to restore a context saved from Clay_GetCurrentContext when using multiple instances of clay simultaneously.
void Clay_SetCurrentContext(Clay_Context* context);
// Updates the state of Clay's internal scroll data, updating scroll content positions if scrollDelta is non zero, and progressing momentum scrolling.
// - enableDragScrolling when set to true will enable mobile device like "touch drag" scroll of scroll containers, including momentum scrolling after the touch has ended.
// - scrollDelta is the amount to scroll this frame on each axis in pixels.
// - deltaTime is the time in seconds since the last "frame" (scroll update)
void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime);
// Updates the layout dimensions in response to the window or outer container being resized.
void Clay_SetLayoutDimensions(Clay_Dimensions dimensions);
// Called before starting any layout declarations.
void Clay_BeginLayout(void);
// Called when all layout declarations are finished.
// Computes the layout and generates and returns the array of render commands to draw.
Clay_RenderCommandArray Clay_EndLayout(void);
// Calculates a hash ID from the given idString.
// Generally only used for dynamic strings when CLAY_ID("stringLiteral") can't be used.
Clay_ElementId Clay_GetElementId(Clay_String idString);
// Calculates a hash ID from the given idString and index.
// - index is used to avoid constructing dynamic ID strings in loops.
// Generally only used for dynamic strings when CLAY_IDI("stringLiteral", index) can't be used.
Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index);
// Returns layout data such as the final calculated bounding box for an element with a given ID.
// The returned Clay_ElementData contains a `found` bool that will be true if an element with the provided ID was found.
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
Clay_ElementData Clay_GetElementData(Clay_ElementId id);
// Returns true if the pointer position provided by Clay_SetPointerState is within the current element's bounding box.
// Works during element declaration, e.g. CLAY({ .backgroundColor = Clay_Hovered() ? BLUE : RED });
bool Clay_Hovered(void);
// Bind a callback that will be called when the pointer position provided by Clay_SetPointerState is within the current element's bounding box.
// - onHoverFunction is a function pointer to a user defined function.
// - userData is a pointer that will be transparently passed through when the onHoverFunction is called.
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerData, intptr_t userData), intptr_t userData);
// An imperative function that returns true if the pointer position provided by Clay_SetPointerState is within the element with the provided ID's bounding box.
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
bool Clay_PointerOver(Clay_ElementId elementId);
// Returns data representing the state of the scrolling element with the provided ID.
// The returned Clay_ScrollContainerData contains a `found` bool that will be true if a scroll element was found with the provided ID.
// An imperative function that returns true if the pointer position provided by Clay_SetPointerState is within the element with the provided ID's bounding box.
// This ID can be calculated either with CLAY_ID() for string literal IDs, or Clay_GetElementId for dynamic strings.
Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id);
// Binds a callback function that Clay will call to determine the dimensions of a given string slice.
// - measureTextFunction is a user provided function that adheres to the interface Clay_Dimensions (Clay_StringSlice text, Clay_TextElementConfig *config, void *userData);
// - userData is a pointer that will be transparently passed through when the measureTextFunction is called.
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData), void *userData);
// Experimental - Used in cases where Clay needs to integrate with a system that manages its own scrolling containers externally.
// Please reach out if you plan to use this function, as it may be subject to change.
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId, void *userData), void *userData);
// A bounds-checked "get" function for the Clay_RenderCommandArray returned from Clay_EndLayout().
Clay_RenderCommand * Clay_RenderCommandArray_Get(Clay_RenderCommandArray* array, int32_t index);
// Enables and disables Clay's internal debug tools.
// This state is retained and does not need to be set each frame.
void Clay_SetDebugModeEnabled(bool enabled);
// Returns true if Clay's internal debug tools are currently enabled.
bool Clay_IsDebugModeEnabled(void);
// Enables and disables visibility culling. By default, Clay will not generate render commands for elements whose bounding box is entirely outside the screen.
void Clay_SetCullingEnabled(bool enabled);
// Returns the maximum number of UI elements supported by Clay's current configuration.
int32_t Clay_GetMaxElementCount(void);
// Modifies the maximum number of UI elements supported by Clay's current configuration.
// This may require reallocating additional memory, and re-calling Clay_Initialize();
void Clay_SetMaxElementCount(int32_t maxElementCount);
// Returns the maximum number of measured "words" (whitespace seperated runs of characters) that Clay can store in its internal text measurement cache.
int32_t Clay_GetMaxMeasureTextCacheWordCount(void);
// Modifies the maximum number of measured "words" (whitespace seperated runs of characters) that Clay can store in its internal text measurement cache.
// This may require reallocating additional memory, and re-calling Clay_Initialize();
void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount);
// Resets Clay's internal text measurement cache, useful if memory to represent strings is being re-used.
// Similar behaviour can be achieved on an individual text element level by using Clay_TextElementConfig.hashStringContents
void Clay_ResetMeasureTextCache(void);
// Internal API functions required by macros ----------------------
void Clay__OpenElement(void);
void Clay__ConfigureOpenElement(const Clay_ElementDeclaration config);
void Clay__CloseElement(void);
Clay_ElementId Clay__HashString(Clay_String key, uint32_t offset, uint32_t seed);
void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig);
Clay_TextElementConfig *Clay__StoreTextElementConfig(Clay_TextElementConfig config);
uint32_t Clay__GetParentElementId(void);
extern Clay_Color Clay__debugViewHighlightColor;
extern uint32_t Clay__debugViewWidth;
#ifdef __cplusplus
}
#endif
#endif // CLAY_HEADER
// -----------------------------------------
// IMPLEMENTATION --------------------------
// -----------------------------------------
#ifdef CLAY_IMPLEMENTATION
#undef CLAY_IMPLEMENTATION
#ifndef CLAY__NULL
#define CLAY__NULL 0
#endif
#ifndef CLAY__MAXFLOAT
#define CLAY__MAXFLOAT 3.40282346638528859812e+38F
#endif
Clay_LayoutConfig CLAY_LAYOUT_DEFAULT = CLAY__DEFAULT_STRUCT;
Clay_Color Clay__Color_DEFAULT = CLAY__DEFAULT_STRUCT;
Clay_CornerRadius Clay__CornerRadius_DEFAULT = CLAY__DEFAULT_STRUCT;
Clay_BorderWidth Clay__BorderWidth_DEFAULT = CLAY__DEFAULT_STRUCT;
// The below functions define array bounds checking and convenience functions for a provided type.
#define CLAY__ARRAY_DEFINE_FUNCTIONS(typeName, arrayName) \
\
typedef struct \
{ \
int32_t length; \
typeName *internalArray; \
} arrayName##Slice; \
\
typeName typeName##_DEFAULT = CLAY__DEFAULT_STRUCT; \
\
arrayName arrayName##_Allocate_Arena(int32_t capacity, Clay_Arena *arena) { \
return CLAY__INIT(arrayName){.capacity = capacity, .length = 0, \
.internalArray = (typeName *)Clay__Array_Allocate_Arena(capacity, sizeof(typeName), arena)}; \
} \
\
typeName *arrayName##_Get(arrayName *array, int32_t index) { \
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &typeName##_DEFAULT; \
} \
\
typeName arrayName##_GetValue(arrayName *array, int32_t index) { \
return Clay__Array_RangeCheck(index, array->length) ? array->internalArray[index] : typeName##_DEFAULT; \
} \
\
typeName *arrayName##_Add(arrayName *array, typeName item) { \
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) { \
array->internalArray[array->length++] = item; \
return &array->internalArray[array->length - 1]; \
} \
return &typeName##_DEFAULT; \
} \
\
typeName *arrayName##Slice_Get(arrayName##Slice *slice, int32_t index) { \
return Clay__Array_RangeCheck(index, slice->length) ? &slice->internalArray[index] : &typeName##_DEFAULT; \
} \
\
typeName arrayName##_RemoveSwapback(arrayName *array, int32_t index) { \
if (Clay__Array_RangeCheck(index, array->length)) { \
array->length--; \
typeName removed = array->internalArray[index]; \
array->internalArray[index] = array->internalArray[array->length]; \
return removed; \
} \
return typeName##_DEFAULT; \
} \
\
void arrayName##_Set(arrayName *array, int32_t index, typeName value) { \
if (Clay__Array_RangeCheck(index, array->capacity)) { \
array->internalArray[index] = value; \
array->length = index < array->length ? array->length : index + 1; \
} \
} \
#define CLAY__ARRAY_DEFINE(typeName, arrayName) \
typedef struct \
{ \
int32_t capacity; \
int32_t length; \
typeName *internalArray; \
} arrayName; \
\
CLAY__ARRAY_DEFINE_FUNCTIONS(typeName, arrayName) \
Clay_Context *Clay__currentContext;
int32_t Clay__defaultMaxElementCount = 8192;
int32_t Clay__defaultMaxMeasureTextWordCacheCount = 16384;
void Clay__ErrorHandlerFunctionDefault(Clay_ErrorData errorText) {
(void) errorText;
}
Clay_String CLAY__SPACECHAR = { .length = 1, .chars = " " };
Clay_String CLAY__STRING_DEFAULT = { .length = 0, .chars = NULL };
typedef struct {
bool maxElementsExceeded;
bool maxRenderCommandsExceeded;
bool maxTextMeasureCacheExceeded;
bool textMeasurementFunctionNotSet;
} Clay_BooleanWarnings;
typedef struct {
Clay_String baseMessage;
Clay_String dynamicMessage;
} Clay__Warning;
Clay__Warning CLAY__WARNING_DEFAULT = CLAY__DEFAULT_STRUCT;
typedef struct {
int32_t capacity;
int32_t length;
Clay__Warning *internalArray;
} Clay__WarningArray;
typedef struct {
Clay_Color backgroundColor;
Clay_CornerRadius cornerRadius;
void* userData;
} Clay_SharedElementConfig;
CLAY__WRAPPER_STRUCT(Clay_SharedElementConfig);
Clay__WarningArray Clay__WarningArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena);