...

Source file src/gitlab.com/tslocum/cview/button.go

Documentation: gitlab.com/tslocum/cview

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

View as plain text