Added masking to InputField, password field to form. Resolves #7, resolves #8.

This commit is contained in:
Oliver 2018-01-11 16:13:01 +01:00
parent 61d8ea30f8
commit d6ce974e6d
4 changed files with 44 additions and 3 deletions

View File

@ -12,6 +12,7 @@ func main() {
AddInputField("First name", "", 20, nil, nil).
AddInputField("Last name", "", 20, nil, nil).
AddCheckbox("Age 18+", false, nil).
AddPasswordField("Password", "", 10, '*', nil).
AddButton("Save", nil).
AddButton("Quit", func() {
app.Stop()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 29 KiB

22
form.go
View File

@ -138,7 +138,27 @@ func (f *Form) AddInputField(label, value string, fieldLength int, accept func(t
SetLabel(label).
SetText(value).
SetFieldLength(fieldLength).
SetAcceptanceFunc(accept))
SetAcceptanceFunc(accept).
SetChangedFunc(changed))
return f
}
// AddPasswordField adds a password field to the form. This is similar to an
// input field except that the user's input not shown. Instead, a "mask"
// character is displayed. The password field has a label, an optional initial
// value, a field length (a value of 0 extends it as far as possible), and an
// (optional) callback function which is invoked when the input field's text has
// changed.
func (f *Form) AddPasswordField(label, value string, fieldLength int, mask rune, changed func(text string)) *Form {
if mask == 0 {
mask = '*'
}
f.items = append(f.items, NewInputField().
SetLabel(label).
SetText(value).
SetFieldLength(fieldLength).
SetMaskCharacter(mask).
SetChangedFunc(changed))
return f
}

View File

@ -3,6 +3,8 @@ package tview
import (
"math"
"regexp"
"strings"
"unicode/utf8"
"github.com/gdamore/tcell"
runewidth "github.com/mattn/go-runewidth"
@ -11,6 +13,9 @@ import (
// InputField is a one-line box (three lines if there is a title) where the
// user can enter text.
//
// Use SetMaskCharacter() to hide input from onlookers (e.g. for password
// input).
//
// See https://github.com/rivo/tview/wiki/InputField for an example.
type InputField struct {
*Box
@ -34,6 +39,10 @@ type InputField struct {
// possible.
fieldLength int
// A character to mask entered text (useful for password fields). A value of 0
// disables masking.
maskCharacter rune
// An optional function which may reject the last character that was entered.
accept func(text string, ch rune) bool
@ -116,6 +125,13 @@ func (i *InputField) SetFieldLength(length int) *InputField {
return i
}
// SetMaskCharacter sets a character that masks user input on a screen. A value
// of 0 disables masking.
func (i *InputField) SetMaskCharacter(mask rune) *InputField {
i.maskCharacter = mask
return i
}
// SetAcceptanceFunc sets a handler which may reject the last character that was
// entered (by returning false).
//
@ -180,11 +196,15 @@ func (i *InputField) Draw(screen tcell.Screen) {
}
// Draw entered text.
text := i.text
if i.maskCharacter > 0 {
text = strings.Repeat(string(i.maskCharacter), utf8.RuneCountInString(i.text))
}
fieldLength-- // We need one cell for the cursor.
if fieldLength < runewidth.StringWidth(i.text) {
Print(screen, i.text, x, y, fieldLength, AlignRight, i.fieldTextColor)
Print(screen, text, x, y, fieldLength, AlignRight, i.fieldTextColor)
} else {
Print(screen, i.text, x, y, fieldLength, AlignLeft, i.fieldTextColor)
Print(screen, text, x, y, fieldLength, AlignLeft, i.fieldTextColor)
}
// Set cursor.