mirror of
				https://github.com/nicbarker/clay.git
				synced 2025-11-04 00:26:17 +00:00 
			
		
		
		
	Finish off odin bindings and add raylib example
This commit is contained in:
		
							parent
							
								
									cf61b75ba5
								
							
						
					
					
						commit
						b2fde01a22
					
				| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
TODO
 | 
			
		||||
| 
						 | 
				
			
			@ -5,429 +5,423 @@ import "core:strings"
 | 
			
		|||
foreign import Clay "clay.a"
 | 
			
		||||
 | 
			
		||||
String :: struct {
 | 
			
		||||
	length: c.int,
 | 
			
		||||
	chars:  [^]c.char,
 | 
			
		||||
    length: c.int,
 | 
			
		||||
    chars:  [^]c.char,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vector2 :: struct {
 | 
			
		||||
	x: c.float,
 | 
			
		||||
	y: c.float,
 | 
			
		||||
    x: c.float,
 | 
			
		||||
    y: c.float,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Dimensions :: struct {
 | 
			
		||||
	width:  c.float,
 | 
			
		||||
	height: c.float,
 | 
			
		||||
    width:  c.float,
 | 
			
		||||
    height: c.float,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Arena :: struct {
 | 
			
		||||
	label:          String,
 | 
			
		||||
	nextAllocation: c.uint64_t,
 | 
			
		||||
	capacity:       c.uint64_t,
 | 
			
		||||
	memory:         [^]c.char,
 | 
			
		||||
    label:          String,
 | 
			
		||||
    nextAllocation: c.uint64_t,
 | 
			
		||||
    capacity:       c.uint64_t,
 | 
			
		||||
    memory:         [^]c.char,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BoundingBox :: struct {
 | 
			
		||||
	x:      c.float,
 | 
			
		||||
	y:      c.float,
 | 
			
		||||
	width:  c.float,
 | 
			
		||||
	height: c.float,
 | 
			
		||||
    x:      c.float,
 | 
			
		||||
    y:      c.float,
 | 
			
		||||
    width:  c.float,
 | 
			
		||||
    height: c.float,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Color :: struct {
 | 
			
		||||
	r: c.float,
 | 
			
		||||
	g: c.float,
 | 
			
		||||
	b: c.float,
 | 
			
		||||
	a: c.float,
 | 
			
		||||
    r: c.float,
 | 
			
		||||
    g: c.float,
 | 
			
		||||
    b: c.float,
 | 
			
		||||
    a: c.float,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CornerRadius :: struct {
 | 
			
		||||
	topLeft:     c.float,
 | 
			
		||||
	topRight:    c.float,
 | 
			
		||||
	bottomLeft:  c.float,
 | 
			
		||||
	bottomRight: c.float,
 | 
			
		||||
    topLeft:     c.float,
 | 
			
		||||
    topRight:    c.float,
 | 
			
		||||
    bottomLeft:  c.float,
 | 
			
		||||
    bottomRight: c.float,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BorderData :: struct {
 | 
			
		||||
	width: c.uint32_t,
 | 
			
		||||
	color: Color,
 | 
			
		||||
    width: c.uint32_t,
 | 
			
		||||
    color: Color,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RenderCommandType :: enum u8 {
 | 
			
		||||
	None,
 | 
			
		||||
	Rectangle,
 | 
			
		||||
	Border,
 | 
			
		||||
	Text,
 | 
			
		||||
	Image,
 | 
			
		||||
	ScissorStart,
 | 
			
		||||
	ScissorEnd,
 | 
			
		||||
	Custom,
 | 
			
		||||
    None,
 | 
			
		||||
    Rectangle,
 | 
			
		||||
    Border,
 | 
			
		||||
    Text,
 | 
			
		||||
    Image,
 | 
			
		||||
    ScissorStart,
 | 
			
		||||
    ScissorEnd,
 | 
			
		||||
    Custom,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RectangleElementConfig :: struct {
 | 
			
		||||
	color:        Color,
 | 
			
		||||
	cornerRadius: CornerRadius,
 | 
			
		||||
    color:        Color,
 | 
			
		||||
    cornerRadius: CornerRadius,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TextElementConfig :: struct {
 | 
			
		||||
	textColor:     Color,
 | 
			
		||||
	fontId:        c.uint16_t,
 | 
			
		||||
	fontSize:      c.uint16_t,
 | 
			
		||||
	letterSpacing: c.uint16_t,
 | 
			
		||||
	lineSpacing:   c.uint16_t,
 | 
			
		||||
    textColor:     Color,
 | 
			
		||||
    fontId:        c.uint16_t,
 | 
			
		||||
    fontSize:      c.uint16_t,
 | 
			
		||||
    letterSpacing: c.uint16_t,
 | 
			
		||||
    lineSpacing:   c.uint16_t,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ImageElementConfig :: struct {
 | 
			
		||||
	imageData:        rawptr,
 | 
			
		||||
	sourceDimensions: Dimensions,
 | 
			
		||||
    imageData:        rawptr,
 | 
			
		||||
    sourceDimensions: Dimensions,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CustomElementConfig :: struct {
 | 
			
		||||
	customData: rawptr,
 | 
			
		||||
    customData: rawptr,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BorderElementConfig :: struct {
 | 
			
		||||
	left:            BorderData,
 | 
			
		||||
	right:           BorderData,
 | 
			
		||||
	top:             BorderData,
 | 
			
		||||
	bottom:          BorderData,
 | 
			
		||||
	betweenChildren: BorderData,
 | 
			
		||||
	cornerRadius:    CornerRadius,
 | 
			
		||||
    left:            BorderData,
 | 
			
		||||
    right:           BorderData,
 | 
			
		||||
    top:             BorderData,
 | 
			
		||||
    bottom:          BorderData,
 | 
			
		||||
    betweenChildren: BorderData,
 | 
			
		||||
    cornerRadius:    CornerRadius,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ScrollElementConfig :: struct {
 | 
			
		||||
	horizontal: c.bool,
 | 
			
		||||
	vertical:   c.bool,
 | 
			
		||||
    horizontal: c.bool,
 | 
			
		||||
    vertical:   c.bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FloatingAttachPointType :: enum u8 {
 | 
			
		||||
	LEFT_TOP,
 | 
			
		||||
	LEFT_CENTER,
 | 
			
		||||
	LEFT_BOTTOM,
 | 
			
		||||
	CENTER_TOP,
 | 
			
		||||
	CENTER_CENTER,
 | 
			
		||||
	CENTER_BOTTOM,
 | 
			
		||||
	RIGHT_TOP,
 | 
			
		||||
	RIGHT_CENTER,
 | 
			
		||||
	RIGHT_BOTTOM,
 | 
			
		||||
    LEFT_TOP,
 | 
			
		||||
    LEFT_CENTER,
 | 
			
		||||
    LEFT_BOTTOM,
 | 
			
		||||
    CENTER_TOP,
 | 
			
		||||
    CENTER_CENTER,
 | 
			
		||||
    CENTER_BOTTOM,
 | 
			
		||||
    RIGHT_TOP,
 | 
			
		||||
    RIGHT_CENTER,
 | 
			
		||||
    RIGHT_BOTTOM,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FloatingAttachPoints :: struct {
 | 
			
		||||
	element: FloatingAttachPointType,
 | 
			
		||||
	parent:  FloatingAttachPointType,
 | 
			
		||||
    element: FloatingAttachPointType,
 | 
			
		||||
    parent:  FloatingAttachPointType,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FloatingElementConfig :: struct {
 | 
			
		||||
	offset:     Vector2,
 | 
			
		||||
	expand:     Dimensions,
 | 
			
		||||
	zIndex:     c.uint16_t,
 | 
			
		||||
	parentId:   c.uint32_t,
 | 
			
		||||
	attachment: FloatingAttachPoints,
 | 
			
		||||
    offset:     Vector2,
 | 
			
		||||
    expand:     Dimensions,
 | 
			
		||||
    zIndex:     c.uint16_t,
 | 
			
		||||
    parentId:   c.uint32_t,
 | 
			
		||||
    attachment: FloatingAttachPoints,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ElementConfigUnion :: struct #raw_union {
 | 
			
		||||
	rectangleElementConfig: ^RectangleElementConfig,
 | 
			
		||||
	textElementConfig:      ^TextElementConfig,
 | 
			
		||||
	imageElementConfig:     ^ImageElementConfig,
 | 
			
		||||
	customElementConfig:    ^CustomElementConfig,
 | 
			
		||||
	borderElementConfig:    ^BorderElementConfig,
 | 
			
		||||
    rectangleElementConfig: ^RectangleElementConfig,
 | 
			
		||||
    textElementConfig:      ^TextElementConfig,
 | 
			
		||||
    imageElementConfig:     ^ImageElementConfig,
 | 
			
		||||
    customElementConfig:    ^CustomElementConfig,
 | 
			
		||||
    borderElementConfig:    ^BorderElementConfig,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RenderCommand :: struct {
 | 
			
		||||
	boundingBox: BoundingBox,
 | 
			
		||||
	config:      ElementConfigUnion,
 | 
			
		||||
	text:        String,
 | 
			
		||||
	id:          c.uint32_t,
 | 
			
		||||
	commandType: RenderCommandType,
 | 
			
		||||
    boundingBox: BoundingBox,
 | 
			
		||||
    config:      ElementConfigUnion,
 | 
			
		||||
    text:        String,
 | 
			
		||||
    id:          c.uint32_t,
 | 
			
		||||
    commandType: RenderCommandType,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ScrollContainerData :: 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.
 | 
			
		||||
	scrollPosition:            ^Vector2,
 | 
			
		||||
	scrollContainerDimensions: Dimensions,
 | 
			
		||||
	contentDimensions:         Dimensions,
 | 
			
		||||
	config:                    ScrollElementConfig,
 | 
			
		||||
	// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
 | 
			
		||||
	found:                     c.bool,
 | 
			
		||||
    // 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.
 | 
			
		||||
    scrollPosition:            ^Vector2,
 | 
			
		||||
    scrollContainerDimensions: Dimensions,
 | 
			
		||||
    contentDimensions:         Dimensions,
 | 
			
		||||
    config:                    ScrollElementConfig,
 | 
			
		||||
    // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
 | 
			
		||||
    found:                     c.bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SizingType :: enum u8 {
 | 
			
		||||
	FIT,
 | 
			
		||||
	GROW,
 | 
			
		||||
	PERCENT,
 | 
			
		||||
    FIT,
 | 
			
		||||
    GROW,
 | 
			
		||||
    PERCENT,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SizingConstraintsMinMax :: struct {
 | 
			
		||||
    min: c.float,
 | 
			
		||||
    max: c.float,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SizingConstraints :: struct #raw_union {
 | 
			
		||||
    sizeMinMax:  SizingConstraintsMinMax,
 | 
			
		||||
    sizePercent: c.float,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SizingAxis :: struct {
 | 
			
		||||
	// Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
 | 
			
		||||
	min:  c.float,
 | 
			
		||||
	max:  c.float,
 | 
			
		||||
	type: SizingType,
 | 
			
		||||
    // Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
 | 
			
		||||
    constraints: SizingConstraints,
 | 
			
		||||
    type:        SizingType,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sizing :: struct {
 | 
			
		||||
	width:  SizingAxis,
 | 
			
		||||
	height: SizingAxis,
 | 
			
		||||
    width:  SizingAxis,
 | 
			
		||||
    height: SizingAxis,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Padding :: struct {
 | 
			
		||||
	x: c.uint16_t,
 | 
			
		||||
	y: c.uint16_t,
 | 
			
		||||
    x: c.uint16_t,
 | 
			
		||||
    y: c.uint16_t,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LayoutDirection :: enum u8 {
 | 
			
		||||
	LEFT_TO_RIGHT,
 | 
			
		||||
	TOP_TO_BOTTOM,
 | 
			
		||||
    LEFT_TO_RIGHT,
 | 
			
		||||
    TOP_TO_BOTTOM,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LayoutAlignmentX :: enum u8 {
 | 
			
		||||
	LEFT,
 | 
			
		||||
	RIGHT,
 | 
			
		||||
	CENTER,
 | 
			
		||||
    LEFT,
 | 
			
		||||
    RIGHT,
 | 
			
		||||
    CENTER,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LayoutAlignmentY :: enum u8 {
 | 
			
		||||
	TOP,
 | 
			
		||||
	BOTTOM,
 | 
			
		||||
	CENTER,
 | 
			
		||||
    TOP,
 | 
			
		||||
    BOTTOM,
 | 
			
		||||
    CENTER,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ChildAlignment :: struct {
 | 
			
		||||
	x: LayoutAlignmentX,
 | 
			
		||||
	y: LayoutAlignmentY,
 | 
			
		||||
    x: LayoutAlignmentX,
 | 
			
		||||
    y: LayoutAlignmentY,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LayoutConfig :: struct {
 | 
			
		||||
	sizing:          Sizing,
 | 
			
		||||
	padding:         Padding,
 | 
			
		||||
	childGap:        c.uint16_t,
 | 
			
		||||
	layoutDirection: LayoutDirection,
 | 
			
		||||
	childAlignment:  ChildAlignment,
 | 
			
		||||
    sizing:          Sizing,
 | 
			
		||||
    padding:         Padding,
 | 
			
		||||
    childGap:        c.uint16_t,
 | 
			
		||||
    layoutDirection: LayoutDirection,
 | 
			
		||||
    childAlignment:  ChildAlignment,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClayArray :: struct($type: typeid) {
 | 
			
		||||
	capacity:      c.uint32_t,
 | 
			
		||||
	length:        c.uint32_t,
 | 
			
		||||
	internalArray: [^]type,
 | 
			
		||||
    capacity:      c.uint32_t,
 | 
			
		||||
    length:        c.uint32_t,
 | 
			
		||||
    internalArray: [^]type,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(link_prefix = "Clay_")
 | 
			
		||||
foreign Clay {
 | 
			
		||||
	Clay_MinMemorySize :: proc() -> c.uint32_t ---
 | 
			
		||||
	Clay_CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena ---
 | 
			
		||||
	Clay_SetPointerPosition :: proc(position: Vector2) ---
 | 
			
		||||
	Clay_Initialize :: proc(arena: Arena) ---
 | 
			
		||||
	Clay_UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) ---
 | 
			
		||||
	Clay_BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) ---
 | 
			
		||||
	Clay_EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) ---
 | 
			
		||||
	Clay_PointerOver :: proc(id: c.uint32_t) -> c.bool ---
 | 
			
		||||
	Clay_GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData ---
 | 
			
		||||
	Clay_SetMeasureTextFunction :: proc(measureTextFunction: proc(text: [^]String, config: [^]TextElementConfig) -> Dimensions) ---
 | 
			
		||||
	Clay__OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) ---
 | 
			
		||||
	Clay__OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
 | 
			
		||||
	Clay__OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) ---
 | 
			
		||||
	Clay__OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
 | 
			
		||||
	Clay__OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
 | 
			
		||||
	Clay__OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
 | 
			
		||||
	Clay__OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
 | 
			
		||||
	Clay__OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
 | 
			
		||||
	Clay__CloseElementWithChildren :: proc() ---
 | 
			
		||||
	Clay__CloseScrollElement :: proc() ---
 | 
			
		||||
	Clay__CloseFloatingElement :: proc() ---
 | 
			
		||||
	Clay__layoutConfigs: ClayArray(LayoutConfig)
 | 
			
		||||
	Clay__LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig ---
 | 
			
		||||
	Clay__rectangleElementConfigs: ClayArray(RectangleElementConfig)
 | 
			
		||||
	Clay__RectangleElementConfigArray_Add :: proc(array: ^ClayArray(RectangleElementConfig), config: RectangleElementConfig) -> ^RectangleElementConfig ---
 | 
			
		||||
	Clay__textElementConfigs: ClayArray(TextElementConfig)
 | 
			
		||||
	Clay__TextElementConfigArray_Add :: proc(array: ^ClayArray(TextElementConfig), config: TextElementConfig) -> ^TextElementConfig ---
 | 
			
		||||
	Clay__imageElementConfigs: ClayArray(ImageElementConfig)
 | 
			
		||||
	Clay__ImageElementConfigArray_Add :: proc(array: ^ClayArray(ImageElementConfig), config: ImageElementConfig) -> ^ImageElementConfig ---
 | 
			
		||||
	Clay__floatingElementConfigs: ClayArray(FloatingElementConfig)
 | 
			
		||||
	Clay__FloatingElementConfigArray_Add :: proc(array: ^ClayArray(FloatingElementConfig), config: FloatingElementConfig) -> ^FloatingElementConfig ---
 | 
			
		||||
	Clay__customElementConfigs: ClayArray(CustomElementConfig)
 | 
			
		||||
	Clay__CustomElementConfigArray_Add :: proc(array: ^ClayArray(CustomElementConfig), config: CustomElementConfig) -> ^CustomElementConfig ---
 | 
			
		||||
	Clay__scrollElementConfigs: ClayArray(ScrollElementConfig)
 | 
			
		||||
	Clay__ScrollElementConfigArray_Add :: proc(array: ^ClayArray(ScrollElementConfig), config: ScrollElementConfig) -> ^ScrollElementConfig ---
 | 
			
		||||
	Clay__borderElementConfigs: ClayArray(BorderElementConfig)
 | 
			
		||||
	Clay__BorderElementConfigArray_Add :: proc(array: ^ClayArray(BorderElementConfig), config: BorderElementConfig) -> ^BorderElementConfig ---
 | 
			
		||||
	Clay__HashString :: proc(toHash: String, index: c.uint32_t) -> c.uint32_t ---
 | 
			
		||||
    MinMemorySize :: proc() -> c.uint32_t ---
 | 
			
		||||
    CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena ---
 | 
			
		||||
    SetPointerPosition :: proc(position: Vector2) ---
 | 
			
		||||
    Initialize :: proc(arena: Arena) ---
 | 
			
		||||
    UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) ---
 | 
			
		||||
    BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) ---
 | 
			
		||||
    EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) ---
 | 
			
		||||
    PointerOver :: proc(id: c.uint32_t) -> c.bool ---
 | 
			
		||||
    GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData ---
 | 
			
		||||
    SetMeasureTextFunction :: proc(measureTextFunction: proc(text: ^String, config: ^TextElementConfig) -> Dimensions) ---
 | 
			
		||||
    RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: c.int32_t) -> ^RenderCommand ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _CloseElementWithChildren :: proc() ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _CloseScrollElement :: proc() ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _CloseFloatingElement :: proc() ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _layoutConfigs: ClayArray(LayoutConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _rectangleElementConfigs: ClayArray(RectangleElementConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _RectangleElementConfigArray_Add :: proc(array: ^ClayArray(RectangleElementConfig), config: RectangleElementConfig) -> ^RectangleElementConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _textElementConfigs: ClayArray(TextElementConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _TextElementConfigArray_Add :: proc(array: ^ClayArray(TextElementConfig), config: TextElementConfig) -> ^TextElementConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _imageElementConfigs: ClayArray(ImageElementConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _ImageElementConfigArray_Add :: proc(array: ^ClayArray(ImageElementConfig), config: ImageElementConfig) -> ^ImageElementConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _floatingElementConfigs: ClayArray(FloatingElementConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _FloatingElementConfigArray_Add :: proc(array: ^ClayArray(FloatingElementConfig), config: FloatingElementConfig) -> ^FloatingElementConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _customElementConfigs: ClayArray(CustomElementConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _CustomElementConfigArray_Add :: proc(array: ^ClayArray(CustomElementConfig), config: CustomElementConfig) -> ^CustomElementConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _scrollElementConfigs: ClayArray(ScrollElementConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _ScrollElementConfigArray_Add :: proc(array: ^ClayArray(ScrollElementConfig), config: ScrollElementConfig) -> ^ScrollElementConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _borderElementConfigs: ClayArray(BorderElementConfig)
 | 
			
		||||
    @(private)
 | 
			
		||||
    _BorderElementConfigArray_Add :: proc(array: ^ClayArray(BorderElementConfig), config: BorderElementConfig) -> ^BorderElementConfig ---
 | 
			
		||||
    @(private)
 | 
			
		||||
    _HashString :: proc(toHash: String, index: c.uint32_t) -> c.uint32_t ---
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MinMemorySize :: proc() -> c.uint32_t {
 | 
			
		||||
	return Clay_MinMemorySize()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena {
 | 
			
		||||
	return Clay_CreateArenaWithCapacityAndMemory(capacity, offset)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SetPointerPosition :: proc(position: Vector2) {
 | 
			
		||||
	Clay_SetPointerPosition(position)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Initialize :: proc(arena: Arena) {
 | 
			
		||||
	Clay_Initialize(arena)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) {
 | 
			
		||||
	Clay_UpdateScrollContainers(isPointerActive, scrollDelta, deltaTime)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) {
 | 
			
		||||
	Clay_BeginLayout(screenWidth, screenHeight)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) {
 | 
			
		||||
	return Clay_EndLayout(screenWidth, screenHeight)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PointerOver :: proc(id: c.uint32_t) -> c.bool {
 | 
			
		||||
	return Clay_PointerOver(id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData {
 | 
			
		||||
	return Clay_GetScrollContainerData(id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(deferred_none = Clay__CloseElementWithChildren)
 | 
			
		||||
@(require_results, deferred_none = _CloseElementWithChildren)
 | 
			
		||||
Container :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) -> bool {
 | 
			
		||||
	Clay__OpenContainerElement(id, layoutConfig)
 | 
			
		||||
	return true
 | 
			
		||||
    _OpenContainerElement(id, layoutConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(deferred_none = Clay__CloseElementWithChildren)
 | 
			
		||||
Rectangle :: proc(
 | 
			
		||||
	id: c.uint32_t,
 | 
			
		||||
	layoutConfig: ^LayoutConfig,
 | 
			
		||||
	rectangleConfig: ^RectangleElementConfig,
 | 
			
		||||
) -> bool {
 | 
			
		||||
	Clay__OpenRectangleElement(id, layoutConfig, rectangleConfig)
 | 
			
		||||
	return true
 | 
			
		||||
@(require_results, deferred_none = _CloseElementWithChildren)
 | 
			
		||||
Rectangle :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) -> bool {
 | 
			
		||||
    _OpenRectangleElement(id, layoutConfig, rectangleConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Text :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) -> bool {
 | 
			
		||||
	Clay__OpenTextElement(id, text, textConfig)
 | 
			
		||||
	return true
 | 
			
		||||
    _OpenTextElement(id, text, textConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(deferred_none = Clay__CloseElementWithChildren)
 | 
			
		||||
Image :: proc(
 | 
			
		||||
	id: c.uint32_t,
 | 
			
		||||
	layoutConfig: ^LayoutConfig,
 | 
			
		||||
	imageConfig: ^ImageElementConfig,
 | 
			
		||||
) -> bool {
 | 
			
		||||
	Clay__OpenImageElement(id, layoutConfig, imageConfig)
 | 
			
		||||
	return true
 | 
			
		||||
@(require_results, deferred_none = _CloseElementWithChildren)
 | 
			
		||||
Image :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) -> bool {
 | 
			
		||||
    _OpenImageElement(id, layoutConfig, imageConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(deferred_none = Clay__CloseScrollElement)
 | 
			
		||||
Scroll :: proc(
 | 
			
		||||
	id: c.uint32_t,
 | 
			
		||||
	layoutConfig: ^LayoutConfig,
 | 
			
		||||
	scrollConfig: ^ScrollElementConfig,
 | 
			
		||||
) -> bool {
 | 
			
		||||
	Clay__OpenScrollElement(id, layoutConfig, scrollConfig)
 | 
			
		||||
	return true
 | 
			
		||||
@(require_results, deferred_none = _CloseScrollElement)
 | 
			
		||||
Scroll :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, scrollConfig: ^ScrollElementConfig) -> bool {
 | 
			
		||||
    _OpenScrollElement(id, layoutConfig, scrollConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(deferred_none = Clay__CloseFloatingElement)
 | 
			
		||||
Floating :: proc(
 | 
			
		||||
	id: c.uint32_t,
 | 
			
		||||
	layoutConfig: ^LayoutConfig,
 | 
			
		||||
	floatingConfig: ^FloatingElementConfig,
 | 
			
		||||
) -> bool {
 | 
			
		||||
	Clay__OpenFloatingElement(id, layoutConfig, floatingConfig)
 | 
			
		||||
	return true
 | 
			
		||||
@(require_results, deferred_none = _CloseFloatingElement)
 | 
			
		||||
Floating :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, floatingConfig: ^FloatingElementConfig) -> bool {
 | 
			
		||||
    _OpenFloatingElement(id, layoutConfig, floatingConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(deferred_none = Clay__CloseElementWithChildren)
 | 
			
		||||
Border :: proc(
 | 
			
		||||
	id: c.uint32_t,
 | 
			
		||||
	layoutConfig: ^LayoutConfig,
 | 
			
		||||
	borderConfig: ^BorderElementConfig,
 | 
			
		||||
) -> bool {
 | 
			
		||||
	Clay__OpenBorderElement(id, layoutConfig, borderConfig)
 | 
			
		||||
	return true
 | 
			
		||||
@(require_results, deferred_none = _CloseElementWithChildren)
 | 
			
		||||
Border :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, borderConfig: ^BorderElementConfig) -> bool {
 | 
			
		||||
    _OpenBorderElement(id, layoutConfig, borderConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@(deferred_none = Clay__CloseElementWithChildren)
 | 
			
		||||
Custom :: proc(
 | 
			
		||||
	id: c.uint32_t,
 | 
			
		||||
	layoutConfig: ^LayoutConfig,
 | 
			
		||||
	customConfig: ^CustomElementConfig,
 | 
			
		||||
) -> bool {
 | 
			
		||||
	Clay__OpenCustomElement(id, layoutConfig, customConfig)
 | 
			
		||||
	return true
 | 
			
		||||
@(require_results, deferred_none = _CloseElementWithChildren)
 | 
			
		||||
Custom :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, customConfig: ^CustomElementConfig) -> bool {
 | 
			
		||||
    _OpenCustomElement(id, layoutConfig, customConfig)
 | 
			
		||||
    return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Layout :: proc(config: LayoutConfig) -> ^LayoutConfig {
 | 
			
		||||
	return Clay__LayoutConfigArray_Add(&Clay__layoutConfigs, config)
 | 
			
		||||
    return _LayoutConfigArray_Add(&_layoutConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RectangleConfig :: proc(config: RectangleElementConfig) -> ^RectangleElementConfig {
 | 
			
		||||
	return Clay__RectangleElementConfigArray_Add(&Clay__rectangleElementConfigs, config)
 | 
			
		||||
    return _RectangleElementConfigArray_Add(&_rectangleElementConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TextConfig :: proc(config: TextElementConfig) -> ^TextElementConfig {
 | 
			
		||||
	return Clay__TextElementConfigArray_Add(&Clay__textElementConfigs, config)
 | 
			
		||||
    return _TextElementConfigArray_Add(&_textElementConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ImageConfig :: proc(config: ImageElementConfig) -> ^ImageElementConfig {
 | 
			
		||||
	return Clay__ImageElementConfigArray_Add(&Clay__imageElementConfigs, config)
 | 
			
		||||
    return _ImageElementConfigArray_Add(&_imageElementConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FloatingConfig :: proc(config: FloatingElementConfig) -> ^FloatingElementConfig {
 | 
			
		||||
	return Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, config)
 | 
			
		||||
    return _FloatingElementConfigArray_Add(&_floatingElementConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Custom_elementConfig :: proc(config: CustomElementConfig) -> ^CustomElementConfig {
 | 
			
		||||
	return Clay__CustomElementConfigArray_Add(&Clay__customElementConfigs, config)
 | 
			
		||||
    return _CustomElementConfigArray_Add(&_customElementConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ScrollConfig :: proc(config: ScrollElementConfig) -> ^ScrollElementConfig {
 | 
			
		||||
	return Clay__ScrollElementConfigArray_Add(&Clay__scrollElementConfigs, config)
 | 
			
		||||
    return _ScrollElementConfigArray_Add(&_scrollElementConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BorderConfig :: proc(config: BorderElementConfig) -> ^BorderElementConfig {
 | 
			
		||||
	return Clay__BorderElementConfigArray_Add(&Clay__borderElementConfigs, config)
 | 
			
		||||
    return _BorderElementConfigArray_Add(&_borderElementConfigs, config)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BorderConfigOutside :: proc(outsideBorders: BorderData) -> ^BorderElementConfig {
 | 
			
		||||
	return Clay__BorderElementConfigArray_Add(
 | 
			
		||||
		&Clay__borderElementConfigs,
 | 
			
		||||
		(BorderElementConfig) {
 | 
			
		||||
			left = outsideBorders,
 | 
			
		||||
			right = outsideBorders,
 | 
			
		||||
			top = outsideBorders,
 | 
			
		||||
			bottom = outsideBorders,
 | 
			
		||||
		},
 | 
			
		||||
	)
 | 
			
		||||
    return _BorderElementConfigArray_Add(
 | 
			
		||||
        &_borderElementConfigs,
 | 
			
		||||
        (BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders},
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BorderConfig_outside_radius :: proc(width, color, radius)  Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { width, color }, .right = { width, color }, .top = { width, color }, .bottom = { width, color }, .cornerRadius = { radius, radius, radius, radius } })) -> CLAY_BORDER_CONFIG_OUTSIDE_RADIUS
 | 
			
		||||
BorderConfigOutsideRadius :: proc(outsideBorders: BorderData, radius: f32) -> ^BorderElementConfig {
 | 
			
		||||
    return _BorderElementConfigArray_Add(
 | 
			
		||||
        &_borderElementConfigs,
 | 
			
		||||
        (BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders, cornerRadius = {radius, radius, radius, radius}},
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BorderConfig_all :: proc(...)  Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { __VA_ARGS__ }, .right = { __VA_ARGS__ }, .top = { __VA_ARGS__ }, .bottom = { __VA_ARGS__ }, .betweenChildren = { __VA_ARGS__ } })) -> CLAY_BORDER_CONFIG_ALL
 | 
			
		||||
BorderConfigAll :: proc(allBorders: BorderData) -> ^BorderElementConfig {
 | 
			
		||||
    return _BorderElementConfigArray_Add(
 | 
			
		||||
        &_borderElementConfigs,
 | 
			
		||||
        (BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, betweenChildren = allBorders},
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BorderConfig_all_radius :: proc(width, color, radius)  Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { __VA_ARGS__ }, .right = { __VA_ARGS__ }, .top = { __VA_ARGS__ }, .bottom = { __VA_ARGS__ }, .betweenChildren = { __VA_ARGS__ }, .cornerRadius = { radius, radius, radius, radius }})) -> CLAY_BORDER_CONFIG_ALL_RADIUS
 | 
			
		||||
BorderConfigAllRadius :: proc(allBorders: BorderData, radius: f32) -> ^BorderElementConfig {
 | 
			
		||||
    return _BorderElementConfigArray_Add(
 | 
			
		||||
        &_borderElementConfigs,
 | 
			
		||||
        (BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, cornerRadius = {radius, radius, radius, radius}},
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Corner_radius :: proc(radius) (Clay_CornerRadius) { radius, radius, radius, radius }) -> CLAY_CORNER_RADIUS
 | 
			
		||||
SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
 | 
			
		||||
    return SizingAxis{type = SizingType.FIT, constraints = {sizeMinMax = sizeMinMax}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sizing_fit :: proc(...) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_FIT, .sizeMinMax = (Clay_SizingMinMax) {__VA_ARGS__} }) -> CLAY_SIZING_FIT
 | 
			
		||||
SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
 | 
			
		||||
    return SizingAxis{type = SizingType.GROW, constraints = {sizeMinMax = sizeMinMax}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sizing_grow :: proc(...) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_GROW, .sizeMinMax = (Clay_SizingMinMax) {__VA_ARGS__} }) -> CLAY_SIZING_GROW
 | 
			
		||||
SizingFixed :: proc(size: c.float) -> SizingAxis {
 | 
			
		||||
    return SizingAxis{type = SizingType.FIT, constraints = {sizeMinMax = {size, size}}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sizing_fixed :: proc(fixedSize) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_GROW, .sizeMinMax = { fixedSize, fixedSize } }) -> CLAY_SIZING_FIXED
 | 
			
		||||
SizingPercent :: proc(sizePercent: c.float) -> SizingAxis {
 | 
			
		||||
    return SizingAxis{type = SizingType.PERCENT, constraints = {sizePercent = sizePercent}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sizing_percent :: proc(percentOfParent) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_PERCENT, .sizePercent = percentOfParent }) -> CLAY_SIZING_PERCENT
 | 
			
		||||
 | 
			
		||||
ClayString :: proc(label: string) -> String {
 | 
			
		||||
	return String{chars = raw_data(label), length = cast(c.int)len(label)}
 | 
			
		||||
MakeString :: proc(label: string) -> String {
 | 
			
		||||
    return String{chars = raw_data(label), length = cast(c.int)len(label)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ID :: proc(label: string) -> c.uint32_t {
 | 
			
		||||
	return Clay__HashString(ClayString(label), 0)
 | 
			
		||||
    return _HashString(MakeString(label), 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IDI :: proc(label: string, index: u32) -> c.uint32_t {
 | 
			
		||||
	return Clay__HashString(ClayString(label), index)
 | 
			
		||||
    return _HashString(MakeString(label), index)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// _string_length :: proc(s) ((sizeof(s) / sizeof(s[0])) - sizeof(s[0]))) -> CLAY__STRING_LENGTH
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										224
									
								
								bindings/odin/clay_renderer_raylib.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								bindings/odin/clay_renderer_raylib.odin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,224 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import clay "clay-odin"
 | 
			
		||||
import "core:math"
 | 
			
		||||
import "vendor:raylib"
 | 
			
		||||
 | 
			
		||||
RaylibFont :: struct {
 | 
			
		||||
    fontId: u32,
 | 
			
		||||
    font:   raylib.Font,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
clayColorToRaylibColor :: proc(color: clay.Color) -> raylib.Color {
 | 
			
		||||
    return raylib.Color{cast(u8)color.r, cast(u8)color.g, cast(u8)color.b, cast(u8)color.a}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
raylibFonts := [10]RaylibFont{}
 | 
			
		||||
 | 
			
		||||
measureText :: proc "c" (text: ^clay.String, config: ^clay.TextElementConfig) -> clay.Dimensions {
 | 
			
		||||
    // Measure string size for Font
 | 
			
		||||
    textSize: clay.Dimensions = {0, 0}
 | 
			
		||||
 | 
			
		||||
    maxTextWidth: f32 = 0
 | 
			
		||||
    lineTextWidth: f32 = 0
 | 
			
		||||
 | 
			
		||||
    textHeight: f32 = cast(f32)config.fontSize
 | 
			
		||||
    fontToUse: raylib.Font = raylibFonts[config.fontId].font
 | 
			
		||||
 | 
			
		||||
    for i := 0; i < cast(int)text.length; i += 1 {
 | 
			
		||||
        if (text.chars[i] == '\n') {
 | 
			
		||||
            maxTextWidth = math.max(maxTextWidth, lineTextWidth)
 | 
			
		||||
            lineTextWidth = 0
 | 
			
		||||
            continue
 | 
			
		||||
        }
 | 
			
		||||
        index: i32 = cast(i32)text.chars[i] - 32
 | 
			
		||||
        if (fontToUse.glyphs[index].advanceX != 0) {
 | 
			
		||||
            lineTextWidth += cast(f32)fontToUse.glyphs[index].advanceX
 | 
			
		||||
        } else {
 | 
			
		||||
            lineTextWidth += (fontToUse.recs[index].width + cast(f32)fontToUse.glyphs[index].offsetX)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    maxTextWidth = math.max(maxTextWidth, lineTextWidth)
 | 
			
		||||
 | 
			
		||||
    textSize.width = maxTextWidth / 2
 | 
			
		||||
    textSize.height = textHeight
 | 
			
		||||
 | 
			
		||||
    return textSize
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
clayRaylibRender :: proc(renderCommands: ^clay.ClayArray(clay.RenderCommand)) {
 | 
			
		||||
    for i := 0; i < cast(int)renderCommands.length; i += 1 {
 | 
			
		||||
        renderCommand: ^clay.RenderCommand = clay.RenderCommandArray_Get(renderCommands, cast(i32)i)
 | 
			
		||||
        boundingBox: clay.BoundingBox = renderCommand.boundingBox
 | 
			
		||||
        switch (renderCommand.commandType) 
 | 
			
		||||
        {
 | 
			
		||||
        case clay.RenderCommandType.None:
 | 
			
		||||
            {
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        case clay.RenderCommandType.Text:
 | 
			
		||||
            {
 | 
			
		||||
                // Raylib uses standard C strings so isn't compatible with cheap slices, we need to clone the string to append null terminator
 | 
			
		||||
                text: clay.String = renderCommand.text
 | 
			
		||||
                cloned: []u8 = make([]u8, text.length + 1)
 | 
			
		||||
                copy(cloned[0:text.length], text.chars[0:text.length])
 | 
			
		||||
                cloned[text.length] = 0
 | 
			
		||||
                fontToUse: raylib.Font = raylibFonts[renderCommand.config.textElementConfig.fontId].font
 | 
			
		||||
                raylib.DrawTextEx(
 | 
			
		||||
                    fontToUse,
 | 
			
		||||
                    cstring(raw_data(cloned)),
 | 
			
		||||
                    raylib.Vector2{boundingBox.x, boundingBox.y},
 | 
			
		||||
                    cast(f32)renderCommand.config.textElementConfig.fontSize,
 | 
			
		||||
                    cast(f32)renderCommand.config.textElementConfig.letterSpacing,
 | 
			
		||||
                    clayColorToRaylibColor(renderCommand.config.textElementConfig.textColor),
 | 
			
		||||
                )
 | 
			
		||||
                delete(cloned)
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        case clay.RenderCommandType.Image:
 | 
			
		||||
            {
 | 
			
		||||
                imageTexture: ^raylib.Texture2D = cast(^raylib.Texture2D)renderCommand.config.imageElementConfig.imageData
 | 
			
		||||
                raylib.DrawTextureEx(imageTexture^, raylib.Vector2{boundingBox.x, boundingBox.y}, 0, boundingBox.width / cast(f32)imageTexture.width, raylib.WHITE)
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        case clay.RenderCommandType.ScissorStart:
 | 
			
		||||
            {
 | 
			
		||||
                raylib.BeginScissorMode(
 | 
			
		||||
                    cast(i32)math.round(boundingBox.x),
 | 
			
		||||
                    cast(i32)math.round(boundingBox.y),
 | 
			
		||||
                    cast(i32)math.round(boundingBox.width),
 | 
			
		||||
                    cast(i32)math.round(boundingBox.height),
 | 
			
		||||
                )
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        case clay.RenderCommandType.ScissorEnd:
 | 
			
		||||
            {
 | 
			
		||||
                raylib.EndScissorMode()
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        case clay.RenderCommandType.Rectangle:
 | 
			
		||||
            {
 | 
			
		||||
                config: ^clay.RectangleElementConfig = renderCommand.config.rectangleElementConfig
 | 
			
		||||
                if (config.cornerRadius.topLeft > 0) {
 | 
			
		||||
                    radius: f32 = (config.cornerRadius.topLeft * 2) / (boundingBox.width > boundingBox.height ? boundingBox.height : boundingBox.width)
 | 
			
		||||
                    raylib.DrawRectangleRounded(
 | 
			
		||||
                        raylib.Rectangle{boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height},
 | 
			
		||||
                        radius,
 | 
			
		||||
                        8,
 | 
			
		||||
                        clayColorToRaylibColor(config.color),
 | 
			
		||||
                    )
 | 
			
		||||
                } else {
 | 
			
		||||
                    raylib.DrawRectangle(
 | 
			
		||||
                        cast(i32)boundingBox.x,
 | 
			
		||||
                        cast(i32)boundingBox.y,
 | 
			
		||||
                        cast(i32)boundingBox.width,
 | 
			
		||||
                        cast(i32)boundingBox.height,
 | 
			
		||||
                        clayColorToRaylibColor(config.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        case clay.RenderCommandType.Border:
 | 
			
		||||
            {
 | 
			
		||||
                config: ^clay.BorderElementConfig = renderCommand.config.borderElementConfig
 | 
			
		||||
                // Left border
 | 
			
		||||
                if (config.left.width > 0) {
 | 
			
		||||
                    raylib.DrawRectangle(
 | 
			
		||||
                        cast(i32)math.round(boundingBox.x),
 | 
			
		||||
                        cast(i32)math.round(boundingBox.y + config.cornerRadius.topLeft),
 | 
			
		||||
                        cast(i32)config.left.width,
 | 
			
		||||
                        cast(i32)math.round(boundingBox.height - config.cornerRadius.topLeft - config.cornerRadius.bottomLeft),
 | 
			
		||||
                        clayColorToRaylibColor(config.left.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                // Right border
 | 
			
		||||
                if (config.right.width > 0) {
 | 
			
		||||
                    raylib.DrawRectangle(
 | 
			
		||||
                        cast(i32)math.round(boundingBox.x + boundingBox.width - cast(f32)config.right.width),
 | 
			
		||||
                        cast(i32)math.round(boundingBox.y + config.cornerRadius.topRight),
 | 
			
		||||
                        cast(i32)config.right.width,
 | 
			
		||||
                        cast(i32)math.round(boundingBox.height - config.cornerRadius.topRight - config.cornerRadius.bottomRight),
 | 
			
		||||
                        clayColorToRaylibColor(config.right.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                // Top border
 | 
			
		||||
                if (config.top.width > 0) {
 | 
			
		||||
                    raylib.DrawRectangle(
 | 
			
		||||
                        cast(i32)math.round(boundingBox.x + config.cornerRadius.topLeft),
 | 
			
		||||
                        cast(i32)math.round(boundingBox.y),
 | 
			
		||||
                        cast(i32)math.round(boundingBox.width - config.cornerRadius.topLeft - config.cornerRadius.topRight),
 | 
			
		||||
                        cast(i32)config.top.width,
 | 
			
		||||
                        clayColorToRaylibColor(config.top.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                // Bottom border
 | 
			
		||||
                if (config.bottom.width > 0) {
 | 
			
		||||
                    raylib.DrawRectangle(
 | 
			
		||||
                        cast(i32)math.round(boundingBox.x + config.cornerRadius.bottomLeft),
 | 
			
		||||
                        cast(i32)math.round(boundingBox.y + boundingBox.height - cast(f32)config.bottom.width),
 | 
			
		||||
                        cast(i32)math.round(boundingBox.width - config.cornerRadius.bottomLeft - config.cornerRadius.bottomRight),
 | 
			
		||||
                        cast(i32)config.bottom.width,
 | 
			
		||||
                        clayColorToRaylibColor(config.bottom.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                if (config.cornerRadius.topLeft > 0) {
 | 
			
		||||
                    raylib.DrawRing(
 | 
			
		||||
                        raylib.Vector2{math.round(boundingBox.x + config.cornerRadius.topLeft), math.round(boundingBox.y + config.cornerRadius.topLeft)},
 | 
			
		||||
                        math.round(config.cornerRadius.topLeft - cast(f32)config.top.width),
 | 
			
		||||
                        config.cornerRadius.topLeft,
 | 
			
		||||
                        180,
 | 
			
		||||
                        270,
 | 
			
		||||
                        10,
 | 
			
		||||
                        clayColorToRaylibColor(config.top.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                if (config.cornerRadius.topRight > 0) {
 | 
			
		||||
                    raylib.DrawRing(
 | 
			
		||||
                        raylib.Vector2{math.round(boundingBox.x + boundingBox.width - config.cornerRadius.topRight), math.round(boundingBox.y + config.cornerRadius.topRight)},
 | 
			
		||||
                        math.round(config.cornerRadius.topRight - cast(f32)config.top.width),
 | 
			
		||||
                        config.cornerRadius.topRight,
 | 
			
		||||
                        270,
 | 
			
		||||
                        360,
 | 
			
		||||
                        10,
 | 
			
		||||
                        clayColorToRaylibColor(config.top.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                if (config.cornerRadius.bottomLeft > 0) {
 | 
			
		||||
                    raylib.DrawRing(
 | 
			
		||||
                        raylib.Vector2 {
 | 
			
		||||
                            math.round(boundingBox.x + config.cornerRadius.bottomLeft),
 | 
			
		||||
                            math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomLeft),
 | 
			
		||||
                        },
 | 
			
		||||
                        math.round(config.cornerRadius.bottomLeft - cast(f32)config.top.width),
 | 
			
		||||
                        config.cornerRadius.bottomLeft,
 | 
			
		||||
                        90,
 | 
			
		||||
                        180,
 | 
			
		||||
                        10,
 | 
			
		||||
                        clayColorToRaylibColor(config.bottom.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                if (config.cornerRadius.bottomRight > 0) {
 | 
			
		||||
                    raylib.DrawRing(
 | 
			
		||||
                        raylib.Vector2 {
 | 
			
		||||
                            math.round(boundingBox.x + boundingBox.width - config.cornerRadius.bottomRight),
 | 
			
		||||
                            math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomRight),
 | 
			
		||||
                        },
 | 
			
		||||
                        math.round(config.cornerRadius.bottomRight - cast(f32)config.bottom.width),
 | 
			
		||||
                        config.cornerRadius.bottomRight,
 | 
			
		||||
                        0.1,
 | 
			
		||||
                        90,
 | 
			
		||||
                        10,
 | 
			
		||||
                        clayColorToRaylibColor(config.bottom.color),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        case clay.RenderCommandType.Custom:
 | 
			
		||||
            {
 | 
			
		||||
                // Implement custom element rendering here
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								bindings/odin/example.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								bindings/odin/example.odin
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import clay "clay-odin"
 | 
			
		||||
import "core:c"
 | 
			
		||||
import "core:fmt"
 | 
			
		||||
import "vendor:raylib"
 | 
			
		||||
 | 
			
		||||
createLayout :: proc() -> clay.ClayArray(clay.RenderCommand) {
 | 
			
		||||
    clay.BeginLayout(1024, 768)
 | 
			
		||||
    layoutConfig: clay.LayoutConfig = clay.LayoutConfig {
 | 
			
		||||
        sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}},
 | 
			
		||||
        padding = {16, 16},
 | 
			
		||||
    }
 | 
			
		||||
    rectangleConfig: clay.RectangleElementConfig = clay.RectangleElementConfig {
 | 
			
		||||
        cornerRadius = {topLeft = 5},
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if clay.Rectangle(
 | 
			
		||||
        clay.ID("Outer Container"),
 | 
			
		||||
        clay.Layout({sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}}, padding = {16, 16}}),
 | 
			
		||||
        clay.RectangleConfig({cornerRadius = {topLeft = 5}}),
 | 
			
		||||
    ) {
 | 
			
		||||
        if clay.Rectangle(clay.ID("Inner Container"), &layoutConfig, &rectangleConfig) {
 | 
			
		||||
            if clay.Rectangle(clay.ID("percentContainer"), clay.Layout({sizing = {width = clay.SizingPercent(0.5)}}), clay.RectangleConfig({})) {}
 | 
			
		||||
            if clay.Rectangle(clay.ID("growContainer"), clay.Layout({sizing = {width = clay.SizingGrow({max = 200})}}), clay.RectangleConfig({})) {}
 | 
			
		||||
            clay.Text(clay.ID("textfield"), clay.MakeString("Texti"), clay.TextConfig({fontId = 0, fontSize = 24, textColor = {255, 255, 255, 255}}))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return clay.EndLayout(1024, 768)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main :: proc() {
 | 
			
		||||
    minMemorySize: c.uint32_t = clay.MinMemorySize()
 | 
			
		||||
    memory := make([^]u8, minMemorySize)
 | 
			
		||||
    arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
 | 
			
		||||
    clay.SetMeasureTextFunction(measureText)
 | 
			
		||||
    clay.Initialize(arena)
 | 
			
		||||
 | 
			
		||||
    raylib.InitWindow(1024, 768, "Raylib Odin Example")
 | 
			
		||||
 | 
			
		||||
    raylibFonts[0] = RaylibFont {
 | 
			
		||||
        font   = raylib.LoadFontEx("resources/Roboto-Regular.ttf", 32, nil, 0),
 | 
			
		||||
        fontId = 0,
 | 
			
		||||
    }
 | 
			
		||||
    raylib.SetTextureFilter(raylibFonts[0].font.texture, raylib.TextureFilter.TRILINEAR)
 | 
			
		||||
 | 
			
		||||
    for !raylib.WindowShouldClose() {
 | 
			
		||||
        renderCommands: clay.ClayArray(clay.RenderCommand) = createLayout()
 | 
			
		||||
        raylib.BeginDrawing()
 | 
			
		||||
        clayRaylibRender(&renderCommands)
 | 
			
		||||
        raylib.EndDrawing()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,45 +0,0 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import clay "clay-odin"
 | 
			
		||||
import "core:c"
 | 
			
		||||
import "core:fmt"
 | 
			
		||||
 | 
			
		||||
measureText :: proc(text: [^]clay.String, config: [^]clay.TextElementConfig) -> clay.Dimensions {
 | 
			
		||||
	return clay.Dimensions{20, 20}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main :: proc() {
 | 
			
		||||
	minMemorySize: c.uint32_t = clay.MinMemorySize()
 | 
			
		||||
	memory := make([^]u8, minMemorySize)
 | 
			
		||||
	arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
 | 
			
		||||
	clay.Initialize(arena)
 | 
			
		||||
	clay.BeginLayout(1024, 768)
 | 
			
		||||
	layoutConfig: clay.LayoutConfig = clay.LayoutConfig {
 | 
			
		||||
		sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}},
 | 
			
		||||
		padding = {16, 16},
 | 
			
		||||
	}
 | 
			
		||||
	rectangleConfig: clay.RectangleElementConfig = clay.RectangleElementConfig {
 | 
			
		||||
		cornerRadius = {topLeft = 5},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if clay.Rectangle(
 | 
			
		||||
		clay.ID("Outer Container"),
 | 
			
		||||
		clay.Layout(
 | 
			
		||||
			{
 | 
			
		||||
				sizing = {
 | 
			
		||||
					width = {type = clay.SizingType.GROW},
 | 
			
		||||
					height = {type = clay.SizingType.GROW},
 | 
			
		||||
				},
 | 
			
		||||
				padding = {16, 16},
 | 
			
		||||
			},
 | 
			
		||||
		),
 | 
			
		||||
		clay.RectangleConfig({cornerRadius = {topLeft = 5}}),
 | 
			
		||||
	) {
 | 
			
		||||
		if clay.Rectangle(clay.ID("Inner Container"), &layoutConfig, &rectangleConfig) {
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	renderCommands: clay.ClayArray(clay.RenderCommand) = clay.EndLayout(1024, 768)
 | 
			
		||||
	x: int = 5
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								bindings/odin/odinfmt.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								bindings/odin/odinfmt.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
{
 | 
			
		||||
	"$schema": "https://raw.githubusercontent.com/DanielGavin/ols/master/misc/odinfmt.schema.json",
 | 
			
		||||
	"character_width": 180,
 | 
			
		||||
	"sort_imports": true,
 | 
			
		||||
	"tabs": false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								bindings/odin/resources/Roboto-Regular.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								bindings/odin/resources/Roboto-Regular.ttf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in a new issue