func updateMemCPU(gcpu, gmem *ui.Gauge) { done := make(chan struct{}) memInfoChan, errc := daemon.TotalMemory(done, daemon.Delay) cpuInfoChan, errc := daemon.TotalCPU(done, daemon.Delay) timeout := time.After(2 * daemon.Delay) defer func() { close(done) // Necessary to read from error channel to prevent sending goroutine going into deadlock <-errc }() for { select { case memInfo := <-memInfoChan: pc := int(100 * (float64(memInfo.MemTotal-memInfo.MemFree) / float64(memInfo.MemTotal))) gmem.Percent = pc ui.Render(ui.Body) case cpuInfo := <-cpuInfoChan: pc := int(cpuInfo.AverageUtilization) gcpu.Percent = pc ui.Render(ui.Body) case err := <-errc: if err != nil { } return case <-timeout: } } }
func addSparkLine(serviceName string, titles []string, color ui.Attribute) *ui.Sparklines { var sparkLines []ui.Sparkline for _, title := range titles { sparkLine := ui.NewSparkline() sparkLine.Height = 1 sparkLine.Data = []int{} sparkLine.Title = title sparkLine.TitleColor = titleColor sparkLine.LineColor = color sparkLines = append(sparkLines, sparkLine) } sp := ui.NewSparklines(sparkLines...) sp.Height = 11 sp.BorderLabel = serviceName ui.Body.AddRows( ui.NewRow(ui.NewCol(12, 0, sp)), ) ui.Body.Align() ui.Render(sp) ui.Render(ui.Body) return sp }
func SendBoxEvents(p *ui.Par) { ui.Handle("/sys/kbd/<enter>", func(e ui.Event) { Input <- p.Text p.Text = "" ui.Render(ui.Body) }) ui.Handle("/sys/kbd/<space>", func(e ui.Event) { p.Text += " " ui.Render(ui.Body) }) ui.Handle("/sys/kbd/C-8", func(e ui.Event) { if len(p.Text) > 0 { p.Text = p.Text[:len(p.Text)-1] ui.Render(ui.Body) } }) ui.Handle("/sys/kbd", func(e ui.Event) { char := e.Data.(ui.EvtKbd).KeyStr p.Text += char ui.Render(ui.Body) }) }
func BuildUI() { ui.Init() defer ui.Close() receiveBox := CreateReceiveBox() sendBox := CreateSendBox() ui.Body.AddRows( ui.NewRow(ui.NewCol(12, 0, receiveBox)), ui.NewRow(ui.NewCol(12, 0, sendBox)), ) ui.Body.Align() ui.Render(ui.Body) ui.Handle("/sys/kbd/C-x", func(e ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { ReceiveBoxHeight = ui.TermHeight() - SendBoxHeight receiveBox.Height = ReceiveBoxHeight ui.Body.Align() ui.Render(ui.Body) }) // Leaving this commented out for now // I'd like to get this method of screen refreshing working instead of the 1s method, // but this crashes on resize. // ui.Handle("/sys/wnd/resize", func(e ui.Event) { // ui.Body.Align() // ui.Render(ui.Body) // }) ui.Loop() }
//doLiveGraph builds a graph in the terminal window that //updates every graphUpdate seconds //It will build up to maxGraphs graphs with one time-series //per graph func doLiveGraph(res *wavefront.QueryResponse, query *wavefront.Querying, period int64) { err := ui.Init() if err != nil { log.Fatal(err) } defer ui.Close() if maxGraphs > len(res.TimeSeries) { maxGraphs = len(res.TimeSeries) } var wDivisor, hDivisor int switch maxGraphs { case 1: wDivisor = 1 hDivisor = 1 case 2: wDivisor = 2 hDivisor = 1 case 3, 4: wDivisor = 2 hDivisor = 2 } height := ui.TermHeight() / hDivisor width := ui.TermWidth() / wDivisor xVals, yVals := calculateCoords(maxGraphs, ui.TermWidth()/wDivisor, ui.TermHeight()/hDivisor) graphs := buildGraphs(res, height, width, xVals, yVals) ui.Render(graphs...) ui.Handle("/sys/kbd/q", func(ui.Event) { // press q to quit ui.StopLoop() }) ui.Handle("/sys/kbd/C-c", func(ui.Event) { // handle Ctrl + c combination ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { query.SetEndTime(time.Now()) query.SetStartTime(period) res, err := query.Execute() if err != nil { log.Fatal(err) } graphs := buildGraphs(res, height, width, xVals, yVals) ui.Render(graphs...) }) ui.Loop() }
func readMessage(message *imap.MessageInfo) { set := new(imap.SeqSet) set.AddNum(message.Seq) cmd, err := imap.Wait(c.Fetch(set, BODY_PART_NAME)) panicMaybe(err) reader, err := messageReader(cmd.Data[0].MessageInfo()) panicMaybe(err) scanner := bufio.NewScanner(reader) var lines []string for scanner.Scan() { lines = append(lines, scanner.Text()) } messageBodyStr := strings.Join(lines[:min(len(lines), ui.TermHeight()-2)], "\n") if len(messageBodyStr) <= 0 { LOG.Printf("Message body was empty or could not be retrieved: +%v\n", err) return } msgBox := ui.NewPar(messageBodyStr) msgBox.Border.Label = "Reading Message" msgBox.Height = ui.TermHeight() msgBox.Width = ui.TermWidth() msgBox.Y = 0 ui.Render(msgBox) topLineIndex := 0 redraw := make(chan bool) for { select { case e := <-ui.EventCh(): switch e.Key { case ui.KeyArrowDown: topLineIndex = max(0, min( len(lines)-msgBox.Height/2, topLineIndex+1)) go func() { redraw <- true }() case ui.KeyArrowUp: topLineIndex = max(0, topLineIndex-1) go func() { redraw <- true }() case ui.KeyEsc: // back to "list messages" return } case <-redraw: messageBodyStr = strings.Join(lines[topLineIndex+1:], "\n") msgBox.Text = messageBodyStr ui.Render(msgBox) } } }
func main() { // run as client if len(os.Args) > 1 { fmt.Print(debug.ConnectAndListen()) return } // run as server go func() { panic(debug.ListenAndServe()) }() if err := termui.Init(); err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") b := termui.NewBlock() b.Width = 20 b.Height = 20 b.Float = termui.AlignCenter b.BorderLabel = "[HELLO](fg-red,bg-white) [WORLD](fg-blue,bg-green)" termui.Render(b) termui.Handle("/sys", func(e termui.Event) { k, ok := e.Data.(termui.EvtKbd) debug.Logf("->%v\n", e) if ok && k.KeyStr == "q" { termui.StopLoop() } }) termui.Handle(("/usr"), func(e termui.Event) { debug.Logf("->%v\n", e) }) termui.Handle("/timer/1s", func(e termui.Event) { t := e.Data.(termui.EvtTimer) termui.SendCustomEvt("/usr/t", t.Count) if t.Count%2 == 0 { b.BorderLabel = "[HELLO](fg-red,bg-green) [WORLD](fg-blue,bg-white)" } else { b.BorderLabel = "[HELLO](fg-blue,bg-white) [WORLD](fg-red,bg-green)" } termui.Render(b) }) termui.Loop() }
func main() { if err := termui.Init(); err != nil { panic(err) } defer termui.Close() 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.BorderLabel = "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.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
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() }
// TransformSingleMemory transforms a single service's memory data into spark // lines. func (spark *SparkTransformer) TransformSingleMemory(metric *models.Metrics) { var memMin []int var memMax []int var memAvg []int var memTotal []int if metric.Data != nil && metric.Data.MemoryUsage != nil { for _, data := range *metric.Data.MemoryUsage { memMin = append(memMin, int(data.Min/1024.0)) memMax = append(memMax, int(data.Max/1024.0)) memAvg = append(memAvg, int(data.AVG/1024.0)) memTotal = append(memTotal, int(metric.Size.RAM*1024.0)) } } var sparkLines = spark.SparkLines[metric.ServiceLabel] if sparkLines == nil { sparkLines = addSparkLine(metric.ServiceLabel, []string{"Mem Min", "Mem Max", "Mem AVG", "Mem Total"}, memoryColor) spark.SparkLines[metric.ServiceLabel] = sparkLines } for i := range sparkLines.Lines { if sparkLines.Lines[i].Title == "Mem Min" { sparkLines.Lines[i].Data = memMin } else if sparkLines.Lines[i].Title == "Mem Max" { sparkLines.Lines[i].Data = memMax } else if sparkLines.Lines[i].Title == "Mem AVG" { sparkLines.Lines[i].Data = memAvg } else if sparkLines.Lines[i].Title == "Mem Total" { sparkLines.Lines[i].Data = memTotal } } ui.Render(ui.Body) }
func main() { err := ui.Init() if err != nil { panic(err) } defer ui.Close() p := ui.NewPar("Press q to QUIT THE DEMO. [There](fg-blue) are other things [that](fg-red) are going to fit in here I think. What do you think? Now is the time for all good [men to](bg-blue) come to the aid of their country. [This is going to be one really really really long line](fg-green) that is going to go together and stuffs and things. Let's see how this thing renders out.\n Here is a new paragraph and stuffs and things. There should be a tab indent at the beginning of the paragraph. Let's see if that worked as well.") p.WrapLength = 48 // this should be at least p.Width - 2 p.Height = 20 p.Width = 50 p.Y = 2 p.X = 20 p.TextFgColor = ui.ColorWhite p.BorderLabel = "Text Box with Wrapping" p.BorderFg = ui.ColorCyan //p.Border = false ui.Render(p) ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Loop() }
func main() { err := ui.Init() if err != nil { panic(err) } defer ui.Close() p := ui.NewPar(":PRESS q TO QUIT DEMO") p.Height = 3 p.Width = 50 p.TextFgColor = ui.ColorWhite p.BorderLabel = "Text Box" p.BorderFg = ui.ColorCyan g := ui.NewGauge() g.Percent = 50 g.Width = 50 g.Height = 3 g.Y = 11 g.BorderLabel = "Gauge" g.BarColor = ui.ColorRed g.BorderFg = ui.ColorWhite g.BorderLabelFg = ui.ColorCyan ui.Render(p, g) // feel free to call Render, it's async and non-block }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") strs := []string{ "[0] github.com/gizak/termui", "[1] [你好,世界](fg-blue)", "[2] [こんにちは世界](fg-red)", "[3] [color output](fg-white,bg-green)", "[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.BorderLabel = "List" ls.Height = 7 ls.Width = 25 ls.Y = 0 termui.Render(ls) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func (m *Monitor) Start(conn *net.Conn) { if err := ui.Init(); err != nil { panic(err) } defer ui.Close() help := ui.NewPar(":PRESS q TO QUIT") help.Height = 3 help.Width = 50 help.TextFgColor = ui.ColorWhite help.BorderLabel = "Help" help.BorderFg = ui.ColorCyan // build ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, help), ), ) draw := func(t int) { ui.Body.Align() ui.Render(ui.Body) } draw(0) ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { t := e.Data.(ui.EvtTimer) draw(int(t.Count)) }) ui.Loop() }
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 main() { err := ui.Init() if err != nil { panic(err) } defer ui.Close() w11 := ui.NewPar("Hello world") w11.Height = 10 w11.Border.Label = "Hello" w11.Border.LabelFgColor = ui.ColorGreen w12 := ui.NewPar("first") w12.Height = 20 w2 := ui.NewPar("second") w2.Height = 20 ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, w11), ui.NewCol(6, 0, w12)), ui.NewRow( ui.NewCol(12, 0, w2))) ui.Body.Align() ui.Render(ui.Body) <-ui.EventCh() }
func (wr *widgetRenderer) Render() { var jobs []termui.Bufferer for _, j := range wr.jobs { jobs = append(jobs, j) } termui.Render(jobs...) }
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.Border = 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.BorderLabel = "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.BorderFg = termui.ColorCyan spls2.X = 21 spls2.BorderLabel = "Tweeked Sparkline" termui.Render(spls0, spls1, spls2) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func updateUptime(p *ui.Par) { for { <-time.After(2 * daemon.Delay) ut, _ := daemon.Uptime() p.Text = ut.String() ui.Render(ui.Body) } }
func (p *LabelListPage) Update() { ls := p.uiList p.markActiveLine() ls.Items = p.displayLines[p.firstDisplayLine:] ui.Render(ls) p.statusBar.Update() p.commandBar.Update() }
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.BorderLabel = "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.BorderLabel = "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.BorderLabel = "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.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func (p *QueryPage) Update() { ls := p.uiList log.Debugf("QueryPage.Update(): self: %s (%p), ls: (%p)", p.Id(), p, ls) p.markActiveLine() ls.Items = p.displayLines[p.firstDisplayLine:] ui.Render(ls) p.statusBar.Update() p.commandBar.Update() }
func (s *Stats) Start() { s.cfUI.Say("Starting Stats...") err := termui.Init() if err != nil { s.cfUI.Warn(err.Error()) return } defer termui.Close() go func() { sinkTypeChart := &charts.SinkTypeChart{} sinkTypeChart.Init(s.cfUI) uaaChart := &charts.UAAChart{} uaaChart.Init(s.cfUI) msgLossChart := &charts.MsgLossChart{} msgLossChart.Init(s.cfUI) notesChart := &charts.NotesChart{} notesChart.Init() s.client.Sift( []charts.Chart{ sinkTypeChart, uaaChart, msgLossChart, }, ) termui.Body.AddRows( termui.NewRow( termui.NewCol(6, 0, sinkTypeChart), termui.NewCol(6, 0, uaaChart), ), termui.NewRow( termui.NewCol(6, 0, msgLossChart), termui.NewCol(6, 0, notesChart), ), ) for { termui.Body.Align() termui.Render(termui.Body) time.Sleep(1 * time.Second) } }() termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() sinps := (func() []float64 { n := 220 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/5) } return ps })() p := termui.NewPar(":PRESS q or Esc TO QUIT DEMO Hello World") p.Height = 3 p.Width = 50 p.TextFgColor = termui.ColorWhite p.BorderLabel = "Hello-World" p.BorderFg = termui.ColorCyan lc1 := termui.NewLineChart() lc1.BorderLabel = "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 g0 := termui.NewGauge() g0.Percent = 40 g0.Width = 50 g0.Height = 3 g0.Y = 3 g0.BorderLabel = "Slim Gauge" g0.BarColor = termui.ColorRed g0.BorderFg = termui.ColorWhite g0.BorderLabelFg = termui.ColorCyan termui.Render(p, g0, lc1) termui.Handle("/sys", func(e termui.Event) { k, ok := e.Data.(termui.EvtKbd) if ok && (k.KeyStr == "q" || k.KeyStr == "<escape>") { termui.StopLoop() } }) termui.Loop() }
func sparkLinesEventLoop() { ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() ui.Body.Align() ui.Render(ui.Body) }) ui.Loop() // blocking call }
func main() { flag.Parse() if err := ui.Init(); err != nil { panic(err) } defer ui.Close() draw() ui.Handle("/sys/kbd", func(e ui.Event) { ev := e.Data.(ui.EvtKbd) switch ev.KeyStr { case ":": promptMsg = ":" case "C-8": if l := len(promptMsg); l != 0 { promptMsg = promptMsg[:l-1] } case "<enter>": handleInput() promptMsg = "" case "<left>": case "<up>": if reportPage > 0 { reportPage-- } case "<right>": case "<down>": reportPage++ case "<escape>": promptMsg = "" default: // TODO: filter irrelevant keys such as up, down, etc. promptMsg += ev.KeyStr } refresh() }) ui.Handle("/sys/kbd/C-c", func(ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(ui.Event) { loadProfile(false) loadStats() refresh() }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() refresh() }) ui.Body.Align() ui.Render(ui.Body) ui.Loop() }
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() }
func (p *CommandBar) Update() { if len(p.text) == 0 { if obj, ok := currentPage.(CommandBoxer); ok { obj.SetCommandMode(false) } } else { p.commandType = p.text[0] } ls := p.uiList strs := []string{string(p.text)} ls.Items = strs ui.Render(ls) }
func DisplayDiscovering() { p := ui.NewPar("Discovering Pip-Boys") p.Width = 22 p.Height = 3 discoverUi := ui.NewGrid( ui.NewRow( ui.NewCol(4, 4, p), ), ) discoverUi.Width = ui.Body.Width discoverUi.Align() ui.Render(discoverUi) }
// 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 }