Skip to content

Commit edd7767

Browse files
andreakarashoclaude
andcommitted
Add Spacer, LayoutStyle, dual-axis scroll; convert example to pure ClayUI
- Add Spacer() for flexible grow elements in layouts - Add LayoutStyle struct and style parameter to BeginHorizontal/BeginVertical for background color, corner radius, border, padding, and sizing - Extend BeginScrollArea with horizontal parameter for dual-axis scrolling - Convert entire example app to use only ClayUI API (no Clay.Element calls) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2a9ef97 commit edd7767

2 files changed

Lines changed: 306 additions & 227 deletions

File tree

src/Clay.Example/Program.cs

Lines changed: 109 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -125,59 +125,39 @@
125125
ForwardKeyboardInput();
126126

127127
// Root container
128-
using (Clay.Clay.Element(new ElementDeclaration
128+
ClayUI.BeginVertical(gap: 16, style: new LayoutStyle
129129
{
130-
Id = Clay.Clay.Id("Root"),
131-
Layout = new LayoutConfig
132-
{
133-
Sizing = Sizing.Fill(),
134-
Direction = LayoutDirection.TopToBottom,
135-
Padding = Padding.All(16),
136-
ChildGap = 16
137-
},
130+
Sizing = Sizing.Fill(),
131+
Padding = Padding.All(16),
138132
BackgroundColor = ClayUI.Style.Window.BackgroundColor
139-
}))
133+
});
134+
135+
// ===== Header =====
136+
RenderHeader();
137+
138+
// ===== Main Area (Sidebar + Content) =====
139+
ClayUI.BeginHorizontal(gap: 16, style: new LayoutStyle
140140
{
141-
// ===== Header =====
142-
RenderHeader();
141+
Sizing = Sizing.Fill()
142+
});
143+
RenderSidebar();
144+
RenderContent();
145+
ClayUI.EndHorizontal();
143146

144-
// ===== Main Area (Sidebar + Content) =====
145-
using (Clay.Clay.Element(new ElementDeclaration
146-
{
147-
Id = Clay.Clay.Id("MainArea"),
148-
Layout = new LayoutConfig
149-
{
150-
Sizing = new Sizing { Width = SizingAxis.Grow(), Height = SizingAxis.Grow() },
151-
Direction = LayoutDirection.LeftToRight,
152-
ChildGap = 16
153-
}
154-
}))
155-
{
156-
RenderSidebar();
157-
RenderContent();
158-
}
147+
// ===== Footer =====
148+
ClayUI.BeginHorizontal(style: new LayoutStyle { Padding = Padding.Symmetric(8, 4) });
149+
ClayUI.Label("Pure .NET Clay UI Library - No native dependencies | F12 or Debug button for inspector",
150+
new LabelStyle { FontSize = 12 });
151+
ClayUI.EndHorizontal();
159152

160-
// ===== Footer =====
161-
using (Clay.Clay.Element(new ElementDeclaration
162-
{
163-
Layout = new LayoutConfig
164-
{
165-
Sizing = new Sizing { Width = SizingAxis.Grow(), Height = SizingAxis.Fit() },
166-
Padding = Padding.Symmetric(8, 4)
167-
}
168-
}))
169-
{
170-
Clay.Clay.Text("Pure .NET Clay UI Library - No native dependencies | F12 or Debug button for inspector",
171-
new TextConfig { FontSize = 12, TextColor = ClayUI.Style.Label.TextColor, WrapMode = TextWrapMode.None });
172-
}
153+
// ===== Windows (rendered at root level) =====
154+
if (selectedPage == Array.IndexOf(pages, "Windows"))
155+
RenderDemoWindows();
173156

174-
// ===== Windows (rendered at root level) =====
175-
if (selectedPage == Array.IndexOf(pages, "Windows"))
176-
RenderDemoWindows();
157+
if (debugWindowOpen)
158+
ClayUI.ShowDebugWindow();
177159

