textinput.go raw
1 package gel
2
3 import (
4 "image/color"
5
6 l "github.com/p9c/gio/layout"
7 "github.com/p9c/gio/op"
8 "github.com/p9c/gio/op/paint"
9 "github.com/p9c/gio/text"
10 "github.com/p9c/gio/unit"
11
12 "github.com/p9c/gel/f32color"
13 )
14
15 // TextInput is a simple text input widget
16 type TextInput struct {
17 *Window
18 font text.Font
19 textSize unit.Value
20 // Color is the text color.
21 color color.NRGBA
22 // Hint contains the text displayed when the editor is empty.
23 hint string
24 // HintColor is the color of hint text.
25 hintColor color.NRGBA
26 // SelectionColor is the color of the background for selected text.
27 selectionColor color.NRGBA
28 editor *Editor
29 shaper text.Shaper
30 }
31
32 // TextInput creates a simple text input widget
33 func (w *Window) TextInput(editor *Editor, hint string) *TextInput {
34 var fon text.Font
35 var e error
36 if fon, e = w.collection.Font("bariol regular"); E.Chk(e) {
37 panic(e)
38 }
39 ti := &TextInput{
40 Window: w,
41 editor: editor,
42 textSize: w.TextSize,
43 font: fon,
44 color: w.Colors.GetNRGBAFromName("DocText"),
45 shaper: w.shaper,
46 hint: hint,
47 hintColor: w.Colors.GetNRGBAFromName("Hint"),
48 selectionColor: w.Colors.GetNRGBAFromName("scrim"),
49 }
50 ti.Font("bariol regular")
51 return ti
52 }
53
54 // Font sets the font for the text input widget
55 func (ti *TextInput) Font(font string) *TextInput {
56 var fon text.Font
57 var e error
58 if fon, e = ti.Theme.collection.Font(font); !E.Chk(e) {
59 ti.editor.font = fon
60 }
61 return ti
62 }
63
64 // TextScale sets the size of the text relative to the base font size
65 func (ti *TextInput) TextScale(scale float32) *TextInput {
66 ti.textSize = ti.Theme.TextSize.Scale(scale)
67 return ti
68 }
69
70 // Color sets the color to render the text
71 func (ti *TextInput) Color(color string) *TextInput {
72 ti.color = ti.Theme.Colors.GetNRGBAFromName(color)
73 return ti
74 }
75
76 // SelectionColor sets the color to render the text
77 func (ti *TextInput) SelectionColor(color string) *TextInput {
78 ti.selectionColor = ti.Theme.Colors.GetNRGBAFromName(color)
79 return ti
80 }
81
82 // Hint sets the text to show when the box is empty
83 func (ti *TextInput) Hint(hint string) *TextInput {
84 ti.hint = hint
85 return ti
86 }
87
88 // HintColor sets the color of the hint text
89 func (ti *TextInput) HintColor(color string) *TextInput {
90 ti.hintColor = ti.Theme.Colors.GetNRGBAFromName(color)
91 return ti
92 }
93
94 // Fn renders the text input widget
95 func (ti *TextInput) Fn(gtx l.Context) l.Dimensions {
96 defer op.Save(gtx.Ops).Load()
97 macro := op.Record(gtx.Ops)
98 paint.ColorOp{Color: ti.hintColor}.Add(gtx.Ops)
99 var maxlines int
100 if ti.editor.singleLine {
101 maxlines = 1
102 }
103 tl := Label{
104 Window: ti.Window,
105 font: ti.font,
106 color: ti.hintColor,
107 alignment: ti.editor.alignment,
108 maxLines: maxlines,
109 text: ti.hint,
110 textSize: ti.textSize,
111 shaper: ti.shaper,
112 }
113 dims := tl.Fn(gtx)
114 call := macro.Stop()
115 if w := dims.Size.X; gtx.Constraints.Min.X < w {
116 gtx.Constraints.Min.X = w
117 }
118 if h := dims.Size.Y; gtx.Constraints.Min.Y < h {
119 gtx.Constraints.Min.Y = h
120 }
121 dims = ti.editor.Layout(gtx, ti.shaper, ti.font, ti.textSize)
122 disabled := gtx.Queue == nil
123 if ti.editor.Len() > 0 {
124 paint.ColorOp{Color: blendDisabledColor(disabled, ti.selectionColor)}.Add(gtx.Ops)
125 ti.editor.PaintSelection(gtx)
126 paint.ColorOp{Color: blendDisabledColor(disabled, ti.color)}.Add(gtx.Ops)
127 ti.editor.PaintText(gtx)
128 } else {
129 call.Add(gtx.Ops)
130 }
131 if !disabled {
132 paint.ColorOp{Color: ti.color}.Add(gtx.Ops)
133 ti.editor.PaintCaret(gtx)
134 }
135 return dims
136 }
137
138 func blendDisabledColor(disabled bool, c color.NRGBA) color.NRGBA {
139 if disabled {
140 return f32color.Disabled(c)
141 }
142 return c
143 }
144