diff --git a/layout/flex.go b/layout/flex.go index 942b94bb..0b17111f 100644 --- a/layout/flex.go +++ b/layout/flex.go @@ -24,6 +24,11 @@ type Flex struct { rigidSize int // fraction is the rounding error from a Flex weighting. fraction float32 + + // Use an empty StackOp for tracking whether Rigid, Flex + // is called in the same layout scope as Layout. + begun bool + stack op.StackOp } // FlexChild is the layout result of a call End. @@ -58,6 +63,7 @@ const ( // Rigid lays out a widget with the main axis constrained to the range // from 0 to the remaining space. func (f *Flex) Rigid(gtx *Context, w Widget) FlexChild { + f.begin(gtx.Ops) cs := gtx.Constraints mainc := axisMainConstraint(f.Axis, cs) mainMax := mainc.Max - f.size @@ -74,9 +80,18 @@ func (f *Flex) Rigid(gtx *Context, w Widget) FlexChild { return FlexChild{m, dims} } +func (f *Flex) begin(ops *op.Ops) { + if f.begun { + return + } + f.stack.Push(ops) + f.begun = true +} + // Flex is like Rigid, where the main axis size is also constrained to a // fraction of the space not taken up by Rigid children. func (f *Flex) Flex(gtx *Context, weight float32, w Widget) FlexChild { + f.begin(gtx.Ops) cs := gtx.Constraints mainc := axisMainConstraint(f.Axis, cs) var flexSize int @@ -111,6 +126,9 @@ func (f *Flex) expand(dims Dimensions) { // Layout a list of children. The order of the children determines their laid // out order. func (f *Flex) Layout(gtx *Context, children ...FlexChild) { + if len(children) > 0 { + f.stack.Pop() + } var maxCross int var maxBaseline int for _, child := range children { @@ -181,6 +199,7 @@ func (f *Flex) Layout(gtx *Context, children ...FlexChild) { } sz := axisPoint(f.Axis, mainSize, maxCross) gtx.Dimensions = Dimensions{Size: sz, Baseline: sz.Y - maxBaseline} + f.begun = false f.size = 0 f.rigidSize = 0 } diff --git a/layout/stack.go b/layout/stack.go index 560d7aa3..9e80ea9a 100644 --- a/layout/stack.go +++ b/layout/stack.go @@ -16,6 +16,10 @@ type Stack struct { Alignment Direction maxSZ image.Point + // Use an empty StackOp for tracking whether Rigid, Flex + // is called in the same layout scope as Layout. + begun bool + stack op.StackOp } // StackChild is the layout result of a call to End. @@ -34,7 +38,7 @@ func (s *Stack) Rigid(gtx *Context, w Widget) StackChild { m.Record(gtx.Ops) dims := ctxLayout(gtx, cs, w) m.Stop() - s.expand(dims) + s.expand(gtx.Ops, dims) return StackChild{m, dims} } @@ -48,11 +52,15 @@ func (s *Stack) Expand(gtx *Context, w Widget) StackChild { } dims := ctxLayout(gtx, cs, w) m.Stop() - s.expand(dims) + s.expand(gtx.Ops, dims) return StackChild{m, dims} } -func (s *Stack) expand(dims Dimensions) { +func (s *Stack) expand(ops *op.Ops, dims Dimensions) { + if !s.begun { + s.stack.Push(ops) + s.begun = true + } if w := dims.Size.X; w > s.maxSZ.X { s.maxSZ.X = w } @@ -64,8 +72,12 @@ func (s *Stack) expand(dims Dimensions) { // Layout a list of children. The order of the children determines their laid // out order. func (s *Stack) Layout(gtx *Context, children ...StackChild) { + if len(children) > 0 { + s.stack.Pop() + } maxSZ := gtx.Constraints.Constrain(s.maxSZ) s.maxSZ = image.Point{} + s.begun = false var baseline int for _, ch := range children { sz := ch.dims.Size