diff options
author | Sean E. Russell <ser@ser1.net> | 2020-02-28 14:38:32 -0600 |
---|---|---|
committer | Sean E. Russell <ser@ser1.net> | 2020-02-28 14:38:32 -0600 |
commit | c6af0ab404e54713f7b4039eaf9a0f21340cb00b (patch) | |
tree | f279ae965acca840ff335698287046e22f1a4a09 /layout | |
parent | d16cf1c6d2b91f6ca75da1ded02bde25782b7a3f (diff) | |
parent | 231b0d03fed93ccc4b5f953f503763966341ec48 (diff) |
Merge branch 'v3.4.x'
Diffstat (limited to 'layout')
-rw-r--r-- | layout/layout.go | 76 | ||||
-rw-r--r-- | layout/layout_test.go | 27 |
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 { |