...
1 package cview
2
3 import (
4 "sync"
5
6 "github.com/gdamore/tcell/v2"
7 )
8
9
10 type Button struct {
11 *Box
12
13
14 label []byte
15
16
17 labelColor tcell.Color
18
19
20 labelColorFocused tcell.Color
21
22
23 backgroundColorFocused tcell.Color
24
25
26 selected func()
27
28
29
30 blur func(tcell.Key)
31
32
33 cursorRune rune
34
35 sync.RWMutex
36 }
37
38
39 func NewButton(label string) *Button {
40 box := NewBox()
41 box.SetRect(0, 0, TaggedStringWidth(label)+4, 1)
42 box.SetBackgroundColor(Styles.MoreContrastBackgroundColor)
43 return &Button{
44 Box: box,
45 label: []byte(label),
46 labelColor: Styles.PrimaryTextColor,
47 labelColorFocused: Styles.PrimaryTextColor,
48 cursorRune: Styles.ButtonCursorRune,
49 backgroundColorFocused: Styles.ContrastBackgroundColor,
50 }
51 }
52
53
54 func (b *Button) SetLabel(label string) {
55 b.Lock()
56 defer b.Unlock()
57
58 b.label = []byte(label)
59 }
60
61
62 func (b *Button) GetLabel() string {
63 b.RLock()
64 defer b.RUnlock()
65
66 return string(b.label)
67 }
68
69
70 func (b *Button) SetLabelColor(color tcell.Color) {
71 b.Lock()
72 defer b.Unlock()
73
74 b.labelColor = color
75 }
76
77
78
79 func (b *Button) SetLabelColorFocused(color tcell.Color) {
80 b.Lock()
81 defer b.Unlock()
82
83 b.labelColorFocused = color
84 }
85
86
87 func (b *Button) SetCursorRune(rune rune) {
88 b.Lock()
89 defer b.Unlock()
90
91 b.cursorRune = rune
92 }
93
94
95
96 func (b *Button) SetBackgroundColorFocused(color tcell.Color) {
97 b.Lock()
98 defer b.Unlock()
99
100 b.backgroundColorFocused = color
101 }
102
103
104 func (b *Button) SetSelectedFunc(handler func()) {
105 b.Lock()
106 defer b.Unlock()
107
108 b.selected = handler
109 }
110
111
112
113
114
115
116
117
118 func (b *Button) SetBlurFunc(handler func(key tcell.Key)) {
119 b.Lock()
120 defer b.Unlock()
121
122 b.blur = handler
123 }
124
125
126 func (b *Button) Draw(screen tcell.Screen) {
127 if !b.GetVisible() {
128 return
129 }
130
131 b.Lock()
132 defer b.Unlock()
133
134
135 borderColor := b.borderColor
136 backgroundColor := b.backgroundColor
137 if b.focus.HasFocus() {
138 b.backgroundColor = b.backgroundColorFocused
139 b.borderColor = b.labelColorFocused
140 defer func() {
141 b.borderColor = borderColor
142 }()
143 }
144 b.Unlock()
145 b.Box.Draw(screen)
146 b.Lock()
147 b.backgroundColor = backgroundColor
148
149
150 x, y, width, height := b.GetInnerRect()
151 if width > 0 && height > 0 {
152 y = y + height/2
153 labelColor := b.labelColor
154 if b.focus.HasFocus() {
155 labelColor = b.labelColorFocused
156 }
157 _, pw := Print(screen, b.label, x, y, width, AlignCenter, labelColor)
158
159
160 if b.focus.HasFocus() && b.cursorRune != 0 {
161 cursorX := x + int(float64(width)/2+float64(pw)/2)
162 if cursorX > x+width-1 {
163 cursorX = x + width - 1
164 } else if cursorX < x+width {
165 cursorX++
166 }
167 Print(screen, []byte(string(b.cursorRune)), cursorX, y, width, AlignLeft, labelColor)
168 }
169 }
170 }
171
172
173 func (b *Button) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
174 return b.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
175
176 if HitShortcut(event, Keys.Select, Keys.Select2) {
177 if b.selected != nil {
178 b.selected()
179 }
180 } else if HitShortcut(event, Keys.Cancel, Keys.MovePreviousField, Keys.MoveNextField) {
181 if b.blur != nil {
182 b.blur(event.Key())
183 }
184 }
185 })
186 }
187
188
189 func (b *Button) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
190 return b.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
191 if !b.InRect(event.Position()) {
192 return false, nil
193 }
194
195
196 if action == MouseLeftClick {
197 setFocus(b)
198 if b.selected != nil {
199 b.selected()
200 }
201 consumed = true
202 }
203
204 return
205 })
206 }
207
View as plain text