package ui import ( "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) // arrowNavigation lets a form be driven with the arrow keys: // - Up/Down move between the fields and buttons, // - Left/Right change the value of a closed dropdown without opening it // (and move between the buttons), // // Enter or Space still opens a dropdown list. While a list is open it gets all keys. func arrowNavigation(f *tview.Form) { f.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey { item, button := f.GetFocusedItemIndex() if item < 0 && button < 0 { return ev } dd, _ := focusedDropDown(f, item) if dd != nil && dd.IsOpen() { return ev } total := f.GetFormItemCount() + f.GetButtonCount() pos := item if button >= 0 { pos = f.GetFormItemCount() + button } switch ev.Key() { case tcell.KeyDown: f.SetFocus(min(pos+1, total-1)) case tcell.KeyUp: f.SetFocus(max(pos-1, 0)) case tcell.KeyLeft, tcell.KeyRight: step := 1 if ev.Key() == tcell.KeyLeft { step = -1 } switch { case dd != nil: n := dd.GetOptionCount() cur, _ := dd.GetCurrentOption() dd.SetCurrentOption((cur + step + n) % n) case button >= 0: f.SetFocus(min(max(pos+step, f.GetFormItemCount()), total-1)) default: return ev } default: return ev } return nil }) } func focusedDropDown(f *tview.Form, item int) (*tview.DropDown, bool) { if item < 0 { return nil, false } dd, ok := f.GetFormItem(item).(*tview.DropDown) return dd, ok }