[PATCH v7] widget: add some rudimentary exported editing methods
Export this patch
Editor.Delete
Editor.Move
Editor.Insert
Move the Editor.command method up above all the functions it calls.
Signed-off-by: Larry Clapp <larry@theclapp.org>
---
widget/buffer.go | 43 ++++++++++++-----------
widget/editor.go | 88 ++++++++++++++++++++++++------------------------
2 files changed, 65 insertions(+), 66 deletions(-)
7th time's the charm? :)
diff --git a/widget/buffer.go b/widget/buffer.go
index 22e8451..74cacdf 100644
--- a/widget/buffer.go
+++ b/widget/buffer.go
@@ -35,20 +35,19 @@ func (e *editBuffer) Changed() bool {
return c
}
-func (e *editBuffer) deleteRuneForward() {
+func (e *editBuffer) deleteRunes(runes int) {
e.moveGap(0)
- _, s := utf8.DecodeRune(e.text[e.gapend:])
- e.gapend += s
- e.changed = e.changed || s > 0
- e.dump()
-}
-
-func (e *editBuffer) deleteRune() {
- e.moveGap(0)
- _, s := utf8.DecodeLastRune(e.text[:e.gapstart])
- e.gapstart -= s
- e.caret -= s
- e.changed = e.changed || s > 0
+ for ; runes < 0 && e.gapstart > 0; runes++ {
+ _, s := utf8.DecodeLastRune(e.text[:e.gapstart])
+ e.gapstart -= s
+ e.caret -= s
+ e.changed = e.changed || s > 0
+ }
+ for ; runes > 0 && e.gapend < len(e.text); runes-- {
+ _, s := utf8.DecodeRune(e.text[e.gapend:])
+ e.gapend += s
+ e.changed = e.changed || s > 0
+ }
e.dump()
}
@@ -141,15 +140,15 @@ func (e *editBuffer) dump() {
}
}
-func (e *editBuffer) moveLeft() {
- _, s := e.runeBefore(e.caret)
- e.caret -= s
- e.dump()
-}
-
-func (e *editBuffer) moveRight() {
- _, s := e.runeAt(e.caret)
- e.caret += s
+func (e *editBuffer) move(runes int) {
+ for ; runes < 0 && e.caret > 0; runes++ {
+ _, s := e.runeBefore(e.caret)
+ e.caret -= s
+ }
+ for ; runes > 0 && e.caret < len(e.text); runes-- {
+ _, s := e.runeAt(e.caret)
+ e.caret += s
+ }
e.dump()
}
diff --git a/widget/editor.go b/widget/editor.go
index 8b7b07d..7ba8d3c 100644
--- a/widget/editor.go
+++ b/widget/editor.go
@@ -175,6 +175,38 @@ func (e *Editor) processKey(gtx *layout.Context) {
}
}
+func (e *Editor) command(k key.Event) bool {
+ switch k.Name {
+ case key.NameReturn, key.NameEnter:
+ e.append("\n")
+ case key.NameDeleteBackward:
+ e.Delete(-1)
+ case key.NameDeleteForward:
+ e.Delete(1)
+ case key.NameUpArrow:
+ line, _, carX, _ := e.layoutCaret()
+ e.carXOff = e.moveToLine(carX+e.carXOff, line-1)
+ case key.NameDownArrow:
+ line, _, carX, _ := e.layoutCaret()
+ e.carXOff = e.moveToLine(carX+e.carXOff, line+1)
+ case key.NameLeftArrow:
+ e.Move(-1)
+ case key.NameRightArrow:
+ e.Move(1)
+ case key.NamePageUp:
+ e.movePages(-1)
+ case key.NamePageDown:
+ e.movePages(+1)
+ case key.NameHome:
+ e.moveStart()
+ case key.NameEnd:
+ e.moveEnd()
+ default:
+ return false
+ }
+ return true
+}
+
// Focus requests the input focus for the Editor.
func (e *Editor) Focus() {
e.requestFocus = true
@@ -451,15 +483,18 @@ func (e *Editor) invalidate() {
e.valid = false
}
-func (e *Editor) deleteRune() {
- e.rr.deleteRune()
+// Delete runes from the caret position. The sign of runes specifies the
+// direction to delete: positive is forward, negative is backward.
+func (e *Editor) Delete(runes int) {
+ e.rr.deleteRunes(runes)
e.carXOff = 0
e.invalidate()
}
-func (e *Editor) deleteRuneForward() {
- e.rr.deleteRuneForward()
- e.carXOff = 0
+// Insert inserts text at the caret, moving the caret forward.
+func (e *Editor) Insert(s string) {
+ e.append(s)
+ e.caretScroll = true
e.invalidate()
}
@@ -549,13 +584,10 @@ func (e *Editor) moveToLine(carX fixed.Int26_6, carLine2 int) fixed.Int26_6 {
return carX - carX2
}
-func (e *Editor) moveLeft() {
- e.rr.moveLeft()
- e.carXOff = 0
-}
-
-func (e *Editor) moveRight() {
- e.rr.moveRight()
+// Move the caret: positive distance moves forward, negative distance moves
+// backward.
+func (e *Editor) Move(distance int) {
+ e.rr.move(distance)
e.carXOff = 0
}
@@ -612,37 +644,5 @@ func (e *Editor) scrollToCaret() {
}
}
-func (e *Editor) command(k key.Event) bool {
- switch k.Name {
- case key.NameReturn, key.NameEnter:
- e.append("\n")
- case key.NameDeleteBackward:
- e.deleteRune()
- case key.NameDeleteForward:
- e.deleteRuneForward()
- case key.NameUpArrow:
- line, _, carX, _ := e.layoutCaret()
- e.carXOff = e.moveToLine(carX+e.carXOff, line-1)
- case key.NameDownArrow:
- line, _, carX, _ := e.layoutCaret()
- e.carXOff = e.moveToLine(carX+e.carXOff, line+1)
- case key.NameLeftArrow:
- e.moveLeft()
- case key.NameRightArrow:
- e.moveRight()
- case key.NamePageUp:
- e.movePages(-1)
- case key.NamePageDown:
- e.movePages(+1)
- case key.NameHome:
- e.moveStart()
- case key.NameEnd:
- e.moveEnd()
- default:
- return false
- }
- return true
-}
-
func (s ChangeEvent) isEditorEvent() {}
func (s SubmitEvent) isEditorEvent() {}
--
2.23.0
Thank you for your patience :) Applied.