Bridge Tabpane
This commit is contained in:
parent
d29684eba4
commit
8e01231aa1
@ -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':
|
tabpane.SetActiveLeft()
|
||||||
return
|
termui.Render(header, tabpane)
|
||||||
case 'j':
|
})
|
||||||
tabpane.SetActiveLeft()
|
|
||||||
termui.Render(header, tabpane)
|
termui.Handle("/sys/kbd/k", func(termui.Event) {
|
||||||
case 'k':
|
tabpane.SetActiveRight()
|
||||||
tabpane.SetActiveRight()
|
termui.Render(header, tabpane)
|
||||||
termui.Render(header, tabpane)
|
})
|
||||||
}
|
|
||||||
}
|
termui.Loop()
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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,37 +335,35 @@ 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 {
|
|
||||||
switch e.Ch {
|
|
||||||
case 'q':
|
|
||||||
return
|
|
||||||
case 'j':
|
|
||||||
tabpane.SetActiveLeft()
|
|
||||||
termui.Render(header, tabpane)
|
|
||||||
case 'k':
|
|
||||||
tabpane.SetActiveRight()
|
|
||||||
termui.Render(header, tabpane)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
cs, errcs := getCpusStatsMap()
|
|
||||||
if errcs != nil {
|
|
||||||
panic(errcs)
|
|
||||||
}
|
|
||||||
cpusStats.tick(cs)
|
|
||||||
cpuTabElems.Update(*cpusStats)
|
|
||||||
|
|
||||||
ms, errm := getMemStats()
|
termui.Handle("/sys/kbd/j", func(termui.Event) {
|
||||||
if errm != nil {
|
tabpane.SetActiveLeft()
|
||||||
panic(errm)
|
termui.Render(header, tabpane)
|
||||||
}
|
})
|
||||||
memTabElems.Update(ms)
|
|
||||||
|
|
||||||
termui.Render(header, tabpane)
|
termui.Handle("/sys/kbd/k", func(termui.Event) {
|
||||||
|
tabpane.SetActiveRight()
|
||||||
|
termui.Render(header, tabpane)
|
||||||
|
})
|
||||||
|
|
||||||
|
termui.Handle("/timer/1s", func(e termui.Event) {
|
||||||
|
cs, errcs := getCpusStatsMap()
|
||||||
|
if errcs != nil {
|
||||||
|
panic(errcs)
|
||||||
}
|
}
|
||||||
}
|
cpusStats.tick(cs)
|
||||||
|
cpuTabElems.Update(*cpusStats)
|
||||||
|
|
||||||
|
ms, errm := getMemStats()
|
||||||
|
if errm != nil {
|
||||||
|
panic(errm)
|
||||||
|
}
|
||||||
|
memTabElems.Update(ms)
|
||||||
|
termui.Render(header, tabpane)
|
||||||
|
})
|
||||||
|
|
||||||
|
termui.Loop()
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user