package termui import ( "image" "strings" "unicode/utf8" . "github.com/gizak/termui/v3" rw "github.com/mattn/go-runewidth" "github.com/xxxserxxx/gotop/v4/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 "", "": self.Value = "" self.editing = false self.update() case "": self.editing = false case "": if self.Value != "" { r := []rune(self.Value) self.Value = string(r[:len(r)-1]) self.update() } case "": 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) }