ctop/widgets/view.go

97 lines
1.8 KiB
Go
Raw Normal View History

2017-11-25 18:30:50 +00:00
package widgets
import (
"fmt"
2017-11-28 13:40:43 +00:00
ui "github.com/gizak/termui"
2017-11-25 18:30:50 +00:00
)
type TextView struct {
ui.Block
2017-11-28 13:40:43 +00:00
inputStream <-chan string
2017-11-25 18:30:50 +00:00
render chan bool
Text []string // all the text
TextOut []string // text to be displayed
TextFgColor ui.Attribute
TextBgColor ui.Attribute
padding Padding
}
2017-11-28 13:40:43 +00:00
func NewTextView(lines <-chan string) *TextView {
2017-11-25 18:30:50 +00:00
i := &TextView{
Block: *ui.NewBlock(),
inputStream: lines,
render: make(chan bool),
Text: []string{},
TextOut: []string{},
TextFgColor: ui.ThemeAttr("menu.text.fg"),
TextBgColor: ui.ThemeAttr("menu.text.bg"),
padding: Padding{4, 2},
}
i.BorderFg = ui.ThemeAttr("menu.border.fg")
i.BorderLabelFg = ui.ThemeAttr("menu.label.fg")
2017-11-28 13:55:29 +00:00
i.Resize()
2017-11-25 18:30:50 +00:00
i.readInputLoop()
i.renderLoop()
return i
}
2017-11-28 13:55:29 +00:00
func (i *TextView) Resize() {
ui.Clear()
i.Height = ui.TermHeight()
i.Width = ui.TermWidth()
}
2017-11-25 18:30:50 +00:00
func (i *TextView) Buffer() ui.Buffer {
var cell ui.Cell
buf := i.Block.Buffer()
x := i.Block.X + i.padding[0]
y := i.Block.Y + i.padding[1]
2017-11-28 13:55:29 +00:00
maxWidth := i.Width - (i.padding[0] * 2)
2017-11-25 18:30:50 +00:00
for _, line := range i.TextOut {
2017-11-28 13:55:29 +00:00
// truncate lines longer than maxWidth
if len(line) > maxWidth {
line = fmt.Sprintf("%s...", line[:maxWidth-3])
}
2017-11-25 18:30:50 +00:00
for _, ch := range line {
cell = ui.Cell{Ch: ch, Fg: i.TextFgColor, Bg: i.TextBgColor}
buf.Set(x, y, cell)
x++
}
x = i.Block.X + i.padding[0]
y++
}
return buf
}
func (i *TextView) renderLoop() {
go func() {
for range i.render {
size := i.Height - (i.padding[1] * 2)
if size > len(i.Text) {
size = len(i.Text)
}
2017-11-28 13:40:43 +00:00
i.TextOut = i.Text[len(i.Text)-size:]
2017-11-25 18:30:50 +00:00
ui.Render(i)
}
}()
}
func (i *TextView) readInputLoop() {
go func() {
for line := range i.inputStream {
i.Text = append(i.Text, line)
i.render <- true
}
close(i.render)
}()
}