summaryrefslogtreecommitdiffstats
path: root/termui
diff options
context:
space:
mode:
authorSean E. Russell <ser@ser1.net>2020-02-14 09:35:58 -0600
committerSean E. Russell <ser@ser1.net>2020-02-14 09:35:58 -0600
commitf850a47d91d413de40de219aa597ade41a05f757 (patch)
treefa15d4e8ddc62888788d6814e4ab3c010931d892 /termui
parent64d4a81212a43a4b805b92963fd4da230b3ca313 (diff)
parent246ebfbff2c87f66218c42ea9490214006f2efc8 (diff)
Merge remote-tracking branch 'rephorm/filter'
Diffstat (limited to 'termui')
-rw-r--r--termui/entry.go113
-rw-r--r--termui/table.go3
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