From 86bc3e612d009c35b7858ccd72ed80fb3329b9bc Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 5 Jul 2019 16:52:13 +0200 Subject: [PATCH] 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 --- ui/ops.go | 3 +++ ui/text/editor.go | 13 ++++++++----- ui/text/label.go | 2 ++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ui/ops.go b/ui/ops.go index f4728179..570c9067 100644 --- a/ui/ops.go +++ b/ui/ops.go @@ -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 diff --git a/ui/text/editor.go b/ui/text/editor.go index 9964ef67..9dacacb2 100644 --- a/ui/text/editor.go +++ b/ui/text/editor.go @@ -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) diff --git a/ui/text/label.go b/ui/text/label.go index b4587477..3684310c 100644 --- a/ui/text/label.go +++ b/ui/text/label.go @@ -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) }