mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
remove Grid struct, move cursor into own package file
This commit is contained in:
parent
662d1d182b
commit
132335c8a4
79
cursor.go
Normal file
79
cursor.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
ui "github.com/gizak/termui"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GridCursor struct {
|
||||||
|
selectedID string // id of currently selected container
|
||||||
|
containers Containers
|
||||||
|
cSource ContainerSource
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGridCursor() *GridCursor {
|
||||||
|
return &GridCursor{
|
||||||
|
cSource: NewDockerContainerSource(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gc *GridCursor) Len() int { return len(gc.containers) }
|
||||||
|
func (gc *GridCursor) Selected() *Container { return gc.containers[gc.Idx()] }
|
||||||
|
|
||||||
|
func (gc *GridCursor) RefreshContainers() {
|
||||||
|
gc.containers = gc.cSource.All().Filter()
|
||||||
|
if gc.selectedID == "" {
|
||||||
|
gc.Reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set an initial cursor position, if possible
|
||||||
|
func (gc *GridCursor) Reset() {
|
||||||
|
if gc.Len() > 0 {
|
||||||
|
gc.selectedID = gc.containers[0].Id
|
||||||
|
gc.containers[0].Widgets.Name.Highlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return current cursor index
|
||||||
|
func (gc *GridCursor) Idx() int {
|
||||||
|
for n, c := range gc.containers {
|
||||||
|
if c.Id == gc.selectedID {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gc *GridCursor) Up() {
|
||||||
|
idx := gc.Idx()
|
||||||
|
// decrement if possible
|
||||||
|
if idx <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
active := gc.containers[idx]
|
||||||
|
next := gc.containers[idx-1]
|
||||||
|
|
||||||
|
active.Widgets.Name.UnHighlight()
|
||||||
|
gc.selectedID = next.Id
|
||||||
|
next.Widgets.Name.Highlight()
|
||||||
|
|
||||||
|
ui.Render(cGrid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gc *GridCursor) Down() {
|
||||||
|
idx := gc.Idx()
|
||||||
|
// increment if possible
|
||||||
|
if idx >= (gc.Len() - 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if idx >= maxRows()-1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
active := gc.containers[idx]
|
||||||
|
next := gc.containers[idx+1]
|
||||||
|
|
||||||
|
active.Widgets.Name.UnHighlight()
|
||||||
|
gc.selectedID = next.Id
|
||||||
|
next.Widgets.Name.Highlight()
|
||||||
|
ui.Render(cGrid)
|
||||||
|
}
|
116
grid.go
116
grid.go
@ -4,94 +4,21 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/bcicen/ctop/config"
|
"github.com/bcicen/ctop/config"
|
||||||
"github.com/bcicen/ctop/cwidgets/compact"
|
|
||||||
"github.com/bcicen/ctop/widgets"
|
|
||||||
ui "github.com/gizak/termui"
|
ui "github.com/gizak/termui"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
cGrid = compact.NewCompactGrid()
|
|
||||||
header = widgets.NewCTopHeader()
|
|
||||||
)
|
|
||||||
|
|
||||||
func maxRows() int {
|
func maxRows() int {
|
||||||
return ui.TermHeight() - 2 - cGrid.Y
|
return ui.TermHeight() - 2 - cGrid.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
type Grid struct {
|
func RedrawRows() {
|
||||||
cursorID string // id of currently selected container
|
|
||||||
cSource ContainerSource
|
|
||||||
containers Containers // sorted slice of containers
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGrid() *Grid {
|
|
||||||
g := &Grid{
|
|
||||||
//cSource: NewDockerContainerSource(),
|
|
||||||
cSource: NewMockContainerSource(),
|
|
||||||
}
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.Name.Highlight()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return current cursor index
|
|
||||||
func (g *Grid) cursorIdx() int {
|
|
||||||
for n, c := range g.containers {
|
|
||||||
if c.Id == g.cursorID {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Grid) cursorUp() {
|
|
||||||
idx := g.cursorIdx()
|
|
||||||
// decrement if possible
|
|
||||||
if idx <= 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
active := g.containers[idx]
|
|
||||||
next := g.containers[idx-1]
|
|
||||||
|
|
||||||
active.Widgets.Name.UnHighlight()
|
|
||||||
g.cursorID = next.Id
|
|
||||||
next.Widgets.Name.Highlight()
|
|
||||||
|
|
||||||
ui.Render(cGrid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Grid) cursorDown() {
|
|
||||||
idx := g.cursorIdx()
|
|
||||||
// increment if possible
|
|
||||||
if idx >= (len(g.containers) - 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if idx >= maxRows()-1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
active := g.containers[idx]
|
|
||||||
next := g.containers[idx+1]
|
|
||||||
|
|
||||||
active.Widgets.Name.UnHighlight()
|
|
||||||
g.cursorID = next.Id
|
|
||||||
next.Widgets.Name.Highlight()
|
|
||||||
ui.Render(cGrid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Grid) redrawRows() {
|
|
||||||
// reinit body rows
|
// reinit body rows
|
||||||
cGrid.Clear()
|
cGrid.Clear()
|
||||||
|
|
||||||
// build layout
|
// build layout
|
||||||
y := 1
|
y := 1
|
||||||
if config.GetSwitchVal("enableHeader") {
|
if config.GetSwitchVal("enableHeader") {
|
||||||
header.SetCount(len(g.containers))
|
header.SetCount(cursor.Len())
|
||||||
header.SetFilter(config.GetVal("filterStr"))
|
header.SetFilter(config.GetVal("filterStr"))
|
||||||
y += header.Height()
|
y += header.Height()
|
||||||
}
|
}
|
||||||
@ -99,18 +26,18 @@ func (g *Grid) redrawRows() {
|
|||||||
|
|
||||||
var cursorVisible bool
|
var cursorVisible bool
|
||||||
max := maxRows()
|
max := maxRows()
|
||||||
for n, c := range g.containers {
|
for n, c := range cursor.containers {
|
||||||
if n >= max {
|
if n >= max {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
cGrid.AddRows(c.Widgets)
|
cGrid.AddRows(c.Widgets)
|
||||||
if c.Id == g.cursorID {
|
if c.Id == cursor.selectedID {
|
||||||
cursorVisible = true
|
cursorVisible = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cursorVisible {
|
if !cursorVisible {
|
||||||
g.cursorReset()
|
cursor.Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Clear()
|
ui.Clear()
|
||||||
@ -121,13 +48,8 @@ func (g *Grid) redrawRows() {
|
|||||||
ui.Render(cGrid)
|
ui.Render(cGrid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Grid) refreshContainers() {
|
|
||||||
g.containers = g.cSource.All().Filter()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log current container and widget state
|
// Log current container and widget state
|
||||||
func (g *Grid) dumpContainer() {
|
func dumpContainer(c *Container) {
|
||||||
c, _ := g.cSource.Get(g.cursorID)
|
|
||||||
msg := fmt.Sprintf("logging state for container: %s\n", c.Id)
|
msg := fmt.Sprintf("logging state for container: %s\n", c.Id)
|
||||||
msg += fmt.Sprintf("Id = %s\nname = %s\nstate = %s\n", c.Id, c.Name, c.State)
|
msg += fmt.Sprintf("Id = %s\nname = %s\nstate = %s\n", c.Id, c.Name, c.State)
|
||||||
msg += inspect(&c.Metrics)
|
msg += inspect(&c.Metrics)
|
||||||
@ -157,7 +79,7 @@ func (g *Grid) dumpContainer() {
|
|||||||
//container.widgets.Reset()
|
//container.widgets.Reset()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
func Display(g *Grid) bool {
|
func Display() bool {
|
||||||
var menu func()
|
var menu func()
|
||||||
|
|
||||||
cGrid.SetWidth(ui.TermWidth())
|
cGrid.SetWidth(ui.TermWidth())
|
||||||
@ -165,28 +87,28 @@ func Display(g *Grid) bool {
|
|||||||
|
|
||||||
// initial draw
|
// initial draw
|
||||||
header.Align()
|
header.Align()
|
||||||
g.refreshContainers()
|
cursor.RefreshContainers()
|
||||||
g.redrawRows()
|
RedrawRows()
|
||||||
|
|
||||||
ui.Handle("/sys/kbd/<up>", func(ui.Event) {
|
ui.Handle("/sys/kbd/<up>", func(ui.Event) {
|
||||||
g.cursorUp()
|
cursor.Up()
|
||||||
})
|
})
|
||||||
ui.Handle("/sys/kbd/<down>", func(ui.Event) {
|
ui.Handle("/sys/kbd/<down>", func(ui.Event) {
|
||||||
g.cursorDown()
|
cursor.Down()
|
||||||
})
|
})
|
||||||
ui.Handle("/sys/kbd/<enter>", func(ui.Event) {
|
ui.Handle("/sys/kbd/<enter>", func(ui.Event) {
|
||||||
//c := g.containers[g.cursorIdx()]
|
//c := g.containers[g.cursorIdx()]
|
||||||
//c.Widgets.ToggleExpand()
|
//c.Widgets.ToggleExpand()
|
||||||
g.redrawRows()
|
RedrawRows()
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.Handle("/sys/kbd/a", func(ui.Event) {
|
ui.Handle("/sys/kbd/a", func(ui.Event) {
|
||||||
config.Toggle("allContainers")
|
config.Toggle("allContainers")
|
||||||
g.refreshContainers()
|
cursor.RefreshContainers()
|
||||||
g.redrawRows()
|
RedrawRows()
|
||||||
})
|
})
|
||||||
ui.Handle("/sys/kbd/D", func(ui.Event) {
|
ui.Handle("/sys/kbd/D", func(ui.Event) {
|
||||||
g.dumpContainer()
|
dumpContainer(cursor.Selected())
|
||||||
})
|
})
|
||||||
ui.Handle("/sys/kbd/f", func(ui.Event) {
|
ui.Handle("/sys/kbd/f", func(ui.Event) {
|
||||||
menu = FilterMenu
|
menu = FilterMenu
|
||||||
@ -198,7 +120,7 @@ func Display(g *Grid) bool {
|
|||||||
})
|
})
|
||||||
ui.Handle("/sys/kbd/H", func(ui.Event) {
|
ui.Handle("/sys/kbd/H", func(ui.Event) {
|
||||||
config.Toggle("enableHeader")
|
config.Toggle("enableHeader")
|
||||||
g.redrawRows()
|
RedrawRows()
|
||||||
})
|
})
|
||||||
ui.Handle("/sys/kbd/q", func(ui.Event) {
|
ui.Handle("/sys/kbd/q", func(ui.Event) {
|
||||||
ui.StopLoop()
|
ui.StopLoop()
|
||||||
@ -212,15 +134,15 @@ func Display(g *Grid) bool {
|
|||||||
})
|
})
|
||||||
|
|
||||||
ui.Handle("/timer/1s", func(e ui.Event) {
|
ui.Handle("/timer/1s", func(e ui.Event) {
|
||||||
g.refreshContainers()
|
cursor.RefreshContainers()
|
||||||
g.redrawRows()
|
RedrawRows()
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.Handle("/sys/wnd/resize", func(e ui.Event) {
|
ui.Handle("/sys/wnd/resize", func(e ui.Event) {
|
||||||
header.Align()
|
header.Align()
|
||||||
cGrid.SetWidth(ui.TermWidth())
|
cGrid.SetWidth(ui.TermWidth())
|
||||||
log.Infof("resize: width=%v max-rows=%v", cGrid.Width, maxRows())
|
log.Infof("resize: width=%v max-rows=%v", cGrid.Width, maxRows())
|
||||||
g.redrawRows()
|
RedrawRows()
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.Loop()
|
ui.Loop()
|
||||||
|
14
main.go
14
main.go
@ -5,11 +5,18 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/bcicen/ctop/config"
|
"github.com/bcicen/ctop/config"
|
||||||
|
"github.com/bcicen/ctop/cwidgets/compact"
|
||||||
"github.com/bcicen/ctop/logging"
|
"github.com/bcicen/ctop/logging"
|
||||||
|
"github.com/bcicen/ctop/widgets"
|
||||||
ui "github.com/gizak/termui"
|
ui "github.com/gizak/termui"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log *logging.CTopLogger
|
var (
|
||||||
|
log *logging.CTopLogger
|
||||||
|
cursor *GridCursor
|
||||||
|
cGrid = compact.NewCompactGrid()
|
||||||
|
header = widgets.NewCTopHeader()
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -19,19 +26,20 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
config.Init()
|
config.Init()
|
||||||
log = logging.Init()
|
log = logging.Init()
|
||||||
if config.GetSwitchVal("loggingEnabled") {
|
if config.GetSwitchVal("loggingEnabled") {
|
||||||
logging.StartServer()
|
logging.StartServer()
|
||||||
}
|
}
|
||||||
|
cursor = NewGridCursor()
|
||||||
if err := ui.Init(); err != nil {
|
if err := ui.Init(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer ui.Close()
|
defer ui.Close()
|
||||||
|
|
||||||
g := NewGrid()
|
|
||||||
for {
|
for {
|
||||||
exit := Display(g)
|
exit := Display()
|
||||||
if exit {
|
if exit {
|
||||||
log.Notice("shutting down")
|
log.Notice("shutting down")
|
||||||
log.Exit()
|
log.Exit()
|
||||||
|
Loading…
Reference in New Issue
Block a user