ui: make OpPush and OpPop explicit

We're about to allow OpBlock for invoking ops from multiple (cached)
Ops containers. To allow for drawing state changes to stick after
invoking such a cached block, we can't let OpBlock perform an implicit
save and restore of drawing state.

Instead, introduce OpPush and OpPop for explicit drawing state stack
management.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-06-02 15:10:09 +02:00
parent bf5d083b8a
commit 9142345fd4
7 changed files with 28 additions and 20 deletions
+2 -2
View File
@@ -157,12 +157,12 @@ func (f *Flex) Layout(ops *ui.Ops, children ...FlexChild) Dimens {
cross = f.maxBaseline - b cross = f.maxBaseline - b
} }
} }
ops.Begin() ui.OpPush{}.Add(ops)
ui.OpTransform{ ui.OpTransform{
Transform: ui.Offset(toPointF(axisPoint(f.Axis, mainSize, cross))), Transform: ui.Offset(toPointF(axisPoint(f.Axis, mainSize, cross))),
}.Add(ops) }.Add(ops)
child.block.Add(ops) child.block.Add(ops)
ops.End().Add(ops) ui.OpPop{}.Add(ops)
mainSize += axisMain(f.Axis, dims.Size) mainSize += axisMain(f.Axis, dims.Size)
switch f.MainAxisAlignment { switch f.MainAxisAlignment {
case SpaceEvenly: case SpaceEvenly:
+4 -4
View File
@@ -97,13 +97,13 @@ func (in *Insets) Begin(ops *ui.Ops, cs Constraints) Constraints {
mcs.Height.Max = mcs.Height.Min mcs.Height.Max = mcs.Height.Min
} }
} }
ops.Begin() ui.OpPush{}.Add(ops)
ui.OpTransform{Transform: ui.Offset(toPointF(image.Point{X: l, Y: t}))}.Add(ops) ui.OpTransform{Transform: ui.Offset(toPointF(image.Point{X: l, Y: t}))}.Add(ops)
return mcs return mcs
} }
func (in *Insets) End(ops *ui.Ops, dims Dimens) Dimens { func (in *Insets) End(ops *ui.Ops, dims Dimens) Dimens {
ops.End().Add(ops) ui.OpPop{}.Add(ops)
t, r, b, l := int(math.Round(float64(in.Top))), int(math.Round(float64(in.Right))), int(math.Round(float64(in.Bottom))), int(math.Round(float64(in.Left))) t, r, b, l := int(math.Round(float64(in.Top))), int(math.Round(float64(in.Right))), int(math.Round(float64(in.Bottom))), int(math.Round(float64(in.Left)))
return Dimens{ return Dimens{
Size: in.cs.Constrain(dims.Size.Add(image.Point{X: r + l, Y: t + b})), Size: in.cs.Constrain(dims.Size.Add(image.Point{X: r + l, Y: t + b})),
@@ -176,10 +176,10 @@ func (a *Align) End(ops *ui.Ops, dims Dimens) Dimens {
case SW, S, SE: case SW, S, SE:
p.Y = sz.Y - dims.Size.Y p.Y = sz.Y - dims.Size.Y
} }
ops.Begin() ui.OpPush{}.Add(ops)
ui.OpTransform{Transform: ui.Offset(toPointF(p))}.Add(ops) ui.OpTransform{Transform: ui.Offset(toPointF(p))}.Add(ops)
block.Add(ops) block.Add(ops)
ops.End().Add(ops) ui.OpPop{}.Add(ops)
return Dimens{ return Dimens{
Size: sz, Size: sz,
Baseline: dims.Baseline, Baseline: dims.Baseline,
+2 -2
View File
@@ -178,13 +178,13 @@ func (l *List) Layout(ops *ui.Ops) Dimens {
Min: axisPoint(l.Axis, min, -ui.Inf), Min: axisPoint(l.Axis, min, -ui.Inf),
Max: axisPoint(l.Axis, max, ui.Inf), Max: axisPoint(l.Axis, max, ui.Inf),
} }
ops.Begin() ui.OpPush{}.Add(ops)
draw.OpClip{Path: draw.RectPath(r)}.Add(ops) draw.OpClip{Path: draw.RectPath(r)}.Add(ops)
ui.OpTransform{ ui.OpTransform{
Transform: ui.Offset(toPointF(axisPoint(l.Axis, pos, cross))), Transform: ui.Offset(toPointF(axisPoint(l.Axis, pos, cross))),
}.Add(ops) }.Add(ops)
child.block.Add(ops) child.block.Add(ops)
ops.End().Add(ops) ui.OpPop{}.Add(ops)
pos += axisMain(l.Axis, sz) pos += axisMain(l.Axis, sz)
} }
atStart := l.first == 0 && l.offset <= 0 atStart := l.first == 0 && l.offset <= 0
+2 -2
View File
@@ -101,10 +101,10 @@ func (s *Stack) Layout(ops *ui.Ops, children ...StackChild) Dimens {
case SW, S, SE: case SW, S, SE:
p.Y = s.maxSZ.Y - sz.Y p.Y = s.maxSZ.Y - sz.Y
} }
ops.Begin() ui.OpPush{}.Add(ops)
ui.OpTransform{Transform: ui.Offset(toPointF(p))}.Add(ops) ui.OpTransform{Transform: ui.Offset(toPointF(p))}.Add(ops)
ch.block.Add(ops) ch.block.Add(ops)
ops.End().Add(ops) ui.OpPop{}.Add(ops)
} }
b := s.baseline b := s.baseline
if b == 0 { if b == 0 {
+14 -6
View File
@@ -24,8 +24,6 @@ type OpsReader struct {
pc pc pc pc
stack []block stack []block
ops opsData ops opsData
pseudoOp [1]byte
} }
type block struct { type block struct {
@@ -73,6 +71,10 @@ var refLengths = [...]int{
ops.TypePopRefs, ops.TypePopRefs,
} }
type OpPush struct{}
type OpPop struct{}
type OpBlock struct { type OpBlock struct {
ops *Ops ops *Ops
pc pc pc pc
@@ -82,6 +84,14 @@ type opBlockDef struct {
endpc pc endpc pc
} }
func (p OpPush) Add(o *Ops) {
o.Write([]byte{byte(ops.TypePush)}, nil)
}
func (p OpPop) Add(o *Ops) {
o.Write([]byte{byte(ops.TypePop)}, nil)
}
// Begin a block of ops. // Begin a block of ops.
func (o *Ops) Begin() { func (o *Ops) Begin() {
o.stack = append(o.stack, o.ops.pc()) o.stack = append(o.stack, o.ops.pc())
@@ -183,8 +193,7 @@ func (r *OpsReader) Decode() ([]byte, []interface{}, bool) {
r.ops = b.ops r.ops = b.ops
r.pc = b.retPC r.pc = b.retPC
r.stack = r.stack[:len(r.stack)-1] r.stack = r.stack[:len(r.stack)-1]
r.pseudoOp[0] = byte(ops.TypePop) continue
return r.pseudoOp[:], nil, true
} }
} }
if r.pc.data == len(r.ops.data) { if r.pc.data == len(r.ops.data) {
@@ -217,8 +226,7 @@ func (r *OpsReader) Decode() ([]byte, []interface{}, bool) {
r.pc = op.pc r.pc = op.pc
r.pc.data += ops.TypeBlockDefLen r.pc.data += ops.TypeBlockDefLen
r.pc.refs += ops.TypeBlockDefRefs r.pc.refs += ops.TypeBlockDefRefs
r.pseudoOp[0] = byte(ops.TypePush) continue
return r.pseudoOp[:], nil, true
case ops.TypeBlockDef: case ops.TypeBlockDef:
var op opBlockDef var op opBlockDef
op.decode(data) op.decode(data)
+2 -2
View File
@@ -171,11 +171,11 @@ func (e *Editor) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
break break
} }
path := e.Face.Path(str) path := e.Face.Path(str)
ops.Begin() ui.OpPush{}.Add(ops)
ui.OpTransform{Transform: ui.Offset(lineOff)}.Add(ops) ui.OpTransform{Transform: ui.Offset(lineOff)}.Add(ops)
draw.OpClip{Path: path}.Add(ops) draw.OpClip{Path: path}.Add(ops)
draw.OpDraw{Rect: toRectF(clip).Sub(lineOff)}.Add(ops) draw.OpDraw{Rect: toRectF(clip).Sub(lineOff)}.Add(ops)
ops.End().Add(ops) ui.OpPop{}.Add(ops)
} }
if e.focused { if e.focused {
now := e.cfg.Now now := e.cfg.Now
+2 -2
View File
@@ -102,11 +102,11 @@ func (l Label) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
} }
path := l.Face.Path(str) path := l.Face.Path(str)
lclip := toRectF(clip).Sub(off) lclip := toRectF(clip).Sub(off)
ops.Begin() ui.OpPush{}.Add(ops)
ui.OpTransform{Transform: ui.Offset(off)}.Add(ops) ui.OpTransform{Transform: ui.Offset(off)}.Add(ops)
draw.OpClip{Path: path}.Add(ops) draw.OpClip{Path: path}.Add(ops)
draw.OpDraw{Rect: lclip}.Add(ops) draw.OpDraw{Rect: lclip}.Add(ops)
ops.End().Add(ops) ui.OpPop{}.Add(ops)
} }
return dims return dims
} }