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
|
||||
c.widgets = widgets.NewExpanded(c.ShortID(), c.ShortName())
|
||||
c.widgets.Render()
|
||||
c.widgets.Render(0, 0)
|
||||
c.widgets = curWidgets
|
||||
}
|
||||
|
||||
|
78
grid.go
78
grid.go
@ -8,23 +8,27 @@ import (
|
||||
ui "github.com/gizak/termui"
|
||||
)
|
||||
|
||||
var cGrid = &widgets.CompactGrid{}
|
||||
|
||||
func maxRows() int {
|
||||
return ui.TermHeight() - widgets.CompactHeader.Height - ui.Body.Y
|
||||
return ui.TermHeight() - 2 - cGrid.Y
|
||||
}
|
||||
|
||||
type Grid struct {
|
||||
cursorID string // id of currently selected container
|
||||
cmap *ContainerMap
|
||||
containers Containers // sorted slice of containers
|
||||
header *widgets.CTopHeader
|
||||
cursorID string // id of currently selected container
|
||||
cmap *ContainerMap
|
||||
containers Containers // sorted slice of containers
|
||||
header *widgets.CTopHeader
|
||||
fieldHeader *widgets.CompactHeader
|
||||
}
|
||||
|
||||
func NewGrid() *Grid {
|
||||
cmap := NewContainerMap()
|
||||
g := &Grid{
|
||||
cmap: cmap,
|
||||
containers: cmap.All(),
|
||||
header: widgets.NewCTopHeader(),
|
||||
cmap: cmap,
|
||||
containers: cmap.All(),
|
||||
header: widgets.NewCTopHeader(),
|
||||
fieldHeader: widgets.NewCompactHeader(),
|
||||
}
|
||||
return g
|
||||
}
|
||||
@ -60,7 +64,7 @@ func (g *Grid) cursorUp() {
|
||||
g.cursorID = next.id
|
||||
next.widgets.Highlight()
|
||||
|
||||
ui.Render(ui.Body)
|
||||
ui.Render(cGrid)
|
||||
}
|
||||
|
||||
func (g *Grid) cursorDown() {
|
||||
@ -78,69 +82,50 @@ func (g *Grid) cursorDown() {
|
||||
active.widgets.UnHighlight()
|
||||
g.cursorID = next.id
|
||||
next.widgets.Highlight()
|
||||
ui.Render(ui.Body)
|
||||
ui.Render(cGrid)
|
||||
}
|
||||
|
||||
func (g *Grid) redrawRows() {
|
||||
// reinit body rows
|
||||
ui.Body.Rows = []*ui.Row{}
|
||||
cGrid.Rows = []widgets.ContainerWidgets{}
|
||||
ui.Clear()
|
||||
|
||||
// build layout
|
||||
y := 1
|
||||
if config.GetSwitchVal("enableHeader") {
|
||||
ui.Body.Y = g.header.Height()
|
||||
g.header.SetCount(len(g.containers))
|
||||
g.header.SetFilter(config.GetVal("filterStr"))
|
||||
g.header.Render()
|
||||
} else {
|
||||
ui.Body.Y = 0
|
||||
y += g.header.Height()
|
||||
}
|
||||
|
||||
ui.Body.AddRows(widgets.CompactHeader)
|
||||
|
||||
var cursorVisible bool
|
||||
max := maxRows()
|
||||
y += 2 // for field header
|
||||
for n, c := range g.containers.Filter() {
|
||||
if n >= max {
|
||||
break
|
||||
}
|
||||
cGrid.Rows = append(cGrid.Rows, c.widgets)
|
||||
if c.id == g.cursorID {
|
||||
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 {
|
||||
g.cursorReset()
|
||||
}
|
||||
|
||||
ui.Body.Align()
|
||||
resizeIndicator()
|
||||
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)
|
||||
}
|
||||
}
|
||||
ui.Render(g.fieldHeader)
|
||||
ui.Render(cGrid)
|
||||
}
|
||||
|
||||
func (g *Grid) ExpandView() {
|
||||
@ -164,6 +149,7 @@ func Display(g *Grid) bool {
|
||||
var menu func()
|
||||
var expand bool
|
||||
|
||||
cGrid.SetWidth(ui.TermWidth())
|
||||
ui.DefaultEvtStream.Hook(logEvent)
|
||||
|
||||
// initial draw
|
||||
@ -214,8 +200,8 @@ func Display(g *Grid) bool {
|
||||
|
||||
ui.Handle("/sys/wnd/resize", func(e ui.Event) {
|
||||
g.header.Align()
|
||||
ui.Body.Width = ui.TermWidth()
|
||||
log.Infof("resize: width=%v max-rows=%v", ui.Body.Width, maxRows())
|
||||
cGrid.SetWidth(ui.TermWidth())
|
||||
log.Infof("resize: width=%v max-rows=%v", cGrid.Width, maxRows())
|
||||
g.redrawRows()
|
||||
})
|
||||
|
||||
|
@ -4,34 +4,83 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/bcicen/ctop/logging"
|
||||
ui "github.com/gizak/termui"
|
||||
)
|
||||
|
||||
var log = logging.Init()
|
||||
|
||||
const (
|
||||
mark = string('\u25C9')
|
||||
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 {
|
||||
Row() *ui.Row
|
||||
Render()
|
||||
Render(int, int)
|
||||
Reset()
|
||||
Buffer() ui.Buffer
|
||||
Highlight()
|
||||
UnHighlight()
|
||||
SetY(int)
|
||||
SetWidth(int)
|
||||
SetStatus(string)
|
||||
SetCPU(int)
|
||||
SetNet(int64, int64)
|
||||
SetMem(int64, int64, int)
|
||||
}
|
||||
|
||||
var CompactHeader = ui.NewRow(
|
||||
ui.NewCol(1, 0, slimHeaderPar("")),
|
||||
ui.NewCol(2, 0, slimHeaderPar("NAME")),
|
||||
ui.NewCol(2, 0, slimHeaderPar("CID")),
|
||||
ui.NewCol(2, 0, slimHeaderPar("CPU")),
|
||||
ui.NewCol(2, 0, slimHeaderPar("MEM")),
|
||||
ui.NewCol(2, 0, slimHeaderPar("NET RX/TX")),
|
||||
)
|
||||
type CompactHeader struct {
|
||||
pars []*ui.Par
|
||||
}
|
||||
|
||||
func NewCompactHeader() *CompactHeader {
|
||||
fields := []string{"", "NAME", "CID", "CPU", "MEM", "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 {
|
||||
Status *ui.Par
|
||||
@ -40,7 +89,6 @@ type Compact struct {
|
||||
Name *ui.Par
|
||||
Cpu *ui.Gauge
|
||||
Memory *ui.Gauge
|
||||
row *ui.Row
|
||||
}
|
||||
|
||||
func NewCompact(id, name, status string) *Compact {
|
||||
@ -59,21 +107,56 @@ func (w *Compact) Reset() {
|
||||
w.Net = slimPar("-")
|
||||
w.Cpu = 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 {
|
||||
return w.row
|
||||
func (w *Compact) SetY(y int) {
|
||||
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() {
|
||||
@ -149,6 +232,7 @@ func centerParText(p *ui.Par) {
|
||||
|
||||
func slimHeaderPar(s string) *ui.Par {
|
||||
p := slimPar(s)
|
||||
p.Y = 2
|
||||
p.Height = 2
|
||||
return p
|
||||
}
|
||||
|
@ -33,10 +33,18 @@ func NewInfo(id, name string) *ui.Table {
|
||||
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.Handle("/timer/1s", func(ui.Event) {
|
||||
ui.Render(w.Info, w.Cpu, w.Mem, w.Net)
|
||||
@ -47,23 +55,6 @@ func (w *Expanded) Render() {
|
||||
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) {
|
||||
w.Cpu.Update(val)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user