Code cleanup and comments

This commit is contained in:
Caleb Bassi 2018-02-23 00:42:39 -08:00
parent f0efec1ec7
commit b06502d7f2
14 changed files with 63 additions and 90 deletions

View File

@ -4,15 +4,13 @@ import (
"image"
)
// Block is a base struct for all other upper level widgets,
// consider it as css: display:block.
// Normally you do not need to create it manually.
// Block is a base struct for all other upper level widgets.
type Block struct {
Grid image.Rectangle
X int
Y int
XOffset int
YOffset int
X int // largest X value in the inner square
Y int // largest Y value in the inner square
XOffset int // the X position of the widget on the terminal
YOffset int // the Y position of the widget on the terminal
Label string
BorderFg Color
BorderBg Color
@ -22,7 +20,7 @@ type Block struct {
Bg Color
}
// NewBlock returns a *Block which inherits styles from current theme.
// NewBlock returns a *Block which inherits styles from the current theme.
func NewBlock() *Block {
return &Block{
Fg: Theme.Fg,
@ -34,7 +32,6 @@ func NewBlock() *Block {
}
}
// Buffer draws a box border.
func (b *Block) drawBorder(buf *Buffer) {
x := b.X + 1
y := b.Y + 1
@ -67,7 +64,7 @@ func (b *Block) drawLabel(buf *Buffer) {
}
}
// Resize computes Height, Width, XOffset, and YOffset
// Resize computes Height, Width, XOffset, and YOffset given terminal dimensions.
func (b *Block) Resize(termWidth, termHeight, termCols, termRows int) {
b.X = int((float64(b.Grid.Dx())/float64(termCols))*float64(termWidth)) - 2
b.Y = int((float64(b.Grid.Dy())/float64(termRows))*float64(termHeight)) - 2
@ -75,6 +72,7 @@ func (b *Block) Resize(termWidth, termHeight, termCols, termRows int) {
b.YOffset = int(((float64(b.Grid.Min.Y) / float64(termRows)) * float64(termHeight)))
}
// SetGrid create a rectangle representing the block's dimensions in the grid.
func (b *Block) SetGrid(c0, r0, c1, r1 int) {
b.Grid = image.Rect(c0, r0, c1, r1)
}
@ -87,7 +85,7 @@ func (b *Block) GetYOffset() int {
return b.YOffset
}
// Buffer implements Bufferer interface and draws background and border
// Buffer implements Bufferer interface and draws background, border, and borderlabel.
func (b *Block) Buffer() *Buffer {
buf := NewBuffer()
buf.SetAreaXY(b.X+2, b.Y+2)

View File

@ -4,7 +4,7 @@ import (
"image"
)
// Cell is a rune with assigned Fg and Bg
// Cell is a rune with assigned Fg and Bg.
type Cell struct {
Ch rune
Fg Color
@ -21,14 +21,13 @@ func NewCell(ch rune, Fg, Bg Color) Cell {
return Cell{ch, Fg, Bg}
}
// NewBuffer returns a new Buffer
func NewBuffer() *Buffer {
return &Buffer{
CellMap: make(map[image.Point]Cell),
Area: image.Rectangle{}}
}
// NewFilledBuffer returns a new Buffer filled with ch, fb and bg.
// NewFilledBuffer returns a new Buffer filled with the given Cell.
func NewFilledBuffer(x0, y0, x1, y1 int, c Cell) *Buffer {
buf := NewBuffer()
buf.Area.Min = image.Pt(x0, y0)
@ -42,11 +41,12 @@ func NewFilledBuffer(x0, y0, x1, y1 int, c Cell) *Buffer {
return buf
}
// Set assigns a char to (x,y)
// Set assigns a Cell to (x,y).
func (b *Buffer) SetCell(x, y int, c Cell) {
b.CellMap[image.Pt(x, y)] = c
}
// SetString assigns a string to a Buffer starting at (x,y).
func (b *Buffer) SetString(x, y int, s string, fg, bg Color) {
for i, char := range s {
b.SetCell(x+i, y, Cell{char, fg, bg})
@ -58,32 +58,13 @@ func (b *Buffer) At(x, y int) Cell {
return b.CellMap[image.Pt(x, y)]
}
// Bounds returns the domain for which At can return non-zero color.
func (b *Buffer) Bounds() image.Rectangle {
x0, y0, x1, y1 := 0, 0, 0, 0
for p := range b.CellMap {
if p.X > x1 {
x1 = p.X
}
if p.X < x0 {
x0 = p.X
}
if p.Y > y1 {
y1 = p.Y
}
if p.Y < y0 {
y0 = p.Y
}
}
return image.Rect(x0, y0, x1+1, y1+1)
}
// SetArea assigns a new rect area to Buffer b.
func (b *Buffer) SetArea(r image.Rectangle) {
b.Area.Max = r.Max
b.Area.Min = r.Min
}
// SetAreaXY sets the Buffer bounds from (0,0) to (x,y).
func (b *Buffer) SetAreaXY(x, y int) {
b.Area.Min.Y = 0
b.Area.Min.X = 0
@ -91,12 +72,7 @@ func (b *Buffer) SetAreaXY(x, y int) {
b.Area.Max.X = x
}
// Sync sets drawing area to the buffer's bound
func (b *Buffer) Sync() {
b.SetArea(b.Bounds())
}
// Merge merges bs Buffers onto b
// Merge merges the given buffers onto the current Buffer.
func (b *Buffer) Merge(bs ...*Buffer) {
for _, buf := range bs {
for p, c := range buf.CellMap {
@ -106,6 +82,7 @@ func (b *Buffer) Merge(bs ...*Buffer) {
}
}
// MergeWithOffset merges the given buffer at a certain position on the given buffer.
func (b *Buffer) MergeWithOffset(buf *Buffer, xOffset, yOffset int) {
for p, c := range buf.CellMap {
b.SetCell(p.X+xOffset, p.Y+yOffset, c)
@ -114,7 +91,7 @@ func (b *Buffer) MergeWithOffset(buf *Buffer, xOffset, yOffset int) {
b.SetArea(b.Area.Union(rect))
}
// Fill fills the Buffer b with ch,fg and bg.
// Fill fills the Buffer with a Cell.
func (b *Buffer) Fill(c Cell) {
for x := b.Area.Min.X; x < b.Area.Max.X; x++ {
for y := b.Area.Min.Y; y < b.Area.Max.Y; y++ {

View File

@ -1,15 +1,19 @@
package termui
// Color is an integer in the range -1 to 255
type Color int
// ColorDefault = clear
const ColorDefault = -1
// Copied from termbox
const (
AttrBold Color = 1 << (iota + 9)
AttrUnderline
AttrReverse
)
// Theme is assigned to the current theme
var Theme = DefaultTheme
var DefaultTheme = Colorscheme{
@ -29,7 +33,7 @@ var DefaultTheme = Colorscheme{
TempHigh: 1,
}
// A ColorScheme represents the current look-and-feel of the dashboard.
// A Colorscheme represents the current look-and-feel of the dashboard.
type Colorscheme struct {
Fg Color
Bg Color

View File

@ -15,11 +15,12 @@ var eventStream = EventStream{
type EventStream struct {
eventHandlers map[string]func(Event)
prevKey string
prevKey string // previous keypress
stopLoop chan bool
eventQueue chan tb.Event
eventQueue chan tb.Event // list of events from termbox
}
// Event includes only the termbox.Event attributes we need.
type Event struct {
Key string
Width int
@ -137,7 +138,6 @@ func convertTermboxKeyValue(e tb.Event) string {
return pre + mod + k
}
// convertTermboxMouseValue turns termbox mouse events into strings
func convertTermboxMouseValue(e tb.Event) string {
switch e.Key {
case tb.MouseLeft:

View File

@ -9,19 +9,21 @@ type GridBufferer interface {
SetGrid(int, int, int, int)
}
// Grid holds widgets and information about terminal dimensions.
// Widgets are adjusted and rendered through the grid.
type Grid struct {
Widgets []GridBufferer
Width int
Height int
Cols int
Rows int
BgColor Color
}
func NewGrid() *Grid {
return &Grid{}
}
// Set takes a widget along with it's grid dimensions to be controlled by the grid.
func (g *Grid) Set(x0, y0, x1, y1 int, widget GridBufferer) {
if widget == nil {
return
@ -36,13 +38,14 @@ func (g *Grid) Set(x0, y0, x1, y1 int, widget GridBufferer) {
g.Widgets = append(g.Widgets, widget)
}
// Resize resizes each widget in the grid's control.
func (g *Grid) Resize() {
for _, w := range g.Widgets {
w.Resize(g.Width, g.Height, g.Cols, g.Rows)
}
}
// Buffer implements Bufferer interface.
// Buffer implements Bufferer interface and merges each widget into one buffer.
func (g *Grid) Buffer() *Buffer {
buf := NewFilledBuffer(0, 0, g.Width, g.Height, Cell{' ', ColorDefault, Theme.Bg})
for _, w := range g.Widgets {

View File

@ -14,17 +14,13 @@ func Init() error {
tb.SetOutputMode(tb.Output256)
Body = NewGrid()
Body.BgColor = Theme.Bg
// renderLock.Lock()
Body.Width, Body.Height = tb.Size()
// renderLock.Unlock()
return nil
}
// Close finalizes termui library,
// should be called after successful initialization when termui's functionality isn't required anymore.
// Close finalizes termui library.
// It should be called after successful initialization when termui's functionality isn't required anymore.
func Close() {
tb.Close()
}

View File

@ -6,19 +6,14 @@ import (
tb "github.com/nsf/termbox-go"
)
var renderJobs chan []Bufferer
// So that only one render function can flush/write to the screen at a time
// var renderLock sync.Mutex
// Bufferer should be implemented by all renderable components. Bufferers can render a Buffer.
// Bufferer should be implemented by all renderable components.
type Bufferer interface {
Buffer() *Buffer
GetXOffset() int
GetYOffset() int
}
// Render renders all Bufferer in the given order from left to right, right could overlap on left ones.
// Render renders all Bufferers in the given order to termbox, then asks termbox to print the screen.
func Render(bs ...Bufferer) {
var wg sync.WaitGroup
for _, b := range bs {
@ -35,13 +30,11 @@ func Render(bs ...Bufferer) {
}(b)
}
// renderLock.Lock()
wg.Wait()
tb.Flush()
// renderLock.Unlock()
}
// Clear clears the screen with the default Bg color.
func Clear() {
tb.Clear(tb.ColorDefault+1, tb.Attribute(Theme.Bg)+1)
}

View File

@ -6,7 +6,7 @@ import (
const DOTS = '…'
// MaxString trims a string and adds dots if its length is greater than l
// MaxString trims a string and adds dots if the string is longer than a give length.
func MaxString(s string, l int) string {
if l <= 0 {
return ""

View File

@ -5,17 +5,17 @@ import (
"time"
ui "github.com/cjbassi/gotop/termui"
ps "github.com/shirou/gopsutil/cpu"
cpu "github.com/shirou/gopsutil/cpu"
)
type CPU struct {
*ui.LineGraph
count int
count int // number of CPUs
interval time.Duration
}
func NewCPU() *CPU {
count, _ := ps.Counts(false)
count, _ := cpu.Counts(false)
c := &CPU{ui.NewLineGraph(), count, time.Second}
c.Label = "CPU Usage"
for i := 0; i < c.count; i++ {
@ -35,7 +35,9 @@ func NewCPU() *CPU {
}
func (c *CPU) update() {
percent, _ := ps.Percent(time.Second, true) // takes one second to get the data
// psutil calculates the CPU usage over a 1 second interval, therefore it blocks for 1 second
// `true` makes it so psutil doesn't group CPU usage percentages
percent, _ := cpu.Percent(time.Second, true)
for i := 0; i < c.count; i++ {
key := "CPU" + strconv.Itoa(i+1)
c.Data[key] = append(c.Data[key], percent[i])

View File

@ -6,7 +6,7 @@ import (
ui "github.com/cjbassi/gotop/termui"
"github.com/cjbassi/gotop/utils"
ps "github.com/shirou/gopsutil/disk"
disk "github.com/shirou/gopsutil/disk"
)
type Disk struct {
@ -16,6 +16,7 @@ type Disk struct {
}
func NewDisk() *Disk {
// get root filesystem usage
d := &Disk{ui.NewGauge(), "/", time.Second * 5}
d.Label = "Disk Usage"
@ -31,7 +32,7 @@ func NewDisk() *Disk {
}
func (d *Disk) update() {
disk, _ := ps.Usage(d.fs)
disk, _ := disk.Usage(d.fs)
d.Percent = int(disk.UsedPercent)
d.Description = fmt.Sprintf(" (%dGB free)", int(utils.BytesToGB(disk.Free)))
}

View File

@ -30,12 +30,10 @@ type HelpMenu struct {
func NewHelpMenu() *HelpMenu {
block := *ui.NewBlock()
block.X = 48
block.Y = 15
block.XOffset = (ui.Body.Width - block.X) / 2
block.YOffset = (ui.Body.Height - block.Y) / 2
// block.XOffset = ui.Body.Width - 50
// block.YOffset = ui.Body.Height - 50
block.X = 48 // width
block.Y = 15 // height
block.XOffset = (ui.Body.Width - block.X) / 2 // X coordinate
block.YOffset = (ui.Body.Height - block.Y) / 2 // Y coordinate
return &HelpMenu{block}
}
@ -48,7 +46,5 @@ func (hm *HelpMenu) Buffer() *ui.Buffer {
}
}
buf.SetAreaXY(hm.X+2, hm.Y+2)
return buf
}

View File

@ -4,7 +4,7 @@ import (
"time"
ui "github.com/cjbassi/gotop/termui"
ps "github.com/shirou/gopsutil/mem"
mem "github.com/shirou/gopsutil/mem"
)
type Mem struct {
@ -15,7 +15,7 @@ type Mem struct {
func NewMem() *Mem {
m := &Mem{ui.NewLineGraph(), time.Second}
m.Label = "Memory Usage"
m.Data["Main"] = []float64{0} // Sets initial data to 0
m.Data["Main"] = []float64{0}
m.Data["Swap"] = []float64{0}
go m.update()
@ -30,8 +30,8 @@ func NewMem() *Mem {
}
func (m *Mem) update() {
main, _ := ps.VirtualMemory()
swap, _ := ps.SwapMemory()
main, _ := mem.VirtualMemory()
swap, _ := mem.SwapMemory()
m.Data["Main"] = append(m.Data["Main"], main.UsedPercent)
m.Data["Swap"] = append(m.Data["Swap"], swap.UsedPercent)
}

View File

@ -6,12 +6,13 @@ import (
ui "github.com/cjbassi/gotop/termui"
"github.com/cjbassi/gotop/utils"
ps "github.com/shirou/gopsutil/net"
net "github.com/shirou/gopsutil/net"
)
type Net struct {
*ui.Sparklines
interval time.Duration
interval time.Duration
// used to calculate recent network activity
recvTotal uint64
sentTotal uint64
}
@ -39,7 +40,8 @@ func NewNet() *Net {
}
func (n *Net) update() {
interfaces, _ := ps.IOCounters(false)
// `false` causes psutil to group all network activity
interfaces, _ := net.IOCounters(false)
recv := interfaces[0].BytesRecv
sent := interfaces[0].BytesSent
@ -51,6 +53,7 @@ func (n *Net) update() {
n.Lines[1].Data = append(n.Lines[1].Data, int(curSent))
}
// used for later calls to update
n.recvTotal = recv
n.sentTotal = sent
@ -62,10 +65,10 @@ func (n *Net) update() {
curUnit := "B"
if i == 0 {
total = n.recvTotal
total = recv
method = "Rx"
} else {
total = n.sentTotal
total = sent
method = "Tx"
}

View File

@ -7,7 +7,7 @@ import (
ui "github.com/cjbassi/gotop/termui"
cpu "github.com/shirou/gopsutil/cpu"
ps "github.com/shirou/gopsutil/process"
proc "github.com/shirou/gopsutil/process"
)
const (
@ -71,7 +71,7 @@ func NewProc(loaded, keyPressed chan bool) *Proc {
}
func (p *Proc) update() {
psProcs, _ := ps.Processes()
psProcs, _ := proc.Processes()
processes := make([]Process, len(psProcs))
for i, pr := range psProcs {
pid := pr.Pid