A ui/layout/doc.go => ui/layout/doc.go +49 -0
@@ 0,0 1,49 @@
+// SPDX-License-Identifier: Unlicense OR MIT
+
+/*
+Package layout implements layouts common to GUI programs.
+
+Constraints and dimensions
+
+Constraints and dimensions form the the interface between
+layouts and interface child elements. Every layout operation
+start with a set of constraints for acceptable widths and heights
+of a child. The operation ends by the child computing and returning
+its chosen size in the form of a Dimens.
+
+For example, to add space above a widget:
+
+ var cs layout.Constraints = ...
+
+ // Configure a top inset.
+ inset := layout.Inset{Top: ui.Dp(8), ...}
+ // Start insetting and modify the constraints.
+ cs = inset.Begin(..., cs)
+ // Lay out widget and determine its size given the constraints.
+ dimensions := widget.Layout(..., cs)
+ // End the inset and account for the insets.
+ dimensions = inset.End(dimensions)
+
+Note that the example does not generate any garbage even though the
+Inset is transient. Layouts that don't accept user input are designed
+to escape to the heap during their use.
+
+Layout operations are recursive: a child in a layout operation can
+itself be another layout. That way, complex user interfaces can
+be created from a few generic layouts.
+
+This example both aligns and insets a child:
+
+ inset := layout.Inset{...}
+ cs = inset.Begin(..., cs)
+ align := layout.Align{...}
+ cs = align.Begin(..., cs)
+ dims := widget.Layout(..., cs)
+ dims = align.End(dims)
+ dims = inset.End(dims)
+
+More complex layouts such as Stack and Flex lay out multiple children,
+but follow the same pattern of constraints and dimensions.
+
+*/
+package layout
M ui/layout/layout.go => ui/layout/layout.go +7 -0
@@ 107,6 107,8 @@ type Align struct {
cs Constraints
}
+// Begin the inset operation and modify the input constraints to
+// account for the insets.
func (in *Inset) Begin(c ui.Config, ops *ui.Ops, cs Constraints) Constraints {
if in.begun {
panic("must End before Begin")
@@ 139,6 141,8 @@ func (in *Inset) Begin(c ui.Config, ops *ui.Ops, cs Constraints) Constraints {
return mcs
}
+// End the inset operation and return the dimensions for the
+// inset child.
func (in *Inset) End(dims Dimens) Dimens {
if !in.begun {
panic("must Begin before End")
@@ 157,6 161,7 @@ func UniformInset(v ui.Value) Inset {
return Inset{Top: v, Right: v, Bottom: v, Left: v}
}
+// Begin aligning and return the constraints with no minimum size.
func (a *Align) Begin(ops *ui.Ops, cs Constraints) Constraints {
if a.begun {
panic("must End before Begin")
@@ 170,6 175,8 @@ func (a *Align) Begin(ops *ui.Ops, cs Constraints) Constraints {
return cs
}
+// End the align operation and return the dimensions for the
+// aligned child.
func (a *Align) End(dims Dimens) Dimens {
if !a.begun {
panic("must Begin before End")