// SPDX-License-Identifier: Apache-2.0 // Copyright Authors of K9s package ui import ( "context" "github.com/derailed/k9s/internal/model" "github.com/derailed/tcell/v2" "github.com/derailed/tview" ) // KeyListenerFunc listens to key presses. type KeyListenerFunc func() // Tree represents a tree view. type Tree struct { *tview.TreeView actions *KeyActions selectedItem string cmdBuff *model.FishBuff expandNodes bool Count int keyListener KeyListenerFunc } // NewTree returns a new view. func NewTree() *Tree { return &Tree{ TreeView: tview.NewTreeView(), expandNodes: true, actions: NewKeyActions(), cmdBuff: model.NewFishBuff('/', model.FilterBuffer), } } // Init initializes the view. func (t *Tree) Init(context.Context) error { t.BindKeys() t.SetBorder(true) t.SetBorderAttributes(tcell.AttrBold) t.SetBorderPadding(0, 0, 1, 1) t.SetGraphics(true) t.SetGraphicsColor(tcell.ColorCadetBlue) t.SetInputCapture(t.keyboard) return nil } // SetSelectedItem sets the currently selected node. func (t *Tree) SetSelectedItem(s string) { t.selectedItem = s } // GetSelectedItem returns the currently selected item or blank if none. func (t *Tree) GetSelectedItem() string { return t.selectedItem } // ExpandNodes returns true if nodes are expanded or false otherwise. func (t *Tree) ExpandNodes() bool { return t.expandNodes } // CmdBuff returns the filter command. func (t *Tree) CmdBuff() *model.FishBuff { return t.cmdBuff } // SetKeyListenerFn sets a key entered listener. func (t *Tree) SetKeyListenerFn(f KeyListenerFunc) { t.keyListener = f } // Actions returns active menu bindings. func (t *Tree) Actions() *KeyActions { return t.actions } // Hints returns the view hints. func (t *Tree) Hints() model.MenuHints { return t.actions.Hints() } // ExtraHints returns additional hints. func (*Tree) ExtraHints() map[string]string { return nil } // BindKeys binds default mnemonics. func (t *Tree) BindKeys() { t.Actions().Merge(NewKeyActionsFromMap(KeyMap{ KeySpace: NewKeyAction("Expand/Collapse", t.noopCmd, true), KeyX: NewKeyAction("Expand/Collapse All", t.toggleCollapseCmd, true), })) } func (t *Tree) keyboard(evt *tcell.EventKey) *tcell.EventKey { if a, ok := t.actions.Get(AsKey(evt)); ok { return a.Action(evt) } return evt } func (*Tree) noopCmd(evt *tcell.EventKey) *tcell.EventKey { return evt } func (t *Tree) toggleCollapseCmd(*tcell.EventKey) *tcell.EventKey { t.expandNodes = !t.expandNodes t.GetRoot().Walk(func(node, parent *tview.TreeNode) bool { if parent != nil { node.SetExpanded(t.expandNodes) } return true }) return nil } // ClearSelection clears the currently selected node. func (t *Tree) ClearSelection() { t.selectedItem = "" t.SetCurrentNode(nil) }