mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
grid updates, fix menu alignment
This commit is contained in:
@ -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
33
grid.go
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
Reference in New Issue
Block a user