Added Primitive demo to go along with the GitHub Wiki entry on how to create your own primitive.

This commit is contained in:
Oliver 2018-03-19 21:25:30 +01:00
parent b357eaf10f
commit 761e3d72da
15 changed files with 85 additions and 12 deletions

8
box.go
View File

@ -130,10 +130,12 @@ func (b *Box) GetDrawFunc() func(screen tcell.Screen, x, y, width, height int) (
return b.draw
}
// wrapInputHandler wraps an input handler (see InputHandler()) with the
// WrapInputHandler wraps an input handler (see InputHandler()) with the
// functionality to capture input (see SetInputCapture()) before passing it
// on to the provided (default) input handler.
func (b *Box) wrapInputHandler(inputHandler func(*tcell.EventKey, func(p Primitive))) func(*tcell.EventKey, func(p Primitive)) {
//
// This is only meant to be used by subclassing primitives.
func (b *Box) WrapInputHandler(inputHandler func(*tcell.EventKey, func(p Primitive))) func(*tcell.EventKey, func(p Primitive)) {
return func(event *tcell.EventKey, setFocus func(p Primitive)) {
if b.inputCapture != nil {
event = b.inputCapture(event)
@ -146,7 +148,7 @@ func (b *Box) wrapInputHandler(inputHandler func(*tcell.EventKey, func(p Primiti
// InputHandler returns nil.
func (b *Box) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return b.wrapInputHandler(nil)
return b.WrapInputHandler(nil)
}
// SetInputCapture installs a function which captures key events before they are

View File

@ -121,7 +121,7 @@ func (b *Button) Draw(screen tcell.Screen) {
// InputHandler returns the handler for this primitive.
func (b *Button) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return b.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return b.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
// Process key event.
switch key := event.Key(); key {
case tcell.KeyEnter: // Selected.

View File

@ -155,7 +155,7 @@ func (c *Checkbox) Draw(screen tcell.Screen) {
// InputHandler returns the handler for this primitive.
func (c *Checkbox) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return c.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return c.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
// Process key event.
switch key := event.Key(); key {
case tcell.KeyRune, tcell.KeyEnter: // Check.

View File

@ -0,0 +1 @@
![Screenshot](screenshot.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

70
demos/primitive/main.go Normal file
View File

@ -0,0 +1,70 @@
// Demo code which illustrates how to implement your own primitive.
package main
import (
"fmt"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
// RadioButtons implements a simple primitive for radio button selections.
type RadioButtons struct {
*tview.Box
options []string
currentOption int
}
// NewRadioButtons returns a new radio button primitive.
func NewRadioButtons(options []string) *RadioButtons {
return &RadioButtons{
Box: tview.NewBox(),
options: options,
}
}
// Draw draws this primitive onto the screen.
func (r *RadioButtons) Draw(screen tcell.Screen) {
r.Box.Draw(screen)
x, y, width, height := r.GetInnerRect()
for index, option := range r.options {
if index >= height {
break
}
radioButton := "\u25ef" // Unchecked.
if index == r.currentOption {
radioButton = "\u25c9" // Checked.
}
line := fmt.Sprintf(`%s[white] %s`, radioButton, option)
tview.Print(screen, line, x, y+index, width, tview.AlignLeft, tcell.ColorYellow)
}
}
// InputHandler returns the handler for this primitive.
func (r *RadioButtons) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
return r.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
switch event.Key() {
case tcell.KeyUp:
r.currentOption--
if r.currentOption < 0 {
r.currentOption = 0
}
case tcell.KeyDown:
r.currentOption++
if r.currentOption >= len(r.options) {
r.currentOption = len(r.options) - 1
}
}
})
}
func main() {
radioButtons := NewRadioButtons([]string{"Lions", "Elephants", "Giraffes"})
radioButtons.SetBorder(true).
SetTitle("Radio Button Demo").
SetRect(0, 0, 30, 5)
if err := tview.NewApplication().SetRoot(radioButtons, false).Run(); err != nil {
panic(err)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -299,7 +299,7 @@ func (d *DropDown) Draw(screen tcell.Screen) {
// InputHandler returns the handler for this primitive.
func (d *DropDown) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return d.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return d.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
// A helper function which selects an item in the drop-down list based on
// the current prefix.
evalPrefix := func() {

View File

@ -263,7 +263,7 @@ func (g *Grid) HasFocus() bool {
// InputHandler returns the handler for this primitive.
func (g *Grid) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return g.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return g.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
switch event.Key() {
case tcell.KeyRune:
switch event.Rune() {

View File

@ -289,7 +289,7 @@ func (i *InputField) setCursor(screen tcell.Screen) {
// InputHandler returns the handler for this primitive.
func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return i.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return i.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
// Trigger changed events.
currentText := i.text
defer func() {

View File

@ -259,7 +259,7 @@ func (l *List) Draw(screen tcell.Screen) {
// InputHandler returns the handler for this primitive.
func (l *List) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return l.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return l.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
previousItem := l.currentItem
switch key := event.Key(); key {

View File

@ -31,7 +31,7 @@ type Primitive interface {
//
// The Box class provides functionality to intercept keyboard input. If you
// subclass from Box, it is recommended that you wrap your handler using
// Box.wrapInputHandler() so you inherit that functionality.
// Box.WrapInputHandler() so you inherit that functionality.
InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive))
// Focus is called by the application when the primitive receives focus.

View File

@ -818,7 +818,7 @@ ColumnLoop:
// InputHandler returns the handler for this primitive.
func (t *Table) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return t.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
key := event.Key()
if (!t.rowsSelectable && !t.columnsSelectable && key == tcell.KeyEnter) ||

View File

@ -839,7 +839,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
// InputHandler returns the handler for this primitive.
func (t *TextView) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
return t.wrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) {
key := event.Key()
if key == tcell.KeyEscape || key == tcell.KeyEnter || key == tcell.KeyTab || key == tcell.KeyBacktab {