Bridge Tabpane

This commit is contained in:
Zack Guo 2016-11-03 01:41:47 -04:00
parent d29684eba4
commit 8e01231aa1
3 changed files with 98 additions and 82 deletions

View File

@ -18,12 +18,12 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
header := termui.NewPar("Press q to quit, Press j or k to switch tabs") header := termui.NewPar("Press q to quit, Press j or k to switch tabs")
header.Height = 1 header.Height = 1
header.Width = 50 header.Width = 50
header.HasBorder = false header.Border = false
header.TextBgColor = termui.ColorBlue header.TextBgColor = termui.ColorBlue
tab1 := extra.NewTab("pierwszy") tab1 := extra.NewTab("pierwszy")
@ -32,7 +32,7 @@ func main() {
par2.Width = 37 par2.Width = 37
par2.Y = 0 par2.Y = 0
par2.BorderLabel = "Keys" par2.BorderLabel = "Keys"
par2.Border.FgColor = termui.ColorYellow par2.BorderFg = termui.ColorYellow
tab1.AddBlocks(par2) tab1.AddBlocks(par2)
tab2 := extra.NewTab("drugi") tab2 := extra.NewTab("drugi")
@ -57,29 +57,25 @@ func main() {
tabpane := extra.NewTabpane() tabpane := extra.NewTabpane()
tabpane.Y = 1 tabpane.Y = 1
tabpane.Width = 30 tabpane.Width = 30
tabpane.HasBorder = true tabpane.Border = true
tabpane.SetTabs(*tab1, *tab2, *tab3, *tab4, *tab5, *tab6) tabpane.SetTabs(*tab1, *tab2, *tab3, *tab4, *tab5, *tab6)
evt := termui.EventCh()
termui.Render(header, tabpane) termui.Render(header, tabpane)
for { termui.Handle("/sys/kbd/q", func(termui.Event) {
select { termui.StopLoop()
case e := <-evt: })
if e.Type == termui.EventKey {
switch e.Ch { termui.Handle("/sys/kbd/j", func(termui.Event) {
case 'q':
return
case 'j':
tabpane.SetActiveLeft() tabpane.SetActiveLeft()
termui.Render(header, tabpane) termui.Render(header, tabpane)
case 'k': })
termui.Handle("/sys/kbd/k", func(termui.Event) {
tabpane.SetActiveRight() tabpane.SetActiveRight()
termui.Render(header, tabpane) termui.Render(header, tabpane)
} })
}
} termui.Loop()
}
} }

View File