178-
if (debugWindowOpen)
179-
ClayUI.ShowDebugWindow();
180-
}
160+
ClayUI.EndVertical();
181161

182162
var commands = ClayUI.EndFrame();
183163

@@ -194,80 +174,70 @@
194174

195175
void RenderHeader()
196176
{
197-
using (Clay.Clay.Element(new ElementDeclaration
177+
ClayUI.BeginHorizontal(gap: 12, alignment: ChildAlignment.CenterLeft, style: new LayoutStyle
198178
{
199-
Id = Clay.Clay.Id("Header"),
200-
Layout = new LayoutConfig
201-
{
202-
Sizing = new Sizing { Width = SizingAxis.Grow(), Height = SizingAxis.Fixed(50) },
203-
Direction = LayoutDirection.LeftToRight,
204-
Padding = Padding.Horizontal(16),
205-
ChildGap = 12,
206-
ChildAlignment = ChildAlignment.CenterLeft
207-
},
179+
Sizing = new Sizing(SizingAxis.Grow(), SizingAxis.Fixed(50)),
180+
Padding = Padding.Horizontal(16),
208181
BackgroundColor = ClayUI.Style.Window.TitleBarColor,
209182
CornerRadius = CornerRadius.All(8)
210-
}))
211-
{
212-
ClayUI.Heading("Clay .NET", new HeadingStyle { TextColor = Color.Rgba(100, 180, 255) });
183+
});
213184

214-
// Spacer
215-
using (Clay.Clay.Element(new ElementDeclaration
216-
{
217-
Layout = new LayoutConfig { Sizing = new Sizing { Width = SizingAxis.Grow() } }
218-
})) { }
219-
220-
// Header menu buttons using ClayUI popups
221-
if (ClayUI.Button("File")) ClayUI.OpenPopup("FileMenu");
222-
if (ClayUI.Button("Edit")) ClayUI.OpenPopup("EditMenu");
223-
if (ClayUI.Button("View")) ClayUI.OpenPopup("ViewMenu");
224-
if (ClayUI.Button("Help")) ClayUI.OpenPopup("HelpMenu");
225-
if (ClayUI.Button(debugWindowOpen ? "Debug [ON]" : "Debug"))
226-
{
227-
debugWindowOpen = !debugWindowOpen;
228-
}
185+
ClayUI.Heading("Clay .NET", new HeadingStyle { TextColor = Color.Rgba(100, 180, 255) });
229186

230-
// File menu popup
231-
if (ClayUI.BeginPopup("FileMenu"))
232-
{
233-
if (ClayUI.MenuItem("New")) Console.WriteLine("File > New");
234-
if (ClayUI.MenuItem("Open")) Console.WriteLine("File > Open");
235-
if (ClayUI.MenuItem("Save")) Console.WriteLine("File > Save");
236-
ClayUI.MenuSeparator();
237-
if (ClayUI.MenuItem("Exit")) Environment.Exit(0);
238-
ClayUI.EndPopup();
239-
}
187+
ClayUI.Spacer();
240188

241-
// Edit menu popup
242-
if (ClayUI.BeginPopup("EditMenu"))
243-
{
244-
if (ClayUI.MenuItem("Undo")) Console.WriteLine("Edit > Undo");
245-
if (ClayUI.MenuItem("Redo")) Console.WriteLine("Edit > Redo");
246-
ClayUI.MenuSeparator();
247-
if (ClayUI.MenuItem("Cut")) Console.WriteLine("Edit > Cut");
248-
if (ClayUI.MenuItem("Copy")) Console.WriteLine("Edit > Copy");
249-
if (ClayUI.MenuItem("Paste")) Console.WriteLine("Edit > Paste");
250-
ClayUI.EndPopup();
251-
}
189+
// Header menu buttons using ClayUI popups
190+
if (ClayUI.Button("File")) ClayUI.OpenPopup("FileMenu");
191+
if (ClayUI.Button("Edit")) ClayUI.OpenPopup("EditMenu");
192+
if (ClayUI.Button("View")) ClayUI.OpenPopup("ViewMenu");
193+
if (ClayUI.Button("Help")) ClayUI.OpenPopup("HelpMenu");
194+
if (ClayUI.Button(debugWindowOpen ? "Debug [ON]" : "Debug"))
195+
{
196+
debugWindowOpen = !debugWindowOpen;
197+
}
252198

253-
// View menu popup
254-
if (ClayUI.BeginPopup("ViewMenu"))
255-
{
256-
if (ClayUI.MenuItem("Zoom In")) Console.WriteLine("View > Zoom In");
257-
if (ClayUI.MenuItem("Zoom Out")) Console.WriteLine("View > Zoom Out");
258-
ClayUI.MenuSeparator();
259-
if (ClayUI.MenuItem("Debug Window (F12)")) ClayUI.ToggleDebugWindow();
260-
ClayUI.EndPopup();
261-
}
199+
// File menu popup
200+
if (ClayUI.BeginPopup("FileMenu"))
201+
{
202+
if (ClayUI.MenuItem("New")) Console.WriteLine("File > New");
203+
if (ClayUI.MenuItem("Open")) Console.WriteLine("File > Open");
204+
if (ClayUI.MenuItem("Save")) Console.WriteLine("File > Save");
205+
ClayUI.MenuSeparator();
206+
if (ClayUI.MenuItem("Exit")) Environment.Exit(0);
207+
ClayUI.EndPopup();
208+
}
262209

263-
// Help menu popup
264-
if (ClayUI.BeginPopup("HelpMenu"))
265-
{
266-
if (ClayUI.MenuItem("Documentation")) Console.WriteLine("Help > Docs");
267-
if (ClayUI.MenuItem("About")) Console.WriteLine("Help > About");
268-
ClayUI.EndPopup();
269-
}
210+
// Edit menu popup
211+
if (ClayUI.BeginPopup("EditMenu"))
212+
{
213+
if (ClayUI.MenuItem("Undo")) Console.WriteLine("Edit > Undo");
214+
if (ClayUI.MenuItem("Redo")) Console.WriteLine("Edit > Redo");
215+
ClayUI.MenuSeparator();
216+
if (ClayUI.MenuItem("Cut")) Console.WriteLine("Edit > Cut");
217+
if (ClayUI.MenuItem("Copy")) Console.WriteLine("Edit > Copy");
218+
if (ClayUI.MenuItem("Paste")) Console.WriteLine("Edit > Paste");
219+
ClayUI.EndPopup();
220+
}
221+
222+
// View menu popup
223+
if (ClayUI.BeginPopup("ViewMenu"))
224+
{
225+
if (ClayUI.MenuItem("Zoom In")) Console.WriteLine("View > Zoom In");
226+
if (ClayUI.MenuItem("Zoom Out")) Console.WriteLine("View > Zoom Out");
227+
ClayUI.MenuSeparator();
228+
if (ClayUI.MenuItem("Debug Window (F12)")) ClayUI.ToggleDebugWindow();
229+
ClayUI.EndPopup();
230+
}
231+
232+
// Help menu popup
233+
if (ClayUI.BeginPopup("HelpMenu"))
234+
{
235+
if (ClayUI.MenuItem("Documentation")) Console.WriteLine("Help > Docs");
236+
if (ClayUI.MenuItem("About")) Console.WriteLine("Help > About");
237+
ClayUI.EndPopup();
270238
}
239+
240+
ClayUI.EndHorizontal();
271241
}
272242

