Added a presentation demonstrating tview's capabilities.

This commit is contained in:
Oliver 2017-12-30 22:10:13 +01:00
parent 7a69902269
commit 53527f5f80
12 changed files with 884 additions and 0 deletions

View File

@ -0,0 +1,16 @@
package main
import "github.com/rivo/tview"
// Center returns a new primitive which shows the provided primitive in its
// center, given the provided primitive's size.
func Center(width, height int, p tview.Primitive) tview.Primitive {
return tview.NewFlex().
AddItem(tview.NewBox(), 0, 1, false).
AddItem(tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(tview.NewBox(), 0, 1, false).
AddItem(p, height, 1, true).
AddItem(tview.NewBox(), 0, 1, false), width, 1, true).
AddItem(tview.NewBox(), 0, 1, false)
}

View File

@ -0,0 +1,25 @@
package main
import (
"fmt"
"github.com/rivo/tview"
)
// The width of the code window.
const codeWidth = 56
// Code returns a primitive which displays the given primitive (with the given
// size) on the left side and its source code on the right side.
func Code(p tview.Primitive, width, height int, code string) tview.Primitive {
// Set up code view.
codeView := tview.NewTextView().
SetWrap(false).
SetDynamicColors(true)
codeView.SetBorderPadding(1, 1, 2, 0)
fmt.Fprint(codeView, code)
return tview.NewFlex().
AddItem(Center(width, height, p), 0, 1, true).
AddItem(codeView, codeWidth, 1, false)
}

View File

