114 lines
2.1 KiB
Go
114 lines
2.1 KiB
Go
|
package termui
|
||
|
|
||
|
import (
|
||
|
"image"
|
||
|
"strings"
|
||
|
"unicode/utf8"
|
||
|
|
||
|
"github.com/cjbassi/gotop/src/utils"
|
||
|
. "github.com/gizak/termui/v3"
|
||
|
rw "github.com/mattn/go-runewidth"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
ELLIPSIS = "…"
|
||
|
CURSOR = " "
|
||
|
)
|
||
|
|
||
|
type Entry struct {
|
||
|
Block
|
||
|
|
||
|
Style Style
|
||
|
|
||
|
Label string
|
||
|
Value string
|
||
|
ShowWhenEmpty bool
|
||
|
UpdateCallback func(string)
|
||
|
|
||
|
editing bool
|
||
|
}
|
||
|
|
||
|
func (self *Entry) SetEditing(editing bool) {
|
||
|
self.editing = editing
|
||
|
}
|
||
|
|
||
|
func (self *Entry) update() {
|
||
|
if self.UpdateCallback != nil {
|
||
|
self.UpdateCallback(self.Value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// HandleEvent handles input events if the entry is being edited.
|
||
|
// Returns true if the event was handled.
|
||
|
func (self *Entry) HandleEvent(e Event) bool {
|
||
|
if !self.editing {
|
||
|
return false
|
||
|
}
|
||
|
if utf8.RuneCountInString(e.ID) == 1 {
|
||
|
self.Value += e.ID
|
||
|
self.update()
|
||
|
return true
|
||
|
}
|
||
|
switch e.ID {
|
||
|
case "<C-c>", "<Escape>":
|
||
|
self.Value = ""
|
||
|
self.editing = false
|
||
|
self.update()
|
||
|
case "<Enter>":
|
||
|
self.editing = false
|
||
|
case "<Backspace>":
|
||
|
if self.Value != "" {
|
||
|
r := []rune(self.Value)
|
||
|
self.Value = string(r[:len(r)-1])
|
||
|
self.update()
|
||
|
}
|
||
|
case "<Space>":
|
||
|
self.Value += " "
|
||
|
self.update()
|
||
|
default:
|
||
|
return false
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func (self *Entry) Draw(buf *Buffer) {
|
||
|
if self.Value == "" && !self.editing && !self.ShowWhenEmpty {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
style := self.Style
|
||
|
label := self.Label
|
||
|
if self.editing {
|
||
|
label += "["
|
||
|
style = NewStyle(style.Fg, style.Bg, ModifierBold)
|
||
|
}
|
||
|
cursorStyle := NewStyle(style.Bg, style.Fg, ModifierClear)
|
||
|
|
||
|
p := image.Pt(self.Min.X, self.Min.Y)
|
||
|
buf.SetString(label, style, p)
|
||
|
p.X += rw.StringWidth(label)
|
||
|
|
||
|
tail := " "
|
||
|
if self.editing {
|
||
|
tail = "] "
|
||
|
}
|
||
|
|
||
|
maxLen := self.Max.X - p.X - rw.StringWidth(tail)
|
||
|
if self.editing {
|
||
|
maxLen -= 1 // for cursor
|
||
|
}
|
||
|
value := utils.TruncateFront(self.Value, maxLen, ELLIPSIS)
|
||
|
buf.SetString(value, self.Style, p)
|
||
|
p.X += rw.StringWidth(value)
|
||
|
|
||
|
if self.editing {
|
||
|
buf.SetString(CURSOR, cursorStyle, p)
|
||
|
p.X += rw.StringWidth(CURSOR)
|
||
|
if remaining := maxLen - rw.StringWidth(value); remaining > 0 {
|
||
|
buf.SetString(strings.Repeat(" ", remaining), self.TitleStyle, p)
|
||
|
p.X += remaining
|
||
|
}
|
||
|
}
|
||
|
buf.SetString(tail, style, p)
|
||
|
}
|