aboutsummaryrefslogtreecommitdiff
path: root/vendor/gioui.org/layout
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gioui.org/layout')
-rw-r--r--vendor/gioui.org/layout/context.go20
-rw-r--r--vendor/gioui.org/layout/doc.go2
-rw-r--r--vendor/gioui.org/layout/flex.go106
-rw-r--r--vendor/gioui.org/layout/layout.go126
-rw-r--r--vendor/gioui.org/layout/list.go139
-rw-r--r--vendor/gioui.org/layout/stack.go18
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