dvStudioLayoutBox function
The box node describes, holding children.
Shared, because the page and the surface it is edited on both draw one and the editor used to draw its own: a switch over the layout name and nothing else, so a card with padding, a background and a radius was a bare column while somebody was styling it and a card once the page ran. What is edited is what ships is the promise, and two implementations cannot keep it.
Implementation
Widget dvStudioLayoutBox(DVPageNode node, List<Widget> children) {
// How the children sit together, which a box could describe and not
// render: every list and row came out with the framework's default gap,
// packed to the start and stretched across, whatever the document said.
final double spacing = dvStudioSpacingOf(node.properties);
final DVAlign main = dvStudioAlignOf(node.properties['mainAxis']);
final DVCrossAlign cross =
dvStudioCrossAlignOf(node.properties['crossAxis']);
// Whether the box scrolls its own axis. Almost every screen in a design is
// taller than the device, and a document that could not say so rendered the
// overflow stripe on the first screen.
final bool scrolls = node.properties['scroll'] == true;
return switch (node.layout) {
'row' when scrolls =>
DVBox.horizontalScrollable(children, spacing: spacing),
'row' => DVBox.row(children,
spacing: spacing, align: main, crossAlign: cross),
'wrap' => DVBox.wrapLine(children,
spacing: spacing, align: main, crossAlign: cross),
'grid' => DVBox.grid(
children,
columns: (node.properties['columns'] as num?)?.toInt() ?? 2,
),
'stack' => DVBox.stack(children),
'single' => children.isEmpty
? const DVBox(SizedBox.shrink())
: DVBox(children.first),
_ => scrolls
? DVBox.list(children,
spacing: spacing, align: main, crossAlign: cross)
.scrollable()
: DVBox.list(children,
spacing: spacing, align: main, crossAlign: cross),
};
}