diff --git a/bindings/odin/clay-odin/clay.odin b/bindings/odin/clay-odin/clay.odin index e913037..8195a18 100644 --- a/bindings/odin/clay-odin/clay.odin +++ b/bindings/odin/clay-odin/clay.odin @@ -1,436 +1,459 @@ package clay import "core:c" -import "core:strings" when ODIN_OS == .Windows { - foreign import Clay "windows/clay.lib" + foreign import Clay "windows/clay.lib" } else when ODIN_OS == .Linux { - foreign import Clay "linux/clay.a" + foreign import Clay "linux/clay.a" } else when ODIN_OS == .Darwin { - when ODIN_ARCH == .arm64 { - foreign import Clay "macos-arm64/clay.a" - } else { - foreign import Clay "macos/clay.a" - } + when ODIN_ARCH == .arm64 { + foreign import Clay "macos-arm64/clay.a" + } else { + foreign import Clay "macos/clay.a" + } } else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 { - foreign import Clay "wasm/clay.o" + foreign import Clay "wasm/clay.o" } String :: struct { - length: c.int32_t, - chars: [^]c.char, + length: c.int32_t, + chars: [^]c.char, } StringSlice :: struct { - length: c.int32_t, - chars: [^]c.char, - baseChars: [^]c.char, + length: c.int32_t, + chars: [^]c.char, + baseChars: [^]c.char, } Vector2 :: [2]c.float Dimensions :: struct { - width: c.float, - height: c.float, + width: c.float, + height: c.float, } Arena :: struct { - nextAllocation: uintptr, - capacity: uintptr, - memory: [^]c.char, + nextAllocation: uintptr, + capacity: uintptr, + 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 :: [4]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: u32, - color: Color, + width: u32, + color: Color, } ElementId :: struct { - id: u32, - offset: u32, - baseId: u32, - stringId: String, + id: u32, + offset: u32, + baseId: u32, + stringId: String, } when ODIN_OS == .Windows { - EnumBackingType :: u32 + EnumBackingType :: u32 } else { - EnumBackingType :: u8 + EnumBackingType :: u8 } RenderCommandType :: enum EnumBackingType { - None, - Rectangle, - Border, - Text, - Image, - ScissorStart, - ScissorEnd, - Custom, + None, + Rectangle, + Border, + Text, + Image, + ScissorStart, + ScissorEnd, + Custom, } RectangleElementConfig :: struct { - color: Color, + color: Color, } TextWrapMode :: enum EnumBackingType { - Words, - Newlines, - None, + Words, + Newlines, + None, } TextAlignment :: enum EnumBackingType { - Left, - Center, - Right, + Left, + Center, + Right, } TextElementConfig :: struct { - textColor: Color, - fontId: u16, - fontSize: u16, - letterSpacing: u16, - lineHeight: u16, - wrapMode: TextWrapMode, - textAlignment: TextAlignment, - hashStringContents: bool, + textColor: Color, + fontId: u16, + fontSize: u16, + letterSpacing: u16, + lineHeight: u16, + wrapMode: TextWrapMode, + textAlignment: TextAlignment, + hashStringContents: bool, } ImageElementConfig :: struct { - imageData: rawptr, - sourceDimensions: Dimensions, + imageData: rawptr, + sourceDimensions: Dimensions, } CustomElementConfig :: struct { - customData: rawptr, + customData: rawptr, } BorderWidth :: struct { - left: u16, - right: u16, - top: u16, - bottom: u16, - betweenChildren: u16, + left: u16, + right: u16, + top: u16, + bottom: u16, + betweenChildren: u16, } BorderElementConfig :: struct { - color: Color, - width: BorderWidth, + color: Color, + width: BorderWidth, } ScrollElementConfig :: struct { - horizontal: bool, - vertical: bool, + horizontal: bool, + vertical: bool, } FloatingAttachPointType :: enum EnumBackingType { - LeftTop, - LeftCenter, - LeftBottom, - CenterTop, - CenterCenter, - CenterBottom, - RightTop, - RightCenter, - RightBottom, + LeftTop, + LeftCenter, + LeftBottom, + CenterTop, + CenterCenter, + CenterBottom, + RightTop, + RightCenter, + RightBottom, } FloatingAttachPoints :: struct { - element: FloatingAttachPointType, - parent: FloatingAttachPointType, + element: FloatingAttachPointType, + parent: FloatingAttachPointType, } PointerCaptureMode :: enum EnumBackingType { - Capture, - Passthrough, + Capture, + Passthrough, } FloatingAttachToElement :: enum EnumBackingType { - None, - Parent, - ElementWithId, - Root, + None, + Parent, + ElementWithId, + Root, } FloatingElementConfig :: struct { - offset: Vector2, - expand: Dimensions, - parentId: u32, - zIndex: i32, - attachment: FloatingAttachPoints, - pointerCaptureMode: PointerCaptureMode, - attachTo: FloatingAttachToElement + offset: Vector2, + expand: Dimensions, + parentId: u32, + zIndex: i32, + attachment: FloatingAttachPoints, + pointerCaptureMode: PointerCaptureMode, + attachTo: FloatingAttachToElement, } TextRenderData :: struct { - stringContents: StringSlice, - textColor: Color, - fontId: u16, - fontSize: u16, - letterSpacing: u16, - lineHeight: u16, + stringContents: StringSlice, + textColor: Color, + fontId: u16, + fontSize: u16, + letterSpacing: u16, + lineHeight: u16, } RectangleRenderData :: struct { - backgroundColor: Color, - cornerRadius: CornerRadius, + backgroundColor: Color, + cornerRadius: CornerRadius, } ImageRenderData :: struct { - backgroundColor: Color, - cornerRadius: CornerRadius, - sourceDimensions: Dimensions, - imageData: rawptr, + backgroundColor: Color, + cornerRadius: CornerRadius, + sourceDimensions: Dimensions, + imageData: rawptr, } CustomRenderData :: struct { - backgroundColor: Color, - cornerRadius: CornerRadius, - customData: rawptr, + backgroundColor: Color, + cornerRadius: CornerRadius, + customData: rawptr, } BorderRenderData :: struct { - color: Color, - cornerRadius: CornerRadius, - width: BorderWidth, + color: Color, + cornerRadius: CornerRadius, + width: BorderWidth, } RenderCommandData :: struct #raw_union { - rectangle: RectangleRenderData, - text: TextRenderData, - image: ImageRenderData, - custom: CustomRenderData, - border: BorderRenderData, + rectangle: RectangleRenderData, + text: TextRenderData, + image: ImageRenderData, + custom: CustomRenderData, + border: BorderRenderData, } RenderCommand :: struct { - boundingBox: BoundingBox, - renderData: RenderCommandData, - userData: rawptr, - id: u32, - zIndex: i16, - commandType: RenderCommandType, + boundingBox: BoundingBox, + renderData: RenderCommandData, + userData: rawptr, + id: u32, + zIndex: i16, + 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: 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: bool, +} + +ElementData :: struct { + boundingBox: BoundingBox, + found: bool, +} + +PointerDataInteractionState :: enum EnumBackingType { + PressedThisFrame, + Pressed, + ReleasedThisFrame, + Released, +} + +PointerData :: struct { + position: Vector2, + state: PointerDataInteractionState, } SizingType :: enum EnumBackingType { - Fit, - Grow, - Percent, - Fixed, + Fit, + Grow, + Percent, + Fixed, } SizingConstraintsMinMax :: struct { - min: c.float, - max: c.float, + min: c.float, + max: c.float, } SizingConstraints :: struct #raw_union { - sizeMinMax: SizingConstraintsMinMax, - sizePercent: c.float, + 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 - constraints: SizingConstraints, - 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 { - left: u16, - right: u16, - top: u16, - bottom: u16, + left: u16, + right: u16, + top: u16, + bottom: u16, } LayoutDirection :: enum EnumBackingType { - LeftToRight, - TopToBottom, + LeftToRight, + TopToBottom, } LayoutAlignmentX :: enum EnumBackingType { - Left, - Right, - Center, + Left, + Right, + Center, } LayoutAlignmentY :: enum EnumBackingType { - Top, - Bottom, - Center, + Top, + Bottom, + Center, } ChildAlignment :: struct { - x: LayoutAlignmentX, - y: LayoutAlignmentY, + x: LayoutAlignmentX, + y: LayoutAlignmentY, } LayoutConfig :: struct { - sizing: Sizing, - padding: Padding, - childGap: u16, - childAlignment: ChildAlignment, - layoutDirection: LayoutDirection, + sizing: Sizing, + padding: Padding, + childGap: u16, + childAlignment: ChildAlignment, + layoutDirection: LayoutDirection, } ClayArray :: struct($type: typeid) { - capacity: i32, - length: i32, - internalArray: [^]type, + capacity: i32, + length: i32, + internalArray: [^]type, } ElementDeclaration :: struct { - id: ElementId, - layout: LayoutConfig, - backgroundColor: Color, - cornerRadius: CornerRadius, - image: ImageElementConfig, - floating: FloatingElementConfig, - custom: CustomElementConfig, - scroll: ScrollElementConfig, - border: BorderElementConfig, - userData: rawptr + id: ElementId, + layout: LayoutConfig, + backgroundColor: Color, + cornerRadius: CornerRadius, + image: ImageElementConfig, + floating: FloatingElementConfig, + custom: CustomElementConfig, + scroll: ScrollElementConfig, + border: BorderElementConfig, + userData: rawptr, } ErrorType :: enum EnumBackingType { - TextMeasurementFunctionNotProvided, - ArenaCapacityExceeded, - ElementsCapacityExceeded, - TextMeasurementCapacityExceeded, - DuplicateId, - FloatingContainerParentNotFound, - PercentageOver1, - InternalError, + TextMeasurementFunctionNotProvided, + ArenaCapacityExceeded, + ElementsCapacityExceeded, + TextMeasurementCapacityExceeded, + DuplicateId, + FloatingContainerParentNotFound, + PercentageOver1, + InternalError, } ErrorData :: struct { - errorType: ErrorType, - errorText: String, - userData: rawptr + errorType: ErrorType, + errorText: String, + userData: rawptr, } ErrorHandler :: struct { - handler: proc "c" (errorData: ErrorData), - userData: rawptr + handler: proc "c" (errorData: ErrorData), + userData: rawptr, } Context :: struct {} // opaque structure, only use as a pointer @(link_prefix = "Clay_", default_calling_convention = "c") foreign Clay { - MinMemorySize :: proc() -> u32 --- - CreateArenaWithCapacityAndMemory :: proc(capacity: u32, offset: [^]u8) -> Arena --- - SetPointerState :: proc(position: Vector2, pointerDown: bool) --- - Initialize :: proc(arena: Arena, layoutDimensions: Dimensions, errorHandler: ErrorHandler) --- - UpdateScrollContainers :: proc(enableDragScrolling: bool, scrollDelta: Vector2, deltaTime: c.float) --- - SetLayoutDimensions :: proc(dimensions: Dimensions) --- - BeginLayout :: proc() --- - EndLayout :: proc() -> ClayArray(RenderCommand) --- - Hovered :: proc() -> bool --- - PointerOver :: proc(id: ElementId) -> bool --- - GetElementId :: proc(id: String) -> ElementId --- - GetScrollContainerData :: proc(id: ElementId) -> ScrollContainerData --- - SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: StringSlice, config: ^TextElementConfig, userData: uintptr) -> Dimensions, userData: uintptr) --- - RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: i32) -> ^RenderCommand --- - SetDebugModeEnabled :: proc(enabled: bool) --- - GetCurrentContext :: proc() -> ^Context --- - SetCurrentContext :: proc(ctx: ^Context) --- + MinMemorySize :: proc() -> u32 --- + CreateArenaWithCapacityAndMemory :: proc(capacity: u32, offset: [^]u8) -> Arena --- + SetPointerState :: proc(position: Vector2, pointerDown: bool) --- + Initialize :: proc(arena: Arena, layoutDimensions: Dimensions, errorHandler: ErrorHandler) -> ^Context --- + GetCurrentContext :: proc() -> ^Context --- + SetCurrentContext :: proc(ctx: ^Context) --- + UpdateScrollContainers :: proc(enableDragScrolling: bool, scrollDelta: Vector2, deltaTime: c.float) --- + SetLayoutDimensions :: proc(dimensions: Dimensions) --- + BeginLayout :: proc() --- + EndLayout :: proc() -> ClayArray(RenderCommand) --- + GetElementId :: proc(id: String) -> ElementId --- + GetElementIdWithIndex :: proc(id: String, index: u32) -> ElementId --- + GetElementData :: proc(id: ElementId) -> ElementData --- + Hovered :: proc() -> bool --- + OnHover :: proc(onHoverFunction: proc "c" (id: ElementId, pointerData: PointerData, userData: rawptr), userData: rawptr) --- + PointerOver :: proc(id: ElementId) -> bool --- + GetScrollContainerData :: proc(id: ElementId) -> ScrollContainerData --- + SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: StringSlice, config: ^TextElementConfig, userData: rawptr) -> Dimensions, userData: rawptr) --- + SetQueryScrollOffsetFunction :: proc(queryScrollOffsetFunction: proc "c" (elementId: u32, userData: rawptr) -> Vector2, userData: rawptr) --- + RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: i32) -> ^RenderCommand --- + SetDebugModeEnabled :: proc(enabled: bool) --- + IsDebugModeEnabled :: proc() -> bool --- + SetCullingEnabled :: proc(enabled: bool) --- + GetMaxElementCount :: proc() -> i32 --- + SetMaxElementCount :: proc(maxElementCount: i32) --- + GetMaxMeasureTextCacheWordCount :: proc() -> i32 --- + SetMaxMeasureTextCacheWordCount :: proc(maxMeasureTextCacheWordCount: i32) --- + ResetMeasureTextCache :: proc() --- } @(link_prefix = "Clay_", default_calling_convention = "c", private) foreign Clay { - _OpenElement :: proc() --- - _ConfigureOpenElement :: proc(config: ElementDeclaration) --- - _CloseElement :: proc() --- - _OpenTextElement :: proc(text: String, textConfig: ^TextElementConfig) --- - _StoreTextElementConfig :: proc(config: TextElementConfig) -> ^TextElementConfig --- - _HashString :: proc(toHash: String, index: u32, seed: u32) -> ElementId --- - _GetOpenLayoutElementId :: proc() -> u32 --- -} - -ClayOpenElement :: struct { - configure: proc (config: ElementDeclaration) -> bool + _OpenElement :: proc() --- + _ConfigureOpenElement :: proc(config: ElementDeclaration) --- + _CloseElement :: proc() --- + _HashString :: proc(key: String, offset: u32, seed: u32) -> ElementId --- + _OpenTextElement :: proc(text: String, textConfig: ^TextElementConfig) --- + _StoreTextElementConfig :: proc(config: TextElementConfig) -> ^TextElementConfig --- + _GetParentElementId :: proc() -> u32 --- } ConfigureOpenElement :: proc(config: ElementDeclaration) -> bool { - _ConfigureOpenElement(config) - return true; + _ConfigureOpenElement(config) + return true } @(deferred_none = _CloseElement) -UI :: proc() -> ClayOpenElement { - _OpenElement() - return { configure = ConfigureOpenElement } +UI :: proc() -> proc (config: ElementDeclaration) -> bool { + _OpenElement() + return ConfigureOpenElement } Text :: proc(text: string, config: ^TextElementConfig) { - _OpenTextElement(MakeString(text), config) + _OpenTextElement(MakeString(text), config) } TextConfig :: proc(config: TextElementConfig) -> ^TextElementConfig { - return _StoreTextElementConfig(config) + return _StoreTextElementConfig(config) } PaddingAll :: proc(allPadding: u16) -> Padding { - return { left = allPadding, right = allPadding, top = allPadding, bottom = allPadding } + return { left = allPadding, right = allPadding, top = allPadding, bottom = allPadding } } CornerRadiusAll :: proc(radius: f32) -> CornerRadius { - return CornerRadius{radius, radius, radius, radius} + return CornerRadius{radius, radius, radius, radius} } SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis { - return SizingAxis{type = SizingType.Fit, constraints = {sizeMinMax = sizeMinMax}} + return SizingAxis{type = SizingType.Fit, constraints = {sizeMinMax = sizeMinMax}} } SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis { - return SizingAxis{type = SizingType.Grow, constraints = {sizeMinMax = sizeMinMax}} + return SizingAxis{type = SizingType.Grow, constraints = {sizeMinMax = sizeMinMax}} } SizingFixed :: proc(size: c.float) -> SizingAxis { - return SizingAxis{type = SizingType.Fixed, constraints = {sizeMinMax = {size, size}}} + return SizingAxis{type = SizingType.Fixed, constraints = {sizeMinMax = {size, size}}} } SizingPercent :: proc(sizePercent: c.float) -> SizingAxis { - return SizingAxis{type = SizingType.Percent, constraints = {sizePercent = sizePercent}} + return SizingAxis{type = SizingType.Percent, constraints = {sizePercent = sizePercent}} } MakeString :: proc(label: string) -> String { - return String{chars = raw_data(label), length = cast(c.int)len(label)} + return String{chars = raw_data(label), length = cast(c.int)len(label)} } ID :: proc(label: string, index: u32 = 0) -> ElementId { - return _HashString(MakeString(label), index, 0) + return _HashString(MakeString(label), index, 0) } diff --git a/bindings/odin/examples/clay-official-website/clay-official-website.odin b/bindings/odin/examples/clay-official-website/clay-official-website.odin index acc97bd..d96b01b 100644 --- a/bindings/odin/examples/clay-official-website/clay-official-website.odin +++ b/bindings/odin/examples/clay-official-website/clay-official-website.odin @@ -63,13 +63,13 @@ border2pxRed := clay.BorderElementConfig { } LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Color, text: string, image: ^raylib.Texture2D) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("HeroBlob", index), layout = { sizing = { width = clay.SizingGrow({ max = 480 }) }, padding = clay.PaddingAll(16), childGap = 16, childAlignment = clay.ChildAlignment{ y = .Center } }, border = border2pxRed, cornerRadius = clay.CornerRadiusAll(10) }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("CheckImage", index), layout = { sizing = { width = clay.SizingFixed(32) } }, image = { imageData = image, sourceDimensions = { 128, 128 } }, @@ -79,27 +79,27 @@ LandingPageBlob :: proc(index: u32, fontSize: u16, fontId: u16, color: clay.Colo } LandingPageDesktop :: proc() { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("LandingPage1Desktop"), layout = { sizing = { width = clay.SizingGrow({ }), height = clay.SizingFit({ min = cast(f32)windowHeight - 70 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } }, }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("LandingPage1"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 }, border = { COLOR_RED, { left = 2, right = 2 } }, }) { - if clay.UI().configure({ id = clay.ID("LeftText"), layout = { sizing = { width = clay.SizingPercent(0.55) }, layoutDirection = .TopToBottom, childGap = 8 } }) { + if clay.UI()({ id = clay.ID("LeftText"), layout = { sizing = { width = clay.SizingPercent(0.55) }, layoutDirection = .TopToBottom, childGap = 8 } }) { clay.Text( "Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance.", clay.TextConfig({fontSize = 56, fontId = FONT_ID_TITLE_56, textColor = COLOR_RED}), ) - if clay.UI().configure({ layout = { sizing = { width = clay.SizingGrow({}), height = clay.SizingFixed(32) } } }) {} + if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({}), height = clay.SizingFixed(32) } } }) {} clay.Text( "Clay is laying out this webpage right now!", clay.TextConfig({fontSize = 36, fontId = FONT_ID_TITLE_36, textColor = COLOR_ORANGE}), ) } - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("HeroImageOuter"), layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingPercent(0.45) }, childAlignment = { x = .Center }, childGap = 16 }, }) { @@ -114,7 +114,7 @@ LandingPageDesktop :: proc() { } LandingPageMobile :: proc() { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("LandingPage1Mobile"), layout = { layoutDirection = .TopToBottom, @@ -124,18 +124,18 @@ LandingPageMobile :: proc() { childGap = 32, }, }) { - if clay.UI().configure({ id = clay.ID("LeftText"), layout = { sizing = { width = clay.SizingGrow({ }) }, layoutDirection = .TopToBottom, childGap = 8 } }) { + if clay.UI()({ id = clay.ID("LeftText"), layout = { sizing = { width = clay.SizingGrow({ }) }, layoutDirection = .TopToBottom, childGap = 8 } }) { clay.Text( "Clay is a flex-box style UI auto layout library in C, with declarative syntax and microsecond performance.", clay.TextConfig({fontSize = 48, fontId = FONT_ID_TITLE_48, textColor = COLOR_RED}), ) - if clay.UI().configure({ layout = { sizing = { width = clay.SizingGrow({}), height = clay.SizingFixed(32) } } }) {} + if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({}), height = clay.SizingFixed(32) } } }) {} clay.Text( "Clay is laying out this webpage right now!", clay.TextConfig({fontSize = 32, fontId = FONT_ID_TITLE_32, textColor = COLOR_ORANGE}), ) } - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("HeroImageOuter"), layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingGrow({ }) }, childAlignment = { x = .Center }, childGap = 16 }, }) { @@ -150,17 +150,17 @@ LandingPageMobile :: proc() { FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) { textConfig := clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_RED}) - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("HFileBoxOuter"), layout = { layoutDirection = .TopToBottom, sizing = { width = widthSizing }, childAlignment = { y = .Center }, padding = { outerPadding, outerPadding, 32, 32 }, childGap = 8 }, }) { - if clay.UI().configure({ id = clay.ID("HFileIncludeOuter"), layout = { padding = { 8, 8, 4, 4 } }, backgroundColor = COLOR_RED, cornerRadius = clay.CornerRadiusAll(8) }) { + if clay.UI()({ id = clay.ID("HFileIncludeOuter"), layout = { padding = { 8, 8, 4, 4 } }, backgroundColor = COLOR_RED, cornerRadius = clay.CornerRadiusAll(8) }) { clay.Text("#include clay.h", clay.TextConfig({fontSize = 24, fontId = FONT_ID_BODY_24, textColor = COLOR_LIGHT})) } clay.Text("~2000 lines of C99.", textConfig) clay.Text("Zero dependencies, including no C standard library.", textConfig) } - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("BringYourOwnRendererOuter"), layout = { layoutDirection = .TopToBottom, sizing = { width = widthSizing }, childAlignment = { y = .Center }, padding = { outerPadding, outerPadding, 32, 32 }, childGap = 8 }, }) { @@ -171,8 +171,8 @@ FeatureBlocks :: proc(widthSizing: clay.SizingAxis, outerPadding: u16) { } FeatureBlocksDesktop :: proc() { - if clay.UI().configure({ id = clay.ID("FeatureBlocksOuter"), layout = { sizing = { width = clay.SizingGrow({}) } } }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("FeatureBlocksOuter"), layout = { sizing = { width = clay.SizingGrow({}) } } }) { + if clay.UI()({ id = clay.ID("FeatureBlocksInner"), layout = { sizing = { width = clay.SizingGrow({ }) }, childAlignment = { y = .Center } }, border = { width = { betweenChildren = 2}, color = COLOR_RED }, @@ -183,7 +183,7 @@ FeatureBlocksDesktop :: proc() { } FeatureBlocksMobile :: proc() { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("FeatureBlocksInner"), layout = { layoutDirection = .TopToBottom, sizing = { width = clay.SizingGrow({ }) } }, border = { width = { betweenChildren = 2}, color = COLOR_RED }, @@ -193,9 +193,9 @@ FeatureBlocksMobile :: proc() { } DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.SizingAxis) { - if clay.UI().configure({ id = clay.ID("SyntaxPageLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) { + if clay.UI()({ id = clay.ID("SyntaxPageLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) { clay.Text("Declarative Syntax", clay.TextConfig(titleTextConfig)) - if clay.UI().configure({ id = clay.ID("SyntaxSpacer"), layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } } }) {} + if clay.UI()({ id = clay.ID("SyntaxSpacer"), layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } } }) {} clay.Text( "Flexible and readable declarative syntax with nested UI element hierarchies.", clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_RED}), @@ -209,8 +209,8 @@ DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizi clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_28, textColor = COLOR_RED}), ) } - if clay.UI().configure({ id = clay.ID("SyntaxPageRightImage"), layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("SyntaxPageRightImage"), layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) { + if clay.UI()({ id = clay.ID("SyntaxPageRightImageInner"), layout = { sizing = { width = clay.SizingGrow({ max = 568 }) } }, image = { imageData = &syntaxImage, sourceDimensions = { 1136, 1194 } }, @@ -219,11 +219,11 @@ DeclarativeSyntaxPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizi } DeclarativeSyntaxPageDesktop :: proc() { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("SyntaxPageDesktop"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } }, }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("SyntaxPage"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 }, border = border2pxRed, @@ -234,7 +234,7 @@ DeclarativeSyntaxPageDesktop :: proc() { } DeclarativeSyntaxPageMobile :: proc() { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("SyntaxPageMobile"), layout = { layoutDirection = .TopToBottom, @@ -255,9 +255,9 @@ ColorLerp :: proc(a: clay.Color, b: clay.Color, amount: f32) -> clay.Color { LOREM_IPSUM_TEXT := "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementConfig, widthSizing: clay.SizingAxis) { - if clay.UI().configure({ id = clay.ID("PerformanceLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) { + if clay.UI()({ id = clay.ID("PerformanceLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) { clay.Text("High Performance", clay.TextConfig(titleTextConfig)) - if clay.UI().configure({ layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } }}) {} + if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } }}) {} clay.Text( "Fast enough to recompute your entire UI every frame.", clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_36, textColor = COLOR_LIGHT}), @@ -271,20 +271,20 @@ HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementCon clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_36, textColor = COLOR_LIGHT}), ) } - if clay.UI().configure({ id = clay.ID("PerformanceRightImageOuter"), layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("PerformanceRightImageOuter"), layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center } } }) { + if clay.UI()({ id = clay.ID("PerformanceRightBorder"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(400) } }, border = { COLOR_LIGHT, {2, 2, 2, 2, 2} }, }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("AnimationDemoContainerLeft"), layout = { sizing = { clay.SizingPercent(0.35 + 0.3 * lerpValue), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(16) }, backgroundColor = ColorLerp(COLOR_RED, COLOR_ORANGE, lerpValue), }) { clay.Text(LOREM_IPSUM_TEXT, clay.TextConfig({fontSize = 16, fontId = FONT_ID_BODY_16, textColor = COLOR_LIGHT})) } - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("AnimationDemoContainerRight"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(16) }, backgroundColor = ColorLerp(COLOR_ORANGE, COLOR_RED, lerpValue), @@ -296,7 +296,7 @@ HighPerformancePage :: proc(lerpValue: f32, titleTextConfig: clay.TextElementCon } HighPerformancePageDesktop :: proc(lerpValue: f32) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("PerformanceDesktop"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { 82, 82, 32, 32 }, childGap = 64 }, backgroundColor = COLOR_RED, @@ -306,7 +306,7 @@ HighPerformancePageDesktop :: proc(lerpValue: f32) { } HighPerformancePageMobile :: proc(lerpValue: f32) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("PerformanceMobile"), layout = { layoutDirection = .TopToBottom, @@ -322,7 +322,7 @@ HighPerformancePageMobile :: proc(lerpValue: f32) { } RendererButtonActive :: proc(index: i32, text: string) { - if clay.UI().configure({ + if clay.UI()({ layout = { sizing = { width = clay.SizingFixed(300) }, padding = clay.PaddingAll(16) }, backgroundColor = COLOR_RED, cornerRadius = clay.CornerRadiusAll(10) @@ -332,8 +332,8 @@ RendererButtonActive :: proc(index: i32, text: string) { } RendererButtonInactive :: proc(index: u32, text: string) { - if clay.UI().configure({ border = border2pxRed }) { - if clay.UI().configure({ + if clay.UI()({ border = border2pxRed }) { + if clay.UI()({ id = clay.ID("RendererButtonInactiveInner", index), layout = { sizing = { width = clay.SizingFixed(300) }, padding = clay.PaddingAll(16) }, backgroundColor = COLOR_LIGHT, @@ -345,9 +345,9 @@ RendererButtonInactive :: proc(index: u32, text: string) { } RendererPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay.SizingAxis) { - if clay.UI().configure({ id = clay.ID("RendererLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) { + if clay.UI()({ id = clay.ID("RendererLeftText"), layout = { sizing = { width = widthSizing }, layoutDirection = .TopToBottom, childGap = 8 } }) { clay.Text("Renderer & Platform Agnostic", clay.TextConfig(titleTextConfig)) - if clay.UI().configure({ layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } } }) {} + if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({ max = 16 }) } } }) {} clay.Text( "Clay outputs a sorted array of primitive render commands, such as RECTANGLE, TEXT or IMAGE.", clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_36, textColor = COLOR_RED}), @@ -361,22 +361,22 @@ RendererPage :: proc(titleTextConfig: clay.TextElementConfig, widthSizing: clay. clay.TextConfig({fontSize = 28, fontId = FONT_ID_BODY_36, textColor = COLOR_RED}), ) } - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("RendererRightText"), layout = { sizing = { width = widthSizing }, childAlignment = { x = .Center }, layoutDirection = .TopToBottom, childGap = 16 }, }) { clay.Text("Try changing renderer!", clay.TextConfig({fontSize = 36, fontId = FONT_ID_BODY_36, textColor = COLOR_ORANGE})) - if clay.UI().configure({ layout = { sizing = { width = clay.SizingGrow({ max = 32 }) } } }) {} + if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({ max = 32 }) } } }) {} RendererButtonActive(0, "Raylib Renderer") } } RendererPageDesktop :: proc() { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("RendererPageDesktop"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFit({ min = cast(f32)windowHeight - 50 }) }, childAlignment = { y = .Center }, padding = { left = 50, right = 50 } }, }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("RendererPage"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, childAlignment = { y = .Center }, padding = clay.PaddingAll(32), childGap = 32 }, border = { COLOR_RED, { left = 2, right = 2 } }, @@ -387,7 +387,7 @@ RendererPageDesktop :: proc() { } RendererPageMobile :: proc() { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("RendererMobile"), layout = { layoutDirection = .TopToBottom, @@ -414,27 +414,27 @@ animationLerpValue: f32 = -1.0 createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) { mobileScreen := windowWidth < 750 clay.BeginLayout() - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("OuterContainer"), layout = { layoutDirection = .TopToBottom, sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) } }, backgroundColor = COLOR_LIGHT, }) { - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("Header"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(50) }, childAlignment = { y = .Center }, childGap = 24, padding = { left = 32, right = 32 } }, }) { clay.Text("Clay", &headerTextConfig) - if clay.UI().configure({ layout = { sizing = { width = clay.SizingGrow({ }) } } }) {} + if clay.UI()({ layout = { sizing = { width = clay.SizingGrow({ }) } } }) {} if (!mobileScreen) { - if clay.UI().configure({ id = clay.ID("LinkExamplesOuter"), backgroundColor = {0, 0, 0, 0} }) { + if clay.UI()({ id = clay.ID("LinkExamplesOuter"), backgroundColor = {0, 0, 0, 0} }) { clay.Text("Examples", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = {61, 26, 5, 255}})) } - if clay.UI().configure({ id = clay.ID("LinkDocsOuter"), backgroundColor = {0, 0, 0, 0} }) { + if clay.UI()({ id = clay.ID("LinkDocsOuter"), backgroundColor = {0, 0, 0, 0} }) { clay.Text("Docs", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = {61, 26, 5, 255}})) } } - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("LinkGithubOuter"), layout = { padding = { 16, 16, 6, 6 } }, border = border2pxRed, @@ -444,12 +444,12 @@ createLayout :: proc(lerpValue: f32) -> clay.ClayArray(clay.RenderCommand) { clay.Text("Github", clay.TextConfig({fontId = FONT_ID_BODY_24, fontSize = 24, textColor = {61, 26, 5, 255}})) } } - if clay.UI().configure({ id = clay.ID("TopBorder1"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_5 } ) {} - if clay.UI().configure({ id = clay.ID("TopBorder2"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_4 } ) {} - if clay.UI().configure({ id = clay.ID("TopBorder3"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_3 } ) {} - if clay.UI().configure({ id = clay.ID("TopBorder4"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_2 } ) {} - if clay.UI().configure({ id = clay.ID("TopBorder5"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_1 } ) {} - if clay.UI().configure({ + if clay.UI()({ id = clay.ID("TopBorder1"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_5 } ) {} + if clay.UI()({ id = clay.ID("TopBorder2"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_4 } ) {} + if clay.UI()({ id = clay.ID("TopBorder3"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_3 } ) {} + if clay.UI()({ id = clay.ID("TopBorder4"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_2 } ) {} + if clay.UI()({ id = clay.ID("TopBorder5"), layout = { sizing = { clay.SizingGrow({ }), clay.SizingFixed(4) } }, backgroundColor = COLOR_TOP_BORDER_1 } ) {} + if clay.UI()({ id = clay.ID("ScrollContainerBackgroundRectangle"), scroll = { vertical = true }, layout = { sizing = { clay.SizingGrow({ }), clay.SizingGrow({ }) }, layoutDirection = clay.LayoutDirection.TopToBottom }, @@ -493,7 +493,7 @@ main :: proc() { memory := make([^]u8, minMemorySize) arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory) clay.Initialize(arena, {cast(f32)raylib.GetScreenWidth(), cast(f32)raylib.GetScreenHeight()}, { handler = errorHandler }) - clay.SetMeasureTextFunction(measureText, 0) + clay.SetMeasureTextFunction(measureText, nil) raylib.SetConfigFlags({.VSYNC_HINT, .WINDOW_RESIZABLE, .WINDOW_HIGHDPI, .MSAA_4X_HINT}) raylib.InitWindow(windowWidth, windowHeight, "Raylib Odin Example") diff --git a/bindings/odin/examples/clay-official-website/clay_renderer_raylib.odin b/bindings/odin/examples/clay-official-website/clay_renderer_raylib.odin index eae1855..d2c1a5c 100644 --- a/bindings/odin/examples/clay-official-website/clay_renderer_raylib.odin +++ b/bindings/odin/examples/clay-official-website/clay_renderer_raylib.odin @@ -16,7 +16,7 @@ clayColorToRaylibColor :: proc(color: clay.Color) -> raylib.Color { raylibFonts := [10]RaylibFont{} -measureText :: proc "c" (text: clay.StringSlice, config: ^clay.TextElementConfig, userData: uintptr) -> clay.Dimensions { +measureText :: proc "c" (text: clay.StringSlice, config: ^clay.TextElementConfig, userData: rawptr) -> clay.Dimensions { // Measure string size for Font textSize: clay.Dimensions = {0, 0}