...
1 package etk
2
3 import (
4 "image"
5 "image/color"
6
7 "code.rocket9labs.com/tslocum/etk/messeji"
8 "github.com/hajimehoshi/ebiten/v2"
9 "golang.org/x/image/font/sfnt"
10 )
11
12
13
14 type Input struct {
15 *Box
16 field *messeji.InputField
17 cursor string
18 borderSize int
19 borderFocused color.RGBA
20 borderUnfocused color.RGBA
21 focus bool
22 }
23
24
25 func NewInput(text string, onSelected func(text string) (handled bool)) *Input {
26 textColor := Style.TextColorDark
27
30
31 f := messeji.NewInputField(FontFace(Style.TextFont, Scale(Style.TextSize)), fontMutex)
32 f.SetForegroundColor(textColor)
33 f.SetBackgroundColor(transparent)
34 f.SetScrollBarColors(Style.ScrollAreaColor, Style.ScrollHandleColor)
35 f.SetScrollBorderSize(Scale(Style.ScrollBorderSize))
36 f.SetScrollBorderColors(Style.ScrollBorderTop, Style.ScrollBorderRight, Style.ScrollBorderBottom, Style.ScrollBorderLeft)
37 f.SetPrefix("")
38 f.SetSuffix("")
39 f.SetText(text)
40 f.SetHandleKeyboard(true)
41 f.SetSelectedFunc(func() (accept bool) {
42 return onSelected(f.Text())
43 })
44
45 i := &Input{
46 Box: NewBox(),
47 field: f,
48 cursor: "_",
49 borderSize: Scale(Style.InputBorderSize),
50 borderFocused: Style.InputBorderFocused,
51 borderUnfocused: Style.InputBorderUnfocused,
52 }
53 i.SetBackground(Style.InputBgColor)
54 return i
55 }
56
57
58 func (i *Input) SetRect(r image.Rectangle) {
59 i.Box.rect = r
60
61 i.field.SetRect(r)
62
63 for _, w := range i.children {
64 w.SetRect(r)
65 }
66 }
67
68
69 func (i *Input) SetBorderSize(size int) {
70 i.Lock()
71 defer i.Unlock()
72
73 i.borderSize = size
74 }
75
76
77 func (i *Input) SetBorderColors(focused color.RGBA, unfocused color.RGBA) {
78 i.Lock()
79 defer i.Unlock()
80
81 i.borderFocused = focused
82 i.borderUnfocused = unfocused
83 }
84
85
86 func (i *Input) Foreground() color.RGBA {
87 i.Lock()
88 defer i.Unlock()
89
90 return i.field.ForegroundColor()
91 }
92
93
94 func (i *Input) SetForeground(c color.RGBA) {
95 i.Lock()
96 defer i.Unlock()
97
98 i.field.SetForegroundColor(c)
99 }
100
101
102 func (i *Input) SetPrefix(prefix string) {
103 i.Lock()
104 defer i.Unlock()
105
106 i.field.SetPrefix(prefix)
107 }
108
109
110 func (i *Input) SetSuffix(suffix string) {
111 i.Lock()
112 defer i.Unlock()
113
114 i.field.SetSuffix(suffix)
115 }
116
117
118 func (i *Input) SetCursor(cursor string) {
119 i.Lock()
120 defer i.Unlock()
121
122 i.cursor = cursor
123 if i.focus {
124 i.field.SetSuffix(cursor)
125 }
126 }
127
128
129 func (i *Input) Focus() bool {
130 return i.focus
131 }
132
133
134 func (i *Input) SetFocus(focus bool) bool {
135 i.focus = focus
136
137 var cursor string
138 if focus {
139 cursor = i.cursor
140 }
141 i.field.SetSuffix(cursor)
142 return true
143 }
144
145
146 func (i *Input) Text() string {
147 i.Lock()
148 defer i.Unlock()
149
150 return i.field.Text()
151 }
152
153
154 func (i *Input) SetText(text string) {
155 i.Lock()
156 defer i.Unlock()
157
158 i.field.SetText(text)
159 }
160
161
162 func (i *Input) SetScrollBarWidth(width int) {
163 i.Lock()
164 defer i.Unlock()
165
166 i.field.SetScrollBarWidth(width)
167 }
168
169
170 func (i *Input) SetScrollBarColors(area color.RGBA, handle color.RGBA) {
171 i.Lock()
172 defer i.Unlock()
173
174 i.field.SetScrollBarColors(Style.ScrollAreaColor, Style.ScrollHandleColor)
175 }
176
177
178 func (i *Input) SetScrollBarVisible(scrollVisible bool) {
179 i.Lock()
180 defer i.Unlock()
181
182 i.field.SetScrollBarVisible(scrollVisible)
183 }
184
185
186
187 func (i *Input) SetAutoHideScrollBar(autoHide bool) {
188 i.Lock()
189 defer i.Unlock()
190
191 i.field.SetAutoHideScrollBar(autoHide)
192 }
193
194
195 func (t *Input) SetFont(fnt *sfnt.Font, size int) {
196 t.Lock()
197 defer t.Unlock()
198
199 t.field.SetFont(FontFace(fnt, size), fontMutex)
200 }
201
202
203 func (i *Input) Padding() int {
204 i.Lock()
205 defer i.Unlock()
206
207 return i.field.Padding()
208 }
209
210
211 func (i *Input) SetPadding(padding int) {
212 i.Lock()
213 defer i.Unlock()
214
215 i.field.SetPadding(padding)
216 }
217
218
219 func (i *Input) SetWordWrap(wrap bool) {
220 i.Lock()
221 defer i.Unlock()
222
223 i.field.SetWordWrap(wrap)
224 }
225
226
227 func (i *Input) SetHorizontal(h Alignment) {
228 i.Lock()
229 defer i.Unlock()
230
231 i.field.SetHorizontal(messeji.Alignment(h))
232 }
233
234
235 func (i *Input) SetVertical(v Alignment) {
236 i.Lock()
237 defer i.Unlock()
238
239 i.field.SetVertical(messeji.Alignment(v))
240 }
241
242
243 func (i *Input) SetMask(r rune) {
244 i.Lock()
245 defer i.Unlock()
246
247 i.field.SetMask(r)
248 }
249
250
251
252 func (i *Input) Cursor() ebiten.CursorShapeType {
253 return ebiten.CursorShapeText
254 }
255
256
257 func (i *Input) Write(p []byte) (n int, err error) {
258 return i.field.Write(p)
259 }
260
261
262 func (i *Input) HandleKeyboard(key ebiten.Key, r rune) (handled bool, err error) {
263 if !i.focus {
264 return false, nil
265 }
266
267 return i.field.HandleKeyboardEvent(key, r)
268 }
269
270
271 func (i *Input) HandleMouse(cursor image.Point, pressed bool, clicked bool) (handled bool, err error) {
272 return i.field.HandleMouseEvent(cursor, pressed, clicked)
273 }
274
275
276 func (i *Input) Draw(screen *ebiten.Image) error {
277 i.field.Draw(screen)
278
279
280 if i.borderSize == 0 {
281 return nil
282 }
283 r := i.rect
284 c := i.borderUnfocused
285 if i.focus {
286 c = i.borderFocused
287 }
288 screen.SubImage(image.Rect(r.Min.X, r.Min.Y, r.Min.X+i.borderSize, r.Max.Y)).(*ebiten.Image).Fill(c)
289 screen.SubImage(image.Rect(r.Min.X, r.Min.Y, r.Max.X, r.Min.Y+i.borderSize)).(*ebiten.Image).Fill(c)
290 screen.SubImage(image.Rect(r.Max.X-i.borderSize, r.Min.Y, r.Max.X, r.Max.Y)).(*ebiten.Image).Fill(c)
291 screen.SubImage(image.Rect(r.Min.X, r.Max.Y-i.borderSize, r.Max.X, r.Max.Y)).(*ebiten.Image).Fill(c)
292 return nil
293 }
294
View as plain text