From 851255f7a67b14d5dc0199375241270346e70b53 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sun, 28 Jun 2020 22:34:15 +0200 Subject: [PATCH] widget: tolerate nil shader in Editor movement methods Fixes gio#142 Signed-off-by: Elias Naur --- widget/editor.go | 47 ++++++++++++++++++++++++++++++++++--------- widget/editor_test.go | 6 ++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/widget/editor.go b/widget/editor.go index 3cb2e7d0..ef8b1655 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -3,6 +3,7 @@ package widget import ( + "bufio" "image" "io" "math" @@ -172,15 +173,16 @@ func (e *Editor) processEvents(gtx layout.Context) { } func (e *Editor) makeValid() { - if !e.valid { - e.lines, e.dims = e.layoutText(e.shaper) - line, col, x, y := e.layoutCaret() - e.caret.line = line - e.caret.col = col - e.caret.x = x - e.caret.y = y - e.valid = true + if e.valid { + return } + e.lines, e.dims = e.layoutText(e.shaper) + line, col, x, y := e.layoutCaret() + e.caret.line = line + e.caret.col = col + e.caret.x = x + e.caret.y = y + e.valid = true } func (e *Editor) processPointer(gtx layout.Context) { @@ -530,7 +532,12 @@ func (e *Editor) layoutText(s text.Shaper) ([]text.Line, layout.Dimensions) { e.maskReader.Reset(&e.rr, e.Mask) r = &e.maskReader } - lines, _ := s.Layout(e.font, e.textSize, e.maxWidth, r) + var lines []text.Line + if s != nil { + lines, _ = s.Layout(e.font, e.textSize, e.maxWidth, r) + } else { + lines, _ = nullLayout(r) + } dims := linesDimens(lines) for i := 0; i < len(lines)-1; i++ { // To avoid layout flickering while editing, assume a soft newline takes @@ -799,5 +806,27 @@ func (e *Editor) NumLines() int { return len(e.lines) } +func nullLayout(r io.Reader) ([]text.Line, error) { + var layout []text.Glyph + rr := bufio.NewReader(r) + var rerr error + var n int + for { + r, s, err := rr.ReadRune() + n += s + layout = append(layout, text.Glyph{Rune: r}) + if err != nil { + rerr = err + break + } + } + return []text.Line{ + { + Layout: layout, + Len: n, + }, + }, rerr +} + func (s ChangeEvent) isEditorEvent() {} func (s SubmitEvent) isEditorEvent() {} diff --git a/widget/editor_test.go b/widget/editor_test.go index ae696978..7f512971 100644 --- a/widget/editor_test.go +++ b/widget/editor_test.go @@ -155,6 +155,12 @@ func TestEditorCaretConsistency(t *testing.T) { } } +func TestEditorNoLayout(t *testing.T) { + var e Editor + e.SetText("hi!\n") + e.Move(1) +} + // Generate generates a value of itself, for testing/quick. func (editMutation) Generate(rand *rand.Rand, size int) reflect.Value { t := editMutation(rand.Intn(int(moveLast)))