@ -0,0 +1,56 @@
package main
import (
"fmt"
"strings"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
const logo = `
__ _
/ /__ __(_)__ _ __
/ __/ | / / / _ \ | /| / /
/ /_ | |/ / / __/ |/ |/ /
\__/ |___/_/\___/|__/|__/
`
const subtitle = `tview - Rich Widgets for Terminal UIs`
// Cover returns the cover page.
func Cover(nextSlide func()) (title string, content tview.Primitive) {
// What's the size of the logo?
lines := strings.Split(logo, "\n")
logoWidth := 0
logoHeight := len(lines)
for _, line := range lines {
if len(line) > logoWidth {
logoWidth = len(line)
}
}
logoBox := tview.NewTextView().
SetTextColor(tcell.ColorGreen).
SetDoneFunc(func(key tcell.Key) {
nextSlide()
})
fmt.Fprint(logoBox, logo)
// Create a frame for the subtitle.
frame := tview.NewFrame(tview.NewBox()).
SetBorders(0, 0, 0, 0, 0, 0).
AddText(subtitle, true, tview.AlignCenter, tcell.ColorWhite)
// Create a Flex layout that centers the logo and subtitle.
flex := tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(tview.NewBox(), 0, 7, false).
AddItem(tview.NewFlex().
AddItem(tview.NewBox(), 0, 1, false).
AddItem(logoBox, logoWidth, 1, true).
AddItem(tview.NewBox(), 0, 1, false), logoHeight, 1, true).
AddItem(frame, 0, 10, false)
return "Start", flex
}

18
demos/presentation/end.go Normal file
View File

@ -0,0 +1,18 @@
package main
import (
"fmt"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
// End shows the final slide.
func End(nextSlide func()) (title string, content tview.Primitive) {
textView := tview.NewTextView().SetDoneFunc(func(key tcell.Key) {
nextSlide()
})
url := "https://github.com/rivo/tview"
fmt.Fprint(textView, url)
return "End", Center(len(url), 1, textView)
}

View File

@ -0,0 +1,39 @@
package main
import (
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
// Flex demonstrates flexbox layout.
func Flex(nextSlide func()) (title string, content tview.Primitive) {
modalShown := false
pages := tview.NewPages()
textView := tview.NewTextView().
SetDoneFunc(func(key tcell.Key) {
if modalShown {
nextSlide()
modalShown = false
} else {
pages.ShowPage("modal")
modalShown = true
}
})
textView.SetBorder(true).SetTitle("Flexible width, twice of middle column")
flex := tview.NewFlex().
AddItem(textView, 0, 2, true).
AddItem(tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(tview.NewBox().SetBorder(true).SetTitle("Flexible width"), 0, 1, false).
AddItem(tview.NewBox().SetBorder(true).SetTitle("Fixed height"), 15, 1, false).
AddItem(tview.NewBox().SetBorder(true).SetTitle("Flexible height"), 0, 1, false), 0, 1, false).
AddItem(tview.NewBox().SetBorder(true).SetTitle("Fixed width"), 30, 1, false)
modal := tview.NewModal().
SetText("Resize the window to see the effect of the flexbox parameters").
AddButtons([]string{"Ok"}).SetDoneFunc(func(buttonIndex int, buttonLabel string) {
pages.HidePage("modal")
})
pages.AddPage("flex", flex, true, true).
AddPage("modal", modal, false, false)
return "Flex", pages
}

View File

@ -0,0 +1,42 @@
package main
import (
"github.com/rivo/tview"
)
const form = `[green]package[white] main
[green]import[white] (
[red]"github.com/rivo/tview"[white]
)
[green]func[white] [yellow]main[white]() {
form := tview.[yellow]NewForm[white]().
[yellow]AddInputField[white]([red]"First name:"[white], [red]""[white], [red]20[white], nil).
[yellow]AddInputField[white]([red]"Last name:"[white], [red]""[white], [red]20[white], nil).
[yellow]AddDropDown[white]([red]"Role:"[white], [][green]string[white]{
[red]"Engineer"[white],
[red]"Manager"[white],
[red]"Administration"[white],
}, [red]0[white], nil).
[yellow]AddCheckbox[white]([red]"On vacation:"[white], false, nil).
[yellow]AddButton[white]([red]"Save"[white], [yellow]func[white]() { [blue]/* Save data */[white] }).
[yellow]AddButton[white]([red]"Cancel"[white], [yellow]func[white]() { [blue]/* Cancel */[white] })
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](form, true).
[yellow]SetFocus[white](form).
[yellow]Run[white]()
}`
// Form demonstrates forms.
func Form(nextSlide func()) (title string, content tview.Primitive) {
f := tview.NewForm().
AddInputField("First name:", "", 20, nil).
AddInputField("Last name:", "", 20, nil).
AddDropDown("Role:", []string{"Engineer", "Manager", "Administration"}, 0, nil).
AddCheckbox("On vacation:", false, nil).
AddButton("Save", nextSlide).
AddButton("Cancel", nextSlide)
f.SetBorder(true).SetTitle("Employee Information")
return "Forms", Code(f, 36, 13, form)
}

View File

@ -0,0 +1,31 @@
package main
import (
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
const helloWorld = `[green]package[white] main
[green]import[white] (
[red]"github.com/rivo/tview"[white]
)
[green]func[white] [yellow]main[white]() {
box := tview.[yellow]NewBox[white]().
[yellow]SetBorder[white](true).
[yellow]SetTitle[white]([red]"Hello, world!"[white])
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](box, true).
[yellow]Run[white]()
}`
// HelloWorld shows a simple "Hello world" example.
func HelloWorld(nextSlide func()) (title string, content tview.Primitive) {
// We use a text view because we want to capture keyboard input.
textView := tview.NewTextView().SetDoneFunc(func(key tcell.Key) {
nextSlide()
})
textView.SetBorder(true).SetTitle("Hello, world!")
return "Hello, world", Code(textView, 30, 10, helloWorld)
}

View File

@ -0,0 +1,41 @@
package main
import (
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
const inputField = `[green]package[white] main
[green]import[white] (
[red]"strconv"[white]
[red]"github.com/gdamore/tcell"[white]
[red]"github.com/rivo/tview"[white]
)
[green]func[white] [yellow]main[white]() {
input := tview.[yellow]NewInputField[white]().
[yellow]SetLabel[white]([red]"Enter a number: "[white]).
[yellow]SetAcceptanceFunc[white](
tview.InputFieldInteger,
).[yellow]SetDoneFunc[white]([yellow]func[white](key tcell.Key) {
text := input.[yellow]GetText[white]()
n, _ := strconv.[yellow]Atoi[white](text)
[blue]// We have a number.[white]
})
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](input, true).
[yellow]SetFocus[white](input).
[yellow]Run[white]()
}`
// InputField demonstrates the InputField.
func InputField(nextSlide func()) (title string, content tview.Primitive) {
input := tview.NewInputField().
SetLabel("Enter a number: ").
SetAcceptanceFunc(tview.InputFieldInteger).SetDoneFunc(func(key tcell.Key) {
nextSlide()
})
return "Input", Code(input, 30, 1, inputField)
}

View File

@ -0,0 +1,14 @@
package main
import "github.com/rivo/tview"
// Introduction returns a tview.List with the highlights of the tview package.
func Introduction(nextSlide func()) (title string, content tview.Primitive) {
list := tview.NewList().
AddItem("A Go package for terminal based UIs", "with a special focus on rich interactive widgets", '1', nextSlide).
AddItem("Based on github.com/gdamore/tcell", "Like termbox but better (see tcell docs)", '2', nextSlide).
AddItem("Designed to be simple", `"Hello world" is 5 lines of code`, '3', nextSlide).
AddItem("Good for data entry", `For charts, use "termui" - for low-level views, use "gocui" - ...`, '4', nextSlide).
AddItem("Extensive documentation", "Everything is documented, examples in GitHub wiki, demo code for each widget", '5', nextSlide)
return "Introduction", Center(80, 10, list)
}

View File

@ -0,0 +1,86 @@
/*
Navigation
- Ctrl-N: Jump to next slide
- Ctrl-P: Jump to previous slide
*/
package main
import (
"fmt"
"strconv"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
// Slide is a function which returns the slide's main primitive and its title.
// It receives a "nextSlide" function which can be called to advance the
// presentation to the next slide.
type Slide func(nextSlide func()) (title string, content tview.Primitive)
// The application.
var app = tview.NewApplication()
// Starting point for the presentation.
func main() {
// The presentation slides.
slides := []Slide{
Cover,
Introduction,
HelloWorld,
InputField,
Form,
TextView1,
TextView2,
Table,
Flex,
End,
}
// The bottom row has some info on where we are.
info := tview.NewTextView().
SetDynamicColors(true).
SetRegions(true).
SetWrap(false)
// Create the pages for all slides.
currentSlide := 0
info.Highlight(strconv.Itoa(currentSlide))
pages := tview.NewPages()
previousSlide := func() {
currentSlide = (currentSlide - 1 + len(slides)) % len(slides)
info.Highlight(strconv.Itoa(currentSlide))
pages.SwitchToPage(strconv.Itoa(currentSlide))
}
nextSlide := func() {
currentSlide = (currentSlide + 1) % len(slides)
info.Highlight(strconv.Itoa(currentSlide))
pages.SwitchToPage(strconv.Itoa(currentSlide))
}
for index, slide := range slides {
title, primitive := slide(nextSlide)
pages.AddPage(strconv.Itoa(index), primitive, true, index == currentSlide)
fmt.Fprintf(info, `%d ["%d"][cyan]%s[white][""] `, index+1, index, title)
}
// Create the main layout.
layout := tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(pages, 0, 1, true).
AddItem(info, 1, 1, false)
// Shortcuts to navigate the slides.
app.SetKeyCapture(tcell.KeyCtrlN, 0, func(p tview.Primitive) bool {
nextSlide()
return false
}).SetKeyCapture(tcell.KeyCtrlP, 0, func(p tview.Primitive) bool {
previousSlide()
return false
})
// Start the application.
if err := app.SetRoot(layout, true).SetFocus(layout).Run(); err != nil {
panic(err)
}
}

366
demos/presentation/table.go Normal file
View File

@ -0,0 +1,366 @@
package main
import (
"fmt"
"strings"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
const tableData = `OrderDate|Region|Rep|Item|Units|UnitCost|Total
1/6/2017|East|Jones|Pencil|95|1.99|189.05
1/23/2017|Central|Kivell|Binder|50|19.99|999.50
2/9/2017|Central|Jardine|Pencil|36|4.99|179.64
2/26/2017|Central|Gill|Pen|27|19.99|539.73
3/15/2017|West|Sorvino|Pencil|56|2.99|167.44
4/1/2017|East|Jones|Binder|60|4.99|299.40
4/18/2017|Central|Andrews|Pencil|75|1.99|149.25
5/5/2017|Central|Jardine|Pencil|90|4.99|449.10
5/22/2017|West|Thompson|Pencil|32|1.99|63.68
6/8/2017|East|Jones|Binder|60|8.99|539.40
6/25/2017|Central|Morgan|Pencil|90|4.99|449.10
7/12/2017|East|Howard|Binder|29|1.99|57.71
7/29/2017|East|Parent|Binder|81|19.99|1,619.19
8/15/2017|East|Jones|Pencil|35|4.99|174.65
9/1/2017|Central|Smith|Desk|2|125.00|250.00
9/18/2017|East|Jones|Pen Set|16|15.99|255.84
10/5/2017|Central|Morgan|Binder|28|8.99|251.72
10/22/2017|East|Jones|Pen|64|8.99|575.36
11/8/2017|East|Parent|Pen|15|19.99|299.85
11/25/2017|Central|Kivell|Pen Set|96|4.99|479.04
12/12/2017|Central|Smith|Pencil|67|1.29|86.43
12/29/2017|East|Parent|Pen Set|74|15.99|1,183.26
1/15/2018|Central|Gill|Binder|46|8.99|413.54
2/1/2018|Central|Smith|Binder|87|15.00|1,305.00
2/18/2018|East|Jones|Binder|4|4.99|19.96
3/7/2018|West|Sorvino|Binder|7|19.99|139.93
3/24/2018|Central|Jardine|Pen Set|50|4.99|249.50
4/10/2018|Central|Andrews|Pencil|66|1.99|131.34
4/27/2018|East|Howard|Pen|96|4.99|479.04
5/14/2018|Central|Gill|Pencil|53|1.29|68.37
5/31/2018|Central|Gill|Binder|80|8.99|719.20
6/17/2018|Central|Kivell|Desk|5|125.00|625.00
7/4/2018|East|Jones|Pen Set|62|4.99|309.38
7/21/2018|Central|Morgan|Pen Set|55|12.49|686.95
8/7/2018|Central|Kivell|Pen Set|42|23.95|1,005.90
8/24/2018|West|Sorvino|Desk|3|275.00|825.00
9/10/2018|Central|Gill|Pencil|7|1.29|9.03
9/27/2018|West|Sorvino|Pen|76|1.99|151.24
10/14/2018|West|Thompson|Binder|57|19.99|1,139.43
10/31/2018|Central|Andrews|Pencil|14|1.29|18.06
11/17/2018|Central|Jardine|Binder|11|4.99|54.89
12/4/2018|Central|Jardine|Binder|94|19.99|1,879.06
12/21/2018|Central|Andrews|Binder|28|4.99|139.72`
const tableBasic = `[green]func[white] [yellow]main[white]() {
table := tview.[yellow]NewTable[white]().
[yellow]SetFixed[white]([red]1[white], [red]1[white])
[yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
[yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
color := tcell.ColorWhite
[yellow]if[white] row == [red]0[white] {
color = tcell.ColorYellow
} [yellow]else[white] [yellow]if[white] column == [red]0[white] {
color = tcell.ColorDarkCyan
}
align := tview.AlignLeft
[yellow]if[white] row == [red]0[white] {
align = tview.AlignCenter
} [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
align = tview.AlignRight
}
table.[yellow]SetCell[white](row,
column,
&tview.TableCell{
Text: [red]"..."[white],
Color: color,
Align: align,
})
}
}
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](table, true).
[yellow]SetFocus[white](table).
[yellow]Run[white]()
}`
const tableSeparator = `[green]func[white] [yellow]main[white]() {
table := tview.[yellow]NewTable[white]().
[yellow]SetFixed[white]([red]1[white], [red]1[white]).
[yellow]SetSeparator[white](tview.GraphicsVertBar)
[yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
[yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
color := tcell.ColorWhite
[yellow]if[white] row == [red]0[white] {
color = tcell.ColorYellow
} [yellow]else[white] [yellow]if[white] column == [red]0[white] {
color = tcell.ColorDarkCyan
}
align := tview.AlignLeft
[yellow]if[white] row == [red]0[white] {
align = tview.AlignCenter
} [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
align = tview.AlignRight
}
table.[yellow]SetCell[white](row,
column,
&tview.TableCell{
Text: [red]"..."[white],
Color: color,
Align: align,
})
}
}
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](table, true).
[yellow]SetFocus[white](table).
[yellow]Run[white]()
}`
const tableBorders = `[green]func[white] [yellow]main[white]() {
table := tview.[yellow]NewTable[white]().
[yellow]SetFixed[white]([red]1[white], [red]1[white]).
[yellow]SetBorders[white](true)
[yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
[yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
color := tcell.ColorWhite
[yellow]if[white] row == [red]0[white] {
color = tcell.ColorYellow
} [yellow]else[white] [yellow]if[white] column == [red]0[white] {
color = tcell.ColorDarkCyan
}
align := tview.AlignLeft
[yellow]if[white] row == [red]0[white] {
align = tview.AlignCenter
} [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
align = tview.AlignRight
}
table.[yellow]SetCell[white](row,
column,
&tview.TableCell{
Text: [red]"..."[white],
Color: color,
Align: align,
})
}
}
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](table, true).
[yellow]SetFocus[white](table).
[yellow]Run[white]()
}`
const tableSelectRow = `[green]func[white] [yellow]main[white]() {
table := tview.[yellow]NewTable[white]().
[yellow]SetFixed[white]([red]1[white], [red]1[white]).
[yellow]SetSelectable[white](true, false)
[yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
[yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
color := tcell.ColorWhite
[yellow]if[white] row == [red]0[white] {
color = tcell.ColorYellow
} [yellow]else[white] [yellow]if[white] column == [red]0[white] {
color = tcell.ColorDarkCyan
}
align := tview.AlignLeft
[yellow]if[white] row == [red]0[white] {
align = tview.AlignCenter
} [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
align = tview.AlignRight
}
table.[yellow]SetCell[white](row,
column,
&tview.TableCell{
Text: [red]"..."[white],
Color: color,
Align: align,
NotSelectable: row == [red]0[white] || column == [red]0[white],
})
}
}
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](table, true).
[yellow]SetFocus[white](table).
[yellow]Run[white]()
}`
const tableSelectColumn = `[green]func[white] [yellow]main[white]() {
table := tview.[yellow]NewTable[white]().
[yellow]SetFixed[white]([red]1[white], [red]1[white]).
[yellow]SetSelectable[white](false, true)
[yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
[yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
color := tcell.ColorWhite
[yellow]if[white] row == [red]0[white] {
color = tcell.ColorYellow
} [yellow]else[white] [yellow]if[white] column == [red]0[white] {
color = tcell.ColorDarkCyan
}
align := tview.AlignLeft
[yellow]if[white] row == [red]0[white] {
align = tview.AlignCenter
} [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
align = tview.AlignRight
}
table.[yellow]SetCell[white](row,
column,
&tview.TableCell{
Text: [red]"..."[white],
Color: color,
Align: align,
NotSelectable: row == [red]0[white] || column == [red]0[white],
})
}
}
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](table, true).
[yellow]SetFocus[white](table).
[yellow]Run[white]()
}`
const tableSelectCell = `[green]func[white] [yellow]main[white]() {
table := tview.[yellow]NewTable[white]().
[yellow]SetFixed[white]([red]1[white], [red]1[white]).
[yellow]SetSelectable[white](true, true)
[yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ {
[yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ {
color := tcell.ColorWhite
[yellow]if[white] row == [red]0[white] {
color = tcell.ColorYellow
} [yellow]else[white] [yellow]if[white] column == [red]0[white] {
color = tcell.ColorDarkCyan
}
align := tview.AlignLeft
[yellow]if[white] row == [red]0[white] {
align = tview.AlignCenter
} [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] {
align = tview.AlignRight
}
table.[yellow]SetCell[white](row,
column,
&tview.TableCell{
Text: [red]"..."[white],
Color: color,
Align: align,
NotSelectable: row == [red]0[white] || column == [red]0[white],
})
}
}
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](table, true).
[yellow]SetFocus[white](table).
[yellow]Run[white]()
}`
// Table demonstrates the Table.
func Table(nextSlide func()) (title string, content tview.Primitive) {
table := tview.NewTable().
SetFixed(1, 1)
for row, line := range strings.Split(tableData, "\n") {
for column, cell := range strings.Split(line, "|") {
color := tcell.ColorWhite
if row == 0 {
color = tcell.ColorYellow
} else if column == 0 {
color = tcell.ColorDarkCyan
}
align := tview.AlignLeft
if row == 0 {
align = tview.AlignCenter
} else if column == 0 || column >= 4 {
align = tview.AlignRight
}
table.SetCell(row, column, &tview.TableCell{
Text: cell,
Color: color,
Align: align,
NotSelectable: row == 0 || column == 0,
})
}
}
table.SetBorder(true).SetTitle("Table")
code := tview.NewTextView().
SetWrap(false).
SetDynamicColors(true)
code.SetBorderPadding(1, 1, 2, 0)
list := tview.NewList()
basic := func() {
table.SetBorders(false).
SetSelectable(false, false).
SetSeparator(' ')
code.Clear()
fmt.Fprint(code, tableBasic)
}
separator := func() {
table.SetBorders(false).
SetSelectable(false, false).
SetSeparator(tview.GraphicsVertBar)
code.Clear()
fmt.Fprint(code, tableSeparator)
}
borders := func() {
table.SetBorders(true).
SetSelectable(false, false)
code.Clear()
fmt.Fprint(code, tableBorders)
}
selectRow := func() {
table.SetBorders(false).
SetSelectable(true, false).
SetSeparator(' ')
code.Clear()
fmt.Fprint(code, tableSelectRow)
}
selectColumn := func() {
table.SetBorders(false).
SetSelectable(false, true).
SetSeparator(' ')
code.Clear()
fmt.Fprint(code, tableSelectColumn)
}
selectCell := func() {
table.SetBorders(false).
SetSelectable(true, true).
SetSeparator(' ')
code.Clear()
fmt.Fprint(code, tableSelectCell)
}
navigate := func() {
app.SetFocus(table)
table.SetDoneFunc(func(key tcell.Key) {
app.SetFocus(list)
}).SetSelectedFunc(func(row int, column int) {
app.SetFocus(list)
})
}
list.ShowSecondaryText(false).
AddItem("Basic table", "", 'b', basic).
AddItem("Table with separator", "", 's', separator).
AddItem("Table with borders", "", 'o', borders).
AddItem("Selectable rows", "", 'r', selectRow).
AddItem("Selectable columns", "", 'c', selectColumn).
AddItem("Selectable cells", "", 'l', selectCell).
AddItem("Navigate", "", 'n', navigate).
AddItem("Next slide", "", 'x', nextSlide)
list.SetBorderPadding(1, 1, 2, 2)
basic()
return "Table", tview.NewFlex().
AddItem(tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(list, 10, 1, true).
AddItem(table, 0, 1, false), 0, 1, true).
AddItem(code, codeWidth, 1, false)
}

View File

@ -0,0 +1,150 @@
package main
import (
"fmt"
"strconv"
"time"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
)
const textView1 = `[green]func[white] [yellow]main[white]() {
textView := tview.[yellow]NewTextView[white]().
[yellow]SetTextColor[white](tcell.ColorYellow).
[yellow]SetScrollable[white](false).
[yellow]SetChangedFunc[white]([yellow]func[white]() {
app.[yellow]Draw[white]()
})
[green]go[white] [yellow]func[white]() {
[green]var[white] n [green]int
[white] [yellow]for[white] {
n++
fmt.[yellow]Fprintf[white](textView, [red]"%d "[white], n)
time.[yellow]Sleep[white]([red]200[white] * time.Millisecond)
}
}()
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](textView, true).
[yellow]SetFocus[white](textView).
[yellow]Run[white]()
}`
// TextView1 demonstrates the basic text view.
func TextView1(nextSlide func()) (title string, content tview.Primitive) {
textView := tview.NewTextView().
SetTextColor(tcell.ColorYellow).
SetScrollable(false).
SetChangedFunc(func() {
app.Draw()
}).SetDoneFunc(func(key tcell.Key) {
nextSlide()
})
go func() {
var n int
for {
n++
fmt.Fprintf(textView, "%d ", n)
time.Sleep(200 * time.Millisecond)
}
}()
textView.SetBorder(true).SetTitle("TextView implements io.Writer")
return "Text 1", Code(textView, 36, 13, textView1)
}
const textView2 = `[green]package[white] main
[green]import[white] (
[red]"strconv"[white]
[red]"github.com/gdamore/tcell"[white]
[red]"github.com/rivo/tview"[white]
)
[green]func[white] [yellow]main[white]() {
["0"]textView[""] := tview.[yellow]NewTextView[white]()
["1"]textView[""].[yellow]SetDynamicColors[white](true).
[yellow]SetWrap[white](false).
[yellow]SetRegions[white](true).
[yellow]SetDoneFunc[white]([yellow]func[white](key tcell.Key) {
highlights := ["2"]textView[""].[yellow]GetHighlights[white]()
hasHighlights := [yellow]len[white](highlights) > [red]0
[white] [yellow]switch[white] key {
[yellow]case[white] tcell.KeyEnter:
[yellow]if[white] hasHighlights {
["3"]textView[""].[yellow]Highlight[white]()
} [yellow]else[white] {
["4"]textView[""].[yellow]Highlight[white]([red]"0"[white]).
[yellow]ScrollToHighlight[white]()
}
[yellow]case[white] tcell.KeyTab:
[yellow]if[white] hasHighlights {
current, _ := strconv.[yellow]Atoi[white](highlights[[red]0[white]])
next := (current + [red]1[white]) % [red]9
[white] ["5"]textView[""].[yellow]Highlight[white](strconv.[yellow]Itoa[white](next)).
[yellow]ScrollToHighlight[white]()
}
[yellow]case[white] tcell.KeyBacktab:
[yellow]if[white] hasHighlights {
current, _ := strconv.[yellow]Atoi[white](highlights[[red]0[white]])
next := (current - [red]1[white] + [red]9[white]) % [red]9
[white] ["6"]textView[""].[yellow]Highlight[white](strconv.[yellow]Itoa[white](next)).
[yellow]ScrollToHighlight[white]()
}
}
})
fmt.[yellow]Fprint[white](["7"]textView[""], content)
tview.[yellow]NewApplication[white]().
[yellow]SetRoot[white](["8"]textView[""], true).
[yellow]SetFocus[white](["9"]textView[""]).
[yellow]Run[white]()
}`
// TextView2 demonstrates the extended text view.
func TextView2(nextSlide func()) (title string, content tview.Primitive) {
codeView := tview.NewTextView().
SetWrap(false)
fmt.Fprint(codeView, textView2)
codeView.SetBorder(true).SetTitle("TextView content")
textView := tview.NewTextView()
textView.SetDynamicColors(true).
SetWrap(false).
SetRegions(true).
SetDoneFunc(func(key tcell.Key) {
if key == tcell.KeyEscape {
nextSlide()
return
}
highlights := textView.GetHighlights()
hasHighlights := len(highlights) > 0
switch key {
case tcell.KeyEnter:
if hasHighlights {
textView.Highlight()
} else {
textView.Highlight("0").
ScrollToHighlight()
}
case tcell.KeyTab:
if hasHighlights {
current, _ := strconv.Atoi(highlights[0])
next := (current + 1) % 10
textView.Highlight(strconv.Itoa(next)).
ScrollToHighlight()
}
case tcell.KeyBacktab:
if hasHighlights {
current, _ := strconv.Atoi(highlights[0])
next := (current - 1 + 10) % 10
textView.Highlight(strconv.Itoa(next)).
ScrollToHighlight()
}
}
})
fmt.Fprint(textView, textView2)
textView.SetBorder(true).SetTitle("TextView code")
return "Text 2", tview.NewFlex().
AddItem(textView, 0, 1, true).
AddItem(codeView, 0, 1, false)
}