diff options
Diffstat (limited to 'termui')
-rw-r--r-- | termui/block.go | 2 | ||||
-rw-r--r-- | termui/buffer.go | 16 | ||||
-rw-r--r-- | termui/colors.go | 7 | ||||
-rw-r--r-- | termui/events.go | 28 | ||||
-rw-r--r-- | termui/gauge.go | 2 | ||||
-rw-r--r-- | termui/grid.go | 9 | ||||
-rw-r--r-- | termui/linegraph.go | 21 | ||||
-rw-r--r-- | termui/sparkline.go | 11 | ||||
-rw-r--r-- | termui/table.go | 20 |
9 files changed, 64 insertions, 52 deletions
diff --git a/termui/block.go b/termui/block.go index cc3a15c..5d1ab8e 100644 --- a/termui/block.go +++ b/termui/block.go @@ -77,10 +77,12 @@ func (b *Block) SetGrid(c0, r0, c1, r1 int) { b.Grid = image.Rect(c0, r0, c1, r1) } +// GetXOffset implements Bufferer interface. func (b *Block) GetXOffset() int { return b.XOffset } +// GetYOffset implements Bufferer interface. func (b *Block) GetYOffset() int { return b.YOffset } diff --git a/termui/buffer.go b/termui/buffer.go index bab7e30..47c234c 100644 --- a/termui/buffer.go +++ b/termui/buffer.go @@ -17,14 +17,17 @@ type Buffer struct { CellMap map[image.Point]Cell } +// NewCell returne a new Cell given all necessary fields. func NewCell(ch rune, Fg, Bg Color) Cell { return Cell{ch, Fg, Bg} } +// NewBuffer returns a new empty Buffer. func NewBuffer() *Buffer { return &Buffer{ CellMap: make(map[image.Point]Cell), - Area: image.Rectangle{}} + Area: image.Rectangle{}, + } } // NewFilledBuffer returns a new Buffer filled with the given Cell. @@ -32,16 +35,11 @@ func NewFilledBuffer(x0, y0, x1, y1 int, c Cell) *Buffer { buf := NewBuffer() buf.Area.Min = image.Pt(x0, y0) buf.Area.Max = image.Pt(x1, y1) - - for x := buf.Area.Min.X; x < buf.Area.Max.X; x++ { - for y := buf.Area.Min.Y; y < buf.Area.Max.Y; y++ { - buf.SetCell(x, y, c) - } - } + buf.Fill(c) return buf } -// Set assigns a Cell to (x,y). +// SetCell assigns a Cell to (x,y). func (b *Buffer) SetCell(x, y int, c Cell) { b.CellMap[image.Pt(x, y)] = c } @@ -82,7 +80,7 @@ func (b *Buffer) Merge(bs ...*Buffer) { } } -// MergeWithOffset merges the given buffer at a certain position on the given buffer. +// MergeWithOffset merges a Buffer onto another with an offset. func (b *Buffer) MergeWithOffset(buf *Buffer, xOffset, yOffset int) { for p, c := range buf.CellMap { b.SetCell(p.X+xOffset, p.Y+yOffset, c) diff --git a/termui/colors.go b/termui/colors.go index f1de7bf..3af2469 100644 --- a/termui/colors.go +++ b/termui/colors.go @@ -1,21 +1,22 @@ package termui -// Color is an integer in the range -1 to 255 +// Color is an integer in the range -1 to 255. type Color int // ColorDefault = clear const ColorDefault = -1 -// Copied from termbox +// Copied from termbox. Attributes that can be bitwise OR'ed with a color. const ( AttrBold Color = 1 << (iota + 9) AttrUnderline AttrReverse ) -// Theme is assigned to the current theme +// Theme is assigned to the current theme. var Theme = DefaultTheme +// DefaultTheme implements a generic set of colors to use by default. var DefaultTheme = Colorscheme{ Fg: 7, Bg: -1, diff --git a/termui/events.go b/termui/events.go index 30c6581..8849101 100644 --- a/termui/events.go +++ b/termui/events.go @@ -20,7 +20,7 @@ type EventStream struct { eventQueue chan tb.Event // list of events from termbox } -// Event includes only the termbox.Event attributes we need. +// Event is a copy of termbox.Event that only contains the fields we need. type Event struct { Key string Width int @@ -76,7 +76,7 @@ func Loop() { } } -// StopLoop stops the events Loop +// StopLoop stops the event loop. func StopLoop() { eventStream.stopLoop <- true } @@ -156,21 +156,27 @@ func convertTermboxMouseValue(e tb.Event) string { return "" } -// convertTermboxEvent turns a termbox event into a termui event +// convertTermboxEvent turns a termbox event into a termui event. func convertTermboxEvent(e tb.Event) Event { - ne := Event{} // new event + var ne Event switch e.Type { case tb.EventKey: - ne.Key = convertTermboxKeyValue(e) + ne = Event{ + Key: convertTermboxKeyValue(e), + } case tb.EventMouse: - ne.Key = convertTermboxMouseValue(e) - ne.MouseX = e.MouseX - ne.MouseY = e.MouseY + ne = Event{ + Key: convertTermboxMouseValue(e), + MouseX: e.MouseX, + MouseY: e.MouseY, + } case tb.EventResize: - ne.Key = "resize" - ne.Width = e.Width - ne.Height = e.Height + ne = Event{ + Key: "resize", + Width: e.Width, + Height: e.Height, + } } return ne diff --git a/termui/gauge.go b/termui/gauge.go index 5667686..1896871 100644 --- a/termui/gauge.go +++ b/termui/gauge.go @@ -35,10 +35,8 @@ func (g *Gauge) Buffer() *Buffer { // plot percentage s := strconv.Itoa(g.Percent) + "%" + g.Description s = MaxString(s, g.X) - y := (g.Y + 1) / 2 x := ((g.X - len(s)) + 1) / 2 - for i, char := range s { bg := g.Bg fg := g.Fg diff --git a/termui/grid.go b/termui/grid.go index c8321a2..a005234 100644 --- a/termui/grid.go +++ b/termui/grid.go @@ -19,11 +19,12 @@ type Grid struct { Rows int } +// NewGrid creates an empty Grid. func NewGrid() *Grid { return &Grid{} } -// Set takes a widget along with it's grid dimensions to be controlled by the grid. +// Set assigns a widget and its grid dimensions to Grid. func (g *Grid) Set(x0, y0, x1, y1 int, widget GridBufferer) { if widget == nil { return @@ -38,14 +39,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. +// Resize resizes each widget in the grid. func (g *Grid) Resize() { for _, w := range g.Widgets { w.Resize(g.Width, g.Height, g.Cols, g.Rows) } } -// Buffer implements Bufferer interface and merges each widget into one buffer. +// Buffer implements the Bufferer interface by merging each widget in Grid 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 { @@ -54,10 +55,12 @@ func (g *Grid) Buffer() *Buffer { return buf } +// GetXOffset implements Bufferer interface. func (g *Grid) GetXOffset() int { return 0 } +// GetYOffset implements Bufferer interface. func (g *Grid) GetYOffset() int { return 0 } diff --git a/termui/linegraph.go b/termui/linegraph.go index 1aebeb3..4b01691 100644 --- a/termui/linegraph.go +++ b/termui/linegraph.go @@ -7,7 +7,7 @@ import ( drawille "github.com/cjbassi/drawille-go" ) -// LineGraph implements a graph of data points. +// LineGraph implements a line graph of data points. type LineGraph struct { *Block Data map[string][]float64 @@ -27,17 +27,19 @@ func NewLineGraph() *LineGraph { } } -// renderPoints plots and interpolates data points. +// Buffer implements Bufferer interface. func (lc *LineGraph) Buffer() *Buffer { buf := lc.Block.Buffer() + // 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 c := drawille.NewCanvas() - // used to keep track of colors but not write them to the buffer until the end + // 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) for i := range colors { colors[i] = make([]Color, lc.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)) i := 0 for seriesName := range lc.Data { @@ -46,7 +48,7 @@ func (lc *LineGraph) Buffer() *Buffer { } sort.Strings(seriesList) - // draw lines in reverse order so the first one 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-- { seriesName := seriesList[i] seriesData := lc.Data[seriesName] @@ -61,13 +63,12 @@ func (lc *LineGraph) Buffer() *Buffer { for i := len(seriesData) - 1; i >= 0; i-- { x := ((lc.X + 1) * 2) - 1 - (((len(seriesData) - 1) - i) * 5) y := ((lc.Y + 1) * 4) - 1 - int((float64((lc.Y)*4)-1)*(seriesData[i]/100)) - // stop rendering at the left-most wall - if x < 0 { + if x < 0 { // stop rendering at the left-most wall break } if lastY == -1 { // if this is the first point c.Set(x, y) - colors[x/2][y/4] = seriesLineColor // divide by 2 and 4 due to 2x4 dots in braille characters + colors[x/2][y/4] = seriesLineColor } else { c.DrawLine(lastX, lastY, x, y) for _, p := range drawille.Line(lastX, lastY, x, y) { @@ -91,14 +92,16 @@ func (lc *LineGraph) Buffer() *Buffer { } } + // renders key ontop for j, seriesName := range seriesList { + // sorts lines again seriesData := lc.Data[seriesName] seriesLineColor, ok := lc.LineColor[seriesName] if !ok { seriesLineColor = lc.DefaultLineColor } - // Render key ontop, but let braille be drawn between words + // render key ontop, but let braille be drawn over space characters str := fmt.Sprintf("%s %3.0f%%", seriesName, seriesData[len(seriesData)-1]) for k, char := range str { if char != ' ' { diff --git a/termui/sparkline.go b/termui/sparkline.go index 5de952f..6beeb8d 100644 --- a/termui/sparkline.go +++ b/termui/sparkline.go @@ -17,12 +17,12 @@ type Sparklines struct { Lines []*Sparkline } -// Add appends a given Sparkline to s *Sparklines. +// Add appends a given Sparkline to the *Sparklines. func (s *Sparklines) Add(sl Sparkline) { s.Lines = append(s.Lines, &sl) } -// NewSparkline returns a unrenderable single sparkline that intended to be added into Sparklines. +// NewSparkline returns an unrenderable single sparkline that intended to be added into a Sparklines. func NewSparkline() *Sparkline { return &Sparkline{ TitleColor: Theme.Fg, @@ -30,7 +30,7 @@ func NewSparkline() *Sparkline { } } -// NewSparklines return a new *Sparklines with given Sparkline(s), you can always add a new Sparkline later. +// NewSparklines return a new *Sparklines with given Sparklines, you can always add a new Sparkline later. func NewSparklines(ss ...*Sparkline) *Sparklines { return &Sparklines{ Block: NewBlock(), @@ -44,19 +44,18 @@ func (sl *Sparklines) Buffer() *Buffer { lc := len(sl.Lines) // lineCount - // for each line + // renders each sparkline and its titles for i, line := range sl.Lines { + // prints titles title1Y := 2 + (sl.Y/lc)*i title2Y := (2 + (sl.Y/lc)*i) + 1 - title1 := MaxString(line.Title1, sl.X) title2 := MaxString(line.Title2, sl.X) buf.SetString(1, title1Y, title1, line.TitleColor|AttrBold, sl.Bg) buf.SetString(1, title2Y, title2, line.TitleColor|AttrBold, sl.Bg) sparkY := (sl.Y / lc) * (i + 1) - // finds max data in current view used for relative heights max := 1 for i := len(line.Data) - 1; i >= 0 && sl.X-((len(line.Data)-1)-i) >= 1; i-- { diff --git a/termui/table.go b/termui/table.go index c5d8909..7e377d2 100644 --- a/termui/table.go +++ b/termui/table.go @@ -10,7 +10,7 @@ type Table struct { Header []string Rows [][]string ColWidths []int - Cp []int // column position + CellXPos []int // column position Gap int // gap between columns Cursor Color UniqueCol int // the column used to identify the selected item @@ -34,6 +34,7 @@ func NewTable() *Table { } // ColResize is the default column resizer, but can be overriden. +// ColResize calculates the width of each column. func (t *Table) ColResize() { // calculate gap size based on total width t.Gap = 3 @@ -46,7 +47,7 @@ func (t *Table) ColResize() { cur := 0 for _, w := range t.ColWidths { cur += t.Gap - t.Cp = append(t.Cp, cur) + t.CellXPos = append(t.CellXPos, cur) cur += w } } @@ -55,21 +56,20 @@ func (t *Table) ColResize() { func (t *Table) Buffer() *Buffer { buf := t.Block.Buffer() - // makes sure there isn't a gap at the bottom of the table view + // removes gap at the bottom of the current view if there is one if t.TopRow > len(t.Rows)-(t.Y-1) { t.TopRow = len(t.Rows) - (t.Y - 1) } t.ColResizer() - // print header - // for i := 0; i < render; i++ { + // prints header for i, width := range t.ColWidths { if width == 0 { break } r := MaxString(t.Header[i], t.X-6) - buf.SetString(t.Cp[i], 1, r, t.Fg|AttrBold, t.Bg) + buf.SetString(t.CellXPos[i], 1, r, t.Fg|AttrBold, t.Bg) } // prints each row @@ -77,7 +77,7 @@ func (t *Table) Buffer() *Buffer { row := t.Rows[rowNum] y := (rowNum + 2) - t.TopRow - // cursor + // prints cursor bg := t.Bg if (t.SelectedItem == "" && rowNum == t.SelectedRow) || (t.SelectedItem != "" && t.SelectedItem == row[t.UniqueCol]) { bg = t.Cursor @@ -97,7 +97,7 @@ func (t *Table) Buffer() *Buffer { break } r := MaxString(row[i], t.X-6) - buf.SetString(t.Cp[i], y, r, t.Fg, bg) + buf.SetString(t.CellXPos[i], y, r, t.Fg, bg) } } @@ -108,7 +108,7 @@ func (t *Table) Buffer() *Buffer { // Cursor Movement // ///////////////////////////////////////////////////////////////////////////////// -// calcPos is used to calculate the cursor position and where in the process list we are located. +// calcPos is used to calculate the cursor position and the current view. func (t *Table) calcPos() { t.SelectedItem = "" @@ -147,6 +147,8 @@ func (t *Table) Bottom() { t.calcPos() } +// The number of lines in a page is equal to the height of the widget. + func (t *Table) HalfPageUp() { t.SelectedRow = t.SelectedRow - (t.Y-2)/2 t.calcPos() |