@@ 49,6 49,9 @@ type Editor struct {
InputHint key.InputHint
// MaxLen limits the editor content to a maximum length. Zero means no limit.
MaxLen int
+ // Filter is the list of characters allowed in the Editor. If Filter is empty,
+ // all characters are allowed.
+ Filter string
eventKey int
font text.Font
@@ 1235,12 1238,21 @@ func (e *Editor) replace(start, end int, s string, addHistory bool) int {
startPos := e.closestPosition(combinedPos{runes: start})
endPos := e.closestPosition(combinedPos{runes: end})
startOff := e.runeOffset(startPos.runes)
- sc := utf8.RuneCountInString(s)
el := e.Len()
- for e.MaxLen > 0 && el+sc > e.MaxLen {
- _, n := utf8.DecodeLastRuneInString(s)
- s = s[:len(s)-n]
- sc--
+ var sc int
+ idx := 0
+ for idx < len(s) {
+ if e.MaxLen > 0 && el+sc >= e.MaxLen {
+ s = s[:idx]
+ break
+ }
+ _, n := utf8.DecodeRuneInString(s[idx:])
+ if e.Filter != "" && !strings.Contains(e.Filter, s[idx:idx+n]) {
+ s = s[:idx] + s[idx+n:]
+ continue
+ }
+ idx += n
+ sc++
}
newEnd := startPos.runes + sc
replaceSize := endPos.runes - startPos.runes
@@ 1036,6 1036,37 @@ func TestEditor_MaxLen(t *testing.T) {
}
}
+func TestEditor_Filter(t *testing.T) {
+ e := new(Editor)
+
+ e.Filter = "123456789"
+ e.SetText("abcde1234")
+ if got, want := e.Text(), "1234"; got != want {
+ t.Errorf("editor failed to filter SetText")
+ }
+
+ e.SetText("2345678")
+ gtx := layout.Context{
+ Ops: new(op.Ops),
+ Constraints: layout.Exact(image.Pt(100, 100)),
+ Queue: newQueue(
+ key.EditEvent{Range: key.Range{Start: 0, End: 0}, Text: "ab1"},
+ key.SelectionEvent{Start: 4, End: 4},
+ ),
+ }
+ cache := text.NewCache(gofont.Collection())
+ fontSize := unit.Sp(10)
+ font := text.Font{}
+ e.Layout(gtx, cache, font, fontSize, nil)
+
+ if got, want := e.Text(), "12345678"; got != want {
+ t.Errorf("editor failed to filter EditEvent")
+ }
+ if start, end := e.Selection(); start != 2 || end != 2 {
+ t.Errorf("editor failed to adjust SelectionEvent")
+ }
+}
+
func textWidth(e *Editor, lineNum, colStart, colEnd int) float32 {
var w fixed.Int26_6
glyphs := e.lines[lineNum].Layout.Glyphs