Move widget back to root
This commit is contained in:
parent
196d9aae34
commit
e0dec9dbb9
@ -7,7 +7,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/gizak/termui"
|
import "github.com/gizak/termui"
|
||||||
import "github.com/gizak/termui/widget"
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := termui.Init()
|
err := termui.Init()
|
||||||
@ -16,54 +15,57 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer termui.Close()
|
defer termui.Close()
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
//termui.UseTheme("helloworld")
|
||||||
|
|
||||||
g0 := widget.NewGauge()
|
g0 := termui.NewGauge()
|
||||||
g0.Percent = 40
|
g0.Percent = 40
|
||||||
g0.Width = 50
|
g0.Width = 50
|
||||||
g0.Height = 3
|
g0.Height = 3
|
||||||
g0.Border.Label = "Slim Gauge"
|
g0.BorderLabel = "Slim Gauge"
|
||||||
g0.BarColor = termui.ColorRed
|
g0.BarColor = termui.ColorRed
|
||||||
g0.Border.Fg = termui.ColorWhite
|
g0.BorderFg = termui.ColorWhite
|
||||||
g0.Border.LabelFgClr = termui.ColorCyan
|
g0.BorderLabelFg = termui.ColorCyan
|
||||||
|
|
||||||
gg := termui.NewBlock()
|
gg := termui.NewBlock()
|
||||||
gg.Width = 50
|
gg.Width = 50
|
||||||
gg.Height = 5
|
gg.Height = 5
|
||||||
gg.Y = 12
|
gg.Y = 12
|
||||||
gg.Border.Label = "TEST"
|
gg.BorderLabel = "TEST"
|
||||||
gg.Align()
|
gg.Align()
|
||||||
|
|
||||||
g2 := widget.NewGauge()
|
g2 := termui.NewGauge()
|
||||||
g2.Percent = 60
|
g2.Percent = 60
|
||||||
g2.Width = 50
|
g2.Width = 50
|
||||||
g2.Height = 3
|
g2.Height = 3
|
||||||
g2.PercentColor = termui.ColorBlue
|
g2.PercentColor = termui.ColorBlue
|
||||||
g2.Y = 3
|
g2.Y = 3
|
||||||
g2.Border.Label = "Slim Gauge"
|
g2.BorderLabel = "Slim Gauge"
|
||||||
g2.BarColor = termui.ColorYellow
|
g2.BarColor = termui.ColorYellow
|
||||||
g2.Border.Fg = termui.ColorWhite
|
g2.BorderFg = termui.ColorWhite
|
||||||
|
|
||||||
g1 := widget.NewGauge()
|
g1 := termui.NewGauge()
|
||||||
g1.Percent = 30
|
g1.Percent = 30
|
||||||
g1.Width = 50
|
g1.Width = 50
|
||||||
g1.Height = 5
|
g1.Height = 5
|
||||||
g1.Y = 6
|
g1.Y = 6
|
||||||
g1.Border.Label = "Big Gauge"
|
g1.BorderLabel = "Big Gauge"
|
||||||
g1.PercentColor = termui.ColorYellow
|
g1.PercentColor = termui.ColorYellow
|
||||||
g1.BarColor = termui.ColorGreen
|
g1.BarColor = termui.ColorGreen
|
||||||
g1.Border.Fg = termui.ColorWhite
|
g1.BorderFg = termui.ColorWhite
|
||||||
g1.Border.LabelFgClr = termui.ColorMagenta
|
g1.BorderLabelFg = termui.ColorMagenta
|
||||||
|
|
||||||
g3 := termui.NewGauge()
|
g3 := termui.NewGauge()
|
||||||
g3.Percent = 50
|
g3.Percent = 50
|
||||||
g3.Width = 50
|
g3.Width = 50
|
||||||
g3.Height = 3
|
g3.Height = 3
|
||||||
g3.Y = 11
|
g3.Y = 11
|
||||||
g3.Border.Label = "Gauge with custom label"
|
g3.BorderLabel = "Gauge with custom label"
|
||||||
g3.Label = "{{percent}}% (100MBs free)"
|
g3.Label = "{{percent}}% (100MBs free)"
|
||||||
g3.LabelAlign = termui.AlignRight
|
g3.LabelAlign = termui.AlignRight
|
||||||
|
|
||||||
termui.Render(g0, g1, g2, g3)
|
termui.Render(g0, g1, g2, g3)
|
||||||
<-termui.EventCh()
|
termui.Handle("/sys/kbd/q", func(termui.Event) {
|
||||||
|
termui.StopLoop()
|
||||||
|
})
|
||||||
|
termui.Loop()
|
||||||
}
|
}
|
||||||
|
@ -41,16 +41,16 @@ type BarChart struct {
|
|||||||
// NewBarChart returns a new *BarChart with current theme.
|
// NewBarChart returns a new *BarChart with current theme.
|
||||||
func NewBarChart() *BarChart {
|
func NewBarChart() *BarChart {
|
||||||
bc := &BarChart{Block: *NewBlock()}
|
bc := &BarChart{Block: *NewBlock()}
|
||||||
bc.BarColor = theme.BarChartBar
|
bc.BarColor = ThemeAttr("barchart.bar.bg")
|
||||||
bc.NumColor = theme.BarChartNum
|
bc.NumColor = ThemeAttr("barchart.num.fg")
|
||||||
bc.TextColor = theme.BarChartText
|
bc.TextColor = ThemeAttr("barchart.text.fg")
|
||||||
bc.BarGap = 1
|
bc.BarGap = 1
|
||||||
bc.BarWidth = 3
|
bc.BarWidth = 3
|
||||||
return bc
|
return bc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BarChart) layout() {
|
func (bc *BarChart) layout() {
|
||||||
bc.numBar = bc.innerWidth / (bc.BarGap + bc.BarWidth)
|
bc.numBar = bc.innerArea.Dx() / (bc.BarGap + bc.BarWidth)
|
||||||
bc.labels = make([][]rune, bc.numBar)
|
bc.labels = make([][]rune, bc.numBar)
|
||||||
bc.dataNum = make([][]rune, len(bc.Data))
|
bc.dataNum = make([][]rune, len(bc.Data))
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ func (bc *BarChart) layout() {
|
|||||||
bc.max = bc.Data[i]
|
bc.max = bc.Data[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bc.scale = float64(bc.max) / float64(bc.innerHeight-1)
|
bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BarChart) SetMax(max int) {
|
func (bc *BarChart) SetMax(max int) {
|
||||||
@ -82,8 +82,8 @@ func (bc *BarChart) SetMax(max int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (bc *BarChart) Buffer() []Point {
|
func (bc *BarChart) Buffer() Buffer {
|
||||||
ps := bc.Block.Buffer()
|
buf := bc.Block.Buffer()
|
||||||
bc.layout()
|
bc.layout()
|
||||||
|
|
||||||
for i := 0; i < bc.numBar && i < len(bc.Data) && i < len(bc.DataLabels); i++ {
|
for i := 0; i < bc.numBar && i < len(bc.Data) && i < len(bc.DataLabels); i++ {
|
||||||
@ -92,46 +92,48 @@ func (bc *BarChart) Buffer() []Point {
|
|||||||
// plot bar
|
// plot bar
|
||||||
for j := 0; j < bc.BarWidth; j++ {
|
for j := 0; j < bc.BarWidth; j++ {
|
||||||
for k := 0; k < h; k++ {
|
for k := 0; k < h; k++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = ' '
|
Ch: ' ',
|
||||||
p.Bg = bc.BarColor
|
Bg: bc.BarColor,
|
||||||
if bc.BarColor == ColorDefault { // when color is default, space char treated as transparent!
|
|
||||||
p.Bg |= AttrReverse
|
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + i*(bc.BarWidth+bc.BarGap) + j
|
if bc.BarColor == ColorDefault { // when color is default, space char treated as transparent!
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2 - k
|
c.Bg |= AttrReverse
|
||||||
ps = append(ps, p)
|
}
|
||||||
|
x := bc.innerArea.Min.X + i*(bc.BarWidth+bc.BarGap) + j
|
||||||
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - k
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// plot text
|
// plot text
|
||||||
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
||||||
w := charWidth(bc.labels[i][j])
|
w := charWidth(bc.labels[i][j])
|
||||||
p := Point{}
|
c := Cell{}
|
||||||
p.Ch = bc.labels[i][j]
|
p.Ch = bc.labels[i][j]
|
||||||
p.Bg = bc.BgColor
|
p.Bg = bc.BgColor
|
||||||
p.Fg = bc.TextColor
|
p.Fg = bc.TextColor
|
||||||
p.Y = bc.innerY + bc.innerHeight - 1
|
p.Y = bc.innerArea.Min.Y + bc.innerArea.Dy() - 1
|
||||||
p.X = bc.innerX + oftX + k
|
p.X = bc.innerArea.Min.X + oftX + k
|
||||||
ps = append(ps, p)
|
ps = append(ps, p)
|
||||||
k += w
|
k += w
|
||||||
}
|
}
|
||||||
// plot num
|
// plot num
|
||||||
for j := 0; j < len(bc.dataNum[i]); j++ {
|
for j := 0; j < len(bc.dataNum[i]); j++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.dataNum[i][j]
|
Ch: bc.dataNum[i][j],
|
||||||
p.Fg = bc.NumColor
|
Fg: bc.NumColor,
|
||||||
p.Bg = bc.BarColor
|
Bg: bc.BarColor,
|
||||||
|
}
|
||||||
if bc.BarColor == ColorDefault { // the same as above
|
if bc.BarColor == ColorDefault { // the same as above
|
||||||
p.Bg |= AttrReverse
|
c.Bg |= AttrReverse
|
||||||
}
|
}
|
||||||
if h == 0 {
|
if h == 0 {
|
||||||
p.Bg = bc.BgColor
|
c.Bg = bc.BgColor
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j
|
x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2
|
||||||
ps = append(ps, p)
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bc.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
6
block.go
6
block.go
@ -119,6 +119,7 @@ type Block struct {
|
|||||||
PaddingBottom int
|
PaddingBottom int
|
||||||
PaddingLeft int
|
PaddingLeft int
|
||||||
PaddingRight int
|
PaddingRight int
|
||||||
|
id string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlock returns a *Block which inherits styles from current theme.
|
// NewBlock returns a *Block which inherits styles from current theme.
|
||||||
@ -137,9 +138,14 @@ func NewBlock() *Block {
|
|||||||
b.Bg = ThemeAttr("block.bg")
|
b.Bg = ThemeAttr("block.bg")
|
||||||
b.Width = 2
|
b.Width = 2
|
||||||
b.Height = 2
|
b.Height = 2
|
||||||
|
b.id = GenId()
|
||||||
return &b
|
return &b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b Block) Id() string {
|
||||||
|
return b.id
|
||||||
|
}
|
||||||
|
|
||||||
// Align computes box model
|
// Align computes box model
|
||||||
func (b *Block) Align() {
|
func (b *Block) Align() {
|
||||||
b.area.Min.X = b.X
|
b.area.Min.X = b.X
|
||||||
|
27
events.go
27
events.go
@ -152,6 +152,7 @@ type EvtStream struct {
|
|||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
sigStopLoop chan Event
|
sigStopLoop chan Event
|
||||||
Handlers map[string]func(Event)
|
Handlers map[string]func(Event)
|
||||||
|
hook func(Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEvtStream() *EvtStream {
|
func NewEvtStream() *EvtStream {
|
||||||
@ -209,10 +210,10 @@ func (es *EvtStream) Handle(path string, handler func(Event)) {
|
|||||||
es.Handlers[cleanPath(path)] = handler
|
es.Handlers[cleanPath(path)] = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *EvtStream) match(path string) string {
|
func findMatch(mux map[string]func(Event), path string) string {
|
||||||
n := -1
|
n := -1
|
||||||
pattern := ""
|
pattern := ""
|
||||||
for m := range es.Handlers {
|
for m := range mux {
|
||||||
if !isPathMatch(m, path) {
|
if !isPathMatch(m, path) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -222,11 +223,28 @@ func (es *EvtStream) match(path string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pattern
|
return pattern
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) match(path string) string {
|
||||||
|
return findMatch(es.Handlers, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
var internalHandlers = make(map[string]func(Event))
|
||||||
|
|
||||||
|
func initInternalHandling() {
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
func (es *EvtStream) Hook(f func(Event)) {
|
||||||
|
es.hook = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *EvtStream) Loop() {
|
func (es *EvtStream) Loop() {
|
||||||
for e := range es.stream {
|
for e := range es.stream {
|
||||||
if e.Path == "/sig/stoploop" {
|
switch e.Path {
|
||||||
|
case "/sig/stoploop":
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go func(a Event) {
|
go func(a Event) {
|
||||||
@ -236,6 +254,9 @@ func (es *EvtStream) Loop() {
|
|||||||
es.Handlers[pattern](a)
|
es.Handlers[pattern](a)
|
||||||
}
|
}
|
||||||
}(e)
|
}(e)
|
||||||
|
if es.hook != nil {
|
||||||
|
es.hook(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ type Gauge struct {
|
|||||||
func NewGauge() *Gauge {
|
func NewGauge() *Gauge {
|
||||||
g := &Gauge{
|
g := &Gauge{
|
||||||
Block: *NewBlock(),
|
Block: *NewBlock(),
|
||||||
PercentColor: theme.GaugePercent,
|
PercentColor: ThemeAttr("gauge.percent.fg"),
|
||||||
BarColor: theme.GaugeBar,
|
BarColor: ThemeAttr("gauge.bar.bg"),
|
||||||
Label: "{{percent}}%",
|
Label: "{{percent}}%",
|
||||||
LabelAlign: AlignCenter,
|
LabelAlign: AlignCenter,
|
||||||
}
|
}
|
||||||
@ -56,28 +56,26 @@ func NewGauge() *Gauge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (g *Gauge) Buffer() []Point {
|
func (g *Gauge) Buffer() Buffer {
|
||||||
ps := g.Block.Buffer()
|
buf := g.Block.Buffer()
|
||||||
|
|
||||||
// plot bar
|
// plot bar
|
||||||
w := g.Percent * g.innerWidth / 100
|
w := g.Percent * g.innerArea.Dx() / 100
|
||||||
for i := 0; i < g.innerHeight; i++ {
|
for i := 0; i < g.innerArea.Dy(); i++ {
|
||||||
for j := 0; j < w; j++ {
|
for j := 0; j < w; j++ {
|
||||||
p := Point{}
|
c := Cell{}
|
||||||
p.X = g.innerX + j
|
c.Ch = ' '
|
||||||
p.Y = g.innerY + i
|
c.Bg = g.BarColor
|
||||||
p.Ch = ' '
|
if c.Bg == ColorDefault {
|
||||||
p.Bg = g.BarColor
|
c.Bg |= AttrReverse
|
||||||
if p.Bg == ColorDefault {
|
|
||||||
p.Bg |= AttrReverse
|
|
||||||
}
|
}
|
||||||
ps = append(ps, p)
|
buf.Set(g.innerArea.Min.X+j, g.innerArea.Min.Y+i, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// plot percentage
|
// plot percentage
|
||||||
s := strings.Replace(g.Label, "{{percent}}", strconv.Itoa(g.Percent), -1)
|
s := strings.Replace(g.Label, "{{percent}}", strconv.Itoa(g.Percent), -1)
|
||||||
pry := g.innerY + g.innerHeight/2
|
pry := g.innerArea.Min.Y + g.innerArea.Dy()/2
|
||||||
rs := str2runes(s)
|
rs := str2runes(s)
|
||||||
var pos int
|
var pos int
|
||||||
switch g.LabelAlign {
|
switch g.LabelAlign {
|
||||||
@ -85,29 +83,29 @@ func (g *Gauge) Buffer() []Point {
|
|||||||
pos = 0
|
pos = 0
|
||||||
|
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
pos = (g.innerWidth - strWidth(s)) / 2
|
pos = (g.innerArea.Dx() - strWidth(s)) / 2
|
||||||
|
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
pos = g.innerWidth - strWidth(s)
|
pos = g.innerArea.Dx() - strWidth(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, v := range rs {
|
for i, v := range rs {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.X = 1 + pos + i
|
Ch: v,
|
||||||
p.Y = pry
|
Fg: g.PercentColor,
|
||||||
p.Ch = v
|
}
|
||||||
p.Fg = g.PercentColor
|
|
||||||
if w+g.innerX > pos+i {
|
if w+g.innerArea.Min.X > pos+i {
|
||||||
p.Bg = g.BarColor
|
c.Bg = g.BarColor
|
||||||
if p.Bg == ColorDefault {
|
if c.Bg == ColorDefault {
|
||||||
p.Bg |= AttrReverse
|
c.Bg |= AttrReverse
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p.Bg = g.Block.BgColor
|
c.Bg = g.Block.Bg
|
||||||
}
|
}
|
||||||
|
|
||||||
ps = append(ps, p)
|
buf.Set(1+pos+i, pry, c)
|
||||||
}
|
}
|
||||||
return g.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
2
grid.go
2
grid.go
@ -275,3 +275,5 @@ func (g Grid) Buffer() Buffer {
|
|||||||
}
|
}
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Body = NewGrid()
|
||||||
|
@ -89,8 +89,8 @@ func NewLineChart() *LineChart {
|
|||||||
|
|
||||||
// one cell contains two data points
|
// one cell contains two data points
|
||||||
// so the capicity is 2x as dot-mode
|
// so the capicity is 2x as dot-mode
|
||||||
func (lc *LineChart) renderBraille() []Point {
|
func (lc *LineChart) renderBraille() Buffer {
|
||||||
ps := []Point{}
|
buf := NewBuffer()
|
||||||
|
|
||||||
// return: b -> which cell should the point be in
|
// return: b -> which cell should the point be in
|
||||||
// m -> in the cell, divided into 4 equal height levels, which subcell?
|
// m -> in the cell, divided into 4 equal height levels, which subcell?
|
||||||
@ -106,44 +106,48 @@ func (lc *LineChart) renderBraille() []Point {
|
|||||||
b1, m1 := getPos(lc.Data[2*i+1])
|
b1, m1 := getPos(lc.Data[2*i+1])
|
||||||
|
|
||||||
if b0 == b1 {
|
if b0 == b1 {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = braillePatterns[[2]int{m0, m1}]
|
Ch: braillePatterns[[2]int{m0, m1}],
|
||||||
p.Bg = lc.BgColor
|
Bg: lc.BgColor,
|
||||||
p.Fg = lc.LineColor
|
Fg: lc.LineColor,
|
||||||
p.Y = lc.innerY + lc.innerHeight - 3 - b0
|
}
|
||||||
p.X = lc.innerX + lc.labelYSpace + 1 + i
|
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0
|
||||||
ps = append(ps, p)
|
x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
|
buf.Set(x, y, c)
|
||||||
} else {
|
} else {
|
||||||
p0 := newPointWithAttrs(lSingleBraille[m0],
|
c0 := Cell{Ch: lSingleBraille[m0],
|
||||||
lc.innerX+lc.labelYSpace+1+i,
|
Fg: lc.LineColor,
|
||||||
lc.innerY+lc.innerHeight-3-b0,
|
Bg: lc.BgColor}
|
||||||
lc.LineColor,
|
x0 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
lc.BgColor)
|
y0 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0
|
||||||
p1 := newPointWithAttrs(rSingleBraille[m1],
|
buf.Set(x0, y0, c0)
|
||||||
lc.innerX+lc.labelYSpace+1+i,
|
|
||||||
lc.innerY+lc.innerHeight-3-b1,
|
c1 := Cell{Ch: rSingleBraille[m1],
|
||||||
lc.LineColor,
|
Fg: lc.LineColor,
|
||||||
lc.BgColor)
|
Bg: lc.Bg}
|
||||||
ps = append(ps, p0, p1)
|
x1 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
|
y1 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b1
|
||||||
|
buf.Set(x1, y1, c1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *LineChart) renderDot() []Point {
|
func (lc *LineChart) renderDot() Buffer {
|
||||||
ps := []Point{}
|
buf := NewBuffer()
|
||||||
for i := 0; i < len(lc.Data) && i < lc.axisXWidth; i++ {
|
for i := 0; i < len(lc.Data) && i < lc.axisXWidth; i++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = lc.DotStyle
|
Ch: lc.DotStyle,
|
||||||
p.Fg = lc.LineColor
|
Fg: lc.LineColor,
|
||||||
p.Bg = lc.BgColor
|
Bg: lc.BgColor,
|
||||||
p.X = lc.innerX + lc.labelYSpace + 1 + i
|
}
|
||||||
p.Y = lc.innerY + lc.innerHeight - 3 - int((lc.Data[i]-lc.bottomValue)/lc.scale+0.5)
|
x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
ps = append(ps, p)
|
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - int((lc.Data[i]-lc.bottomValue)/lc.scale+0.5)
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *LineChart) calcLabelX() {
|
func (lc *LineChart) calcLabelX() {
|
||||||
@ -222,9 +226,9 @@ func (lc *LineChart) calcLayout() {
|
|||||||
lc.maxY = lc.Data[0]
|
lc.maxY = lc.Data[0]
|
||||||
|
|
||||||
// valid visible range
|
// valid visible range
|
||||||
vrange := lc.innerWidth
|
vrange := lc.innerArea.Dx()
|
||||||
if lc.Mode == "braille" {
|
if lc.Mode == "braille" {
|
||||||
vrange = 2 * lc.innerWidth
|
vrange = 2 * lc.innerArea.Dx()
|
||||||
}
|
}
|
||||||
if vrange > len(lc.Data) {
|
if vrange > len(lc.Data) {
|
||||||
vrange = len(lc.Data)
|
vrange = len(lc.Data)
|
||||||
@ -249,40 +253,30 @@ func (lc *LineChart) calcLayout() {
|
|||||||
lc.topValue = lc.maxY + 0.2*span
|
lc.topValue = lc.maxY + 0.2*span
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.axisYHeight = lc.innerHeight - 2
|
lc.axisYHeight = lc.innerArea.Dy() - 2
|
||||||
lc.calcLabelY()
|
lc.calcLabelY()
|
||||||
|
|
||||||
lc.axisXWidth = lc.innerWidth - 1 - lc.labelYSpace
|
lc.axisXWidth = lc.innerArea.Dx() - 1 - lc.labelYSpace
|
||||||
lc.calcLabelX()
|
lc.calcLabelX()
|
||||||
|
|
||||||
lc.drawingX = lc.innerX + 1 + lc.labelYSpace
|
lc.drawingX = lc.innerArea.Min.X + 1 + lc.labelYSpace
|
||||||
lc.drawingY = lc.innerY
|
lc.drawingY = lc.innerArea.Min.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *LineChart) plotAxes() []Point {
|
func (lc *LineChart) plotAxes() Buffer {
|
||||||
origY := lc.innerY + lc.innerHeight - 2
|
buf := NewBuffer()
|
||||||
origX := lc.innerX + lc.labelYSpace
|
|
||||||
|
|
||||||
ps := []Point{newPointWithAttrs(ORIGIN, origX, origY, lc.AxesColor, lc.BgColor)}
|
origY := lc.innerArea.Min.Y + lc.innerArea.Dy() - 2
|
||||||
|
origX := lc.innerArea.Min.X + lc.labelYSpace
|
||||||
|
|
||||||
|
buf.Set(origX, origY, Cell{Ch: ORIGIN, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
|
|
||||||
for x := origX + 1; x < origX+lc.axisXWidth; x++ {
|
for x := origX + 1; x < origX+lc.axisXWidth; x++ {
|
||||||
p := Point{}
|
buf.Set(x, origY, Cell{Ch: HDASH, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
p.X = x
|
|
||||||
p.Y = origY
|
|
||||||
p.Bg = lc.BgColor
|
|
||||||
p.Fg = lc.AxesColor
|
|
||||||
p.Ch = HDASH
|
|
||||||
ps = append(ps, p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for dy := 1; dy <= lc.axisYHeight; dy++ {
|
for dy := 1; dy <= lc.axisYHeight; dy++ {
|
||||||
p := Point{}
|
buf.Set(origX, origY-dy, Cell{Ch: VDASH, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
p.X = origX
|
|
||||||
p.Y = origY - dy
|
|
||||||
p.Bg = lc.BgColor
|
|
||||||
p.Fg = lc.AxesColor
|
|
||||||
p.Ch = VDASH
|
|
||||||
ps = append(ps, p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// x label
|
// x label
|
||||||
@ -292,13 +286,14 @@ func (lc *LineChart) plotAxes() []Point {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
for j, r := range rs {
|
for j, r := range rs {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = r
|
Ch: r,
|
||||||
p.Fg = lc.AxesColor
|
Fg: lc.AxesColor,
|
||||||
p.Bg = lc.BgColor
|
Bg: lc.BgColor,
|
||||||
p.X = origX + oft + j
|
}
|
||||||
p.Y = lc.innerY + lc.innerHeight - 1
|
x := origX + oft + j
|
||||||
ps = append(ps, p)
|
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 1
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
oft += len(rs) + lc.axisXLebelGap
|
oft += len(rs) + lc.axisXLebelGap
|
||||||
}
|
}
|
||||||
@ -306,33 +301,31 @@ func (lc *LineChart) plotAxes() []Point {
|
|||||||
// y labels
|
// y labels
|
||||||
for i, rs := range lc.labelY {
|
for i, rs := range lc.labelY {
|
||||||
for j, r := range rs {
|
for j, r := range rs {
|
||||||
p := Point{}
|
buf.Set(
|
||||||
p.Ch = r
|
lc.innerArea.Min.X+j,
|
||||||
p.Fg = lc.AxesColor
|
origY-i*(lc.axisYLebelGap+1),
|
||||||
p.Bg = lc.BgColor
|
Cell{Ch: r, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
p.X = lc.innerX + j
|
|
||||||
p.Y = origY - i*(lc.axisYLebelGap+1)
|
|
||||||
ps = append(ps, p)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (lc *LineChart) Buffer() []Point {
|
func (lc *LineChart) Buffer() []Point {
|
||||||
ps := lc.Block.Buffer()
|
buf := lc.Block.Buffer()
|
||||||
|
|
||||||
if lc.Data == nil || len(lc.Data) == 0 {
|
if lc.Data == nil || len(lc.Data) == 0 {
|
||||||
return ps
|
return ps
|
||||||
}
|
}
|
||||||
lc.calcLayout()
|
lc.calcLayout()
|
||||||
ps = append(ps, lc.plotAxes()...)
|
buf.Merge(lc.plotAxes())
|
||||||
|
|
||||||
if lc.Mode == "dot" {
|
if lc.Mode == "dot" {
|
||||||
ps = append(ps, lc.renderDot()...)
|
buf.Merge(lc.renderDot())
|
||||||
} else {
|
} else {
|
||||||
ps = append(ps, lc.renderBraille()...)
|
buf.Merge(ps, lc.renderBraille())
|
||||||
}
|
}
|
||||||
|
|
||||||
return lc.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
@ -53,7 +53,7 @@ func (l *List) Buffer() []Point {
|
|||||||
buffer := l.Block.Buffer()
|
buffer := l.Block.Buffer()
|
||||||
|
|
||||||
breakLoop := func(y int) bool {
|
breakLoop := func(y int) bool {
|
||||||
return y+1 > l.innerHeight
|
return y+1 > l.innerArea.Dy()
|
||||||
}
|
}
|
||||||
y := 0
|
y := 0
|
||||||
|
|
||||||
@ -65,9 +65,9 @@ MainLoop:
|
|||||||
sequence := renderer.Render(bg, fg)
|
sequence := renderer.Render(bg, fg)
|
||||||
|
|
||||||
for n := range []rune(sequence.NormalizedText) {
|
for n := range []rune(sequence.NormalizedText) {
|
||||||
point, width := sequence.PointAt(n, x+l.innerX, y+l.innerY)
|
point, width := sequence.PointAt(n, x+l.innerArea.Min.X, y+l.innerArea.Min.Y)
|
||||||
|
|
||||||
if width+x <= l.innerWidth {
|
if width+x <= l.innerArea.Dx() {
|
||||||
buffer = append(buffer, point)
|
buffer = append(buffer, point)
|
||||||
x += width
|
x += width
|
||||||
} else {
|
} else {
|
||||||
@ -79,8 +79,8 @@ MainLoop:
|
|||||||
x = 0
|
x = 0
|
||||||
} else {
|
} else {
|
||||||
dotR := []rune(dot)[0]
|
dotR := []rune(dot)[0]
|
||||||
dotX := l.innerWidth + l.innerX - charWidth(dotR)
|
dotX := l.innerArea.Dx() + l.innerArea.Min.X - charWidth(dotR)
|
||||||
p := newPointWithAttrs(dotR, dotX, y+l.innerY, bg, fg)
|
p := newPointWithAttrs(dotR, dotX, y+l.innerArea.Min.Y, bg, fg)
|
||||||
buffer = append(buffer, p)
|
buffer = append(buffer, p)
|
||||||
break
|
break
|
||||||
}
|
}
|
@ -48,16 +48,16 @@ type MBarChart struct {
|
|||||||
// NewBarChart returns a new *BarChart with current theme.
|
// NewBarChart returns a new *BarChart with current theme.
|
||||||
func NewMBarChart() *MBarChart {
|
func NewMBarChart() *MBarChart {
|
||||||
bc := &MBarChart{Block: *NewBlock()}
|
bc := &MBarChart{Block: *NewBlock()}
|
||||||
bc.BarColor[0] = theme.MBarChartBar
|
bc.BarColor[0] = ThemeAttr("mbarchart.bar.bg")
|
||||||
bc.NumColor[0] = theme.MBarChartNum
|
bc.NumColor[0] = ThemeAttr("mbarchart.num.fg")
|
||||||
bc.TextColor = theme.MBarChartText
|
bc.TextColor = ThemeAttr("mbarchart.text.fg")
|
||||||
bc.BarGap = 1
|
bc.BarGap = 1
|
||||||
bc.BarWidth = 3
|
bc.BarWidth = 3
|
||||||
return bc
|
return bc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *MBarChart) layout() {
|
func (bc *MBarChart) layout() {
|
||||||
bc.numBar = bc.innerWidth / (bc.BarGap + bc.BarWidth)
|
bc.numBar = bc.innerArea.Dx() / (bc.BarGap + bc.BarWidth)
|
||||||
bc.labels = make([][]rune, bc.numBar)
|
bc.labels = make([][]rune, bc.numBar)
|
||||||
DataLen := 0
|
DataLen := 0
|
||||||
LabelLen := len(bc.DataLabels)
|
LabelLen := len(bc.DataLabels)
|
||||||
@ -129,9 +129,9 @@ func (bc *MBarChart) layout() {
|
|||||||
if bc.ShowScale {
|
if bc.ShowScale {
|
||||||
s := fmt.Sprintf("%d", bc.max)
|
s := fmt.Sprintf("%d", bc.max)
|
||||||
bc.maxScale = trimStr2Runes(s, len(s))
|
bc.maxScale = trimStr2Runes(s, len(s))
|
||||||
bc.scale = float64(bc.max) / float64(bc.innerHeight-2)
|
bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-2)
|
||||||
} else {
|
} else {
|
||||||
bc.scale = float64(bc.max) / float64(bc.innerHeight-1)
|
bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -144,8 +144,8 @@ func (bc *MBarChart) SetMax(max int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (bc *MBarChart) Buffer() []Point {
|
func (bc *MBarChart) Buffer() Buffer {
|
||||||
ps := bc.Block.Buffer()
|
buf := bc.Block.Buffer()
|
||||||
bc.layout()
|
bc.layout()
|
||||||
var oftX int
|
var oftX int
|
||||||
|
|
||||||
@ -157,15 +157,17 @@ func (bc *MBarChart) Buffer() []Point {
|
|||||||
// plot bars
|
// plot bars
|
||||||
for j := 0; j < bc.BarWidth; j++ {
|
for j := 0; j < bc.BarWidth; j++ {
|
||||||
for k := 0; k < h; k++ {
|
for k := 0; k < h; k++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = ' '
|
Ch: ' ',
|
||||||
p.Bg = bc.BarColor[i1]
|
Bg: bc.BarColor[i1],
|
||||||
if bc.BarColor[i1] == ColorDefault { // when color is default, space char treated as transparent!
|
|
||||||
p.Bg |= AttrReverse
|
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + i*(bc.BarWidth+bc.BarGap) + j
|
if bc.BarColor[i1] == ColorDefault { // when color is default, space char treated as transparent!
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2 - k - ph
|
c.Bg |= AttrReverse
|
||||||
ps = append(ps, p)
|
}
|
||||||
|
x := bc.innerArea.Min.X + i*(bc.BarWidth+bc.BarGap) + j
|
||||||
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - k - ph
|
||||||
|
buf.Set(x, y, c)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ph += h
|
ph += h
|
||||||
@ -173,13 +175,14 @@ func (bc *MBarChart) Buffer() []Point {
|
|||||||
// plot text
|
// plot text
|
||||||
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
||||||
w := charWidth(bc.labels[i][j])
|
w := charWidth(bc.labels[i][j])
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.labels[i][j]
|
Ch: bc.labels[i][j],
|
||||||
p.Bg = bc.BgColor
|
Bg: bc.Bg,
|
||||||
p.Fg = bc.TextColor
|
Fg: bc.TextColor,
|
||||||
p.Y = bc.innerY + bc.innerHeight - 1
|
}
|
||||||
p.X = bc.innerX + oftX + ((bc.BarWidth - len(bc.labels[i])) / 2) + k
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 1
|
||||||
ps = append(ps, p)
|
x := bc.innerArea.Max.X + oftX + ((bc.BarWidth - len(bc.labels[i])) / 2) + k
|
||||||
|
buf.Set(x, y, c)
|
||||||
k += w
|
k += w
|
||||||
}
|
}
|
||||||
// plot num
|
// plot num
|
||||||
@ -187,19 +190,20 @@ func (bc *MBarChart) Buffer() []Point {
|
|||||||
for i1 := 0; i1 < bc.numStack; i1++ {
|
for i1 := 0; i1 < bc.numStack; i1++ {
|
||||||
h := int(float64(bc.Data[i1][i]) / bc.scale)
|
h := int(float64(bc.Data[i1][i]) / bc.scale)
|
||||||
for j := 0; j < len(bc.dataNum[i1][i]) && h > 0; j++ {
|
for j := 0; j < len(bc.dataNum[i1][i]) && h > 0; j++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.dataNum[i1][i][j]
|
Ch: bc.dataNum[i1][i][j],
|
||||||
p.Fg = bc.NumColor[i1]
|
Fg: bc.NumColor[i1],
|
||||||
p.Bg = bc.BarColor[i1]
|
Bg: bc.BarColor[i1],
|
||||||
|
}
|
||||||
if bc.BarColor[i1] == ColorDefault { // the same as above
|
if bc.BarColor[i1] == ColorDefault { // the same as above
|
||||||
p.Bg |= AttrReverse
|
c.Bg |= AttrReverse
|
||||||
}
|
}
|
||||||
if h == 0 {
|
if h == 0 {
|
||||||
p.Bg = bc.BgColor
|
c.Bg = bc.Bg
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + oftX + (bc.BarWidth-len(bc.dataNum[i1][i]))/2 + j
|
x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i1][i]))/2 + j
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2 - ph
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - ph
|
||||||
ps = append(ps, p)
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
ph += h
|
ph += h
|
||||||
}
|
}
|
||||||
@ -208,26 +212,31 @@ func (bc *MBarChart) Buffer() []Point {
|
|||||||
if bc.ShowScale {
|
if bc.ShowScale {
|
||||||
//Currently bar graph only supprts data range from 0 to MAX
|
//Currently bar graph only supprts data range from 0 to MAX
|
||||||
//Plot 0
|
//Plot 0
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = '0'
|
Ch: '0',
|
||||||
p.Bg = bc.BgColor
|
Bg: bc.Bg,
|
||||||
p.Fg = bc.TextColor
|
Fg: bc.TextColor,
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2
|
}
|
||||||
p.X = bc.X
|
|
||||||
ps = append(ps, p)
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2
|
||||||
|
x := bc.X
|
||||||
|
buf.Set(x, y, c)
|
||||||
|
|
||||||
//Plot the maximum sacle value
|
//Plot the maximum sacle value
|
||||||
for i := 0; i < len(bc.maxScale); i++ {
|
for i := 0; i < len(bc.maxScale); i++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.maxScale[i]
|
Ch: bc.maxScale[i],
|
||||||
p.Bg = bc.BgColor
|
Bg: bc.Bg,
|
||||||
p.Fg = bc.TextColor
|
Fg: bc.TextColor,
|
||||||
p.Y = bc.innerY
|
}
|
||||||
p.X = bc.X + i
|
|
||||||
ps = append(ps, p)
|
y := bc.innerArea.Min.Y
|
||||||
|
x := bc.X + i
|
||||||
|
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bc.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
@ -41,20 +41,20 @@ func (p *Par) Buffer() []Point {
|
|||||||
runes := []rune(sequence.NormalizedText)
|
runes := []rune(sequence.NormalizedText)
|
||||||
|
|
||||||
y, x, n := 0, 0, 0
|
y, x, n := 0, 0, 0
|
||||||
for y < p.innerHeight && n < len(runes) {
|
for y < p.innerArea.Dy() && n < len(runes) {
|
||||||
point, width := sequence.PointAt(n, x+p.innerX, y+p.innerY)
|
point, width := sequence.PointAt(n, x+p.innerArea.Min.X, y+p.innerArea.Min.Y)
|
||||||
|
|
||||||
if runes[n] == '\n' || x+width > p.innerWidth {
|
if runes[n] == '\n' || x+width > p.innerArea.Dx() {
|
||||||
y++
|
y++
|
||||||
x = 0 // set x = 0
|
x = 0 // set x = 0
|
||||||
if runes[n] == '\n' {
|
if runes[n] == '\n' {
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
|
|
||||||
if y >= p.innerHeight {
|
if y >= p.innerArea.Dy() {
|
||||||
ps = append(ps, newPointWithAttrs('…',
|
ps = append(ps, newPointWithAttrs('…',
|
||||||
p.innerX+p.innerWidth-1,
|
p.innerArea.Min.X+p.innerArea.Dx()-1,
|
||||||
p.innerY+p.innerHeight-1,
|
p.innerArea.Min.Y+p.innerArea.Dy()-1,
|
||||||
p.TextFgColor, p.TextBgColor))
|
p.TextFgColor, p.TextBgColor))
|
||||||
break
|
break
|
||||||
}
|
}
|
@ -35,7 +35,13 @@ func Init() error {
|
|||||||
DefaultEvtStream.Merge("termbox", NewSysEvtCh())
|
DefaultEvtStream.Merge("termbox", NewSysEvtCh())
|
||||||
DefaultEvtStream.Merge("timer", NewTimerCh(time.Second))
|
DefaultEvtStream.Merge("timer", NewTimerCh(time.Second))
|
||||||
DefaultEvtStream.Handle("/", DefualtHandler)
|
DefaultEvtStream.Handle("/", DefualtHandler)
|
||||||
|
DefaultEvtStream.Handle("/sys/wnd/resize", func(e Event) {
|
||||||
|
w := e.Data.(EvtWnd)
|
||||||
|
Body.Width = w.Width
|
||||||
|
})
|
||||||
|
|
||||||
|
DefaultWgtMgr = NewWgtMgr()
|
||||||
|
DefaultEvtStream.Hook(DefaultWgtMgr.WgtHandlersHook())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,13 +69,13 @@ func (sl *Sparklines) update() {
|
|||||||
sl.Lines[i].displayHeight = v.Height + 1
|
sl.Lines[i].displayHeight = v.Height + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sl.displayWidth = sl.innerWidth
|
sl.displayWidth = sl.innerArea.Dx()
|
||||||
|
|
||||||
// get how many lines gotta display
|
// get how many lines gotta display
|
||||||
h := 0
|
h := 0
|
||||||
sl.displayLines = 0
|
sl.displayLines = 0
|
||||||
for _, v := range sl.Lines {
|
for _, v := range sl.Lines {
|
||||||
if h+v.displayHeight <= sl.innerHeight {
|
if h+v.displayHeight <= sl.innerArea.Dy() {
|
||||||
sl.displayLines++
|
sl.displayLines++
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@ -107,21 +107,21 @@ func (sl *Sparklines) Buffer() []Point {
|
|||||||
l := sl.Lines[i]
|
l := sl.Lines[i]
|
||||||
data := l.Data
|
data := l.Data
|
||||||
|
|
||||||
if len(data) > sl.innerWidth {
|
if len(data) > sl.innerArea.Dx() {
|
||||||
data = data[len(data)-sl.innerWidth:]
|
data = data[len(data)-sl.innerArea.Dx():]
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.Title != "" {
|
if l.Title != "" {
|
||||||
rs := trimStr2Runes(l.Title, sl.innerWidth)
|
rs := trimStr2Runes(l.Title, sl.innerArea.Dx())
|
||||||
oftX := 0
|
oftX := 0
|
||||||
for _, v := range rs {
|
for _, v := range rs {
|
||||||
w := charWidth(v)
|
w := charWidth(v)
|
||||||
p := Point{}
|
c := Cell{}
|
||||||
p.Ch = v
|
p.Ch = v
|
||||||
p.Fg = l.TitleColor
|
p.Fg = l.TitleColor
|
||||||
p.Bg = sl.BgColor
|
p.Bg = sl.BgColor
|
||||||
p.X = sl.innerX + oftX
|
p.X = sl.innerArea.Min.X + oftX
|
||||||
p.Y = sl.innerY + oftY
|
p.Y = sl.innerArea.Min.Y + oftY
|
||||||
ps = append(ps, p)
|
ps = append(ps, p)
|
||||||
oftX += w
|
oftX += w
|
||||||
}
|
}
|
||||||
@ -132,18 +132,18 @@ func (sl *Sparklines) Buffer() []Point {
|
|||||||
barCnt := h / 8
|
barCnt := h / 8
|
||||||
barMod := h % 8
|
barMod := h % 8
|
||||||
for jj := 0; jj < barCnt; jj++ {
|
for jj := 0; jj < barCnt; jj++ {
|
||||||
p := Point{}
|
c := Cell{}
|
||||||
p.X = sl.innerX + j
|
p.X = sl.innerArea.Min.X + j
|
||||||
p.Y = sl.innerY + oftY + l.Height - jj
|
p.Y = sl.innerArea.Min.Y + oftY + l.Height - jj
|
||||||
p.Ch = ' ' // => sparks[7]
|
p.Ch = ' ' // => sparks[7]
|
||||||
p.Bg = l.LineColor
|
p.Bg = l.LineColor
|
||||||
//p.Bg = sl.BgColor
|
//p.Bg = sl.BgColor
|
||||||
ps = append(ps, p)
|
ps = append(ps, p)
|
||||||
}
|
}
|
||||||
if barMod != 0 {
|
if barMod != 0 {
|
||||||
p := Point{}
|
c := Cell{}
|
||||||
p.X = sl.innerX + j
|
p.X = sl.innerArea.Min.X + j
|
||||||
p.Y = sl.innerY + oftY + l.Height - barCnt
|
p.Y = sl.innerArea.Min.Y + oftY + l.Height - barCnt
|
||||||
p.Ch = sparks[barMod-1]
|
p.Ch = sparks[barMod-1]
|
||||||
p.Fg = l.LineColor
|
p.Fg = l.LineColor
|
||||||
p.Bg = sl.BgColor
|
p.Bg = sl.BgColor
|
82
widget.go
Normal file
82
widget.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package termui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// event mixins
|
||||||
|
type WgtMgr map[string]WgtInfo
|
||||||
|
|
||||||
|
type WgtInfo struct {
|
||||||
|
Handlers map[string]func(Event)
|
||||||
|
WgtRef Widget
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Widget interface {
|
||||||
|
Id() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWgtInfo(wgt Widget) WgtInfo {
|
||||||
|
return WgtInfo{
|
||||||
|
Handlers: make(map[string]func(Event)),
|
||||||
|
WgtRef: wgt,
|
||||||
|
Id: wgt.Id(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWgtMgr() WgtMgr {
|
||||||
|
wm := WgtMgr(make(map[string]WgtInfo))
|
||||||
|
return wm
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) AddWgt(wgt Widget) {
|
||||||
|
wm[wgt.Id()] = NewWgtInfo(wgt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) RmWgt(wgt Widget) {
|
||||||
|
wm.RmWgtById(wgt.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) RmWgtById(id string) {
|
||||||
|
delete(wm, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) AddWgtHandler(id, path string, h func(Event)) {
|
||||||
|
if w, ok := wm[id]; ok {
|
||||||
|
w.Handlers[path] = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) RmWgtHandler(id, path string) {
|
||||||
|
if w, ok := wm[id]; ok {
|
||||||
|
delete(w.Handlers, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var counter struct {
|
||||||
|
sync.RWMutex
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenId() string {
|
||||||
|
counter.Lock()
|
||||||
|
defer counter.Unlock()
|
||||||
|
|
||||||
|
counter.count += 1
|
||||||
|
return fmt.Sprintf("%d", counter.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) WgtHandlersHook() func(Event) {
|
||||||
|
return func(e Event) {
|
||||||
|
for _, v := range wm {
|
||||||
|
if k := findMatch(v.Handlers, e.Path); k != "" {
|
||||||
|
v.Handlers[k](e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefaultWgtMgr WgtMgr
|
Loading…
Reference in New Issue
Block a user