mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
continuing compact widget refactor
This commit is contained in:
parent
918ccdbe39
commit
1ca40bb7e1
@ -22,7 +22,7 @@ type Container struct {
|
||||
models.Metrics
|
||||
Id string
|
||||
Meta models.Meta
|
||||
Widgets *compact.Compact
|
||||
Widgets *compact.CompactRow
|
||||
Display bool // display this container in compact view
|
||||
updater cwidgets.WidgetUpdater
|
||||
collector collector.Collector
|
||||
@ -30,11 +30,11 @@ type Container struct {
|
||||
}
|
||||
|
||||
func New(id string, collector collector.Collector, manager manager.Manager) *Container {
|
||||
widgets := compact.NewCompact(id)
|
||||
widgets := compact.NewCompactRow()
|
||||
return &Container{
|
||||
Metrics: models.NewMetrics(),
|
||||
Id: id,
|
||||
Meta: models.NewMeta(),
|
||||
Meta: models.NewMeta("id", id),
|
||||
Widgets: widgets,
|
||||
updater: widgets,
|
||||
collector: collector,
|
||||
|
@ -12,6 +12,10 @@ type CPUCol struct {
|
||||
*GaugeCol
|
||||
}
|
||||
|
||||
func NewCPUCol() CompactCol {
|
||||
return &CPUCol{NewGaugeCol("CPU")}
|
||||
}
|
||||
|
||||
func (w *CPUCol) SetMetrics(m models.Metrics) {
|
||||
val := m.CPUUtil
|
||||
w.BarColor = colorScale(val)
|
||||
@ -27,6 +31,10 @@ type MemCol struct {
|
||||
*GaugeCol
|
||||
}
|
||||
|
||||
func NewMemCol() CompactCol {
|
||||
return &MemCol{NewGaugeCol("MEM")}
|
||||
}
|
||||
|
||||
func (w *MemCol) SetMetrics(m models.Metrics) {
|
||||
w.BarColor = ui.ThemeAttr("gauge.bar.bg")
|
||||
w.Label = fmt.Sprintf("%s / %s", cwidgets.ByteFormat(m.MemUsage), cwidgets.ByteFormat(m.MemLimit))
|
||||
@ -35,10 +43,12 @@ func (w *MemCol) SetMetrics(m models.Metrics) {
|
||||
|
||||
type GaugeCol struct {
|
||||
*ui.Gauge
|
||||
header string
|
||||
fWidth int
|
||||
}
|
||||
|
||||
func NewGaugeCol() *GaugeCol {
|
||||
g := &GaugeCol{ui.NewGauge()}
|
||||
func NewGaugeCol(header string) *GaugeCol {
|
||||
g := &GaugeCol{ui.NewGauge(), header, 0}
|
||||
g.Height = 1
|
||||
g.Border = false
|
||||
g.PaddingBottom = 0
|
||||
@ -63,10 +73,10 @@ func (w *GaugeCol) Buffer() ui.Buffer {
|
||||
}
|
||||
|
||||
// GaugeCol implements CompactCol
|
||||
func (w *GaugeCol) SetMeta(models.Meta) {}
|
||||
|
||||
// GaugeCol implements CompactCol
|
||||
func (w *GaugeCol) SetMeta(models.Meta) {}
|
||||
func (w *GaugeCol) SetMetrics(models.Metrics) {}
|
||||
func (w *GaugeCol) Header() string { return w.header }
|
||||
func (w *GaugeCol) FixedWidth() int { return w.fWidth }
|
||||
|
||||
// GaugeCol implements CompactCol
|
||||
func (w *GaugeCol) Highlight() {
|
||||
|
@ -4,11 +4,11 @@ import (
|
||||
ui "github.com/gizak/termui"
|
||||
)
|
||||
|
||||
var header *CompactHeader
|
||||
|
||||
type CompactGrid struct {
|
||||
ui.GridBufferer
|
||||
Rows []ui.GridBufferer
|
||||
header *CompactHeader
|
||||
cols []CompactCol // reference columns
|
||||
Rows []RowBufferer
|
||||
X, Y int
|
||||
Width int
|
||||
Height int
|
||||
@ -16,8 +16,13 @@ type CompactGrid struct {
|
||||
}
|
||||
|
||||
func NewCompactGrid() *CompactGrid {
|
||||
header = NewCompactHeader() // init column header
|
||||
return &CompactGrid{}
|
||||
cg := &CompactGrid{header: NewCompactHeader()}
|
||||
for _, wFn := range allCols {
|
||||
w := wFn()
|
||||
cg.cols = append(cg.cols, w)
|
||||
cg.header.addFieldPar(w.Header())
|
||||
}
|
||||
return cg
|
||||
}
|
||||
|
||||
func (cg *CompactGrid) Align() {
|
||||
@ -28,22 +33,47 @@ func (cg *CompactGrid) Align() {
|
||||
}
|
||||
|
||||
// update row ypos, width recursively
|
||||
colWidths := cg.calcWidths()
|
||||
for _, r := range cg.pageRows() {
|
||||
r.SetY(y)
|
||||
y += r.GetHeight()
|
||||
r.SetWidth(cg.Width)
|
||||
r.SetWidths(cg.Width, colWidths)
|
||||
}
|
||||
}
|
||||
|
||||
func (cg *CompactGrid) Clear() { cg.Rows = []ui.GridBufferer{} }
|
||||
func (cg *CompactGrid) GetHeight() int { return len(cg.Rows) + header.Height }
|
||||
func (cg *CompactGrid) Clear() { cg.Rows = []RowBufferer{} }
|
||||
func (cg *CompactGrid) GetHeight() int { return len(cg.Rows) + cg.header.Height }
|
||||
func (cg *CompactGrid) SetX(x int) { cg.X = x }
|
||||
func (cg *CompactGrid) SetY(y int) { cg.Y = y }
|
||||
func (cg *CompactGrid) SetWidth(w int) { cg.Width = w }
|
||||
func (cg *CompactGrid) MaxRows() int { return ui.TermHeight() - header.Height - cg.Y }
|
||||
func (cg *CompactGrid) MaxRows() int { return ui.TermHeight() - cg.header.Height - cg.Y }
|
||||
|
||||
func (cg *CompactGrid) pageRows() (rows []ui.GridBufferer) {
|
||||
rows = append(rows, header)
|
||||
// calculate and return per-column width
|
||||
func (cg *CompactGrid) calcWidths() []int {
|
||||
var autoCols int
|
||||
width := cg.Width
|
||||
colWidths := make([]int, len(cg.cols))
|
||||
|
||||
for n, w := range cg.cols {
|
||||
colWidths[n] = w.FixedWidth()
|
||||
width -= w.FixedWidth()
|
||||
if w.FixedWidth() == 0 {
|
||||
autoCols++
|
||||
}
|
||||
}
|
||||
|
||||
spacing := colSpacing * len(cg.cols)
|
||||
autoWidth := (width - spacing) / autoCols
|
||||
for n, val := range colWidths {
|
||||
if val == 0 {
|
||||
colWidths[n] = autoWidth
|
||||
}
|
||||
}
|
||||
return colWidths
|
||||
}
|
||||
|
||||
func (cg *CompactGrid) pageRows() (rows []RowBufferer) {
|
||||
rows = append(rows, cg.header)
|
||||
rows = append(rows, cg.Rows[cg.Offset:]...)
|
||||
return rows
|
||||
}
|
||||
@ -56,6 +86,6 @@ func (cg *CompactGrid) Buffer() ui.Buffer {
|
||||
return buf
|
||||
}
|
||||
|
||||
func (cg *CompactGrid) AddRows(rows ...ui.GridBufferer) {
|
||||
func (cg *CompactGrid) AddRows(rows ...RowBufferer) {
|
||||
cg.Rows = append(cg.Rows, rows...)
|
||||
}
|
||||
|
@ -8,63 +8,52 @@ type CompactHeader struct {
|
||||
X, Y int
|
||||
Width int
|
||||
Height int
|
||||
cols []CompactCol
|
||||
widths []int
|
||||
pars []*ui.Par
|
||||
}
|
||||
|
||||
func NewCompactHeader() *CompactHeader {
|
||||
fields := []string{"", "NAME", "CID", "CPU", "MEM", "NET RX/TX", "IO R/W", "PIDS"}
|
||||
ch := &CompactHeader{}
|
||||
ch.Height = 2
|
||||
for _, f := range fields {
|
||||
ch.addFieldPar(f)
|
||||
return &CompactHeader{Height: 2}
|
||||
}
|
||||
|
||||
func (row *CompactHeader) GetHeight() int {
|
||||
return row.Height
|
||||
}
|
||||
|
||||
func (row *CompactHeader) SetWidths(totalWidth int, widths []int) {
|
||||
x := row.X
|
||||
|
||||
for n, w := range row.pars {
|
||||
w.SetX(x)
|
||||
w.SetWidth(widths[n])
|
||||
x += widths[n] + colSpacing
|
||||
}
|
||||
return ch
|
||||
row.Width = totalWidth
|
||||
}
|
||||
|
||||
func (ch *CompactHeader) GetHeight() int {
|
||||
return ch.Height
|
||||
func (row *CompactHeader) SetX(x int) {
|
||||
row.X = x
|
||||
}
|
||||
|
||||
func (ch *CompactHeader) SetWidth(w int) {
|
||||
x := ch.X
|
||||
autoWidth := calcWidth(w)
|
||||
for n, col := range ch.pars {
|
||||
// set column to static width
|
||||
if colWidths[n] != 0 {
|
||||
col.SetX(x)
|
||||
col.SetWidth(colWidths[n])
|
||||
x += colWidths[n]
|
||||
continue
|
||||
}
|
||||
col.SetX(x)
|
||||
col.SetWidth(autoWidth)
|
||||
x += autoWidth + colSpacing
|
||||
}
|
||||
ch.Width = w
|
||||
}
|
||||
|
||||
func (ch *CompactHeader) SetX(x int) {
|
||||
ch.X = x
|
||||
}
|
||||
|
||||
func (ch *CompactHeader) SetY(y int) {
|
||||
for _, p := range ch.pars {
|
||||
func (row *CompactHeader) SetY(y int) {
|
||||
for _, p := range row.pars {
|
||||
p.SetY(y)
|
||||
}
|
||||
ch.Y = y
|
||||
row.Y = y
|
||||
}
|
||||
|
||||
func (ch *CompactHeader) Buffer() ui.Buffer {
|
||||
func (row *CompactHeader) Buffer() ui.Buffer {
|
||||
buf := ui.NewBuffer()
|
||||
for _, p := range ch.pars {
|
||||
for _, p := range row.pars {
|
||||
buf.Merge(p.Buffer())
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
func (ch *CompactHeader) addFieldPar(s string) {
|
||||
func (row *CompactHeader) addFieldPar(s string) {
|
||||
p := ui.NewPar(s)
|
||||
p.Height = ch.Height
|
||||
p.Height = row.Height
|
||||
p.Border = false
|
||||
ch.pars = append(ch.pars, p)
|
||||
row.pars = append(row.pars, p)
|
||||
}
|
||||
|
@ -1,152 +0,0 @@
|
||||
package compact
|
||||
|
||||
import (
|
||||
"github.com/bcicen/ctop/config"
|
||||
"github.com/bcicen/ctop/logging"
|
||||
"github.com/bcicen/ctop/models"
|
||||
ui "github.com/gizak/termui"
|
||||
)
|
||||
|
||||
var log = logging.Init()
|
||||
|
||||
type CompactCol interface {
|
||||
ui.GridBufferer
|
||||
Reset()
|
||||
Highlight()
|
||||
UnHighlight()
|
||||
SetMeta(models.Meta)
|
||||
SetMetrics(models.Metrics)
|
||||
}
|
||||
|
||||
type Compact struct {
|
||||
Bg *RowBg
|
||||
Cols []CompactCol
|
||||
X, Y int
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
||||
func NewCompact(id string) *Compact {
|
||||
// truncate container id
|
||||
if len(id) > 12 {
|
||||
id = id[:12]
|
||||
}
|
||||
row := &Compact{
|
||||
Bg: NewRowBg(),
|
||||
Cols: []CompactCol{
|
||||
NewStatus(),
|
||||
&NameCol{NewTextCol("-")},
|
||||
&CIDCol{NewTextCol(id)},
|
||||
&CPUCol{NewGaugeCol()},
|
||||
&MemCol{NewGaugeCol()},
|
||||
&NetCol{NewTextCol("-")},
|
||||
&IOCol{NewTextCol("-")},
|
||||
&PIDCol{NewTextCol("-")},
|
||||
},
|
||||
X: 1,
|
||||
Height: 1,
|
||||
}
|
||||
return row
|
||||
}
|
||||
|
||||
func (row *Compact) SetMeta(m models.Meta) {
|
||||
for _, w := range row.Cols {
|
||||
w.SetMeta(m)
|
||||
}
|
||||
}
|
||||
|
||||
func (row *Compact) SetMetrics(m models.Metrics) {
|
||||
for _, w := range row.Cols {
|
||||
w.SetMetrics(m)
|
||||
}
|
||||
}
|
||||
|
||||
// Set gauges, counters, etc. to default unread values
|
||||
func (row *Compact) Reset() {
|
||||
for _, w := range row.Cols {
|
||||
w.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func (row *Compact) GetHeight() int { return row.Height }
|
||||
func (row *Compact) SetX(x int) { row.X = x }
|
||||
|
||||
func (row *Compact) SetY(y int) {
|
||||
if y == row.Y {
|
||||
return
|
||||
}
|
||||
|
||||
row.Bg.Y = y
|
||||
for _, w := range row.Cols {
|
||||
w.SetY(y)
|
||||
}
|
||||
row.Y = y
|
||||
}
|
||||
|
||||
func (row *Compact) SetWidth(width int) {
|
||||
if width == row.Width {
|
||||
return
|
||||
}
|
||||
x := row.X
|
||||
|
||||
row.Bg.SetX(x + colWidths[0] + 1)
|
||||
row.Bg.SetWidth(width)
|
||||
|
||||
autoWidth := calcWidth(width)
|
||||
for n, w := range row.Cols {
|
||||
// set static width, if provided
|
||||
if colWidths[n] != 0 {
|
||||
w.SetX(x)
|
||||
w.SetWidth(colWidths[n])
|
||||
x += colWidths[n]
|
||||
continue
|
||||
}
|
||||
// else use auto width
|
||||
w.SetX(x)
|
||||
w.SetWidth(autoWidth)
|
||||
x += autoWidth + colSpacing
|
||||
}
|
||||
row.Width = width
|
||||
}
|
||||
|
||||
func (row *Compact) Buffer() ui.Buffer {
|
||||
buf := ui.NewBuffer()
|
||||
buf.Merge(row.Bg.Buffer())
|
||||
for _, w := range row.Cols {
|
||||
buf.Merge(w.Buffer())
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
func (row *Compact) Highlight() {
|
||||
row.Cols[1].Highlight()
|
||||
if config.GetSwitchVal("fullRowCursor") {
|
||||
for _, w := range row.Cols {
|
||||
w.Highlight()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (row *Compact) UnHighlight() {
|
||||
row.Cols[1].UnHighlight()
|
||||
if config.GetSwitchVal("fullRowCursor") {
|
||||
for _, w := range row.Cols {
|
||||
w.UnHighlight()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type RowBg struct {
|
||||
*ui.Par
|
||||
}
|
||||
|
||||
func NewRowBg() *RowBg {
|
||||
bg := ui.NewPar("")
|
||||
bg.Height = 1
|
||||
bg.Border = false
|
||||
bg.Bg = ui.ThemeAttr("par.text.bg")
|
||||
return &RowBg{bg}
|
||||
}
|
||||
|
||||
func (w *RowBg) Highlight() { w.Bg = ui.ThemeAttr("par.text.fg") }
|
||||
func (w *RowBg) UnHighlight() { w.Bg = ui.ThemeAttr("par.text.bg") }
|
@ -54,6 +54,8 @@ func (s *Status) Reset() {}
|
||||
func (s *Status) SetMetrics(models.Metrics) {}
|
||||
func (s *Status) Highlight() {}
|
||||
func (s *Status) UnHighlight() {}
|
||||
func (s *Status) Header() string { return "" }
|
||||
func (s *Status) FixedWidth() int { return 3 }
|
||||
|
||||
func (s *Status) setState(val string) {
|
||||
// defaults
|
||||
|
@ -12,23 +12,38 @@ type NameCol struct {
|
||||
*TextCol
|
||||
}
|
||||
|
||||
func (w *NameCol) SetMeta(m models.Meta) {
|
||||
if s, ok := m["name"]; ok {
|
||||
w.Text = s
|
||||
}
|
||||
func NewNameCol() CompactCol {
|
||||
return &NameCol{NewTextCol("NAME")}
|
||||
}
|
||||
|
||||
func (w *NameCol) SetMetrics(m models.Metrics) {
|
||||
func (w *NameCol) SetMeta(m models.Meta) {
|
||||
w.Text = m.Get("name")
|
||||
// truncate container id
|
||||
if len(w.Text) > 12 {
|
||||
w.Text = w.Text[:12]
|
||||
}
|
||||
}
|
||||
|
||||
type CIDCol struct {
|
||||
*TextCol
|
||||
}
|
||||
|
||||
func NewCIDCol() CompactCol {
|
||||
return &CIDCol{NewTextCol("CID")}
|
||||
}
|
||||
|
||||
func (w *CIDCol) SetMeta(m models.Meta) {
|
||||
w.Text = m.Get("id")
|
||||
}
|
||||
|
||||
type NetCol struct {
|
||||
*TextCol
|
||||
}
|
||||
|
||||
func NewNetCol() CompactCol {
|
||||
return &NetCol{NewTextCol("NET RX/TX")}
|
||||
}
|
||||
|
||||
func (w *NetCol) SetMetrics(m models.Metrics) {
|
||||
label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(m.NetRx), cwidgets.ByteFormat(m.NetTx))
|
||||
w.Text = label
|
||||
@ -38,6 +53,10 @@ type IOCol struct {
|
||||
*TextCol
|
||||
}
|
||||
|
||||
func NewIOCol() CompactCol {
|
||||
return &IOCol{NewTextCol("IO R/W")}
|
||||
}
|
||||
|
||||
func (w *IOCol) SetMetrics(m models.Metrics) {
|
||||
label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(m.IOBytesRead), cwidgets.ByteFormat(m.IOBytesWrite))
|
||||
w.Text = label
|
||||
@ -47,20 +66,28 @@ type PIDCol struct {
|
||||
*TextCol
|
||||
}
|
||||
|
||||
func NewPIDCol() CompactCol {
|
||||
w := &PIDCol{NewTextCol("PIDS")}
|
||||
w.fWidth = 4
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *PIDCol) SetMetrics(m models.Metrics) {
|
||||
w.Text = fmt.Sprintf("%d", m.Pids)
|
||||
}
|
||||
|
||||
type TextCol struct {
|
||||
*ui.Par
|
||||
header string
|
||||
fWidth int
|
||||
}
|
||||
|
||||
func NewTextCol(s string) *TextCol {
|
||||
p := ui.NewPar(s)
|
||||
func NewTextCol(header string) *TextCol {
|
||||
p := ui.NewPar("-")
|
||||
p.Border = false
|
||||
p.Height = 1
|
||||
p.Width = 20
|
||||
return &TextCol{p}
|
||||
return &TextCol{p, header, 0}
|
||||
}
|
||||
|
||||
func (w *TextCol) Highlight() {
|
||||
@ -75,7 +102,8 @@ func (w *TextCol) UnHighlight() {
|
||||
w.TextBgColor = ui.ThemeAttr("par.text.bg")
|
||||
}
|
||||
|
||||
//func (w *TextCol) Set(s string) { w.Text = s }
|
||||
func (w *TextCol) Reset() { w.Text = "-" }
|
||||
func (w *TextCol) SetMeta(models.Meta) {}
|
||||
func (w *TextCol) SetMetrics(models.Metrics) {}
|
||||
func (w *TextCol) Header() string { return w.header }
|
||||
func (w *TextCol) FixedWidth() int { return w.fWidth }
|
||||
|
@ -22,19 +22,6 @@ var colWidths = []int{
|
||||
4, // pids
|
||||
}
|
||||
|
||||
// Calculate per-column width, given total width
|
||||
func calcWidth(width int) int {
|
||||
spacing := colSpacing * len(colWidths)
|
||||
var staticCols int
|
||||
for _, w := range colWidths {
|
||||
width -= w
|
||||
if w == 0 {
|
||||
staticCols++
|
||||
}
|
||||
}
|
||||
return (width - spacing) / staticCols
|
||||
}
|
||||
|
||||
func centerParText(p *ui.Par) {
|
||||
var text string
|
||||
var padding string
|
||||
|
@ -9,7 +9,23 @@ type Log struct {
|
||||
|
||||
type Meta map[string]string
|
||||
|
||||
func NewMeta() Meta { return make(Meta) }
|
||||
// NewMeta returns an initialized Meta map.
|
||||
// An optional series of key, values may be provided to populate the map prior to returning
|
||||
func NewMeta(kvs ...string) Meta {
|
||||
m := make(Meta)
|
||||
|
||||
var k string
|
||||
for i := 0; i < len(kvs)-1; i++ {
|
||||
if k == "" {
|
||||
k = kvs[i]
|
||||
} else {
|
||||
m[k] = kvs[i]
|
||||
k = ""
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m Meta) Get(k string) string {
|
||||
if s, ok := m[k]; ok {
|
||||
|
Loading…
Reference in New Issue
Block a user