1package termui
  2
  3import (
  4	"errors"
  5	"io/ioutil"
  6
  7	"github.com/awesome-gocui/gocui"
  8)
  9
 10const inputPopupView = "inputPopupView"
 11
 12// inputPopup is a simple popup with an input field
 13type inputPopup struct {
 14	active  bool
 15	title   string
 16	preload string
 17	c       chan string
 18}
 19
 20func newInputPopup() *inputPopup {
 21	return &inputPopup{}
 22}
 23
 24func (ip *inputPopup) keybindings(g *gocui.Gui) error {
 25	// Close
 26	if err := g.SetKeybinding(inputPopupView, gocui.KeyEsc, gocui.ModNone, ip.close); err != nil {
 27		return err
 28	}
 29
 30	// Validate
 31	if err := g.SetKeybinding(inputPopupView, gocui.KeyEnter, gocui.ModNone, ip.validate); err != nil {
 32		return err
 33	}
 34
 35	return nil
 36}
 37
 38func (ip *inputPopup) layout(g *gocui.Gui) error {
 39	if !ip.active {
 40		return nil
 41	}
 42
 43	maxX, maxY := g.Size()
 44
 45	width := minInt(30, maxX)
 46	height := 2
 47	x0 := (maxX - width) / 2
 48	y0 := (maxY - height) / 2
 49
 50	v, err := g.SetView(inputPopupView, x0, y0, x0+width, y0+height, 0)
 51	if err != nil {
 52		if !errors.Is(err, gocui.ErrUnknownView) {
 53			return err
 54		}
 55
 56		v.Frame = true
 57		v.Title = ip.title
 58		v.Editable = true
 59		_, err = v.Write([]byte(ip.preload))
 60		if err != nil {
 61			return err
 62		}
 63	}
 64
 65	if _, err := g.SetCurrentView(inputPopupView); err != nil {
 66		return err
 67	}
 68
 69	return nil
 70}
 71
 72func (ip *inputPopup) close(g *gocui.Gui, v *gocui.View) error {
 73	ip.title = ""
 74	ip.active = false
 75	return g.DeleteView(inputPopupView)
 76}
 77
 78func (ip *inputPopup) validate(g *gocui.Gui, v *gocui.View) error {
 79	ip.title = ""
 80
 81	content, err := ioutil.ReadAll(v)
 82	if err != nil {
 83		return err
 84	}
 85
 86	ip.title = ""
 87	ip.active = false
 88	err = g.DeleteView(inputPopupView)
 89	if err != nil {
 90		return err
 91	}
 92
 93	ip.c <- string(content)
 94
 95	return nil
 96}
 97
 98func (ip *inputPopup) ActivateWithContent(title string, content string) <-chan string {
 99	ip.preload = content
100	return ip.Activate(title)
101}
102
103func (ip *inputPopup) Activate(title string) <-chan string {
104	ip.title = title
105	ip.active = true
106	ip.c = make(chan string)
107	return ip.c
108}