ui/text: use BlockOp as materials

Before this change, clients were expected to set up the current
material (color or image) before laying out Labels and Editors.
This was done to avoid garbage from a hypothetical material
interface covering both colors and images.

However, some widgets need more than one material: the Editor had
HintImage for the hint text material.

This change implements generalized materials through blocks:
anywhere a material is expected, a ui.BlockOp is is assumed to
contain the operation(s) needed for setting the desired material.

This way we avoid allocations (interfaces) and keep the
abstraction over material types.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-07-05 16:52:13 +02:00
parent 30a558d10d
commit 86bc3e612d
3 changed files with 13 additions and 5 deletions
+3
View File
@@ -213,6 +213,9 @@ func (b *BlockOp) decode(data []byte, refs []interface{}) {
}
func (b BlockOp) Add(o *Ops) {
if b.ops == nil {
return
}
data := make([]byte, ops.TypeBlockLen)
data[0] = byte(ops.TypeBlock)
bo := binary.LittleEndian
+8 -5
View File
@@ -27,8 +27,9 @@ type Editor struct {
SingleLine bool
Submit bool
Hint string
HintImage image.Image
Material ui.BlockOp
Hint string
HintMaterial ui.BlockOp
oldCfg ui.Config
blinkStart time.Time
@@ -202,8 +203,10 @@ func (e *Editor) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
Offset: off,
}
ui.PushOp{}.Add(ops)
if e.HintImage != nil && e.rr.len() == 0 {
draw.ImageOp{Img: e.HintImage, Rect: e.HintImage.Bounds()}.Add(ops)
if e.rr.len() > 0 {
e.Material.Add(ops)
} else {
e.HintMaterial.Add(ops)
}
for {
str, lineOff, ok := e.it.Next()
@@ -216,7 +219,6 @@ func (e *Editor) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
draw.DrawOp{Rect: toRectF(clip).Sub(lineOff)}.Add(ops)
ui.PopOp{}.Add(ops)
}
ui.PopOp{}.Add(ops)
if e.focused {
now := e.Config.Now
dt := now.Sub(e.blinkStart)
@@ -246,6 +248,7 @@ func (e *Editor) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
redraw.Add(ops)
}
}
ui.PopOp{}.Add(ops)
baseline := e.padTop + e.dims.Baseline
pointer.AreaRect(e.viewSize).Add(ops)
+2
View File
@@ -17,6 +17,7 @@ import (
type Label struct {
Face Face
Material ui.BlockOp
Alignment Alignment
Text string
MaxLines int
@@ -108,6 +109,7 @@ func (l Label) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
ui.PushOp{}.Add(ops)
ui.TransformOp{Transform: ui.Offset(off)}.Add(ops)
l.Face.Path(str).Add(ops)
l.Material.Add(ops)
draw.DrawOp{Rect: lclip}.Add(ops)
ui.PopOp{}.Add(ops)
}