ctop/grid.go

227 lines
4.2 KiB
Go
Raw Normal View History

2016-12-22 17:15:22 +01:00
package main
import (
2016-12-27 03:24:02 +01:00
"fmt"
2016-12-22 17:15:22 +01:00
2017-02-07 04:33:09 +01:00
"github.com/bcicen/ctop/config"
"github.com/bcicen/ctop/cwidgets/compact"
2017-01-06 14:49:22 +01:00
"github.com/bcicen/ctop/widgets"
2016-12-22 17:15:22 +01:00
ui "github.com/gizak/termui"
)
var cGrid = compact.NewCompactGrid()
2017-02-25 08:16:00 +01:00
func maxRows() int {
return ui.TermHeight() - 2 - cGrid.Y
2017-02-25 08:16:00 +01:00
}
2016-12-22 17:15:22 +01:00
type Grid struct {
cursorID string // id of currently selected container
cSource ContainerSource
containers Containers // sorted slice of containers
header *widgets.CTopHeader
2016-12-22 17:15:22 +01:00
}
2016-12-30 22:14:07 +01:00
func NewGrid() *Grid {
cs := NewDockerContainerSource()
2017-01-25 20:57:22 +01:00
g := &Grid{
cSource: cs,
containers: cs.All(),
header: widgets.NewCTopHeader(),
2016-12-30 22:14:07 +01:00
}
2017-01-25 20:57:22 +01:00
return g
2016-12-26 19:39:15 +01:00
}
2017-02-24 10:10:14 +01:00
// Set an initial cursor position, if possible
func (g *Grid) cursorReset() {
if len(g.containers) > 0 {
g.cursorID = g.containers[0].id
g.containers[0].widgets.Highlight()
}
}
2017-01-02 17:04:22 +01:00
// Return current cursor index
2017-01-02 21:14:35 +01:00
func (g *Grid) cursorIdx() int {
2017-01-02 17:04:22 +01:00
for n, c := range g.containers {
if c.id == g.cursorID {
return n
}
}
return 0
}
2017-01-02 21:14:35 +01:00
func (g *Grid) cursorUp() {
idx := g.cursorIdx()
2017-01-02 17:04:22 +01:00
// decrement if possible
if idx <= 0 {
return
2017-01-02 17:04:22 +01:00
}
active := g.containers[idx]
next := g.containers[idx-1]
active.widgets.UnHighlight()
g.cursorID = next.id
next.widgets.Highlight()
ui.Render(cGrid)
2017-01-02 17:04:22 +01:00
}
2017-01-02 21:14:35 +01:00
func (g *Grid) cursorDown() {
idx := g.cursorIdx()
2017-01-02 17:04:22 +01:00
// increment if possible
2017-02-22 06:20:37 +01:00
if idx >= (len(g.containers) - 1) {
return
2016-12-22 17:15:22 +01:00
}
2017-02-25 08:16:00 +01:00
if idx >= maxRows()-1 {
return
2016-12-26 19:39:15 +01:00
}
active := g.containers[idx]
next := g.containers[idx+1]
active.widgets.UnHighlight()
g.cursorID = next.id
next.widgets.Highlight()
ui.Render(cGrid)
2016-12-26 19:39:15 +01:00
}
2017-01-02 21:14:35 +01:00
func (g *Grid) redrawRows() {
2016-12-30 23:10:49 +01:00
// reinit body rows
cGrid.Clear()
2017-01-02 21:14:35 +01:00
2016-12-30 23:10:49 +01:00
// build layout
y := 1
if config.GetSwitchVal("enableHeader") {
2017-01-06 14:49:22 +01:00
g.header.SetCount(len(g.containers))
g.header.SetFilter(config.GetVal("filterStr"))
g.header.Render()
y += g.header.Height()
2017-01-06 14:49:22 +01:00
}
cGrid.SetY(y)
2017-02-24 10:10:14 +01:00
var cursorVisible bool
2017-02-25 08:16:00 +01:00
max := maxRows()
for n, c := range g.containers.Filter() {
2017-02-25 08:16:00 +01:00
if n >= max {
break
}
cGrid.Rows = append(cGrid.Rows, c.widgets)
2017-02-24 10:10:14 +01:00
if c.id == g.cursorID {
cursorVisible = true
}
2016-12-22 17:15:22 +01:00
}
2016-12-30 23:10:49 +01:00
2017-02-24 10:10:14 +01:00
if !cursorVisible {
g.cursorReset()
}
ui.Clear()
if config.GetSwitchVal("enableHeader") {
g.header.Render()
}
cGrid.Align()
ui.Render(cGrid)
2016-12-22 17:15:22 +01:00
}
2017-01-06 20:46:30 +01:00
func (g *Grid) ExpandView() {
ui.Clear()
ui.DefaultEvtStream.ResetHandlers()
defer ui.DefaultEvtStream.ResetHandlers()
container, _ := g.cSource.Get(g.cursorID)
// copy current widgets to restore on exit view
curWidgets := container.widgets
2017-01-06 20:46:30 +01:00
container.Expand()
ui.Render(container.widgets)
ui.Handle("/timer/1s", func(ui.Event) {
ui.Render(container.widgets)
})
ui.Handle("/sys/kbd/", func(ui.Event) {
ui.StopLoop()
})
ui.Loop()
container.widgets = curWidgets
2017-01-06 20:46:30 +01:00
}
2017-02-05 01:56:45 +01:00
func logEvent(e ui.Event) {
var s string
s += fmt.Sprintf("Type: %s\n", e.Type)
s += fmt.Sprintf("Path: %s\n", e.Path)
s += fmt.Sprintf("From: %s\n", e.From)
s += fmt.Sprintf("To: %s", e.To)
log.Debugf("new event:\n%s", s)
}
func Display(g *Grid) bool {
2017-01-09 00:07:58 +01:00
var menu func()
2017-01-06 20:46:30 +01:00
var expand bool
cGrid.SetWidth(ui.TermWidth())
2017-02-05 01:56:45 +01:00
ui.DefaultEvtStream.Hook(logEvent)
// initial draw
g.redrawRows()
2016-12-22 17:15:22 +01:00
2016-12-26 19:39:15 +01:00
ui.Handle("/sys/kbd/<up>", func(ui.Event) {
2017-01-02 21:14:35 +01:00
g.cursorUp()
2016-12-26 19:39:15 +01:00
})
ui.Handle("/sys/kbd/<down>", func(ui.Event) {
2017-01-02 21:14:35 +01:00
g.cursorDown()
2016-12-26 19:39:15 +01:00
})
2017-01-06 20:46:30 +01:00
ui.Handle("/sys/kbd/<enter>", func(ui.Event) {
expand = true
ui.StopLoop()
})
2017-02-23 23:00:05 +01:00
ui.Handle("/sys/kbd/a", func(ui.Event) {
config.Toggle("allContainers")
g.redrawRows()
})
2017-01-21 19:15:29 +01:00
ui.Handle("/sys/kbd/f", func(ui.Event) {
menu = FilterMenu
ui.StopLoop()
})
ui.Handle("/sys/kbd/h", func(ui.Event) {
2017-01-09 00:07:58 +01:00
menu = HelpMenu
2017-01-03 00:40:55 +01:00
ui.StopLoop()
})
2017-02-13 04:37:17 +01:00
ui.Handle("/sys/kbd/H", func(ui.Event) {
config.Toggle("enableHeader")
g.redrawRows()
})
2017-01-12 20:48:29 +01:00
ui.Handle("/sys/kbd/q", func(ui.Event) {
ui.StopLoop()
})
2017-01-21 19:15:29 +01:00
ui.Handle("/sys/kbd/r", func(e ui.Event) {
2017-02-07 04:33:09 +01:00
config.Toggle("sortReversed")
2017-01-12 20:48:29 +01:00
})
ui.Handle("/sys/kbd/s", func(ui.Event) {
menu = SortMenu
2016-12-22 17:15:22 +01:00
ui.StopLoop()
})
2017-02-23 23:00:05 +01:00
2016-12-22 17:15:22 +01:00
ui.Handle("/timer/1s", func(e ui.Event) {
g.containers = g.cSource.All() // refresh containers for current sort order
2017-01-02 21:14:35 +01:00
g.redrawRows()
2016-12-22 17:15:22 +01:00
})
ui.Handle("/sys/wnd/resize", func(e ui.Event) {
g.header.Align()
cGrid.SetWidth(ui.TermWidth())
log.Infof("resize: width=%v max-rows=%v", cGrid.Width, maxRows())
2017-02-18 01:59:13 +01:00
g.redrawRows()
2016-12-22 17:15:22 +01:00
})
ui.Loop()
2017-01-09 00:07:58 +01:00
if menu != nil {
menu()
return false
}
2017-01-06 20:46:30 +01:00
if expand {
g.ExpandView()
return false
}
return true
2016-12-22 17:15:22 +01:00
}