// go get github.com/rivo/tview@master package tui import ( "errors" node "git.zzyxyz.com/zzy/goncdu/node" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) type UI struct { app *tview.Application msg string err string main *ListFrame list tview.Primitive input tview.Primitive modal tview.Primitive } func NewUI(n *node.NodeManager) *UI { ui := &UI{ app: tview.NewApplication(), msg: "", err: "", main: &ListFrame{node: n}, } return ui } func (ui *UI) MakeAllUI() { ui.list = ui.main.MakeListFrameUI(func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { case tcell.KeyRight: idx := ui.main.list.GetCurrentItem() if len(ui.main.nodes) == 0 { ui.err = errors.New("no children nodes").Error() break } name := ui.main.nodes[idx].GetPath() if err := ui.main.node.GoIn(name); err != nil { ui.err = err.Error() break } case tcell.KeyLeft: if err := ui.main.node.GoOut(); err != nil { ui.err = err.Error() } case tcell.KeyRune: switch event.Rune() { case 'q': ui.app.Stop() case '?': // show help ui.app.SetRoot(ui.modal, false) case 'R': ui.app.SetRoot(ui.input, true) case 'S': if err := ui.main.node.SaveToFile(); err != nil { ui.err = err.Error() } case 'L': if err := ui.main.node.LoadFromFile(); err != nil { ui.err = err.Error() } default: return event } default: return event } // END: ui.main.RenderList() return nil }) ui.modal = MakeHelpUI(func() { ui.app.SetRoot(ui.list, true) }) ui.input = MakeInputUI(func(path string) error { valid := ui.main.node.SetRootPath(path) if valid { ui.app.SetRoot(ui.list, true) ui.scanPath() return nil } else { return errors.New("invalid path") } }) } func (ui *UI) run() { if err := ui.app.Run(); err != nil { panic(err) } } func (ui *UI) scanPath() { err := ui.main.node.Scan() if err != nil { ui.err = err.Error() } ui.main.RenderList() } func ShowMain(entry *node.NodeManager) { ui := NewUI(entry) ui.MakeAllUI() // need input path if entry.VaildRoot() { ui.app.SetRoot(ui.list, true) ui.scanPath() } else { ui.app.SetRoot(ui.input, true) } ui.run() }