Moving layout into its own module (and file)

This commit is contained in:
Dustin Swan 2026-04-02 15:05:50 -06:00
parent d6466555df
commit d606a83dbd
No known key found for this signature in database
GPG key ID: 30D46587E2100467
2 changed files with 133 additions and 75 deletions

View file

@ -390,78 +390,78 @@ LayoutChild = Fixed Int (Int \ Int \ UI) | Flex Int (Int \ Int \ UI);
Alignment = Start | Center | End; Alignment = Start | Center | End;
Direction = Col | Row; Direction = Col | Row;
@layout # @layout
#
layoutDir # layoutDir
: Direction \ { w : Int, h : Int } \ List LayoutChild \ { ui : UI, w : Int, h : Int } # : Direction \ { w : Int, h : Int } \ List LayoutChild \ { ui : UI, w : Int, h : Int }
= dir constraints children \ # = dir constraints children \
mainSize = dir | Col \ constraints.h | Row \ constraints.w; # mainSize = dir | Col \ constraints.h | Row \ constraints.w;
crossSize = dir | Col \ constraints.w | Row \ constraints.h; # crossSize = dir | Col \ constraints.w | Row \ constraints.h;
#
# Pass 1: sum fixed heights, total flex weight # # Pass 1: sum fixed heights, total flex weight
info = fold (acc child \ child # info = fold (acc child \ child
| Fixed s _ \ acc.{ fixedMain = acc.fixedMain + s } # | Fixed s _ \ acc.{ fixedMain = acc.fixedMain + s }
| Flex n _ \ acc.{ totalFlex = acc.totalFlex + n } # | Flex n _ \ acc.{ totalFlex = acc.totalFlex + n }
) { fixedMain = 0, totalFlex = 0 } children; # ) { fixedMain = 0, totalFlex = 0 } children;
#
remaining = mainSize - info.fixedMain; # remaining = mainSize - info.fixedMain;
#
# Pass 2 # # Pass 2
result = fold (acc child \ # result = fold (acc child \
allocated = (child # allocated = (child
| Fixed s view \ { s = s, view = view } # | Fixed s view \ { s = s, view = view }
| Flex n view \ { s = remaining * n / info.totalFlex, view = view }); # | Flex n view \ { s = remaining * n / info.totalFlex, view = view });
#
childW = dir | Col \ crossSize | Row \ allocated.s; # childW = dir | Col \ crossSize | Row \ allocated.s;
childH = dir | Col \ allocated.s | Row \ crossSize; # childH = dir | Col \ allocated.s | Row \ crossSize;
posX = dir | Col \ 0 | Row \ acc.pos; # posX = dir | Col \ 0 | Row \ acc.pos;
posY = dir | Col \ acc.pos | Row \ 0; # posY = dir | Col \ acc.pos | Row \ 0;
#
rendered = ui.positioned { # rendered = ui.positioned {
x = posX, y = posY, # x = posX, y = posY,
child = allocated.view childW childH # child = allocated.view childW childH
}; # };
#
acc.{ pos = acc.pos + allocated.s, children = [...acc.children, rendered] } # acc.{ pos = acc.pos + allocated.s, children = [...acc.children, rendered] }
) { pos = 0, children = [] } children; # ) { pos = 0, children = [] } children;
#
{ ui = ui.stack { children = result.children }, w = constraints.w, h = constraints.h }; # { ui = ui.stack { children = result.children }, w = constraints.w, h = constraints.h };
#
col = layoutDir Col; # col = layoutDir Col;
row = layoutDir Row; # row = layoutDir Row;
#
align = hAlign vAlign w h child \ # align = hAlign vAlign w h child \
x = hAlign # x = hAlign
| Start \ 0 # | Start \ 0
| Center \ (w - child.w) / 2 # | Center \ (w - child.w) / 2
| End \ w - child.w; # | End \ w - child.w;
y = vAlign # y = vAlign
| Start \ 0 # | Start \ 0
| Center \ (h - child.h) / 2 # | Center \ (h - child.h) / 2
| End \ h - child.h; # | End \ h - child.h;
{ ui = ui.positioned { x = x, y = y, child = child.ui }, w = w, h = h }; # { ui = ui.positioned { x = x, y = y, child = child.ui }, w = w, h = h };
#
@ # @
#
testApp = name \ # testApp = name \
{ view = ctx \ # { view = ctx \
col { w = ctx.w, h = ctx.h } [ # col { w = ctx.w, h = ctx.h } [
Fixed 40 (w h \ box { w = w, h = h, color = "red", child = text "Header" }), # Fixed 40 (w h \ box { w = w, h = h, color = "red", child = text "Header" }),
Flex 1 (w h \ box { w = w, h = h, color = "#1a1a2e", child = text "Main content" }), # Flex 1 (w h \ box { w = w, h = h, color = "#1a1a2e", child = text "Main content" }),
Fixed 30 (w h \ box { w = w, h = h, color = "blue", child = text "Footer" }), # Fixed 30 (w h \ box { w = w, h = h, color = "blue", child = text "Footer" }),
] # ]
~ (e \ e.ui) # ~ (e \ e.ui)
}; # };
#
testApp2 = _ \ # testApp2 = _ \
{ view = ctx \ # { view = ctx \
col { w = ctx.w, h = ctx.h } [ # col { w = ctx.w, h = ctx.h } [
Fixed 40 (w h \ (align Center Center w h (sizedText "Header")).ui), # Fixed 40 (w h \ (align Center Center w h (sizedText "Header")).ui),
Flex 1 (w h \ (row { w = w, h = h } [ # Flex 1 (w h \ (row { w = w, h = h } [
Fixed 200 (w h \ box { w = w, h = h, color = "#2a2a3e", child = text "Sidebar" }), # Fixed 200 (w h \ box { w = w, h = h, color = "#2a2a3e", child = text "Sidebar" }),
Flex 1 (w h \ box { w = w, h = h, color = "#1a1a2e", child = text "Main" }), # Flex 1 (w h \ box { w = w, h = h, color = "#1a1a2e", child = text "Main" }),
]).ui), # ]).ui),
Fixed 30 (w h \ (align Center Center w h (sizedText "Footer")).ui), # Fixed 30 (w h \ (align Center Center w h (sizedText "Footer")).ui),
] # ]
~ (e \ e.ui) # ~ (e \ e.ui)
}; # };

