~eliasnaur/gio

b6e9c0324d17d124f7a179f5c0a549a0c6d5171c — pierre 5 months ago df0e058
widget: make Editor implement io.Seeker, io.Reader and io.WriterTo

The WriteTo, Seek, Read methods implement a more efficient access to
the Editor content than Text.

Signed-off-by: pierre <pierre.curto@gmail.com>
3 files changed, 67 insertions(+), 0 deletions(-)

M widget/buffer.go
M widget/editor.go
M widget/editor_test.go
M widget/buffer.go => widget/buffer.go +10 -0
@@ 142,6 142,16 @@ func (e *editBuffer) ReadRune() (rune, int, error) {
	return r, s, nil
}

// WriteTo implements io.WriterTo.
func (e *editBuffer) WriteTo(w io.Writer) (int64, error) {
	n1, err := w.Write(e.text[:e.gapstart])
	if err != nil {
		return int64(n1), err
	}
	n2, err := w.Write(e.text[e.gapend:])
	return int64(n1 + n2), err
}

func (e *editBuffer) String() string {
	var b strings.Builder
	b.Grow(e.len())

M widget/editor.go => widget/editor.go +15 -0
@@ 1250,6 1250,21 @@ func (e *Editor) ClearSelection() {
	e.caret.end = e.caret.start
}

// WriteTo implements io.WriterTo.
func (e *Editor) WriteTo(w io.Writer) (int64, error) {
	return e.rr.WriteTo(w)
}

// Seek implements io.Seeker.
func (e *Editor) Seek(offset int64, whence int) (int64, error) {
	return e.rr.Seek(0, io.SeekStart)
}

// Read implements io.Reader.
func (e *Editor) Read(p []byte) (int, error) {
	return e.rr.Read(p)
}

func max(a, b int) int {
	if a > b {
		return a

M widget/editor_test.go => widget/editor_test.go +42 -0
@@ 3,8 3,10 @@
package widget

import (
	"bytes"
	"fmt"
	"image"
	"io"
	"math/rand"
	"reflect"
	"strings"


@@ 476,6 478,46 @@ func TestSelectMove(t *testing.T) {
	testKey(key.NameDownArrow)
}

func TestEditor_Read(t *testing.T) {
	s := "hello world"
	buf := make([]byte, len(s))
	e := new(Editor)
	e.SetText(s)

	_, err := e.Seek(0, io.SeekStart)
	if err != nil {
		t.Error(err)
	}
	n, err := io.ReadFull(e, buf)
	if err != nil {
		t.Error(err)
	}
	if got, want := n, len(s); got != want {
		t.Errorf("got %d; want %d", got, want)
	}
	if got, want := string(buf), s; got != want {
		t.Errorf("got %q; want %q", got, want)
	}
}

func TestEditor_WriteTo(t *testing.T) {
	s := "hello world"
	var buf bytes.Buffer
	e := new(Editor)
	e.SetText(s)

	n, err := io.Copy(&buf, e)
	if err != nil {
		t.Error(err)
	}
	if got, want := int(n), len(s); got != want {
		t.Errorf("got %d; want %d", got, want)
	}
	if got, want := buf.String(), s; got != want {
		t.Errorf("got %q; want %q", got, want)
	}
}

func textWidth(e *Editor, lineNum, colStart, colEnd int) float32 {
	var w fixed.Int26_6
	advances := e.lines[lineNum].Layout.Advances