button.go (5579B)
1 package tview 2 3 import ( 4 "github.com/gdamore/tcell/v2" 5 ) 6 7 // Button is labeled box that triggers an action when selected. 8 // 9 // See https://github.com/rivo/tview/wiki/Button for an example. 10 type Button struct { 11 *Box 12 13 // If set to true, the button cannot be activated. 14 disabled bool 15 16 // The text to be displayed inside the button. 17 text string 18 19 // The button's style (when deactivated). 20 style tcell.Style 21 22 // The button's style (when activated). 23 activatedStyle tcell.Style 24 25 // The button's style (when disabled). 26 disabledStyle tcell.Style 27 28 // An optional function which is called when the button was selected. 29 selected func() 30 31 // An optional function which is called when the user leaves the button. A 32 // key is provided indicating which key was pressed to leave (tab or 33 // backtab). 34 exit func(tcell.Key) 35 } 36 37 // NewButton returns a new input field. 38 func NewButton(label string) *Button { 39 box := NewBox() 40 box.SetRect(0, 0, TaggedStringWidth(label)+4, 1) 41 return &Button{ 42 Box: box, 43 text: label, 44 style: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor), 45 activatedStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.InverseTextColor), 46 disabledStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.ContrastSecondaryTextColor), 47 } 48 } 49 50 // SetLabel sets the button text. 51 func (b *Button) SetLabel(label string) *Button { 52 b.text = label 53 return b 54 } 55 56 // GetLabel returns the button text. 57 func (b *Button) GetLabel() string { 58 return b.text 59 } 60 61 // SetLabelColor sets the color of the button text. 62 func (b *Button) SetLabelColor(color tcell.Color) *Button { 63 b.style = b.style.Foreground(color) 64 return b 65 } 66 67 // SetStyle sets the style of the button used when it is not focused. 68 func (b *Button) SetStyle(style tcell.Style) *Button { 69 b.style = style 70 return b 71 } 72 73 // SetLabelColorActivated sets the color of the button text when the button is 74 // in focus. 75 func (b *Button) SetLabelColorActivated(color tcell.Color) *Button { 76 b.activatedStyle = b.activatedStyle.Foreground(color) 77 return b 78 } 79 80 // SetBackgroundColorActivated sets the background color of the button text when 81 // the button is in focus. 82 func (b *Button) SetBackgroundColorActivated(color tcell.Color) *Button { 83 b.activatedStyle = b.activatedStyle.Background(color) 84 return b 85 } 86 87 // SetActivatedStyle sets the style of the button used when it is focused. 88 func (b *Button) SetActivatedStyle(style tcell.Style) *Button { 89 b.activatedStyle = style 90 return b 91 } 92 93 // SetDisabledStyle sets the style of the button used when it is disabled. 94 func (b *Button) SetDisabledStyle(style tcell.Style) *Button { 95 b.disabledStyle = style 96 return b 97 } 98 99 // SetDisabled sets whether or not the button is disabled. Disabled buttons 100 // cannot be activated. 101 // 102 // If the button is part of a form, you should set focus to the form itself 103 // after calling this function to set focus to the next non-disabled form item. 104 func (b *Button) SetDisabled(disabled bool) *Button { 105 b.disabled = disabled 106 return b 107 } 108 109 // IsDisabled returns whether or not the button is disabled. 110 func (b *Button) IsDisabled() bool { 111 return b.disabled 112 } 113 114 // SetSelectedFunc sets a handler which is called when the button was selected. 115 func (b *Button) SetSelectedFunc(handler func()) *Button { 116 b.selected = handler 117 return b 118 } 119 120 // SetExitFunc sets a handler which is called when the user leaves the button. 121 // The callback function is provided with the key that was pressed, which is one 122 // of the following: 123 // 124 // - KeyEscape: Leaving the button with no specific direction. 125 // - KeyTab: Move to the next field. 126 // - KeyBacktab: Move to the previous field. 127 func (b *Button) SetExitFunc(handler func(key tcell.Key)) *Button { 128 b.exit = handler 129 return b 130 } 131 132 // Draw draws this primitive onto the screen. 133 func (b *Button) Draw(screen tcell.Screen) { 134 // Draw the box. 135 style := b.style 136 if b.disabled { 137 style = b.disabledStyle 138 } 139 if b.HasFocus() && !b.disabled { 140 style = b.activatedStyle 141 } 142 _, backgroundColor, _ := style.Decompose() 143 b.SetBackgroundColor(backgroundColor) 144 b.Box.DrawForSubclass(screen, b) 145 146 // Draw label. 147 x, y, width, height := b.GetInnerRect() 148 if width > 0 && height > 0 { 149 y = y + height/2 150 printWithStyle(screen, b.text, x, y, 0, width, AlignCenter, style, true) 151 } 152 } 153 154 // InputHandler returns the handler for this primitive. 155 func (b *Button) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { 156 return b.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { 157 if b.disabled { 158 return 159 } 160 161 // Process key event. 162 switch key := event.Key(); key { 163 case tcell.KeyEnter: // Selected. 164 if b.selected != nil { 165 b.selected() 166 } 167 case tcell.KeyBacktab, tcell.KeyTab, tcell.KeyEscape: // Leave. No action. 168 if b.exit != nil { 169 b.exit(key) 170 } 171 } 172 }) 173 } 174 175 // MouseHandler returns the mouse handler for this primitive. 176 func (b *Button) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { 177 return b.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { 178 if b.disabled { 179 return false, nil 180 } 181 182 if !b.InRect(event.Position()) { 183 return false, nil 184 } 185 186 // Process mouse event. 187 if action == MouseLeftDown { 188 setFocus(b) 189 consumed = true 190 } else if action == MouseLeftClick { 191 if b.selected != nil { 192 b.selected() 193 } 194 consumed = true 195 } 196 197 return 198 }) 199 }