grid updates, fix menu alignment

This commit is contained in:
Bradley Cicenas
2017-03-06 02:00:30 +00:00
parent 4b035ad52a
commit 38a1b305a7
5 changed files with 37 additions and 29 deletions

View File

@ -10,7 +10,7 @@ import (
) )
type ContainerSource interface { type ContainerSource interface {
All() []*Container All() Containers
Get(string) (*Container, bool) Get(string) (*Container, bool)
} }
@ -129,8 +129,7 @@ func (cm *DockerContainerSource) delByID(id string) {
} }
// Return array of all containers, sorted by field // Return array of all containers, sorted by field
func (cm *DockerContainerSource) All() []*Container { func (cm *DockerContainerSource) All() (containers Containers) {
var containers Containers
for _, c := range cm.containers { for _, c := range cm.containers {
containers = append(containers, c) containers = append(containers, c)
} }

33
grid.go
View File

@ -9,7 +9,10 @@ import (
ui "github.com/gizak/termui" ui "github.com/gizak/termui"
) )
var cGrid = compact.NewCompactGrid() 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
@ -19,13 +22,12 @@ type Grid struct {
cursorID string // id of currently selected container cursorID string // id of currently selected container
cSource ContainerSource cSource ContainerSource
containers Containers // sorted slice of containers containers Containers // sorted slice of containers
header *widgets.CTopHeader
} }
func NewGrid() *Grid { func NewGrid() *Grid {
g := &Grid{ g := &Grid{
cSource: NewDockerContainerSource(), //cSource: NewDockerContainerSource(),
header: widgets.NewCTopHeader(), cSource: NewMockContainerSource(),
} }
return g return g
} }
@ -89,15 +91,15 @@ func (g *Grid) redrawRows() {
// build layout // build layout
y := 1 y := 1
if config.GetSwitchVal("enableHeader") { if config.GetSwitchVal("enableHeader") {
g.header.SetCount(len(g.containers)) header.SetCount(len(g.containers))
g.header.SetFilter(config.GetVal("filterStr")) header.SetFilter(config.GetVal("filterStr"))
y += g.header.Height() y += header.Height()
} }
cGrid.SetY(y) cGrid.SetY(y)
var cursorVisible bool var cursorVisible bool
max := maxRows() max := maxRows()
for n, c := range g.containers.Filter() { for n, c := range g.containers {
if n >= max { if n >= max {
break break
} }
@ -113,12 +115,16 @@ func (g *Grid) redrawRows() {
ui.Clear() ui.Clear()
if config.GetSwitchVal("enableHeader") { if config.GetSwitchVal("enableHeader") {
g.header.Render() header.Render()
} }
cGrid.Align() cGrid.Align()
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 (g *Grid) dumpContainer() {
c, _ := g.cSource.Get(g.cursorID) c, _ := g.cSource.Get(g.cursorID)
@ -158,7 +164,8 @@ func Display(g *Grid) bool {
ui.DefaultEvtStream.Hook(logEvent) ui.DefaultEvtStream.Hook(logEvent)
// initial draw // initial draw
g.containers = g.cSource.All() header.Align()
g.refreshContainers()
g.redrawRows() g.redrawRows()
ui.Handle("/sys/kbd/<up>", func(ui.Event) { ui.Handle("/sys/kbd/<up>", func(ui.Event) {
@ -175,6 +182,7 @@ func Display(g *Grid) bool {
ui.Handle("/sys/kbd/a", func(ui.Event) { ui.Handle("/sys/kbd/a", func(ui.Event) {
config.Toggle("allContainers") config.Toggle("allContainers")
g.refreshContainers()
g.redrawRows() g.redrawRows()
}) })
ui.Handle("/sys/kbd/D", func(ui.Event) { ui.Handle("/sys/kbd/D", func(ui.Event) {
@ -204,12 +212,12 @@ func Display(g *Grid) bool {
}) })
ui.Handle("/timer/1s", func(e ui.Event) { ui.Handle("/timer/1s", func(e ui.Event) {
g.containers = g.cSource.All() // refresh containers for current sort order g.refreshContainers()
g.redrawRows() g.redrawRows()
}) })
ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Handle("/sys/wnd/resize", func(e ui.Event) {
g.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() g.redrawRows()
@ -217,6 +225,7 @@ func Display(g *Grid) bool {
ui.Loop() ui.Loop()
if menu != nil { if menu != nil {
ui.Clear()
menu() menu()
return false return false
} }

View File

@ -17,7 +17,7 @@ type MockContainerSource struct {
func NewMockContainerSource() *MockContainerSource { func NewMockContainerSource() *MockContainerSource {
cs := &MockContainerSource{} cs := &MockContainerSource{}
cs.Init() go cs.Init()
go cs.Loop() go cs.Loop()
return cs return cs
} }
@ -28,12 +28,12 @@ func (cs *MockContainerSource) Init() {
rand.Seed(int64(time.Now().Nanosecond())) rand.Seed(int64(time.Now().Nanosecond()))
for i := 0; i < total; i++ { for i := 0; i < total; i++ {
time.Sleep(2 * time.Second)
collector := metrics.NewMock() collector := metrics.NewMock()
c := NewContainer(makeID(), collector) c := NewContainer(makeID(), collector)
c.SetName(makeName()) c.SetName(makeName())
cs.containers = append(cs.containers, c)
c.SetState(makeState()) c.SetState(makeState())
cs.containers = append(cs.containers, c)
} }
} }
@ -42,7 +42,7 @@ func (cs *MockContainerSource) Loop() {
iter := 0 iter := 0
for { for {
// Change state for random container // Change state for random container
if iter%5 == 0 { if iter%5 == 0 && len(cs.containers) > 0 {
randC := cs.containers[rand.Intn(len(cs.containers))] randC := cs.containers[rand.Intn(len(cs.containers))]
randC.SetState(makeState()) randC.SetState(makeState())
} }
@ -61,6 +61,12 @@ func (cs *MockContainerSource) Get(id string) (*Container, bool) {
return nil, false return nil, false
} }
// Return array of all containers, sorted by field
func (cs *MockContainerSource) All() Containers {
sort.Sort(cs.containers)
return cs.containers
}
// Remove containers by ID // Remove containers by ID
func (cs *MockContainerSource) delByID(id string) { func (cs *MockContainerSource) delByID(id string) {
for n, c := range cs.containers { for n, c := range cs.containers {
@ -79,12 +85,6 @@ func (cs *MockContainerSource) del(idx ...int) {
log.Infof("removed %d dead containers", len(idx)) log.Infof("removed %d dead containers", len(idx))
} }
// Return array of all containers, sorted by field
func (cs *MockContainerSource) All() []*Container {
sort.Sort(cs.containers)
return cs.containers
}
func makeID() string { func makeID() string {
u, err := uuid.NewV4() u, err := uuid.NewV4()
if err != nil { if err != nil {

View File

@ -40,7 +40,6 @@ func (c *CTopHeader) Height() int {
func headerBgBordered() *ui.Par { func headerBgBordered() *ui.Par {
bg := ui.NewPar("") bg := ui.NewPar("")
bg.X = 1 bg.X = 1
bg.Width = ui.TermWidth() - 1
bg.Height = 3 bg.Height = 3
bg.Bg = ui.ColorWhite bg.Bg = ui.ColorWhite
return bg return bg
@ -49,7 +48,6 @@ func headerBgBordered() *ui.Par {
func headerBg() *ui.Par { func headerBg() *ui.Par {
bg := ui.NewPar("") bg := ui.NewPar("")
bg.X = 1 bg.X = 1
bg.Width = ui.TermWidth() - 1
bg.Height = 1 bg.Height = 1
bg.Border = false bg.Border = false
bg.Bg = ui.ColorWhite bg.Bg = ui.ColorWhite

View File

@ -20,13 +20,15 @@ type Menu struct {
} }
func NewMenu() *Menu { func NewMenu() *Menu {
return &Menu{ m := &Menu{
Block: *ui.NewBlock(), Block: *ui.NewBlock(),
TextFgColor: ui.ThemeAttr("par.text.fg"), TextFgColor: ui.ThemeAttr("par.text.fg"),
TextBgColor: ui.ThemeAttr("par.text.bg"), TextBgColor: ui.ThemeAttr("par.text.bg"),
cursorPos: 0, cursorPos: 0,
padding: Padding{4, 2}, padding: Padding{4, 2},
} }
m.X = 1
return m
} }
// Append Item to Menu // Append Item to Menu
@ -119,7 +121,7 @@ func (m *Menu) NavigationHandlers() {
// Set width and height based on menu items // Set width and height based on menu items
func (m *Menu) calcSize() { func (m *Menu) calcSize() {
m.Width = 8 // minimum width m.Width = 7 // minimum width
items := m.items items := m.items
for _, i := range m.items { for _, i := range m.items {