mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
refactor compact widgets into recursive gridbufferer
This commit is contained in:
parent
381f1da602
commit
b84e22fb90
@ -37,7 +37,7 @@ func (c *Container) Expand() {
|
|||||||
|
|
||||||
curWidgets = c.widgets
|
curWidgets = c.widgets
|
||||||
c.widgets = widgets.NewExpanded(c.ShortID(), c.ShortName())
|
c.widgets = widgets.NewExpanded(c.ShortID(), c.ShortName())
|
||||||
c.widgets.Render()
|
c.widgets.Render(0, 0)
|
||||||
c.widgets = curWidgets
|
c.widgets = curWidgets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
78
grid.go
78
grid.go
@ -8,23 +8,27 @@ import (
|
|||||||
ui "github.com/gizak/termui"
|
ui "github.com/gizak/termui"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var cGrid = &widgets.CompactGrid{}
|
||||||
|
|
||||||
func maxRows() int {
|
func maxRows() int {
|
||||||
return ui.TermHeight() - widgets.CompactHeader.Height - ui.Body.Y
|
return ui.TermHeight() - 2 - cGrid.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
type Grid struct {
|
type Grid struct {
|
||||||
cursorID string // id of currently selected container
|
cursorID string // id of currently selected container
|
||||||
cmap *ContainerMap
|
cmap *ContainerMap
|
||||||
containers Containers // sorted slice of containers
|
containers Containers // sorted slice of containers
|
||||||
header *widgets.CTopHeader
|
header *widgets.CTopHeader
|
||||||
|
fieldHeader *widgets.CompactHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGrid() *Grid {
|
func NewGrid() *Grid {
|
||||||
cmap := NewContainerMap()
|
cmap := NewContainerMap()
|
||||||
g := &Grid{
|
g := &Grid{
|
||||||
cmap: cmap,
|
cmap: cmap,
|
||||||
containers: cmap.All(),
|
containers: cmap.All(),
|
||||||
header: widgets.NewCTopHeader(),
|
header: widgets.NewCTopHeader(),
|
||||||
|
fieldHeader: widgets.NewCompactHeader(),
|
||||||
}
|
}
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
@ -60,7 +64,7 @@ func (g *Grid) cursorUp() {
|
|||||||
g.cursorID = next.id
|
g.cursorID = next.id
|
||||||
next.widgets.Highlight()
|
next.widgets.Highlight()
|
||||||
|
|
||||||
ui.Render(ui.Body)
|
ui.Render(cGrid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Grid) cursorDown() {
|
func (g *Grid) cursorDown() {
|
||||||
@ -78,69 +82,50 @@ func (g *Grid) cursorDown() {
|
|||||||
active.widgets.UnHighlight()
|
active.widgets.UnHighlight()
|
||||||
g.cursorID = next.id
|
g.cursorID = next.id
|
||||||
next.widgets.Highlight()
|
next.widgets.Highlight()
|
||||||
ui.Render(ui.Body)
|
ui.Render(cGrid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Grid) redrawRows() {
|
func (g *Grid) redrawRows() {
|
||||||
// reinit body rows
|
// reinit body rows
|
||||||
ui.Body.Rows = []*ui.Row{}
|
cGrid.Rows = []widgets.ContainerWidgets{}
|
||||||
ui.Clear()
|
ui.Clear()
|
||||||
|
|
||||||
// build layout
|
// build layout
|
||||||
|
y := 1
|
||||||
if config.GetSwitchVal("enableHeader") {
|
if config.GetSwitchVal("enableHeader") {
|
||||||
ui.Body.Y = g.header.Height()
|
|
||||||
g.header.SetCount(len(g.containers))
|
g.header.SetCount(len(g.containers))
|
||||||
g.header.SetFilter(config.GetVal("filterStr"))
|
g.header.SetFilter(config.GetVal("filterStr"))
|
||||||
g.header.Render()
|
g.header.Render()
|
||||||
} else {
|
y += g.header.Height()
|
||||||
ui.Body.Y = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Body.AddRows(widgets.CompactHeader)
|
|
||||||
|
|
||||||
var cursorVisible bool
|
var cursorVisible bool
|
||||||
max := maxRows()
|
max := maxRows()
|
||||||
|
y += 2 // for field header
|
||||||
for n, c := range g.containers.Filter() {
|
for n, c := range g.containers.Filter() {
|
||||||
if n >= max {
|
if n >= max {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
cGrid.Rows = append(cGrid.Rows, c.widgets)
|
||||||
if c.id == g.cursorID {
|
if c.id == g.cursorID {
|
||||||
cursorVisible = true
|
cursorVisible = true
|
||||||
}
|
}
|
||||||
ui.Body.AddRows(c.widgets.Row())
|
|
||||||
}
|
}
|
||||||
|
cGrid.SetY(y)
|
||||||
|
cGrid.SetWidth(ui.TermWidth())
|
||||||
|
|
||||||
|
//log.Infof("rows: %d", len(cGrid.Rows))
|
||||||
|
//log.Infof("Width: %d", cGrid.Width)
|
||||||
|
//log.Infof("Height: %d", cGrid.Height)
|
||||||
|
//log.Infof("X: %d", cGrid.X)
|
||||||
|
//log.Infof("Y: %d", cGrid.Y)
|
||||||
|
|
||||||
if !cursorVisible {
|
if !cursorVisible {
|
||||||
g.cursorReset()
|
g.cursorReset()
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Body.Align()
|
ui.Render(g.fieldHeader)
|
||||||
resizeIndicator()
|
ui.Render(cGrid)
|
||||||
ui.Render(ui.Body)
|
|
||||||
|
|
||||||
// dump aligned widget positions and sizes
|
|
||||||
//for i, w := range ui.Body.Rows[1].Cols {
|
|
||||||
//log.Infof("w%v: x=%v y=%v w=%v h=%v", i, w.X, w.Y, w.Width, w.Height)
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// override Align()'d size for indicator column
|
|
||||||
func resizeIndicator() {
|
|
||||||
xShift := 1
|
|
||||||
toWidth := 3
|
|
||||||
for _, r := range ui.Body.Rows {
|
|
||||||
wDiff := r.Cols[0].Width - (toWidth + xShift)
|
|
||||||
// set indicator x, width
|
|
||||||
r.Cols[0].SetX(xShift)
|
|
||||||
r.Cols[0].SetWidth(toWidth)
|
|
||||||
|
|
||||||
// shift remainder of columns left by wDiff
|
|
||||||
for _, c := range r.Cols[1:] {
|
|
||||||
c.SetX(c.X - wDiff)
|
|
||||||
c.SetWidth(c.Width - wDiff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Grid) ExpandView() {
|
func (g *Grid) ExpandView() {
|
||||||
@ -164,6 +149,7 @@ func Display(g *Grid) bool {
|
|||||||
var menu func()
|
var menu func()
|
||||||
var expand bool
|
var expand bool
|
||||||
|
|
||||||
|
cGrid.SetWidth(ui.TermWidth())
|
||||||
ui.DefaultEvtStream.Hook(logEvent)
|
ui.DefaultEvtStream.Hook(logEvent)
|
||||||
|
|
||||||
// initial draw
|
// initial draw
|
||||||
@ -214,8 +200,8 @@ func Display(g *Grid) bool {
|
|||||||
|
|
||||||
ui.Handle("/sys/wnd/resize", func(e ui.Event) {
|
ui.Handle("/sys/wnd/resize", func(e ui.Event) {
|
||||||
g.header.Align()
|
g.header.Align()
|
||||||
ui.Body.Width = ui.TermWidth()
|
cGrid.SetWidth(ui.TermWidth())
|
||||||
log.Infof("resize: width=%v max-rows=%v", ui.Body.Width, maxRows())
|
log.Infof("resize: width=%v max-rows=%v", cGrid.Width, maxRows())
|
||||||
g.redrawRows()
|
g.redrawRows()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -4,34 +4,83 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/bcicen/ctop/logging"
|
||||||
ui "github.com/gizak/termui"
|
ui "github.com/gizak/termui"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var log = logging.Init()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
mark = string('\u25C9')
|
mark = string('\u25C9')
|
||||||
vBar = string('\u25AE')
|
vBar = string('\u25AE')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CompactGrid struct {
|
||||||
|
ui.GridBufferer
|
||||||
|
Rows []ContainerWidgets
|
||||||
|
X, Y int
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CompactGrid) SetX(x int) { c.X = x }
|
||||||
|
func (c CompactGrid) SetY(y int) {
|
||||||
|
c.Y = y
|
||||||
|
for n, r := range c.Rows {
|
||||||
|
log.Infof("row %d: y=%d", n, c.Y+n)
|
||||||
|
r.SetY(c.Y + n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c CompactGrid) GetHeight() int { return len(c.Rows) }
|
||||||
|
func (c CompactGrid) SetWidth(w int) {
|
||||||
|
c.Width = w
|
||||||
|
for _, r := range c.Rows {
|
||||||
|
r.SetWidth(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CompactGrid) Buffer() ui.Buffer {
|
||||||
|
buf := ui.NewBuffer()
|
||||||
|
for _, r := range c.Rows {
|
||||||
|
buf.Merge(r.Buffer())
|
||||||
|
}
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
type ContainerWidgets interface {
|
type ContainerWidgets interface {
|
||||||
Row() *ui.Row
|
Render(int, int)
|
||||||
Render()
|
|
||||||
Reset()
|
Reset()
|
||||||
|
Buffer() ui.Buffer
|
||||||
Highlight()
|
Highlight()
|
||||||
UnHighlight()
|
UnHighlight()
|
||||||
|
SetY(int)
|
||||||
|
SetWidth(int)
|
||||||
SetStatus(string)
|
SetStatus(string)
|
||||||
SetCPU(int)
|
SetCPU(int)
|
||||||
SetNet(int64, int64)
|
SetNet(int64, int64)
|
||||||
SetMem(int64, int64, int)
|
SetMem(int64, int64, int)
|
||||||
}
|
}
|
||||||
|
|
||||||
var CompactHeader = ui.NewRow(
|
type CompactHeader struct {
|
||||||
ui.NewCol(1, 0, slimHeaderPar("")),
|
pars []*ui.Par
|
||||||
ui.NewCol(2, 0, slimHeaderPar("NAME")),
|
}
|
||||||
ui.NewCol(2, 0, slimHeaderPar("CID")),
|
|
||||||
ui.NewCol(2, 0, slimHeaderPar("CPU")),
|
func NewCompactHeader() *CompactHeader {
|
||||||
ui.NewCol(2, 0, slimHeaderPar("MEM")),
|
fields := []string{"", "NAME", "CID", "CPU", "MEM", "NET RX/TX"}
|
||||||
ui.NewCol(2, 0, slimHeaderPar("NET RX/TX")),
|
header := &CompactHeader{}
|
||||||
)
|
for _, f := range fields {
|
||||||
|
header.pars = append(header.pars, slimHeaderPar(f))
|
||||||
|
}
|
||||||
|
return header
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompactHeader) Buffer() ui.Buffer {
|
||||||
|
buf := ui.NewBuffer()
|
||||||
|
for _, p := range c.pars {
|
||||||
|
buf.Merge(p.Buffer())
|
||||||
|
}
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
type Compact struct {
|
type Compact struct {
|
||||||
Status *ui.Par
|
Status *ui.Par
|
||||||
@ -40,7 +89,6 @@ type Compact struct {
|
|||||||
Name *ui.Par
|
Name *ui.Par
|
||||||
Cpu *ui.Gauge
|
Cpu *ui.Gauge
|
||||||
Memory *ui.Gauge
|
Memory *ui.Gauge
|
||||||
row *ui.Row
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCompact(id, name, status string) *Compact {
|
func NewCompact(id, name, status string) *Compact {
|
||||||
@ -59,21 +107,56 @@ func (w *Compact) Reset() {
|
|||||||
w.Net = slimPar("-")
|
w.Net = slimPar("-")
|
||||||
w.Cpu = slimGauge()
|
w.Cpu = slimGauge()
|
||||||
w.Memory = slimGauge()
|
w.Memory = slimGauge()
|
||||||
w.row = ui.NewRow(
|
|
||||||
ui.NewCol(1, 0, w.Status),
|
|
||||||
ui.NewCol(2, 0, w.Name),
|
|
||||||
ui.NewCol(2, 0, w.Cid),
|
|
||||||
ui.NewCol(2, 0, w.Cpu),
|
|
||||||
ui.NewCol(2, 0, w.Memory),
|
|
||||||
ui.NewCol(2, 0, w.Net),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Compact) Render() {
|
func (w *Compact) all() []ui.GridBufferer {
|
||||||
|
return []ui.GridBufferer{
|
||||||
|
w.Status,
|
||||||
|
w.Name,
|
||||||
|
w.Cid,
|
||||||
|
w.Cpu,
|
||||||
|
w.Memory,
|
||||||
|
w.Net,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Compact) Row() *ui.Row {
|
func (w *Compact) SetY(y int) {
|
||||||
return w.row
|
for _, col := range w.all() {
|
||||||
|
col.SetY(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Compact) SetWidth(width int) {
|
||||||
|
x := 1
|
||||||
|
statusWidth := 3
|
||||||
|
autoWidth := (width - statusWidth) / 5
|
||||||
|
log.Infof("autowidth: %d", autoWidth)
|
||||||
|
for n, col := range w.all() {
|
||||||
|
if n == 0 {
|
||||||
|
col.SetX(x)
|
||||||
|
col.SetWidth(statusWidth)
|
||||||
|
x += statusWidth
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
col.SetX(x)
|
||||||
|
col.SetWidth(autoWidth)
|
||||||
|
x += autoWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Compact) Render(y, rowWidth int) {}
|
||||||
|
|
||||||
|
func (w *Compact) Buffer() ui.Buffer {
|
||||||
|
buf := ui.NewBuffer()
|
||||||
|
|
||||||
|
buf.Merge(w.Status.Buffer())
|
||||||
|
buf.Merge(w.Name.Buffer())
|
||||||
|
buf.Merge(w.Cid.Buffer())
|
||||||
|
buf.Merge(w.Cpu.Buffer())
|
||||||
|
buf.Merge(w.Memory.Buffer())
|
||||||
|
buf.Merge(w.Net.Buffer())
|
||||||
|
|
||||||
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Compact) Highlight() {
|
func (w *Compact) Highlight() {
|
||||||
@ -149,6 +232,7 @@ func centerParText(p *ui.Par) {
|
|||||||
|
|
||||||
func slimHeaderPar(s string) *ui.Par {
|
func slimHeaderPar(s string) *ui.Par {
|
||||||
p := slimPar(s)
|
p := slimPar(s)
|
||||||
|
p.Y = 2
|
||||||
p.Height = 2
|
p.Height = 2
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,18 @@ func NewInfo(id, name string) *ui.Table {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Expanded) Reset() {
|
func (w *Expanded) Buffer() ui.Buffer {
|
||||||
|
return ui.NewBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Expanded) Render() {
|
func (w *Expanded) Reset() {}
|
||||||
|
func (w *Expanded) SetY(_ int) {}
|
||||||
|
func (w *Expanded) SetWidth(_ int) {}
|
||||||
|
func (w *Expanded) Highlight() {}
|
||||||
|
func (w *Expanded) UnHighlight() {}
|
||||||
|
func (w *Expanded) SetStatus(val string) {}
|
||||||
|
|
||||||
|
func (w *Expanded) Render(_, _ int) {
|
||||||
ui.Render(w.Info, w.Cpu, w.Mem, w.Net)
|
ui.Render(w.Info, w.Cpu, w.Mem, w.Net)
|
||||||
ui.Handle("/timer/1s", func(ui.Event) {
|
ui.Handle("/timer/1s", func(ui.Event) {
|
||||||
ui.Render(w.Info, w.Cpu, w.Mem, w.Net)
|
ui.Render(w.Info, w.Cpu, w.Mem, w.Net)
|
||||||
@ -47,23 +55,6 @@ func (w *Expanded) Render() {
|
|||||||
ui.Loop()
|
ui.Loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Expanded) Row() *ui.Row {
|
|
||||||
return ui.NewRow(
|
|
||||||
ui.NewCol(2, 0, w.Cpu),
|
|
||||||
ui.NewCol(2, 0, w.Mem),
|
|
||||||
ui.NewCol(2, 0, w.Net),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Expanded) Highlight() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Expanded) UnHighlight() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Expanded) SetStatus(val string) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Expanded) SetCPU(val int) {
|
func (w *Expanded) SetCPU(val int) {
|
||||||
w.Cpu.Update(val)
|
w.Cpu.Update(val)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user