diff options
author | Sean E. Russell <ser@ser1.net> | 2020-02-14 09:35:58 -0600 |
---|---|---|
committer | Sean E. Russell <ser@ser1.net> | 2020-02-14 09:35:58 -0600 |
commit | f850a47d91d413de40de219aa597ade41a05f757 (patch) | |
tree | fa15d4e8ddc62888788d6814e4ab3c010931d892 /termui | |
parent | 64d4a81212a43a4b805b92963fd4da230b3ca313 (diff) | |
parent | 246ebfbff2c87f66218c42ea9490214006f2efc8 (diff) |
Merge remote-tracking branch 'rephorm/filter'
Diffstat (limited to 'termui')
-rw-r--r-- | termui/entry.go | 113 | ||||
-rw-r--r-- | termui/table.go | 3 |
2 files changed, 116 insertions, 0 deletions
diff --git a/termui/entry.go b/termui/entry.go new file mode 100644 index 0000000..2ba4ecc --- /dev/null +++ b/termui/entry.go @@ -0,0 +1,113 @@ +package termui + +import ( + "image" + "strings" + "unicode/utf8" + + . "github.com/gizak/termui/v3" + rw "github.com/mattn/go-runewidth" + "github.com/xxxserxxx/gotop/utils" +) + +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) +} diff --git a/termui/table.go b/termui/table.go index eeb82af..e587839 100644 --- a/termui/table.go +++ b/termui/table.go @@ -131,6 +131,9 @@ func (self *Table) Draw(buf *Buffer) { func (self *Table) drawLocation(buf *Buffer) { total := len(self.Rows) topRow := self.TopRow + 1 + if topRow > total { + topRow = total + } bottomRow := self.TopRow + self.Inner.Dy() - 1 if bottomRow > total { bottomRow = total |