77 lines
2.3 KiB
Go
77 lines
2.3 KiB
Go
// Package tree holds what discordo's trees share.
|
|
package tree
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
"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/tree"
|
|
"github.com/gdamore/tcell/v3"
|
|
"golang.design/x/clipboard"
|
|
)
|
|
|
|
// New returns a boxed tree of the nodes under root, drawn with theme and moved with kbs, that turns changes into the message onChange returns.
|
|
func New(root *tree.Node, selectionState *tree.SelectionState, cfg *config.Config, theme config.CommonTreeTheme, kbs config.TreeKeybinds, focused bool, onChange func(tree.Change) tview.Msg) box.Widget {
|
|
set := cfg.Theme.Border.NormalSet.BorderSet
|
|
if focused {
|
|
set = cfg.Theme.Border.ActiveSet.BorderSet
|
|
}
|
|
t := tree.New(root, selectionState).
|
|
TopLevel(1).
|
|
Markers(tree.Markers{
|
|
Expanded: cfg.Sidebar.Markers.Expanded,
|
|
Collapsed: cfg.Sidebar.Markers.Collapsed,
|
|
Leaf: cfg.Sidebar.Markers.Leaf,
|
|
}).
|
|
Graphics(theme.Graphics).
|
|
GraphicsSet(set).
|
|
GraphicsStyle(tcell.StyleDefault.Foreground(tcell.GetColor(theme.GraphicsColor))).
|
|
Keybind(bindKeys(kbs)).
|
|
Focused(focused).
|
|
OnChange(onChange)
|
|
return ui.Box(t, &cfg.Theme, focused)
|
|
}
|
|
|
|
func bindKeys(kbs config.TreeKeybinds) func(tview.KeyMsg) (tree.Action, bool) {
|
|
return func(key tview.KeyMsg) (tree.Action, bool) {
|
|
switch {
|
|
case keybind.Matches(key, kbs.SelectUp.Keybind):
|
|
return tree.ActionUp, true
|
|
case keybind.Matches(key, kbs.SelectDown.Keybind):
|
|
return tree.ActionDown, true
|
|
case keybind.Matches(key, kbs.SelectTop.Keybind):
|
|
return tree.ActionTop, true
|
|
case keybind.Matches(key, kbs.SelectBottom.Keybind):
|
|
return tree.ActionBottom, true
|
|
case keybind.Matches(key, kbs.MoveToParentNode.Keybind):
|
|
return tree.ActionMoveToParent, true
|
|
case keybind.Matches(key, kbs.SelectCurrent.Keybind):
|
|
return tree.ActionSelect, true
|
|
}
|
|
return 0, false
|
|
}
|
|
}
|
|
|
|
// YankID copies the ID of node to the clipboard.
|
|
func YankID(node *tree.Node) tview.Cmd {
|
|
if node == nil {
|
|
return nil
|
|
}
|
|
|
|
id, ok := node.Reference().(fmt.Stringer)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return func() tview.Msg {
|
|
if _, err := clipboard.Write(context.Background(), clipboard.FmtText, []byte(id.String())); err != nil {
|
|
slog.Error("failed to write to clipboard", "err", err)
|
|
}
|
|
return nil
|
|
}
|
|
}
|