diff options
Diffstat (limited to 'vendor/gioui.org/layout')
-rw-r--r-- | vendor/gioui.org/layout/context.go | 20 | ||||
-rw-r--r-- | vendor/gioui.org/layout/doc.go | 2 | ||||
-rw-r--r-- | vendor/gioui.org/layout/flex.go | 106 | ||||
-rw-r--r-- | vendor/gioui.org/layout/layout.go | 126 | ||||
-rw-r--r-- | vendor/gioui.org/layout/list.go | 139 | ||||
-rw-r--r-- | vendor/gioui.org/layout/stack.go | 18 |
6 files changed, 251 insertions, 160 deletions
diff --git a/vendor/gioui.org/layout/context.go b/vendor/gioui.org/layout/context.go index f47233b..5d31496 100644 --- a/vendor/gioui.org/layout/context.go +++ b/vendor/gioui.org/layout/context.go @@ -5,6 +5,7 @@ package layout import ( "time" + "gioui.org/f32" "gioui.org/io/event" "gioui.org/io/system" "gioui.org/op" @@ -39,15 +40,30 @@ type Context struct { // Constraints: Exact(e.Size), // } // -// NewContext calls ops.Reset. +// NewContext calls ops.Reset and adjusts ops for e.Insets. func NewContext(ops *op.Ops, e system.FrameEvent) Context { ops.Reset() + + size := e.Size + + if e.Insets != (system.Insets{}) { + left := e.Metric.Px(e.Insets.Left) + top := e.Metric.Px(e.Insets.Top) + op.Offset(f32.Point{ + X: float32(left), + Y: float32(top), + }).Add(ops) + + size.X -= left + e.Metric.Px(e.Insets.Right) + size.Y -= top + e.Metric.Px(e.Insets.Bottom) + } + return Context{ Ops: ops, Now: e.Now, Queue: e.Queue, Metric: e.Metric, - Constraints: Exact(e.Size), + Constraints: Exact(size), } } diff --git a/vendor/gioui.org/layout/doc.go b/vendor/gioui.org/layout/doc.go index d318765..3824084 100644 --- a/vendor/gioui.org/layout/doc.go +++ b/vendor/gioui.org/layout/doc.go @@ -37,7 +37,7 @@ This example both aligns and insets a child: inset := layout.Inset{...} inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions { - align := layout.Align(...) + align := layout.Alignment(...) return align.Layout(gtx, func(gtx layout.Context) layout.Dimensions { return widget.Layout(gtx, ...) }) diff --git a/vendor/gioui.org/layout/flex.go b/vendor/gioui.org/layout/flex.go index fe85b64..7d66f8f 100644 --- a/vendor/gioui.org/layout/flex.go +++ b/vendor/gioui.org/layout/flex.go @@ -65,9 +65,10 @@ func Rigid(widget Widget) FlexChild { } } -// Flexed returns a Flex child forced to take up w fraction of the -// of the space left over from Rigid children. The fraction is weight -// divided by the weight sum of all Flexed children. +// Flexed returns a Flex child forced to take up weight fraction of the +// space left over from Rigid children. The fraction is weight +// divided by either the weight sum of all Flexed children or the Flex +// WeightSum if non zero. func Flexed(weight float32, widget Widget) FlexChild { return FlexChild{ flex: true, @@ -82,10 +83,11 @@ func Flexed(weight float32, widget Widget) FlexChild { func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions { size := 0 cs := gtx.Constraints - mainMin, mainMax := axisMainConstraint(f.Axis, cs) - crossMin, crossMax := axisCrossConstraint(f.Axis, cs) + mainMin, mainMax := f.Axis.mainConstraint(cs) + crossMin, crossMax := f.Axis.crossConstraint(cs) remaining := mainMax var totalWeight float32 + cgtx := gtx // Lay out Rigid children. for i, child := range children { if child.flex { @@ -93,11 +95,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions { continue } macro := op.Record(gtx.Ops) - gtx := gtx - gtx.Constraints = axisConstraints(f.Axis, 0, remaining, crossMin, crossMax) - dims := child.widget(gtx) + cgtx.Constraints = f.Axis.constraints(0, remaining, crossMin, crossMax) + dims := child.widget(cgtx) c := macro.Stop() - sz := axisMain(f.Axis, dims.Size) + sz := f.Axis.Convert(dims.Size).X size += sz remaining -= sz if remaining < 0 { @@ -129,11 +130,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions { } } macro := op.Record(gtx.Ops) - gtx := gtx - gtx.Constraints = axisConstraints(f.Axis, flexSize, flexSize, crossMin, crossMax) - dims := child.widget(gtx) + cgtx.Constraints = f.Axis.constraints(flexSize, flexSize, crossMin, crossMax) + dims := child.widget(cgtx) c := macro.Stop() - sz := axisMain(f.Axis, dims.Size) + sz := f.Axis.Convert(dims.Size).X size += sz remaining -= sz if remaining < 0 { @@ -145,7 +145,7 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions { var maxCross int var maxBaseline int for _, child := range children { - if c := axisCross(f.Axis, child.dims.Size); c > maxCross { + if c := f.Axis.Convert(child.dims.Size).Y; c > maxCross { maxCross = c } if b := child.dims.Size.Y - child.dims.Baseline; b > maxBaseline { @@ -165,7 +165,9 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions { case SpaceEvenly: mainSize += space / (1 + len(children)) case SpaceAround: - mainSize += space / (len(children) * 2) + if len(children) > 0 { + mainSize += space / (len(children) * 2) + } } for i, child := range children { dims := child.dims @@ -173,27 +175,31 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions { var cross int switch f.Alignment { case End: - cross = maxCross - axisCross(f.Axis, dims.Size) + cross = maxCross - f.Axis.Convert(dims.Size).Y case Middle: - cross = (maxCross - axisCross(f.Axis, dims.Size)) / 2 + cross = (maxCross - f.Axis.Convert(dims.Size).Y) / 2 case Baseline: if f.Axis == Horizontal { cross = maxBaseline - b } } - stack := op.Push(gtx.Ops) - op.Offset(FPt(axisPoint(f.Axis, mainSize, cross))).Add(gtx.Ops) + pt := f.Axis.Convert(image.Pt(mainSize, cross)) + trans := op.Offset(FPt(pt)).Push(gtx.Ops) child.call.Add(gtx.Ops) - stack.Pop() - mainSize += axisMain(f.Axis, dims.Size) + trans.Pop() + mainSize += f.Axis.Convert(dims.Size).X if i < len(children)-1 { switch f.Spacing { case SpaceEvenly: mainSize += space / (1 + len(children)) case SpaceAround: - mainSize += space / len(children) + if len(children) > 0 { + mainSize += space / len(children) + } case SpaceBetween: - mainSize += space / (len(children) - 1) + if len(children) > 1 { + mainSize += space / (len(children) - 1) + } } } } @@ -205,60 +211,14 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions { case SpaceEvenly: mainSize += space / (1 + len(children)) case SpaceAround: - mainSize += space / (len(children) * 2) + if len(children) > 0 { + mainSize += space / (len(children) * 2) + } } - sz := axisPoint(f.Axis, mainSize, maxCross) + sz := f.Axis.Convert(image.Pt(mainSize, maxCross)) return Dimensions{Size: sz, Baseline: sz.Y - maxBaseline} } -func axisPoint(a Axis, main, cross int) image.Point { - if a == Horizontal { - return image.Point{main, cross} - } else { - return image.Point{cross, main} - } -} - -func axisMain(a Axis, sz image.Point) int { - if a == Horizontal { - return sz.X - } else { - return sz.Y - } -} - -func axisCross(a Axis, sz image.Point) int { - if a == Horizontal { - return sz.Y - } else { - return sz.X - } -} - -func axisMainConstraint(a Axis, cs Constraints) (int, int) { - if a == Horizontal { - return cs.Min.X, cs.Max.X - } else { - return cs.Min.Y, cs.Max.Y - } -} - -func axisCrossConstraint(a Axis, cs Constraints) (int, int) { - if a == Horizontal { - return cs.Min.Y, cs.Max.Y - } else { - return cs.Min.X, cs.Max.X - } -} - -func axisConstraints(a Axis, mainMin, mainMax, crossMin, crossMax int) Constraints { - if a == Horizontal { - return Constraints{Min: image.Pt(mainMin, crossMin), Max: image.Pt(mainMax, crossMax)} - } else { - return Constraints{Min: image.Pt(crossMin, mainMin), Max: image.Pt(crossMax, mainMax)} - } -} - func (s Spacing) String() string { switch s { case SpaceEnd: diff --git a/vendor/gioui.org/layout/layout.go b/vendor/gioui.org/layout/layout.go index 112c45d..2318c22 100644 --- a/vendor/gioui.org/layout/layout.go +++ b/vendor/gioui.org/layout/layout.go @@ -23,6 +23,10 @@ type Constraints struct { } // Dimensions are the resolved size and baseline for a widget. +// +// Baseline is the distance from the bottom of a widget to the baseline of +// any text it contains (or 0). The purpose is to be able to align text +// that span multiple widgets. type Dimensions struct { Size image.Point Baseline int @@ -105,7 +109,9 @@ func (c Constraints) Constrain(size image.Point) image.Point { return size } -// Inset adds space around a widget. +// Inset adds space around a widget by decreasing its maximum +// constraints. The minimum constraints will be adjusted to ensure +// they do not exceed the maximum. type Inset struct { Top, Right, Bottom, Left unit.Value } @@ -135,11 +141,10 @@ func (in Inset) Layout(gtx Context, w Widget) Dimensions { if mcs.Min.Y > mcs.Max.Y { mcs.Min.Y = mcs.Max.Y } - stack := op.Push(gtx.Ops) - op.Offset(FPt(image.Point{X: left, Y: top})).Add(gtx.Ops) gtx.Constraints = mcs + trans := op.Offset(FPt(image.Point{X: left, Y: top})).Push(gtx.Ops) dims := w(gtx) - stack.Pop() + trans.Pop() return Dimensions{ Size: dims.Size.Add(image.Point{X: right + left, Y: top + bottom}), Baseline: dims.Baseline + bottom, @@ -153,39 +158,70 @@ func UniformInset(v unit.Value) Inset { } // Layout a widget according to the direction. -func (a Direction) Layout(gtx Context, w Widget) Dimensions { +// The widget is called with the context constraints minimum cleared. +func (d Direction) Layout(gtx Context, w Widget) Dimensions { macro := op.Record(gtx.Ops) - cs := gtx.Constraints - gtx.Constraints.Min = image.Point{} + csn := gtx.Constraints.Min + switch d { + case N, S: + gtx.Constraints.Min.Y = 0 + case E, W: + gtx.Constraints.Min.X = 0 + default: + gtx.Constraints.Min = image.Point{} + } dims := w(gtx) call := macro.Stop() sz := dims.Size - if sz.X < cs.Min.X { - sz.X = cs.Min.X + if sz.X < csn.X { + sz.X = csn.X + } + if sz.Y < csn.Y { + sz.Y = csn.Y } - if sz.Y < cs.Min.Y { - sz.Y = cs.Min.Y + + p := d.Position(dims.Size, sz) + defer op.Offset(FPt(p)).Push(gtx.Ops).Pop() + call.Add(gtx.Ops) + + return Dimensions{ + Size: sz, + Baseline: dims.Baseline + sz.Y - dims.Size.Y - p.Y, } +} + +// Position calculates widget position according to the direction. +func (d Direction) Position(widget, bounds image.Point) image.Point { var p image.Point - switch Direction(a) { + + switch d { case N, S, Center: - p.X = (sz.X - dims.Size.X) / 2 + p.X = (bounds.X - widget.X) / 2 case NE, SE, E: - p.X = sz.X - dims.Size.X + p.X = bounds.X - widget.X } - switch Direction(a) { + + switch d { case W, Center, E: - p.Y = (sz.Y - dims.Size.Y) / 2 + p.Y = (bounds.Y - widget.Y) / 2 case SW, S, SE: - p.Y = sz.Y - dims.Size.Y + p.Y = bounds.Y - widget.Y } - stack := op.Push(gtx.Ops) - op.Offset(FPt(p)).Add(gtx.Ops) - call.Add(gtx.Ops) - stack.Pop() + + return p +} + +// Spacer adds space between widgets. +type Spacer struct { + Width, Height unit.Value +} + +func (s Spacer) Layout(gtx Context) Dimensions { return Dimensions{ - Size: sz, - Baseline: dims.Baseline + sz.Y - dims.Size.Y - p.Y, + Size: image.Point{ + X: gtx.Px(s.Width), + Y: gtx.Px(s.Height), + }, } } @@ -204,6 +240,50 @@ func (a Alignment) String() string { } } +// Convert a point in (x, y) coordinates to (main, cross) coordinates, +// or vice versa. Specifically, Convert((x, y)) returns (x, y) unchanged +// for the horizontal axis, or (y, x) for the vertical axis. +func (a Axis) Convert(pt image.Point) image.Point { + if a == Horizontal { + return pt + } + return image.Pt(pt.Y, pt.X) +} + +// FConvert a point in (x, y) coordinates to (main, cross) coordinates, +// or vice versa. Specifically, FConvert((x, y)) returns (x, y) unchanged +// for the horizontal axis, or (y, x) for the vertical axis. +func (a Axis) FConvert(pt f32.Point) f32.Point { + if a == Horizontal { + return pt + } + return f32.Pt(pt.Y, pt.X) +} + +// mainConstraint returns the min and max main constraints for axis a. +func (a Axis) mainConstraint(cs Constraints) (int, int) { + if a == Horizontal { + return cs.Min.X, cs.Max.X + } + return cs.Min.Y, cs.Max.Y +} + +// crossConstraint returns the min and max cross constraints for axis a. +func (a Axis) crossConstraint(cs Constraints) (int, int) { + if a == Horizontal { + return cs.Min.Y, cs.Max.Y + } + return cs.Min.X, cs.Max.X +} + +// constraints returns the constraints for axis a. +func (a Axis) constraints(mainMin, mainMax, crossMin, crossMax int) Constraints { + if a == Horizontal { + return Constraints{Min: image.Pt(mainMin, crossMin), Max: image.Pt(mainMax, crossMax)} + } + return Constraints{Min: image.Pt(crossMin, mainMin), Max: image.Pt(crossMax, mainMax)} +} + func (a Axis) String() string { switch a { case Horizontal: diff --git a/vendor/gioui.org/layout/list.go b/vendor/gioui.org/layout/list.go index 68b63f7..aa78f1b 100644 --- a/vendor/gioui.org/layout/list.go +++ b/vendor/gioui.org/layout/list.go @@ -6,7 +6,6 @@ import ( "image" "gioui.org/gesture" - "gioui.org/io/pointer" "gioui.org/op" "gioui.org/op/clip" ) @@ -29,15 +28,13 @@ type List struct { // Alignment is the cross axis alignment of list elements. Alignment Alignment - ctx Context - macro op.MacroOp - child op.MacroOp + cs Constraints scroll gesture.Scroll scrollDelta int // Position is updated during Layout. To save the list scroll position, // just save Position after Layout finishes. To scroll the list - // programatically, update Position (e.g. restore it from a saved value) + // programmatically, update Position (e.g. restore it from a saved value) // before calling Layout. Position Position @@ -71,6 +68,13 @@ type Position struct { // Offset is the distance in pixels from the top edge to the child at index // First. Offset int + // OffsetLast is the signed distance in pixels from the bottom edge to the + // bottom edge of the child at index First+Count. + OffsetLast int + // Count is the number of visible children. + Count int + // Length is the estimated total size of all children, measured in pixels. + Length int } const ( @@ -86,29 +90,41 @@ func (l *List) init(gtx Context, len int) { if l.more() { panic("unfinished child") } - l.ctx = gtx + l.cs = gtx.Constraints l.maxSize = 0 l.children = l.children[:0] l.len = len - l.update() + l.update(gtx) if l.scrollToEnd() || l.Position.First > len { l.Position.Offset = 0 l.Position.First = len } - l.macro = op.Record(gtx.Ops) - l.next() } // Layout the List. func (l *List) Layout(gtx Context, len int, w ListElement) Dimensions { - for l.init(gtx, len); l.more(); l.next() { - crossMin, crossMax := axisCrossConstraint(l.Axis, l.ctx.Constraints) - cs := axisConstraints(l.Axis, 0, inf, crossMin, crossMax) - i := l.index() - gtx.Constraints = cs - l.end(w(gtx, i)) + l.init(gtx, len) + crossMin, crossMax := l.Axis.crossConstraint(gtx.Constraints) + gtx.Constraints = l.Axis.constraints(0, inf, crossMin, crossMax) + macro := op.Record(gtx.Ops) + laidOutTotalLength := 0 + numLaidOut := 0 + + for l.next(); l.more(); l.next() { + child := op.Record(gtx.Ops) + dims := w(gtx, l.index()) + call := child.Stop() + l.end(dims, call) + laidOutTotalLength += l.Axis.Convert(dims.Size).X + numLaidOut++ + } + + if numLaidOut > 0 { + l.Position.Length = laidOutTotalLength * len / numLaidOut + } else { + l.Position.Length = 0 } - return l.layout() + return l.layout(gtx.Ops, macro) } func (l *List) scrollToEnd() bool { @@ -120,8 +136,8 @@ func (l *List) Dragging() bool { return l.scroll.State() == gesture.StateDragging } -func (l *List) update() { - d := l.scroll.Scroll(l.ctx.Metric, l.ctx, l.ctx.Now, gesture.Axis(l.Axis)) +func (l *List) update(gtx Context) { + d := l.scroll.Scroll(gtx.Metric, gtx, gtx.Now, gesture.Axis(l.Axis)) l.scrollDelta = d l.Position.Offset += d } @@ -136,9 +152,6 @@ func (l *List) next() { l.Position.Offset += l.scrollDelta l.dir = l.nextDir() } - if l.more() { - l.child = op.Record(l.ctx.Ops) - } } // index is current child's position in the underlying list. @@ -159,7 +172,7 @@ func (l *List) more() bool { } func (l *List) nextDir() iterationDir { - _, vsize := axisMainConstraint(l.Axis, l.ctx.Constraints) + _, vsize := l.Axis.mainConstraint(l.cs) last := l.Position.First + len(l.children) // Clamp offset. if l.maxSize-l.Position.Offset < vsize && last == l.len { @@ -180,16 +193,17 @@ func (l *List) nextDir() iterationDir { } // End the current child by specifying its dimensions. -func (l *List) end(dims Dimensions) { - call := l.child.Stop() +func (l *List) end(dims Dimensions, call op.CallOp) { child := scrollChild{dims.Size, call} - mainSize := axisMain(l.Axis, child.size) + mainSize := l.Axis.Convert(child.size).X l.maxSize += mainSize switch l.dir { case iterateForward: l.children = append(l.children, child) case iterateBackward: - l.children = append([]scrollChild{child}, l.children...) + l.children = append(l.children, scrollChild{}) + copy(l.children[1:], l.children) + l.children[0] = child l.Position.First-- l.Position.Offset += mainSize default: @@ -199,17 +213,18 @@ func (l *List) end(dims Dimensions) { } // Layout the List and return its dimensions. -func (l *List) layout() Dimensions { +func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions { if l.more() { panic("unfinished child") } - mainMin, mainMax := axisMainConstraint(l.Axis, l.ctx.Constraints) + mainMin, mainMax := l.Axis.mainConstraint(l.cs) children := l.children // Skip invisible children for len(children) > 0 { sz := children[0].size - mainSize := axisMain(l.Axis, sz) - if l.Position.Offset <= mainSize { + mainSize := l.Axis.Convert(sz).X + if l.Position.Offset < mainSize { + // First child is partially visible. break } l.Position.First++ @@ -219,32 +234,33 @@ func (l *List) layout() Dimensions { size := -l.Position.Offset var maxCross int for i, child := range children { - sz := child.size - if c := axisCross(l.Axis, sz); c > maxCross { + sz := l.Axis.Convert(child.size) + if c := sz.Y; c > maxCross { maxCross = c } - size += axisMain(l.Axis, sz) + size += sz.X if size >= mainMax { children = children[:i+1] break } } - ops := l.ctx.Ops + l.Position.Count = len(children) + l.Position.OffsetLast = mainMax - size pos := -l.Position.Offset // ScrollToEnd lists are end aligned. - if space := mainMax - size; l.ScrollToEnd && space > 0 { + if space := l.Position.OffsetLast; l.ScrollToEnd && space > 0 { pos += space } for _, child := range children { - sz := child.size + sz := l.Axis.Convert(child.size) var cross int switch l.Alignment { case End: - cross = maxCross - axisCross(l.Axis, sz) + cross = maxCross - sz.Y case Middle: - cross = (maxCross - axisCross(l.Axis, sz)) / 2 + cross = (maxCross - sz.Y) / 2 } - childSize := axisMain(l.Axis, sz) + childSize := sz.X max := childSize + pos if max > mainMax { max = mainMax @@ -254,14 +270,15 @@ func (l *List) layout() Dimensions { min = 0 } r := image.Rectangle{ - Min: axisPoint(l.Axis, min, -inf), - Max: axisPoint(l.Axis, max, inf), + Min: l.Axis.Convert(image.Pt(min, -inf)), + Max: l.Axis.Convert(image.Pt(max, inf)), } - stack := op.Push(ops) - clip.Rect{Rect: FRect(r)}.Op(ops).Add(ops) - op.Offset(FPt(axisPoint(l.Axis, pos, cross))).Add(ops) + cl := clip.Rect(r).Push(ops) + pt := l.Axis.Convert(image.Pt(pos, cross)) + trans := op.Offset(FPt(pt)).Push(ops) child.call.Add(ops) - stack.Pop() + trans.Pop() + cl.Pop() pos += childSize } atStart := l.Position.First == 0 && l.Position.Offset <= 0 @@ -276,11 +293,33 @@ func (l *List) layout() Dimensions { if pos > mainMax { pos = mainMax } - dims := axisPoint(l.Axis, pos, maxCross) - call := l.macro.Stop() - defer op.Push(l.ctx.Ops).Pop() - pointer.Rect(image.Rectangle{Max: dims}).Add(ops) - l.scroll.Add(ops) + if crossMin, crossMax := l.Axis.crossConstraint(l.cs); maxCross < crossMin { + maxCross = crossMin + } else if maxCross > crossMax { + maxCross = crossMax + } + dims := l.Axis.Convert(image.Pt(pos, maxCross)) + call := macro.Stop() + defer clip.Rect(image.Rectangle{Max: dims}).Push(ops).Pop() + + var min, max int + if o := l.Position.Offset; o > 0 { + // Use the size of the invisible part as scroll boundary. + min = -o + } else if l.Position.First > 0 { + min = -inf + } + if o := l.Position.OffsetLast; o < 0 { + max = -o + } else if l.Position.First+l.Position.Count < l.len { + max = inf + } + scrollRange := image.Rectangle{ + Min: l.Axis.Convert(image.Pt(min, 0)), + Max: l.Axis.Convert(image.Pt(max, 0)), + } + l.scroll.Add(ops, scrollRange) + call.Add(ops) return Dimensions{Size: dims} } diff --git a/vendor/gioui.org/layout/stack.go b/vendor/gioui.org/layout/stack.go index 0de43df..fb8b8ac 100644 --- a/vendor/gioui.org/layout/stack.go +++ b/vendor/gioui.org/layout/stack.go @@ -50,14 +50,14 @@ func Expanded(w Widget) StackChild { func (s Stack) Layout(gtx Context, children ...StackChild) Dimensions { var maxSZ image.Point // First lay out Stacked children. + cgtx := gtx + cgtx.Constraints.Min = image.Point{} for i, w := range children { if w.expanded { continue } macro := op.Record(gtx.Ops) - gtx := gtx - gtx.Constraints.Min = image.Pt(0, 0) - dims := w.widget(gtx) + dims := w.widget(cgtx) call := macro.Stop() if w := dims.Size.X; w > maxSZ.X { maxSZ.X = w @@ -74,11 +74,8 @@ func (s Stack) Layout(gtx Context, children ...StackChild) Dimensions { continue } macro := op.Record(gtx.Ops) - gtx := gtx - gtx.Constraints = Constraints{ - Min: maxSZ, Max: gtx.Constraints.Max, - } - dims := w.widget(gtx) + cgtx.Constraints.Min = maxSZ + dims := w.widget(cgtx) call := macro.Stop() if w := dims.Size.X; w > maxSZ.X { maxSZ.X = w @@ -107,10 +104,9 @@ func (s Stack) Layout(gtx Context, children ...StackChild) Dimensions { case SW, S, SE: p.Y = maxSZ.Y - sz.Y } - stack := op.Push(gtx.Ops) - op.Offset(FPt(p)).Add(gtx.Ops) + trans := op.Offset(FPt(p)).Push(gtx.Ops) ch.call.Add(gtx.Ops) - stack.Pop() + trans.Pop() if baseline == 0 { if b := ch.dims.Baseline; b != 0 { baseline = b + maxSZ.Y - sz.Y - p.Y |