From e660493794bc19c45ba4d0062861d019da411c11 Mon Sep 17 00:00:00 2001 From: Dan Korostelev Date: Fri, 7 Feb 2025 22:46:53 +0100 Subject: [PATCH] Odin Bindings: simplify clay.UI usage, just pass ElementDeclaration directly instead of requiring an extra .configure call --- bindings/odin/clay-odin/clay.odin | 14 +-- .../clay-official-website.odin | 108 +++++++++--------- 2 files changed, 57 insertions(+), 65 deletions(-) diff --git a/bindings/odin/clay-odin/clay.odin b/bindings/odin/clay-odin/clay.odin index cc529ba..a73ea24 100644 --- a/bindings/odin/clay-odin/clay.odin +++ b/bindings/odin/clay-odin/clay.odin @@ -368,19 +368,11 @@ foreign Clay { _GetOpenLayoutElementId :: proc() -> u32 --- } -ClayOpenElement :: struct { - configure: proc (config: ElementDeclaration) -> bool -} - -ConfigureOpenElement :: proc(config: ElementDeclaration) -> bool { - _ConfigureOpenElement(config) - return true; -} - @(deferred_none = _CloseElement) -UI :: proc() -> ClayOpenElement { +UI :: proc(config: ElementDeclaration) -> bool { _OpenElement() - return { configure = ConfigureOpenElement } + _ConfigureOpenElement(config) + return true } Text :: proc(text: string, config: ^TextElementConfig) { 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 7887992..1567bca 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 },