layout: refactor List.Layout and related functions

I found the interplay of List's Layout/init/next/more/end methods
somewhat confusing and hard to reason about, so I refactored them.

Signed-off-by: Larry Clapp <larry@theclapp.org>
This commit is contained in:
Larry Clapp
2020-07-12 15:23:32 -04:00
committed by Elias Naur
parent 773939fe1d
commit a54b460595
+13 -18
View File
@@ -30,8 +30,6 @@ type List struct {
Alignment Alignment Alignment Alignment
ctx Context ctx Context
macro op.MacroOp
child op.MacroOp
scroll gesture.Scroll scroll gesture.Scroll
scrollDelta int scrollDelta int
@@ -95,20 +93,21 @@ func (l *List) init(gtx Context, len int) {
l.Position.Offset = 0 l.Position.Offset = 0
l.Position.First = len l.Position.First = len
} }
l.macro = op.Record(gtx.Ops)
l.next()
} }
// Layout the List. // Layout the List.
func (l *List) Layout(gtx Context, len int, w ListElement) Dimensions { func (l *List) Layout(gtx Context, len int, w ListElement) Dimensions {
for l.init(gtx, len); l.more(); l.next() { l.init(gtx, len)
crossMin, crossMax := axisCrossConstraint(l.Axis, l.ctx.Constraints) crossMin, crossMax := axisCrossConstraint(l.Axis, gtx.Constraints)
cs := axisConstraints(l.Axis, 0, inf, crossMin, crossMax) gtx.Constraints = axisConstraints(l.Axis, 0, inf, crossMin, crossMax)
i := l.index() macro := op.Record(gtx.Ops)
gtx.Constraints = cs for l.next(); l.more(); l.next() {
l.end(w(gtx, i)) child := op.Record(gtx.Ops)
dims := w(gtx, l.index())
call := child.Stop()
l.end(dims, call)
} }
return l.layout() return l.layout(macro)
} }
func (l *List) scrollToEnd() bool { func (l *List) scrollToEnd() bool {
@@ -136,9 +135,6 @@ func (l *List) next() {
l.Position.Offset += l.scrollDelta l.Position.Offset += l.scrollDelta
l.dir = l.nextDir() l.dir = l.nextDir()
} }
if l.more() {
l.child = op.Record(l.ctx.Ops)
}
} }
// index is current child's position in the underlying list. // index is current child's position in the underlying list.
@@ -180,8 +176,7 @@ func (l *List) nextDir() iterationDir {
} }
// End the current child by specifying its dimensions. // End the current child by specifying its dimensions.
func (l *List) end(dims Dimensions) { func (l *List) end(dims Dimensions, call op.CallOp) {
call := l.child.Stop()
child := scrollChild{dims.Size, call} child := scrollChild{dims.Size, call}
mainSize := axisMain(l.Axis, child.size) mainSize := axisMain(l.Axis, child.size)
l.maxSize += mainSize l.maxSize += mainSize
@@ -199,7 +194,7 @@ func (l *List) end(dims Dimensions) {
} }
// Layout the List and return its dimensions. // Layout the List and return its dimensions.
func (l *List) layout() Dimensions { func (l *List) layout(macro op.MacroOp) Dimensions {
if l.more() { if l.more() {
panic("unfinished child") panic("unfinished child")
} }
@@ -277,7 +272,7 @@ func (l *List) layout() Dimensions {
pos = mainMax pos = mainMax
} }
dims := axisPoint(l.Axis, pos, maxCross) dims := axisPoint(l.Axis, pos, maxCross)
call := l.macro.Stop() call := macro.Stop()
defer op.Push(l.ctx.Ops).Pop() defer op.Push(l.ctx.Ops).Pop()
pointer.Rect(image.Rectangle{Max: dims}).Add(ops) pointer.Rect(image.Rectangle{Max: dims}).Add(ops)
l.scroll.Add(ops) l.scroll.Add(ops)