1package termui
2
3import (
4 "errors"
5 "io"
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 := io.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}