k9s/views/menu.go

167 lines
2.5 KiB
Go

package views
import (
"fmt"
"sort"
"strconv"
"strings"
"github.com/gdamore/tcell"
"github.com/k8sland/k9s/resource"
"github.com/k8sland/tview"
)
const (
menuFmt = " [dodgerblue::b]%s[white::d]%s "
menuSepFmt = " [dodgerblue::b]<%s> [white::d]%s "
menuIndexFmt = " [dodgerblue::b]<%d> [white::d]%s "
maxRows = 5
colLen = 20
)
// Defines numeric keys for container actions
const (
Key0 int32 = iota + 48
Key1
Key2
Key3
Key4
Key5
Key6
Key7
Key8
Key9
)
// Defines char keystrokes
const (
KeyA int32 = iota + 97
KeyB
KeyC
KeyD
KeyE
KeyF
KeyG
KeyH
KeyI
KeyJ
KeyK
KeyL
KeyM
KeyN
KeyO
KeyP
KeyQ
KeyR
KeyS
KeyT
KeyU
KeyV
KeyW
KeyX
KeyY
KeyZ
)
var numKeys = map[int]int32{
0: Key0,
1: Key1,
2: Key2,
3: Key3,
4: Key4,
5: Key5,
6: Key6,
7: Key7,
8: Key8,
9: Key9,
}
type (
keyboardHandler func(*tcell.EventKey)
hint struct {
mnemonic, display string
}
hints []hint
hinter interface {
hints() hints
}
keyAction struct {
description string
action keyboardHandler
}
keyActions map[tcell.Key]keyAction
menuView struct {
*tview.Grid
}
)
func newKeyHandler(d string, a keyboardHandler) keyAction {
return keyAction{description: d, action: a}
}
func newMenuView() *menuView {
v := menuView{tview.NewGrid()}
v.SetGap(0, 1)
return &v
}
func (v *menuView) setMenu(hh hints) {
v.Clear()
v.SetRows(1, 1, 1, 1)
v.SetColumns(colLen, colLen)
isNS := true
var row, col int
for _, h := range hh {
// Reset cols for namespace menus...
if len(h.mnemonic) == 1 && isNS {
col++
row = 0
isNS = false
}
v.AddItem(v.item(h), row, col, 1, 1, 1, 1, false)
row++
if row > maxRows {
col++
row = 0
}
}
}
func (v *menuView) item(h hint) tview.Primitive {
c := tview.NewTextView()
c.SetDynamicColors(true)
var s string
if i, err := strconv.Atoi(h.mnemonic); err != nil {
if strings.ToLower(h.display)[0] == h.mnemonic[0] {
s = fmt.Sprintf(menuFmt, strings.ToUpper(h.mnemonic), h.display[1:])
} else {
s = fmt.Sprintf(menuSepFmt, strings.ToUpper(h.mnemonic), h.display)
}
} else {
s = fmt.Sprintf(menuIndexFmt, i, resource.Truncate(h.display, 14))
}
c.SetText(s)
return c
}
func (a keyActions) toHints() hints {
kk := make([]int, 0, len(a))
for k := range a {
kk = append(kk, int(k))
}
sort.Ints(kk)
hh := make(hints, 0, len(a))
for _, k := range kk {
hh = append(hh, hint{
mnemonic: tcell.KeyNames[tcell.Key(k)],
display: a[tcell.Key(k)].description})
}
return hh
}