Code cleanup and comments
This commit is contained in:
parent
f0efec1ec7
commit
b06502d7f2
|
@ -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)
|
||||
|
|
|
@ -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++ {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 ""
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user