op: rename StackOp/Push/Pop to StateOp/Save/Load

The semantics were relaxed in a previous commit; this change renames
to operations accordingly.

API change. Use gofmt to adjust your code accordingly:

gofmt -r 'op.Push(a).Pop() -> op.Save(a).Load()'
gofmt -r 'op.Push(a) -> op.Save(a)'
gofmt -r 'v.Pop() -> v.Load()'
gofmt -r 'op.StackOp -> op.StateOp'

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-01-12 20:48:41 +01:00
parent ae2c74ec13
commit d331dd2de8
25 changed files with 177 additions and 177 deletions
+16 -16
View File
@@ -82,13 +82,13 @@ func BenchmarkDrawUI(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
resetOps(gtx) resetOps(gtx)
p := op.Push(gtx.Ops) p := op.Save(gtx.Ops)
off := float32(math.Mod(float64(i)/10, 10)) off := float32(math.Mod(float64(i)/10, 10))
op.Offset(f32.Pt(off, off)).Add(gtx.Ops) op.Offset(f32.Pt(off, off)).Add(gtx.Ops)
drawCore(gtx, th) drawCore(gtx, th)
p.Pop() p.Load()
w.Frame(gtx.Ops) w.Frame(gtx.Ops)
} }
finishBenchmark(b, w) finishBenchmark(b, w)
@@ -104,14 +104,14 @@ func BenchmarkDrawUITransformed(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
resetOps(gtx) resetOps(gtx)
p := op.Push(gtx.Ops) p := op.Save(gtx.Ops)
angle := float32(math.Mod(float64(i)/1000, 0.05)) angle := float32(math.Mod(float64(i)/1000, 0.05))
a := f32.Affine2D{}.Shear(f32.Point{}, angle, angle).Rotate(f32.Point{}, angle) a := f32.Affine2D{}.Shear(f32.Point{}, angle, angle).Rotate(f32.Point{}, angle)
op.Affine(a).Add(gtx.Ops) op.Affine(a).Add(gtx.Ops)
drawCore(gtx, th) drawCore(gtx, th)
p.Pop() p.Load()
w.Frame(gtx.Ops) w.Frame(gtx.Ops)
} }
finishBenchmark(b, w) finishBenchmark(b, w)
@@ -153,7 +153,7 @@ func Benchmark1000CirclesInstanced(b *testing.B) {
func draw1000Circles(gtx layout.Context) { func draw1000Circles(gtx layout.Context) {
ops := gtx.Ops ops := gtx.Ops
for x := 0; x < 100; x++ { for x := 0; x < 100; x++ {
p := op.Push(ops) p := op.Save(ops)
op.Offset(f32.Pt(float32(x*10), 0)).Add(ops) op.Offset(f32.Pt(float32(x*10), 0)).Add(ops)
for y := 0; y < 10; y++ { for y := 0; y < 10; y++ {
paint.FillShape(ops, paint.FillShape(ops,
@@ -162,7 +162,7 @@ func draw1000Circles(gtx layout.Context) {
) )
op.Offset(f32.Pt(0, float32(100))).Add(ops) op.Offset(f32.Pt(0, float32(100))).Add(ops)
} }
p.Pop() p.Load()
} }
} }
@@ -175,16 +175,16 @@ func draw1000CirclesInstanced(gtx layout.Context) {
c := r.Stop() c := r.Stop()
for x := 0; x < 100; x++ { for x := 0; x < 100; x++ {
p := op.Push(ops) p := op.Save(ops)
op.Offset(f32.Pt(float32(x*10), 0)).Add(ops) op.Offset(f32.Pt(float32(x*10), 0)).Add(ops)
for y := 0; y < 10; y++ { for y := 0; y < 10; y++ {
pi := op.Push(ops) pi := op.Save(ops)
paint.ColorOp{Color: color.NRGBA{R: 100 + uint8(x), G: 100 + uint8(y), B: 100, A: 120}}.Add(ops) paint.ColorOp{Color: color.NRGBA{R: 100 + uint8(x), G: 100 + uint8(y), B: 100, A: 120}}.Add(ops)
c.Add(ops) c.Add(ops)
pi.Pop() pi.Load()
op.Offset(f32.Pt(0, float32(100))).Add(ops) op.Offset(f32.Pt(0, float32(100))).Add(ops)
} }
p.Pop() p.Load()
} }
} }
@@ -204,7 +204,7 @@ func drawIndividualShapes(gtx layout.Context, th *material.Theme) chan op.CallOp
ops := &op1 ops := &op1
c := op.Record(ops) c := op.Record(ops)
for x := 0; x < 9; x++ { for x := 0; x < 9; x++ {
p := op.Push(ops) p := op.Save(ops)
op.Offset(f32.Pt(float32(x*50), 0)).Add(ops) op.Offset(f32.Pt(float32(x*50), 0)).Add(ops)
for y := 0; y < 9; y++ { for y := 0; y < 9; y++ {
paint.FillShape(ops, paint.FillShape(ops,
@@ -213,7 +213,7 @@ func drawIndividualShapes(gtx layout.Context, th *material.Theme) chan op.CallOp
) )
op.Offset(f32.Pt(0, float32(50))).Add(ops) op.Offset(f32.Pt(0, float32(50))).Add(ops)
} }
p.Pop() p.Load()
} }
c1 <- c.Stop() c1 <- c.Stop()
}() }()
@@ -235,10 +235,10 @@ func drawShapeInstances(gtx layout.Context, th *material.Theme) chan op.CallOp {
rad := float32(0) rad := float32(0)
for x := 0; x < 20; x++ { for x := 0; x < 20; x++ {
for y := 0; y < 20; y++ { for y := 0; y < 20; y++ {
p := op.Push(ops) p := op.Save(ops)
op.Offset(f32.Pt(float32(x*50+25), float32(y*50+25))).Add(ops) op.Offset(f32.Pt(float32(x*50+25), float32(y*50+25))).Add(ops)
c.Add(ops) c.Add(ops)
p.Pop() p.Load()
rad += math.Pi * 2 / 400 rad += math.Pi * 2 / 400
} }
} }
@@ -256,11 +256,11 @@ func drawText(gtx layout.Context, th *material.Theme) chan op.CallOp {
txt := material.H6(th, "") txt := material.H6(th, "")
for x := 0; x < 40; x++ { for x := 0; x < 40; x++ {
txt.Text = textRows[x] txt.Text = textRows[x]
p := op.Push(ops) p := op.Save(ops)
op.Offset(f32.Pt(float32(0), float32(24*x))).Add(ops) op.Offset(f32.Pt(float32(0), float32(24*x))).Add(ops)
gtx.Ops = ops gtx.Ops = ops
txt.Layout(gtx) txt.Layout(gtx)
p.Pop() p.Load()
} }
c3 <- c.Stop() c3 <- c.Stop()
}() }()
+28 -28
View File
@@ -229,7 +229,7 @@ func TestStrokedPathRoundRound(t *testing.T) {
func TestStrokedPathFlatMiter(t *testing.T) { func TestStrokedPathFlatMiter(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
clip.Stroke{ clip.Stroke{
Path: p, Path: p,
@@ -241,10 +241,10 @@ func TestStrokedPathFlatMiter(t *testing.T) {
}, },
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, red) paint.Fill(o, red)
stk.Pop() stk.Load()
} }
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
clip.Stroke{ clip.Stroke{
Path: p, Path: p,
@@ -253,7 +253,7 @@ func TestStrokedPathFlatMiter(t *testing.T) {
}, },
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, black) paint.Fill(o, black)
stk.Pop() stk.Load()
} }
}, func(r result) { }, func(r result) {
@@ -266,7 +266,7 @@ func TestStrokedPathFlatMiter(t *testing.T) {
func TestStrokedPathFlatMiterInf(t *testing.T) { func TestStrokedPathFlatMiterInf(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
clip.Stroke{ clip.Stroke{
Path: p, Path: p,
@@ -278,10 +278,10 @@ func TestStrokedPathFlatMiterInf(t *testing.T) {
}, },
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, red) paint.Fill(o, red)
stk.Pop() stk.Load()
} }
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
clip.Stroke{ clip.Stroke{
Path: p, Path: p,
@@ -290,7 +290,7 @@ func TestStrokedPathFlatMiterInf(t *testing.T) {
}, },
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, black) paint.Fill(o, black)
stk.Pop() stk.Load()
} }
}, func(r result) { }, func(r result) {
@@ -303,7 +303,7 @@ func TestStrokedPathFlatMiterInf(t *testing.T) {
func TestStrokedPathZeroWidth(t *testing.T) { func TestStrokedPathZeroWidth(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
{ {
stk := op.Push(o) stk := op.Save(o)
p := new(clip.Path) p := new(clip.Path)
p.Begin(o) p.Begin(o)
p.Move(f32.Pt(10, 50)) p.Move(f32.Pt(10, 50))
@@ -316,11 +316,11 @@ func TestStrokedPathZeroWidth(t *testing.T) {
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, black) paint.Fill(o, black)
stk.Pop() stk.Load()
} }
{ {
stk := op.Push(o) stk := op.Save(o)
p := new(clip.Path) p := new(clip.Path)
p.Begin(o) p.Begin(o)
p.Move(f32.Pt(10, 50)) p.Move(f32.Pt(10, 50))
@@ -330,7 +330,7 @@ func TestStrokedPathZeroWidth(t *testing.T) {
}.Op().Add(o) // width=0, disable stroke }.Op().Add(o) // width=0, disable stroke
paint.Fill(o, red) paint.Fill(o, red)
stk.Pop() stk.Load()
} }
}, func(r result) { }, func(r result) {
@@ -344,7 +344,7 @@ func TestStrokedPathZeroWidth(t *testing.T) {
func TestDashedPathFlatCapEllipse(t *testing.T) { func TestDashedPathFlatCapEllipse(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
{ {
stk := op.Push(o) stk := op.Save(o)
p := newEllipsePath(o) p := newEllipsePath(o)
var dash clip.Dash var dash clip.Dash
@@ -367,10 +367,10 @@ func TestDashedPathFlatCapEllipse(t *testing.T) {
o, o,
red, red,
) )
stk.Pop() stk.Load()
} }
{ {
stk := op.Push(o) stk := op.Save(o)
p := newEllipsePath(o) p := newEllipsePath(o)
clip.Stroke{ clip.Stroke{
Path: p, Path: p,
@@ -383,7 +383,7 @@ func TestDashedPathFlatCapEllipse(t *testing.T) {
o, o,
black, black,
) )
stk.Pop() stk.Load()
} }
}, func(r result) { }, func(r result) {
@@ -396,7 +396,7 @@ func TestDashedPathFlatCapEllipse(t *testing.T) {
func TestDashedPathFlatCapZ(t *testing.T) { func TestDashedPathFlatCapZ(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
var dash clip.Dash var dash clip.Dash
dash.Begin(o) dash.Begin(o)
@@ -414,18 +414,18 @@ func TestDashedPathFlatCapZ(t *testing.T) {
Dashes: dash.End(), Dashes: dash.End(),
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, red) paint.Fill(o, red)
stk.Pop() stk.Load()
} }
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
clip.Stroke{ clip.Stroke{
Path: p, Path: p,
Style: clip.StrokeStyle{Width: 2}, Style: clip.StrokeStyle{Width: 2},
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, black) paint.Fill(o, black)
stk.Pop() stk.Load()
} }
}, func(r result) { }, func(r result) {
r.expect(0, 0, colornames.White) r.expect(0, 0, colornames.White)
@@ -438,7 +438,7 @@ func TestDashedPathFlatCapZ(t *testing.T) {
func TestDashedPathFlatCapZNoDash(t *testing.T) { func TestDashedPathFlatCapZNoDash(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
var dash clip.Dash var dash clip.Dash
dash.Begin(o) dash.Begin(o)
@@ -455,16 +455,16 @@ func TestDashedPathFlatCapZNoDash(t *testing.T) {
Dashes: dash.End(), Dashes: dash.End(),
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, red) paint.Fill(o, red)
stk.Pop() stk.Load()
} }
{ {
stk := op.Push(o) stk := op.Save(o)
clip.Stroke{ clip.Stroke{
Path: newZigZagPath(o), Path: newZigZagPath(o),
Style: clip.StrokeStyle{Width: 2}, Style: clip.StrokeStyle{Width: 2},
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, black) paint.Fill(o, black)
stk.Pop() stk.Load()
} }
}, func(r result) { }, func(r result) {
r.expect(0, 0, colornames.White) r.expect(0, 0, colornames.White)
@@ -477,7 +477,7 @@ func TestDashedPathFlatCapZNoDash(t *testing.T) {
func TestDashedPathFlatCapZNoPath(t *testing.T) { func TestDashedPathFlatCapZNoPath(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
{ {
stk := op.Push(o) stk := op.Save(o)
var dash clip.Dash var dash clip.Dash
dash.Begin(o) dash.Begin(o)
dash.Dash(0) dash.Dash(0)
@@ -492,17 +492,17 @@ func TestDashedPathFlatCapZNoPath(t *testing.T) {
Dashes: dash.End(), Dashes: dash.End(),
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, red) paint.Fill(o, red)
stk.Pop() stk.Load()
} }
{ {
stk := op.Push(o) stk := op.Save(o)
p := newZigZagPath(o) p := newZigZagPath(o)
clip.Stroke{ clip.Stroke{
Path: p, Path: p,
Style: clip.StrokeStyle{Width: 2}, Style: clip.StrokeStyle{Width: 2},
}.Op().Add(o) }.Op().Add(o)
paint.Fill(o, black) paint.Fill(o, black)
stk.Pop() stk.Load()
} }
}, func(r result) { }, func(r result) {
r.expect(0, 0, colornames.White) r.expect(0, 0, colornames.White)
+22 -22
View File
@@ -33,26 +33,26 @@ func TestTransformMacro(t *testing.T) {
m2 := op.Record(o) m2 := op.Record(o)
paint.ColorOp{Color: red}.Add(o) paint.ColorOp{Color: red}.Add(o)
// Simulate a draw text call // Simulate a draw text call
stack := op.Push(o) stack := op.Save(o)
op.Offset(f32.Pt(0, 10)).Add(o) op.Offset(f32.Pt(0, 10)).Add(o)
// Apply the clip-path. // Apply the clip-path.
c.Add(o) c.Add(o)
paint.PaintOp{}.Add(o) paint.PaintOp{}.Add(o)
stack.Pop() stack.Load()
c2 := m2.Stop() c2 := m2.Stop()
// Call each of them in a transform // Call each of them in a transform
s1 := op.Push(o) s1 := op.Save(o)
op.Offset(f32.Pt(0, 0)).Add(o) op.Offset(f32.Pt(0, 0)).Add(o)
c1.Add(o) c1.Add(o)
s1.Pop() s1.Load()
s2 := op.Push(o) s2 := op.Save(o)
op.Offset(f32.Pt(0, 0)).Add(o) op.Offset(f32.Pt(0, 0)).Add(o)
c2.Add(o) c2.Add(o)
s2.Pop() s2.Load()
}, func(r result) { }, func(r result) {
r.expect(5, 15, colornames.Red) r.expect(5, 15, colornames.Red)
r.expect(15, 15, colornames.Black) r.expect(15, 15, colornames.Black)
@@ -140,14 +140,14 @@ func TestReuseStencil(t *testing.T) {
c2 := drawChild(ops, txt) c2 := drawChild(ops, txt)
// lay out the children // lay out the children
stack1 := op.Push(ops) stack1 := op.Save(ops)
c1.Add(ops) c1.Add(ops)
stack1.Pop() stack1.Load()
stack2 := op.Push(ops) stack2 := op.Save(ops)
op.Offset(f32.Pt(0, 50)).Add(ops) op.Offset(f32.Pt(0, 50)).Add(ops)
c2.Add(ops) c2.Add(ops)
stack2.Pop() stack2.Load()
}, func(r result) { }, func(r result) {
r.expect(5, 5, colornames.Black) r.expect(5, 5, colornames.Black)
r.expect(5, 55, colornames.Black) r.expect(5, 55, colornames.Black)
@@ -161,11 +161,11 @@ func TestBuildOffscreen(t *testing.T) {
txt := constSqCirc() txt := constSqCirc()
draw := func(off float32, o *op.Ops) { draw := func(off float32, o *op.Ops) {
s := op.Push(o) s := op.Save(o)
op.Offset(f32.Pt(0, off)).Add(o) op.Offset(f32.Pt(0, off)).Add(o)
txt.Add(o) txt.Add(o)
paint.PaintOp{}.Add(o) paint.PaintOp{}.Add(o)
s.Pop() s.Load()
} }
multiRun(t, multiRun(t,
@@ -230,12 +230,12 @@ func TestLinearGradient(t *testing.T) {
Stop2: f32.Pt(gr.Max.X, gr.Min.Y), Stop2: f32.Pt(gr.Max.X, gr.Min.Y),
Color2: g.To, Color2: g.To,
}.Add(ops) }.Add(ops)
st := op.Push(ops) st := op.Save(ops)
clip.RRect{Rect: gr}.Add(ops) clip.RRect{Rect: gr}.Add(ops)
op.Affine(f32.Affine2D{}.Offset(pixelAligned.Min)).Add(ops) op.Affine(f32.Affine2D{}.Offset(pixelAligned.Min)).Add(ops)
scale(pixelAligned.Dx()/128, 1).Add(ops) scale(pixelAligned.Dx()/128, 1).Add(ops)
paint.PaintOp{}.Add(ops) paint.PaintOp{}.Add(ops)
st.Pop() st.Load()
gr = gr.Add(f32.Pt(0, gradienth)) gr = gr.Add(f32.Pt(0, gradienth))
} }
}, func(r result) { }, func(r result) {
@@ -260,10 +260,10 @@ func TestLinearGradientAngled(t *testing.T) {
Stop2: f32.Pt(0, 0), Stop2: f32.Pt(0, 0),
Color2: red, Color2: red,
}.Add(ops) }.Add(ops)
st := op.Push(ops) st := op.Save(ops)
clip.Rect(image.Rect(0, 0, 64, 64)).Add(ops) clip.Rect(image.Rect(0, 0, 64, 64)).Add(ops)
paint.PaintOp{}.Add(ops) paint.PaintOp{}.Add(ops)
st.Pop() st.Load()
paint.LinearGradientOp{ paint.LinearGradientOp{
Stop1: f32.Pt(64, 64), Stop1: f32.Pt(64, 64),
@@ -271,10 +271,10 @@ func TestLinearGradientAngled(t *testing.T) {
Stop2: f32.Pt(128, 0), Stop2: f32.Pt(128, 0),
Color2: green, Color2: green,
}.Add(ops) }.Add(ops)
st = op.Push(ops) st = op.Save(ops)
clip.Rect(image.Rect(64, 0, 128, 64)).Add(ops) clip.Rect(image.Rect(64, 0, 128, 64)).Add(ops)
paint.PaintOp{}.Add(ops) paint.PaintOp{}.Add(ops)
st.Pop() st.Load()
paint.LinearGradientOp{ paint.LinearGradientOp{
Stop1: f32.Pt(64, 64), Stop1: f32.Pt(64, 64),
@@ -282,10 +282,10 @@ func TestLinearGradientAngled(t *testing.T) {
Stop2: f32.Pt(128, 128), Stop2: f32.Pt(128, 128),
Color2: blue, Color2: blue,
}.Add(ops) }.Add(ops)
st = op.Push(ops) st = op.Save(ops)
clip.Rect(image.Rect(64, 64, 128, 128)).Add(ops) clip.Rect(image.Rect(64, 64, 128, 128)).Add(ops)
paint.PaintOp{}.Add(ops) paint.PaintOp{}.Add(ops)
st.Pop() st.Load()
paint.LinearGradientOp{ paint.LinearGradientOp{
Stop1: f32.Pt(64, 64), Stop1: f32.Pt(64, 64),
@@ -293,10 +293,10 @@ func TestLinearGradientAngled(t *testing.T) {
Stop2: f32.Pt(0, 128), Stop2: f32.Pt(0, 128),
Color2: magenta, Color2: magenta,
}.Add(ops) }.Add(ops)
st = op.Push(ops) st = op.Save(ops)
clip.Rect(image.Rect(0, 64, 64, 128)).Add(ops) clip.Rect(image.Rect(0, 64, 64, 128)).Add(ops)
paint.PaintOp{}.Add(ops) paint.PaintOp{}.Add(ops)
st.Pop() st.Load()
}, func(r result) {}) }, func(r result) {})
} }
+1 -1
View File
@@ -130,7 +130,7 @@ func TestOffsetScaleTexture(t *testing.T) {
func TestRotateTexture(t *testing.T) { func TestRotateTexture(t *testing.T) {
run(t, func(o *op.Ops) { run(t, func(o *op.Ops) {
defer op.Push(o).Pop() defer op.Save(o).Load()
squares.Add(o) squares.Add(o)
a := f32.Affine2D{}.Offset(f32.Pt(30, 30)).Rotate(f32.Pt(40, 40), math.Pi/4) a := f32.Affine2D{}.Offset(f32.Pt(30, 30)).Rotate(f32.Pt(40, 40), math.Pi/4)
op.Affine(a).Add(o) op.Affine(a).Add(o)
+4 -4
View File
@@ -51,13 +51,13 @@ For example:
var stack op.StackOp var stack op.StackOp
var h1, h2 *Handler var h1, h2 *Handler
stack := op.Push(ops) state := op.Save(ops)
pointer.InputOp{Tag: h1}.Add(Ops) pointer.InputOp{Tag: h1}.Add(Ops)
stack.Pop() state.Load()
stack = op.Push(ops) state = op.Save(ops)
pointer.InputOp{Tag: h2}.Add(ops) pointer.InputOp{Tag: h2}.Add(ops)
stack.Pop() state.Load()
implies a tree of two inner nodes, each with one pointer handler. implies a tree of two inner nodes, each with one pointer handler.
+38 -38
View File
@@ -38,30 +38,30 @@ func TestKeyStacked(t *testing.T) {
ops := new(op.Ops) ops := new(op.Ops)
r := new(Router) r := new(Router)
s := op.Push(ops) s := op.Save(ops)
key.InputOp{Tag: &handlers[0]}.Add(ops) key.InputOp{Tag: &handlers[0]}.Add(ops)
// FocusOp must not overwrite the // FocusOp must not overwrite the
// FocusOp{Focus: true}. // FocusOp{Focus: true}.
key.FocusOp{Focus: false}.Add(ops) key.FocusOp{Focus: false}.Add(ops)
s.Pop() s.Load()
s = op.Push(ops) s = op.Save(ops)
key.SoftKeyboardOp{Show: false}.Add(ops) key.SoftKeyboardOp{Show: false}.Add(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
key.FocusOp{Focus: true}.Add(ops) key.FocusOp{Focus: true}.Add(ops)
s.Pop() s.Load()
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[2]}.Add(ops) key.InputOp{Tag: &handlers[2]}.Add(ops)
// SoftwareKeyboardOp will open the keyboard, // SoftwareKeyboardOp will open the keyboard,
// overwriting `SoftKeyboardOp{Show: false}`. // overwriting `SoftKeyboardOp{Show: false}`.
key.SoftKeyboardOp{Show: true}.Add(ops) key.SoftKeyboardOp{Show: true}.Add(ops)
s.Pop() s.Load()
s = op.Push(ops) s = op.Save(ops)
key.SoftKeyboardOp{Show: false}.Add(ops) key.SoftKeyboardOp{Show: false}.Add(ops)
key.InputOp{Tag: &handlers[3]}.Add(ops) key.InputOp{Tag: &handlers[3]}.Add(ops)
// FocusOp must not overwrite the // FocusOp must not overwrite the
// FocusOp{Focus: true}. // FocusOp{Focus: true}.
key.FocusOp{Focus: false}.Add(ops) key.FocusOp{Focus: false}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
@@ -93,16 +93,16 @@ func TestKeyRemoveFocus(t *testing.T) {
r := new(Router) r := new(Router)
// New InputOp with Focus and Keyboard: // New InputOp with Focus and Keyboard:
s := op.Push(ops) s := op.Save(ops)
key.InputOp{Tag: &handlers[0]}.Add(ops) key.InputOp{Tag: &handlers[0]}.Add(ops)
key.FocusOp{Focus: true}.Add(ops) key.FocusOp{Focus: true}.Add(ops)
key.SoftKeyboardOp{Show: true}.Add(ops) key.SoftKeyboardOp{Show: true}.Add(ops)
s.Pop() s.Load()
// New InputOp without any focus: // New InputOp without any focus:
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
@@ -118,19 +118,19 @@ func TestKeyRemoveFocus(t *testing.T) {
ops.Reset() ops.Reset()
// Will get the focus removed: // Will get the focus removed:
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[0]}.Add(ops) key.InputOp{Tag: &handlers[0]}.Add(ops)
s.Pop() s.Load()
// Unchanged: // Unchanged:
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
s.Pop() s.Load()
// Removing any Focus: // Removing any Focus:
s = op.Push(ops) s = op.Save(ops)
key.FocusOp{Focus: false}.Add(ops) key.FocusOp{Focus: false}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
@@ -141,18 +141,18 @@ func TestKeyRemoveFocus(t *testing.T) {
ops.Reset() ops.Reset()
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[0]}.Add(ops) key.InputOp{Tag: &handlers[0]}.Add(ops)
s.Pop() s.Load()
// Setting Focus without InputOp: // Setting Focus without InputOp:
s = op.Push(ops) s = op.Save(ops)
key.FocusOp{Focus: true}.Add(ops) key.FocusOp{Focus: true}.Add(ops)
s.Pop() s.Load()
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
@@ -165,18 +165,18 @@ func TestKeyRemoveFocus(t *testing.T) {
// Set focus to InputOp which already // Set focus to InputOp which already
// exists in the previous frame: // exists in the previous frame:
s = op.Push(ops) s = op.Save(ops)
key.FocusOp{Focus: true}.Add(ops) key.FocusOp{Focus: true}.Add(ops)
key.InputOp{Tag: &handlers[0]}.Add(ops) key.InputOp{Tag: &handlers[0]}.Add(ops)
key.SoftKeyboardOp{Show: true}.Add(ops) key.SoftKeyboardOp{Show: true}.Add(ops)
s.Pop() s.Load()
// Tries to remove focus: // Tries to remove focus:
// It must not overwrite the previous `FocusOp`. // It must not overwrite the previous `FocusOp`.
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
key.FocusOp{Focus: false}.Add(ops) key.FocusOp{Focus: false}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
@@ -192,16 +192,16 @@ func TestKeyFocusedInvisible(t *testing.T) {
r := new(Router) r := new(Router)
// Set new InputOp with focus: // Set new InputOp with focus:
s := op.Push(ops) s := op.Save(ops)
key.FocusOp{Focus: true}.Add(ops) key.FocusOp{Focus: true}.Add(ops)
key.InputOp{Tag: &handlers[0]}.Add(ops) key.InputOp{Tag: &handlers[0]}.Add(ops)
key.SoftKeyboardOp{Show: true}.Add(ops) key.SoftKeyboardOp{Show: true}.Add(ops)
s.Pop() s.Load()
// Set new InputOp without focus: // Set new InputOp without focus:
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
@@ -217,9 +217,9 @@ func TestKeyFocusedInvisible(t *testing.T) {
// //
// Unchanged: // Unchanged:
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
@@ -232,14 +232,14 @@ func TestKeyFocusedInvisible(t *testing.T) {
// Respawn the first element: // Respawn the first element:
// It must receive one `Event{Focus: false}`. // It must receive one `Event{Focus: false}`.
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[0]}.Add(ops) key.InputOp{Tag: &handlers[0]}.Add(ops)
s.Pop() s.Load()
// Unchanged // Unchanged
s = op.Push(ops) s = op.Save(ops)
key.InputOp{Tag: &handlers[1]}.Add(ops) key.InputOp{Tag: &handlers[1]}.Add(ops)
s.Pop() s.Load()
r.Frame(ops) r.Frame(ops)
+3 -3
View File
@@ -243,12 +243,12 @@ func TestMultipleAreas(t *testing.T) {
var ops op.Ops var ops op.Ops
addPointerHandler(&ops, handler, image.Rect(0, 0, 100, 100)) addPointerHandler(&ops, handler, image.Rect(0, 0, 100, 100))
st := op.Push(&ops) st := op.Save(&ops)
pointer.Rect(image.Rect(50, 50, 200, 200)).Add(&ops) pointer.Rect(image.Rect(50, 50, 200, 200)).Add(&ops)
// Second area has no Types set, yet should receive events because // Second area has no Types set, yet should receive events because
// Types for the same handles are or-ed together. // Types for the same handles are or-ed together.
pointer.InputOp{Tag: handler}.Add(&ops) pointer.InputOp{Tag: handler}.Add(&ops)
st.Pop() st.Load()
var r Router var r Router
r.Frame(&ops) r.Frame(&ops)
@@ -468,7 +468,7 @@ func TestCursorNameOp(t *testing.T) {
// addPointerHandler adds a pointer.InputOp for the tag in a // addPointerHandler adds a pointer.InputOp for the tag in a
// rectangular area. // rectangular area.
func addPointerHandler(ops *op.Ops, tag event.Tag, area image.Rectangle) { func addPointerHandler(ops *op.Ops, tag event.Tag, area image.Rectangle) {
defer op.Push(ops).Pop() defer op.Save(ops).Load()
pointer.Rect(area).Add(ops) pointer.Rect(area).Add(ops)
pointer.InputOp{ pointer.InputOp{
Tag: tag, Tag: tag,
+2 -2
View File
@@ -181,10 +181,10 @@ func (f Flex) Layout(gtx Context, children ...FlexChild) Dimensions {
cross = maxBaseline - b cross = maxBaseline - b
} }
} }
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
op.Offset(FPt(f.Axis.point(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.Load()
mainSize += f.Axis.Main(dims.Size) mainSize += f.Axis.Main(dims.Size)
if i < len(children)-1 { if i < len(children)-1 {
switch f.Spacing { switch f.Spacing {
+4 -4
View File
@@ -141,11 +141,11 @@ func (in Inset) Layout(gtx Context, w Widget) Dimensions {
if mcs.Min.Y > mcs.Max.Y { if mcs.Min.Y > mcs.Max.Y {
mcs.Min.Y = mcs.Max.Y mcs.Min.Y = mcs.Max.Y
} }
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
op.Offset(FPt(image.Point{X: left, Y: top})).Add(gtx.Ops) op.Offset(FPt(image.Point{X: left, Y: top})).Add(gtx.Ops)
gtx.Constraints = mcs gtx.Constraints = mcs
dims := w(gtx) dims := w(gtx)
stack.Pop() stack.Load()
return Dimensions{ return Dimensions{
Size: dims.Size.Add(image.Point{X: right + left, Y: top + bottom}), Size: dims.Size.Add(image.Point{X: right + left, Y: top + bottom}),
Baseline: dims.Baseline + bottom, Baseline: dims.Baseline + bottom,
@@ -186,10 +186,10 @@ func (d Direction) Layout(gtx Context, w Widget) Dimensions {
case SW, S, SE: case SW, S, SE:
p.Y = sz.Y - dims.Size.Y p.Y = sz.Y - dims.Size.Y
} }
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
op.Offset(FPt(p)).Add(gtx.Ops) op.Offset(FPt(p)).Add(gtx.Ops)
call.Add(gtx.Ops) call.Add(gtx.Ops)
stack.Pop() stack.Load()
return Dimensions{ return Dimensions{
Size: sz, Size: sz,
Baseline: dims.Baseline + sz.Y - dims.Size.Y - p.Y, Baseline: dims.Baseline + sz.Y - dims.Size.Y - p.Y,
+3 -3
View File
@@ -253,11 +253,11 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
Min: l.Axis.point(min, -inf), Min: l.Axis.point(min, -inf),
Max: l.Axis.point(max, inf), Max: l.Axis.point(max, inf),
} }
stack := op.Push(ops) stack := op.Save(ops)
clip.Rect(r).Add(ops) clip.Rect(r).Add(ops)
op.Offset(FPt(l.Axis.point(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.Load()
pos += childSize pos += childSize
} }
atStart := l.Position.First == 0 && l.Position.Offset <= 0 atStart := l.Position.First == 0 && l.Position.Offset <= 0
@@ -274,7 +274,7 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions {
} }
dims := l.Axis.point(pos, maxCross) dims := l.Axis.point(pos, maxCross)
call := macro.Stop() call := macro.Stop()
defer op.Push(ops).Pop() defer op.Save(ops).Load()
pointer.Rect(image.Rectangle{Max: dims}).Add(ops) pointer.Rect(image.Rectangle{Max: dims}).Add(ops)
l.scroll.Add(ops) l.scroll.Add(ops)
call.Add(ops) call.Add(ops)
+2 -2
View File
@@ -104,10 +104,10 @@ func (s Stack) Layout(gtx Context, children ...StackChild) Dimensions {
case SW, S, SE: case SW, S, SE:
p.Y = maxSZ.Y - sz.Y p.Y = maxSZ.Y - sz.Y
} }
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
op.Offset(FPt(p)).Add(gtx.Ops) op.Offset(FPt(p)).Add(gtx.Ops)
ch.call.Add(gtx.Ops) ch.call.Add(gtx.Ops)
stack.Pop() stack.Load()
if baseline == 0 { if baseline == 0 {
if b := ch.dims.Baseline; b != 0 { if b := ch.dims.Baseline; b != 0 {
baseline = b + maxSZ.Y - sz.Y - p.Y baseline = b + maxSZ.Y - sz.Y - p.Y
+15 -15
View File
@@ -33,21 +33,21 @@ State
An Ops list can be viewed as a very simple virtual machine: it has an implicit An Ops list can be viewed as a very simple virtual machine: it has an implicit
mutable state stack and execution flow can be controlled with macros. mutable state stack and execution flow can be controlled with macros.
The StackOp saves the current state to the state stack and restores it later: The Save function saves the current state for later restoring:
ops := new(op.Ops) ops := new(op.Ops)
// Save the current state, in particular the transform. // Save the current state, in particular the transform.
stack := op.Push(ops) state := op.Save(ops)
// Apply a transform to subsequent operations. // Apply a transform to subsequent operations.
op.Offset(...).Add(ops) op.Offset(...).Add(ops)
... ...
// Restore the previous transform. // Restore the previous transform.
stack.Pop() state.Load()
You can also use this one-line to save the current state and restore it at the You can also use this one-line to save the current state and restore it at the
end of a function : end of a function :
defer op.Push(ops).Pop() defer op.Save(ops).Load()
The MacroOp records a list of operations to be executed later: The MacroOp records a list of operations to be executed later:
@@ -85,15 +85,15 @@ type Ops struct {
// refs hold external references for operations. // refs hold external references for operations.
refs []interface{} refs []interface{}
// nextStateID is the id allocated for the next // nextStateID is the id allocated for the next
// StackOp. // StateOp.
nextStateID int nextStateID int
macroStack stack macroStack stack
} }
// StackOp saves and restores the operation state // StateOp represents a saved operation snapshop to be restored
// in a stack-like manner. // later.
type StackOp struct { type StateOp struct {
id int id int
macroID int macroID int
ops *Ops ops *Ops
@@ -125,8 +125,8 @@ type TransformOp struct {
t f32.Affine2D t f32.Affine2D
} }
// stack tracks the integer identities of StackOp and MacroOp // stack tracks the integer identities of MacroOp
// operations to ensure correct pairing of Push/Pop and Record/End. // operations to ensure correct pairing of Record/End.
type stack struct { type stack struct {
currentID int currentID int
nextID int nextID int
@@ -142,10 +142,10 @@ type pc struct {
refs int refs int
} }
// Push (save) the current operations state. // Save the current operations state.
func Push(o *Ops) StackOp { func Save(o *Ops) StateOp {
o.nextStateID++ o.nextStateID++
s := StackOp{ s := StateOp{
ops: o, ops: o,
id: o.nextStateID, id: o.nextStateID,
macroID: o.macroStack.currentID, macroID: o.macroStack.currentID,
@@ -157,8 +157,8 @@ func Push(o *Ops) StackOp {
return s return s
} }
// Pop (restore) a previously Pushed operations state. // Load a previously saved operations state.
func (s StackOp) Pop() { func (s StateOp) Load() {
if s.id == 0 { if s.id == 0 {
panic("zero-value op") panic("zero-value op")
} }
+2 -2
View File
@@ -139,7 +139,7 @@ func (d PaintOp) Add(o *op.Ops) {
// FillShape fills the clip shape with a color. // FillShape fills the clip shape with a color.
func FillShape(ops *op.Ops, c color.NRGBA, shape clip.Op) { func FillShape(ops *op.Ops, c color.NRGBA, shape clip.Op) {
defer op.Push(ops).Pop() defer op.Save(ops).Load()
shape.Add(ops) shape.Add(ops)
Fill(ops, c) Fill(ops, c)
} }
@@ -149,7 +149,7 @@ func FillShape(ops *op.Ops, c color.NRGBA, shape clip.Op) {
// the painted area. Use FillShape unless you need to paint several // the painted area. Use FillShape unless you need to paint several
// times within the same clip.Op. // times within the same clip.Op.
func Fill(ops *op.Ops, c color.NRGBA) { func Fill(ops *op.Ops, c color.NRGBA) {
defer op.Push(ops).Pop() defer op.Save(ops).Load()
ColorOp{Color: c}.Add(ops) ColorOp{Color: c}.Add(ops)
PaintOp{}.Add(ops) PaintOp{}.Add(ops)
} }
+2 -2
View File
@@ -24,7 +24,7 @@ func (b Border) Layout(gtx layout.Context, w layout.Widget) layout.Dimensions {
dims := w(gtx) dims := w(gtx)
sz := dims.Size sz := dims.Size
rr := float32(gtx.Px(b.CornerRadius)) rr := float32(gtx.Px(b.CornerRadius))
st := op.Push(gtx.Ops) st := op.Save(gtx.Ops)
width := gtx.Px(b.Width) width := gtx.Px(b.Width)
clip.Border{ clip.Border{
Rect: f32.Rectangle{ Rect: f32.Rectangle{
@@ -35,6 +35,6 @@ func (b Border) Layout(gtx layout.Context, w layout.Widget) layout.Dimensions {
}.Add(gtx.Ops) }.Add(gtx.Ops)
paint.ColorOp{Color: b.Color}.Add(gtx.Ops) paint.ColorOp{Color: b.Color}.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
st.Pop() st.Load()
return dims return dims
} }
+2 -2
View File
@@ -74,10 +74,10 @@ func (b *Clickable) History() []Press {
func (b *Clickable) Layout(gtx layout.Context) layout.Dimensions { func (b *Clickable) Layout(gtx layout.Context) layout.Dimensions {
b.update(gtx) b.update(gtx)
stack := op.Push(gtx.Ops) stack := op.Save(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)
stack.Pop() stack.Load()
for len(b.history) > 0 { for len(b.history) > 0 {
c := b.history[0] c := b.history[0]
if c.End.IsZero() || gtx.Now.Sub(c.End) < 1*time.Second { if c.End.IsZero() || gtx.Now.Sub(c.End) < 1*time.Second {
+5 -5
View File
@@ -451,12 +451,12 @@ func (e *Editor) PaintText(gtx layout.Context) {
cl := textPadding(e.lines) cl := textPadding(e.lines)
cl.Max = cl.Max.Add(e.viewSize) cl.Max = cl.Max.Add(e.viewSize)
for _, shape := range e.shapes { for _, shape := range e.shapes {
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
op.Offset(layout.FPt(shape.offset)).Add(gtx.Ops) op.Offset(layout.FPt(shape.offset)).Add(gtx.Ops)
shape.clip.Add(gtx.Ops) shape.clip.Add(gtx.Ops)
clip.Rect(cl.Sub(shape.offset)).Add(gtx.Ops) clip.Rect(cl.Sub(shape.offset)).Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
stack.Pop() stack.Load()
} }
} }
@@ -469,7 +469,7 @@ func (e *Editor) PaintCaret(gtx layout.Context) {
carX := e.caret.x carX := e.caret.x
carY := e.caret.y carY := e.caret.y
defer op.Push(gtx.Ops).Pop() defer op.Save(gtx.Ops).Load()
carX -= carWidth / 2 carX -= carWidth / 2
carAsc, carDesc := -e.lines[e.caret.line].Bounds.Min.Y, e.lines[e.caret.line].Bounds.Max.Y carAsc, carDesc := -e.lines[e.caret.line].Bounds.Min.Y, e.lines[e.caret.line].Bounds.Max.Y
carRect := image.Rectangle{ carRect := image.Rectangle{
@@ -492,10 +492,10 @@ func (e *Editor) PaintCaret(gtx layout.Context) {
cl.Max = cl.Max.Add(e.viewSize) cl.Max = cl.Max.Add(e.viewSize)
carRect = cl.Intersect(carRect) carRect = cl.Intersect(carRect)
if !carRect.Empty() { if !carRect.Empty() {
st := op.Push(gtx.Ops) st := op.Save(gtx.Ops)
clip.Rect(carRect).Add(gtx.Ops) clip.Rect(carRect).Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
st.Pop() st.Load()
} }
} }
+1 -1
View File
@@ -37,7 +37,7 @@ func (e *Enum) Changed() bool {
// Layout adds the event handler for key. // Layout adds the event handler for key.
func (e *Enum) Layout(gtx layout.Context, key string) layout.Dimensions { func (e *Enum) Layout(gtx layout.Context, key string) layout.Dimensions {
defer op.Push(gtx.Ops).Pop() defer op.Save(gtx.Ops).Load()
pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Add(gtx.Ops) pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Add(gtx.Ops)
if index(e.values, key) == -1 { if index(e.values, key) == -1 {
+1 -1
View File
@@ -52,7 +52,7 @@ func (f *Float) Layout(gtx layout.Context, pointerMargin int, min, max float32)
f.pos = 1 f.pos = 1
} }
defer op.Push(gtx.Ops).Pop() defer op.Save(gtx.Ops).Load()
rect := image.Rectangle{Max: size} rect := image.Rectangle{Max: size}
rect.Min.X -= pointerMargin rect.Min.X -= pointerMargin
rect.Max.X += pointerMargin rect.Max.X += pointerMargin
+2 -2
View File
@@ -32,10 +32,10 @@ func (im Image) Layout(gtx layout.Context) layout.Dimensions {
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 := cs.Constrain(image.Pt(w, h)) d := cs.Constrain(image.Pt(w, h))
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
clip.Rect(image.Rectangle{Max: d}).Add(gtx.Ops) clip.Rect(image.Rectangle{Max: d}).Add(gtx.Ops)
im.Src.Add(gtx.Ops) im.Src.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
stack.Pop() stack.Load()
return layout.Dimensions{Size: d} return layout.Dimensions{Size: d}
} }
+2 -2
View File
@@ -110,12 +110,12 @@ func (l Label) Layout(gtx layout.Context, s text.Shaper, font text.Font, size un
if !ok { if !ok {
break break
} }
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
op.Offset(layout.FPt(off)).Add(gtx.Ops) op.Offset(layout.FPt(off)).Add(gtx.Ops)
s.Shape(font, textSize, l).Add(gtx.Ops) s.Shape(font, textSize, l).Add(gtx.Ops)
clip.Rect(cl.Sub(off)).Add(gtx.Ops) clip.Rect(cl.Sub(off)).Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
stack.Pop() stack.Load()
} }
return dims return dims
} }
+1 -1
View File
@@ -271,7 +271,7 @@ func drawInk(gtx layout.Context, c widget.Press) {
alpha := 0.7 * alphaBezier alpha := 0.7 * alphaBezier
const col = 0.8 const col = 0.8
ba, bc := byte(alpha*0xff), byte(col*0xff) ba, bc := byte(alpha*0xff), byte(col*0xff)
defer op.Push(gtx.Ops).Pop() defer op.Save(gtx.Ops).Load()
rgba := f32color.MulAlpha(color.NRGBA{A: 0xff, R: bc, G: bc, B: bc}, ba) rgba := f32color.MulAlpha(color.NRGBA{A: 0xff, R: bc, G: bc, B: bc}, ba)
ink := paint.ColorOp{Color: rgba} ink := paint.ColorOp{Color: rgba}
ink.Add(gtx.Ops) ink.Add(gtx.Ops)
+1 -1
View File
@@ -40,7 +40,7 @@ func Editor(th *Theme, editor *widget.Editor, hint string) EditorStyle {
} }
func (e EditorStyle) Layout(gtx layout.Context) layout.Dimensions { func (e EditorStyle) Layout(gtx layout.Context) layout.Dimensions {
defer op.Push(gtx.Ops).Pop() defer op.Save(gtx.Ops).Load()
macro := op.Record(gtx.Ops) macro := op.Record(gtx.Ops)
paint.ColorOp{Color: e.HintColor}.Add(gtx.Ops) paint.ColorOp{Color: e.HintColor}.Add(gtx.Ops)
var maxlines int var maxlines int
+1 -1
View File
@@ -36,7 +36,7 @@ func (l LoaderStyle) Layout(gtx layout.Context) layout.Dimensions {
} }
sz := gtx.Constraints.Constrain(image.Pt(diam, diam)) sz := gtx.Constraints.Constrain(image.Pt(diam, diam))
radius := float64(sz.X) * .5 radius := float64(sz.X) * .5
defer op.Push(gtx.Ops).Pop() defer op.Save(gtx.Ops).Load()
op.Offset(f32.Pt(float32(radius), float32(radius))).Add(gtx.Ops) op.Offset(f32.Pt(float32(radius), float32(radius))).Add(gtx.Ops)
dt := (time.Duration(gtx.Now.UnixNano()) % (time.Second)).Seconds() dt := (time.Duration(gtx.Now.UnixNano()) % (time.Second)).Seconds()
+8 -8
View File
@@ -58,13 +58,13 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
size.Y = 2 * (touchSizePx / 2) size.Y = 2 * (touchSizePx / 2)
} }
st := op.Push(gtx.Ops) st := op.Save(gtx.Ops)
op.Offset(f32.Pt(thumbRadius, 0)).Add(gtx.Ops) op.Offset(f32.Pt(thumbRadius, 0)).Add(gtx.Ops)
gtx.Constraints.Min = image.Pt(size.X-2*thumbRadiusInt, size.Y) gtx.Constraints.Min = image.Pt(size.X-2*thumbRadiusInt, size.Y)
s.Float.Layout(gtx, thumbRadiusInt, s.Min, s.Max) s.Float.Layout(gtx, thumbRadiusInt, s.Min, s.Max)
gtx.Constraints.Min.Y = size.Y gtx.Constraints.Min.Y = size.Y
thumbPos := thumbRadius + s.Float.Pos() thumbPos := thumbRadius + s.Float.Pos()
st.Pop() st.Load()
color := s.Color color := s.Color
if gtx.Queue == nil { if gtx.Queue == nil {
@@ -72,7 +72,7 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
} }
// Draw track before thumb. // Draw track before thumb.
st = op.Push(gtx.Ops) st = op.Save(gtx.Ops)
track := f32.Rectangle{ track := f32.Rectangle{
Min: f32.Point{ Min: f32.Point{
X: thumbRadius, X: thumbRadius,
@@ -86,19 +86,19 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
clip.RRect{Rect: track}.Add(gtx.Ops) clip.RRect{Rect: track}.Add(gtx.Ops)
paint.ColorOp{Color: color}.Add(gtx.Ops) paint.ColorOp{Color: color}.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
st.Pop() st.Load()
// Draw track after thumb. // Draw track after thumb.
st = op.Push(gtx.Ops) st = op.Save(gtx.Ops)
track.Min.X = thumbPos track.Min.X = thumbPos
track.Max.X = float32(size.X) - thumbRadius track.Max.X = float32(size.X) - thumbRadius
clip.RRect{Rect: track}.Add(gtx.Ops) clip.RRect{Rect: track}.Add(gtx.Ops)
paint.ColorOp{Color: f32color.MulAlpha(color, 96)}.Add(gtx.Ops) paint.ColorOp{Color: f32color.MulAlpha(color, 96)}.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
st.Pop() st.Load()
// Draw thumb. // Draw thumb.
st = op.Push(gtx.Ops) st = op.Save(gtx.Ops)
thumb := f32.Rectangle{ thumb := f32.Rectangle{
Min: f32.Point{ Min: f32.Point{
X: thumbPos - thumbRadius, X: thumbPos - thumbRadius,
@@ -116,7 +116,7 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
}.Add(gtx.Ops) }.Add(gtx.Ops)
paint.ColorOp{Color: color}.Add(gtx.Ops) paint.ColorOp{Color: color}.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
st.Pop() st.Load()
return layout.Dimensions{Size: size} return layout.Dimensions{Size: size}
} }
+11 -11
View File
@@ -45,7 +45,7 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
trackOff := float32(thumbSize-trackHeight) * .5 trackOff := float32(thumbSize-trackHeight) * .5
// Draw track. // Draw track.
stack := op.Push(gtx.Ops) stack := op.Save(gtx.Ops)
trackCorner := float32(trackHeight) / 2 trackCorner := float32(trackHeight) / 2
trackRect := f32.Rectangle{Max: f32.Point{ trackRect := f32.Rectangle{Max: f32.Point{
X: float32(trackWidth), X: float32(trackWidth),
@@ -66,10 +66,10 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
}.Add(gtx.Ops) }.Add(gtx.Ops)
paint.ColorOp{Color: trackColor}.Add(gtx.Ops) paint.ColorOp{Color: trackColor}.Add(gtx.Ops)
paint.PaintOp{}.Add(gtx.Ops) paint.PaintOp{}.Add(gtx.Ops)
stack.Pop() stack.Load()
// Draw thumb ink. // Draw thumb ink.
stack = op.Push(gtx.Ops) stack = op.Save(gtx.Ops)
inkSize := gtx.Px(unit.Dp(44)) inkSize := gtx.Px(unit.Dp(44))
rr := float32(inkSize) * .5 rr := float32(inkSize) * .5
inkOff := f32.Point{ inkOff := f32.Point{
@@ -87,10 +87,10 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
for _, p := range s.Switch.History() { for _, p := range s.Switch.History() {
drawInk(gtx, p) drawInk(gtx, p)
} }
stack.Pop() stack.Load()
// Compute thumb offset and color. // Compute thumb offset and color.
stack = op.Push(gtx.Ops) stack = op.Save(gtx.Ops)
if s.Switch.Value { if s.Switch.Value {
off := trackWidth - thumbSize off := trackWidth - thumbSize
op.Offset(f32.Point{X: float32(off)}).Add(gtx.Ops) op.Offset(f32.Point{X: float32(off)}).Add(gtx.Ops)
@@ -98,19 +98,19 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
// Draw thumb shadow, a translucent disc slightly larger than the // Draw thumb shadow, a translucent disc slightly larger than the
// thumb itself. // thumb itself.
shadowStack := op.Push(gtx.Ops) shadowStack := op.Save(gtx.Ops)
shadowSize := float32(2) shadowSize := float32(2)
// Center shadow horizontally and slightly adjust its Y. // Center shadow horizontally and slightly adjust its Y.
op.Offset(f32.Point{X: -shadowSize / 2, Y: -.75}).Add(gtx.Ops) op.Offset(f32.Point{X: -shadowSize / 2, Y: -.75}).Add(gtx.Ops)
drawDisc(gtx.Ops, float32(thumbSize)+shadowSize, argb(0x55000000)) drawDisc(gtx.Ops, float32(thumbSize)+shadowSize, argb(0x55000000))
shadowStack.Pop() shadowStack.Load()
// Draw thumb. // Draw thumb.
drawDisc(gtx.Ops, float32(thumbSize), col) drawDisc(gtx.Ops, float32(thumbSize), col)
stack.Pop() stack.Load()
// Set up click area. // Set up click area.
stack = op.Push(gtx.Ops) stack = op.Save(gtx.Ops)
clickSize := gtx.Px(unit.Dp(40)) clickSize := gtx.Px(unit.Dp(40))
clickOff := f32.Point{ clickOff := f32.Point{
X: (float32(trackWidth) - float32(clickSize)) * .5, X: (float32(trackWidth) - float32(clickSize)) * .5,
@@ -121,14 +121,14 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
pointer.Ellipse(image.Rectangle{Max: sz}).Add(gtx.Ops) pointer.Ellipse(image.Rectangle{Max: sz}).Add(gtx.Ops)
gtx.Constraints.Min = sz gtx.Constraints.Min = sz
s.Switch.Layout(gtx) s.Switch.Layout(gtx)
stack.Pop() stack.Load()
dims := image.Point{X: trackWidth, Y: thumbSize} dims := image.Point{X: trackWidth, Y: thumbSize}
return layout.Dimensions{Size: dims} return layout.Dimensions{Size: dims}
} }
func drawDisc(ops *op.Ops, sz float32, col color.NRGBA) { func drawDisc(ops *op.Ops, sz float32, col color.NRGBA) {
defer op.Push(ops).Pop() defer op.Save(ops).Load()
rr := sz / 2 rr := sz / 2
r := f32.Rectangle{Max: f32.Point{X: sz, Y: sz}} r := f32.Rectangle{Max: f32.Point{X: sz, Y: sz}}
clip.RRect{ clip.RRect{