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 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
package tview
import (
"github.com/gdamore/tcell/v2"
)
// Button is labeled box that triggers an action when selected.
//
// See https://github.com/rivo/tview/wiki/Button for an example.
type Button struct {
*Box
// If set to true, the button cannot be activated.
disabled bool
// The text to be displayed inside the button.
text string
// The button's style (when deactivated).
style tcell.Style
// The button's style (when activated).
activatedStyle tcell.Style
// The button's style (when disabled).
disabledStyle tcell.Style
// 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).
exit func(tcell.Key)
}
// NewButton returns a new input field.
func NewButton(label string) *Button {
box := NewBox()
box.SetRect(0, 0, TaggedStringWidth(label)+4, 1)
return &Button{
Box: box,
text: label,
style: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor),
activatedStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.InverseTextColor),
disabledStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.ContrastSecondaryTextColor),
}
}
// SetLabel sets the button text.
func (b *Button) SetLabel(label string) *Button {
b.text = label
return b
}
// GetLabel returns the button text.
func (b *Button) GetLabel() string {
return b.text
}
// SetLabelColor sets the color of the button text.
func (b *Button) SetLabelColor(color tcell.Color) *Button {
b.style = b.style.Foreground(color)
return b
}
// SetStyle sets the style of the button used when it is not focused.
func (b *Button) SetStyle(style tcell.Style) *Button {
b.style = style
return b
}
// SetLabelColorActivated sets the color of the button text when the button is
// in focus.
func (b *Button) SetLabelColorActivated(color tcell.Color) *Button {
b.activatedStyle = b.activatedStyle.Foreground(color)
return b
}
// SetBackgroundColorActivated sets the background color of the button text when
// the button is in focus.
func (b *Button) SetBackgroundColorActivated(color tcell.Color) *Button {
b.activatedStyle = b.activatedStyle.Background(color)
return b
}
// SetActivatedStyle sets the style of the button used when it is focused.
func (b *Button) SetActivatedStyle(style tcell.Style) *Button {
b.activatedStyle = style
return b
}
// SetDisabledStyle sets the style of the button used when it is disabled.
func (b *Button) SetDisabledStyle(style tcell.Style) *Button {
b.disabledStyle = style
return b
}
// SetDisabled sets whether or not the button is disabled. Disabled buttons
// cannot be activated.
//
// If the button is part of a form, you should set focus to the form itself
// after calling this function to set focus to the next non-disabled form item.
func (b *Button) SetDisabled(disabled bool) *Button {
b.disabled = disabled
return b
}
// IsDisabled returns whether or not the button is disabled.
func (b *Button) IsDisabled() bool {
return b.disabled
}
// SetSelectedFunc sets a handler which is called when the button was selected.
func (b *Button) SetSelectedFunc(handler func()) *Button {
b.selected = handler
return b
}
// SetExitFunc 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) SetExitFunc(handler func(key tcell.Key)) *Button {
b.exit = handler
return b
}
// Draw draws this primitive onto the screen.
func (b *Button) Draw(screen tcell.Screen) {
// Draw the box.
style := b.style
if b.disabled {
style = b.disabledStyle
}
_, backgroundColor, _ := style.Decompose()
if b.HasFocus() && !b.disabled {
style = b.activatedStyle
_, backgroundColor, _ = style.Decompose()
// Highlight button for one drawing cycle.
borderColor := b.GetBorderColor()
b.SetBorderColor(backgroundColor)
defer func() {
b.SetBorderColor(borderColor)
}()
}
b.SetBackgroundColor(backgroundColor)
b.Box.DrawForSubclass(screen, b)
// Draw label.
x, y, width, height := b.GetInnerRect()
if width > 0 && height > 0 {
y = y + height/2
printWithStyle(screen, b.text, x, y, 0, width, AlignCenter, style, true)
}
}
// 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)) {
if b.disabled {
return
}
// Process key event.
switch key := event.Key(); key {
case tcell.KeyEnter: // Selected.
if b.selected != nil {
b.selected()
}
case tcell.KeyBacktab, tcell.KeyTab, tcell.KeyEscape: // Leave. No action.
if b.exit != nil {
b.exit(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.disabled {
return false, nil
}
if !b.InRect(event.Position()) {
return false, nil
}
// Process mouse event.
if action == MouseLeftDown {
setFocus(b)
consumed = true
} else if action == MouseLeftClick {
if b.selected != nil {
b.selected()
}
consumed = true
}
return
})
}
|