nt

A sensible note-taking program
git clone git://git.laack.co/nt.git
Log | Files | Refs | README

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 }