1
0
mirror of https://github.com/gizak/termui.git synced 2025-04-24 13:48:50 +08:00

Merge 3a1e439947a180830b93dbcb53d6a3d222533568 into 2b8f0c7960e9553acea6d579a740713066da5e13

This commit is contained in:
Michael-Andrew Keays 2024-10-21 18:13:42 +03:00 committed by GitHub
commit 6145fd834c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 106 additions and 65 deletions

View File

@ -1,12 +1,14 @@
# termui
This is [gizak's termui](https://github.com/gizak/termui) with minor alterations
[<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.
## Note
Please be aware that due to my fluctuating availability, the frequency of updates to this project may not always follow a consistent schedule. I would like to invite potential maintainers to contribute to this project. If you are interested in becoming a maintainer, please do not hesitate to reach out to me.
~Please be aware that due to my fluctuating availability, the frequency of updates to this project may not always follow a consistent schedule. I would like to invite potential maintainers to contribute to this project. If you are interested in becoming a maintainer, please do not hesitate to reach out to me.~
## Versions
@ -38,8 +40,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -1,3 +1,4 @@
//go:build ignore
// +build ignore
package main
@ -6,7 +7,7 @@ import (
"image"
"log"
ui "github.com/gizak/termui/v3"
ui "github.com/keaysma/termui/v3"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -11,8 +12,8 @@ import (
"math"
"time"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -10,8 +11,8 @@ import (
"fmt"
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -11,8 +12,8 @@ import (
"math"
"time"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -1,3 +1,4 @@
//go:build ignore
// +build ignore
package main
@ -5,8 +6,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -18,8 +19,8 @@ import (
"os"
"strings"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {
@ -22,7 +23,7 @@ func main() {
l := widgets.NewList()
l.Title = "List"
l.Rows = []string{
"[0] github.com/gizak/termui/v3",
"[0] github.com/keaysma/termui/v3",
"[1] [你好,世界](fg:blue)",
"[2] [こんにちは世界](fg:red)",
"[3] [color](fg:white,bg:green) output",

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -1,3 +1,4 @@
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ import (
"math/rand"
"time"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
var run = true

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -10,8 +11,8 @@ import (
"log"
"math"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -9,8 +10,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
func main() {

View File

@ -5,8 +5,8 @@ package main
import (
"log"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
ui "github.com/keaysma/termui/v3"
"github.com/keaysma/termui/v3/widgets"
)
type nodeValue string

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT license that can
// be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
@ -10,7 +11,7 @@ import (
"fmt"
"log"
ui "github.com/gizak/termui/v3"
ui "github.com/keaysma/termui/v3"
)
// logs all events to the termui window

View File

@ -3,7 +3,7 @@ package termui
import (
"image"
"github.com/gizak/termui/v3/drawille"
"github.com/keaysma/termui/v3/drawille"
)
type Canvas struct {

2
go.mod
View File

@ -1,4 +1,4 @@
module github.com/gizak/termui/v3
module github.com/keaysma/termui/v3
go 1.15

View File

@ -93,6 +93,22 @@ func GetMaxFloat64FromSlice(slice []float64) (float64, error) {
return max, nil
}
func GetMinFloat64From2dSlice(slices [][]float64) (float64, error) {
if len(slices) == 0 {
return 0, fmt.Errorf("cannot get min value from empty slice")
}
var min float64
for _, slice := range slices {
for _, val := range slice {
if val < min {
min = val
}
}
}
return min, nil
}
func GetMaxFloat64From2dSlice(slices [][]float64) (float64, error) {
if len(slices) == 0 {
return 0, fmt.Errorf("cannot get max value from empty slice")

View File

@ -10,7 +10,7 @@ import (
rw "github.com/mattn/go-runewidth"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
type BarChart struct {

View File

@ -8,7 +8,7 @@ import (
"fmt"
"image"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
type Gauge struct {

View File

@ -8,7 +8,7 @@ import (
"image"
"image/color"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
type Image struct {

View File

@ -9,7 +9,7 @@ import (
rw "github.com/mattn/go-runewidth"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
type List struct {

View File

@ -7,7 +7,7 @@ package widgets
import (
"image"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
type Paragraph struct {

View File

@ -4,7 +4,7 @@ import (
"image"
"math"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
const (

View File

@ -8,7 +8,7 @@ import (
"fmt"
"image"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
// Plot has two modes: line(default) and scatter.
@ -20,6 +20,7 @@ type Plot struct {
Data [][]float64
DataLabels []string
MinVal float64
MaxVal float64
LineColors []Color
@ -76,7 +77,8 @@ func NewPlot() *Plot {
}
}
func (self *Plot) renderBraille(buf *Buffer, drawArea image.Rectangle, maxVal float64) {
func (self *Plot) renderBraille(buf *Buffer, drawArea image.Rectangle, minVal float64, maxVal float64) {
r := maxVal - minVal
canvas := NewCanvas()
canvas.Rectangle = drawArea
@ -84,7 +86,7 @@ func (self *Plot) renderBraille(buf *Buffer, drawArea image.Rectangle, maxVal fl
case ScatterPlot:
for i, line := range self.Data {
for j, val := range line {
height := int((val / maxVal) * float64(drawArea.Dy()-1))
height := int(((val - minVal) / r) * float64(drawArea.Dy()-1))
canvas.SetPoint(
image.Pt(
(drawArea.Min.X+(j*self.HorizontalScale))*2,
@ -96,9 +98,9 @@ func (self *Plot) renderBraille(buf *Buffer, drawArea image.Rectangle, maxVal fl
}
case LineChart:
for i, line := range self.Data {
previousHeight := int((line[1] / maxVal) * float64(drawArea.Dy()-1))
previousHeight := int(((line[1] - minVal) / r) * float64(drawArea.Dy()-1))
for j, val := range line[1:] {
height := int((val / maxVal) * float64(drawArea.Dy()-1))
height := int(((val - minVal) / r) * float64(drawArea.Dy()-1))
canvas.SetLine(
image.Pt(
(drawArea.Min.X+(j*self.HorizontalScale))*2,
@ -118,12 +120,13 @@ func (self *Plot) renderBraille(buf *Buffer, drawArea image.Rectangle, maxVal fl
canvas.Draw(buf)
}
func (self *Plot) renderDot(buf *Buffer, drawArea image.Rectangle, maxVal float64) {
func (self *Plot) renderDot(buf *Buffer, drawArea image.Rectangle, minVal float64, maxVal float64) {
r := maxVal - minVal
switch self.PlotType {
case ScatterPlot:
for i, line := range self.Data {
for j, val := range line {
height := int((val / maxVal) * float64(drawArea.Dy()-1))
height := int(((val - minVal) / r) * float64(drawArea.Dy()-1))
point := image.Pt(drawArea.Min.X+(j*self.HorizontalScale), drawArea.Max.Y-1-height)
if point.In(drawArea) {
buf.SetCell(
@ -137,7 +140,7 @@ func (self *Plot) renderDot(buf *Buffer, drawArea image.Rectangle, maxVal float6
for i, line := range self.Data {
for j := 0; j < len(line) && j*self.HorizontalScale < drawArea.Dx(); j++ {
val := line[j]
height := int((val / maxVal) * float64(drawArea.Dy()-1))
height := int(((val - minVal) / r) * float64(drawArea.Dy()-1))
buf.SetCell(
NewCell(self.DotMarkerRune, NewStyle(SelectColor(self.LineColors, i))),
image.Pt(drawArea.Min.X+(j*self.HorizontalScale), drawArea.Max.Y-1-height),
@ -147,7 +150,7 @@ func (self *Plot) renderDot(buf *Buffer, drawArea image.Rectangle, maxVal float6
}
}
func (self *Plot) plotAxes(buf *Buffer, maxVal float64) {
func (self *Plot) plotAxes(buf *Buffer, minVal float64, maxVal float64) {
// draw origin cell
buf.SetCell(
NewCell(BOTTOM_LEFT, NewStyle(ColorWhite)),
@ -188,10 +191,10 @@ func (self *Plot) plotAxes(buf *Buffer, maxVal float64) {
x += (len(label) + xAxisLabelsGap) * self.HorizontalScale
}
// draw y axis labels
verticalScale := maxVal / float64(self.Inner.Dy()-xAxisLabelsHeight-1)
verticalScale := (maxVal - minVal) / float64(self.Inner.Dy()-xAxisLabelsHeight-1)
for i := 0; i*(yAxisLabelsGap+1) < self.Inner.Dy()-1; i++ {
buf.SetString(
fmt.Sprintf("%.2f", float64(i)*verticalScale*(yAxisLabelsGap+1)),
fmt.Sprintf("%.2f", (float64(i)*verticalScale*(yAxisLabelsGap+1))+minVal),
NewStyle(ColorWhite),
image.Pt(self.Inner.Min.X, self.Inner.Max.Y-(i*(yAxisLabelsGap+1))-2),
)
@ -201,13 +204,16 @@ func (self *Plot) plotAxes(buf *Buffer, maxVal float64) {
func (self *Plot) Draw(buf *Buffer) {
self.Block.Draw(buf)
maxVal := self.MaxVal
minVal, maxVal := self.MinVal, self.MaxVal
if maxVal == 0 {
maxVal, _ = GetMaxFloat64From2dSlice(self.Data)
}
if minVal == 0 {
minVal, _ = GetMinFloat64From2dSlice(self.Data)
}
if self.ShowAxes {
self.plotAxes(buf, maxVal)
self.plotAxes(buf, minVal, maxVal)
}
drawArea := self.Inner
@ -220,8 +226,8 @@ func (self *Plot) Draw(buf *Buffer) {
switch self.Marker {
case MarkerBraille:
self.renderBraille(buf, drawArea, maxVal)
self.renderBraille(buf, drawArea, minVal, maxVal)
case MarkerDot:
self.renderDot(buf, drawArea, maxVal)
self.renderDot(buf, drawArea, minVal, maxVal)
}
}

View File

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

View File

@ -10,7 +10,7 @@ import (
rw "github.com/mattn/go-runewidth"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
type StackedBarChart struct {

View File

@ -7,10 +7,11 @@ package widgets
import (
"image"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
/*Table is like:
/*
Table is like:
Awesome Table
Col0 | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 |

View File

@ -7,7 +7,7 @@ package widgets
import (
"image"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
)
// TabPane is a renderable widget which can be used to conditionally render certain tabs/views.

View File

@ -5,7 +5,7 @@ import (
"image"
"strings"
. "github.com/gizak/termui/v3"
. "github.com/keaysma/termui/v3"
rw "github.com/mattn/go-runewidth"
)