Add Button.SetCursorRune and CheckBox.SetCursorRune
Cursors are now shown within Buttons and CheckBoxes by default. Resolves #62.
This commit is contained in:
parent
71e3cc57f7
commit
454d759a42
10 changed files with 66 additions and 22 deletions
|
@ -1,8 +1,10 @@
|
|||
v1.5.6 (WIP)
|
||||
- Add TrueColorTags option and do not use TrueColor tag values by default
|
||||
- Add TextView.SetHighlightForegroundColor and TextView.SetHighlightBackgroundColor
|
||||
- Add Button.SetCursorRune (cursors are now shown within Buttons when focused by default)
|
||||
- Add CheckBox.SetCursorRune (cursors are now shown within CheckBoxes when focused by default)
|
||||
- Add DropDown.SetAlwaysDrawDropDownSymbol (DropDown symbols are now shown only when focused by default)
|
||||
- Add DropDown.SetDropDownOpenSymbolRune
|
||||
- Add DropDown.SetAlwaysDrawDropDownSymbol (DropDown symbols are now only drawn when focused by default)
|
||||
- Draw additional accents when rendering a list divider
|
||||
- Update List, Table and TreeView to not handle Tab or Backtab
|
||||
- Allow specifying TabbedPanels switcher height
|
||||
|
|
|
@ -67,10 +67,10 @@ func main() {
|
|||
```
|
||||
|
||||
Examples are available via [godoc](https://docs.rocketnine.space/code.rocketnine.space/tslocum/cview#pkg-examples)
|
||||
and in the [demos](https://code.rocketnine.space/tslocum/cview/src/branch/master/demos) subdirectory.
|
||||
and in the [demos](https://code.rocketnine.space/tslocum/cview/src/branch/master/demos) directory.
|
||||
|
||||
For a presentation highlighting the features of this package, compile and run
|
||||
the program in the [demos/presentation](https://code.rocketnine.space/tslocum/cview/src/branch/master/demos/presentation) subdirectory.
|
||||
the program in the [demos/presentation](https://code.rocketnine.space/tslocum/cview/src/branch/master/demos/presentation) directory.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
|
21
button.go
21
button.go
|
@ -4,6 +4,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// Button is labeled box that triggers an action when selected.
|
||||
|
@ -29,6 +30,9 @@ type Button struct {
|
|||
// key is provided indicating which key was pressed to leave (tab or backtab).
|
||||
blur func(tcell.Key)
|
||||
|
||||
// An optional rune which is drawn after the label when the button is focused.
|
||||
cursorRune rune
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
|
@ -36,13 +40,14 @@ type Button struct {
|
|||
func NewButton(label string) *Button {
|
||||
box := NewBox()
|
||||
box.SetRect(0, 0, TaggedStringWidth(label)+4, 1)
|
||||
box.SetBackgroundColor(Styles.ContrastBackgroundColor)
|
||||
box.SetBackgroundColor(Styles.MoreContrastBackgroundColor)
|
||||
return &Button{
|
||||
Box: box,
|
||||
label: []byte(label),
|
||||
labelColor: Styles.PrimaryTextColor,
|
||||
labelColorFocused: Styles.PrimaryTextColor,
|
||||
backgroundColorFocused: Styles.MoreContrastBackgroundColor,
|
||||
cursorRune: Styles.ButtonCursorRune,
|
||||
backgroundColorFocused: Styles.ContrastBackgroundColor,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +84,14 @@ func (b *Button) SetLabelColorFocused(color tcell.Color) {
|
|||
b.labelColorFocused = color
|
||||
}
|
||||
|
||||
// SetCursorRune sets the rune to show within the button when it is focused.
|
||||
func (b *Button) SetCursorRune(rune rune) {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
|
||||
b.cursorRune = rune
|
||||
}
|
||||
|
||||
// SetBackgroundColorFocused sets the background color of the button text when
|
||||
// the button is in focus.
|
||||
func (b *Button) SetBackgroundColorFocused(color tcell.Color) {
|
||||
|
@ -141,6 +154,10 @@ func (b *Button) Draw(screen tcell.Screen) {
|
|||
labelColor := b.labelColor
|
||||
if b.focus.HasFocus() {
|
||||
labelColor = b.labelColorFocused
|
||||
// Draw cursor.
|
||||
if b.cursorRune != 0 {
|
||||
Print(screen, []byte(string(b.cursorRune)), x+width-(width-runewidth.StringWidth(string(b.label)))/2+1, y, width, AlignLeft, labelColor)
|
||||
}
|
||||
}
|
||||
Print(screen, b.label, x, y, width, AlignCenter, labelColor)
|
||||
}
|
||||
|
|
26
checkbox.go
26
checkbox.go
|
@ -58,6 +58,9 @@ type CheckBox struct {
|
|||
// The rune to show when the checkbox is checked
|
||||
checkedRune rune
|
||||
|
||||
// An optional rune to show within the checkbox when it is focused
|
||||
cursorRune rune
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
|
@ -66,11 +69,12 @@ func NewCheckBox() *CheckBox {
|
|||
return &CheckBox{
|
||||
Box: NewBox(),
|
||||
labelColor: Styles.SecondaryTextColor,
|
||||
fieldBackgroundColor: Styles.ContrastBackgroundColor,
|
||||
fieldBackgroundColor: Styles.MoreContrastBackgroundColor,
|
||||
fieldBackgroundColorFocused: Styles.ContrastBackgroundColor,
|
||||
fieldTextColor: Styles.PrimaryTextColor,
|
||||
checkedRune: Styles.CheckBoxCheckedRune,
|
||||
cursorRune: Styles.CheckBoxCursorRune,
|
||||
labelColorFocused: ColorUnset,
|
||||
fieldBackgroundColorFocused: ColorUnset,
|
||||
fieldTextColorFocused: ColorUnset,
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +95,14 @@ func (c *CheckBox) SetCheckedRune(rune rune) {
|
|||
c.checkedRune = rune
|
||||
}
|
||||
|
||||
// SetCursorRune sets the rune to show within the checkbox when it is focused.
|
||||
func (c *CheckBox) SetCursorRune(rune rune) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
c.cursorRune = rune
|
||||
}
|
||||
|
||||
// IsChecked returns whether or not the box is checked.
|
||||
func (c *CheckBox) IsChecked() bool {
|
||||
c.RLock()
|
||||
|
@ -248,11 +260,13 @@ func (c *CheckBox) Draw(screen tcell.Screen) {
|
|||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
hasFocus := c.GetFocusable().HasFocus()
|
||||
|
||||
// Select colors
|
||||
labelColor := c.labelColor
|
||||
fieldBackgroundColor := c.fieldBackgroundColor
|
||||
fieldTextColor := c.fieldTextColor
|
||||
if c.GetFocusable().HasFocus() {
|
||||
if hasFocus {
|
||||
if c.labelColorFocused != ColorUnset {
|
||||
labelColor = c.labelColorFocused
|
||||
}
|
||||
|
@ -291,9 +305,13 @@ func (c *CheckBox) Draw(screen tcell.Screen) {
|
|||
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, ' ', 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)
|
||||
|
|
|
@ -8,7 +8,6 @@ func main() {
|
|||
app.EnableMouse(true)
|
||||
|
||||
button := cview.NewButton("Hit Enter to close")
|
||||
button.SetBorder(true)
|
||||
button.SetRect(0, 0, 22, 3)
|
||||
button.SetSelectedFunc(func() {
|
||||
app.Stop()
|
||||
|
|
|
@ -8,8 +8,8 @@ func Introduction(nextSlide func()) (title string, info string, content cview.Pr
|
|||
|
||||
listText := [][]string{
|
||||
{"A Go package for terminal based UIs", "with a special focus on rich interactive widgets"},
|
||||
{"Based on github.com/gdamore/tcell", "Like termbox but better (see tcell docs)"},
|
||||
{"Designed to be simple", `"Hello world" is 5 lines of code`},
|
||||
{"Based on github.com/gdamore/tcell", "Supports Linux, FreeBSD, MacOS and Windows"},
|
||||
{"Designed to be simple", `"Hello world" is less than 20 lines of code`},
|
||||
{"Good for data entry", `For charts, use "termui" - for low-level views, use "gocui" - ...`},
|
||||
{"Supports context menus", "Right click on one of these items or press Alt+Enter"},
|
||||
{"Extensive documentation", "Demo code is available for each widget"},
|
||||
|
|
|
@ -154,14 +154,14 @@ func NewDropDown() *DropDown {
|
|||
list.SetSelectedTextColor(Styles.PrimitiveBackgroundColor)
|
||||
list.SetSelectedBackgroundColor(Styles.PrimaryTextColor)
|
||||
list.SetHighlightFullLine(true)
|
||||
list.SetBackgroundColor(Styles.MoreContrastBackgroundColor)
|
||||
list.SetBackgroundColor(Styles.ContrastBackgroundColor)
|
||||
|
||||
d := &DropDown{
|
||||
Box: NewBox(),
|
||||
currentOption: -1,
|
||||
list: list,
|
||||
labelColor: Styles.SecondaryTextColor,
|
||||
fieldBackgroundColor: Styles.ContrastBackgroundColor,
|
||||
fieldBackgroundColor: Styles.MoreContrastBackgroundColor,
|
||||
fieldTextColor: Styles.PrimaryTextColor,
|
||||
prefixTextColor: Styles.ContrastSecondaryTextColor,
|
||||
dropDownSymbol: Styles.DropDownSymbol,
|
||||
|
|
8
form.go
8
form.go
|
@ -151,12 +151,12 @@ func NewForm() *Form {
|
|||
Box: box,
|
||||
itemPadding: 1,
|
||||
labelColor: Styles.SecondaryTextColor,
|
||||
fieldBackgroundColor: Styles.ContrastBackgroundColor,
|
||||
fieldBackgroundColorFocused: Styles.MoreContrastBackgroundColor,
|
||||
fieldBackgroundColor: Styles.MoreContrastBackgroundColor,
|
||||
fieldBackgroundColorFocused: Styles.ContrastBackgroundColor,
|
||||
fieldTextColor: Styles.PrimaryTextColor,
|
||||
fieldTextColorFocused: Styles.PrimaryTextColor,
|
||||
buttonBackgroundColor: Styles.ContrastBackgroundColor,
|
||||
buttonBackgroundColorFocused: Styles.MoreContrastBackgroundColor,
|
||||
buttonBackgroundColor: Styles.MoreContrastBackgroundColor,
|
||||
buttonBackgroundColorFocused: Styles.ContrastBackgroundColor,
|
||||
buttonTextColor: Styles.PrimaryTextColor,
|
||||
buttonTextColorFocused: Styles.PrimaryTextColor,
|
||||
labelColorFocused: ColorUnset,
|
||||
|
|
|
@ -22,8 +22,12 @@ type Theme struct {
|
|||
ContrastBackgroundColor tcell.Color // Background color for contrasting elements.
|
||||
MoreContrastBackgroundColor tcell.Color // Background color for even more contrasting elements.
|
||||
|
||||
// Button
|
||||
ButtonCursorRune rune // The symbol to draw at the end of button labels when focused.
|
||||
|
||||
// Check box
|
||||
CheckBoxCheckedRune rune
|
||||
CheckBoxCursorRune rune // The symbol to draw within the checkbox when focused.
|
||||
|
||||
// Context menu
|
||||
ContextMenuPaddingTop int
|
||||
|
@ -63,7 +67,10 @@ var Styles = Theme{
|
|||
ContrastBackgroundColor: tcell.ColorGreen.TrueColor(),
|
||||
MoreContrastBackgroundColor: tcell.ColorDarkGreen.TrueColor(),
|
||||
|
||||
ButtonCursorRune: '◀',
|
||||
|
||||
CheckBoxCheckedRune: 'X',
|
||||
CheckBoxCursorRune: '◀',
|
||||
|
||||
ContextMenuPaddingTop: 0,
|
||||
ContextMenuPaddingBottom: 0,
|
||||
|
|
|
@ -14,14 +14,15 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
openColorRegex = regexp.MustCompile(`\[([a-zA-Z]*|#[0-9a-zA-Z]*)$`)
|
||||
openRegionRegex = regexp.MustCompile(`\["[a-zA-Z0-9_,;: \-\.]*"?$`)
|
||||
newLineRegex = regexp.MustCompile(`\r?\n`)
|
||||
|
||||
// TabSize is the number of spaces with which a tab character will be replaced.
|
||||
TabSize = 4
|
||||
)
|
||||
|
||||
var (
|
||||
openColorRegex = regexp.MustCompile(`\[([a-zA-Z]*|#[0-9a-zA-Z]*)$`)
|
||||
openRegionRegex = regexp.MustCompile(`\["[a-zA-Z0-9_,;: \-\.]*"?$`)
|
||||
)
|
||||
|
||||
// textViewIndex contains information about each line displayed in the text
|
||||
// view.
|
||||
type textViewIndex struct {
|
||||
|
|
Loading…
Reference in a new issue