Created
January 31, 2025 17:01
-
-
Save farism/deb09a8c21ae5589d944e41a3c7930a3 to your computer and use it in GitHub Desktop.
clay-beef
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
namespace Clay; | |
public static class Clay | |
{ | |
[CRepr] | |
public struct Array<T> | |
{ | |
public int32 capacity; | |
public int32 length; | |
public T* internalArray; | |
} | |
[CRepr] | |
public struct ClayString | |
{ | |
public int32 length; | |
public char8* chars; | |
public this(int32 length, char8* chars) | |
{ | |
this.length = length; | |
this.chars = chars; | |
} | |
} | |
[CRepr] | |
public struct StringSlice | |
{ | |
public int32 length; | |
public char8* chars; | |
public char8* baseChars; | |
} | |
[CRepr] | |
public struct Arena | |
{ | |
public uint* nextAllocation; | |
public uint* capacity; | |
public char8* memory; | |
} | |
[CRepr] | |
public struct Dimensions | |
{ | |
public float width = 0, height = 0; | |
public this(float width, float height) | |
{ | |
this.width = width; | |
this.height = height; | |
} | |
} | |
[CRepr] | |
public struct Vector2 | |
{ | |
public float x, y; | |
} | |
[CRepr] | |
public struct Color | |
{ | |
public float r = 0, g = 0, b = 0, a = 0; | |
public this(float r = 0, float g = 0, float b = 0, float a = 0) | |
{ | |
this.r = r; | |
this.g = g; | |
this.b = b; | |
this.a = a; | |
} | |
} | |
[CRepr] | |
public struct BoundingBox | |
{ | |
public float x = 0, y = 0, width = 0, height = 0; | |
} | |
[CRepr] | |
public struct ElementId | |
{ | |
public uint32 id, offset, baseId; | |
public ClayString stringId; | |
public this(uint32 id, uint32 offset, uint32 baseId, ClayString stringId) | |
{ | |
this.id = id; | |
this.offset = offset; | |
this.baseId = baseId; | |
this.stringId = stringId; | |
} | |
public this() | |
{ | |
this.id = this.offset = this.baseId = 0; | |
this.stringId = ClayString(0, ""); | |
} | |
} | |
[CRepr] | |
public struct CornerRadius | |
{ | |
public float topLeft = 0, topRight = 0, bottomLeft = 0, bottomRight = 0; | |
public this(float topLeft, float topRight, float bottomLeft, float bottomRight) | |
{ | |
this.topLeft = topLeft; | |
this.topRight = topRight; | |
this.bottomLeft = bottomLeft; | |
this.bottomRight = bottomRight; | |
} | |
public this(float radius) | |
{ | |
this.topLeft = this.topRight = this.bottomLeft = this.bottomRight = radius; | |
} | |
public this() { } | |
} | |
public enum ElementConfigType | |
{ | |
Rectangle = 1, | |
Border = 2, | |
Floating = 4, | |
Scroll = 8, | |
Image = 16, | |
Text = 32, | |
Custom = 64, | |
// Odin specific enum types | |
Id = 65, | |
Layout = 66, | |
Children = 67, | |
} | |
public enum LayoutDirection | |
{ | |
LeftToRight, | |
TopToBottom, | |
} | |
public enum LayoutAlignmentX | |
{ | |
Left, | |
Right, | |
Center, | |
} | |
public enum LayoutAlignmentY | |
{ | |
Top, | |
Bottom, | |
Center, | |
} | |
public enum SizingType | |
{ | |
Fit, | |
Grow, | |
Percent, | |
Fixed, | |
} | |
[CRepr] | |
public struct ChildAlignment | |
{ | |
public LayoutAlignmentX x = .Left; | |
public LayoutAlignmentY y = .Top; | |
public this(LayoutAlignmentX x = .Left, LayoutAlignmentY y = .Top) | |
{ | |
this.x = x; | |
this.y = y; | |
} | |
} | |
[CRepr] | |
public struct SizingMinMax | |
{ | |
public float min = 0, max = 0; | |
public this(float min, float max) | |
{ | |
this.min = min; | |
this.max = max; | |
} | |
public this() { } | |
} | |
[CRepr, Union] | |
public struct SizingConstraints | |
{ | |
public SizingMinMax minMax; | |
public float percent; | |
public this(SizingMinMax minMax) | |
{ | |
this.minMax = minMax; | |
} | |
public this(float percent) | |
{ | |
this.percent = percent; | |
} | |
} | |
[CRepr] | |
public struct SizingAxis | |
{ | |
public SizingConstraints constraints; | |
public SizingType type; | |
public this(SizingType type, SizingConstraints constraints) | |
{ | |
this.constraints = constraints; | |
this.type = type; | |
} | |
public this(SizingType type, SizingMinMax minMax) | |
{ | |
this.constraints = .(minMax); | |
this.type = type; | |
} | |
public this(SizingType type, float percent) | |
{ | |
this.constraints = .(percent); | |
this.type = type; | |
} | |
} | |
[CRepr] | |
public struct Sizing | |
{ | |
public SizingAxis width = SizingAxis(.Fixed, 0); | |
public SizingAxis height = SizingAxis(.Fixed, 0); | |
public this(SizingAxis width, SizingAxis height) | |
{ | |
this.width = width; | |
this.height = height; | |
} | |
public this() { } | |
} | |
[CRepr] | |
public struct Padding | |
{ | |
public uint16 left, right, top, bottom; | |
public this(uint16 left, uint16 right, uint16 top, uint16 bottom) | |
{ | |
this.left = left; | |
this.right = right; | |
this.top = top; | |
this.bottom = bottom; | |
} | |
public this(uint16 padding) | |
{ | |
this.left = this.right = this.top = this.bottom = padding; | |
} | |
} | |
[CRepr] | |
public struct LayoutConfig | |
{ | |
public Sizing sizing = .(); | |
public Padding padding = .(0); | |
public uint16 childGap = 0; | |
public ChildAlignment childAlignment = .(); | |
public LayoutDirection layoutDirection = .LeftToRight; | |
} | |
[CRepr] | |
public struct RectangleElementConfig | |
{ | |
public Color color; | |
public CornerRadius cornerRadius; | |
} | |
public enum TextWrapMode | |
{ | |
Words, | |
Newlines, | |
None, | |
} | |
[CRepr] | |
public struct TextElementConfig | |
{ | |
public Color textColor; | |
public uint16 fontId, fontSize, letterSpacing, lineHeight; | |
public TextWrapMode wrapMode; | |
public bool hashStringContents; | |
} | |
[CRepr] | |
public struct ImageElementConfig | |
{ | |
public void* imageData; | |
public Dimensions sourceDimensions; | |
} | |
public enum FloatingAttachPointType | |
{ | |
LeftTop, | |
LeftCenter, | |
LeftBottom, | |
CenterTop, | |
CenterCenter, | |
CenterBottom, | |
RightTop, | |
RightCenter, | |
RightBottom, | |
} | |
[CRepr] | |
public struct FloatingAttachPoints | |
{ | |
public FloatingAttachPointType element; | |
public FloatingAttachPointType parent; | |
} | |
public enum PointerCaptureMode | |
{ | |
Capture, | |
Passthrough, | |
} | |
[CRepr] | |
public struct FloatingElementConfig | |
{ | |
public Vector2 offset; | |
public Dimensions expand; | |
public uint16 zIndex; | |
public uint32 parentId; | |
public FloatingAttachPoints attachment; | |
public PointerCaptureMode pointerCaptureMode; | |
} | |
[CRepr] | |
public struct CustomElementConfig | |
{ | |
public void* customData; | |
} | |
[CRepr] | |
public struct ScrollElementConfig | |
{ | |
public bool horizontal; | |
public bool vertical; | |
} | |
[CRepr] | |
public struct Border | |
{ | |
public uint32 width = 0; | |
public Color color = .(); | |
} | |
[CRepr] | |
public struct BorderElementConfig | |
{ | |
public Border left = .(); | |
public Border right = .(); | |
public Border top = .(); | |
public Border bottom = .(); | |
public Border betweenChildren = .(); | |
public CornerRadius cornerRadius = .(); | |
public this(Border left, Border right, Border top, Border bottom, Border betweenChildren, CornerRadius cornerRadius) | |
{ | |
this.left = left; | |
this.right = right; | |
this.top = top; | |
this.bottom = bottom; | |
this.betweenChildren = betweenChildren; | |
this.cornerRadius = cornerRadius; | |
} | |
public this(Border all, float radius) | |
{ | |
this.left = this.right = this.top = this.bottom = this.betweenChildren = all; | |
this.cornerRadius = .(radius); | |
} | |
public this(Border all) | |
{ | |
this.left = this.right = this.top = this.bottom = this.betweenChildren = all; | |
} | |
} | |
[CRepr, Union] | |
public struct ElementConfigUnion | |
{ | |
public RectangleElementConfig* rectangleElementConfig; | |
public TextElementConfig* textElementConfig; | |
public ImageElementConfig* imageElementConfig; | |
public FloatingElementConfig* floatingElementConfig; | |
public CustomElementConfig* customElementConfig; | |
public ScrollElementConfig* scrollElementConfig; | |
public BorderElementConfig* borderElementConfig; | |
}; | |
[CRepr] | |
public struct ElementConfig | |
{ | |
public ElementConfigType type; | |
public ElementConfigUnion config; | |
}; | |
[CRepr] | |
public 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. | |
public Vector2* scrollPosition; | |
public Dimensions scrollContainerDimensions; | |
public Dimensions contentDimensions; | |
public ScrollElementConfig config; // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned. | |
public bool found; | |
} | |
[CRepr] | |
public struct ElementData | |
{ | |
public BoundingBox boundingBox; | |
// Indicates whether an actual Element matched the provided ID or if the default struct was returned. | |
public bool found; | |
}; | |
public enum RenderCommandType | |
{ | |
None, | |
Rectangle, | |
Border, | |
Text, | |
Image, | |
ScissorStart, | |
ScissorEnd, | |
Custom, | |
} | |
[CRepr] | |
public struct RenderCommand | |
{ | |
public BoundingBox boundingBox; | |
public ElementConfigUnion config; | |
public StringSlice text; | |
public int32 zIndex; | |
public uint32 id; | |
public RenderCommandType commandType; | |
} | |
public enum ErrorType | |
{ | |
TextMeasurementFunctionNotProvided, | |
ArenaCapacityExceeded, | |
ElementsCapacityExceeded, | |
TextMeasurementCapacityExceeded, | |
DuplicateId, | |
FloatingContainerParentNotFound, | |
InternalError, | |
} | |
[CRepr] | |
public struct ErrorData | |
{ | |
public ErrorType errorType; | |
public ClayString errorText; | |
public void* userData; | |
} | |
public function void ErrorHandlerCallback(ErrorData errorData); | |
[CRepr] | |
public struct ErrorHandler | |
{ | |
public ErrorHandlerCallback handler; | |
public void* userData; | |
public this(ErrorHandlerCallback handler, void* userData) | |
{ | |
this.handler = handler; | |
this.userData = userData; | |
} | |
} | |
[CLink] | |
public static extern uint32 Clay_MinMemorySize(); | |
[CLink] | |
public static extern Arena Clay_CreateArenaWithCapacityAndMemory(uint32 capacity, uint8* offset); | |
[CLink] | |
public static extern void Clay_SetPointerState(Vector2 position, bool pointerDown); | |
[CLink] | |
public static extern void Clay_Initialize(Arena arena, Dimensions layoutDimensions, ErrorHandler errorHandler); | |
[CLink] | |
public static extern void Clay_UpdateScrollContainers(bool enableDragScrolling, Vector2 scrollDelta, float deltaTime); | |
[CLink] | |
public static extern void Clay_SetLayoutDimensions(Dimensions dimensions); | |
[CLink] | |
public static extern void Clay_BeginLayout(); | |
[CLink] | |
public static extern Array<RenderCommand> Clay_EndLayout(); | |
[CLink] | |
public static extern bool Clay_PointerOver(ElementId id); | |
[CLink] | |
public static extern ElementId Clay_GetElementId(ClayString id); | |
[CLink] | |
public static extern ScrollContainerData Clay_GetScrollContainerData(ElementId id); | |
[CLink] | |
public static extern void Clay_SetMeasureTextFunction(function Dimensions(StringSlice text, TextElementConfig* config, uint64* userData) measureTextFunction, uint64* userData); | |
[CLink] | |
public static extern RenderCommand* Clay_RenderCommandArray_Get(Array<RenderCommand>* array, int32 index); | |
[CLink] | |
public static extern void Clay_SetDebugModeEnabled(bool enabled); | |
[CLink] | |
public static extern void Clay__OpenElement(); | |
[CLink] | |
public static extern void Clay__CloseElement(); | |
[CLink] | |
public static extern void Clay__ElementPostConfiguration(); | |
[CLink] | |
public static extern void Clay__OpenTextElement(ClayString text, TextElementConfig* textConfig); | |
[CLink] | |
public static extern void Clay__AttachId(ElementId id); | |
[CLink] | |
public static extern void Clay__AttachLayoutConfig(LayoutConfig* layoutConfig); | |
[CLink] | |
public static extern void Clay__AttachElementConfig(void* config, ElementConfigType type); | |
[CLink] | |
public static extern LayoutConfig* Clay__StoreLayoutConfig(LayoutConfig config); | |
[CLink] | |
public static extern RectangleElementConfig* Clay__StoreRectangleElementConfig(RectangleElementConfig config); | |
[CLink] | |
public static extern TextElementConfig* Clay__StoreTextElementConfig(TextElementConfig config); | |
[CLink] | |
public static extern ImageElementConfig* Clay__StoreImageElementConfig(ImageElementConfig config); | |
[CLink] | |
public static extern FloatingElementConfig* Clay__StoreFloatingElementConfig(FloatingElementConfig config); | |
[CLink] | |
public static extern CustomElementConfig* Clay__StoreCustomElementConfig(CustomElementConfig config); | |
[CLink] | |
public static extern ScrollElementConfig* Clay__StoreScrollElementConfig(ScrollElementConfig config); | |
[CLink] | |
public static extern BorderElementConfig* Clay__StoreBorderElementConfig(BorderElementConfig config); | |
[CLink] | |
public static extern ElementId Clay__HashString(ClayString toHash, uint32 index, uint32 seed); | |
[CLink] | |
public static extern uint32 Clay__GetOpenLayoutElementId(); | |
function void ChildrenCallback(); | |
public struct ChildrenConfig | |
{ | |
function void callback(); | |
} | |
public struct TypedConfig | |
{ | |
public ElementConfigType type; | |
public void* config = null; | |
public ElementId id = ElementId(); | |
public this(ElementConfigType type, void* config, ElementId id) | |
{ | |
this.type = type; | |
this.config = config; | |
this.id = id; | |
} | |
public this(ElementConfigType type, void* config) | |
{ | |
this.type = type; | |
this.config = config; | |
} | |
public this(ElementConfigType type, ElementId id) | |
{ | |
this.type = type; | |
this.id = id; | |
} | |
} | |
public static void UI(params TypedConfig[] configs) | |
{ | |
Clay__OpenElement(); | |
defer Clay__CloseElement(); | |
for (let config in configs) | |
{ | |
switch (config.type) { | |
case ElementConfigType.Id: | |
Clay__AttachId(config.id); | |
case ElementConfigType.Layout: | |
Clay__AttachLayoutConfig((LayoutConfig*)config.config); | |
case ElementConfigType.Children: | |
(ChildrenConfig*)config.config; | |
default: | |
Clay__AttachElementConfig(config.config, config.type); | |
} | |
} | |
Clay__ElementPostConfiguration(); | |
} | |
public struct UIConfig | |
{ | |
public ElementId id; | |
public LayoutConfig layout; | |
public RectangleElementConfig rectangle; | |
public TextElementConfig text; | |
public ImageElementConfig image; | |
public FloatingElementConfig floating; | |
public CustomElementConfig custom; | |
public ScrollElementConfig scroll; | |
public BorderElementConfig border; | |
}; | |
public static void UI2(...) | |
{ | |
Clay__OpenElement(); | |
defer Clay__CloseElement(); | |
/*switch (config.id) { | |
case ElementConfigType.Id: | |
Clay__AttachId(config.id); | |
case ElementConfigType.Layout: | |
Clay__AttachLayoutConfig((LayoutConfig*)config.config); | |
default: | |
Clay__AttachElementConfig(config.config, config.type); | |
}*/ | |
Clay__ElementPostConfiguration(); | |
} | |
public static TypedConfig Layout(LayoutConfig config) | |
{ | |
return .(ElementConfigType.Layout, Clay__StoreLayoutConfig(config)); | |
} | |
public static TypedConfig Rectangle(RectangleElementConfig config) | |
{ | |
return .(ElementConfigType.Rectangle, Clay__StoreRectangleElementConfig(config)); | |
} | |
public static void Text(String text, TextElementConfig* config) | |
{ | |
Clay__OpenTextElement(MakeClayString(text), config); | |
} | |
public static TextElementConfig* TextConfig(TextElementConfig config) | |
{ | |
return Clay__StoreTextElementConfig(config); | |
} | |
public static TypedConfig Image(ImageElementConfig config) | |
{ | |
return .(ElementConfigType.Image, Clay__StoreImageElementConfig(config)); | |
} | |
public static TypedConfig Floating(FloatingElementConfig config) | |
{ | |
return .(ElementConfigType.Floating, Clay__StoreFloatingElementConfig(config)); | |
} | |
public static TypedConfig Custom(CustomElementConfig config) | |
{ | |
return .(ElementConfigType.Custom, Clay__StoreCustomElementConfig(config)); | |
} | |
public static TypedConfig Scroll(ScrollElementConfig config) | |
{ | |
return .(ElementConfigType.Scroll, Clay__StoreScrollElementConfig(config)); | |
} | |
public static TypedConfig Border(BorderElementConfig config) | |
{ | |
return .(ElementConfigType.Border, Clay__StoreBorderElementConfig(config)); | |
} | |
public static TypedConfig BorderOutside(Border border) | |
{ | |
return .(ElementConfigType.Border, Clay__StoreBorderElementConfig(.(border))); | |
} | |
public static TypedConfig BorderOutsideRadius(Border outsideBorders, float radius) | |
{ | |
return .(ElementConfigType.Border, Clay__StoreBorderElementConfig(.(outsideBorders, .(radius)))); | |
} | |
public static TypedConfig BorderAll(Border allBorders) | |
{ | |
return .(ElementConfigType.Border, Clay__StoreBorderElementConfig(.(allBorders))); | |
} | |
public static TypedConfig BorderAllRadius(Border allBorders, float radius) | |
{ | |
return .(ElementConfigType.Border, Clay__StoreBorderElementConfig(.(allBorders, radius))); | |
} | |
public static CornerRadius CornerRadiusAll(float radius) | |
{ | |
return .(radius); | |
} | |
public static SizingAxis SizingFit(SizingMinMax sizeMinMax = .()) | |
{ | |
return SizingAxis(.Fit, sizeMinMax); | |
} | |
public static SizingAxis SizingGrow(SizingMinMax sizeMinMax = .()) | |
{ | |
return SizingAxis(.Grow, sizeMinMax); | |
} | |
public static SizingAxis SizingExpand() | |
{ | |
return SizingAxis(.Grow, 100); | |
} | |
public static SizingAxis SizingFixed(float size) | |
{ | |
return SizingAxis(.Fixed, .(size, size)); | |
} | |
public static SizingAxis SizingPercent(float sizePercent) | |
{ | |
return SizingAxis(.Percent, .(sizePercent)); | |
} | |
public static ClayString MakeClayString(String label) | |
{ | |
return .((int32)label.Length, label); | |
} | |
public static TypedConfig ID(String label, uint32 index = 0) | |
{ | |
return TypedConfig(ElementConfigType.Id, Clay__HashString(MakeClayString(label), index, 0)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment