discordo/internal/ui/tree/tree.go

84 lines
2.8 KiB
Go

// Package tree holds what discordo's trees share.
package tree
import (
"github.com/ayn2op/discordo/internal/config"
"github.com/ayn2op/discordo/internal/ui"
"github.com/ayn2op/tview"
"github.com/ayn2op/tview/box"
"github.com/ayn2op/tview/keybind"
"github.com/ayn2op/tview/layout"
"github.com/ayn2op/tview/tree"
"github.com/ayn2op/tview/viewport"
"github.com/gdamore/tcell/v3"
)
// ScrollMsg scrolls the tree to ScrollState, before passing on Msg if the tree sent one.
type ScrollMsg struct {
ScrollState viewport.ScrollState
Msg tview.Msg
}
// New returns a boxed tree of the nodes under root in a viewport.
func New(root, current *tree.Node, scrollState viewport.ScrollState, cfg *config.Config, theme config.TreeThemeConfig, graphics bool, kbs config.TreeKeybinds, focused bool, onChange, onSelect func(*tree.Node) tview.Msg) box.Widget {
set := cfg.UI.Border.NormalSet.BorderSet
if focused {
set = cfg.UI.Border.ActiveSet.BorderSet
}
t := tree.New(root, current).
TopLevel(1).
Markers(tree.Markers{
Expanded: cfg.Sidebar.Markers.Expanded,
Collapsed: cfg.Sidebar.Markers.Collapsed,
Leaf: cfg.Sidebar.Markers.Leaf,
}).
Graphics(graphics).
GraphicsSet(set).
GraphicsStyle(tcell.StyleDefault.Foreground(tcell.GetColor(theme.GraphicsColor))).
Keybind(bindKeys(kbs)).
Focused(focused).
OnChange(onChange).
OnSelect(onSelect)
v := viewport.New(t, scrollState).
Target(t.Target).
ContentWidth(t.RowsWidth).
OnChildMsg(func(s *viewport.ScrollState, msg tview.Msg) tview.Msg { return ScrollMsg{ScrollState: *s, Msg: msg} }).
Axes(layout.Axes{Width: true, Height: true}).
Keybind(bindScrollKeys(kbs)).
Focused(focused).
OnChange(func(s *viewport.ScrollState) tview.Msg { return ScrollMsg{ScrollState: *s} })
return ui.Box(v, cfg, focused)
}
func bindKeys(kbs config.TreeKeybinds) func(tview.KeyMsg) tree.Action {
return func(key tview.KeyMsg) tree.Action {
switch {
case keybind.Matches(key, kbs.SelectUp.Keybind):
return tree.ActionUp
case keybind.Matches(key, kbs.SelectDown.Keybind):
return tree.ActionDown
case keybind.Matches(key, kbs.SelectTop.Keybind):
return tree.ActionTop
case keybind.Matches(key, kbs.SelectBottom.Keybind):
return tree.ActionBottom
case keybind.Matches(key, kbs.MoveToParentNode.Keybind):
return tree.ActionMoveToParent
case keybind.Matches(key, kbs.SelectCurrent.Keybind):
return tree.ActionSelect
}
return tree.ActionNone
}
}
func bindScrollKeys(kbs config.TreeKeybinds) func(tview.KeyMsg) viewport.Action {
scroll := ui.ScrollKeybind(kbs.ScrollKeybinds)
return func(key tview.KeyMsg) viewport.Action {
switch {
case keybind.Matches(key, kbs.ScrollLeft.Keybind):
return viewport.ActionLeft
case keybind.Matches(key, kbs.ScrollRight.Keybind):
return viewport.ActionRight
}
return scroll(key)
}
}