Issue #56. Slight improvement in layout algorithm. Still doesn't handle > 2 columns well, but it's more correct and lays the foundation for a correct solution. It's clear, however, that a full table model parser will require a substantial rewrite and, possibly, a change in the layout syntax. That would add substantial complexity, so maybe for some future effort. I'll fix the basic column layout (rowspans at the edges), and then shelve it.
This commit is contained in:
parent
66ad0f8785
commit
7b09a00230
|
@ -423,7 +423,6 @@ func getLayout(conf gotop.Config) io.Reader {
|
|||
case "battery":
|
||||
return strings.NewReader(batteryUI)
|
||||
default:
|
||||
log.Printf("layout = %s", conf.Layout)
|
||||
fp := filepath.Join(conf.ConfigDir, conf.Layout)
|
||||
fin, err := os.Open(fp)
|
||||
if err != nil {
|
||||
|
|
|
@ -31,17 +31,17 @@ 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{}
|
||||
for len(rowDefs) > 0 {
|
||||
uiRow, rowDefs = processRow(c, numRows, rowDefs)
|
||||
uiRows = append(uiRows, uiRow)
|
||||
}
|
||||
rgs := make([]interface{}, 0)
|
||||
rh := 1.0 / float64(len(uiRows))
|
||||
for _, ur := range uiRows {
|
||||
ur.HeightRatio = ur.HeightRatio / float64(numRows)
|
||||
rgs = append(rgs, ur)
|
||||
rgs = append(rgs, ui.NewRow(rh, ur...))
|
||||
}
|
||||
grid := &MyGrid{ui.NewGrid(), nil, nil}
|
||||
grid.Set(rgs...)
|
||||
|
@ -58,11 +58,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) {
|
||||
// FIXME: 3\:A 2\:B\nC should stop consuming rows when all columns are full
|
||||
func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) ([]interface{}, [][]widgetRule) {
|
||||
// Recursive function #3. See the comment in deepFindProc.
|
||||
if len(rowDefs) < 1 {
|
||||
return ui.GridItem{}, [][]widgetRule{}
|
||||
return 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
|
||||
|
@ -87,6 +86,7 @@ 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,
|
||||
|
@ -102,16 +102,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 = processing[i:]
|
||||
break outer
|
||||
}
|
||||
}
|
||||
}
|
||||
var uiColumns []interface{}
|
||||
|
@ -121,7 +130,7 @@ func processRow(c gotop.Config, numRows int, rowDefs [][]widgetRule) (ui.GridIte
|
|||
}
|
||||
}
|
||||
|
||||
return ui.NewRow(1.0/float64(numRows), uiColumns...), rowDefs
|
||||
return uiColumns, rowDefs
|
||||
}
|
||||
|
||||
type Metric interface {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
cpu/2 mem/1
|
||||
3:temp/1 2:disk/2
|
||||
power
|
||||
power
|
||||
net procs
|
||||
cpu/2 mem/1
|
||||
3:temp/1 2:disk/2
|
||||
power
|
||||
net procs
|
||||
|
|
4
layouts/many_columns_test
Normal file
4
layouts/many_columns_test
Normal file
|
@ -0,0 +1,4 @@
|
|||
cpu/2 mem/1 6:procs/2
|
||||
3:temp/1 2:disk/2
|
||||
power
|
||||
net procs
|
Loading…
Reference in New Issue
Block a user