@ -17,7 +17,6 @@ import (
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/gizak/termui" "github.com/gizak/termui"
"github.com/gizak/termui/extra" "github.com/gizak/termui/extra"
@ -284,12 +283,12 @@ func main() {
termWidth := 70 termWidth := 70
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
header := termui.NewPar("Press q to quit, Press j or k to switch tabs") header := termui.NewPar("Press q to quit, Press j or k to switch tabs")
header.Height = 1 header.Height = 1
header.Width = 50 header.Width = 50
header.HasBorder = false header.Border = false
header.TextBgColor = termui.ColorBlue header.TextBgColor = termui.ColorBlue
tabCpu := extra.NewTab("CPU") tabCpu := extra.NewTab("CPU")
@ -298,7 +297,7 @@ func main() {
tabpane := extra.NewTabpane() tabpane := extra.NewTabpane()
tabpane.Y = 1 tabpane.Y = 1
tabpane.Width = 30 tabpane.Width = 30
tabpane.HasBorder = false tabpane.Border = false
cs, errcs := getCpusStatsMap() cs, errcs := getCpusStatsMap()
cpusStats := NewCpusStats(cs) cpusStats := NewCpusStats(cs)
@ -336,23 +335,21 @@ func main() {
termui.Render(header, tabpane) termui.Render(header, tabpane)
evt := termui.EventCh() termui.Handle("/sys/kbd/q", func(termui.Event) {
for { termui.StopLoop()
select { })
case e := <-evt:
if e.Type == termui.EventKey { termui.Handle("/sys/kbd/j", func(termui.Event) {
switch e.Ch {
case 'q':
return
case 'j':
tabpane.SetActiveLeft() tabpane.SetActiveLeft()
termui.Render(header, tabpane) termui.Render(header, tabpane)
case 'k': })
termui.Handle("/sys/kbd/k", func(termui.Event) {
tabpane.SetActiveRight() tabpane.SetActiveRight()
termui.Render(header, tabpane) termui.Render(header, tabpane)
} })
}
case <-time.After(time.Second): termui.Handle("/timer/1s", func(e termui.Event) {
cs, errcs := getCpusStatsMap() cs, errcs := getCpusStatsMap()
if errcs != nil { if errcs != nil {
panic(errcs) panic(errcs)
@ -365,8 +362,8 @@ func main() {
panic(errm) panic(errm)
} }
memTabElems.Update(ms) memTabElems.Update(ms)
termui.Render(header, tabpane) termui.Render(header, tabpane)
} })
}
termui.Loop()
} }

View File

@ -28,14 +28,13 @@ func (tab *Tab) AddBlocks(rs ...Bufferer) {
} }
} }
func (tab *Tab) Buffer() []Point { func (tab *Tab) Buffer() Buffer {
points := []Point{} buf := NewBuffer()
for blockNum := 0; blockNum < len(tab.Blocks); blockNum++ { for blockNum := 0; blockNum < len(tab.Blocks); blockNum++ {
b := &tab.Blocks[blockNum] b := tab.Blocks[blockNum]
blockPoints := (*b).Buffer() buf.Merge(b.Buffer())
points = append(points, blockPoints...)
} }
return points return buf
} }
type Tabpane struct { type Tabpane struct {
@ -52,7 +51,7 @@ func NewTabpane() *Tabpane {
Block: *NewBlock(), Block: *NewBlock(),
activeTabIndex: 0, activeTabIndex: 0,
offTabText: 0, offTabText: 0,
ActiveTabBg: Theme().TabActiveBg} ActiveTabBg: ThemeAttr("bg.tab.active")}
return &tp return &tp
} }
@ -111,17 +110,35 @@ func (tp *Tabpane) fitsWidth() bool {
} }
func (tp *Tabpane) align() { func (tp *Tabpane) align() {
if !tp.fitsWidth() && !tp.HasBorder { if !tp.fitsWidth() && !tp.Border {
tp.PaddingLeft += 1 tp.PaddingLeft += 1
tp.PaddingRight += 1 tp.PaddingRight += 1
tp.Block.Align() tp.Block.Align()
} }
} }
// bridge the old Point stuct
type point struct {
X int
Y int
Ch rune
Bg Attribute
Fg Attribute
}
func buf2pt(b Buffer) []point {
ps := make([]point, 0, len(b.CellMap))
for k, c := range b.CellMap {
ps = append(ps, point{X: k.X, Y: k.Y, Ch: c.Ch, Fg: c.Fg, Bg: c.Bg})
}
return ps
}
// Adds the point only if it is visible in Tabpane. // Adds the point only if it is visible in Tabpane.
// Point can be invisible if concatenation of Tab's texts is widther then // Point can be invisible if concatenation of Tab's texts is widther then
// innerWidth of Tabpane // innerWidth of Tabpane
func (tp *Tabpane) addPoint(ptab []Point, charOffset *int, oftX *int, points ...Point) []Point { func (tp *Tabpane) addPoint(ptab []point, charOffset *int, oftX *int, points ...point) []point {
if *charOffset < tp.offTabText || tp.offTabText+tp.InnerWidth() < *charOffset { if *charOffset < tp.offTabText || tp.offTabText+tp.InnerWidth() < *charOffset {
*charOffset++ *charOffset++
return ptab return ptab
@ -136,10 +153,10 @@ func (tp *Tabpane) addPoint(ptab []Point, charOffset *int, oftX *int, points ...
} }
// Draws the point and redraws upper and lower border points (if it has one) // Draws the point and redraws upper and lower border points (if it has one)
func (tp *Tabpane) drawPointWithBorder(p Point, ch rune, chbord rune, chdown rune, chup rune) []Point { func (tp *Tabpane) drawPointWithBorder(p point, ch rune, chbord rune, chdown rune, chup rune) []point {
var addp []Point var addp []point
p.Ch = ch p.Ch = ch
if tp.HasBorder { if tp.Border {
p.Ch = chdown p.Ch = chdown
p.Y = tp.InnerY() - 1 p.Y = tp.InnerY() - 1
addp = append(addp, p) addp = append(addp, p)
@ -152,8 +169,8 @@ func (tp *Tabpane) drawPointWithBorder(p Point, ch rune, chbord rune, chdown run
return append(addp, p) return append(addp, p)
} }
func (tp *Tabpane) Buffer() []Point { func (tp *Tabpane) Buffer() Buffer {
if tp.HasBorder { if tp.Border {
tp.Height = 3 tp.Height = 3
} else { } else {
tp.Height = 1 tp.Height = 1
@ -161,14 +178,15 @@ func (tp *Tabpane) Buffer() []Point {
if tp.Width > tp.posTabText[len(tp.Tabs)]+2 { if tp.Width > tp.posTabText[len(tp.Tabs)]+2 {
tp.Width = tp.posTabText[len(tp.Tabs)] + 2 tp.Width = tp.posTabText[len(tp.Tabs)] + 2
} }
ps := tp.Block.Buffer() buf := tp.Block.Buffer()
ps := buf2pt(buf)
tp.align() tp.align()
if tp.InnerHeight() <= 0 || tp.InnerWidth() <= 0 { if tp.InnerHeight() <= 0 || tp.InnerWidth() <= 0 {
return nil return NewBuffer()
} }
oftX := tp.InnerX() oftX := tp.InnerX()
charOffset := 0 charOffset := 0
pt := Point{Bg: tp.Border.BgColor, Fg: tp.Border.FgColor} pt := point{Bg: tp.BorderBg, Fg: tp.BorderFg}
for i, tab := range tp.Tabs { for i, tab := range tp.Tabs {
if i != 0 { if i != 0 {
@ -184,11 +202,11 @@ func (tp *Tabpane) Buffer() []Point {
rs := []rune(tab.Label) rs := []rune(tab.Label)
for k := 0; k < len(rs); k++ { for k := 0; k < len(rs); k++ {
addp := make([]Point, 0, 2) addp := make([]point, 0, 2)
if i == tp.activeTabIndex && tp.HasBorder { if i == tp.activeTabIndex && tp.Border {
pt.Ch = ' ' pt.Ch = ' '
pt.Y = tp.InnerY() + 1 pt.Y = tp.InnerY() + 1
pt.Bg = tp.Border.BgColor pt.Bg = tp.BorderBg
addp = append(addp, pt) addp = append(addp, pt)
pt.Bg = tp.ActiveTabBg pt.Bg = tp.ActiveTabBg
} }
@ -199,14 +217,14 @@ func (tp *Tabpane) Buffer() []Point {
addp = append(addp, pt) addp = append(addp, pt)
ps = tp.addPoint(ps, &charOffset, &oftX, addp...) ps = tp.addPoint(ps, &charOffset, &oftX, addp...)
} }
pt.Bg = tp.Border.BgColor pt.Bg = tp.BorderBg
if !tp.fitsWidth() { if !tp.fitsWidth() {
all := tp.checkAlignment() all := tp.checkAlignment()
pt.X = tp.InnerX() - 1 pt.X = tp.InnerX() - 1
pt.Ch = '*' pt.Ch = '*'
if tp.HasBorder { if tp.Border {
pt.Ch = VERTICAL_LINE pt.Ch = VERTICAL_LINE
} }
ps = append(ps, pt) ps = append(ps, pt)
@ -218,7 +236,7 @@ func (tp *Tabpane) Buffer() []Point {
pt.X = tp.InnerX() + tp.InnerWidth() pt.X = tp.InnerX() + tp.InnerWidth()
pt.Ch = '*' pt.Ch = '*'
if tp.HasBorder { if tp.Border {
pt.Ch = VERTICAL_LINE pt.Ch = VERTICAL_LINE
} }
ps = append(ps, pt) ps = append(ps, pt)
@ -230,7 +248,8 @@ func (tp *Tabpane) Buffer() []Point {
//draw tab content below the Tabpane //draw tab content below the Tabpane
if i == tp.activeTabIndex { if i == tp.activeTabIndex {
blockPoints := tab.Buffer() blockPoints := buf2pt(tab.Buffer())
panic(len(blockPoints))
for i := 0; i < len(blockPoints); i++ { for i := 0; i < len(blockPoints); i++ {
blockPoints[i].Y += tp.Height + tp.Y blockPoints[i].Y += tp.Height + tp.Y
} }
@ -238,5 +257,9 @@ func (tp *Tabpane) Buffer() []Point {
} }
} }
return ps for _, v := range ps {
buf.Set(v.X, v.Y, NewCell(v.Ch, v.Fg, v.Bg))
}
return buf
} }