widget: re-layout Editor before processing events if layout is invalid

Editor's event processing assumes the cached layout is valid, but
it might not be if the program changed the Editor text between calling
Layout and Events.

Fixes #85 (I think)

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-03 23:48:20 +01:00
parent c178ade323
commit 383f3eca40
+26 -14
View File
@@ -35,6 +35,7 @@ type Editor struct {
eventKey int eventKey int
font text.Font font text.Font
shaper text.Shaper
textSize fixed.Int26_6 textSize fixed.Int26_6
blinkStart time.Time blinkStart time.Time
focused bool focused bool
@@ -97,10 +98,22 @@ func (e *Editor) Events(gtx *layout.Context) []EditorEvent {
} }
func (e *Editor) processEvents(gtx *layout.Context) { func (e *Editor) processEvents(gtx *layout.Context) {
if e.shaper == nil {
// Can't process events without a shaper.
return
}
e.makeValid()
e.processPointer(gtx) e.processPointer(gtx)
e.processKey(gtx) e.processKey(gtx)
} }
func (e *Editor) makeValid() {
if !e.valid {
e.lines, e.dims = e.layoutText(e.shaper)
e.valid = true
}
}
func (e *Editor) processPointer(gtx *layout.Context) { func (e *Editor) processPointer(gtx *layout.Context) {
sbounds := e.scrollBounds() sbounds := e.scrollBounds()
var smin, smax int var smin, smax int
@@ -223,14 +236,7 @@ func (e *Editor) Layout(gtx *layout.Context, sh text.Shaper, font text.Font, siz
e.font = font e.font = font
e.textSize = textSize e.textSize = textSize
} }
e.processEvents(gtx) maxWidth := gtx.Constraints.Width.Max
e.layout(gtx, sh)
}
func (e *Editor) layout(gtx *layout.Context, sh text.Shaper) {
cs := gtx.Constraints
maxWidth := cs.Width.Max
if e.SingleLine { if e.SingleLine {
maxWidth = inf maxWidth = inf
} }
@@ -238,13 +244,19 @@ func (e *Editor) layout(gtx *layout.Context, sh text.Shaper) {
e.maxWidth = maxWidth e.maxWidth = maxWidth
e.invalidate() e.invalidate()
} }
if sh != e.shaper {
if !e.valid { e.shaper = sh
e.lines, e.dims = e.layoutText(sh) e.invalidate()
e.valid = true
} }
e.viewSize = cs.Constrain(e.dims.Size) e.processEvents(gtx)
e.layout(gtx)
}
func (e *Editor) layout(gtx *layout.Context) {
e.makeValid()
e.viewSize = gtx.Constraints.Constrain(e.dims.Size)
// Adjust scrolling for new viewport and layout. // Adjust scrolling for new viewport and layout.
e.scrollRel(0, 0) e.scrollRel(0, 0)
@@ -272,7 +284,7 @@ func (e *Editor) layout(gtx *layout.Context, sh text.Shaper) {
if !ok { if !ok {
break break
} }
path := sh.Shape(e.font, e.textSize, layout) path := e.shaper.Shape(e.font, e.textSize, layout)
e.shapes = append(e.shapes, line{off, path}) e.shapes = append(e.shapes, line{off, path})
} }