From 761e3d72da6c156aff91324b479f5cbf2272f53f Mon Sep 17 00:00:00 2001 From: Oliver <480930+rivo@users.noreply.github.com> Date: Mon, 19 Mar 2018 21:25:30 +0100 Subject: [PATCH] Added Primitive demo to go along with the GitHub Wiki entry on how to create your own primitive. --- box.go | 8 ++- button.go | 2 +- checkbox.go | 2 +- demos/primitive/README.md | 1 + demos/primitive/boxwithcenterline.png | Bin 0 -> 11386 bytes demos/primitive/main.go | 70 +++++++++++++++++++++ demos/primitive/screenshot.png | Bin 0 -> 15421 bytes demos/primitive/textviewwithcenterline.png | Bin 0 -> 13636 bytes dropdown.go | 2 +- grid.go | 2 +- inputfield.go | 2 +- list.go | 2 +- primitive.go | 2 +- table.go | 2 +- textview.go | 2 +- 15 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 demos/primitive/README.md create mode 100644 demos/primitive/boxwithcenterline.png create mode 100644 demos/primitive/main.go create mode 100644 demos/primitive/screenshot.png create mode 100644 demos/primitive/textviewwithcenterline.png diff --git a/box.go b/box.go index 547945b..904184a 100644 --- a/box.go +++ b/box.go @@ -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 diff --git a/button.go b/button.go index f89b4c0..5efc31a 100644 --- a/button.go +++ b/button.go @@ -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. diff --git a/checkbox.go b/checkbox.go index 94d5abf..3dbeade 100644 --- a/checkbox.go +++ b/checkbox.go @@ -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. diff --git a/demos/primitive/README.md b/demos/primitive/README.md new file mode 100644 index 0000000..4a14e6c --- /dev/null +++ b/demos/primitive/README.md @@ -0,0 +1 @@ +![Screenshot](screenshot.png) diff --git a/demos/primitive/boxwithcenterline.png b/demos/primitive/boxwithcenterline.png new file mode 100644 index 0000000000000000000000000000000000000000..104ee5b6424204d42eb8fac9949b04f18ad3b855 GIT binary patch literal 11386 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 literal 0 HcmV?d00001 diff --git a/demos/primitive/main.go b/demos/primitive/main.go new file mode 100644 index 0000000..e2d911a --- /dev/null +++ b/demos/primitive/main.go @@ -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) + } +} diff --git a/demos/primitive/screenshot.png b/demos/primitive/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..1c045267d5389382b5c34906a625d6eeb75e2915 GIT binary patch literal 15421 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 literal 0 HcmV?d00001 diff --git a/demos/primitive/textviewwithcenterline.png b/demos/primitive/textviewwithcenterline.png new file mode 100644 index 0000000000000000000000000000000000000000..0376ff5e5168fcef95a1be6da8a6bc78299be39a GIT binary patch literal 13636 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 YvLoR26%Emrztc