mirror of
https://github.com/rivo/tview.git
synced 2025-04-26 13:49:06 +08:00
Added a presentation demonstrating tview's capabilities.
This commit is contained in:
parent
7a69902269
commit
53527f5f80
16
demos/presentation/center.go
Normal file
16
demos/presentation/center.go
Normal 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)
|
||||
}
|
25
demos/presentation/code.go
Normal file
25
demos/presentation/code.go
Normal 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)
|
||||
}
|
56
demos/presentation/cover.go
Normal file
56
demos/presentation/cover.go
Normal 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
18
demos/presentation/end.go
Normal 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)
|
||||
}
|
39
demos/presentation/flex.go
Normal file
39
demos/presentation/flex.go
Normal 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
|
||||
}
|
42
demos/presentation/form.go
Normal file
42
demos/presentation/form.go
Normal 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)
|
||||
}
|
31
demos/presentation/helloworld.go
Normal file
31
demos/presentation/helloworld.go
Normal 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)
|
||||
}
|
41
demos/presentation/inputfield.go
Normal file
41
demos/presentation/inputfield.go
Normal 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)
|
||||
}
|
14
demos/presentation/introduction.go
Normal file
14
demos/presentation/introduction.go
Normal 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)
|
||||
}
|
86
demos/presentation/main.go
Normal file
86
demos/presentation/main.go
Normal 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
366
demos/presentation/table.go
Normal 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)
|
||||
}
|
150
demos/presentation/textview.go
Normal file
150
demos/presentation/textview.go
Normal 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)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user