diff --git a/ui/layout/flex.go b/ui/layout/flex.go index 91c479f3..dc4a6062 100644 --- a/ui/layout/flex.go +++ b/ui/layout/flex.go @@ -9,10 +9,16 @@ import ( "gioui.org/ui/f32" ) +// Flex lays out interface elements along an axis, +// according to alignment and weights. type Flex struct { - Axis Axis - MainAxisAlignment MainAxisAlignment - CrossAxisAlignment CrossAxisAlignment + // Axis is the main axis, either Horizontal or Vertical. + Axis Axis + // Spacing controls the distribution of any space left after + // layout. + Spacing Spacing + // Alignment is the alignment in the cross axis. + Alignment Alignment macro ui.MacroOp ops *ui.Ops @@ -29,21 +35,26 @@ type FlexChild struct { dims Dimens } -type MainAxisAlignment uint8 -type CrossAxisAlignment uint8 +type Spacing uint8 type flexMode uint8 const ( - Start = 100 + iota - End - Center - - SpaceAround MainAxisAlignment = iota + // SpaceEnd leaves space at the end. + SpaceEnd Spacing = iota + // SpaceStart leaves space at the start. + SpaceStart + // SpaceSides shares space between the start and end. + SpaceSides + // SpaceAround distributes space evenly between elements, + // with half as much space at the start and end. + SpaceAround + // SpaceBetween distributes space evenly between elements, + // leaving no space at the start and end. SpaceBetween + // SpaceEvenly distributes space evenly between elements and + // at the start and end. SpaceEvenly - - Baseline CrossAxisAlignment = iota ) const ( @@ -133,10 +144,10 @@ func (f *Flex) Layout(children ...FlexChild) Dimens { } var mainSize int var baseline int - switch f.MainAxisAlignment { - case Center: + switch f.Spacing { + case SpaceSides: mainSize += space / 2 - case End: + case SpaceStart: mainSize += space case SpaceEvenly: mainSize += space / (1 + len(children)) @@ -147,10 +158,10 @@ func (f *Flex) Layout(children ...FlexChild) Dimens { dims := child.dims b := dims.Baseline var cross int - switch f.CrossAxisAlignment { + switch f.Alignment { case End: cross = crossSize - axisCross(f.Axis, dims.Size) - case Center: + case Middle: cross = (crossSize - axisCross(f.Axis, dims.Size)) / 2 case Baseline: if f.Axis == Horizontal { @@ -164,7 +175,7 @@ func (f *Flex) Layout(children ...FlexChild) Dimens { stack.Pop() mainSize += axisMain(f.Axis, dims.Size) if i < len(children)-1 { - switch f.MainAxisAlignment { + switch f.Spacing { case SpaceEvenly: mainSize += space / (1 + len(children)) case SpaceAround: @@ -177,10 +188,10 @@ func (f *Flex) Layout(children ...FlexChild) Dimens { baseline = b } } - switch f.MainAxisAlignment { - case Center: + switch f.Spacing { + case SpaceSides: mainSize += space / 2 - case Start: + case SpaceEnd: mainSize += space case SpaceEvenly: mainSize += space / (1 + len(children)) @@ -245,3 +256,22 @@ func axisConstraints(a Axis, mainc, crossc Constraint) Constraints { func toPointF(p image.Point) f32.Point { return f32.Point{X: float32(p.X), Y: float32(p.Y)} } + +func (s Spacing) String() string { + switch s { + case SpaceEnd: + return "SpaceEnd" + case SpaceStart: + return "SpaceStart" + case SpaceSides: + return "SpaceSides" + case SpaceAround: + return "SpaceAround" + case SpaceBetween: + return "SpaceAround" + case SpaceEvenly: + return "SpaceEvenly" + default: + panic("unreachable") + } +} diff --git a/ui/layout/layout.go b/ui/layout/layout.go index ef6b2b17..fb88b0cd 100644 --- a/ui/layout/layout.go +++ b/ui/layout/layout.go @@ -27,6 +27,27 @@ type Dimens struct { } type Axis uint8 +type Alignment uint8 +type Direction uint8 + +const ( + Start Alignment = iota + End + Middle + Baseline +) + +const ( + NW Direction = iota + N + NE + E + SE + S + SW + W + Center +) const ( Horizontal Axis = iota @@ -173,3 +194,54 @@ func (a *Align) End(dims Dimens) Dimens { Baseline: dims.Baseline, } } + +func (a Alignment) String() string { + switch a { + case Start: + return "Start" + case End: + return "End" + case Middle: + return "Middle" + case Baseline: + return "Baseline" + default: + panic("unreachable") + } +} + +func (a Axis) String() string { + switch a { + case Horizontal: + return "Horizontal" + case Vertical: + return "Vertical" + default: + panic("unreachable") + } +} + +func (d Direction) String() string { + switch d { + case NW: + return "NW" + case N: + return "N" + case NE: + return "NE" + case E: + return "E" + case SE: + return "SE" + case S: + return "S" + case SW: + return "SW" + case W: + return "W" + case Center: + return "Center" + default: + panic("unreachable") + } +} diff --git a/ui/layout/list.go b/ui/layout/list.go index a9145e02..706136e7 100644 --- a/ui/layout/list.go +++ b/ui/layout/list.go @@ -8,8 +8,8 @@ import ( "gioui.org/ui" "gioui.org/ui/gesture" "gioui.org/ui/input" - "gioui.org/ui/pointer" "gioui.org/ui/paint" + "gioui.org/ui/pointer" ) type scrollChild struct { @@ -18,9 +18,9 @@ type scrollChild struct { } type List struct { - Axis Axis - Invert bool - CrossAxisAlignment CrossAxisAlignment + Axis Axis + Invert bool + Alignment Alignment // The distance scrolled since last call to Init. Distance int @@ -204,10 +204,10 @@ func (l *List) Layout() Dimens { for _, child := range l.children { sz := child.size var cross int - switch l.CrossAxisAlignment { + switch l.Alignment { case End: cross = maxCross - axisCross(l.Axis, sz) - case Center: + case Middle: cross = (maxCross - axisCross(l.Axis, sz)) / 2 } childSize := axisMain(l.Axis, sz) diff --git a/ui/layout/stack.go b/ui/layout/stack.go index 7fc85b3a..f61d9ea7 100644 --- a/ui/layout/stack.go +++ b/ui/layout/stack.go @@ -25,19 +25,6 @@ type StackChild struct { dims Dimens } -type Direction uint8 - -const ( - NW Direction = iota - N - NE - E - SE - S - SW - W -) - func (s *Stack) Init(ops *ui.Ops, cs Constraints) *Stack { s.ops = ops s.cs = cs