func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") strs := []string{ "[0] github.com/gizak/termui", "[1] 你好,世界", "[2] こんにちは世界", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"} ls := termui.NewList() ls.Items = strs ls.ItemFgColor = termui.ColorYellow ls.Border.Label = "List" ls.Height = 7 ls.Width = 25 ls.Y = 0 termui.Render(ls) <-termui.EventCh() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") bc := termui.NewBarChart() data := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} bc.Border.Label = "Bar Chart" bc.Data = data bc.Width = 26 bc.Height = 10 bc.DataLabels = bclabels bc.TextColor = termui.ColorGreen bc.BarColor = termui.ColorRed bc.NumColor = termui.ColorYellow termui.Render(bc) <-termui.EventCh() }
func init() { err := termui.Init() if err != nil { panic(err) } termui.UseTheme("default") ui = NewUi() refreshTicker := time.NewTicker(time.Millisecond * 50) evt := termui.EventCh() ui.refresh() go func() { for { select { case e := <-evt: if e.Type == termui.EventKey && e.Ch == 'q' { os.Exit(1) } if e.Type == termui.EventResize { ui.gridWidth = termui.TermWidth() ui.refresh() } case <-refreshTicker.C: ui.refresh() } } }() }
// Init creates widgets, sets sizes and labels. func (t *TermUISingle) Init(data UIData) error { err := termui.Init() if err != nil { return err } t.Sparklines = make(map[VarName]*termui.Sparkline) termui.UseTheme("helloworld") t.Title = func() *termui.Par { p := termui.NewPar("") p.Height = 3 p.TextFgColor = termui.ColorWhite p.Border.Label = "Services Monitor" p.Border.FgColor = termui.ColorCyan return p }() t.Status = func() *termui.Par { p := termui.NewPar("") p.Height = 3 p.TextFgColor = termui.ColorWhite p.Border.Label = "Status" p.Border.FgColor = termui.ColorCyan return p }() t.Pars = make([]*termui.Par, len(data.Vars)) for i, name := range data.Vars { par := termui.NewPar("") par.TextFgColor = colorByKind(name.Kind()) par.Border.Label = name.Short() par.Border.LabelFgColor = termui.ColorGreen par.Height = 3 t.Pars[i] = par } var sparklines []termui.Sparkline for _, name := range data.Vars { spl := termui.NewSparkline() spl.Height = 1 spl.TitleColor = colorByKind(name.Kind()) spl.LineColor = colorByKind(name.Kind()) spl.Title = name.Long() sparklines = append(sparklines, spl) } t.Sparkline = func() *termui.Sparklines { s := termui.NewSparklines(sparklines...) s.Height = 2*len(sparklines) + 2 s.HasBorder = true s.Border.Label = fmt.Sprintf("Monitoring") return s }() t.Relayout() return nil }
func newTerminalUI(appName string) error { if err := ui.Init(); err != nil { return err } ui.UseTheme("helloworld") // usage text usageText := fmt.Sprintf(`Show live statistics for [%s] :Press 'q' or 'ctrl-c' to exit :Press 'PageUp' to increase app instances :Press 'PageDown' to decrease app instances`, appName) usage := ui.NewPar(usageText) usage.Height = 12 usage.TextFgColor = ui.ColorWhite usage.Border.Label = "Usage" usage.Border.FgColor = ui.ColorCyan // summary text summary := ui.NewPar("") summary.Height = 12 summary.TextFgColor = ui.ColorRed summary.Border.Label = "Summary" summary.Border.FgColor = ui.ColorCyan // cpu sparklines data := [400]int{} line := ui.NewSparkline() line.Data = data[:] line.Height = 4 line.LineColor = colors[0] cpu := ui.NewSparklines(line) cpu.Height = 7 cpu.Border.Label = "CPU Usage" // memory gauges mem := make([]*ui.Gauge, 1) for i := range mem { mem[i] = ui.NewGauge() mem[i].Percent = 0 mem[i].Height = 5 } // disk bars disk := ui.NewBarChart() disk.Border.Label = "Disk Usage (in MB)" disk.Data = []int{0, 0, 0, 0, 0, 0, 0, 0} disk.Height = 12 disk.BarWidth = 10 disk.DataLabels = []string{"I: 0", "I: 1", "I: 2", "I: 3", "I: 4", "I: 5", "I: 6", "I: 7"} disk.TextColor = ui.ColorWhite disk.BarColor = ui.ColorYellow disk.NumColor = ui.ColorWhite term = &TerminalUI{ui.Body, usage, summary, cpu, mem, disk} return nil }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6} spl0 := termui.NewSparkline() spl0.Data = data[3:] spl0.Title = "Sparkline 0" spl0.LineColor = termui.ColorGreen // single spls0 := termui.NewSparklines(spl0) spls0.Height = 2 spls0.Width = 20 spls0.HasBorder = false spl1 := termui.NewSparkline() spl1.Data = data spl1.Title = "Sparkline 1" spl1.LineColor = termui.ColorRed spl2 := termui.NewSparkline() spl2.Data = data[5:] spl2.Title = "Sparkline 2" spl2.LineColor = termui.ColorMagenta // group spls1 := termui.NewSparklines(spl0, spl1, spl2) spls1.Height = 8 spls1.Width = 20 spls1.Y = 3 spls1.Border.Label = "Group Sparklines" spl3 := termui.NewSparkline() spl3.Data = data spl3.Title = "Enlarged Sparkline" spl3.Height = 8 spl3.LineColor = termui.ColorYellow spls2 := termui.NewSparklines(spl3) spls2.Height = 11 spls2.Width = 30 spls2.Border.FgColor = termui.ColorCyan spls2.X = 21 spls2.Border.Label = "Tweeked Sparkline" termui.Render(spls0, spls1, spls2) <-termui.EventCh() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") sinps := (func() []float64 { n := 220 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/5) } return ps })() lc0 := termui.NewLineChart() lc0.Border.Label = "braille-mode Line Chart" lc0.Data = sinps lc0.Width = 50 lc0.Height = 12 lc0.X = 0 lc0.Y = 0 lc0.AxesColor = termui.ColorWhite lc0.LineColor = termui.ColorGreen | termui.AttrBold lc1 := termui.NewLineChart() lc1.Border.Label = "dot-mode Line Chart" lc1.Mode = "dot" lc1.Data = sinps lc1.Width = 26 lc1.Height = 12 lc1.X = 51 lc1.DotStyle = '+' lc1.AxesColor = termui.ColorWhite lc1.LineColor = termui.ColorYellow | termui.AttrBold lc2 := termui.NewLineChart() lc2.Border.Label = "dot-mode Line Chart" lc2.Mode = "dot" lc2.Data = sinps[4:] lc2.Width = 77 lc2.Height = 16 lc2.X = 0 lc2.Y = 12 lc2.AxesColor = termui.ColorWhite lc2.LineColor = termui.ColorCyan | termui.AttrBold termui.Render(lc0, lc1, lc2) <-termui.EventCh() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") g0 := termui.NewGauge() g0.Percent = 40 g0.Width = 50 g0.Height = 3 g0.Border.Label = "Slim Gauge" g0.BarColor = termui.ColorRed g0.Border.FgColor = termui.ColorWhite g0.Border.LabelFgColor = termui.ColorCyan g2 := termui.NewGauge() g2.Percent = 60 g2.Width = 50 g2.Height = 3 g2.PercentColor = termui.ColorBlue g2.Y = 3 g2.Border.Label = "Slim Gauge" g2.BarColor = termui.ColorYellow g2.Border.FgColor = termui.ColorWhite g1 := termui.NewGauge() g1.Percent = 30 g1.Width = 50 g1.Height = 5 g1.Y = 6 g1.Border.Label = "Big Gauge" g1.PercentColor = termui.ColorYellow g1.BarColor = termui.ColorGreen g1.Border.FgColor = termui.ColorWhite g1.Border.LabelFgColor = termui.ColorMagenta g3 := termui.NewGauge() g3.Percent = 50 g3.Width = 50 g3.Height = 3 g3.Y = 11 g3.Border.Label = "Gauge with custom label" g3.Label = "{{percent}}% (100MBs free)" g3.LabelAlign = termui.AlignRight termui.Render(g0, g1, g2, g3) <-termui.EventCh() }
// TODO make new widget traffic light // Waiting for canvas from termui func initWidgets() (*ui.List, *ui.Par, *ui.Par, *ui.Par, *ui.Par) { ui.UseTheme("Jenkins Term UI") title := "q to quit - " + *jenkinsUrl if *filter != "" { title += " filter on " + *filter } p := ui.NewPar(title) _, h := tm.Size() p.Height = 3 p.TextFgColor = ui.ColorWhite p.Border.Label = "Go Jenkins Dashboard" p.Border.FgColor = ui.ColorCyan info := ui.NewPar("") info.Height = 3 info.Y = h - 3 info.TextFgColor = ui.ColorWhite info.Border.FgColor = ui.ColorWhite ls := ui.NewList() ls.ItemFgColor = ui.ColorYellow ls.Border.Label = "Jobs" ls.Y = 3 ls.Height = h - 6 width, height := 4, 5 redbox, yellowbox, greenbox := ui.NewPar(""), ui.NewPar(""), ui.NewPar("") redbox.HasBorder, yellowbox.HasBorder, greenbox.HasBorder = false, false, false redbox.Height, yellowbox.Height, greenbox.Height = height, height, height redbox.Width, yellowbox.Width, greenbox.Width = width, width, width redbox.BgColor = ui.ColorRed yellowbox.BgColor = ui.ColorYellow greenbox.BgColor = ui.ColorGreen ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 0, p), ), ui.NewRow( ui.NewCol(10, 0, ls), ui.NewCol(2, 0, redbox, yellowbox, greenbox), ), ui.NewRow( ui.NewCol(12, 0, info), ), ) ui.Body.Align() ui.Render(ui.Body) return ls, info, redbox, yellowbox, greenbox }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() if termutil.Isatty(os.Stdin.Fd()) { panic("...") } eventChan := make(chan termbox.Event) go func() { for { eventChan <- termbox.PollEvent() } }() dataChan := make(chan string) go func() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { dataChan <- scanner.Text() } if err := scanner.Err(); err != nil { panic(err) } }() summary := cntbar.NewSummary() tick := time.Tick(tickInterval) termui.UseTheme("helloworld") render(summary) for { select { case event := <-eventChan: if event.Type == termbox.EventKey && event.Ch == 'q' { return } case data := <-dataChan: summary.CountUp(data) case <-tick: render(summary) } } }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") g0 := termui.NewGauge() g0.Percent = 40 g0.Width = 50 g0.Height = 3 g0.Border.Label = "Slim Gauge" g0.BarColor = termui.ColorRed g0.Border.FgColor = termui.ColorWhite g0.Border.LabelFgColor = termui.ColorCyan g2 := termui.NewGauge() g2.Percent = 60 g2.Width = 50 g2.Height = 3 g2.PercentColor = termui.ColorBlue g2.Y = 3 g2.Border.Label = "Slim Gauge" g2.BarColor = termui.ColorYellow g2.Border.FgColor = termui.ColorWhite g1 := termui.NewGauge() g1.Percent = 30 g1.Width = 50 g1.Height = 5 g1.Y = 6 g1.Border.Label = "Big Gauge" g1.PercentColor = termui.ColorYellow g1.BarColor = termui.ColorGreen g1.Border.FgColor = termui.ColorWhite g1.Border.LabelFgColor = termui.ColorMagenta termui.Render(g0, g1, g2) termbox.PollEvent() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") bc := termui.NewMBarChart() math := []int{90, 85, 90, 80} english := []int{70, 85, 75, 60} science := []int{75, 60, 80, 85} compsci := []int{100, 100, 100, 100} bc.Data[0] = math bc.Data[1] = english bc.Data[2] = science bc.Data[3] = compsci studentsName := []string{"Ken", "Rob", "Dennis", "Linus"} bc.Border.Label = "Student's Marks X-Axis=Name Y-Axis=Marks[Math,English,Science,ComputerScience] in %" bc.Width = 100 bc.Height = 50 bc.Y = 10 bc.BarWidth = 10 bc.DataLabels = studentsName bc.ShowScale = true //Show y_axis scale value (min and max) bc.SetMax(400) bc.TextColor = termui.ColorGreen //this is color for label (x-axis) bc.BarColor[3] = termui.ColorGreen //BarColor for computerscience bc.BarColor[1] = termui.ColorYellow //Bar Color for english bc.NumColor[3] = termui.ColorRed // Num color for computerscience bc.NumColor[1] = termui.ColorRed // num color for english //Other colors are automatically populated, btw All the students seems do well in computerscience. :p termui.Render(bc) <-termui.EventCh() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") par0 := termui.NewPar("Borderless Text") par0.Height = 1 par0.Width = 20 par0.Y = 1 par0.HasBorder = false par1 := termui.NewPar("你好,世界。") par1.Height = 3 par1.Width = 17 par1.X = 20 par1.Border.Label = "标签" par2 := termui.NewPar("Simple colored text\nwith label. It [can be](RED) multilined with \\n or [break automatically](GREEN, BOLD)") par2.RendererFactory = termui.MarkdownTextRendererFactory{} par2.Height = 5 par2.Width = 37 par2.Y = 4 par2.Border.Label = "Multiline" par2.Border.FgColor = termui.ColorYellow par3 := termui.NewPar("Long text with label and it is auto trimmed.") par3.Height = 3 par3.Width = 37 par3.Y = 9 par3.Border.Label = "Auto Trim" termui.Render(par0, par1, par2, par3) <-termui.EventCh() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") par0 := termui.NewPar("Borderless Text") par0.Height = 1 par0.Width = 20 par0.Y = 1 par0.HasBorder = false par1 := termui.NewPar("你好,世界。") par1.Height = 3 par1.Width = 17 par1.X = 20 par1.Border.Label = "标签" par2 := termui.NewPar("Simple text\nwith label. It can be multilined with \\n or break automatically") par2.Height = 5 par2.Width = 37 par2.Y = 4 par2.Border.Label = "Multiline" par2.Border.FgColor = termui.ColorYellow par3 := termui.NewPar("Long text with label and it is auto trimmed.") par3.Height = 3 par3.Width = 37 par3.Y = 9 par3.Border.Label = "Auto Trim" termui.Render(par0, par1, par2, par3) termbox.PollEvent() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() hiddenMarkdownList := hideList(markdownList()) wrappedMarkdownList := wrapList(markdownList()) hiddenEscapeList := hideList(escapeList()) wrappedEscapeList := wrapList(escapeList()) lists := []termui.Bufferer{ hiddenEscapeList, hiddenMarkdownList, wrappedMarkdownList, wrappedEscapeList, } termui.UseTheme("helloworld") termui.Render(lists...) termbox.PollEvent() }
func main() { err := ui.Init() if err != nil { panic(err) } defer ui.Close() sinps := (func() []float64 { n := 400 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/5) } return ps })() sinpsint := (func() []int { ps := make([]int, len(sinps)) for i, v := range sinps { ps[i] = int(100*v + 10) } return ps })() ui.UseTheme("helloworld") spark := ui.Sparkline{} spark.Height = 8 spdata := sinpsint spark.Data = spdata spark.LineColor = ui.ColorCyan spark.TitleColor = ui.ColorWhite sp := ui.NewSparklines(spark) sp.Height = 11 sp.Border.Label = "Sparkline" lc := ui.NewLineChart() lc.Border.Label = "braille-mode Line Chart" lc.Data = sinps lc.Height = 11 lc.AxesColor = ui.ColorWhite lc.LineColor = ui.ColorYellow | ui.AttrBold gs := make([]*ui.Gauge, 3) for i := range gs { gs[i] = ui.NewGauge() gs[i].Height = 2 gs[i].HasBorder = false gs[i].Percent = i * 10 gs[i].PaddingBottom = 1 gs[i].BarColor = ui.ColorRed } ls := ui.NewList() ls.HasBorder = false ls.Items = []string{ "[1] Downloading File 1", "", // == \newline "[2] Downloading File 2", "", "[3] Uploading File 3", } ls.Height = 5 par := ui.NewPar("<> This row has 3 columns\n<- Widgets can be stacked up like left side\n<- Stacked widgets are treated as a single widget") par.Height = 5 par.Border.Label = "Demonstration" // build layout ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, sp), ui.NewCol(6, 0, lc)), ui.NewRow( ui.NewCol(3, 0, ls), ui.NewCol(3, 0, gs[0], gs[1], gs[2]), ui.NewCol(6, 0, par))) // calculate layout ui.Body.Align() draw := func(t int) { sp.Lines[0].Data = spdata[t:] lc.Data = sinps[2*t:] ui.Render(ui.Body) } evt := make(chan tm.Event) go func() { for { evt <- tm.PollEvent() } }() i := 0 for { select { case e := <-evt: if e.Type == tm.EventKey && e.Ch == 'q' { return } if e.Type == tm.EventResize { ui.Body.Width = ui.TermWidth() ui.Body.Align() } default: for _, g := range gs { g.Percent = (g.Percent + 3) % 100 } draw(i) i++ if i == 102 { return } time.Sleep(time.Second / 2) } } }
func main() { // Init err := ui.Init() if err != nil { panic(err) } defer ui.Close() // Theme Setting ui.UseTheme("helloworld") // Setup the CPU Gauge cpuGauge := ui.NewGauge() cpuGauge.Height = 2 cpuGauge.BarColor = ui.ColorRed cpuGauge.HasBorder = false cpuGauge.PaddingBottom = 1 go UpdateGenericGauge(cpuGauge, GetCPUPercentage) // Setup the RAM Gauge ramGauge := ui.NewGauge() ramGauge.Height = 2 ramGauge.BarColor = ui.ColorGreen ramGauge.HasBorder = false ramGauge.PaddingBottom = 1 go UpdateGenericGauge(ramGauge, GetRAMPercentage) // Setup the Label list ls := ui.NewList() ls.HasBorder = false ls.Items = []string{ "CPU", "", "RAM", } ls.Height = 5 // Setup the CPU Line Chart cpuLineChart := ui.NewLineChart() cpuLineChart.Width = 50 cpuLineChart.Height = 11 cpuLineChart.Border.Label = "CPU Usage" cpuLineChart.AxesColor = ui.ColorWhite cpuLineChart.LineColor = ui.ColorGreen | ui.AttrBold go UpdateGenericChart(cpuLineChart, GetCPUPercentage) // Setup the RAM Line Chart ramLineChart := ui.NewLineChart() ramLineChart.Width = 50 ramLineChart.Height = 11 ramLineChart.Border.Label = "RAM Usage" ramLineChart.AxesColor = ui.ColorWhite ramLineChart.LineColor = ui.ColorGreen | ui.AttrBold go UpdateGenericChart(ramLineChart, GetRAMPercentage) // Setup the layout ui.Body.AddRows( ui.NewRow( ui.NewCol(3, 0, cpuGauge, ramGauge), ui.NewCol(3, 0, ls), ), ui.NewRow( ui.NewCol(6, 0, cpuLineChart), ui.NewCol(6, 0, ramLineChart), ), ) // Align ui.Body.Align() // Create the event polling system evt := make(chan tm.Event) go func() { for { evt <- tm.PollEvent() } }() for { select { case e := <-evt: if e.Type == tm.EventKey && e.Ch == 'q' { return } if e.Type == tm.EventResize { ui.Body.Width = ui.TermWidth() ui.Body.Align() } default: ui.Render(ui.Body) time.Sleep(time.Second / 2) } } }
func main() { err := ui.Init() if err != nil { panic(err) } defer ui.Close() ui.UseTheme("helloworld") p := ui.NewPar(":PRESS q TO QUIT DEMO") p.Height = 3 p.Width = 50 p.Border.Label = "Text Box" strs := []string{"[0] gizak/termui", "[1] editbox.go", "[2] iterrupt.go", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"} list := ui.NewList() list.Items = strs list.Border.Label = "List" list.Height = 7 list.Width = 25 list.Y = 4 g := ui.NewGauge() g.Percent = 50 g.Width = 50 g.Height = 3 g.Y = 11 g.Border.Label = "Gauge" spark := ui.NewSparkline() spark.Title = "srv 0:" spdata := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6} spark.Data = spdata spark1 := ui.NewSparkline() spark1.Title = "srv 1:" spark1.Data = spdata sp := ui.NewSparklines(spark, spark1) sp.Width = 25 sp.Height = 7 sp.Border.Label = "Sparkline" sp.Y = 4 sp.X = 25 lc := ui.NewLineChart() sinps := (func() []float64 { n := 100 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/4) } return ps })() lc.Border.Label = "Line Chart" lc.Data = sinps lc.Width = 50 lc.Height = 11 lc.X = 0 lc.Y = 14 lc.Mode = "dot" bc := ui.NewBarChart() bcdata := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} bc.Border.Label = "Bar Chart" bc.Width = 26 bc.Height = 10 bc.X = 51 bc.Y = 0 bc.DataLabels = bclabels lc1 := ui.NewLineChart() lc1.Border.Label = "Line Chart" rndwalk := (func() []float64 { n := 150 d := make([]float64, n) for i := 1; i < n; i++ { if i < 20 { d[i] = d[i-1] + 0.01 } if i > 20 { d[i] = d[i-1] - 0.05 } } return d })() lc1.Data = rndwalk lc1.Width = 26 lc1.Height = 11 lc1.X = 51 lc1.Y = 14 p1 := ui.NewPar("Hey!\nI am a borderless block!") p1.HasBorder = false p1.Width = 26 p1.Height = 2 p1.X = 52 p1.Y = 11 draw := func(t int) { g.Percent = t % 101 list.Items = strs[t%9:] sp.Lines[0].Data = spdata[t%10:] sp.Lines[1].Data = spdata[t/2%10:] lc.Data = sinps[t/2:] lc1.Data = rndwalk[t:] bc.Data = bcdata[t/2%10:] ui.Render(p, list, g, sp, lc, bc, lc1, p1) } evt := ui.EventCh() i := 0 for { select { case e := <-evt: if e.Type == ui.EventKey && e.Ch == 'q' { return } default: draw(i) i++ if i == 102 { return } time.Sleep(time.Second / 2) } } }
// Metrics prints out metrics for a given service or if the service is not // specified, metrics for the entire environment are printed. func Metrics(serviceLabel string, jsonFlag bool, csvFlag bool, sparkFlag bool, streamFlag bool, mins int, settings *models.Settings) { if streamFlag && (jsonFlag || csvFlag || mins != 1) { fmt.Println("--stream cannot be used with a custom format and multiple records") os.Exit(1) } var singleRetriever func(mins int, settings *models.Settings) *models.Metrics if serviceLabel != "" { service := helpers.RetrieveServiceByLabel(serviceLabel, settings) if service == nil { fmt.Printf("Could not find a service with the label \"%s\"\n", serviceLabel) os.Exit(1) } settings.ServiceID = service.ID singleRetriever = helpers.RetrieveServiceMetrics } var transformer Transformer redraw := make(chan bool) if jsonFlag { transformer = Transformer{ SingleRetriever: singleRetriever, DataTransformer: &JSONTransformer{}, } } else if csvFlag { buffer := &bytes.Buffer{} transformer = Transformer{ SingleRetriever: singleRetriever, DataTransformer: &CSVTransformer{ HeadersWritten: false, GroupMode: serviceLabel == "", Buffer: buffer, Writer: csv.NewWriter(buffer), }, } } else if sparkFlag { // the spark lines interface stays up until closed by the user, so // we might as well keep updating it as long as it is there streamFlag = true mins = 60 err := ui.Init() if err != nil { fmt.Println(err.Error()) os.Exit(1) } defer ui.Close() ui.UseTheme("helloworld") p := ui.NewPar("PRESS q TO QUIT") p.HasBorder = false p.TextFgColor = ui.Theme().SparklineTitle ui.Body.AddRows( ui.NewRow(ui.NewCol(12, 0, p)), ) transformer = Transformer{ SingleRetriever: singleRetriever, DataTransformer: &SparkTransformer{ Redraw: redraw, SparkLines: make(map[string]*ui.Sparklines), }, } } else { transformer = Transformer{ SingleRetriever: singleRetriever, DataTransformer: &TextTransformer{}, } } transformer.GroupRetriever = helpers.RetrieveEnvironmentMetrics transformer.Stream = streamFlag transformer.GroupMode = serviceLabel == "" transformer.Mins = mins transformer.settings = settings helpers.SignIn(settings) if sparkFlag { go transformer.process() ui.Body.Align() ui.Render(ui.Body) quit := make(chan bool) go maintainSparkLines(redraw, quit) <-quit } else { transformer.process() } }
func (gv *graphicalVisualizer) PrintDistributionChart(rate time.Duration) error { //Initialize termui err := termui.Init() if err != nil { return errors.New("Unable to initalize terminal graphics mode.") //panic(err) } defer termui.Close() if rate <= time.Duration(0) { rate = graphicalRateDelta } termui.UseTheme("helloworld") //Initalize some widgets p := termui.NewPar("Lattice Visualization") if p == nil { return errors.New("Error Initializing termui objects NewPar") } p.Height = 1 p.Width = 25 p.TextFgColor = termui.ColorWhite p.HasBorder = false r := termui.NewPar(fmt.Sprintf("rate:%v", rate)) if r == nil { return errors.New("Error Initializing termui objects NewPar") } r.Height = 1 r.Width = 10 r.TextFgColor = termui.ColorWhite r.HasBorder = false s := termui.NewPar("hit [+=inc; -=dec; q=quit]") if s == nil { return errors.New("Error Initializing termui objects NewPar") } s.Height = 1 s.Width = 30 s.TextFgColor = termui.ColorWhite s.HasBorder = false bg := termui.NewMBarChart() if bg == nil { return errors.New("Error Initializing termui objects NewMBarChart") } bg.IsDisplay = false bg.Data[0] = []int{0} bg.DataLabels = []string{"Missing"} bg.Width = termui.TermWidth() - 10 bg.Height = termui.TermHeight() - 5 bg.BarColor[0] = termui.ColorGreen bg.BarColor[1] = termui.ColorYellow bg.NumColor[0] = termui.ColorRed bg.NumColor[1] = termui.ColorRed bg.TextColor = termui.ColorWhite bg.Border.LabelFgColor = termui.ColorWhite bg.Border.Label = "[X-Axis: Cells; Y-Axis: Instances]" bg.BarWidth = 10 bg.BarGap = 1 bg.ShowScale = true //12 column grid system termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 5, p))) termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 0, bg))) termui.Body.AddRows(termui.NewRow(termui.NewCol(6, 0, s), termui.NewCol(6, 5, r))) termui.Body.Align() termui.Render(termui.Body) bg.IsDisplay = true clock := clock.NewClock() evt := termui.EventCh() for { select { case e := <-evt: if e.Type == termui.EventKey { switch { case (e.Ch == 'q' || e.Ch == 'Q'): return nil case (e.Ch == '+' || e.Ch == '='): rate += graphicalRateDelta case (e.Ch == '_' || e.Ch == '-'): rate -= graphicalRateDelta if rate <= time.Duration(0) { rate = graphicalRateDelta } } r.Text = fmt.Sprintf("rate:%v", rate) termui.Render(termui.Body) } if e.Type == termui.EventResize { termui.Body.Width = termui.TermWidth() termui.Body.Align() termui.Render(termui.Body) } case <-clock.NewTimer(rate).C(): err := gv.getProgressBars(bg) if err != nil { return err } termui.Render(termui.Body) } } return nil }
func (env *Env) Stats(cmd *cobra.Command, args []string) { err := ui.Init() if err != nil { panic(err) } defer ui.Close() ui.UseTheme("helloworld") s := ui.NewPar(env.db.Scrobbles()) s.Border.Label = "LocalFM" s.Height = 3 recTracks, err := env.db.RecentTracks() if err != nil { log.Fatalf("Error in RecentTracks:", err) } rec := ui.NewPar(recTracks) rec.Border.Label = "Recent Tracks" rec.Height = (viper.GetInt("main.recent_tracks") + 2) topArtists, err := env.db.TopArtists() if err != nil { log.Fatalf("Error in TopArtists:", err) } topart := ui.NewPar(topArtists) topart.Border.Label = "Top Artists" topart.Height = (viper.GetInt("main.top_artists") + 2) topAlbums, err := env.db.TopAlbums() if err != nil { log.Fatalf("Error in TopAlbums:", err) } topalbs := ui.NewPar(topAlbums) topalbs.Border.Label = "Top Albums" topalbs.Height = (viper.GetInt("main.top_albums") + 2) topSongs, err := env.db.TopSongs() if err != nil { log.Fatalf("Error in TopSongs:", err) } topsongs := ui.NewPar(topSongs) topsongs.Border.Label = "Top Songs" topsongs.Height = (viper.GetInt("main.top_songs") + 2) ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 0, s)), ui.NewRow( ui.NewCol(12, 0, rec)), ui.NewRow( ui.NewCol(6, 0, topart), ui.NewCol(6, 0, topalbs)), ui.NewRow( ui.NewCol(12, 0, topsongs))) ui.Body.Align() done := make(chan bool) redraw := make(chan bool) update := func() { time.Sleep(time.Second / 2) redraw <- true } evt := ui.EventCh() ui.Render(ui.Body) go update() for { select { case e := <-evt: if e.Type == ui.EventKey && e.Ch == 'q' { return } if e.Type == ui.EventResize { ui.Body.Width = ui.TermWidth() ui.Body.Align() go func() { redraw <- true }() } case <-done: return case <-redraw: ui.Render(ui.Body) } } }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() termui.UseTheme("helloworld") header := termui.NewPar("Press q to quit, Press j or k to switch tabs") header.Height = 1 header.Width = 50 header.HasBorder = false header.TextBgColor = termui.ColorBlue tab1 := extra.NewTab("pierwszy") par2 := termui.NewPar("Press q to quit\nPress j or k to switch tabs\n") par2.Height = 5 par2.Width = 37 par2.Y = 0 par2.Border.Label = "Keys" par2.Border.FgColor = termui.ColorYellow tab1.AddBlocks(par2) tab2 := extra.NewTab("drugi") bc := termui.NewBarChart() data := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} bc.Border.Label = "Bar Chart" bc.Data = data bc.Width = 26 bc.Height = 10 bc.DataLabels = bclabels bc.TextColor = termui.ColorGreen bc.BarColor = termui.ColorRed bc.NumColor = termui.ColorYellow tab2.AddBlocks(bc) tab3 := extra.NewTab("trzeci") tab4 := extra.NewTab("żółw") tab5 := extra.NewTab("four") tab6 := extra.NewTab("five") tabpane := extra.NewTabpane() tabpane.Y = 1 tabpane.Width = 30 tabpane.HasBorder = true tabpane.SetTabs(*tab1, *tab2, *tab3, *tab4, *tab5, *tab6) evt := termui.EventCh() termui.Render(header, tabpane) for { 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) } } } } }
// Init creates widgets, sets sizes and labels. func (t *TermUI) Init(data UIData) error { err := termui.Init() if err != nil { return err } termui.UseTheme("helloworld") theme := termui.Theme() theme.BodyBg = termui.ColorDefault theme.BlockBg = termui.ColorDefault theme.BorderBg = termui.ColorDefault theme.BorderFg = termui.ColorBlack theme.BorderLabelTextBg = termui.ColorDefault theme.BorderLabelTextFg = termui.ColorCyan theme.ListItemBg = termui.ColorDefault theme.ParTextBg = termui.ColorDefault termui.SetTheme(theme) t.Title = func() *termui.Par { p := termui.NewPar("") p.Height = 3 p.TextFgColor = termui.ColorWhite p.Border.Label = "Services Monitor" p.Border.FgColor = termui.ColorBlack return p }() t.Status = func() *termui.Par { p := termui.NewPar("") p.Height = 3 p.TextFgColor = termui.ColorWhite p.Border.Label = "Status" p.Border.LabelFgColor = termui.ColorCyan p.Border.FgColor = termui.ColorBlack return p }() t.Services = func() *termui.List { list := termui.NewList() list.ItemFgColor = termui.ColorYellow list.Border.LabelFgColor = termui.ColorCyan | termui.AttrBold list.Border.Label = "Services" list.Height = len(data.Services) + 2 return list }() t.Lists = make([]*termui.List, len(data.Vars)) for i, name := range data.Vars { list := termui.NewList() list.ItemFgColor = colorByKind(name.Kind()) list.Border.Label = name.Short() list.Border.LabelFgColor = termui.ColorCyan list.Height = len(data.Services) + 2 t.Lists[i] = list } makeSparkline := func(name VarName) *termui.Sparklines { var sparklines []termui.Sparkline for _, service := range data.Services { spl := termui.NewSparkline() spl.Height = 1 spl.TitleColor = termui.ColorGreen spl.LineColor = termui.ColorGreen spl.Title = service.Name sparklines = append(sparklines, spl) } s := termui.NewSparklines(sparklines...) s.Height = 2*len(data.Services) + 2 s.HasBorder = true s.Border.Label = fmt.Sprintf("Monitoring %s", name.Long()) return s } t.Sparkline1 = makeSparkline(data.Vars[0]) if len(data.Vars) > 1 { t.Sparkline2 = makeSparkline(data.Vars[1]) } t.Relayout() return nil }
func main() { var memStat []float64 err := ui.Init() if err != nil { panic(err) } defer ui.Close() ui.UseTheme("helloworld") header := createHeader("-- Phoenix Dashboard --") footer := createFooterBar() p, _ := plugin.NewPlugin("oci") procList := processList(p) pls := createProcessList(procList) plist, _ := p.GetProcessList() for _, pl := range plist { memStat = append(memStat, processMemory(p, pl)) break } memWidget := createProcessMemoryWidget(memStat) // Adjust widgets on screen ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 5, header)), ui.NewRow( ui.NewCol(3, 0, pls), ui.NewCol(4, 0, memWidget)), ui.NewRow( ui.NewCol(12, 0, footer)), ) ui.Body.Align() ui.Render(ui.Body) paintScreen := func() { ui.Body.Width = ui.TermWidth() ui.Body.Align() pls.Items = processList(p) plist, _ := p.GetProcessList() for _, pl := range plist { memStat = append(memStat, processMemory(p, pl)) break } memStat = []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 4, 3, 5, 7, 9, 4, 3, 2, 4, 3} memWidget.Data = memStat ui.Render(ui.Body) } evt := ui.EventCh() for { select { case e := <-evt: if e.Ch == 'q' { return } if e.Type == ui.EventResize { go paintScreen() } } } }
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) l := &sync.Mutex{} err := ui.Init() if err != nil { panic(err) } defer ui.Close() ui.UseTheme("helloworld") loadConfErr := LoadConfig() loadProxyErr := LoadProxies() LoadedProxies = len(D_PROXY_LIST) ProxiesLeft = LoadedProxies aboutUi := ui.NewPar( "Please report bugs @skype: newjolt\nOptimized to use " + strconv.Itoa(runtime.NumCPU()) + " cores.\nPress 'CTRL+C' to quit, 'CTRL+SPACE' to start task, 'CTRL+R' to reload settings.\nJoin us revive KryptoDEV.com") aboutUi.Height = 5 aboutUi.TextFgColor = ui.ColorBlack aboutUi.Border.FgColor = ui.ColorMagenta aboutUi.TextBgColor = ui.ColorWhite aboutUi.BgColor = ui.ColorWhite aboutUi.Border.Label = "TOGNINJA: a topofgames.com auto voter v0.1 - kryptoDEV.com" aboutUi.Border.LabelFgColor = ui.AttrBold successUi := ui.NewPar("") successUi.Height = 3 successUi.TextFgColor = ui.ColorWhite successUi.Border.Label = "Last Succeeded Vote" failedUi := ui.NewPar("") failedUi.Height = 3 failedUi.TextFgColor = ui.ColorWhite failedUi.Border.Label = "Last Failed Vote" configUi := ui.NewPar(fmt.Sprintf("@Proxies Loaded: %d\n@Target ID: %d\n@Worker Count: %d", LoadedProxies, ConfigStruct.TargetID, ConfigStruct.WorkerCount)) configUi.Height = 5 configUi.TextFgColor = ui.ColorWhite configUi.Border.FgColor = ui.ColorWhite configUi.Border.Label = "Loaded Config." progressUi := ui.NewGauge() progressUi.Percent = 0 progressUi.Height = 3 progressUi.Border.Label = "Progress Report" progressUi.BarColor = ui.ColorRed progressUi.Border.FgColor = ui.ColorWhite progressUi.Border.LabelFgColor = ui.ColorCyan errorUi := ui.NewPar("") if loadConfErr != nil { errorUi.Text = loadConfErr.Error() } else if ConfigStruct.DBCUsername == "" { errorUi.Text = "Deathbycaptcha username not provided." } else if ConfigStruct.DBCPassword == "" { errorUi.Text = "Deathbycaptcha password not provided." } else if loadProxyErr != nil { errorUi.Text = loadProxyErr.Error() } errorUi.Height = 3 errorUi.TextFgColor = ui.ColorRed errorUi.Border.FgColor = ui.ColorWhite errorUi.Border.Label = "Last Error" statsUi := ui.NewPar("") statsUi.Height = 3 statsUi.TextFgColor = ui.ColorWhite statsUi.Border.FgColor = ui.ColorGreen statsUi.Border.Label = "Stats" // build layout ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 0, aboutUi)), ui.NewRow( ui.NewCol(6, 0, configUi), ui.NewCol(6, 0, errorUi)), ui.NewRow( ui.NewCol(6, 0, successUi), ui.NewCol(6, 0, failedUi)), ui.NewRow( ui.NewCol(12, 0, progressUi)), ui.NewRow( ui.NewCol(12, 0, statsUi))) // calculate layout ui.Body.Align() done := make(chan bool) redraw := make(chan bool) evt := ui.EventCh() ui.Render(ui.Body) worker.MaxJobs = ConfigStruct.WorkerCount w := worker.NewWorker() w.On(worker.JobFinished, func(args ...interface{}) { l.Lock() ProxiesLeft-- l.Unlock() pk := args[0].(*worker.Package) job := pk.Job().(*VoteJob) if job.HasError != "" { l.Lock() errorUi.Text = job.HasError ErrorsEncountered++ l.Unlock() } if job.HasSuccessVoted { l.Lock() SuccessfulVotes++ VotesAttempted++ l.Unlock() if job.SuccessVoteText != "" { l.Lock() successUi.Text = job.SuccessVoteText l.Unlock() } } if job.HasFailVoted { l.Lock() FailedVotes++ VotesAttempted++ l.Unlock() if job.FailVoteText != "" { l.Lock() failedUi.Text = job.FailVoteText l.Unlock() } } if job.IsLast { l.Lock() statsUi.Text = "Bot: Finished | Proxies left: 0 | Successful Votes: " + strconv.Itoa(SuccessfulVotes) + " | Failed Votes: " + strconv.Itoa(FailedVotes) + " | Errors Encountered: " + strconv.Itoa(ErrorsEncountered) progressUi.Percent = 100 progressUi.BarColor = ui.ColorGreen ui.Render(ui.Body) l.Unlock() return } l.Lock() progressUi.Percent = int(float32(100 - (100 * ProxiesLeft / LoadedProxies))) statsUi.Text = "Bot: Running | Proxies left: " + strconv.Itoa(ProxiesLeft) + " | Successful Votes: " + strconv.Itoa(SuccessfulVotes) + " | Failed Votes: " + strconv.Itoa(FailedVotes) + " | Errors Encountered: " + strconv.Itoa(ErrorsEncountered) ui.Render(ui.Body) l.Unlock() }) for { select { case e := <-evt: if e.Type == ui.EventKey && e.Key == ui.KeyCtrlC { return } if e.Type == ui.EventKey && e.Key == ui.KeyCtrlR { //FetchCaptcha() } if e.Type == ui.EventKey && e.Key == ui.KeyCtrlSpace { for a := 0; a < LoadedProxies; a++ { if a == LoadedProxies { j := VoteJob{Name: D_PROXY_LIST[a], Proxy: D_PROXY_LIST[a], HasSuccessVoted: false, HasFailVoted: false, IsLast: true} w.Add(&j) } else { j := VoteJob{Name: D_PROXY_LIST[a], Proxy: D_PROXY_LIST[a], HasSuccessVoted: false, HasFailVoted: false, IsLast: false} w.Add(&j) } } w.RunUntilDone() } if e.Type == ui.EventResize { ui.Body.Width = ui.TermWidth() ui.Body.Align() go func() { redraw <- true }() } case <-done: return case <-redraw: ui.Render(ui.Body) } } }
// monitor starts a terminal UI based monitoring tool for the requested metrics. func monitor(ctx *cli.Context) { var ( client comms.EthereumClient err error ) // Attach to an Ethereum node over IPC or RPC endpoint := ctx.String(monitorCommandAttachFlag.Name) if client, err = comms.ClientFromEndpoint(endpoint, codec.JSON); err != nil { utils.Fatalf("Unable to attach to geth node: %v", err) } defer client.Close() xeth := rpc.NewXeth(client) // Retrieve all the available metrics and resolve the user pattens metrics, err := retrieveMetrics(xeth) if err != nil { utils.Fatalf("Failed to retrieve system metrics: %v", err) } monitored := resolveMetrics(metrics, ctx.Args()) if len(monitored) == 0 { list := expandMetrics(metrics, "") sort.Strings(list) if len(list) > 0 { utils.Fatalf("No metrics specified.\n\nAvailable:\n - %s", strings.Join(list, "\n - ")) } else { utils.Fatalf("No metrics collected by geth (--%s).\n", utils.MetricsEnabledFlag.Name) } } sort.Strings(monitored) if cols := len(monitored) / ctx.Int(monitorCommandRowsFlag.Name); cols > 6 { utils.Fatalf("Requested metrics (%d) spans more that 6 columns:\n - %s", len(monitored), strings.Join(monitored, "\n - ")) } // Create and configure the chart UI defaults if err := termui.Init(); err != nil { utils.Fatalf("Unable to initialize terminal UI: %v", err) } defer termui.Close() termui.UseTheme("helloworld") rows := len(monitored) if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max { rows = max } cols := (len(monitored) + rows - 1) / rows for i := 0; i < rows; i++ { termui.Body.AddRows(termui.NewRow()) } // Create each individual data chart footer := termui.NewPar("") footer.HasBorder = true footer.Height = 3 charts := make([]*termui.LineChart, len(monitored)) units := make([]int, len(monitored)) data := make([][]float64, len(monitored)) for i := 0; i < len(monitored); i++ { charts[i] = createChart((termui.TermHeight() - footer.Height) / rows) row := termui.Body.Rows[i%rows] row.Cols = append(row.Cols, termui.NewCol(12/cols, 0, charts[i])) } termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 0, footer))) refreshCharts(xeth, monitored, data, units, charts, ctx, footer) termui.Body.Align() termui.Render(termui.Body) // Watch for various system events, and periodically refresh the charts refresh := time.Tick(time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second) for { select { case event := <-termui.EventCh(): if event.Type == termui.EventKey && event.Key == termui.KeyCtrlC { return } if event.Type == termui.EventResize { termui.Body.Width = termui.TermWidth() for _, chart := range charts { chart.Height = (termui.TermHeight() - footer.Height) / rows } termui.Body.Align() termui.Render(termui.Body) } case <-refresh: if refreshCharts(xeth, monitored, data, units, charts, ctx, footer) { termui.Body.Align() } termui.Render(termui.Body) } } }
func main() { if runtime.GOOS != "linux" { panic("Currently works only on Linux") } err := termui.Init() if err != nil { panic(err) } defer termui.Close() termWidth := 70 termui.UseTheme("helloworld") header := termui.NewPar("Press q to quit, Press j or k to switch tabs") header.Height = 1 header.Width = 50 header.HasBorder = false header.TextBgColor = termui.ColorBlue tabCpu := extra.NewTab("CPU") tabMem := extra.NewTab("MEM") tabpane := extra.NewTabpane() tabpane.Y = 1 tabpane.Width = 30 tabpane.HasBorder = false cs, errcs := getCpusStatsMap() cpusStats := NewCpusStats(cs) if errcs != nil { panic("error") } cpuTabElems := NewCpuTabElems(termWidth) Y := 0 cpuKeys := make([]string, 0, len(cs)) for key := range cs { cpuKeys = append(cpuKeys, key) } sort.Strings(cpuKeys) for _, key := range cpuKeys { g := cpuTabElems.AddGauge(key, Y, termWidth) Y += 3 tabCpu.AddBlocks(g) } cpuTabElems.LChart.Y = Y tabCpu.AddBlocks(cpuTabElems.LChart) memTabElems := NewMemTabElems(termWidth) ms, errm := getMemStats() if errm != nil { panic(errm) } memTabElems.Update(ms) tabMem.AddBlocks(memTabElems.Gauge) tabMem.AddBlocks(memTabElems.SLines) tabpane.SetTabs(*tabCpu, *tabMem) termui.Render(header, tabpane) evt := termui.EventCh() for { 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() if errm != nil { panic(errm) } memTabElems.Update(ms) termui.Render(header, tabpane) } } }
func createUi(state *render.RenderState) { err := ui.Init() if err != nil { panic(err) } defer ui.Close() ui.UseTheme("helloworld") bc := ui.NewBarChart() data := []int{} bclabels := []string{} bc.Border.Label = "SumoCLI" bc.Data = data //bc.Width = 26 bc.Height = ui.TermHeight() - 10 bc.DataLabels = bclabels bc.TextColor = ui.ColorGreen bc.BarColor = ui.ColorRed bc.NumColor = ui.ColorYellow // build layout ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 0, bc))) // calculate layout ui.Body.Align() done := make(chan bool) redraw := make(chan bool) update := func() error { //fmt.Println("updating") bars := render.Columns(*state.Messages) columns := render.ColumnNames(bars) query, ok := (*state.Meta)["_queryString"] if ok && query.(string) != bc.Border.Label { bc.Border.Label = query.(string) } dataCol := render.NumericColumn(columns) data := []int{} labels := []string{} extractor := render.LabelExtractor(columns) for _, msg := range *state.Messages { labels = append(labels, extractor(msg)) // go is the worst floatVal, _ := strconv.ParseFloat(fmt.Sprint(msg[dataCol]), 64) rowData := int(floatVal) data = append(data, rowData) } bc.Data = data var numCols int if len(data) > 0 { numCols = len(data) } else { numCols = 1 } newBarWidth := (ui.TermWidth() - 10) / numCols if int(newBarWidth) != int(bc.BarWidth) { bc.BarWidth = newBarWidth } if len(labels) != len(bc.DataLabels) { bc.DataLabels = labels } redraw <- true return nil } state.Flush = update evt := ui.EventCh() ui.Render(ui.Body) go update() for { select { case e := <-evt: if e.Type == ui.EventKey && e.Ch == 'q' { return } if e.Type == ui.EventResize { ui.Body.Width = ui.TermWidth() ui.Body.Align() go func() { redraw <- true }() } case <-done: return case <-redraw: ui.Render(ui.Body) } } }
func listMessages(messages []*imap.MessageInfo) { selectedIndex := 0 messageStrings := func(index int) []string { strs := make([]string, len(messages), len(messages)) for idx, message := range messages { msg := messageAttr(message, HEADER_PART_NAME) if msg != nil { subject := msg.Header.Get("Subject") if idx == index { strs = append(strs, "> "+subject) } else { strs = append(strs, " "+subject) } } } return strs } err := ui.Init() if err != nil { panic(err) } defer ui.Close() ui.UseTheme("helloworld") lst := ui.NewList() lst.Items = messageStrings(selectedIndex) lst.ItemFgColor = ui.ColorGreen lst.Border.Label = "demo list" lst.Height = ui.TermHeight() lst.Width = ui.TermWidth() lst.Y = 0 ui.Render(lst) redraw := make(chan bool) for { select { case e := <-ui.EventCh(): if e.Type == ui.EventKey { switch e.Key { case ui.KeyEsc: return case ui.KeyArrowUp: selectedIndex = max(0, selectedIndex-1) go func() { redraw <- true }() case ui.KeyArrowDown: selectedIndex = min(len(messages)-1, selectedIndex+1) go func() { redraw <- true }() case ui.KeyEnter: readMessage(messages[selectedIndex]) go func() { redraw <- true }() } } case <-redraw: lst.Items = messageStrings(selectedIndex) ui.Render(lst) } } }