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
font text.Font
shaper text.Shaper
textSize fixed.Int26_6
blinkStart time.Time
focused bool
@@ -97,10 +98,22 @@ func (e *Editor) Events(gtx *layout.Context) []EditorEvent {
}
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.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) {
sbounds := e.scrollBounds()
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.textSize = textSize
}
e.processEvents(gtx)
e.layout(gtx, sh)
}
func (e *Editor) layout(gtx *layout.Context, sh text.Shaper) {
cs := gtx.Constraints
maxWidth := cs.Width.Max
maxWidth := gtx.Constraints.Width.Max
if e.SingleLine {
maxWidth = inf
}
@@ -238,13 +244,19 @@ func (e *Editor) layout(gtx *layout.Context, sh text.Shaper) {
e.maxWidth = maxWidth
e.invalidate()
}
if !e.valid {
e.lines, e.dims = e.layoutText(sh)
e.valid = true
if sh != e.shaper {
e.shaper = sh
e.invalidate()
}
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.
e.scrollRel(0, 0)
@@ -272,7 +284,7 @@ func (e *Editor) layout(gtx *layout.Context, sh text.Shaper) {
if !ok {
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})
}