58
src/cg/layout.cg Normal file
View file

@ -0,0 +1,58 @@
@layout
layoutDir : Direction \ { w : Int, h : Int } \ List LayoutChild \ { ui : UI, w : Int, h : Int } = dir constraints children \
mainSize = dir
| Col \ constraints.h
| Row \ constraints.w;
crossSize = dir
| Col \ constraints.w
| Row \ constraints.h;
info = fold (acc child \
child
| (Fixed s _) \ acc.{ fixedMain = acc.fixedMain + s }
| (Flex n _) \ acc.{ totalFlex = acc.totalFlex + n }) { fixedMain = 0, totalFlex = 0 } children;
remaining = mainSize - info.fixedMain;
result = fold (acc child \
allocated = child
| (Fixed s view) \ { s = s, view = view }
| (Flex n view) \ { s = (remaining * n) / info.totalFlex, view = view };
childW = dir
| Col \ crossSize
| Row \ allocated.s;
childH = dir
| Col \ allocated.s
| Row \ crossSize;
posX = dir
| Col \ 0
| Row \ acc.pos;
posY = dir
| Col \ acc.pos
| Row \ 0;
rendered = ui.positioned { x = posX, y = posY, child = allocated.view childW childH };
acc.{ pos = acc.pos + allocated.s, children = [...acc.children, rendered] }) { pos = 0, children = [] } children;
{
ui = ui.stack { children = result.children },
w = constraints.w,
h = constraints.h
};
col = layoutDir Col;
row = layoutDir Row;
align = hAlign vAlign w h child \
x = hAlign
| Start \ 0
| Center \ (w - child.w) / 2
| End \ w - child.w;
y = vAlign
| Start \ 0
| Center \ (h - child.h) / 2
| End \ h - child.h;
{
ui = ui.positioned { x = x, y = y, child = child.ui },
w = w,
h = h
};
@