mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-04 17:05:38 +00:00
layout,widget: transpose Constraints to use image.Points for limits
Instead of
type Contraints struct {
Width, Height Constraint
}
use
type Constraints struct {
Min, Max image.Point
}
which leads to simpler use. For example, the Min method is trivally replaced by
the field, and the RigidConstraints constructor is no longer a net win.
API Change. Rewrites:
gofmt -r 'gtx.Constraints.Min() -> gtx.Constraints.Min'
gofmt -r 'gtx.Constraints.Width.Min -> gtx.Constraints.Min.X'
gofmt -r 'gtx.Constraints.Height.Min -> gtx.Constraints.Min.Y'
gofmt -r 'gtx.Constraints.Height.Max -> gtx.Constraints.Max.Y'
gofmt -r 'gtx.Constraints.Width.Max -> gtx.Constraints.Max.X'
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+1
-1
@@ -45,7 +45,7 @@ func ctxLayout(gtx *Context, cs Constraints, w Widget) Dimensions {
|
|||||||
// Reset the context. The constraints' minimum and maximum values are
|
// Reset the context. The constraints' minimum and maximum values are
|
||||||
// set to the size.
|
// set to the size.
|
||||||
func (c *Context) Reset(q event.Queue, cfg system.Config, size image.Point) {
|
func (c *Context) Reset(q event.Queue, cfg system.Config, size image.Point) {
|
||||||
c.Constraints = RigidConstraints(size)
|
c.Constraints = Constraints{Min: size, Max: size}
|
||||||
c.Dimensions = Dimensions{}
|
c.Dimensions = Dimensions{}
|
||||||
c.cfg = cfg
|
c.cfg = cfg
|
||||||
c.queue = q
|
c.queue = q
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ func ExampleInset() {
|
|||||||
gtx := new(layout.Context)
|
gtx := new(layout.Context)
|
||||||
gtx.Reset(nil, nil, image.Point{X: 100, Y: 100})
|
gtx.Reset(nil, nil, image.Point{X: 100, Y: 100})
|
||||||
// Loose constraints with no minimal size.
|
// Loose constraints with no minimal size.
|
||||||
gtx.Constraints.Width.Min = 0
|
gtx.Constraints.Min = image.Point{}
|
||||||
gtx.Constraints.Height.Min = 0
|
|
||||||
|
|
||||||
// Inset all edges by 10.
|
// Inset all edges by 10.
|
||||||
inset := layout.UniformInset(unit.Dp(10))
|
inset := layout.UniformInset(unit.Dp(10))
|
||||||
@@ -55,26 +54,25 @@ func ExampleFlex() {
|
|||||||
layout.Flex{}.Layout(gtx,
|
layout.Flex{}.Layout(gtx,
|
||||||
// Rigid 10x10 widget.
|
// Rigid 10x10 widget.
|
||||||
layout.Rigid(func() {
|
layout.Rigid(func() {
|
||||||
fmt.Printf("Rigid: %v\n", gtx.Constraints.Width)
|
fmt.Printf("Rigid: %v\n", gtx.Constraints)
|
||||||
layoutWidget(gtx, 10, 10)
|
layoutWidget(gtx, 10, 10)
|
||||||
}),
|
}),
|
||||||
// Child with 50% space allowance.
|
// Child with 50% space allowance.
|
||||||
layout.Flexed(0.5, func() {
|
layout.Flexed(0.5, func() {
|
||||||
fmt.Printf("50%%: %v\n", gtx.Constraints.Width)
|
fmt.Printf("50%%: %v\n", gtx.Constraints)
|
||||||
layoutWidget(gtx, 10, 10)
|
layoutWidget(gtx, 10, 10)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// Rigid: {0 100}
|
// Rigid: {(0,100) (100,100)}
|
||||||
// 50%: {45 45}
|
// 50%: {(45,100) (45,100)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleStack() {
|
func ExampleStack() {
|
||||||
gtx := new(layout.Context)
|
gtx := new(layout.Context)
|
||||||
gtx.Reset(nil, nil, image.Point{X: 100, Y: 100})
|
gtx.Reset(nil, nil, image.Point{X: 100, Y: 100})
|
||||||
gtx.Constraints.Width.Min = 0
|
gtx.Constraints.Min = image.Point{}
|
||||||
gtx.Constraints.Height.Min = 0
|
|
||||||
|
|
||||||
layout.Stack{}.Layout(gtx,
|
layout.Stack{}.Layout(gtx,
|
||||||
// Force widget to the same size as the second.
|
// Force widget to the same size as the second.
|
||||||
@@ -89,7 +87,7 @@ func ExampleStack() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// Expand: {{50 100} {50 100}}
|
// Expand: {(50,50) (100,100)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleList() {
|
func ExampleList() {
|
||||||
|
|||||||
+22
-21
@@ -83,12 +83,13 @@ func (f Flex) Layout(gtx *Context, children ...FlexChild) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
mainc := axisMainConstraint(f.Axis, cs)
|
_, mainMax := axisMainConstraint(f.Axis, cs)
|
||||||
mainMax := mainc.Max - size
|
mainMax -= size
|
||||||
if mainMax < 0 {
|
if mainMax < 0 {
|
||||||
mainMax = 0
|
mainMax = 0
|
||||||
}
|
}
|
||||||
cs = axisConstraints(f.Axis, Constraint{Max: mainMax}, axisCrossConstraint(f.Axis, cs))
|
crossMin, crossMax := axisCrossConstraint(f.Axis, cs)
|
||||||
|
cs = axisConstraints(f.Axis, 0, mainMax, crossMin, crossMax)
|
||||||
var m op.MacroOp
|
var m op.MacroOp
|
||||||
m.Record(gtx.Ops)
|
m.Record(gtx.Ops)
|
||||||
dims := ctxLayout(gtx, cs, child.widget)
|
dims := ctxLayout(gtx, cs, child.widget)
|
||||||
@@ -107,21 +108,21 @@ func (f Flex) Layout(gtx *Context, children ...FlexChild) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
mainc := axisMainConstraint(f.Axis, cs)
|
_, mainMax := axisMainConstraint(f.Axis, cs)
|
||||||
var flexSize int
|
var flexSize int
|
||||||
if mainc.Max > size {
|
if mainMax > size {
|
||||||
flexSize = mainc.Max - rigidSize
|
flexSize = mainMax - rigidSize
|
||||||
// Apply weight and add any leftover fraction from a
|
// Apply weight and add any leftover fraction from a
|
||||||
// previous Flexed.
|
// previous Flexed.
|
||||||
childSize := float32(flexSize)*child.weight + fraction
|
childSize := float32(flexSize)*child.weight + fraction
|
||||||
flexSize = int(childSize + .5)
|
flexSize = int(childSize + .5)
|
||||||
fraction = childSize - float32(flexSize)
|
fraction = childSize - float32(flexSize)
|
||||||
if max := mainc.Max - size; flexSize > max {
|
if max := mainMax - size; flexSize > max {
|
||||||
flexSize = max
|
flexSize = max
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
submainc := Constraint{Min: flexSize, Max: flexSize}
|
crossMin, crossMax := axisCrossConstraint(f.Axis, cs)
|
||||||
cs = axisConstraints(f.Axis, submainc, axisCrossConstraint(f.Axis, cs))
|
cs = axisConstraints(f.Axis, flexSize, flexSize, crossMin, crossMax)
|
||||||
var m op.MacroOp
|
var m op.MacroOp
|
||||||
m.Record(gtx.Ops)
|
m.Record(gtx.Ops)
|
||||||
dims := ctxLayout(gtx, cs, child.widget)
|
dims := ctxLayout(gtx, cs, child.widget)
|
||||||
@@ -142,10 +143,10 @@ func (f Flex) Layout(gtx *Context, children ...FlexChild) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
mainc := axisMainConstraint(f.Axis, cs)
|
mainMin, _ := axisMainConstraint(f.Axis, cs)
|
||||||
var space int
|
var space int
|
||||||
if mainc.Min > size {
|
if mainMin > size {
|
||||||
space = mainc.Min - size
|
space = mainMin - size
|
||||||
}
|
}
|
||||||
var mainSize int
|
var mainSize int
|
||||||
switch f.Spacing {
|
switch f.Spacing {
|
||||||
@@ -227,27 +228,27 @@ func axisCross(a Axis, sz image.Point) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func axisMainConstraint(a Axis, cs Constraints) Constraint {
|
func axisMainConstraint(a Axis, cs Constraints) (int, int) {
|
||||||
if a == Horizontal {
|
if a == Horizontal {
|
||||||
return cs.Width
|
return cs.Min.X, cs.Max.X
|
||||||
} else {
|
} else {
|
||||||
return cs.Height
|
return cs.Min.Y, cs.Max.Y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func axisCrossConstraint(a Axis, cs Constraints) Constraint {
|
func axisCrossConstraint(a Axis, cs Constraints) (int, int) {
|
||||||
if a == Horizontal {
|
if a == Horizontal {
|
||||||
return cs.Height
|
return cs.Min.Y, cs.Max.Y
|
||||||
} else {
|
} else {
|
||||||
return cs.Width
|
return cs.Min.X, cs.Max.X
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func axisConstraints(a Axis, mainc, crossc Constraint) Constraints {
|
func axisConstraints(a Axis, mainMin, mainMax, crossMin, crossMax int) Constraints {
|
||||||
if a == Horizontal {
|
if a == Horizontal {
|
||||||
return Constraints{Width: mainc, Height: crossc}
|
return Constraints{Min: image.Pt(mainMin, crossMin), Max: image.Pt(mainMax, crossMax)}
|
||||||
} else {
|
} else {
|
||||||
return Constraints{Width: crossc, Height: mainc}
|
return Constraints{Min: image.Pt(crossMin, mainMin), Max: image.Pt(crossMax, mainMax)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-51
@@ -9,17 +9,9 @@ import (
|
|||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Constraints represent a set of acceptable ranges for
|
// Constraints represent the minimum and maximum size of a widget.
|
||||||
// a widget's width and height.
|
|
||||||
type Constraints struct {
|
type Constraints struct {
|
||||||
Width Constraint
|
Min, Max image.Point
|
||||||
Height Constraint
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constraint is a range of acceptable sizes in a single
|
|
||||||
// dimension.
|
|
||||||
type Constraint struct {
|
|
||||||
Min, Max int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dimensions are the resolved size and baseline for a widget.
|
// Dimensions are the resolved size and baseline for a widget.
|
||||||
@@ -66,33 +58,21 @@ const (
|
|||||||
Vertical
|
Vertical
|
||||||
)
|
)
|
||||||
|
|
||||||
// Constrain a value to the range [Min; Max].
|
// Constrain a size so each dimension is in the range [min;max].
|
||||||
func (c Constraint) Constrain(v int) int {
|
|
||||||
if v < c.Min {
|
|
||||||
return c.Min
|
|
||||||
} else if v > c.Max {
|
|
||||||
return c.Max
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constrain a size to the Width and Height ranges.
|
|
||||||
func (c Constraints) Constrain(size image.Point) image.Point {
|
func (c Constraints) Constrain(size image.Point) image.Point {
|
||||||
return image.Point{X: c.Width.Constrain(size.X), Y: c.Height.Constrain(size.Y)}
|
if min := c.Min.X; size.X < min {
|
||||||
}
|
size.X = min
|
||||||
|
|
||||||
// Min returns the smallest dimensions that satisfy the constraints.
|
|
||||||
func (c Constraints) Min() image.Point {
|
|
||||||
return image.Point{X: c.Width.Min, Y: c.Height.Min}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RigidConstraints returns the constraints that can only be
|
|
||||||
// satisfied by the given dimensions.
|
|
||||||
func RigidConstraints(size image.Point) Constraints {
|
|
||||||
return Constraints{
|
|
||||||
Width: Constraint{Min: size.X, Max: size.X},
|
|
||||||
Height: Constraint{Min: size.Y, Max: size.Y},
|
|
||||||
}
|
}
|
||||||
|
if min := c.Min.Y; size.Y < min {
|
||||||
|
size.Y = min
|
||||||
|
}
|
||||||
|
if max := c.Max.X; size.X > max {
|
||||||
|
size.X = max
|
||||||
|
}
|
||||||
|
if max := c.Max.Y; size.Y > max {
|
||||||
|
size.Y = max
|
||||||
|
}
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inset adds space around a widget.
|
// Inset adds space around a widget.
|
||||||
@@ -107,23 +87,23 @@ func (in Inset) Layout(gtx *Context, w Widget) {
|
|||||||
bottom := gtx.Px(in.Bottom)
|
bottom := gtx.Px(in.Bottom)
|
||||||
left := gtx.Px(in.Left)
|
left := gtx.Px(in.Left)
|
||||||
mcs := gtx.Constraints
|
mcs := gtx.Constraints
|
||||||
mcs.Width.Max -= left + right
|
mcs.Max.X -= left + right
|
||||||
if mcs.Width.Max < 0 {
|
if mcs.Max.X < 0 {
|
||||||
left = 0
|
left = 0
|
||||||
right = 0
|
right = 0
|
||||||
mcs.Width.Max = 0
|
mcs.Max.X = 0
|
||||||
}
|
}
|
||||||
if mcs.Width.Min > mcs.Width.Max {
|
if mcs.Min.X > mcs.Max.X {
|
||||||
mcs.Width.Min = mcs.Width.Max
|
mcs.Min.X = mcs.Max.X
|
||||||
}
|
}
|
||||||
mcs.Height.Max -= top + bottom
|
mcs.Max.Y -= top + bottom
|
||||||
if mcs.Height.Max < 0 {
|
if mcs.Max.Y < 0 {
|
||||||
bottom = 0
|
bottom = 0
|
||||||
top = 0
|
top = 0
|
||||||
mcs.Height.Max = 0
|
mcs.Max.Y = 0
|
||||||
}
|
}
|
||||||
if mcs.Height.Min > mcs.Height.Max {
|
if mcs.Min.Y > mcs.Max.Y {
|
||||||
mcs.Height.Min = mcs.Height.Max
|
mcs.Min.Y = mcs.Max.Y
|
||||||
}
|
}
|
||||||
var stack op.StackOp
|
var stack op.StackOp
|
||||||
stack.Push(gtx.Ops)
|
stack.Push(gtx.Ops)
|
||||||
@@ -148,16 +128,15 @@ func (a Direction) Layout(gtx *Context, w Widget) {
|
|||||||
macro.Record(gtx.Ops)
|
macro.Record(gtx.Ops)
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
mcs := cs
|
mcs := cs
|
||||||
mcs.Width.Min = 0
|
mcs.Min = image.Point{}
|
||||||
mcs.Height.Min = 0
|
|
||||||
dims := ctxLayout(gtx, mcs, w)
|
dims := ctxLayout(gtx, mcs, w)
|
||||||
macro.Stop()
|
macro.Stop()
|
||||||
sz := dims.Size
|
sz := dims.Size
|
||||||
if sz.X < cs.Width.Min {
|
if sz.X < cs.Min.X {
|
||||||
sz.X = cs.Width.Min
|
sz.X = cs.Min.X
|
||||||
}
|
}
|
||||||
if sz.Y < cs.Height.Min {
|
if sz.Y < cs.Min.Y {
|
||||||
sz.Y = cs.Height.Min
|
sz.Y = cs.Min.Y
|
||||||
}
|
}
|
||||||
var p image.Point
|
var p image.Point
|
||||||
switch Direction(a) {
|
switch Direction(a) {
|
||||||
|
|||||||
+16
-9
@@ -103,7 +103,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) {
|
func (l *List) Layout(gtx *Context, len int, w ListElement) {
|
||||||
for l.init(gtx, len); l.more(); l.next() {
|
for l.init(gtx, len); l.more(); l.next() {
|
||||||
cs := axisConstraints(l.Axis, Constraint{Max: inf}, axisCrossConstraint(l.Axis, l.ctx.Constraints))
|
crossMin, crossMax := axisCrossConstraint(l.Axis, l.ctx.Constraints)
|
||||||
|
cs := axisConstraints(l.Axis, 0, inf, crossMin, crossMax)
|
||||||
i := l.index()
|
i := l.index()
|
||||||
l.end(ctxLayout(gtx, cs, func() {
|
l.end(ctxLayout(gtx, cs, func() {
|
||||||
w(i)
|
w(i)
|
||||||
@@ -160,7 +161,7 @@ func (l *List) more() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *List) nextDir() iterationDir {
|
func (l *List) nextDir() iterationDir {
|
||||||
vsize := axisMainConstraint(l.Axis, l.ctx.Constraints).Max
|
_, vsize := axisMainConstraint(l.Axis, l.ctx.Constraints)
|
||||||
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 {
|
||||||
@@ -204,7 +205,7 @@ func (l *List) layout() Dimensions {
|
|||||||
if l.more() {
|
if l.more() {
|
||||||
panic("unfinished child")
|
panic("unfinished child")
|
||||||
}
|
}
|
||||||
mainc := axisMainConstraint(l.Axis, l.ctx.Constraints)
|
mainMin, mainMax := axisMainConstraint(l.Axis, l.ctx.Constraints)
|
||||||
children := l.children
|
children := l.children
|
||||||
// Skip invisible children
|
// Skip invisible children
|
||||||
for len(children) > 0 {
|
for len(children) > 0 {
|
||||||
@@ -225,7 +226,7 @@ func (l *List) layout() Dimensions {
|
|||||||
maxCross = c
|
maxCross = c
|
||||||
}
|
}
|
||||||
size += axisMain(l.Axis, sz)
|
size += axisMain(l.Axis, sz)
|
||||||
if size >= mainc.Max {
|
if size >= mainMax {
|
||||||
children = children[:i+1]
|
children = children[:i+1]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -233,7 +234,7 @@ func (l *List) layout() Dimensions {
|
|||||||
ops := l.ctx.Ops
|
ops := l.ctx.Ops
|
||||||
pos := -l.Position.Offset
|
pos := -l.Position.Offset
|
||||||
// ScrollToEnd lists are end aligned.
|
// ScrollToEnd lists are end aligned.
|
||||||
if space := mainc.Max - size; l.ScrollToEnd && space > 0 {
|
if space := mainMax - size; l.ScrollToEnd && space > 0 {
|
||||||
pos += space
|
pos += space
|
||||||
}
|
}
|
||||||
for _, child := range children {
|
for _, child := range children {
|
||||||
@@ -247,8 +248,8 @@ func (l *List) layout() Dimensions {
|
|||||||
}
|
}
|
||||||
childSize := axisMain(l.Axis, sz)
|
childSize := axisMain(l.Axis, sz)
|
||||||
max := childSize + pos
|
max := childSize + pos
|
||||||
if max > mainc.Max {
|
if max > mainMax {
|
||||||
max = mainc.Max
|
max = mainMax
|
||||||
}
|
}
|
||||||
min := pos
|
min := pos
|
||||||
if min < 0 {
|
if min < 0 {
|
||||||
@@ -267,12 +268,18 @@ func (l *List) layout() Dimensions {
|
|||||||
pos += childSize
|
pos += childSize
|
||||||
}
|
}
|
||||||
atStart := l.Position.First == 0 && l.Position.Offset <= 0
|
atStart := l.Position.First == 0 && l.Position.Offset <= 0
|
||||||
atEnd := l.Position.First+len(children) == l.len && mainc.Max >= pos
|
atEnd := l.Position.First+len(children) == l.len && mainMax >= pos
|
||||||
if atStart && l.scrollDelta < 0 || atEnd && l.scrollDelta > 0 {
|
if atStart && l.scrollDelta < 0 || atEnd && l.scrollDelta > 0 {
|
||||||
l.scroll.Stop()
|
l.scroll.Stop()
|
||||||
}
|
}
|
||||||
l.Position.BeforeEnd = !atEnd
|
l.Position.BeforeEnd = !atEnd
|
||||||
dims := axisPoint(l.Axis, mainc.Constrain(pos), maxCross)
|
if pos < mainMin {
|
||||||
|
pos = mainMin
|
||||||
|
}
|
||||||
|
if pos > mainMax {
|
||||||
|
pos = mainMax
|
||||||
|
}
|
||||||
|
dims := axisPoint(l.Axis, pos, maxCross)
|
||||||
l.macro.Stop()
|
l.macro.Stop()
|
||||||
pointer.Rect(image.Rectangle{Max: dims}).Add(ops)
|
pointer.Rect(image.Rectangle{Max: dims}).Add(ops)
|
||||||
l.scroll.Add(ops)
|
l.scroll.Add(ops)
|
||||||
|
|||||||
+2
-4
@@ -54,8 +54,7 @@ func (s Stack) Layout(gtx *Context, children ...StackChild) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
cs.Width.Min = 0
|
cs.Min = image.Pt(0, 0)
|
||||||
cs.Height.Min = 0
|
|
||||||
var m op.MacroOp
|
var m op.MacroOp
|
||||||
m.Record(gtx.Ops)
|
m.Record(gtx.Ops)
|
||||||
dims := ctxLayout(gtx, cs, w.widget)
|
dims := ctxLayout(gtx, cs, w.widget)
|
||||||
@@ -77,8 +76,7 @@ func (s Stack) Layout(gtx *Context, children ...StackChild) {
|
|||||||
var m op.MacroOp
|
var m op.MacroOp
|
||||||
m.Record(gtx.Ops)
|
m.Record(gtx.Ops)
|
||||||
cs := Constraints{
|
cs := Constraints{
|
||||||
Width: Constraint{Min: maxSZ.X, Max: gtx.Constraints.Width.Max},
|
Min: maxSZ, Max: gtx.Constraints.Max,
|
||||||
Height: Constraint{Min: maxSZ.Y, Max: gtx.Constraints.Height.Max},
|
|
||||||
}
|
}
|
||||||
dims := ctxLayout(gtx, cs, w.widget)
|
dims := ctxLayout(gtx, cs, w.widget)
|
||||||
m.Stop()
|
m.Stop()
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import (
|
|||||||
func TestStack(t *testing.T) {
|
func TestStack(t *testing.T) {
|
||||||
var gtx Context
|
var gtx Context
|
||||||
gtx.Reset(nil, nil, image.Point{X: 100, Y: 100})
|
gtx.Reset(nil, nil, image.Point{X: 100, Y: 100})
|
||||||
gtx.Constraints.Width.Min = 0
|
gtx.Constraints.Min = image.Point{}
|
||||||
gtx.Constraints.Height.Min = 0
|
|
||||||
exp := image.Point{X: 60, Y: 70}
|
exp := image.Point{X: 60, Y: 70}
|
||||||
Stack{Alignment: Center}.Layout(>x,
|
Stack{Alignment: Center}.Layout(>x,
|
||||||
Expanded(func() {
|
Expanded(func() {
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ func (b *Clickable) Layout(gtx *layout.Context) {
|
|||||||
b.Update(gtx)
|
b.Update(gtx)
|
||||||
var st op.StackOp
|
var st op.StackOp
|
||||||
st.Push(gtx.Ops)
|
st.Push(gtx.Ops)
|
||||||
pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min()}).Add(gtx.Ops)
|
pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Add(gtx.Ops)
|
||||||
b.click.Add(gtx.Ops)
|
b.click.Add(gtx.Ops)
|
||||||
st.Pop()
|
st.Pop()
|
||||||
for len(b.history) > 0 {
|
for len(b.history) > 0 {
|
||||||
|
|||||||
+1
-1
@@ -244,7 +244,7 @@ func (e *Editor) Layout(gtx *layout.Context, sh text.Shaper, font text.Font, siz
|
|||||||
e.font = font
|
e.font = font
|
||||||
e.textSize = textSize
|
e.textSize = textSize
|
||||||
}
|
}
|
||||||
maxWidth := gtx.Constraints.Width.Max
|
maxWidth := gtx.Constraints.Max.X
|
||||||
if e.SingleLine {
|
if e.SingleLine {
|
||||||
maxWidth = inf
|
maxWidth = inf
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ func (im Image) Layout(gtx *layout.Context) {
|
|||||||
wf, hf := float32(size.X), float32(size.Y)
|
wf, hf := float32(size.X), float32(size.Y)
|
||||||
w, h := gtx.Px(unit.Dp(wf*scale)), gtx.Px(unit.Dp(hf*scale))
|
w, h := gtx.Px(unit.Dp(wf*scale)), gtx.Px(unit.Dp(hf*scale))
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
d := image.Point{X: cs.Width.Constrain(w), Y: cs.Height.Constrain(h)}
|
d := cs.Constrain(image.Pt(w, h))
|
||||||
var s op.StackOp
|
var s op.StackOp
|
||||||
s.Push(gtx.Ops)
|
s.Push(gtx.Ops)
|
||||||
clip.Rect{Rect: f32.Rectangle{Max: toPointF(d)}}.Op(gtx.Ops).Add(gtx.Ops)
|
clip.Rect{Rect: f32.Rectangle{Max: toPointF(d)}}.Op(gtx.Ops).Add(gtx.Ops)
|
||||||
|
|||||||
+1
-1
@@ -87,7 +87,7 @@ func (l *lineIterator) Next() (int, int, []text.Glyph, f32.Point, bool) {
|
|||||||
func (l Label) Layout(gtx *layout.Context, s text.Shaper, font text.Font, size unit.Value, txt string) {
|
func (l Label) Layout(gtx *layout.Context, s text.Shaper, font text.Font, size unit.Value, txt string) {
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
textSize := fixed.I(gtx.Px(size))
|
textSize := fixed.I(gtx.Px(size))
|
||||||
lines := s.LayoutString(font, textSize, cs.Width.Max, txt)
|
lines := s.LayoutString(font, textSize, cs.Max.X, txt)
|
||||||
if max := l.MaxLines; max > 0 && len(lines) > max {
|
if max := l.MaxLines; max > 0 && len(lines) > max {
|
||||||
lines = lines[:max]
|
lines = lines[:max]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ func Clickable(gtx *layout.Context, button *widget.Clickable, w layout.Widget) {
|
|||||||
layout.Expanded(func() {
|
layout.Expanded(func() {
|
||||||
clip.Rect{
|
clip.Rect{
|
||||||
Rect: f32.Rectangle{Max: f32.Point{
|
Rect: f32.Rectangle{Max: f32.Point{
|
||||||
X: float32(gtx.Constraints.Width.Min),
|
X: float32(gtx.Constraints.Min.X),
|
||||||
Y: float32(gtx.Constraints.Height.Min),
|
Y: float32(gtx.Constraints.Min.Y),
|
||||||
}},
|
}},
|
||||||
}.Op(gtx.Ops).Add(gtx.Ops)
|
}.Op(gtx.Ops).Add(gtx.Ops)
|
||||||
for _, c := range button.History() {
|
for _, c := range button.History() {
|
||||||
@@ -111,15 +111,14 @@ func (b ButtonStyle) Layout(gtx *layout.Context, button *widget.Clickable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b ButtonLayoutStyle) Layout(gtx *layout.Context, button *widget.Clickable, w layout.Widget) {
|
func (b ButtonLayoutStyle) Layout(gtx *layout.Context, button *widget.Clickable, w layout.Widget) {
|
||||||
hmin := gtx.Constraints.Width.Min
|
min := gtx.Constraints.Min
|
||||||
vmin := gtx.Constraints.Height.Min
|
|
||||||
layout.Stack{Alignment: layout.Center}.Layout(gtx,
|
layout.Stack{Alignment: layout.Center}.Layout(gtx,
|
||||||
layout.Expanded(func() {
|
layout.Expanded(func() {
|
||||||
rr := float32(gtx.Px(b.CornerRadius))
|
rr := float32(gtx.Px(b.CornerRadius))
|
||||||
clip.Rect{
|
clip.Rect{
|
||||||
Rect: f32.Rectangle{Max: f32.Point{
|
Rect: f32.Rectangle{Max: f32.Point{
|
||||||
X: float32(gtx.Constraints.Width.Min),
|
X: float32(gtx.Constraints.Min.X),
|
||||||
Y: float32(gtx.Constraints.Height.Min),
|
Y: float32(gtx.Constraints.Min.Y),
|
||||||
}},
|
}},
|
||||||
NE: rr, NW: rr, SE: rr, SW: rr,
|
NE: rr, NW: rr, SE: rr, SW: rr,
|
||||||
}.Op(gtx.Ops).Add(gtx.Ops)
|
}.Op(gtx.Ops).Add(gtx.Ops)
|
||||||
@@ -129,8 +128,7 @@ func (b ButtonLayoutStyle) Layout(gtx *layout.Context, button *widget.Clickable,
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
layout.Stacked(func() {
|
layout.Stacked(func() {
|
||||||
gtx.Constraints.Width.Min = hmin
|
gtx.Constraints.Min = min
|
||||||
gtx.Constraints.Height.Min = vmin
|
|
||||||
layout.Center.Layout(gtx, func() {
|
layout.Center.Layout(gtx, func() {
|
||||||
b.Inset.Layout(gtx, func() {
|
b.Inset.Layout(gtx, func() {
|
||||||
w()
|
w()
|
||||||
@@ -146,7 +144,7 @@ func (b ButtonLayoutStyle) Layout(gtx *layout.Context, button *widget.Clickable,
|
|||||||
func (b IconButtonStyle) Layout(gtx *layout.Context, button *widget.Clickable) {
|
func (b IconButtonStyle) Layout(gtx *layout.Context, button *widget.Clickable) {
|
||||||
layout.Stack{Alignment: layout.Center}.Layout(gtx,
|
layout.Stack{Alignment: layout.Center}.Layout(gtx,
|
||||||
layout.Expanded(func() {
|
layout.Expanded(func() {
|
||||||
size := gtx.Constraints.Width.Min
|
size := gtx.Constraints.Min.X
|
||||||
sizef := float32(size)
|
sizef := float32(size)
|
||||||
rr := sizef * .5
|
rr := sizef * .5
|
||||||
clip.Rect{
|
clip.Rect{
|
||||||
@@ -171,7 +169,7 @@ func (b IconButtonStyle) Layout(gtx *layout.Context, button *widget.Clickable) {
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
layout.Expanded(func() {
|
layout.Expanded(func() {
|
||||||
pointer.Ellipse(image.Rectangle{Max: gtx.Constraints.Min()}).Add(gtx.Ops)
|
pointer.Ellipse(image.Rectangle{Max: gtx.Constraints.Min}).Add(gtx.Ops)
|
||||||
button.Layout(gtx)
|
button.Layout(gtx)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ func (c *checkable) layout(gtx *layout.Context, checked bool) {
|
|||||||
icon = c.uncheckedStateIcon
|
icon = c.uncheckedStateIcon
|
||||||
}
|
}
|
||||||
|
|
||||||
hmin := gtx.Constraints.Width.Min
|
min := gtx.Constraints.Min
|
||||||
vmin := gtx.Constraints.Height.Min
|
|
||||||
layout.Flex{Alignment: layout.Middle}.Layout(gtx,
|
layout.Flex{Alignment: layout.Middle}.Layout(gtx,
|
||||||
layout.Rigid(func() {
|
layout.Rigid(func() {
|
||||||
layout.Center.Layout(gtx, func() {
|
layout.Center.Layout(gtx, func() {
|
||||||
@@ -51,8 +50,7 @@ func (c *checkable) layout(gtx *layout.Context, checked bool) {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
layout.Rigid(func() {
|
layout.Rigid(func() {
|
||||||
gtx.Constraints.Width.Min = hmin
|
gtx.Constraints.Min = min
|
||||||
gtx.Constraints.Height.Min = vmin
|
|
||||||
layout.W.Layout(gtx, func() {
|
layout.W.Layout(gtx, func() {
|
||||||
layout.UniformInset(unit.Dp(2)).Layout(gtx, func() {
|
layout.UniformInset(unit.Dp(2)).Layout(gtx, func() {
|
||||||
paint.ColorOp{Color: c.Color}.Add(gtx.Ops)
|
paint.ColorOp{Color: c.Color}.Add(gtx.Ops)
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ func (e EditorStyle) Layout(gtx *layout.Context, editor *widget.Editor) {
|
|||||||
tl := widget.Label{Alignment: editor.Alignment}
|
tl := widget.Label{Alignment: editor.Alignment}
|
||||||
tl.Layout(gtx, e.shaper, e.Font, e.TextSize, e.Hint)
|
tl.Layout(gtx, e.shaper, e.Font, e.TextSize, e.Hint)
|
||||||
macro.Stop()
|
macro.Stop()
|
||||||
if w := gtx.Dimensions.Size.X; gtx.Constraints.Width.Min < w {
|
if w := gtx.Dimensions.Size.X; gtx.Constraints.Min.X < w {
|
||||||
gtx.Constraints.Width.Min = w
|
gtx.Constraints.Min.X = w
|
||||||
}
|
}
|
||||||
if h := gtx.Dimensions.Size.Y; gtx.Constraints.Height.Min < h {
|
if h := gtx.Dimensions.Size.Y; gtx.Constraints.Min.Y < h {
|
||||||
gtx.Constraints.Height.Min = h
|
gtx.Constraints.Min.Y = h
|
||||||
}
|
}
|
||||||
editor.Layout(gtx, e.shaper, e.Font, e.TextSize)
|
editor.Layout(gtx, e.shaper, e.Font, e.TextSize)
|
||||||
if editor.Len() > 0 {
|
if editor.Len() > 0 {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (b ProgressBarStyle) Layout(gtx *layout.Context, progress int) {
|
|||||||
progress = 0
|
progress = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
progressBarWidth := float32(gtx.Constraints.Width.Max)
|
progressBarWidth := float32(gtx.Constraints.Max.X)
|
||||||
|
|
||||||
layout.Stack{Alignment: layout.W}.Layout(gtx,
|
layout.Stack{Alignment: layout.W}.Layout(gtx,
|
||||||
layout.Stacked(func() {
|
layout.Stacked(func() {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
package material
|
package material
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
@@ -66,7 +65,7 @@ func argb(c uint32) color.RGBA {
|
|||||||
|
|
||||||
func fill(gtx *layout.Context, col color.RGBA) {
|
func fill(gtx *layout.Context, col color.RGBA) {
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
d := image.Point{X: cs.Width.Min, Y: cs.Height.Min}
|
d := cs.Min
|
||||||
dr := f32.Rectangle{
|
dr := f32.Rectangle{
|
||||||
Max: f32.Point{X: float32(d.X), Y: float32(d.Y)},
|
Max: f32.Point{X: float32(d.X), Y: float32(d.Y)},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user