mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 18:35:34 +00:00
layout: added Axis methods
Signed-off-by: pierre <pierre.curto@gmail.com>
This commit is contained in:
+12
-62
@@ -3,8 +3,6 @@
|
|||||||
package layout
|
package layout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
|
||||||
|
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -83,8 +81,8 @@ func Flexed(weight float32, widget Widget) FlexChild {
|
|||||||
func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
|
func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
|
||||||
size := 0
|
size := 0
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
mainMin, mainMax := axisMainConstraint(f.Axis, cs)
|
mainMin, mainMax := f.Axis.mainConstraint(cs)
|
||||||
crossMin, crossMax := axisCrossConstraint(f.Axis, cs)
|
crossMin, crossMax := f.Axis.crossConstraint(cs)
|
||||||
remaining := mainMax
|
remaining := mainMax
|
||||||
var totalWeight float32
|
var totalWeight float32
|
||||||
cgtx := gtx
|
cgtx := gtx
|
||||||
@@ -95,10 +93,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
macro := op.Record(gtx.Ops)
|
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)
|
dims := child.widget(cgtx)
|
||||||
c := macro.Stop()
|
c := macro.Stop()
|
||||||
sz := axisMain(f.Axis, dims.Size)
|
sz := f.Axis.Main(dims.Size)
|
||||||
size += sz
|
size += sz
|
||||||
remaining -= sz
|
remaining -= sz
|
||||||
if remaining < 0 {
|
if remaining < 0 {
|
||||||
@@ -130,10 +128,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
macro := op.Record(gtx.Ops)
|
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)
|
dims := child.widget(cgtx)
|
||||||
c := macro.Stop()
|
c := macro.Stop()
|
||||||
sz := axisMain(f.Axis, dims.Size)
|
sz := f.Axis.Main(dims.Size)
|
||||||
size += sz
|
size += sz
|
||||||
remaining -= sz
|
remaining -= sz
|
||||||
if remaining < 0 {
|
if remaining < 0 {
|
||||||
@@ -145,7 +143,7 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
|
|||||||
var maxCross int
|
var maxCross int
|
||||||
var maxBaseline int
|
var maxBaseline int
|
||||||
for _, child := range children {
|
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
|
maxCross = c
|
||||||
}
|
}
|
||||||
if b := child.dims.Size.Y - child.dims.Baseline; b > maxBaseline {
|
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
|
var cross int
|
||||||
switch f.Alignment {
|
switch f.Alignment {
|
||||||
case End:
|
case End:
|
||||||
cross = maxCross - axisCross(f.Axis, dims.Size)
|
cross = maxCross - f.Axis.Cross(dims.Size)
|
||||||
case Middle:
|
case Middle:
|
||||||
cross = (maxCross - axisCross(f.Axis, dims.Size)) / 2
|
cross = (maxCross - f.Axis.Cross(dims.Size)) / 2
|
||||||
case Baseline:
|
case Baseline:
|
||||||
if f.Axis == Horizontal {
|
if f.Axis == Horizontal {
|
||||||
cross = maxBaseline - b
|
cross = maxBaseline - b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack := op.Push(gtx.Ops)
|
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)
|
child.call.Add(gtx.Ops)
|
||||||
stack.Pop()
|
stack.Pop()
|
||||||
mainSize += axisMain(f.Axis, dims.Size)
|
mainSize += f.Axis.Main(dims.Size)
|
||||||
if i < len(children)-1 {
|
if i < len(children)-1 {
|
||||||
switch f.Spacing {
|
switch f.Spacing {
|
||||||
case SpaceEvenly:
|
case SpaceEvenly:
|
||||||
@@ -215,58 +213,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
|
|||||||
mainSize += space / (len(children) * 2)
|
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}
|
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 {
|
func (s Spacing) String() string {
|
||||||
switch s {
|
switch s {
|
||||||
case SpaceEnd:
|
case SpaceEnd:
|
||||||
|
|||||||
@@ -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 {
|
func (a Axis) String() string {
|
||||||
switch a {
|
switch a {
|
||||||
case Horizontal:
|
case Horizontal:
|
||||||
|
|||||||
+15
-15
@@ -98,8 +98,8 @@ func (l *List) init(gtx Context, len int) {
|
|||||||
// 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 {
|
||||||
l.init(gtx, len)
|
l.init(gtx, len)
|
||||||
crossMin, crossMax := axisCrossConstraint(l.Axis, gtx.Constraints)
|
crossMin, crossMax := l.Axis.crossConstraint(gtx.Constraints)
|
||||||
gtx.Constraints = axisConstraints(l.Axis, 0, inf, crossMin, crossMax)
|
gtx.Constraints = l.Axis.constraints(0, inf, crossMin, crossMax)
|
||||||
macro := op.Record(gtx.Ops)
|
macro := op.Record(gtx.Ops)
|
||||||
for l.next(); l.more(); l.next() {
|
for l.next(); l.more(); l.next() {
|
||||||
child := op.Record(gtx.Ops)
|
child := op.Record(gtx.Ops)
|
||||||
@@ -155,7 +155,7 @@ func (l *List) more() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *List) nextDir() iterationDir {
|
func (l *List) nextDir() iterationDir {
|
||||||
_, vsize := axisMainConstraint(l.Axis, l.cs)
|
_, vsize := l.Axis.mainConstraint(l.cs)
|
||||||
last := l.Position.First + len(l.children)
|
last := l.Position.First + len(l.children)
|
||||||
// Clamp offset.
|
// Clamp offset.
|
||||||
if l.maxSize-l.Position.Offset < vsize && last == l.len {
|
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.
|
// End the current child by specifying its dimensions.
|
||||||
func (l *List) end(dims Dimensions, call op.CallOp) {
|
func (l *List) end(dims Dimensions, call op.CallOp) {
|
||||||
child := scrollChild{dims.Size, call}
|
child := scrollChild{dims.Size, call}
|
||||||
mainSize := axisMain(l.Axis, child.size)
|
mainSize := l.Axis.Main(child.size)
|
||||||
l.maxSize += mainSize
|
l.maxSize += mainSize
|
||||||
switch l.dir {
|
switch l.dir {
|
||||||
case iterateForward:
|
case iterateForward:
|
||||||
@@ -200,12 +200,12 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
|
|||||||
if l.more() {
|
if l.more() {
|
||||||
panic("unfinished child")
|
panic("unfinished child")
|
||||||
}
|
}
|
||||||
mainMin, mainMax := axisMainConstraint(l.Axis, l.cs)
|
mainMin, mainMax := l.Axis.mainConstraint(l.cs)
|
||||||
children := l.children
|
children := l.children
|
||||||
// Skip invisible children
|
// Skip invisible children
|
||||||
for len(children) > 0 {
|
for len(children) > 0 {
|
||||||
sz := children[0].size
|
sz := children[0].size
|
||||||
mainSize := axisMain(l.Axis, sz)
|
mainSize := l.Axis.Main(sz)
|
||||||
if l.Position.Offset <= mainSize {
|
if l.Position.Offset <= mainSize {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -217,10 +217,10 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
|
|||||||
var maxCross int
|
var maxCross int
|
||||||
for i, child := range children {
|
for i, child := range children {
|
||||||
sz := child.size
|
sz := child.size
|
||||||
if c := axisCross(l.Axis, sz); c > maxCross {
|
if c := l.Axis.Cross(sz); c > maxCross {
|
||||||
maxCross = c
|
maxCross = c
|
||||||
}
|
}
|
||||||
size += axisMain(l.Axis, sz)
|
size += l.Axis.Main(sz)
|
||||||
if size >= mainMax {
|
if size >= mainMax {
|
||||||
children = children[:i+1]
|
children = children[:i+1]
|
||||||
break
|
break
|
||||||
@@ -236,11 +236,11 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
|
|||||||
var cross int
|
var cross int
|
||||||
switch l.Alignment {
|
switch l.Alignment {
|
||||||
case End:
|
case End:
|
||||||
cross = maxCross - axisCross(l.Axis, sz)
|
cross = maxCross - l.Axis.Cross(sz)
|
||||||
case Middle:
|
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
|
max := childSize + pos
|
||||||
if max > mainMax {
|
if max > mainMax {
|
||||||
max = mainMax
|
max = mainMax
|
||||||
@@ -250,12 +250,12 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
|
|||||||
min = 0
|
min = 0
|
||||||
}
|
}
|
||||||
r := image.Rectangle{
|
r := image.Rectangle{
|
||||||
Min: axisPoint(l.Axis, min, -inf),
|
Min: l.Axis.point(min, -inf),
|
||||||
Max: axisPoint(l.Axis, max, inf),
|
Max: l.Axis.point(max, inf),
|
||||||
}
|
}
|
||||||
stack := op.Push(ops)
|
stack := op.Push(ops)
|
||||||
clip.Rect(r).Add(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)
|
child.call.Add(ops)
|
||||||
stack.Pop()
|
stack.Pop()
|
||||||
pos += childSize
|
pos += childSize
|
||||||
@@ -272,7 +272,7 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
|
|||||||
if pos > mainMax {
|
if pos > mainMax {
|
||||||
pos = mainMax
|
pos = mainMax
|
||||||
}
|
}
|
||||||
dims := axisPoint(l.Axis, pos, maxCross)
|
dims := l.Axis.point(pos, maxCross)
|
||||||
call := macro.Stop()
|
call := macro.Stop()
|
||||||
defer op.Push(ops).Pop()
|
defer op.Push(ops).Pop()
|
||||||
pointer.Rect(image.Rectangle{Max: dims}).Add(ops)
|
pointer.Rect(image.Rectangle{Max: dims}).Add(ops)
|
||||||
|
|||||||
Reference in New Issue
Block a user