Upgrade termui to v3

This commit is contained in:
Caleb Bassi 2019-03-07 23:15:41 -08:00
parent 71e10bb6be
commit 96535ccadd
43 changed files with 802 additions and 502 deletions

4
go.mod
View File

@ -5,14 +5,14 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distatus/battery v0.9.0
github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815
github.com/gizak/termui v0.0.0-20190124041613-958a28575d74
github.com/gizak/termui/v3 v3.0.0
github.com/go-ole/go-ole v1.2.1 // indirect
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/nsf/termbox-go v0.0.0-20190104133558-0938b5187e61 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/shirou/gopsutil v2.18.11+incompatible
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
github.com/stretchr/testify v1.2.2 // indirect
golang.org/x/sys v0.0.0-20190116161447-11f53e031339 // indirect
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
)

18
go.sum
View File

@ -1,19 +1,17 @@
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd h1:XtfPmj9tQRilnrEmI1HjQhxXWRhEM+m8CACtaMJE/kM=
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd/go.mod h1:vjcQJUZJYD3MeVGhtZXSMnCHfUNZxsyYzJt90eCYxK4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distatus/battery v0.9.0 h1:8NS5o00/j3Oh2xgocA6pQROTp5guoR+s8CZlWzHC4QM=
github.com/distatus/battery v0.9.0/go.mod h1:gGO7GxHTi1zlRT+cAj8uGG0/8HFiqAeH0TJvoipnuPs=
github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815 h1:HMAfwOa33y82IaQEKQDfUCiwNlxtM1iw7HLM9ru0RNc=
github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:l7JNRynTRuqe45tpIyItHNqZWTxywYjp87MWTOnU5cg=
github.com/gizak/termui v0.0.0-20190124041613-958a28575d74 h1:gQbT+IgWIflxp7EQaxWGgGoHAxEFzvP36DyxiBGEV9g=
github.com/gizak/termui v0.0.0-20190124041613-958a28575d74/go.mod h1:hJmkzz29zwvMdxina9wLc5fWN7bZuougH5YR93VrJtA=
github.com/gizak/termui/v3 v3.0.0 h1:NYTUG6ig/sJK05O5FyhWemwlVPO8ilNpvS/PgRtrKAE=
github.com/gizak/termui/v3 v3.0.0/go.mod h1:uinu2dMdtMI+FTIdEFUJQT5y+KShnhQRshvPblXq3lY=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163 h1:beB+Da4k9B1zmgag78k3k1Bx4L/fdWr5FwNa0f8RxmY=
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -26,10 +24,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzC
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb h1:YahEjAGkJtCrkqgVHhX6n8ZX+CZ3hDRL9fjLYugLfSs=
github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/nsf/termbox-go v0.0.0-20190104133558-0938b5187e61 h1:pEzZYac/uQ4cgaN1Q/UYZg+ZtCSWz2HQ3rvl8MeN9MA=
github.com/nsf/termbox-go v0.0.0-20190104133558-0938b5187e61/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shirou/gopsutil v2.18.11+incompatible h1:PMFTKnFTr/YTRW5rbLK4vWALV3a+IGXse5nvhSjztmg=
@ -40,8 +36,6 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc h1:F5tKCVGp+MUAHhKp5MZtGqAlGX3+oCsiL1Q629FL90M=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/sys v0.0.0-20190116161447-11f53e031339 h1:g/Jesu8+QLnA0CPzF3E1pURg0Byr7i6jLoX5sqjcAh0=
golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -15,7 +15,7 @@ import (
"time"
docopt "github.com/docopt/docopt.go"
ui "github.com/gizak/termui"
ui "github.com/gizak/termui/v3"
"github.com/cjbassi/gotop/colorschemes"
"github.com/cjbassi/gotop/src/logging"

View File

@ -5,7 +5,7 @@ import (
"sort"
drawille "github.com/cjbassi/gotop/src/termui/drawille-go"
. "github.com/gizak/termui"
. "github.com/gizak/termui/v3"
)
// LineGraph implements a line graph of data points.

View File

@ -4,7 +4,7 @@ import (
"image"
"log"
. "github.com/gizak/termui"
. "github.com/gizak/termui/v3"
)
// Sparkline is like: ▅▆▂▂▅▇▂▂▃▆▆▆▅▃. The data points should be non-negative integers.

View File

@ -5,7 +5,7 @@ import (
"log"
"strings"
. "github.com/gizak/termui"
. "github.com/gizak/termui/v3"
)
type Table struct {

View File

@ -4,7 +4,7 @@ import (
"image"
"strings"
ui "github.com/gizak/termui"
ui "github.com/gizak/termui/v3"
)
const KEYBINDS = `

View File

@ -6,7 +6,7 @@ import (
"os"
"time"
ui "github.com/gizak/termui"
ui "github.com/gizak/termui/v3"
)
type StatusBar struct {

View File

@ -7,7 +7,7 @@ import (
"sync"
"time"
ui "github.com/gizak/termui"
ui "github.com/gizak/termui/v3"
"github.com/cjbassi/gotop/src/utils"
)

21
vendor/github.com/cjbassi/drawille-go/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Caleb Bassi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

5
vendor/github.com/cjbassi/drawille-go/README.md generated vendored Normal file
View File

@ -0,0 +1,5 @@
# drawille-go
A [drawille](https://github.com/asciimoo/drawille) implementation in Go with a more permissive license.
Used in [termui](https://github.com/gizak/termui).

90
vendor/github.com/cjbassi/drawille-go/drawille.go generated vendored Normal file
View File

@ -0,0 +1,90 @@
package drawille
import (
"image"
)
const BRAILLE_OFFSET = '\u2800'
var BRAILLE = [4][2]rune{
{'\u0001', '\u0008'},
{'\u0002', '\u0010'},
{'\u0004', '\u0020'},
{'\u0040', '\u0080'},
}
type Color int
type Cell struct {
Rune rune
Color Color
}
type Canvas struct {
CellMap map[image.Point]Cell
}
func NewCanvas() *Canvas {
return &Canvas{
CellMap: make(map[image.Point]Cell),
}
}
func (self *Canvas) SetPoint(p image.Point, color Color) {
point := image.Pt(p.X/2, p.Y/4)
self.CellMap[point] = Cell{
self.CellMap[point].Rune | BRAILLE[p.Y%4][p.X%2],
color,
}
}
func (self *Canvas) SetLine(p0, p1 image.Point, color Color) {
for _, p := range line(p0, p1) {
self.SetPoint(p, color)
}
}
func (self *Canvas) GetCells() map[image.Point]Cell {
cellMap := make(map[image.Point]Cell)
for point, cell := range self.CellMap {
cellMap[point] = Cell{cell.Rune + BRAILLE_OFFSET, cell.Color}
}
return cellMap
}
func line(p0, p1 image.Point) []image.Point {
points := []image.Point{}
leftPoint, rightPoint := p0, p1
if leftPoint.X > rightPoint.X {
leftPoint, rightPoint = rightPoint, leftPoint
}
xDistance := absInt(leftPoint.X - rightPoint.X)
yDistance := absInt(leftPoint.Y - rightPoint.Y)
slope := float64(yDistance) / float64(xDistance)
slopeSign := 1
if rightPoint.Y < leftPoint.Y {
slopeSign = -1
}
targetYCoordinate := float64(leftPoint.Y)
currentYCoordinate := leftPoint.Y
for i := leftPoint.X; i < rightPoint.X; i++ {
points = append(points, image.Pt(i, currentYCoordinate))
targetYCoordinate += (slope * float64(slopeSign))
for currentYCoordinate != int(targetYCoordinate) {
points = append(points, image.Pt(i, currentYCoordinate))
currentYCoordinate += slopeSign
}
}
return points
}
func absInt(x int) int {
if x >= 0 {
return x
}
return -x
}

View File

@ -1,41 +0,0 @@
Feel free to search/open an issue if something is missing or confusing from the changelog, since many things have been in flux.
## TODO
- moved widgets to `github.com/gizak/termui/widgets`
- rewrote widgets (check examples and code)
- rewrote grid
- grids are instantiated locally instead of through `termui.Body`
- grids can be nested
- changed grid layout mechanism
- columns and rows can be arbitrarily nested
- column and row size is now specified as a ratio of the available space
- `Cell`s now contain a `Style` which holds a `Fg`, `Bg`, and `Modifier`
- Change `Bufferer` interface to `Drawable`
- Add `GetRect` and `SetRect` methods to control widget sizing
- Change `Buffer` method to `Draw`
- `Draw` takes a `Buffer` and draws to it instead of returning a new `Buffer`
- Refactored `Theme`
- `Theme` is now a large struct which holds the default `Styles` of everything
- Combined `TermWidth` and `TermHeight` functions into `TerminalDimensions`
- Added `Canvas` which allows for drawing braille lines to a `Buffer`
- Refactored `Block`
- Refactored `Buffer` methods
- Set `termbox-go` backend to 256 colors by default
- Decremented color numbers by 1 to match xterm colors
- Changed text parsing
- style items changed from `fg-color` to `fg:color`
- added mod item like `mod:reverse`
## 18/11/29
- Move Tabpane from termui/extra to termui and rename it to TabPane
- Rename PollEvent to PollEvents
## 18/11/28
- Migrated from Dep to vgo
- Overhauled the event system
- check the wiki/examples for details
- Renamed Par widget to Paragraph
- Renamed MBarChart widget to StackedBarChart

View File

@ -1,86 +0,0 @@
# termui
<img src="./_assets/dashboard1.gif" alt="demo cast under osx 10.10; Terminal.app; Menlo Regular 12pt.)" width="100%">
termui is a cross-platform and fully-customizable terminal dashboard and widget library built on top of [termbox-go](https://github.com/nsf/termbox-go). It is inspired by [blessed-contrib](https://github.com/yaronn/blessed-contrib) and written purely in Go.
## Installation
Installing from the master branch is recommended:
```bash
go get -u github.com/gizak/termui@master
```
**Note**: termui is currently undergoing API changes so make sure to check the changelog when upgrading.
If you upgrade and notice something is missing or don't like a change, revert the upgrade and open an issue.
## Usage
### Hello World
```go
package main
import (
"log"
ui "github.com/gizak/termui"
"github.com/gizak/termui/widgets"
)
func main() {
if err := ui.Init(); err != nil {
log.Fatalf("failed to initialize termui: %v", err)
}
defer ui.Close()
p := widgets.NewParagraph()
p.Text = "Hello World!"
p.SetRect(0, 0, 25, 5)
ui.Render(p)
for e := range ui.PollEvents() {
if e.Type == ui.KeyboardEvent {
break
}
}
}
```
### Widgets
Click image to see the corresponding demo codes.
[<img src="./_assets/barchart.png" alt="barchart" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/barchart.go)
[<img src="./_assets/gauge.png" alt="gauge" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/gauge.go)
[<img src="./_assets/linechart.png" alt="linechart" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/linechart.go)
[<img src="./_assets/list.png" alt="list" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/list.go)
[<img src="./_assets/paragraph.png" alt="paragraph" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/paragraph.go)
[<img src="./_assets/sparkline.png" alt="sparkline" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/sparkline.go)
[<img src="./_assets/stacked_barchart.png" alt="stacked_barchart" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/stacked_barchart.go)
[<img src="./_assets/table.png" alt="table" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_examples/table.go)
### Examples
Examples can be found in [\_examples](./_examples). Run an example with `go run _examples/{example}.go` or run all of them consecutively with `make run-examples`.
### Documentation
- [wiki](https://github.com/gizak/termui/wiki)
## Uses
- [cjbassi/gotop](https://github.com/cjbassi/gotop)
- [go-ethereum/monitorcmd](https://github.com/ethereum/go-ethereum/blob/96116758d22ddbff4dbef2050d6b63a7b74502d8/cmd/geth/monitorcmd.go)
## Related Works
- [blessed-contrib](https://github.com/yaronn/blessed-contrib)
- [tui-rs](https://github.com/fdehau/tui-rs)
- [gocui](https://github.com/jroimartin/gocui)
## License
[MIT](http://opensource.org/licenses/MIT)

View File

@ -1,63 +0,0 @@
package termui
import (
"image"
)
type Canvas struct {
CellMap map[image.Point]Cell
Block
}
func NewCanvas() *Canvas {
return &Canvas{
Block: *NewBlock(),
CellMap: make(map[image.Point]Cell),
}
}
// points given as arguments correspond to dots within a braille character
// and therefore have 2x4 times the resolution of a normal cell
func (self *Canvas) Line(p0, p1 image.Point, color Color) {
leftPoint, rightPoint := p0, p1
if leftPoint.X > rightPoint.X {
leftPoint, rightPoint = rightPoint, leftPoint
}
xDistance := AbsInt(leftPoint.X - rightPoint.X)
yDistance := AbsInt(leftPoint.Y - rightPoint.Y)
slope := float64(yDistance) / float64(xDistance)
slopeDirection := 1
if rightPoint.Y < leftPoint.Y {
slopeDirection = -1
}
targetYCoordinate := float64(leftPoint.Y)
currentYCoordinate := leftPoint.Y
for i := leftPoint.X; i < rightPoint.X; i++ {
targetYCoordinate += (slope * float64(slopeDirection))
if currentYCoordinate == int(targetYCoordinate) {
point := image.Pt(i/2, currentYCoordinate/4)
self.CellMap[point] = Cell{
self.CellMap[point].Rune | BRAILLE[currentYCoordinate%4][i%2],
NewStyle(color),
}
}
for currentYCoordinate != int(targetYCoordinate) {
point := image.Pt(i/2, currentYCoordinate/4)
self.CellMap[point] = Cell{
self.CellMap[point].Rune | BRAILLE[currentYCoordinate%4][i%2],
NewStyle(color),
}
currentYCoordinate += slopeDirection
}
}
}
func (self *Canvas) Draw(buf *Buffer) {
for point, cell := range self.CellMap {
if point.In(self.Rectangle) {
buf.SetCell(Cell{cell.Rune + BRAILLE_OFFSET, cell.Style}, point)
}
}
}

View File

@ -1,175 +0,0 @@
// Copyright 2017 Zack Guo <zack.y.guo@gmail.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
package termui
import (
"strconv"
tb "github.com/nsf/termbox-go"
)
/*
List of events:
mouse events:
<MouseLeft> <MouseRight> <MouseMiddle>
<MouseWheelUp> <MouseWheelDown>
keyboard events:
any uppercase or lowercase letter like j or J
<C-d> etc
<M-d> etc
<Up> <Down> <Left> <Right>
<Insert> <Delete> <Home> <End> <Previous> <Next>
<Backspace> <Tab> <Enter> <Escape> <Space>
<C-<Space>> etc
terminal events:
<Resize>
*/
type EventType int
const (
KeyboardEvent EventType = iota
MouseEvent
ResizeEvent
)
type Event struct {
Type EventType
ID string
Payload interface{}
}
// Mouse payload.
type Mouse struct {
Drag bool
X int
Y int
}
// Resize payload.
type Resize struct {
Width int
Height int
}
// PollEvents gets events from termbox, converts them, then sends them to each of its channels.
func PollEvents() <-chan Event {
ch := make(chan Event)
go func() {
for {
ch <- convertTermboxEvent(tb.PollEvent())
}
}()
return ch
}
// convertTermboxKeyboardEvent converts a termbox keyboard event to a more friendly string format.
// Combines modifiers into the string instead of having them as additional fields in an event.
func convertTermboxKeyboardEvent(e tb.Event) Event {
k := string(e.Ch)
pre := ""
mod := ""
if e.Mod == tb.ModAlt {
mod = "<M-"
}
if e.Ch == 0 {
if e.Key > 0xFFFF-12 {
k = "<f" + strconv.Itoa(0xFFFF-int(e.Key)+1) + ">"
} else if e.Key > 0xFFFF-25 {
ks := []string{"<Insert>", "<Delete>", "<Home>", "<End>", "<Previous>", "<Next>", "<Up>", "<Down>", "<Left>", "<Right>"}
k = ks[0xFFFF-int(e.Key)-12]
}
if e.Key <= 0x7F {
pre = "<C-"
k = string('a' - 1 + int(e.Key))
kmap := map[tb.Key][2]string{
tb.KeyCtrlSpace: {"C-", "<Space>"},
tb.KeyBackspace: {"", "<Backspace>"},
tb.KeyTab: {"", "<Tab>"},
tb.KeyEnter: {"", "<Enter>"},
tb.KeyEsc: {"", "<Escape>"},
tb.KeyCtrlBackslash: {"C-", "\\"},
tb.KeyCtrlSlash: {"C-", "/"},
tb.KeySpace: {"", "<Space>"},
tb.KeyCtrl8: {"C-", "8"},
}
if sk, ok := kmap[e.Key]; ok {
pre = sk[0]
k = sk[1]
}
}
}
if pre != "" {
k += ">"
}
id := pre + mod + k
return Event{
Type: KeyboardEvent,
ID: id,
}
}
func convertTermboxMouseEvent(e tb.Event) Event {
mouseButtonMap := map[tb.Key]string{
tb.MouseLeft: "<MouseLeft>",
tb.MouseMiddle: "<MouseMiddle>",
tb.MouseRight: "<MouseRight>",
tb.MouseRelease: "<MouseRelease>",
tb.MouseWheelUp: "<MouseWheelUp>",
tb.MouseWheelDown: "<MouseWheelDown>",
}
converted, ok := mouseButtonMap[e.Key]
if !ok {
converted = "Unknown_Mouse_Button"
}
Drag := false
if e.Mod == tb.ModMotion {
Drag = true
}
return Event{
Type: MouseEvent,
ID: converted,
Payload: Mouse{
X: e.MouseX,
Y: e.MouseY,
Drag: Drag,
},
}
}
// convertTermboxEvent turns a termbox event into a termui event.
func convertTermboxEvent(e tb.Event) Event {
if e.Type == tb.EventError {
panic(e.Err)
}
var event Event
switch e.Type {
case tb.EventKey:
event = convertTermboxKeyboardEvent(e)
case tb.EventMouse:
event = convertTermboxMouseEvent(e)
case tb.EventResize:
event = Event{
Type: ResizeEvent,
ID: "<Resize>",
Payload: Resize{
Width: e.Width,
Height: e.Height,
},
}
}
return event
}

View File

@ -1,12 +0,0 @@
module github.com/gizak/termui
require (
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163 // indirect
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 // indirect
github.com/mattn/go-runewidth v0.0.2
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7
github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc // indirect
golang.org/x/sys v0.0.0-20190116161447-11f53e031339 // indirect
)

View File

@ -1,16 +0,0 @@
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163 h1:beB+Da4k9B1zmgag78k3k1Bx4L/fdWr5FwNa0f8RxmY=
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb h1:YahEjAGkJtCrkqgVHhX6n8ZX+CZ3hDRL9fjLYugLfSs=
github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc h1:F5tKCVGp+MUAHhKp5MZtGqAlGX3+oCsiL1Q629FL90M=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/sys v0.0.0-20190116161447-11f53e031339 h1:g/Jesu8+QLnA0CPzF3E1pURg0Byr7i6jLoX5sqjcAh0=
golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

121
vendor/github.com/gizak/termui/v3/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,121 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [3.0.0] - 2019/03/07
### Changed
- Added sync.Locker interface to Drawable interface
## 2019/03/01
### Changed
- Change scroll method names in List widget
### Fixed
- Fix List widget scrolling
## 2019/02/28
### Added
- Add `ColumnResizer` to table which allows for custom column sizing
- Add widget padding
### Changed
- Change various widget field names
- s/`TextParse`/`ParseStyles`
- Remove `AddColorMap` in place of modifying `StyleParserColorMap` directly
## 2019/01/31
### Added
- Add more scrolling options to List
### Changed
- Make list scroll automatically
### Added
## 2019/01/26
### Added
- Add scrolling to List widget
- Add WrapText option to Paragraph
- controls if text should wrap automatically
## 2019/01/24
### Added
- Add image widget [#126]
### Changed
- Change LineChart to Plot
- Added ScatterPlot mode which plots points instead of lines between points
## 2019/01/23
### Added
- Add `Canvas` which allows for drawing braille lines to a `Buffer`
### Changed
- Set `termbox-go` backend to 256 colors by default
- Moved widgets to `github.com/gizak/termui/widgets`
- Rewrote widgets (check examples and code)
- Rewrote grid
- grids are instantiated locally instead of through `termui.Body`
- grids can be nested
- change grid layout mechanism
- columns and rows can be arbitrarily nested
- column and row size is now specified as a ratio of the available space
- `Cell`s now contain a `Style` which holds a `Fg`, `Bg`, and `Modifier`
- Change `Bufferer` interface to `Drawable`
- Add `GetRect` and `SetRect` methods to control widget sizing
- Change `Buffer` method to `Draw`
- `Draw` takes a `Buffer` and draws to it instead of returning a new `Buffer`
- Refactor `Theme`
- `Theme` is now a large struct which holds the default `Styles` of everything
- Combine `TermWidth` and `TermHeight` functions into `TerminalDimensions`
- Rework `Block`
- Rework `Buffer` methods
- Decremente color numbers by 1 to match xterm colors
- Change text parsing
- change style items from `fg-color` to `fg:color`
- adde mod item like `mod:reverse`
## 2018/11/29
### Changed
- Move Tabpane from termui/extra to termui and rename it to TabPane
- Rename PollEvent to PollEvents
## 2018/11/28
### Changed
- Migrate from Dep to vgo
- Overhaul the event system
- check the wiki/examples for details
- Rename Par widget to Paragraph
- Rename MBarChart widget to StackedBarChart
[#126]: https://github.com/gizak/termui/pull/126
[Unreleased]: https://github.com/gizak/termui/compare/v3.0.0...HEAD
[3.0.0]: https://github.com/gizak/termui/compare/v2.3.0...HEAD

93
vendor/github.com/gizak/termui/v3/README.md generated vendored Normal file
View File

@ -0,0 +1,93 @@
# termui
[<img src="./_assets/demo.gif" alt="demo cast under osx 10.10; Terminal.app; Menlo Regular 12pt.)" width="100%">](./_examples/demo.go)
termui is a cross-platform and fully-customizable terminal dashboard and widget library built on top of [termbox-go](https://github.com/nsf/termbox-go). It is inspired by [blessed-contrib](https://github.com/yaronn/blessed-contrib) and [tui-rs](https://github.com/fdehau/tui-rs) and written purely in Go.
## Features
- Several premade widgets for common use cases
- Easily create custom widgets
- Position widgets either in a relative grid or with absolute coordinates
- Keyboard, mouse, and terminal resizing events
- Colors and styling
## Installation
```bash
go get github.com/gizak/termui/v3
```
## Hello World
```go
package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
)
func main() {
if err := ui.Init(); err != nil {
log.Fatalf("failed to initialize termui: %v", err)
}
defer ui.Close()
p := widgets.NewParagraph()
p.Text = "Hello World!"
p.SetRect(0, 0, 25, 5)
ui.Render(p)
for e := range ui.PollEvents() {
if e.Type == ui.KeyboardEvent {
break
}
}
}
```
## Widgets
- [BarChart](./_examples/barchart.go)
- [Canvas](./_examples/canvas.go) (for drawing braille dots)
- [Gauge](./_examples/gauge.go)
- [Image](./_examples/image.go)
- [List](./_examples/list.go)
- [Paragraph](./_examples/paragraph.go)
- [PieChart](./_examples/piechart.go)
- [Plot](./_examples/plot.go) (for scatterplots and linecharts)
- [Sparkline](./_examples/sparkline.go)
- [StackedBarChart](./_examples/stacked_barchart.go)
- [Table](./_examples/table.go)
- [Tabs](./_examples/tabs.go)
Run an example with `go run _examples/{example}.go` or run each example consecutively with `make run-examples`.
## Documentation
- [wiki](https://github.com/gizak/termui/wiki)
## Uses
- [dockdash](https://github.com/byrnedo/dockdash)
- [expvarmon](https://github.com/divan/expvarmon)
- [go-ethereum/monitorcmd](https://github.com/ethereum/go-ethereum/blob/master/cmd/geth/monitorcmd.go)
- [go-jira-ui](https://github.com/mikepea/go-jira-ui)
- [gotop](https://github.com/cjbassi/gotop)
- [termeter](https://github.com/atsaki/termeter)
## Related Works
- [blessed-contrib](https://github.com/yaronn/blessed-contrib)
- [gocui](https://github.com/jroimartin/gocui)
- [termdash](https://github.com/mum4k/termdash)
- [tui-rs](https://github.com/fdehau/tui-rs)
- [tview](https://github.com/rivo/tview)
## License
[MIT](http://opensource.org/licenses/MIT)

View File

@ -6,24 +6,28 @@ package termui
import (
"image"
"sync"
)
// Block is the base struct inherited by all widgets.
// Block manages size, border, and title.
// It implements 2 of the 3 methods needed for `Drawable` interface: `GetRect` and `SetRect`.
// Block is the base struct inherited by most widgets.
// Block manages size, position, border, and title.
// It implements all 3 of the methods needed for the `Drawable` interface.
// Custom widgets will override the Draw method.
type Block struct {
Border bool
BorderStyle Style
BorderLeft bool
BorderRight bool
BorderTop bool
BorderBottom bool
Border bool
BorderStyle Style
BorderLeft, BorderRight, BorderTop, BorderBottom bool
PaddingLeft, PaddingRight, PaddingTop, PaddingBottom int
image.Rectangle
Inner image.Rectangle
Title string
TitleStyle Style
sync.Mutex
}
func NewBlock() *Block {
@ -40,10 +44,6 @@ func NewBlock() *Block {
}
func (self *Block) drawBorder(buf *Buffer) {
if !self.Border {
return
}
verticalCell := Cell{VERTICAL_LINE, self.BorderStyle}
horizontalCell := Cell{HORIZONTAL_LINE, self.BorderStyle}
@ -76,8 +76,11 @@ func (self *Block) drawBorder(buf *Buffer) {
}
}
// Draw implements the Drawable interface.
func (self *Block) Draw(buf *Buffer) {
self.drawBorder(buf)
if self.Border {
self.drawBorder(buf)
}
buf.SetString(
self.Title,
self.TitleStyle,
@ -85,11 +88,18 @@ func (self *Block) Draw(buf *Buffer) {
)
}
// SetRect implements the Drawable interface.
func (self *Block) SetRect(x1, y1, x2, y2 int) {
self.Rectangle = image.Rect(x1, y1, x2, y2)
self.Inner = image.Rect(self.Min.X+1, self.Min.Y+1, self.Max.X-1, self.Max.Y-1)
self.Inner = image.Rect(
self.Min.X+1+self.PaddingLeft,
self.Min.Y+1+self.PaddingTop,
self.Max.X-1-self.PaddingRight,
self.Max.Y-1-self.PaddingBottom,
)
}
// GetRect implements the Drawable interface.
func (self *Block) GetRect() image.Rectangle {
return self.Rectangle
}

View File

@ -6,6 +6,8 @@ package termui
import (
"image"
rw "github.com/mattn/go-runewidth"
)
// Cell represents a viewable terminal cell
@ -65,7 +67,10 @@ func (self *Buffer) Fill(c Cell, rect image.Rectangle) {
}
func (self *Buffer) SetString(s string, style Style, p image.Point) {
for i, char := range s {
self.SetCell(Cell{char, style}, image.Pt(p.X+i, p.Y))
runes := []rune(s)
x := 0
for _, char := range runes {
self.SetCell(Cell{char, style}, image.Pt(p.X+x, p.Y))
x += rw.RuneWidth(char)
}
}

43
vendor/github.com/gizak/termui/v3/canvas.go generated vendored Normal file
View File

@ -0,0 +1,43 @@
package termui
import (
"image"
drawille "github.com/cjbassi/drawille-go"
)
type Canvas struct {
Block
drawille.Canvas
}
func NewCanvas() *Canvas {
return &Canvas{
Block: *NewBlock(),
Canvas: *drawille.NewCanvas(),
}
}
func (self *Canvas) SetPoint(p image.Point, color Color) {
self.Canvas.SetPoint(p, drawille.Color(color))
}
func (self *Canvas) SetLine(p0, p1 image.Point, color Color) {
self.Canvas.SetLine(p0, p1, drawille.Color(color))
}
func (self *Canvas) Draw(buf *Buffer) {
for point, cell := range self.Canvas.GetCells() {
if point.In(self.Rectangle) {
convertedCell := Cell{
cell.Rune,
Style{
Color(cell.Color),
ColorClear,
ModifierClear,
},
}
buf.SetCell(convertedCell, point)
}
}
}

211
vendor/github.com/gizak/termui/v3/events.go generated vendored Normal file
View File

@ -0,0 +1,211 @@
// Copyright 2017 Zack Guo <zack.y.guo@gmail.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
package termui
import (
"fmt"
tb "github.com/nsf/termbox-go"
)
/*
List of events:
mouse events:
<MouseLeft> <MouseRight> <MouseMiddle>
<MouseWheelUp> <MouseWheelDown>
keyboard events:
any uppercase or lowercase letter like j or J
<C-d> etc
<M-d> etc
<Up> <Down> <Left> <Right>
<Insert> <Delete> <Home> <End> <Previous> <Next>
<Backspace> <Tab> <Enter> <Escape> <Space>
<C-<Space>> etc
terminal events:
<Resize>
keyboard events that do not work:
<C-->
<C-2> <C-~>
<C-h>
<C-i>
<C-m>
<C-[> <C-3>
<C-\\>
<C-]>
<C-/> <C-_>
<C-8>
*/
type EventType uint
const (
KeyboardEvent EventType = iota
MouseEvent
ResizeEvent
)
type Event struct {
Type EventType
ID string
Payload interface{}
}
// Mouse payload.
type Mouse struct {
Drag bool
X int
Y int
}
// Resize payload.
type Resize struct {
Width int
Height int
}
// PollEvents gets events from termbox, converts them, then sends them to each of its channels.
func PollEvents() <-chan Event {
ch := make(chan Event)
go func() {
for {
ch <- convertTermboxEvent(tb.PollEvent())
}
}()
return ch
}
var keyboardMap = map[tb.Key]string{
tb.KeyF1: "<F1>",
tb.KeyF2: "<F2>",
tb.KeyF3: "<F3>",
tb.KeyF4: "<F4>",
tb.KeyF5: "<F5>",
tb.KeyF6: "<F6>",
tb.KeyF7: "<F7>",
tb.KeyF8: "<F8>",
tb.KeyF9: "<F9>",
tb.KeyF10: "<F10>",
tb.KeyF11: "<F11>",
tb.KeyF12: "<F12>",
tb.KeyInsert: "<Insert>",
tb.KeyDelete: "<Delete>",
tb.KeyHome: "<Home>",
tb.KeyEnd: "<End>",
tb.KeyPgup: "<PageUp>",
tb.KeyPgdn: "<PageDown>",
tb.KeyArrowUp: "<Up>",
tb.KeyArrowDown: "<Down>",
tb.KeyArrowLeft: "<Left>",
tb.KeyArrowRight: "<Right>",
tb.KeyCtrlSpace: "<C-<Space>>", // tb.KeyCtrl2 tb.KeyCtrlTilde
tb.KeyCtrlA: "<C-a>",
tb.KeyCtrlB: "<C-b>",
tb.KeyCtrlC: "<C-c>",
tb.KeyCtrlD: "<C-d>",
tb.KeyCtrlE: "<C-e>",
tb.KeyCtrlF: "<C-f>",
tb.KeyCtrlG: "<C-g>",
tb.KeyBackspace: "<C-<Backspace>>", // tb.KeyCtrlH
tb.KeyTab: "<Tab>", // tb.KeyCtrlI
tb.KeyCtrlJ: "<C-j>",
tb.KeyCtrlK: "<C-k>",
tb.KeyCtrlL: "<C-l>",
tb.KeyEnter: "<Enter>", // tb.KeyCtrlM
tb.KeyCtrlN: "<C-n>",
tb.KeyCtrlO: "<C-o>",
tb.KeyCtrlP: "<C-p>",
tb.KeyCtrlQ: "<C-q>",
tb.KeyCtrlR: "<C-r>",
tb.KeyCtrlS: "<C-s>",
tb.KeyCtrlT: "<C-t>",
tb.KeyCtrlU: "<C-u>",
tb.KeyCtrlV: "<C-v>",
tb.KeyCtrlW: "<C-w>",
tb.KeyCtrlX: "<C-x>",
tb.KeyCtrlY: "<C-y>",
tb.KeyCtrlZ: "<C-z>",
tb.KeyEsc: "<Escape>", // tb.KeyCtrlLsqBracket tb.KeyCtrl3
tb.KeyCtrl4: "<C-4>", // tb.KeyCtrlBackslash
tb.KeyCtrl5: "<C-5>", // tb.KeyCtrlRsqBracket
tb.KeyCtrl6: "<C-6>",
tb.KeyCtrl7: "<C-7>", // tb.KeyCtrlSlash tb.KeyCtrlUnderscore
tb.KeySpace: "<Space>",
tb.KeyBackspace2: "<Backspace>", // tb.KeyCtrl8:
}
// convertTermboxKeyboardEvent converts a termbox keyboard event to a more friendly string format.
// Combines modifiers into the string instead of having them as additional fields in an event.
func convertTermboxKeyboardEvent(e tb.Event) Event {
ID := "%s"
if e.Mod == tb.ModAlt {
ID = "<M-%s>"
}
if e.Ch != 0 {
ID = fmt.Sprintf(ID, string(e.Ch))
} else {
converted, ok := keyboardMap[e.Key]
if !ok {
converted = ""
}
ID = fmt.Sprintf(ID, converted)
}
return Event{
Type: KeyboardEvent,
ID: ID,
}
}
var mouseButtonMap = map[tb.Key]string{
tb.MouseLeft: "<MouseLeft>",
tb.MouseMiddle: "<MouseMiddle>",
tb.MouseRight: "<MouseRight>",
tb.MouseRelease: "<MouseRelease>",
tb.MouseWheelUp: "<MouseWheelUp>",
tb.MouseWheelDown: "<MouseWheelDown>",
}
func convertTermboxMouseEvent(e tb.Event) Event {
converted, ok := mouseButtonMap[e.Key]
if !ok {
converted = "Unknown_Mouse_Button"
}
Drag := e.Mod == tb.ModMotion
return Event{
Type: MouseEvent,
ID: converted,
Payload: Mouse{
X: e.MouseX,
Y: e.MouseY,
Drag: Drag,
},
}
}
// convertTermboxEvent turns a termbox event into a termui event.
func convertTermboxEvent(e tb.Event) Event {
if e.Type == tb.EventError {
panic(e.Err)
}
switch e.Type {
case tb.EventKey:
return convertTermboxKeyboardEvent(e)
case tb.EventMouse:
return convertTermboxMouseEvent(e)
case tb.EventResize:
return Event{
Type: ResizeEvent,
ID: "<Resize>",
Payload: Resize{
Width: e.Width,
Height: e.Height,
},
}
}
return Event{}
}

9
vendor/github.com/gizak/termui/v3/go.mod generated vendored Normal file
View File

@ -0,0 +1,9 @@
module github.com/gizak/termui/v3
require (
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd
github.com/mattn/go-runewidth v0.0.2
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect
)

10
vendor/github.com/gizak/termui/v3/go.sum generated vendored Normal file
View File

@ -0,0 +1,10 @@
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd h1:XtfPmj9tQRilnrEmI1HjQhxXWRhEM+m8CACtaMJE/kM=
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd/go.mod h1:vjcQJUZJYD3MeVGhtZXSMnCHfUNZxsyYzJt90eCYxK4=
github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=

View File

@ -16,7 +16,8 @@ type Grid struct {
Items []*GridItem
}
// GridItem represents either a Row or Column in a grid and holds sizing information and other GridItems or widgets
// GridItem represents either a Row or Column in a grid.
// Holds sizing information and either an []GridItems or a widget.
type GridItem struct {
Type gridItemType
XRatio float64
@ -152,6 +153,8 @@ func (self *Grid) Draw(buf *Buffer) {
entry.SetRect(x, y, x+w, y+h)
entry.Lock()
entry.Draw(buf)
entry.Unlock()
}
}

View File

@ -6,6 +6,7 @@ package termui
import (
"image"
"sync"
tb "github.com/nsf/termbox-go"
)
@ -14,12 +15,15 @@ type Drawable interface {
GetRect() image.Rectangle
SetRect(int, int, int, int)
Draw(*Buffer)
sync.Locker
}
func Render(items ...Drawable) {
for _, item := range items {
buf := NewBuffer(item.GetRect())
item.Lock()
item.Draw(buf)
item.Unlock()
for point, cell := range buf.CellMap {
if point.In(buf.Rectangle) {
tb.SetCell(

View File

@ -1,11 +1,15 @@
package termui
// Color is an integer from -1 to 255
// -1 = ColorClear
// 0-255 = Xterm colors
type Color int
// ColorClear clears the Fg or Bg color of a Style
const ColorClear Color = -1
// Basic terminal colors
const (
ColorClear Color = -1
ColorBlack Color = 0
ColorRed Color = 1
ColorGreen Color = 2
@ -19,26 +23,28 @@ const (
type Modifier uint
const (
// ModifierClear clears any modifiers
ModifierClear Modifier = 0
ModifierBold Modifier = 1 << 9
ModifierUnderline Modifier = 1 << 10
ModifierReverse Modifier = 1 << 11
)
// Style represents the look of the text of one terminal cell
// Style represents the style of one terminal cell
type Style struct {
Fg Color
Bg Color
Modifier Modifier
}
// StyleClear represents a default Style, with no colors or modifiers
var StyleClear = Style{
Fg: ColorClear,
Bg: ColorClear,
Modifier: ModifierClear,
}
// NewStyle takes 1 to 3 arguments.
// NewStyle takes 1 to 3 arguments
// 1st argument = Fg
// 2nd argument = optional Bg
// 3rd argument = optional Modifier

View File

@ -31,7 +31,8 @@ const (
parserStateStyledText
)
var colorMap = map[string]Color{
// StyleParserColorMap can be modified to add custom color parsing to text
var StyleParserColorMap = map[string]Color{
"red": ColorRed,
"blue": ColorBlue,
"black": ColorBlack,
@ -49,11 +50,6 @@ var modifierMap = map[string]Modifier{
"reverse": ModifierReverse,
}
// AddColorMap allows users to add/override the string to Coloribute mapping
func AddColorMap(str string, color Color) {
colorMap[str] = color
}
// readStyle translates an []rune like `fg:red,mod:bold,bg:white` to a style
func readStyle(runes []rune, defaultStyle Style) Style {
style := defaultStyle
@ -63,9 +59,9 @@ func readStyle(runes []rune, defaultStyle Style) Style {
if len(pair) == 2 {
switch pair[0] {
case tokenFg:
style.Fg = colorMap[pair[1]]
style.Fg = StyleParserColorMap[pair[1]]
case tokenBg:
style.Bg = colorMap[pair[1]]
style.Bg = StyleParserColorMap[pair[1]]
case tokenModifier:
style.Modifier = modifierMap[pair[1]]
}
@ -74,7 +70,11 @@ func readStyle(runes []rune, defaultStyle Style) Style {
return style
}
func ParseText(s string, defaultStyle Style) []Cell {
// ParseStyles parses a string for embedded Styles and returns []Cell with the correct styling.
// Uses defaultStyle for any text without an embedded style.
// Syntax is of the form [text](fg:<color>,mod:<attribute>,bg:<color>).
// Ordering does not matter. All fields are optional.
func ParseStyles(s string, defaultStyle Style) []Cell {
cells := []Cell{}
runes := []rune(s)
state := parserStateDefault

View File

@ -1,13 +1,22 @@
package termui
const (
SHADED_BLOCK = '░'
DOT = '•'
DOTS = '…'
DOT = '•'
ELLIPSES = '…'
UP_ARROW = '▲'
DOWN_ARROW = '▼'
)
var (
BARS = []rune{'▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'}
BARS = [...]rune{' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'}
SHADED_BLOCKS = [...]rune{' ', '░', '▒', '▓', '█'}
IRREGULAR_BLOCKS = [...]rune{
' ', '▘', '▝', '▀', '▖', '▌', '▞', '▛',
'▗', '▚', '▐', '▜', '▄', '▙', '▟', '█',
}
BRAILLE_OFFSET = '\u2800'
BRAILLE = [4][2]rune{

View File

@ -31,7 +31,7 @@ type RootTheme struct {
BarChart BarChartTheme
Gauge GaugeTheme
LineChart LineChartTheme
Plot PlotTheme
List ListTheme
Paragraph ParagraphTheme
PieChart PieChartTheme
@ -57,7 +57,7 @@ type GaugeTheme struct {
Label Style
}
type LineChartTheme struct {
type PlotTheme struct {
Lines []Color
Axes Color
}
@ -94,6 +94,8 @@ type TableTheme struct {
Text Style
}
// Theme holds the default Styles and Colors for all widgets.
// You can set default widget Styles by modifying the Theme before creating the widgets.
var Theme = RootTheme{
Default: NewStyle(ColorWhite),
@ -132,13 +134,13 @@ var Theme = RootTheme{
},
Sparkline: SparklineTheme{
Line: ColorBlack,
Title: NewStyle(ColorBlue),
Title: NewStyle(ColorWhite),
Line: ColorWhite,
},
LineChart: LineChartTheme{
Plot: PlotTheme{
Lines: StandardColors,
Axes: ColorBlue,
Axes: ColorWhite,
},
Table: TableTheme{

View File

@ -13,6 +13,7 @@ import (
wordwrap "github.com/mitchellh/go-wordwrap"
)
// InterfaceSlice takes an []interface{} represented as an interface{} and converts it
// https://stackoverflow.com/questions/12753805/type-converting-slices-of-interfaces-in-go
func InterfaceSlice(slice interface{}) []interface{} {
s := reflect.ValueOf(slice)
@ -29,30 +30,43 @@ func InterfaceSlice(slice interface{}) []interface{} {
return ret
}
func MaxInt(x, y int) int {
if x > y {
return x
}
return y
}
func MinInt(x, y int) int {
if x < y {
return x
}
return y
}
// TrimString trims a string to a max length and adds '…' to the end if it was trimmed.
func TrimString(s string, w int) string {
if w <= 0 {
return ""
}
if rw.StringWidth(s) > w {
return rw.Truncate(s, w, string(DOTS))
return rw.Truncate(s, w, string(ELLIPSES))
}
return s
}
func SelectColor(colors []Color, index int) Color {
return colors[index%len(colors)]
}
func SelectStyle(styles []Style, index int) Style {
return styles[index%len(styles)]
}
// Math ------------------------------------------------------------------------
func SumIntSlice(slice []int) int {
sum := 0
for _, val := range slice {
sum += val
}
return sum
}
func SumFloat64Slice(data []float64) float64 {
sum := 0.0
for _, v := range data {
sum += v
}
return sum
}
func GetMaxIntFromSlice(slice []int) (int, error) {
if len(slice) == 0 {
return 0, fmt.Errorf("cannot get max value from empty slice")
@ -94,40 +108,12 @@ func GetMaxFloat64From2dSlice(slices [][]float64) (float64, error) {
return max, nil
}
func SelectColor(colors []Color, index int) Color {
return colors[index%len(colors)]
}
func SelectStyle(styles []Style, index int) Style {
return styles[index%len(styles)]
}
func CellsToString(cells []Cell) string {
runes := make([]rune, len(cells))
for i, cell := range cells {
runes[i] = cell.Rune
}
return string(runes)
}
func RoundFloat64(x float64) float64 {
return math.Floor(x + 0.5)
}
func SumIntSlice(slice []int) int {
sum := 0
for _, val := range slice {
sum += val
}
return sum
}
func SumFloat64Slice(data []float64) float64 {
sum := 0.0
for _, v := range data {
sum += v
}
return sum
func FloorFloat64(x float64) float64 {
return math.Floor(x)
}
func AbsInt(x int) int {
@ -151,6 +137,23 @@ func MaxFloat64(x, y float64) float64 {
return y
}
func MaxInt(x, y int) int {
if x > y {
return x
}
return y
}
func MinInt(x, y int) int {
if x < y {
return x
}
return y
}
// []Cell ----------------------------------------------------------------------
// WrapCells takes []Cell and inserts Cells containing '\n' wherever a linebreak should go.
func WrapCells(cells []Cell, width uint) []Cell {
str := CellsToString(cells)
wrapped := wordwrap.WrapString(str, width)
@ -174,3 +177,54 @@ func RunesToStyledCells(runes []rune, style Style) []Cell {
}
return cells
}
func CellsToString(cells []Cell) string {
runes := make([]rune, len(cells))
for i, cell := range cells {
runes[i] = cell.Rune
}
return string(runes)
}
func TrimCells(cells []Cell, w int) []Cell {
s := CellsToString(cells)
s = TrimString(s, w)
runes := []rune(s)
newCells := []Cell{}
for i, r := range runes {
newCells = append(newCells, Cell{r, cells[i].Style})
}
return newCells
}
func SplitCells(cells []Cell, r rune) [][]Cell {
splitCells := [][]Cell{}
temp := []Cell{}
for _, cell := range cells {
if cell.Rune == r {
splitCells = append(splitCells, temp)
temp = []Cell{}
} else {
temp = append(temp, cell)
}
}
if len(temp) > 0 {
splitCells = append(splitCells, temp)
}
return splitCells
}
type CellWithX struct {
X int
Cell Cell
}
func BuildCellWithXArray(cells []Cell) []CellWithX {
cellWithXArray := make([]CellWithX, len(cells))
index := 0
for i, cell := range cells {
cellWithXArray[i] = CellWithX{X: index, Cell: cell}
index += rw.RuneWidth(cell.Rune)
}
return cellWithXArray
}

View File

@ -17,6 +17,7 @@ There are also some interesting projects using termbox-go:
- [httopd](https://github.com/verdverm/httopd) is top for httpd logs.
- [mop](https://github.com/mop-tracker/mop) is stock market tracker for hackers.
- [termui](https://github.com/gizak/termui) is a terminal dashboard.
- [termdash](https://github.com/mum4k/termdash) is a terminal dashboard.
- [termloop](https://github.com/JoelOtter/termloop) is a terminal game engine.
- [xterm-color-chart](https://github.com/kutuluk/xterm-color-chart) is a XTerm 256 color chart.
- [gocui](https://github.com/jroimartin/gocui) is a minimalist Go library aimed at creating console user interfaces.

8
vendor/modules.txt vendored
View File

@ -1,11 +1,13 @@
# github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6
github.com/StackExchange/wmi
# github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd
github.com/cjbassi/drawille-go
# github.com/distatus/battery v0.9.0
github.com/distatus/battery
# github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815
github.com/docopt/docopt.go
# github.com/gizak/termui v0.0.0-20190124041613-958a28575d74
github.com/gizak/termui
# github.com/gizak/termui/v3 v3.0.0
github.com/gizak/termui/v3
# github.com/go-ole/go-ole v1.2.1
github.com/go-ole/go-ole
github.com/go-ole/go-ole/oleutil
@ -13,7 +15,7 @@ github.com/go-ole/go-ole/oleutil
github.com/mattn/go-runewidth
# github.com/mitchellh/go-wordwrap v1.0.0
github.com/mitchellh/go-wordwrap
# github.com/nsf/termbox-go v0.0.0-20190104133558-0938b5187e61
# github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d
github.com/nsf/termbox-go
# github.com/shirou/gopsutil v2.18.11+incompatible
github.com/shirou/gopsutil/cpu