input.go raw
1 package gel
2
3 import (
4 "regexp"
5
6 "golang.org/x/exp/shiny/materialdesign/icons"
7
8 l "github.com/p9c/gio/layout"
9 )
10
11 type Input struct {
12 *Window
13 editor *Editor
14 input *TextInput
15 clearClickable *Clickable
16 clearButton *IconButton
17 copyClickable *Clickable
18 copyButton *IconButton
19 pasteClickable *Clickable
20 pasteButton *IconButton
21 GetText func() string
22 SetText func(string)
23 SetPasteFunc func() bool
24 borderColor string
25 borderColorUnfocused string
26 borderColorFocused string
27 backgroundColor string
28 focused bool
29 }
30
31 var findSpaceRegexp = regexp.MustCompile(`\s+`)
32
33 func (w *Window) Input(
34 txt, hint, borderColorFocused, borderColorUnfocused, backgroundColor string,
35 submit, change func(txt string),
36 ) *Input {
37 editor := w.Editor().SingleLine().Submit(false)
38 input := w.TextInput(editor, hint).TextScale(1)
39 p := &Input{
40 Window: w,
41 clearClickable: w.Clickable(),
42 copyClickable: w.Clickable(),
43 pasteClickable: w.Clickable(),
44 editor: editor,
45 input: input,
46 borderColorUnfocused: borderColorUnfocused,
47 borderColorFocused: borderColorFocused,
48 backgroundColor: backgroundColor,
49 }
50 p.GetText = func() string {
51 return p.editor.Text()
52 }
53 p.SetText = func(s string) {
54 p.editor.SetText(s)
55 }
56 p.clearButton = w.IconButton(p.clearClickable)
57 p.copyButton = w.IconButton(p.copyClickable)
58 p.pasteButton = w.IconButton(p.pasteClickable)
59 clearClickableFn := func() {
60 p.editor.SetText("")
61 p.editor.changeHook("")
62 p.editor.Focus()
63 }
64 copyClickableFn := func() {
65 p.ClipboardWriteReqs <- p.editor.Text()
66 p.editor.Focus()
67 }
68 pasteClickableFn := func() {
69 p.ClipboardReadReqs <- func(cs string) {
70 cs = findSpaceRegexp.ReplaceAllString(cs, " ")
71 p.editor.Insert(cs)
72 p.editor.changeHook(cs)
73 p.editor.Focus()
74 }
75 }
76 p.clearButton.
77 Icon(
78 w.Icon().
79 Color("DocText").
80 Src(&icons.ContentBackspace),
81 )
82 p.copyButton.
83 Icon(
84 w.Icon().
85 Color("DocText").
86 Src(&icons.ContentContentCopy),
87 )
88 p.pasteButton.
89 Icon(
90 w.Icon().
91 Color("DocText").
92 Src(&icons.ContentContentPaste),
93 )
94 p.input.Color("DocText")
95 p.clearClickable.SetClick(clearClickableFn)
96 p.copyClickable.SetClick(copyClickableFn)
97 p.pasteClickable.SetClick(pasteClickableFn)
98 p.editor.SetText(txt).SetSubmit(
99 func(txt string) {
100 go func() {
101 submit(txt)
102 }()
103 },
104 ).SetChange(
105 change,
106 )
107 p.editor.SetFocus(
108 func(is bool) {
109 if is {
110 p.borderColor = p.borderColorFocused
111 } else {
112 p.borderColor = p.borderColorUnfocused
113 }
114 },
115 )
116 return p
117 }
118
119 // Fn renders the input widget
120 func (in *Input) Fn(gtx l.Context) l.Dimensions {
121 // gtx.Constraints.Max.X = int(in.TextSize.Scale(float32(in.size)).True)
122 // gtx.Constraints.Min.X = 0
123 // width := int(in.Theme.TextSize.Scale(in.size).True)
124 // gtx.Constraints.Max.X, gtx.Constraints.Min.X = width, width
125 return in.Border().
126 Width(0.125).
127 CornerRadius(0.0).
128 Color(in.borderColor).
129 Embed(
130 in.Fill(
131 in.backgroundColor, l.Center, in.TextSize.V, 0,
132 in.Inset(
133 0.25,
134 in.Flex().
135 Flexed(
136 1,
137 in.Inset(0.125, in.input.Color("DocText").Fn).Fn,
138 ).
139 Rigid(
140 in.copyButton.
141 Background("").
142 Icon(in.Icon().Color(in.borderColor).Scale(Scales["H6"]).Src(&icons.ContentContentCopy)).
143 ButtonInset(0.25).
144 Fn,
145 ).
146 Rigid(
147 in.pasteButton.
148 Background("").
149 Icon(in.Icon().Color(in.borderColor).Scale(Scales["H6"]).Src(&icons.ContentContentPaste)).
150 ButtonInset(0.25).
151 Fn,
152 ).
153 Rigid(
154 in.clearButton.
155 Background("").
156 Icon(in.Icon().Color(in.borderColor).Scale(Scales["H6"]).Src(&icons.ContentBackspace)).
157 ButtonInset(0.25).
158 Fn,
159 ).
160 Fn,
161 ).Fn,
162 ).Fn,
163 ).Fn(gtx)
164 }
165