123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- package door
- import (
- "fmt"
- "log"
- "strconv"
- "strings"
- "time"
- "unicode"
- )
- // See door.go for DEBUG_INPUT const
- var ErrInactivity error = fmt.Errorf("Inactivity")
- var ErrTimeout error = fmt.Errorf("Timeout")
- var ErrDisconnected error = fmt.Errorf("Disconnected")
- var DefaultTimeout time.Duration = time.Duration(60) * time.Second
- func (d *Door) WaitKey(timeout time.Duration) (rune, Extended, error) {
- /*
- d.readerMutex.Lock()
- if d.ReaderClosed {
- d.readerMutex.Unlock()
- return 0, NOP, ErrDisconnected
- }
- d.readerMutex.Unlock()
- */
- // Probably faster to just read from closed channel and get ok = false.
- select {
- case r, ok := <-d.readerChannel:
- if ok {
- if DEBUG_INPUT {
- log.Println("WaitKey:", r)
- }
- // return bio.GetKey()
- return r.R, r.Ex, r.Err
- } else {
- log.Println("WaitKey: Disconnected")
- // Reader has closed.
- // Disconnected = true
- return 0, NOP, ErrDisconnected
- }
- case <-time.After(timeout):
- return 0, NOP, ErrTimeout
- }
- }
- // Outputs spaces and backspaces
- // If you have set a background color, this shows the input area.
- func DisplayInput(max int) string {
- return strings.Repeat(" ", max) + strings.Repeat("\x08", max)
- }
- // Input a string of max length.
- // This displays the input area if a bg color was set.
- // This handles timeout, input, backspace, and enter.
- func (d *Door) Input(max int) string {
- var line []rune = make([]rune, 0, max)
- var length int
- // draw input area
- d.Write(DisplayInput(max))
- var r rune
- var ex Extended
- var err error
- for {
- r, ex, err = d.WaitKey(DefaultTimeout)
- if err != nil {
- // timeout/hangup
- return ""
- }
- if ex != NOP {
- continue
- }
- uw := UnicodeWidth(r)
- if strconv.IsPrint(r) {
- if length+uw <= max {
- d.Write(string(r))
- line = append(line, r)
- length += uw
- } else {
- d.Write("\x07")
- }
- } else {
- // Non-print
- switch r {
- case 0x7f, 0x08:
- if len(line) > 0 {
- d.Write("\x08 \x08")
- rlen := len(line)
- if UnicodeWidth(line[rlen-1]) == 2 {
- d.Write("\x08 \x08")
- length -= 2
- } else {
- length--
- }
- line = line[0 : rlen-1]
- }
- case 0x0d:
- return string(line)
- }
- }
- }
- }
- func (d *Door) GetOneOf(possible string) rune {
- var r rune
- var err error
- for {
- r, _, err = d.WaitKey(DefaultTimeout)
- if err != nil {
- return rune(0)
- }
- r := unicode.ToUpper(r)
- if strings.ContainsRune(possible, r) {
- // return upper case rune
- return r
- }
- }
- }
|