273243
// ============ Sidebar ============
@@ -301,7 +271,7 @@ void RenderSidebar()
301271
if (ClayUI.Button(pages[i] + $"##page_{i}", btnStyle))
302272
{
303273
if (selectedPage != i)
304-
Clay.Clay.ResetScrollPosition(Clay.Clay.Id("Content"));
274+
Clay.Clay.ResetScrollPosition(ClayUI.StableId("ScrollArea_Content"));
305275
selectedPage = i;
306276
}
307277
}
@@ -313,73 +283,38 @@ void RenderSidebar()
313283

314284
void RenderContent()
315285
{
316-
var contentId = Clay.Clay.Id("Content");
317-
318-
// Outer wrapper (vertical: [scroll row] + horizontal scrollbar)
319-
using (Clay.Clay.Element(new ElementDeclaration
286+
ClayUI.BeginScrollArea("Content", horizontal: true, style: new ScrollAreaStyle
320287
{
321-
Layout = new LayoutConfig
322-
{
323-
Sizing = Sizing.Fill(),
324-
Direction = LayoutDirection.TopToBottom
325-
},
326288
BackgroundColor = ClayUI.Style.Panel.BackgroundColor,
289+
Padding = Padding.All(20),
327290
CornerRadius = CornerRadius.All(8)
328-
}))
329-
{
330-
// Inner row (horizontal: scroll container + vertical scrollbar)
331-
using (Clay.Clay.Element(new ElementDeclaration
332-
{
333-
Layout = new LayoutConfig
334-
{
335-
Sizing = Sizing.Fill(),
336-
Direction = LayoutDirection.LeftToRight
337-
}
338-
}))
339-
{
340-
using (Clay.Clay.Element(new ElementDeclaration
341-
{
342-
Id = contentId,
343-
Layout = new LayoutConfig
344-
{
345-
Sizing = Sizing.Fill(),
346-
Direction = LayoutDirection.TopToBottom,
347-
Padding = Padding.All(20),
348-
ChildGap = 12
349-
},
350-
Scroll = new ScrollConfig { Vertical = true, Horizontal = true }
351-
}))
352-
{
353-
ClayUI.Heading(pages[selectedPage]);
354-
ClayUI.Separator();
355-
ClayUI.Space(8);
356-
357-
switch (selectedPage)
358-
{
359-
case 0: PageOverview(); break;
360-
case 1: PageButtons(); break;
361-
case 2: PageTextInput(); break;
362-
case 3: PageCheckboxesAndToggles(); break;
363-
case 4: PageSlidersAndProgress(); break;
364-
case 5: PageRadioGroup(); break;
365-
case 6: PageTreeView(); break;
366-
case 7: PageLayoutHelpers(); break;
367-
case 8: PageTextStyles(); break;
368-
case 9: PageColorPicker(); break;
369-
case 10: PageListBoxAndCombo(); break;
370-
case 11: PageScrollAreas(); break;
371-
case 12: PageWindows(); break;
372-
case 13: PagePopups(); break;
373-
case 14: PageTheming(); break;
374-
case 15: PageDisabledStates(); break;
375-
}
376-
}
377-
378-
ClayUI.VerticalScrollbar(contentId);
379-
}
291+
});
292+
293+
ClayUI.Heading(pages[selectedPage]);
294+
ClayUI.Separator();
295+
ClayUI.Space(8);
380296

381-
ClayUI.HorizontalScrollbar(contentId);
297+
switch (selectedPage)
298+
{
299+
case 0: PageOverview(); break;
300+
case 1: PageButtons(); break;
301+
case 2: PageTextInput(); break;
302+
case 3: PageCheckboxesAndToggles(); break;
303+
case 4: PageSlidersAndProgress(); break;
304+
case 5: PageRadioGroup(); break;
305+
case 6: PageTreeView(); break;
306+
case 7: PageLayoutHelpers(); break;
307+
case 8: PageTextStyles(); break;
308+
case 9: PageColorPicker(); break;
309+
case 10: PageListBoxAndCombo(); break;
310+
case 11: PageScrollAreas(); break;
311+
case 12: PageWindows(); break;
312+
case 13: PagePopups(); break;
313+
case 14: PageTheming(); break;
314+
case 15: PageDisabledStates(); break;
382315
}
316+
317+
ClayUI.EndScrollArea();
383318
}
384319

385320
// ============ Pages ============

0 commit comments

Comments
 (0)