1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
package cview
import (
"sync"
"github.com/gdamore/tcell/v2"
)
// Button is labeled box that triggers an action when selected.
type Button struct {
*Box
// The text to be displayed before the input area.
label []byte
// The label color.
labelColor tcell.Color
// The label color when the button is in focus.
labelColorFocused tcell.Color
// The background color when the button is in focus.
backgroundColorFocused tcell.Color
// An optional function which is called when the button was selected.
selected func()
// An optional function which is called when the user leaves the button. A
// key is provided indicating which key was pressed to leave (tab or backtab).
blur func(tcell.Key)
sync.RWMutex
}
// NewButton returns a new input field.
func NewButton(label string) *Button {
box := NewBox()
box.SetBackgroundColor(Styles.ContrastBackgroundColor)
box.SetRect(0, 0, TaggedStringWidth(label)+4, 1)
return &Button{
Box: box,
label: []byte(label),
labelColor: Styles.PrimaryTextColor,
labelColorFocused: Styles.InverseTextColor,
backgroundColorFocused: Styles.PrimaryTextColor,
}
}
// SetLabel sets the button text.
func (b *Button) SetLabel(label string) {
b.Lock()
defer b.Unlock()
b.label = []byte(label)
}
// GetLabel returns the button text.
func (b *Button) GetLabel() string {
b.RLock()
defer b.RUnlock()
return string(b.label)
}
// SetLabelColor sets the color of the button text.
func (b *Button) SetLabelColor(color tcell.Color) {
b.Lock()
defer b.Unlock()
b.labelColor = color
}
// SetLabelColorFocused sets the color of the button text when the button is
// in focus.
func (b *Button) SetLabelColorFocused(color tcell.Color) {
b.Lock()
defer b.Unlock()
b.labelColorFocused = color
}
// SetBackgroundColorFocused sets the background color of the button text when
// the button is in focus.
func (b *Button) SetBackgroundColorFocused(color tcell.Color) {
b.Lock()
defer b.Unlock()
b.backgroundColorFocused = color
}
// SetSelectedFunc sets a handler which is called when the button was selected.
func (b *Button) SetSelectedFunc(handler func()) {
b.Lock()
defer b.Unlock()
b.selected = handler
}
// SetBlurFunc sets a handler which is called when the user leaves the button.
// The callback function is provided with the key that was pressed, which is one
// of the following:
//
// - KeyEscape: Leaving the button with no specific direction.
// - KeyTab: Move to the next field.
// - KeyBacktab: Move to the previous field.
func (b *Button) SetBlurFunc(handler func(key tcell.Key)) {
b.Lock()
defer b.Unlock()
b.blur = handler
}
// Draw draws this primitive onto the screen.
func (b *Button) Draw(screen tcell.Screen) {
if !b.GetVisible() {
return
}
b.Lock()
defer b.Unlock()
// Draw the box.
borderColor := b.borderColor
backgroundColor := b.backgroundColor
if b.focus.HasFocus() {
b.backgroundColor = b.backgroundColorFocused
b.borderColor = b.labelColorFocused
defer func() {
b.borderColor = borderColor
}()
}
b.Unlock()
b.Box.Draw(screen)
b.Lock()
b.backgroundColor = backgroundColor
// Draw label.
x, y, width, height := b.GetInnerRect()
if width > 0 && height > 0 {
y = y + height/2
labelColor := b.labelColor
if b.focus.HasFocus() {
labelColor = b.labelColorFocused
}
Print(screen, b.label, x, y, width, AlignCenter, labelColor)
}
}
// InputHandler returns the handler for this primitive.
func (b *Button) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return b.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
// Process key event.
if HitShortcut(event, Keys.Select, Keys.Select2) {
if b.selected != nil {
b.selected()
}
} else if HitShortcut(event, Keys.Cancel, Keys.MovePreviousField, Keys.MoveNextField) {
if b.blur != nil {
b.blur(event.Key())
}
}
})
}
// MouseHandler returns the mouse handler for this primitive.
func (b *Button) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
return b.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
if !b.InRect(event.Position()) {
return false, nil
}
// Process mouse event.
if action == MouseLeftClick {
setFocus(b)
if b.selected != nil {
b.selected()
}
consumed = true
}
return
})
}
|