summaryrefslogtreecommitdiffstats
path: root/layout
diff options
context:
space:
mode:
authorSean E. Russell <ser@ser1.net>2020-02-28 14:38:32 -0600
committerSean E. Russell <ser@ser1.net>2020-02-28 14:38:32 -0600
commitc6af0ab404e54713f7b4039eaf9a0f21340cb00b (patch)
treef279ae965acca840ff335698287046e22f1a4a09 /layout
parentd16cf1c6d2b91f6ca75da1ded02bde25782b7a3f (diff)
parent231b0d03fed93ccc4b5f953f503763966341ec48 (diff)
Merge branch 'v3.4.x'
Diffstat (limited to 'layout')
-rw-r--r--layout/layout.go76
-rw-r--r--layout/layout_test.go27
2 files changed, 82 insertions, 21 deletions
diff --git a/layout/layout.go b/layout/layout.go
index b8d3226..d7fbc22 100644
--- a/layout/layout.go
+++ b/layout/layout.go
@@ -31,17 +31,22 @@ var widgetNames []string = []string{"cpu", "disk", "mem", "temp", "net", "procs"
func Layout(wl layout, c gotop.Config) (*MyGrid, error) {
rowDefs := wl.Rows
- uiRows := make([]ui.GridItem, 0)
+ uiRows := make([][]interface{}, 0)
numRows := countNumRows(wl.Rows)
- var uiRow ui.GridItem
+ var uiRow []interface{}
+ maxHeight := 0
+ heights := make([]int, 0)
+ var h int
for len(rowDefs) > 0 {
- uiRow, rowDefs = processRow(c, numRows, rowDefs)
+ h, uiRow, rowDefs = processRow(c, numRows, rowDefs)
+ maxHeight += h
uiRows = append(uiRows, uiRow)
+ heights = append(heights, h)
}
rgs := make([]interface{}, 0)
- for _, ur := range uiRows {
- ur.HeightRatio = ur.HeightRatio / float64(numRows)
- rgs = append(rgs, ur)
+ for i, ur := range uiRows {
+ rh := float64(heights[i]) / float64(maxHeight)
+ rgs = append(rgs, ui.NewRow(rh, ur...))
}
grid := &MyGrid{ui.NewGrid(), nil, nil}
grid.Set(rgs...)
@@ -58,10 +63,10 @@ func Layout(wl layout, c gotop.Config) (*MyGrid, error) {
// if there's a row span widget in the row; in this case, it'll consume as many
// rows as the largest row span object in the row, and produce an uber-row
// containing all that stuff. It returns a slice without the consumed elements.
-func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) (ui.GridItem, [][]widgetRule) {
+func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) (int, []interface{}, [][]widgetRule) {
// Recursive function #3. See the comment in deepFindProc.
if len(rowDefs) < 1 {
- return ui.GridItem{}, [][]widgetRule{}
+ return 0, nil, [][]widgetRule{}
}
// The height of the tallest widget in this row; the number of rows that
// will be consumed, and the overall height of the row that will be
@@ -86,9 +91,10 @@ func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) (ui.GridIte
columns = append(columns, make([]interface{}, 0))
}
colHeights := make([]int, numCols)
+outer:
for i, row := range processing {
// A definition may fill up the columns before all rows are consumed,
- // e.g. wid1/2 wid2/2. This block checks for that and, if it occurs,
+ // e.g. cpu/2 net/2. This block checks for that and, if it occurs,
// prepends the remaining rows to the "remainder" return value.
full := true
for _, ch := range colHeights {
@@ -101,16 +107,25 @@ func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) (ui.GridIte
rowDefs = append(processing[i:], rowDefs...)
break
}
- // Not all rows have been consumed, so go ahead and place the row's widgets in columns
- for _, wid := range row {
- for j, ch := range colHeights {
- if ch+wid.Height <= maxHeight {
- widget := makeWidget(c, wid)
- columns[j] = append(columns[j], ui.NewRow(float64(wid.Height)/float64(maxHeight), widget))
- colHeights[j] += wid.Height
+ // Not all rows have been consumed, so go ahead and place the row's
+ // widgets in columns
+ for w, widg := range row {
+ placed := false
+ for k := w; k < len(colHeights); k++ { // there are enough columns
+ ch := colHeights[k]
+ if ch+widg.Height <= maxHeight {
+ widget := makeWidget(c, widg)
+ columns[k] = append(columns[k], ui.NewRow(float64(widg.Height)/float64(maxHeight), widget))
+ colHeights[k] += widg.Height
+ placed = true
break
}
}
+ // If all columns are full, break out, return the row, and continue processing
+ if !placed {
+ rowDefs = append(processing[i:], rowDefs...)
+ break outer
+ }
}
}
var uiColumns []interface{}
@@ -120,11 +135,15 @@ func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) (ui.GridIte
}
}
- return ui.NewRow(1.0/float64(numRows), uiColumns...), rowDefs
+ return maxHeight, uiColumns, rowDefs
+}
+
+type Metric interface {
+ EnableMetric()
}
func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
- var w interface{}
+ var w Metric
switch widRule.Widget {
case "cpu":
cpu := widgets.NewCpuWidget(c.UpdateInterval, c.GraphHorizontalScale, c.AverageLoad, c.PercpuLoad)
@@ -145,11 +164,19 @@ func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
}
w = cpu
case "disk":
- w = widgets.NewDiskWidget()
+ dw := widgets.NewDiskWidget()
+ w = dw
case "mem":
m := widgets.NewMemWidget(c.UpdateInterval, c.GraphHorizontalScale)
- m.LineColors["Main"] = ui.Color(c.Colorscheme.MainMem)
- m.LineColors["Swap"] = ui.Color(c.Colorscheme.SwapMem)
+ var i int
+ for key, _ := range m.Data {
+ if i >= len(c.Colorscheme.MemLines) {
+ i = 0
+ }
+ color := c.Colorscheme.MemLines[i]
+ m.LineColors[key] = ui.Color(color)
+ i++
+ }
w = m
case "temp":
t := widgets.NewTempWidget(c.TempScale)
@@ -185,10 +212,17 @@ func makeWidget(c gotop.Config, widRule widgetRule) interface{} {
i++
}
w = b
+ case "power":
+ b := widgets.NewBatteryGauge()
+ b.BarColor = ui.Color(c.Colorscheme.ProcCursor)
+ w = b
default:
log.Printf("Invalid widget name %s. Must be one of %v", widRule.Widget, widgetNames)
return ui.NewBlock()
}
+ if c.ExportPort != "" {
+ w.EnableMetric()
+ }
return w
}
diff --git a/layout/layout_test.go b/layout/layout_test.go
index d1f016d..568bbee 100644
--- a/layout/layout_test.go
+++ b/layout/layout_test.go
@@ -101,6 +101,33 @@ func TestParsing(t *testing.T) {
assert.Equal(t, 1, l.Rows[1][0].Height)
assert.Equal(t, 1.0, l.Rows[1][0].Weight)
}},
+ {"cpu/2 mem/1 6:procs\n3:temp/1 2:disk/2\npower\nnet procs", func(l layout) {
+ assert.Equal(t, 4, len(l.Rows))
+ // First row
+ assert.Equal(t, 3, len(l.Rows[0]))
+ assert.Equal(t, 1, l.Rows[0][0].Height)
+ assert.Equal(t, 0.5, l.Rows[0][0].Weight)
+ assert.Equal(t, 1, l.Rows[0][1].Height)
+ assert.Equal(t, 0.25, l.Rows[0][1].Weight)
+ assert.Equal(t, 6, l.Rows[0][2].Height)
+ assert.Equal(t, 0.25, l.Rows[0][2].Weight)
+ // Second row
+ assert.Equal(t, 2, len(l.Rows[1]))
+ assert.Equal(t, 3, l.Rows[1][0].Height)
+ assert.Equal(t, 1/3.0, l.Rows[1][0].Weight)
+ assert.Equal(t, 2, l.Rows[1][1].Height)
+ assert.Equal(t, 2/3.0, l.Rows[1][1].Weight)
+ // Third row
+ assert.Equal(t, 1, len(l.Rows[2]))
+ assert.Equal(t, 1, l.Rows[2][0].Height)
+ assert.Equal(t, 1.0, l.Rows[2][0].Weight)
+ // Fourth row
+ assert.Equal(t, 2, len(l.Rows[3]))
+ assert.Equal(t, 1, l.Rows[3][0].Height)
+ assert.Equal(t, 0.5, l.Rows[3][0].Weight)
+ assert.Equal(t, 1, l.Rows[3][1].Height)
+ assert.Equal(t, 0.5, l.Rows[3][1].Weight)
+ }},
}
for _, tc := range tests {