remove Grid struct, move cursor into own package file

This commit is contained in:
Bradley Cicenas 2017-03-06 03:03:05 +00:00
parent 662d1d182b
commit 132335c8a4
3 changed files with 109 additions and 100 deletions

79
cursor.go Normal file
View 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
View File

@ -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
View File

@ -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()