package cview
import (
"sync"
"github.com/gdamore/tcell/v2"
)
type CheckBox struct {
*Box
checked bool
label []byte
message []byte
labelWidth int
labelColor tcell .Color
labelColorFocused tcell .Color
fieldBackgroundColor tcell .Color
fieldBackgroundColorFocused tcell .Color
fieldTextColor tcell .Color
fieldTextColorFocused tcell .Color
changed func (checked bool )
done func (tcell .Key )
finished func (tcell .Key )
checkedRune rune
cursorRune rune
sync .RWMutex
}
func NewCheckBox () *CheckBox {
return &CheckBox {
Box : NewBox (),
labelColor : Styles .SecondaryTextColor ,
fieldBackgroundColor : Styles .MoreContrastBackgroundColor ,
fieldBackgroundColorFocused : Styles .ContrastBackgroundColor ,
fieldTextColor : Styles .PrimaryTextColor ,
checkedRune : Styles .CheckBoxCheckedRune ,
cursorRune : Styles .CheckBoxCursorRune ,
labelColorFocused : ColorUnset ,
fieldTextColorFocused : ColorUnset ,
}
}
func (c *CheckBox ) SetChecked (checked bool ) {
c .Lock ()
defer c .Unlock ()
c .checked = checked
}
func (c *CheckBox ) SetCheckedRune (rune rune ) {
c .Lock ()
defer c .Unlock ()
c .checkedRune = rune
}
func (c *CheckBox ) SetCursorRune (rune rune ) {
c .Lock ()
defer c .Unlock ()
c .cursorRune = rune
}
func (c *CheckBox ) IsChecked () bool {
c .RLock ()
defer c .RUnlock ()
return c .checked
}
func (c *CheckBox ) SetLabel (label string ) {
c .Lock ()
defer c .Unlock ()
c .label = []byte (label )
}
func (c *CheckBox ) GetLabel () string {
c .RLock ()
defer c .RUnlock ()
return string (c .label )
}
func (c *CheckBox ) SetMessage (message string ) {
c .Lock ()
defer c .Unlock ()
c .message = []byte (message )
}
func (c *CheckBox ) GetMessage () string {
c .RLock ()
defer c .RUnlock ()
return string (c .message )
}
func (c *CheckBox ) SetLabelWidth (width int ) {
c .Lock ()
defer c .Unlock ()
c .labelWidth = width
}
func (c *CheckBox ) SetLabelColor (color tcell .Color ) {
c .Lock ()
defer c .Unlock ()
c .labelColor = color
}
func (c *CheckBox ) SetLabelColorFocused (color tcell .Color ) {
c .Lock ()
defer c .Unlock ()
c .labelColorFocused = color
}
func (c *CheckBox ) SetFieldBackgroundColor (color tcell .Color ) {
c .Lock ()
defer c .Unlock ()
c .fieldBackgroundColor = color
}
func (c *CheckBox ) SetFieldBackgroundColorFocused (color tcell .Color ) {
c .Lock ()
defer c .Unlock ()
c .fieldBackgroundColorFocused = color
}
func (c *CheckBox ) SetFieldTextColor (color tcell .Color ) {
c .Lock ()
defer c .Unlock ()
c .fieldTextColor = color
}
func (c *CheckBox ) SetFieldTextColorFocused (color tcell .Color ) {
c .Lock ()
defer c .Unlock ()
c .fieldTextColorFocused = color
}
func (c *CheckBox ) GetFieldHeight () int {
return 1
}
func (c *CheckBox ) GetFieldWidth () int {
c .RLock ()
defer c .RUnlock ()
if len (c .message ) == 0 {
return 1
}
return 2 + len (c .message )
}
func (c *CheckBox ) SetChangedFunc (handler func (checked bool )) {
c .Lock ()
defer c .Unlock ()
c .changed = handler
}
func (c *CheckBox ) SetDoneFunc (handler func (key tcell .Key )) {
c .Lock ()
defer c .Unlock ()
c .done = handler
}
func (c *CheckBox ) SetFinishedFunc (handler func (key tcell .Key )) {
c .Lock ()
defer c .Unlock ()
c .finished = handler
}
func (c *CheckBox ) Draw (screen tcell .Screen ) {
if !c .GetVisible () {
return
}
c .Box .Draw (screen )
c .Lock ()
defer c .Unlock ()
hasFocus := c .GetFocusable ().HasFocus ()
labelColor := c .labelColor
fieldBackgroundColor := c .fieldBackgroundColor
fieldTextColor := c .fieldTextColor
if hasFocus {
if c .labelColorFocused != ColorUnset {
labelColor = c .labelColorFocused
}
if c .fieldBackgroundColorFocused != ColorUnset {
fieldBackgroundColor = c .fieldBackgroundColorFocused
}
if c .fieldTextColorFocused != ColorUnset {
fieldTextColor = c .fieldTextColorFocused
}
}
x , y , width , height := c .GetInnerRect ()
rightLimit := x + width
if height < 1 || rightLimit <= x {
return
}
if c .labelWidth > 0 {
labelWidth := c .labelWidth
if labelWidth > rightLimit -x {
labelWidth = rightLimit - x
}
Print (screen , c .label , x , y , labelWidth , AlignLeft , labelColor )
x += labelWidth
} else {
_ , drawnWidth := Print (screen , c .label , x , y , rightLimit -x , AlignLeft , labelColor )
x += drawnWidth
}
fieldStyle := tcell .StyleDefault .Background (fieldBackgroundColor ).Foreground (fieldTextColor )
checkedRune := c .checkedRune
if !c .checked {
checkedRune = ' '
}
rightRune := ' '
if c .cursorRune != 0 && hasFocus {
rightRune = c .cursorRune
}
screen .SetContent (x , y , ' ' , nil , fieldStyle )
screen .SetContent (x +1 , y , checkedRune , nil , fieldStyle )
screen .SetContent (x +2 , y , rightRune , nil , fieldStyle )
if len (c .message ) > 0 {
Print (screen , c .message , x +4 , y , len (c .message ), AlignLeft , labelColor )
}
}
func (c *CheckBox ) InputHandler () func (event *tcell .EventKey , setFocus func (p Primitive )) {
return c .WrapInputHandler (func (event *tcell .EventKey , setFocus func (p Primitive )) {
if HitShortcut (event , Keys .Select , Keys .Select2 ) {
c .Lock ()
c .checked = !c .checked
c .Unlock ()
if c .changed != nil {
c .changed (c .checked )
}
} else if HitShortcut (event , Keys .Cancel , Keys .MovePreviousField , Keys .MoveNextField ) {
if c .done != nil {
c .done (event .Key ())
}
if c .finished != nil {
c .finished (event .Key ())
}
}
})
}
func (c *CheckBox ) MouseHandler () func (action MouseAction , event *tcell .EventMouse , setFocus func (p Primitive )) (consumed bool , capture Primitive ) {
return c .WrapMouseHandler (func (action MouseAction , event *tcell .EventMouse , setFocus func (p Primitive )) (consumed bool , capture Primitive ) {
x , y := event .Position ()
_ , rectY , _ , _ := c .GetInnerRect ()
if !c .InRect (x , y ) {
return false , nil
}
if action == MouseLeftClick && y == rectY {
setFocus (c )
c .checked = !c .checked
if c .changed != nil {
c .changed (c .checked )
}
consumed = true
}
return
})
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .