~eliasnaur/gio-patches

gio: layout: added Axis methods v1 PROPOSED

~pierrec
~pierrec: 1
 layout: added Axis methods

 3 files changed, 78 insertions(+), 77 deletions(-)
#392897 apple.yml success
#392898 freebsd.yml success
#392899 linux.yml success
#392900 openbsd.yml success
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/19463/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH gio] layout: added Axis methods Export this patch

~pierrec
From: pierre <pierre.curto@gmail.com>

Signed-off-by: pierre <pierre.curto@gmail.com>
---
 layout/flex.go   | 74 ++++++++----------------------------------------
 layout/layout.go | 51 +++++++++++++++++++++++++++++++++
 layout/list.go   | 30 ++++++++++----------
 3 files changed, 78 insertions(+), 77 deletions(-)

diff --git a/layout/flex.go b/layout/flex.go
index b01e193..9fe997a 100644
--- a/layout/flex.go
+++ b/layout/flex.go
@@ -3,8 +3,6 @@
package layout

import (
	"image"

	"gioui.org/op"
)

@@ -83,8 +81,8 @@ 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
@@ -95,10 +93,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
			continue
		}
		macro := op.Record(gtx.Ops)
		cgtx.Constraints = axisConstraints(f.Axis, 0, remaining, crossMin, crossMax)
		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.Main(dims.Size)
		size += sz
		remaining -= sz
		if remaining < 0 {
@@ -130,10 +128,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
			}
		}
		macro := op.Record(gtx.Ops)
		cgtx.Constraints = axisConstraints(f.Axis, flexSize, flexSize, crossMin, crossMax)
		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.Main(dims.Size)
		size += sz
		remaining -= sz
		if remaining < 0 {
@@ -145,7 +143,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.Cross(child.dims.Size); c > maxCross {
			maxCross = c
		}
		if b := child.dims.Size.Y - child.dims.Baseline; b > maxBaseline {
@@ -175,19 +173,19 @@ 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.Cross(dims.Size)
		case Middle:
			cross = (maxCross - axisCross(f.Axis, dims.Size)) / 2
			cross = (maxCross - f.Axis.Cross(dims.Size)) / 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)
		op.Offset(FPt(f.Axis.point(mainSize, cross))).Add(gtx.Ops)
		child.call.Add(gtx.Ops)
		stack.Pop()
		mainSize += axisMain(f.Axis, dims.Size)
		mainSize += f.Axis.Main(dims.Size)
		if i < len(children)-1 {
			switch f.Spacing {
			case SpaceEvenly:
@@ -215,58 +213,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
			mainSize += space / (len(children) * 2)
		}
	}
	sz := axisPoint(f.Axis, mainSize, maxCross)
	sz := f.Axis.point(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/layout/layout.go b/layout/layout.go
index d3b7a74..a13d1b0 100644
--- a/layout/layout.go
+++ b/layout/layout.go
@@ -225,6 +225,57 @@ func (a Alignment) String() string {
	}
}

// Main returns the main axis of p.
// I.e. if a is Horizontal, then the returned value is p.X.
func (a Axis) Main(p image.Point) int {
	if a == Horizontal {
		return p.X
	}
	return p.Y
}

// Cross returns the cross axis of p.
// I.e. if a is Horizontal, then the returned value is p.Y.
func (a Axis) Cross(p image.Point) int {
	if a == Horizontal {
		return p.Y
	}
	return p.X
}

// point returns the point having its values set based on the axis.
// I.e. if a is Horizontal, then the returned value is image.Point{X: main, Y: cross}.
func (a Axis) point(main, cross int) image.Point {
	if a == Horizontal {
		return image.Pt(main, cross)
	}
	return image.Pt(cross, main)
}

// 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/layout/list.go b/layout/list.go
index a10b21e..aa6da69 100644
--- a/layout/list.go
+++ b/layout/list.go
@@ -98,8 +98,8 @@ func (l *List) init(gtx Context, len int) {
// Layout the List.
func (l *List) Layout(gtx Context, len int, w ListElement) Dimensions {
	l.init(gtx, len)
	crossMin, crossMax := axisCrossConstraint(l.Axis, gtx.Constraints)
	gtx.Constraints = axisConstraints(l.Axis, 0, inf, crossMin, crossMax)
	crossMin, crossMax := l.Axis.crossConstraint(gtx.Constraints)
	gtx.Constraints = l.Axis.constraints(0, inf, crossMin, crossMax)
	macro := op.Record(gtx.Ops)
	for l.next(); l.more(); l.next() {
		child := op.Record(gtx.Ops)
@@ -155,7 +155,7 @@ func (l *List) more() bool {
}

func (l *List) nextDir() iterationDir {
	_, vsize := axisMainConstraint(l.Axis, l.cs)
	_, 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 {
@@ -178,7 +178,7 @@ func (l *List) nextDir() iterationDir {
// End the current child by specifying its dimensions.
func (l *List) end(dims Dimensions, call op.CallOp) {
	child := scrollChild{dims.Size, call}
	mainSize := axisMain(l.Axis, child.size)
	mainSize := l.Axis.Main(child.size)
	l.maxSize += mainSize
	switch l.dir {
	case iterateForward:
@@ -200,12 +200,12 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
	if l.more() {
		panic("unfinished child")
	}
	mainMin, mainMax := axisMainConstraint(l.Axis, l.cs)
	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)
		mainSize := l.Axis.Main(sz)
		if l.Position.Offset <= mainSize {
			break
		}
@@ -217,10 +217,10 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
	var maxCross int
	for i, child := range children {
		sz := child.size
		if c := axisCross(l.Axis, sz); c > maxCross {
		if c := l.Axis.Cross(sz); c > maxCross {
			maxCross = c
		}
		size += axisMain(l.Axis, sz)
		size += l.Axis.Main(sz)
		if size >= mainMax {
			children = children[:i+1]
			break
@@ -236,11 +236,11 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
		var cross int
		switch l.Alignment {
		case End:
			cross = maxCross - axisCross(l.Axis, sz)
			cross = maxCross - l.Axis.Cross(sz)
		case Middle:
			cross = (maxCross - axisCross(l.Axis, sz)) / 2
			cross = (maxCross - l.Axis.Cross(sz)) / 2
		}
		childSize := axisMain(l.Axis, sz)
		childSize := l.Axis.Main(sz)
		max := childSize + pos
		if max > mainMax {
			max = mainMax
@@ -250,12 +250,12 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
			min = 0
		}
		r := image.Rectangle{
			Min: axisPoint(l.Axis, min, -inf),
			Max: axisPoint(l.Axis, max, inf),
			Min: l.Axis.point(min, -inf),
			Max: l.Axis.point(max, inf),
		}
		stack := op.Push(ops)
		clip.Rect(r).Add(ops)
		op.Offset(FPt(axisPoint(l.Axis, pos, cross))).Add(ops)
		op.Offset(FPt(l.Axis.point(pos, cross))).Add(ops)
		child.call.Add(ops)
		stack.Pop()
		pos += childSize
@@ -272,7 +272,7 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
	if pos > mainMax {
		pos = mainMax
	}
	dims := axisPoint(l.Axis, pos, maxCross)
	dims := l.Axis.point(pos, maxCross)
	call := macro.Stop()
	defer op.Push(ops).Pop()
	pointer.Rect(image.Rectangle{Max: dims}).Add(ops)
-- 
2.26.2
Thank you, merged.

Elias