Change methods to use 'self' keyword
This commit is contained in:
parent
0aa09f4fc6
commit
dc8cc5aa4d
|
@ -32,69 +32,69 @@ func NewBlock() *Block {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) drawBorder(buf *Buffer) {
|
func (self *Block) drawBorder(buf *Buffer) {
|
||||||
x := b.X + 1
|
x := self.X + 1
|
||||||
y := b.Y + 1
|
y := self.Y + 1
|
||||||
|
|
||||||
// draw lines
|
// draw lines
|
||||||
buf.Merge(NewFilledBuffer(0, 0, x, 1, Cell{HORIZONTAL_LINE, b.BorderFg, b.BorderBg}))
|
buf.Merge(NewFilledBuffer(0, 0, x, 1, Cell{HORIZONTAL_LINE, self.BorderFg, self.BorderBg}))
|
||||||
buf.Merge(NewFilledBuffer(0, y, x, y+1, Cell{HORIZONTAL_LINE, b.BorderFg, b.BorderBg}))
|
buf.Merge(NewFilledBuffer(0, y, x, y+1, Cell{HORIZONTAL_LINE, self.BorderFg, self.BorderBg}))
|
||||||
buf.Merge(NewFilledBuffer(0, 0, 1, y+1, Cell{VERTICAL_LINE, b.BorderFg, b.BorderBg}))
|
buf.Merge(NewFilledBuffer(0, 0, 1, y+1, Cell{VERTICAL_LINE, self.BorderFg, self.BorderBg}))
|
||||||
buf.Merge(NewFilledBuffer(x, 0, x+1, y+1, Cell{VERTICAL_LINE, b.BorderFg, b.BorderBg}))
|
buf.Merge(NewFilledBuffer(x, 0, x+1, y+1, Cell{VERTICAL_LINE, self.BorderFg, self.BorderBg}))
|
||||||
|
|
||||||
// draw corners
|
// draw corners
|
||||||
buf.SetCell(0, 0, Cell{TOP_LEFT, b.BorderFg, b.BorderBg})
|
buf.SetCell(0, 0, Cell{TOP_LEFT, self.BorderFg, self.BorderBg})
|
||||||
buf.SetCell(x, 0, Cell{TOP_RIGHT, b.BorderFg, b.BorderBg})
|
buf.SetCell(x, 0, Cell{TOP_RIGHT, self.BorderFg, self.BorderBg})
|
||||||
buf.SetCell(0, y, Cell{BOTTOM_LEFT, b.BorderFg, b.BorderBg})
|
buf.SetCell(0, y, Cell{BOTTOM_LEFT, self.BorderFg, self.BorderBg})
|
||||||
buf.SetCell(x, y, Cell{BOTTOM_RIGHT, b.BorderFg, b.BorderBg})
|
buf.SetCell(x, y, Cell{BOTTOM_RIGHT, self.BorderFg, self.BorderBg})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) drawLabel(buf *Buffer) {
|
func (self *Block) drawLabel(buf *Buffer) {
|
||||||
r := MaxString(b.Label, (b.X-3)-1)
|
r := MaxString(self.Label, (self.X-3)-1)
|
||||||
buf.SetString(3, 0, r, b.LabelFg, b.LabelBg)
|
buf.SetString(3, 0, r, self.LabelFg, self.LabelBg)
|
||||||
if b.Label == "" {
|
if self.Label == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c := Cell{' ', b.Fg, b.Bg}
|
c := Cell{' ', self.Fg, self.Bg}
|
||||||
buf.SetCell(2, 0, c)
|
buf.SetCell(2, 0, c)
|
||||||
if len(b.Label)+3 < b.X {
|
if len(self.Label)+3 < self.X {
|
||||||
buf.SetCell(len(b.Label)+3, 0, c)
|
buf.SetCell(len(self.Label)+3, 0, c)
|
||||||
} else {
|
} else {
|
||||||
buf.SetCell(b.X-1, 0, c)
|
buf.SetCell(self.X-1, 0, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize computes Height, Width, XOffset, and YOffset given terminal dimensions.
|
// Resize computes Height, Width, XOffset, and YOffset given terminal dimensions.
|
||||||
func (b *Block) Resize(termWidth, termHeight, termCols, termRows int) {
|
func (self *Block) Resize(termWidth, termHeight, termCols, termRows int) {
|
||||||
b.X = int((float64(b.Grid.Dx())/float64(termCols))*float64(termWidth)) - 2
|
self.X = int((float64(self.Grid.Dx())/float64(termCols))*float64(termWidth)) - 2
|
||||||
b.Y = int((float64(b.Grid.Dy())/float64(termRows))*float64(termHeight)) - 2
|
self.Y = int((float64(self.Grid.Dy())/float64(termRows))*float64(termHeight)) - 2
|
||||||
b.XOffset = int((float64(b.Grid.Min.X) / float64(termCols)) * float64(termWidth))
|
self.XOffset = int((float64(self.Grid.Min.X) / float64(termCols)) * float64(termWidth))
|
||||||
b.YOffset = int((float64(b.Grid.Min.Y) / float64(termRows)) * float64(termHeight))
|
self.YOffset = int((float64(self.Grid.Min.Y) / float64(termRows)) * float64(termHeight))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGrid create a rectangle representing the block's dimensions in the grid.
|
// SetGrid create a rectangle representing the block's dimensions in the grid.
|
||||||
func (b *Block) SetGrid(c0, r0, c1, r1 int) {
|
func (self *Block) SetGrid(c0, r0, c1, r1 int) {
|
||||||
b.Grid = image.Rect(c0, r0, c1, r1)
|
self.Grid = image.Rect(c0, r0, c1, r1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetXOffset implements Bufferer interface.
|
// GetXOffset implements Bufferer interface.
|
||||||
func (b *Block) GetXOffset() int {
|
func (self *Block) GetXOffset() int {
|
||||||
return b.XOffset
|
return self.XOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetYOffset implements Bufferer interface.
|
// GetYOffset implements Bufferer interface.
|
||||||
func (b *Block) GetYOffset() int {
|
func (self *Block) GetYOffset() int {
|
||||||
return b.YOffset
|
return self.YOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface and draws background, border, and borderlabel.
|
// Buffer implements Bufferer interface and draws background, border, and borderlabel.
|
||||||
func (b *Block) Buffer() *Buffer {
|
func (self *Block) Buffer() *Buffer {
|
||||||
buf := NewBuffer()
|
buf := NewBuffer()
|
||||||
buf.SetAreaXY(b.X+2, b.Y+2)
|
buf.SetAreaXY(self.X+2, self.Y+2)
|
||||||
buf.Fill(Cell{' ', ColorDefault, b.Bg})
|
buf.Fill(Cell{' ', ColorDefault, self.Bg})
|
||||||
|
|
||||||
b.drawBorder(buf)
|
self.drawBorder(buf)
|
||||||
b.drawLabel(buf)
|
self.drawLabel(buf)
|
||||||
|
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,60 +40,60 @@ func NewFilledBuffer(x0, y0, x1, y1 int, c Cell) *Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCell assigns a Cell to (x,y).
|
// SetCell assigns a Cell to (x,y).
|
||||||
func (b *Buffer) SetCell(x, y int, c Cell) {
|
func (self *Buffer) SetCell(x, y int, c Cell) {
|
||||||
b.CellMap[image.Pt(x, y)] = c
|
self.CellMap[image.Pt(x, y)] = c
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetString assigns a string to a Buffer starting at (x,y).
|
// SetString assigns a string to a Buffer starting at (x,y).
|
||||||
func (b *Buffer) SetString(x, y int, s string, fg, bg Color) {
|
func (self *Buffer) SetString(x, y int, s string, fg, bg Color) {
|
||||||
for i, char := range s {
|
for i, char := range s {
|
||||||
b.SetCell(x+i, y, Cell{char, fg, bg})
|
self.SetCell(x+i, y, Cell{char, fg, bg})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// At returns the cell at (x,y).
|
// At returns the cell at (x,y).
|
||||||
func (b *Buffer) At(x, y int) Cell {
|
func (self *Buffer) At(x, y int) Cell {
|
||||||
return b.CellMap[image.Pt(x, y)]
|
return self.CellMap[image.Pt(x, y)]
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetArea assigns a new rect area to Buffer b.
|
// SetArea assigns a new rect area to self.
|
||||||
func (b *Buffer) SetArea(r image.Rectangle) {
|
func (self *Buffer) SetArea(r image.Rectangle) {
|
||||||
b.Area.Max = r.Max
|
self.Area.Max = r.Max
|
||||||
b.Area.Min = r.Min
|
self.Area.Min = r.Min
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAreaXY sets the Buffer bounds from (0,0) to (x,y).
|
// SetAreaXY sets the Buffer bounds from (0,0) to (x,y).
|
||||||
func (b *Buffer) SetAreaXY(x, y int) {
|
func (self *Buffer) SetAreaXY(x, y int) {
|
||||||
b.Area.Min.Y = 0
|
self.Area.Min.Y = 0
|
||||||
b.Area.Min.X = 0
|
self.Area.Min.X = 0
|
||||||
b.Area.Max.Y = y
|
self.Area.Max.Y = y
|
||||||
b.Area.Max.X = x
|
self.Area.Max.X = x
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge merges the given buffers onto the current Buffer.
|
// Merge merges the given buffers onto the current Buffer.
|
||||||
func (b *Buffer) Merge(bs ...*Buffer) {
|
func (self *Buffer) Merge(bs ...*Buffer) {
|
||||||
for _, buf := range bs {
|
for _, buf := range bs {
|
||||||
for p, c := range buf.CellMap {
|
for p, c := range buf.CellMap {
|
||||||
b.SetCell(p.X, p.Y, c)
|
self.SetCell(p.X, p.Y, c)
|
||||||
}
|
}
|
||||||
b.SetArea(b.Area.Union(buf.Area))
|
self.SetArea(self.Area.Union(buf.Area))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MergeWithOffset merges a Buffer onto another with an offset.
|
// MergeWithOffset merges a Buffer onto another with an offset.
|
||||||
func (b *Buffer) MergeWithOffset(buf *Buffer, xOffset, yOffset int) {
|
func (self *Buffer) MergeWithOffset(buf *Buffer, xOffset, yOffset int) {
|
||||||
for p, c := range buf.CellMap {
|
for p, c := range buf.CellMap {
|
||||||
b.SetCell(p.X+xOffset, p.Y+yOffset, c)
|
self.SetCell(p.X+xOffset, p.Y+yOffset, c)
|
||||||
}
|
}
|
||||||
rect := image.Rect(xOffset, yOffset, buf.Area.Max.X+xOffset, buf.Area.Max.Y+yOffset)
|
rect := image.Rect(xOffset, yOffset, buf.Area.Max.X+xOffset, buf.Area.Max.Y+yOffset)
|
||||||
b.SetArea(b.Area.Union(rect))
|
self.SetArea(self.Area.Union(rect))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill fills the Buffer with a Cell.
|
// Fill fills the Buffer with a Cell.
|
||||||
func (b *Buffer) Fill(c Cell) {
|
func (self *Buffer) Fill(c Cell) {
|
||||||
for x := b.Area.Min.X; x < b.Area.Max.X; x++ {
|
for x := self.Area.Min.X; x < self.Area.Max.X; x++ {
|
||||||
for y := b.Area.Min.Y; y < b.Area.Max.Y; y++ {
|
for y := self.Area.Min.Y; y < self.Area.Max.Y; y++ {
|
||||||
b.SetCell(x, y, c)
|
self.SetCell(x, y, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,27 +21,27 @@ func NewGauge() *Gauge {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (g *Gauge) Buffer() *Buffer {
|
func (self *Gauge) Buffer() *Buffer {
|
||||||
buf := g.Block.Buffer()
|
buf := self.Block.Buffer()
|
||||||
|
|
||||||
// plot bar
|
// plot bar
|
||||||
width := g.Percent * g.X / 100
|
width := self.Percent * self.X / 100
|
||||||
for y := 1; y <= g.Y; y++ {
|
for y := 1; y <= self.Y; y++ {
|
||||||
for x := 1; x <= width; x++ {
|
for x := 1; x <= width; x++ {
|
||||||
buf.SetCell(x, y, Cell{' ', g.GaugeColor, g.GaugeColor})
|
buf.SetCell(x, y, Cell{' ', self.GaugeColor, self.GaugeColor})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// plot percentage
|
// plot percentage
|
||||||
s := strconv.Itoa(g.Percent) + "%" + g.Description
|
s := strconv.Itoa(self.Percent) + "%" + self.Description
|
||||||
s = MaxString(s, g.X)
|
s = MaxString(s, self.X)
|
||||||
y := (g.Y + 1) / 2
|
y := (self.Y + 1) / 2
|
||||||
x := ((g.X - len(s)) + 1) / 2
|
x := ((self.X - len(s)) + 1) / 2
|
||||||
for i, char := range s {
|
for i, char := range s {
|
||||||
bg := g.Bg
|
bg := self.Bg
|
||||||
fg := g.Fg
|
fg := self.Fg
|
||||||
if x+i < width {
|
if x+i < width {
|
||||||
fg = g.GaugeColor
|
fg = self.GaugeColor
|
||||||
bg = AttrReverse
|
bg = AttrReverse
|
||||||
}
|
}
|
||||||
buf.SetCell(1+x+i, y, Cell{char, fg, bg})
|
buf.SetCell(1+x+i, y, Cell{char, fg, bg})
|
||||||
|
|
|
@ -25,7 +25,7 @@ func NewGrid() *Grid {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set assigns a widget and its grid dimensions to Grid.
|
// Set assigns a widget and its grid dimensions to Grid.
|
||||||
func (g *Grid) Set(x0, y0, x1, y1 int, widget GridBufferer) {
|
func (self *Grid) Set(x0, y0, x1, y1 int, widget GridBufferer) {
|
||||||
if widget == nil {
|
if widget == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -34,33 +34,33 @@ func (g *Grid) Set(x0, y0, x1, y1 int, widget GridBufferer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.SetGrid(x0, y0, x1, y1)
|
widget.SetGrid(x0, y0, x1, y1)
|
||||||
widget.Resize(g.Width, g.Height, g.Cols, g.Rows)
|
widget.Resize(self.Width, self.Height, self.Cols, self.Rows)
|
||||||
|
|
||||||
g.Widgets = append(g.Widgets, widget)
|
self.Widgets = append(self.Widgets, widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize resizes each widget in the grid.
|
// Resize resizes each widget in the grid.
|
||||||
func (g *Grid) Resize() {
|
func (self *Grid) Resize() {
|
||||||
for _, w := range g.Widgets {
|
for _, w := range self.Widgets {
|
||||||
w.Resize(g.Width, g.Height, g.Cols, g.Rows)
|
w.Resize(self.Width, self.Height, self.Cols, self.Rows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements the Bufferer interface by merging each widget in Grid into one buffer.
|
// Buffer implements the Bufferer interface by merging each widget in Grid into one buffer.
|
||||||
func (g *Grid) Buffer() *Buffer {
|
func (self *Grid) Buffer() *Buffer {
|
||||||
buf := NewFilledBuffer(0, 0, g.Width, g.Height, Cell{' ', ColorDefault, Theme.Bg})
|
buf := NewFilledBuffer(0, 0, self.Width, self.Height, Cell{' ', ColorDefault, Theme.Bg})
|
||||||
for _, w := range g.Widgets {
|
for _, w := range self.Widgets {
|
||||||
buf.MergeWithOffset(w.Buffer(), w.GetXOffset(), w.GetYOffset())
|
buf.MergeWithOffset(w.Buffer(), w.GetXOffset(), w.GetYOffset())
|
||||||
}
|
}
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetXOffset implements Bufferer interface.
|
// GetXOffset implements Bufferer interface.
|
||||||
func (g *Grid) GetXOffset() int {
|
func (self *Grid) GetXOffset() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetYOffset implements Bufferer interface.
|
// GetYOffset implements Bufferer interface.
|
||||||
func (g *Grid) GetYOffset() int {
|
func (self *Grid) GetYOffset() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,21 +30,21 @@ func NewLineGraph() *LineGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (lc *LineGraph) Buffer() *Buffer {
|
func (self *LineGraph) Buffer() *Buffer {
|
||||||
buf := lc.Block.Buffer()
|
buf := self.Block.Buffer()
|
||||||
// we render each data point on to the canvas then copy over the braille to the buffer at the end
|
// we render each data point on to the canvas then copy over the braille to the buffer at the end
|
||||||
// fyi braille characters have 2x4 dots for each character
|
// fyi braille characters have 2x4 dots for each character
|
||||||
c := drawille.NewCanvas()
|
c := drawille.NewCanvas()
|
||||||
// used to keep track of the braille colors until the end when we render the braille to the buffer
|
// used to keep track of the braille colors until the end when we render the braille to the buffer
|
||||||
colors := make([][]Color, lc.X+2)
|
colors := make([][]Color, self.X+2)
|
||||||
for i := range colors {
|
for i := range colors {
|
||||||
colors[i] = make([]Color, lc.Y+2)
|
colors[i] = make([]Color, self.Y+2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort the series so that overlapping data will overlap the same way each time
|
// sort the series so that overlapping data will overlap the same way each time
|
||||||
seriesList := make([]string, len(lc.Data))
|
seriesList := make([]string, len(self.Data))
|
||||||
i := 0
|
i := 0
|
||||||
for seriesName := range lc.Data {
|
for seriesName := range self.Data {
|
||||||
seriesList[i] = seriesName
|
seriesList[i] = seriesName
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
@ -53,21 +53,21 @@ func (lc *LineGraph) Buffer() *Buffer {
|
||||||
// draw lines in reverse order so that the first color defined in the colorscheme is on top
|
// draw lines in reverse order so that the first color defined in the colorscheme is on top
|
||||||
for i := len(seriesList) - 1; i >= 0; i-- {
|
for i := len(seriesList) - 1; i >= 0; i-- {
|
||||||
seriesName := seriesList[i]
|
seriesName := seriesList[i]
|
||||||
seriesData := lc.Data[seriesName]
|
seriesData := self.Data[seriesName]
|
||||||
seriesLineColor, ok := lc.LineColor[seriesName]
|
seriesLineColor, ok := self.LineColor[seriesName]
|
||||||
if !ok {
|
if !ok {
|
||||||
seriesLineColor = lc.DefaultLineColor
|
seriesLineColor = self.DefaultLineColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// coordinates of last point
|
// coordinates of last point
|
||||||
lastY, lastX := -1, -1
|
lastY, lastX := -1, -1
|
||||||
// assign colors to `colors` and lines/points to the canvas
|
// assign colors to `colors` and lines/points to the canvas
|
||||||
for i := len(seriesData) - 1; i >= 0; i-- {
|
for i := len(seriesData) - 1; i >= 0; i-- {
|
||||||
x := ((lc.X + 1) * 2) - 1 - (((len(seriesData) - 1) - i) * lc.Zoom)
|
x := ((self.X + 1) * 2) - 1 - (((len(seriesData) - 1) - i) * self.Zoom)
|
||||||
y := ((lc.Y + 1) * 4) - 1 - int((float64((lc.Y)*4)-1)*(seriesData[i]/100))
|
y := ((self.Y + 1) * 4) - 1 - int((float64((self.Y)*4)-1)*(seriesData[i]/100))
|
||||||
if x < 0 {
|
if x < 0 {
|
||||||
// render the line to the last point up to the wall
|
// render the line to the last point up to the wall
|
||||||
if x > 0-lc.Zoom {
|
if x > 0-self.Zoom {
|
||||||
for _, p := range drawille.Line(lastX, lastY, x, y) {
|
for _, p := range drawille.Line(lastX, lastY, x, y) {
|
||||||
if p.X > 0 {
|
if p.X > 0 {
|
||||||
c.Set(p.X, p.Y)
|
c.Set(p.X, p.Y)
|
||||||
|
@ -97,7 +97,7 @@ func (lc *LineGraph) Buffer() *Buffer {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if char != 10240 { // empty braille character
|
if char != 10240 { // empty braille character
|
||||||
buf.SetCell(x, y, Cell{char, colors[x][y], lc.Bg})
|
buf.SetCell(x, y, Cell{char, colors[x][y], self.Bg})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,17 +106,17 @@ func (lc *LineGraph) Buffer() *Buffer {
|
||||||
// renders key ontop
|
// renders key ontop
|
||||||
for j, seriesName := range seriesList {
|
for j, seriesName := range seriesList {
|
||||||
// sorts lines again
|
// sorts lines again
|
||||||
seriesData := lc.Data[seriesName]
|
seriesData := self.Data[seriesName]
|
||||||
seriesLineColor, ok := lc.LineColor[seriesName]
|
seriesLineColor, ok := self.LineColor[seriesName]
|
||||||
if !ok {
|
if !ok {
|
||||||
seriesLineColor = lc.DefaultLineColor
|
seriesLineColor = self.DefaultLineColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// render key ontop, but let braille be drawn over space characters
|
// render key ontop, but let braille be drawn over space characters
|
||||||
str := fmt.Sprintf("%s %3.0f%%", seriesName, seriesData[len(seriesData)-1])
|
str := fmt.Sprintf("%s %3.0f%%", seriesName, seriesData[len(seriesData)-1])
|
||||||
for k, char := range str {
|
for k, char := range str {
|
||||||
if char != ' ' {
|
if char != ' ' {
|
||||||
buf.SetCell(3+k, j+2, Cell{char, seriesLineColor, lc.Bg})
|
buf.SetCell(3+k, j+2, Cell{char, seriesLineColor, self.Bg})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ type Sparklines struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add appends a given Sparkline to the *Sparklines.
|
// Add appends a given Sparkline to the *Sparklines.
|
||||||
func (s *Sparklines) Add(sl Sparkline) {
|
func (self *Sparklines) Add(sl Sparkline) {
|
||||||
s.Lines = append(s.Lines, &sl)
|
self.Lines = append(self.Lines, &sl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSparkline returns an unrenderable single sparkline that intended to be added into a Sparklines.
|
// NewSparkline returns an unrenderable single sparkline that intended to be added into a Sparklines.
|
||||||
|
@ -39,37 +39,37 @@ func NewSparklines(ss ...*Sparkline) *Sparklines {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (sl *Sparklines) Buffer() *Buffer {
|
func (self *Sparklines) Buffer() *Buffer {
|
||||||
buf := sl.Block.Buffer()
|
buf := self.Block.Buffer()
|
||||||
|
|
||||||
lc := len(sl.Lines) // lineCount
|
lc := len(self.Lines) // lineCount
|
||||||
|
|
||||||
// renders each sparkline and its titles
|
// renders each sparkline and its titles
|
||||||
for i, line := range sl.Lines {
|
for i, line := range self.Lines {
|
||||||
|
|
||||||
// prints titles
|
// prints titles
|
||||||
title1Y := 2 + (sl.Y/lc)*i
|
title1Y := 2 + (self.Y/lc)*i
|
||||||
title2Y := (2 + (sl.Y/lc)*i) + 1
|
title2Y := (2 + (self.Y/lc)*i) + 1
|
||||||
title1 := MaxString(line.Title1, sl.X)
|
title1 := MaxString(line.Title1, self.X)
|
||||||
title2 := MaxString(line.Title2, sl.X)
|
title2 := MaxString(line.Title2, self.X)
|
||||||
buf.SetString(1, title1Y, title1, line.TitleColor|AttrBold, sl.Bg)
|
buf.SetString(1, title1Y, title1, line.TitleColor|AttrBold, self.Bg)
|
||||||
buf.SetString(1, title2Y, title2, line.TitleColor|AttrBold, sl.Bg)
|
buf.SetString(1, title2Y, title2, line.TitleColor|AttrBold, self.Bg)
|
||||||
|
|
||||||
sparkY := (sl.Y / lc) * (i + 1)
|
sparkY := (self.Y / lc) * (i + 1)
|
||||||
// finds max data in current view used for relative heights
|
// finds max data in current view used for relative heights
|
||||||
max := 1
|
max := 1
|
||||||
for i := len(line.Data) - 1; i >= 0 && sl.X-((len(line.Data)-1)-i) >= 1; i-- {
|
for i := len(line.Data) - 1; i >= 0 && self.X-((len(line.Data)-1)-i) >= 1; i-- {
|
||||||
if line.Data[i] > max {
|
if line.Data[i] > max {
|
||||||
max = line.Data[i]
|
max = line.Data[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prints sparkline
|
// prints sparkline
|
||||||
for x := sl.X; x >= 1; x-- {
|
for x := self.X; x >= 1; x-- {
|
||||||
char := SPARKS[0]
|
char := SPARKS[0]
|
||||||
if (sl.X - x) < len(line.Data) {
|
if (self.X - x) < len(line.Data) {
|
||||||
char = SPARKS[int((float64(line.Data[(len(line.Data)-1)-(sl.X-x)])/float64(max))*7)]
|
char = SPARKS[int((float64(line.Data[(len(line.Data)-1)-(self.X-x)])/float64(max))*7)]
|
||||||
}
|
}
|
||||||
buf.SetCell(x, sparkY, Cell{char, line.LineColor, sl.Bg})
|
buf.SetCell(x, sparkY, Cell{char, line.LineColor, self.Bg})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
148
termui/table.go
148
termui/table.go
|
@ -22,82 +22,82 @@ type Table struct {
|
||||||
|
|
||||||
// NewTable returns a new Table instance
|
// NewTable returns a new Table instance
|
||||||
func NewTable() *Table {
|
func NewTable() *Table {
|
||||||
t := &Table{
|
self := &Table{
|
||||||
Block: NewBlock(),
|
Block: NewBlock(),
|
||||||
Cursor: Theme.TableCursor,
|
Cursor: Theme.TableCursor,
|
||||||
SelectedRow: 0,
|
SelectedRow: 0,
|
||||||
TopRow: 0,
|
TopRow: 0,
|
||||||
UniqueCol: 0,
|
UniqueCol: 0,
|
||||||
}
|
}
|
||||||
t.ColResizer = t.ColResize
|
self.ColResizer = self.ColResize
|
||||||
return t
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColResize is the default column resizer, but can be overriden.
|
// ColResize is the default column resizer, but can be overriden.
|
||||||
// ColResize calculates the width of each column.
|
// ColResize calculates the width of each column.
|
||||||
func (t *Table) ColResize() {
|
func (self *Table) ColResize() {
|
||||||
// calculate gap size based on total width
|
// calculate gap size based on total width
|
||||||
t.Gap = 3
|
self.Gap = 3
|
||||||
if t.X < 50 {
|
if self.X < 50 {
|
||||||
t.Gap = 1
|
self.Gap = 1
|
||||||
} else if t.X < 75 {
|
} else if self.X < 75 {
|
||||||
t.Gap = 2
|
self.Gap = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
cur := 0
|
cur := 0
|
||||||
for _, w := range t.ColWidths {
|
for _, w := range self.ColWidths {
|
||||||
cur += t.Gap
|
cur += self.Gap
|
||||||
t.CellXPos = append(t.CellXPos, cur)
|
self.CellXPos = append(self.CellXPos, cur)
|
||||||
cur += w
|
cur += w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements the Bufferer interface.
|
// Buffer implements the Bufferer interface.
|
||||||
func (t *Table) Buffer() *Buffer {
|
func (self *Table) Buffer() *Buffer {
|
||||||
buf := t.Block.Buffer()
|
buf := self.Block.Buffer()
|
||||||
|
|
||||||
// removes gap at the bottom of the current view if there is one
|
// removes gap at the bottom of the current view if there is one
|
||||||
if t.TopRow > len(t.Rows)-(t.Y-1) {
|
if self.TopRow > len(self.Rows)-(self.Y-1) {
|
||||||
t.TopRow = len(t.Rows) - (t.Y - 1)
|
self.TopRow = len(self.Rows) - (self.Y - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.ColResizer()
|
self.ColResizer()
|
||||||
|
|
||||||
// prints header
|
// prints header
|
||||||
for i, width := range t.ColWidths {
|
for i, width := range self.ColWidths {
|
||||||
if width == 0 {
|
if width == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r := MaxString(t.Header[i], t.X-6)
|
r := MaxString(self.Header[i], self.X-6)
|
||||||
buf.SetString(t.CellXPos[i], 1, r, t.Fg|AttrBold, t.Bg)
|
buf.SetString(self.CellXPos[i], 1, r, self.Fg|AttrBold, self.Bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints each row
|
// prints each row
|
||||||
for rowNum := t.TopRow; rowNum < t.TopRow+t.Y-1 && rowNum < len(t.Rows); rowNum++ {
|
for rowNum := self.TopRow; rowNum < self.TopRow+self.Y-1 && rowNum < len(self.Rows); rowNum++ {
|
||||||
row := t.Rows[rowNum]
|
row := self.Rows[rowNum]
|
||||||
y := (rowNum + 2) - t.TopRow
|
y := (rowNum + 2) - self.TopRow
|
||||||
|
|
||||||
// prints cursor
|
// prints cursor
|
||||||
bg := t.Bg
|
bg := self.Bg
|
||||||
if (t.SelectedItem == "" && rowNum == t.SelectedRow) || (t.SelectedItem != "" && t.SelectedItem == row[t.UniqueCol]) {
|
if (self.SelectedItem == "" && rowNum == self.SelectedRow) || (self.SelectedItem != "" && self.SelectedItem == row[self.UniqueCol]) {
|
||||||
bg = t.Cursor
|
bg = self.Cursor
|
||||||
for _, width := range t.ColWidths {
|
for _, width := range self.ColWidths {
|
||||||
if width == 0 {
|
if width == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
buf.SetString(1, y, strings.Repeat(" ", t.X), t.Fg, bg)
|
buf.SetString(1, y, strings.Repeat(" ", self.X), self.Fg, bg)
|
||||||
}
|
}
|
||||||
t.SelectedItem = row[t.UniqueCol]
|
self.SelectedItem = row[self.UniqueCol]
|
||||||
t.SelectedRow = rowNum
|
self.SelectedRow = rowNum
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints each col of the row
|
// prints each col of the row
|
||||||
for i, width := range t.ColWidths {
|
for i, width := range self.ColWidths {
|
||||||
if width == 0 {
|
if width == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r := MaxString(row[i], t.X-6)
|
r := MaxString(row[i], self.X-6)
|
||||||
buf.SetString(t.CellXPos[i], y, r, t.Fg, bg)
|
buf.SetString(self.CellXPos[i], y, r, self.Fg, bg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,71 +109,71 @@ func (t *Table) Buffer() *Buffer {
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// calcPos is used to calculate the cursor position and the current view.
|
// calcPos is used to calculate the cursor position and the current view.
|
||||||
func (t *Table) calcPos() {
|
func (self *Table) calcPos() {
|
||||||
t.SelectedItem = ""
|
self.SelectedItem = ""
|
||||||
|
|
||||||
if t.SelectedRow < 0 {
|
if self.SelectedRow < 0 {
|
||||||
t.SelectedRow = 0
|
self.SelectedRow = 0
|
||||||
}
|
}
|
||||||
if t.SelectedRow < t.TopRow {
|
if self.SelectedRow < self.TopRow {
|
||||||
t.TopRow = t.SelectedRow
|
self.TopRow = self.SelectedRow
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.SelectedRow > len(t.Rows)-1 {
|
if self.SelectedRow > len(self.Rows)-1 {
|
||||||
t.SelectedRow = len(t.Rows) - 1
|
self.SelectedRow = len(self.Rows) - 1
|
||||||
}
|
}
|
||||||
if t.SelectedRow > t.TopRow+(t.Y-2) {
|
if self.SelectedRow > self.TopRow+(self.Y-2) {
|
||||||
t.TopRow = t.SelectedRow - (t.Y - 2)
|
self.TopRow = self.SelectedRow - (self.Y - 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) Up() {
|
func (self *Table) Up() {
|
||||||
t.SelectedRow -= 1
|
self.SelectedRow -= 1
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) Down() {
|
func (self *Table) Down() {
|
||||||
t.SelectedRow += 1
|
self.SelectedRow += 1
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) Top() {
|
func (self *Table) Top() {
|
||||||
t.SelectedRow = 0
|
self.SelectedRow = 0
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) Bottom() {
|
func (self *Table) Bottom() {
|
||||||
t.SelectedRow = len(t.Rows) - 1
|
self.SelectedRow = len(self.Rows) - 1
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The number of lines in a page is equal to the height of the widget.
|
// The number of lines in a page is equal to the height of the widgeself.
|
||||||
|
|
||||||
func (t *Table) HalfPageUp() {
|
func (self *Table) HalfPageUp() {
|
||||||
t.SelectedRow = t.SelectedRow - (t.Y-2)/2
|
self.SelectedRow = self.SelectedRow - (self.Y-2)/2
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) HalfPageDown() {
|
func (self *Table) HalfPageDown() {
|
||||||
t.SelectedRow = t.SelectedRow + (t.Y-2)/2
|
self.SelectedRow = self.SelectedRow + (self.Y-2)/2
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) PageUp() {
|
func (self *Table) PageUp() {
|
||||||
t.SelectedRow -= (t.Y - 2)
|
self.SelectedRow -= (self.Y - 2)
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) PageDown() {
|
func (self *Table) PageDown() {
|
||||||
t.SelectedRow += (t.Y - 2)
|
self.SelectedRow += (self.Y - 2)
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) Click(x, y int) {
|
func (self *Table) Click(x, y int) {
|
||||||
x = x - t.XOffset
|
x = x - self.XOffset
|
||||||
y = y - t.YOffset
|
y = y - self.YOffset
|
||||||
if (x > 0 && x <= t.X) && (y > 0 && y <= t.Y) {
|
if (x > 0 && x <= self.X) && (y > 0 && y <= self.Y) {
|
||||||
t.SelectedRow = (t.TopRow + y) - 2
|
self.SelectedRow = (self.TopRow + y) - 2
|
||||||
t.calcPos()
|
self.calcPos()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,43 +16,43 @@ type CPU struct {
|
||||||
|
|
||||||
func NewCPU(interval time.Duration, zoom int) *CPU {
|
func NewCPU(interval time.Duration, zoom int) *CPU {
|
||||||
count, _ := psCPU.Counts(false)
|
count, _ := psCPU.Counts(false)
|
||||||
c := &CPU{
|
self := &CPU{
|
||||||
LineGraph: ui.NewLineGraph(),
|
LineGraph: ui.NewLineGraph(),
|
||||||
Count: count,
|
Count: count,
|
||||||
interval: interval,
|
interval: interval,
|
||||||
}
|
}
|
||||||
c.Label = "CPU Usage"
|
self.Label = "CPU Usage"
|
||||||
c.Zoom = zoom
|
self.Zoom = zoom
|
||||||
if c.Count <= 8 {
|
if self.Count <= 8 {
|
||||||
for i := 0; i < c.Count; i++ {
|
for i := 0; i < self.Count; i++ {
|
||||||
key := "CPU" + strconv.Itoa(i+1)
|
key := "CPU" + strconv.Itoa(i+1)
|
||||||
c.Data[key] = []float64{0}
|
self.Data[key] = []float64{0}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.Data["Average"] = []float64{0}
|
self.Data["Average"] = []float64{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
go c.update()
|
go self.update()
|
||||||
ticker := time.NewTicker(c.interval)
|
ticker := time.NewTicker(self.interval)
|
||||||
go func() {
|
go func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
c.update()
|
self.update()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return c
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CPU) update() {
|
func (self *CPU) update() {
|
||||||
// psutil calculates the CPU usage over a 1 second interval, therefore it blocks for 1 second
|
// psutil calculates the CPU usage over a 1 second interval, therefore it blocks for 1 second
|
||||||
if c.Count <= 8 {
|
if self.Count <= 8 {
|
||||||
percent, _ := psCPU.Percent(c.interval, true)
|
percent, _ := psCPU.Percent(self.interval, true)
|
||||||
for i := 0; i < c.Count; i++ {
|
for i := 0; i < self.Count; i++ {
|
||||||
key := "CPU" + strconv.Itoa(i+1)
|
key := "CPU" + strconv.Itoa(i+1)
|
||||||
c.Data[key] = append(c.Data[key], percent[i])
|
self.Data[key] = append(self.Data[key], percent[i])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
percent, _ := psCPU.Percent(c.interval, false)
|
percent, _ := psCPU.Percent(self.interval, false)
|
||||||
c.Data["Average"] = append(c.Data["Average"], percent[0])
|
self.Data["Average"] = append(self.Data["Average"], percent[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,26 +16,26 @@ type Disk struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDisk() *Disk {
|
func NewDisk() *Disk {
|
||||||
d := &Disk{
|
self := &Disk{
|
||||||
Gauge: ui.NewGauge(),
|
Gauge: ui.NewGauge(),
|
||||||
fs: "/",
|
fs: "/",
|
||||||
interval: time.Second * 5,
|
interval: time.Second * 5,
|
||||||
}
|
}
|
||||||
d.Label = "Disk Usage"
|
self.Label = "Disk Usage"
|
||||||
|
|
||||||
go d.update()
|
go self.update()
|
||||||
ticker := time.NewTicker(d.interval)
|
ticker := time.NewTicker(self.interval)
|
||||||
go func() {
|
go func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
d.update()
|
self.update()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return d
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Disk) update() {
|
func (self *Disk) update() {
|
||||||
usage, _ := psDisk.Usage(d.fs)
|
usage, _ := psDisk.Usage(self.fs)
|
||||||
d.Percent = int(usage.UsedPercent)
|
self.Percent = int(usage.UsedPercent)
|
||||||
d.Description = fmt.Sprintf(" (%dGB free)", int(utils.BytesToGB(usage.Free)))
|
self.Description = fmt.Sprintf(" (%dGB free)", int(utils.BytesToGB(usage.Free)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,12 @@ func NewHelpMenu() *HelpMenu {
|
||||||
return &HelpMenu{block}
|
return &HelpMenu{block}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hm *HelpMenu) Buffer() *ui.Buffer {
|
func (self *HelpMenu) Buffer() *ui.Buffer {
|
||||||
buf := hm.Block.Buffer()
|
buf := self.Block.Buffer()
|
||||||
|
|
||||||
for y, line := range strings.Split(KEYBINDS, "\n") {
|
for y, line := range strings.Split(KEYBINDS, "\n") {
|
||||||
for x, char := range line {
|
for x, char := range line {
|
||||||
buf.SetCell(x+1, y, ui.NewCell(char, ui.Color(7), hm.Bg))
|
buf.SetCell(x+1, y, ui.NewCell(char, ui.Color(7), self.Bg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,29 +13,29 @@ type Mem struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMem(interval time.Duration, zoom int) *Mem {
|
func NewMem(interval time.Duration, zoom int) *Mem {
|
||||||
m := &Mem{
|
self := &Mem{
|
||||||
LineGraph: ui.NewLineGraph(),
|
LineGraph: ui.NewLineGraph(),
|
||||||
interval: interval,
|
interval: interval,
|
||||||
}
|
}
|
||||||
m.Label = "Memory Usage"
|
self.Label = "Memory Usage"
|
||||||
m.Zoom = zoom
|
self.Zoom = zoom
|
||||||
m.Data["Main"] = []float64{0}
|
self.Data["Main"] = []float64{0}
|
||||||
m.Data["Swap"] = []float64{0}
|
self.Data["Swap"] = []float64{0}
|
||||||
|
|
||||||
go m.update()
|
go self.update()
|
||||||
ticker := time.NewTicker(m.interval)
|
ticker := time.NewTicker(self.interval)
|
||||||
go func() {
|
go func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
m.update()
|
self.update()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return m
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mem) update() {
|
func (self *Mem) update() {
|
||||||
main, _ := psMem.VirtualMemory()
|
main, _ := psMem.VirtualMemory()
|
||||||
swap, _ := psMem.SwapMemory()
|
swap, _ := psMem.SwapMemory()
|
||||||
m.Data["Main"] = append(m.Data["Main"], main.UsedPercent)
|
self.Data["Main"] = append(self.Data["Main"], main.UsedPercent)
|
||||||
m.Data["Swap"] = append(m.Data["Swap"], swap.UsedPercent)
|
self.Data["Swap"] = append(self.Data["Swap"], swap.UsedPercent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,46 +25,46 @@ func NewNet() *Net {
|
||||||
sent.Data = []int{0}
|
sent.Data = []int{0}
|
||||||
|
|
||||||
spark := ui.NewSparklines(recv, sent)
|
spark := ui.NewSparklines(recv, sent)
|
||||||
n := &Net{
|
self := &Net{
|
||||||
Sparklines: spark,
|
Sparklines: spark,
|
||||||
interval: time.Second,
|
interval: time.Second,
|
||||||
}
|
}
|
||||||
n.Label = "Network Usage"
|
self.Label = "Network Usage"
|
||||||
|
|
||||||
go n.update()
|
go self.update()
|
||||||
ticker := time.NewTicker(n.interval)
|
ticker := time.NewTicker(self.interval)
|
||||||
go func() {
|
go func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
n.update()
|
self.update()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return n
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Net) update() {
|
func (self *Net) update() {
|
||||||
// `false` causes psutil to group all network activity
|
// `false` causes psutil to group all network activity
|
||||||
interfaces, _ := psNet.IOCounters(false)
|
interfaces, _ := psNet.IOCounters(false)
|
||||||
recvTotal := interfaces[0].BytesRecv
|
recvTotal := interfaces[0].BytesRecv
|
||||||
sentTotal := interfaces[0].BytesSent
|
sentTotal := interfaces[0].BytesSent
|
||||||
|
|
||||||
if n.recvTotal != 0 { // if this isn't the first update
|
if self.recvTotal != 0 { // if this isn't the first update
|
||||||
recvRecent := recvTotal - n.recvTotal
|
recvRecent := recvTotal - self.recvTotal
|
||||||
sentRecent := sentTotal - n.sentTotal
|
sentRecent := sentTotal - self.sentTotal
|
||||||
|
|
||||||
n.Lines[0].Data = append(n.Lines[0].Data, int(recvRecent))
|
self.Lines[0].Data = append(self.Lines[0].Data, int(recvRecent))
|
||||||
n.Lines[1].Data = append(n.Lines[1].Data, int(sentRecent))
|
self.Lines[1].Data = append(self.Lines[1].Data, int(sentRecent))
|
||||||
}
|
}
|
||||||
|
|
||||||
// used in later calls to update
|
// used in later calls to update
|
||||||
n.recvTotal = recvTotal
|
self.recvTotal = recvTotal
|
||||||
n.sentTotal = sentTotal
|
self.sentTotal = sentTotal
|
||||||
|
|
||||||
// renders net widget titles
|
// renders net widget titles
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
var method string // either 'Rx' or 'Tx'
|
var method string // either 'Rx' or 'Tx'
|
||||||
var total float64
|
var total float64
|
||||||
recent := n.Lines[i].Data[len(n.Lines[i].Data)-1]
|
recent := self.Lines[i].Data[len(self.Lines[i].Data)-1]
|
||||||
unitTotal := "B"
|
unitTotal := "B"
|
||||||
unitRecent := "B"
|
unitRecent := "B"
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ func (n *Net) update() {
|
||||||
unitTotal = "MB"
|
unitTotal = "MB"
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", method, total, unitTotal)
|
self.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", method, total, unitTotal)
|
||||||
n.Lines[i].Title2 = fmt.Sprintf(" %s/s: %9d %2s/s", method, recent, unitRecent)
|
self.Lines[i].Title2 = fmt.Sprintf(" %s/s: %9d %2s/s", method, recent, unitRecent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
168
widgets/proc.go
168
widgets/proc.go
|
@ -37,7 +37,7 @@ type Proc struct {
|
||||||
|
|
||||||
func NewProc(loaded, keyPressed chan bool) *Proc {
|
func NewProc(loaded, keyPressed chan bool) *Proc {
|
||||||
cpuCount, _ := psCPU.Counts(false)
|
cpuCount, _ := psCPU.Counts(false)
|
||||||
p := &Proc{
|
self := &Proc{
|
||||||
Table: ui.NewTable(),
|
Table: ui.NewTable(),
|
||||||
interval: time.Second,
|
interval: time.Second,
|
||||||
cpuCount: cpuCount,
|
cpuCount: cpuCount,
|
||||||
|
@ -45,33 +45,33 @@ func NewProc(loaded, keyPressed chan bool) *Proc {
|
||||||
group: true,
|
group: true,
|
||||||
KeyPressed: keyPressed,
|
KeyPressed: keyPressed,
|
||||||
}
|
}
|
||||||
p.ColResizer = p.ColResize
|
self.ColResizer = self.ColResize
|
||||||
p.Label = "Process List"
|
self.Label = "Process List"
|
||||||
p.ColWidths = []int{5, 10, 4, 4}
|
self.ColWidths = []int{5, 10, 4, 4}
|
||||||
|
|
||||||
p.UniqueCol = 0
|
self.UniqueCol = 0
|
||||||
if p.group {
|
if self.group {
|
||||||
p.UniqueCol = 1
|
self.UniqueCol = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
p.keyBinds()
|
self.keyBinds()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
p.update()
|
self.update()
|
||||||
loaded <- true
|
loaded <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ticker := time.NewTicker(p.interval)
|
ticker := time.NewTicker(self.interval)
|
||||||
go func() {
|
go func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
p.update()
|
self.update()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return p
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proc) update() {
|
func (self *Proc) update() {
|
||||||
psProcesses, _ := psProc.Processes()
|
psProcesses, _ := psProc.Processes()
|
||||||
processes := make([]Process, len(psProcesses))
|
processes := make([]Process, len(psProcesses))
|
||||||
for i, psProcess := range psProcesses {
|
for i, psProcess := range psProcesses {
|
||||||
|
@ -83,150 +83,150 @@ func (p *Proc) update() {
|
||||||
processes[i] = Process{
|
processes[i] = Process{
|
||||||
pid,
|
pid,
|
||||||
command,
|
command,
|
||||||
cpu / float64(p.cpuCount),
|
cpu / float64(self.cpuCount),
|
||||||
mem,
|
mem,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.ungroupedProcs = processes
|
self.ungroupedProcs = processes
|
||||||
p.groupedProcs = Group(processes)
|
self.groupedProcs = Group(processes)
|
||||||
|
|
||||||
p.Sort()
|
self.Sort()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort sorts either the grouped or ungrouped []Process based on the sortMethod.
|
// Sort sorts either the grouped or ungrouped []Process based on the sortMethod.
|
||||||
// Called with every update, when the sort method is changed, and when processes are grouped and ungrouped.
|
// Called with every update, when the sort method is changed, and when processes are grouped and ungrouped.
|
||||||
func (p *Proc) Sort() {
|
func (self *Proc) Sort() {
|
||||||
p.Header = []string{"Count", "Command", "CPU%", "Mem%"}
|
self.Header = []string{"Count", "Command", "CPU%", "Mem%"}
|
||||||
|
|
||||||
if !p.group {
|
if !self.group {
|
||||||
p.Header[0] = "PID"
|
self.Header[0] = "PID"
|
||||||
}
|
}
|
||||||
|
|
||||||
processes := &p.ungroupedProcs
|
processes := &self.ungroupedProcs
|
||||||
if p.group {
|
if self.group {
|
||||||
processes = &p.groupedProcs
|
processes = &self.groupedProcs
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.sortMethod {
|
switch self.sortMethod {
|
||||||
case "c":
|
case "c":
|
||||||
sort.Sort(sort.Reverse(ProcessByCPU(*processes)))
|
sort.Sort(sort.Reverse(ProcessByCPU(*processes)))
|
||||||
p.Header[2] += DOWN
|
self.Header[2] += DOWN
|
||||||
case "p":
|
case "p":
|
||||||
if p.group {
|
if self.group {
|
||||||
sort.Sort(sort.Reverse(ProcessByPID(*processes)))
|
sort.Sort(sort.Reverse(ProcessByPID(*processes)))
|
||||||
} else {
|
} else {
|
||||||
sort.Sort(ProcessByPID(*processes))
|
sort.Sort(ProcessByPID(*processes))
|
||||||
}
|
}
|
||||||
p.Header[0] += DOWN
|
self.Header[0] += DOWN
|
||||||
case "m":
|
case "m":
|
||||||
sort.Sort(sort.Reverse(ProcessByMem(*processes)))
|
sort.Sort(sort.Reverse(ProcessByMem(*processes)))
|
||||||
p.Header[3] += DOWN
|
self.Header[3] += DOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Rows = FieldsToStrings(*processes)
|
self.Rows = FieldsToStrings(*processes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColResize overrides the default ColResize in the termui table.
|
// ColResize overrides the default ColResize in the termui table.
|
||||||
func (p *Proc) ColResize() {
|
func (self *Proc) ColResize() {
|
||||||
// calculate gap size based on total width
|
// calculate gap size based on total width
|
||||||
p.Gap = 3
|
self.Gap = 3
|
||||||
if p.X < 50 {
|
if self.X < 50 {
|
||||||
p.Gap = 1
|
self.Gap = 1
|
||||||
} else if p.X < 75 {
|
} else if self.X < 75 {
|
||||||
p.Gap = 2
|
self.Gap = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
p.CellXPos = []int{
|
self.CellXPos = []int{
|
||||||
p.Gap,
|
self.Gap,
|
||||||
p.Gap + p.ColWidths[0] + p.Gap,
|
self.Gap + self.ColWidths[0] + self.Gap,
|
||||||
p.X - p.Gap - p.ColWidths[3] - p.Gap - p.ColWidths[2],
|
self.X - self.Gap - self.ColWidths[3] - self.Gap - self.ColWidths[2],
|
||||||
p.X - p.Gap - p.ColWidths[3],
|
self.X - self.Gap - self.ColWidths[3],
|
||||||
}
|
}
|
||||||
|
|
||||||
rowWidth := p.Gap + p.ColWidths[0] + p.Gap + p.ColWidths[1] + p.Gap + p.ColWidths[2] + p.Gap + p.ColWidths[3] + p.Gap
|
rowWidth := self.Gap + self.ColWidths[0] + self.Gap + self.ColWidths[1] + self.Gap + self.ColWidths[2] + self.Gap + self.ColWidths[3] + self.Gap
|
||||||
|
|
||||||
// only renders a column if it fits
|
// only renders a column if it fits
|
||||||
if p.X < (rowWidth - p.Gap - p.ColWidths[3]) {
|
if self.X < (rowWidth - self.Gap - self.ColWidths[3]) {
|
||||||
p.ColWidths[2] = 0
|
self.ColWidths[2] = 0
|
||||||
p.ColWidths[3] = 0
|
self.ColWidths[3] = 0
|
||||||
} else if p.X < rowWidth {
|
} else if self.X < rowWidth {
|
||||||
p.CellXPos[2] = p.CellXPos[3]
|
self.CellXPos[2] = self.CellXPos[3]
|
||||||
p.ColWidths[3] = 0
|
self.ColWidths[3] = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proc) keyBinds() {
|
func (self *Proc) keyBinds() {
|
||||||
ui.On("<MouseLeft>", func(e ui.Event) {
|
ui.On("<MouseLeft>", func(e ui.Event) {
|
||||||
p.Click(e.MouseX, e.MouseY)
|
self.Click(e.MouseX, e.MouseY)
|
||||||
p.KeyPressed <- true
|
self.KeyPressed <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.On("<MouseWheelUp>", "<MouseWheelDown>", func(e ui.Event) {
|
ui.On("<MouseWheelUp>", "<MouseWheelDown>", func(e ui.Event) {
|
||||||
switch e.Key {
|
switch e.Key {
|
||||||
case "<MouseWheelDown>":
|
case "<MouseWheelDown>":
|
||||||
p.Down()
|
self.Down()
|
||||||
case "<MouseWheelUp>":
|
case "<MouseWheelUp>":
|
||||||
p.Up()
|
self.Up()
|
||||||
}
|
}
|
||||||
p.KeyPressed <- true
|
self.KeyPressed <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.On("<up>", "<down>", func(e ui.Event) {
|
ui.On("<up>", "<down>", func(e ui.Event) {
|
||||||
switch e.Key {
|
switch e.Key {
|
||||||
case "<up>":
|
case "<up>":
|
||||||
p.Up()
|
self.Up()
|
||||||
case "<down>":
|
case "<down>":
|
||||||
p.Down()
|
self.Down()
|
||||||
}
|
}
|
||||||
p.KeyPressed <- true
|
self.KeyPressed <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
viKeys := []string{"j", "k", "gg", "G", "<C-d>", "<C-u>", "<C-f>", "<C-b>"}
|
viKeys := []string{"j", "k", "gg", "G", "<C-d>", "<C-u>", "<C-f>", "<C-b>"}
|
||||||
ui.On(viKeys, func(e ui.Event) {
|
ui.On(viKeys, func(e ui.Event) {
|
||||||
switch e.Key {
|
switch e.Key {
|
||||||
case "j":
|
case "j":
|
||||||
p.Down()
|
self.Down()
|
||||||
case "k":
|
case "k":
|
||||||
p.Up()
|
self.Up()
|
||||||
case "gg":
|
case "gg":
|
||||||
p.Top()
|
self.Top()
|
||||||
case "G":
|
case "G":
|
||||||
p.Bottom()
|
self.Bottom()
|
||||||
case "<C-d>":
|
case "<C-d>":
|
||||||
p.HalfPageDown()
|
self.HalfPageDown()
|
||||||
case "<C-u>":
|
case "<C-u>":
|
||||||
p.HalfPageUp()
|
self.HalfPageUp()
|
||||||
case "<C-f>":
|
case "<C-f>":
|
||||||
p.PageDown()
|
self.PageDown()
|
||||||
case "<C-b>":
|
case "<C-b>":
|
||||||
p.PageUp()
|
self.PageUp()
|
||||||
}
|
}
|
||||||
p.KeyPressed <- true
|
self.KeyPressed <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.On("dd", func(e ui.Event) {
|
ui.On("dd", func(e ui.Event) {
|
||||||
p.Kill()
|
self.Kill()
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.On("<tab>", func(e ui.Event) {
|
ui.On("<tab>", func(e ui.Event) {
|
||||||
p.group = !p.group
|
self.group = !self.group
|
||||||
if p.group {
|
if self.group {
|
||||||
p.UniqueCol = 1
|
self.UniqueCol = 1
|
||||||
} else {
|
} else {
|
||||||
p.UniqueCol = 0
|
self.UniqueCol = 0
|
||||||
}
|
}
|
||||||
p.sortMethod = "c"
|
self.sortMethod = "c"
|
||||||
p.Sort()
|
self.Sort()
|
||||||
p.Top()
|
self.Top()
|
||||||
p.KeyPressed <- true
|
self.KeyPressed <- true
|
||||||
})
|
})
|
||||||
|
|
||||||
ui.On("m", "c", "p", func(e ui.Event) {
|
ui.On("m", "c", "p", func(e ui.Event) {
|
||||||
if p.sortMethod != e.Key {
|
if self.sortMethod != e.Key {
|
||||||
p.sortMethod = e.Key
|
self.sortMethod = e.Key
|
||||||
p.Top()
|
self.Top()
|
||||||
p.Sort()
|
self.Sort()
|
||||||
p.KeyPressed <- true
|
self.KeyPressed <- true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -279,13 +279,13 @@ func FieldsToStrings(P []Process) [][]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill kills process or group of processes.
|
// Kill kills process or group of processes.
|
||||||
func (p *Proc) Kill() {
|
func (self *Proc) Kill() {
|
||||||
p.SelectedItem = ""
|
self.SelectedItem = ""
|
||||||
command := "kill"
|
command := "kill"
|
||||||
if p.UniqueCol == 1 {
|
if self.UniqueCol == 1 {
|
||||||
command = "pkill"
|
command = "pkill"
|
||||||
}
|
}
|
||||||
cmd := exec.Command(command, p.Rows[p.SelectedRow][p.UniqueCol])
|
cmd := exec.Command(command, self.Rows[self.SelectedRow][self.UniqueCol])
|
||||||
cmd.Start()
|
cmd.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,60 +23,60 @@ type Temp struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTemp() *Temp {
|
func NewTemp() *Temp {
|
||||||
t := &Temp{
|
self := &Temp{
|
||||||
Block: ui.NewBlock(),
|
Block: ui.NewBlock(),
|
||||||
interval: time.Second * 5,
|
interval: time.Second * 5,
|
||||||
Data: make(map[string]int),
|
Data: make(map[string]int),
|
||||||
Threshold: 80, // temp at which color should change
|
Threshold: 80, // temp at which color should change
|
||||||
}
|
}
|
||||||
t.Label = "Temperatures"
|
self.Label = "Temperatures"
|
||||||
|
|
||||||
go t.update()
|
go self.update()
|
||||||
ticker := time.NewTicker(t.interval)
|
ticker := time.NewTicker(self.interval)
|
||||||
go func() {
|
go func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
t.update()
|
self.update()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return t
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Temp) update() {
|
func (self *Temp) update() {
|
||||||
sensors, _ := psHost.SensorsTemperatures()
|
sensors, _ := psHost.SensorsTemperatures()
|
||||||
for _, sensor := range sensors {
|
for _, sensor := range sensors {
|
||||||
// only sensors with input in their name are giving us live temp info
|
// only sensors with input in their name are giving us live temp info
|
||||||
if strings.Contains(sensor.SensorKey, "input") {
|
if strings.Contains(sensor.SensorKey, "input") {
|
||||||
// removes '_input' from the end of the sensor name
|
// removes '_input' from the end of the sensor name
|
||||||
label := sensor.SensorKey[:strings.Index(sensor.SensorKey, "_input")]
|
label := sensor.SensorKey[:strings.Index(sensor.SensorKey, "_input")]
|
||||||
t.Data[label] = int(sensor.Temperature)
|
self.Data[label] = int(sensor.Temperature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements ui.Bufferer interface.
|
// Buffer implements ui.Bufferer interface.
|
||||||
func (t *Temp) Buffer() *ui.Buffer {
|
func (self *Temp) Buffer() *ui.Buffer {
|
||||||
buf := t.Block.Buffer()
|
buf := self.Block.Buffer()
|
||||||
|
|
||||||
var keys []string
|
var keys []string
|
||||||
for k := range t.Data {
|
for k := range self.Data {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
|
|
||||||
for y, key := range keys {
|
for y, key := range keys {
|
||||||
if y+1 > t.Y {
|
if y+1 > self.Y {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
fg := t.TempLow
|
fg := self.TempLow
|
||||||
if t.Data[key] >= t.Threshold {
|
if self.Data[key] >= self.Threshold {
|
||||||
fg = t.TempHigh
|
fg = self.TempHigh
|
||||||
}
|
}
|
||||||
|
|
||||||
s := ui.MaxString(key, (t.X - 4))
|
s := ui.MaxString(key, (self.X - 4))
|
||||||
buf.SetString(1, y+1, s, t.Fg, t.Bg)
|
buf.SetString(1, y+1, s, self.Fg, self.Bg)
|
||||||
buf.SetString(t.X-2, y+1, fmt.Sprintf("%dC", t.Data[key]), fg, t.Bg)
|
buf.SetString(self.X-2, y+1, fmt.Sprintf("%dC", self.Data[key]), fg, self.Bg)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user