163 lines
3.1 KiB
Go
163 lines
3.1 KiB
Go
package tui
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
"github.com/rivo/tview"
|
|
)
|
|
|
|
type TabPrimitive interface {
|
|
tview.Primitive
|
|
ForceRedraw()
|
|
}
|
|
|
|
type Tabs struct {
|
|
*tview.Flex
|
|
|
|
names []string
|
|
items map[string]tview.Primitive
|
|
selector *tview.TextView
|
|
pages *tview.Pages
|
|
fallover bool
|
|
unlock bool
|
|
}
|
|
|
|
func NewTabs(selectorAtTop bool) *Tabs {
|
|
widget := &Tabs{
|
|
Flex: tview.NewFlex(),
|
|
names: []string{},
|
|
items: make(map[string]tview.Primitive),
|
|
fallover: true,
|
|
}
|
|
widget.SetDirection(tview.FlexRow)
|
|
|
|
// Selector
|
|
widget.selector = tview.NewTextView().
|
|
SetDynamicColors(true).
|
|
SetRegions(true).
|
|
SetWrap(false).
|
|
SetTextAlign(tview.AlignLeft)
|
|
widget.selector.SetHighlightedFunc(
|
|
func(added, removed, remaining []string) {
|
|
if len(added) == 0 {
|
|
return
|
|
}
|
|
|
|
widget.pages.SwitchToPage(added[0])
|
|
},
|
|
)
|
|
if selectorAtTop {
|
|
widget.AddItem(widget.selector, 1, 0, false)
|
|
}
|
|
|
|
// Pages
|
|
widget.pages = tview.NewPages()
|
|
widget.AddItem(widget.pages, 0, 1, false)
|
|
|
|
if !selectorAtTop {
|
|
widget.AddItem(widget.selector, 1, 0, false)
|
|
}
|
|
|
|
return widget
|
|
}
|
|
|
|
func (widget *Tabs) AllowFallover(allow bool) {
|
|
widget.fallover = allow
|
|
}
|
|
|
|
func (widget *Tabs) AddText(text string) {
|
|
fmt.Fprint(widget.selector, text)
|
|
}
|
|
|
|
func (widget *Tabs) AddTab(name string, label string, item tview.Primitive, visible bool) {
|
|
widget.names = append(widget.names, name)
|
|
widget.items[name] = item
|
|
fmt.Fprintf(widget.selector, `["%s"][darkcyan]%s[white][""] `, name, label)
|
|
widget.pages.AddPage(name, item, true, false)
|
|
if visible {
|
|
widget.Select(name)
|
|
}
|
|
}
|
|
|
|
func (widget *Tabs) Select(name string) {
|
|
widget.selector.Highlight(name)
|
|
}
|
|
|
|
func (widget *Tabs) Next() tview.Primitive {
|
|
widget.unlock = true
|
|
if len(widget.names) == 0 {
|
|
return nil
|
|
}
|
|
|
|
index := -1
|
|
highlights := widget.selector.GetHighlights()
|
|
if len(highlights) > 0 {
|
|
currentName := highlights[0]
|
|
for currentIndex, name := range widget.names {
|
|
if name == currentName {
|
|
index = currentIndex
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
index++
|
|
if index >= len(widget.names) {
|
|
if widget.fallover {
|
|
index = 0
|
|
} else {
|
|
index = len(widget.names) - 1
|
|
}
|
|
}
|
|
|
|
widget.selector.Highlight(widget.names[index])
|
|
|
|
return widget.items[widget.names[index]]
|
|
}
|
|
|
|
func (widget *Tabs) Prev() tview.Primitive {
|
|
widget.unlock = true
|
|
if len(widget.names) == 0 {
|
|
return nil
|
|
}
|
|
|
|
index := len(widget.names)
|
|
highlights := widget.selector.GetHighlights()
|
|
if len(highlights) > 0 {
|
|
currentName := highlights[0]
|
|
for currentIndex, name := range widget.names {
|
|
if name == currentName {
|
|
index = currentIndex
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
index--
|
|
if index < 0 {
|
|
if widget.fallover {
|
|
index = len(widget.names) - 1
|
|
} else {
|
|
index = 0
|
|
}
|
|
}
|
|
|
|
widget.selector.Highlight(widget.names[index])
|
|
|
|
return widget.items[widget.names[index]]
|
|
}
|
|
|
|
func (widget *Tabs) Focus(delegate func(p tview.Primitive)) {
|
|
delegate(widget.pages)
|
|
}
|
|
|
|
func (widget *Tabs) Draw(screen tcell.Screen) {
|
|
if widget.unlock {
|
|
widgetX, widgetY, widgetWidth, widgetHeight := widget.GetInnerRect()
|
|
screen.LockRegion(widgetX, widgetY, widgetWidth, widgetHeight, false)
|
|
widget.unlock = false
|
|
}
|
|
|
|
widget.Flex.Draw(screen)
|
|
}
|