1package widgets 2 3import ( 4 "github.com/ambientsound/visp/api" 5 "github.com/ambientsound/visp/log" 6 "github.com/ambientsound/visp/multibar" 7 "github.com/ambientsound/visp/style" 8 "github.com/gdamore/tcell/v2" 9 "github.com/gdamore/tcell/v2/views" 10) 11 12type widgets struct { 13 layout *views.BoxLayout 14 Topbar *Topbar 15 multibar *Multibar 16 table *Table 17} 18 19type Application struct { 20 api api.API 21 events chan tcell.Event 22 screen tcell.Screen 23 Widgets widgets 24 style.Styled 25} 26 27var _ tcell.EventHandler = &Application{} 28 29var _ api.UI = &Application{} 30 31func NewApplication(a api.API) (*Application, error) { 32 screen, err := tcell.NewScreen() 33 if err != nil { 34 return nil, err 35 } 36 37 err = screen.Init() 38 if err != nil { 39 return nil, err 40 } 41 42 screen.Clear() 43 screen.Show() 44 45 return &Application{ 46 api: a, 47 events: make(chan tcell.Event, 1024), 48 screen: screen, 49 }, nil 50} 51 52func (app *Application) Init() { 53 app.Widgets.Topbar = NewTopbar(app.api) 54 app.Widgets.table = NewTable(app.api) 55 app.Widgets.multibar = NewMultibarWidget(app.api) 56 app.Resize() 57} 58 59func (app *Application) Resize() { 60 app.Widgets.layout = views.NewBoxLayout(views.Vertical) 61 app.Widgets.layout.AddWidget(app.Widgets.Topbar, 0) 62 app.Widgets.layout.AddWidget(app.Widgets.table, 1) 63 app.Widgets.layout.AddWidget(app.Widgets.multibar, 0) 64 app.Widgets.layout.SetView(app.screen) 65} 66 67func (app *Application) HandleEvent(ev tcell.Event) bool { 68 switch e := ev.(type) { 69 case *tcell.EventResize: 70 cols, rows := e.Size() 71 log.Debugf("Terminal resize: %dx%d", cols, rows) 72 app.screen.Sync() 73 app.Resize() 74 return true 75 case *tcell.EventKey: 76 return false 77 default: 78 log.Debugf("unrecognized input event: %T %+v", e, e) 79 app.Widgets.layout.HandleEvent(ev) 80 return false 81 } 82} 83 84func (app *Application) Draw() { 85 app.Widgets.layout.Draw() 86 app.updateCursor() 87 app.screen.Show() 88} 89 90func (app *Application) Poll() { 91 for { 92 app.events <- app.screen.PollEvent() 93 } 94} 95 96func (app *Application) Events() <-chan tcell.Event { 97 return app.events 98} 99 100func (app *Application) Finish() { 101 app.screen.Fini() 102} 103 104func (app *Application) Refresh() { 105 app.screen.Sync() 106} 107 108func (app *Application) TableWidget() api.TableWidget { 109 return app.Widgets.table 110} 111 112func (app *Application) updateCursor() { 113 switch app.api.Multibar().Mode() { 114 case multibar.ModeInput, multibar.ModeSearch: 115 _, ymax := app.screen.Size() 116 x := app.api.Multibar().Cursor() + 1 117 app.screen.ShowCursor(x, ymax-1) 118 default: 119 app.screen.HideCursor() 120 } 121} 122