Пример #1
0
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()
			}
		}
	}()
}
Пример #2
0
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()

}
Пример #3
0
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()
}
Пример #4
0
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()
}
Пример #5
0
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()
}
Пример #6
0
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)
		}
	}
}
Пример #7
0
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()
}
Пример #8
0
func main() {
	err := ui.Init()
	if err != nil {
		panic(err)
	}
	defer ui.Close()
	initial()
	ech := ui.EventCh()
	for screen := intro; screen != nil; {
		screen = screen(ech)
	}
}
Пример #9
0
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()
}
Пример #10
0
Файл: main.go Проект: bnadland/r
func showSubreddit(subredditName string) error {
	r := geddit.NewSession("r by /u/bnadland")

	submissions, err := r.SubredditSubmissions(subredditName, geddit.HotSubmissions, geddit.ListingOptions{})
	if err != nil {
		return err
	}

	isActive := true

	cursor := 3
	for isActive {

		entries := []string{}
		for i, submission := range submissions {
			entries = append(entries, fmt.Sprintf("%s %s", isActiveCursor(cursor, i), submission.Title))
		}

		ls := termui.NewList()
		ls.Items = entries
		ls.ItemFgColor = termui.ColorDefault
		ls.Border.Label = fmt.Sprintf("Subreddit: %s", subredditName)
		ls.Height = termui.TermHeight()
		ls.Width = termui.TermWidth()
		ls.Y = 0
		termui.Render(ls)
		event := <-termui.EventCh()
		if event.Type == termui.EventKey {
			switch event.Key {
			case termui.KeyArrowLeft:
				isActive = false
			case termui.KeyArrowDown:
				cursor = cursor + 1
				if cursor > len(submissions) {
					cursor = len(submissions)
				}
			case termui.KeyArrowUp:
				cursor = cursor - 1
				if cursor < 0 {
					cursor = 0
				}
			}
		}
	}
	return nil
}
Пример #11
0
func main() {
	err := ui.Init()
	fmt.Println(daemon.UpSince())
	if err != nil {
		fmt.Println("Could not initialise UI")
	}
	defer ui.Close()

	ut, _ := daemon.Uptime()
	p := ui.NewPar(ut.String())
	p.Height = 3
	p.Width = 50
	p.TextFgColor = ui.ColorWhite
	p.Border.Label = "Uptime"
	p.Border.FgColor = ui.ColorCyan

	g0 := ui.NewGauge()
	g0.Percent = 40
	g0.Width = 50
	g0.Height = 3
	g0.Border.Label = "Memory"
	g0.BarColor = ui.ColorRed
	g0.Border.FgColor = ui.ColorWhite
	g0.Border.LabelFgColor = ui.ColorCyan

	g2 := ui.NewGauge()
	g2.Percent = 60
	g2.Width = 50
	g2.Height = 3
	g2.PercentColor = ui.ColorBlue
	g2.Y = 3
	g2.Border.Label = "CPU"
	g2.BarColor = ui.ColorYellow
	g2.Border.FgColor = ui.ColorWhite

	ui.Body.AddRows(ui.NewRow(ui.NewCol(6, 0, g0), ui.NewCol(6, 0, p)),
		ui.NewRow(ui.NewCol(6, 0, g2)))
	ui.Body.Align()
	ui.Render(ui.Body)
	go updateMemCPU(g2, g0)
	go updateUptime(p)
	<-ui.EventCh()
}
Пример #12
0
func maintainSparkLines(redraw chan bool, quit chan bool) {
	evt := ui.EventCh()
	for {
		select {
		case e := <-evt:
			if e.Type == ui.EventKey && e.Ch == 'q' {
				quit <- true
				return
			}
			if e.Type == ui.EventResize {
				ui.Body.Width = ui.TermWidth()
				ui.Body.Align()
				go func() { redraw <- true }()
			}
		case <-redraw:
			ui.Render(ui.Body)
		}
	}
}
Пример #13
0
Файл: main.go Проект: rzh/montu
func main() {
	// show flashscreen

	views.MainView().Init()
	err := termui.Init()
	if err != nil {
		panic(err)
	}
	defer termui.Close()

	currentView = views.MainView().SwitchToView()

	go func() {
		for {
			currentView.Render()

			time.Sleep(1 * time.Second)
		}
	}()

	for {
		e := <-termui.EventCh()

		if e.Type == termui.EventKey {
			if e.Key == termui.KeyEsc {
				break
			} else if e.Key == termui.KeyArrowLeft {
				currentView = views.EventView().SwitchToView()
				currentView.Render()
			} else if e.Key == termui.KeyArrowRight {
				currentView = views.MainView().SwitchToView()
				currentView.Render()
			} else if e.Key == termui.KeyArrowUp {
				currentView = views.RPSView().SwitchToView()
				currentView.Render()
			} else {
				// FIXME: quit with any key
				break
			}
		}
	}
}
Пример #14
0
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()
}
Пример #15
0
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()
}
Пример #16
0
func showMainWindow() {

	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.Border.Label = "Text Box"
	p.Border.FgColor = ui.ColorCyan

	draw := func(t int) {
		ui.Render(p)
	}

	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)
		}
	}
}
Пример #17
0
func main() {

	sysmon = gtop.NewSysmon()
	go sysmon.MonCPU()

	err := termui.Init()
	if err != nil {
		panic(err)
	}
	defer termui.Close()

	bufferer := []termui.Bufferer{}

	lcpu_c, _, err := sysmon.CPUCount()
	if err == nil {
		cpu_bars = []*gtop.Bar{}
		bar_offset := 0
		for i := 0; i < lcpu_c; i++ {
			b := gtop.NewBar(35, 2, 1+bar_offset, strconv.Itoa(i+1), &bufferer)
			cpu_bars = append(cpu_bars, b)
			bar_offset += b.Height
		}
	}

	go render_loop(bufferer)
	go update_cpu_bars()

	evt := termui.EventCh()
	for {
		select {
		case e := <-evt:
			if e.Type == termui.EventKey && e.Ch == 0 {
				return
			}
		}
	}
}
Пример #18
0
func main() {
	flag.Usage = Usage
	flag.Parse()

	// Process ports/urls
	ports, _ := ParsePorts(*urls)
	if *self {
		port, err := StartSelfMonitor()
		if err == nil {
			ports = append(ports, port)
		}
	}
	if len(ports) == 0 {
		fmt.Fprintln(os.Stderr, "no ports specified. Use -ports arg to specify ports of Go apps to monitor")
		Usage()
		os.Exit(1)
	}
	if *interval <= 0 {
		fmt.Fprintln(os.Stderr, "update interval is not valid. Valid examples: 5s, 1m, 1h30m")
		Usage()
		os.Exit(1)
	}

	// Process vars
	vars, err := ParseVars(*varsArg)
	if err != nil {
		log.Fatal(err)
	}

	// Init UIData
	data := NewUIData(vars)
	for _, port := range ports {
		service := NewService(port, vars)
		data.Services = append(data.Services, service)
	}

	// Start proper UI
	var ui UI
	if len(data.Services) > 1 {
		ui = &TermUI{}
	} else {
		ui = &TermUISingle{}
	}
	if *dummy {
		ui = &DummyUI{}
	}

	if err := ui.Init(*data); err != nil {
		log.Fatal(err)
	}
	defer ui.Close()

	tick := time.NewTicker(*interval)
	evtCh := termui.EventCh()

	UpdateAll(ui, data)
	for {
		select {
		case <-tick.C:
			UpdateAll(ui, data)
		case e := <-evtCh:
			if e.Type == termui.EventKey && e.Ch == 'q' {
				return
			}
			if e.Type == termui.EventResize {
				ui.Update(*data)
			}
		}
	}
}
Пример #19
0
// 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)
		}
	}
}
Пример #20
0
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[:100]
	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()

	done := make(chan bool)
	redraw := make(chan bool)

	/*
		update := func() {
			for i := 0; i < 103; i++ {
				for _, g := range gs {
					g.Percent = (g.Percent + 3) % 100
				}

				sp.Lines[0].Data = spdata[:100+i]
				lc.Data = sinps[2*i:]

				time.Sleep(time.Second / 2)
				redraw <- true
			}
			done <- 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)
		}
	}
}
Пример #21
0
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)
		}
	}
}
Пример #22
0
func main() {
	pfile := flag.String("f", "", "psafe3 file")
	flag.Parse()

	fmt.Printf("Password: "******"Last Saved: %s\nLast Saved By %s @ %s",
		safe.Headers.LastSave.Format("2006-01-02 15:04:05"),
		safe.Headers.User, safe.Headers.Host))
	rightpar.Height = 2
	rightpar.HasBorder = false

	leftpar := termui.NewPar(fmt.Sprintf("File Name: %s\nLast Program: %s",
		filepath.Base(*pfile),
		safe.Headers.ProgramSave))
	leftpar.Height = 2
	leftpar.HasBorder = false

	recordlist := termui.NewList()
	recordlist.Height = termui.TermHeight() - 5
	recordlist.Items = getRecordList(safe)
	recordlist.Border.Label = fmt.Sprintf("Records (%d)", len(safe.Records))

	recorddetail := termui.NewPar("")
	recorddetail.Height = recordlist.Height
	recorddetail.Border.Label = "Record Information"

	inputbox := termui.NewPar("")
	inputbox.Height = 3
	inputbox.Border.Label = "Input Box ([Enter] to save, [Esc] to cancel)"
	inputrow := termui.NewRow(termui.NewCol(12, 0, inputbox))

	commandinfo := termui.NewPar(strings.Join([]string{
		"Select record by typing the index number. Edit field by typing field marker.",
	}, "\n"))
	commandinfo.Height = 3
	commandinfo.Border.Label = "Help"
	commandrow := termui.NewRow(termui.NewCol(12, 0, commandinfo))

	termui.Body.AddRows(
		termui.NewRow(
			termui.NewCol(6, 0, leftpar),
			termui.NewCol(6, 0, rightpar),
		),
		termui.NewRow(
			termui.NewCol(6, 0, recordlist),
			termui.NewCol(6, 0, recorddetail),
		),
		commandrow,
	)

	termui.Body.Align()
	termui.Render(termui.Body)

	evt := termui.EventCh()

	inputMode := false
	valBuffer := bytes.Buffer{}
	numBuffer := bytes.Buffer{}
	var selRecord *pwsafe.Record
	var selField *string
	var inputPrompt string
	var startIndex int
Main:
	for {
		select {
		case e := <-evt:
			if !inputMode && e.Type == termui.EventKey {
				switch e.Ch {
				case 'q':
					break Main
				case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
					numBuffer.WriteRune(e.Ch)
				case '#':
					selIndex, _ := strconv.ParseInt(numBuffer.String(), 10, 64)
					selRecord = &safe.Records[selIndex]
					selField = nil
					numBuffer.Reset()
				case 'j':
					startIndex++
					rlist := getRecordList(safe)
					recordlist.Items = rlist[startIndex:]
				case 'k':
					if startIndex > 1 {
						startIndex--
						rlist := getRecordList(safe)
						recordlist.Items = rlist[startIndex:]
					}
				case 'a':
					selIndex := len(safe.Records)
					safe.Records = append(safe.Records, pwsafe.Record{})
					selRecord = &safe.Records[selIndex]
					selRecord.UUID = uuid.NewV1()
					selRecord.CreationTime = time.Now()
					selField = nil
					rlist := getRecordList(safe)
					recordlist.Items = rlist[startIndex:]
					recordlist.Border.Label = fmt.Sprintf("Records (%d)", len(safe.Records))
				case 'g':
					selField = &selRecord.Group
					inputPrompt = "Group: "
					inputMode = true
					valBuffer.WriteString(selRecord.Group)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 't':
					selField = &selRecord.Title
					inputPrompt = "Title: "
					inputMode = true
					valBuffer.WriteString(selRecord.Title)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 'u':
					selField = &selRecord.Username
					inputPrompt = "Username: "******"Password: "******"Url: "
					inputMode = true
					valBuffer.WriteString(selRecord.Url)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 'n':
					selField = &selRecord.Notes
					inputPrompt = "Notes: "
					inputMode = true
					valBuffer.WriteString(selRecord.Notes)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 'e':
					selField = &selRecord.Email
					inputPrompt = "Email: "
					inputMode = true
					valBuffer.WriteString(selRecord.Email)
					inputbox.Text = inputPrompt + valBuffer.String()
				}
			} else if inputMode && e.Type == termui.EventKey {
				if e.Key == termui.KeyEnter {
					if selField != nil {
						*selField = valBuffer.String()
					}
					valBuffer.Reset()
					inputMode = false
					inputbox.Text = ""
					rlist := getRecordList(safe)
					recordlist.Items = rlist[startIndex:]
				} else if e.Key == termui.KeyEsc {
					valBuffer.Reset()
					inputMode = false
					inputbox.Text = ""
				} else if e.Key == termui.KeySpace {
					valBuffer.WriteRune(' ')
				} else if e.Key == termui.KeyBackspace || e.Ch == '' {
					s := valBuffer.String()
					valBuffer = bytes.Buffer{}
					if len(s) > 0 {
						s = s[0 : len(s)-1]
					}
					valBuffer.WriteString(s)
					inputbox.Text = inputPrompt + valBuffer.String()
				} else {
					valBuffer.WriteRune(e.Ch)
					inputbox.Text = inputPrompt + valBuffer.String()
				}
			}
			if e.Type == termui.EventResize {
				termui.Body.Width = termui.TermWidth()
				termui.Body.Align()
			}

			if selRecord != nil {
				recorddetail.Text = getRecordDetail(*selRecord)
			}

			if inputMode {
				termui.Body.Rows[2] = inputrow
			} else {
				termui.Body.Rows[2] = commandrow
			}
			termui.Body.Align()
			termui.Render(termui.Body)
		}
	}

	oerr := pwsafe.OutputFile(*pfile, string(pw), *safe)
	if oerr != nil {
		log.Fatalln(oerr)
	}

}
Пример #23
0
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)
		}
	}
}
Пример #24
0
func selectConnection(conf *types.Configuration, input string) *types.Connection {
	if err := ui.Init(); err != nil {
		panic(err)
	}
	defer func() {
		ui.Close()
		if e := recover(); e != nil {
			panic(e)
		}
	}()
	treeView := NewSelectList()
	treeView.Border.Label = " Connections "

	debugView := ui.NewPar("")

	searchView := ui.NewPar(input)
	searchView.Border.Label = " Search "

	connectButton := ui.NewPar(" Connect ")

	menuView := ui.NewRow(
		ui.NewCol(8, 0, connectButton),
	)

	selectedButton := 0
	buttons := []*ui.Par{connectButton}

	selectButtons := func() {
		selectedButton %= len(buttons)
		for i, v := range buttons {
			if i == selectedButton {
				v.TextBgColor = ui.ColorBlue
			} else {
				v.TextBgColor = ui.ColorDefault
			}
		}
	}
	selectButtons()

	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(12, 0, treeView)),
		ui.NewRow(
			ui.NewCol(12, 0, debugView)),
		ui.NewRow(
			ui.NewCol(6, 0, searchView),
			ui.NewCol(6, 0, menuView)))

	heights := func() {
		searchView.Height = 3
		connectButton.Height = searchView.Height
		menuView.Height = searchView.Height
		debugView.Height = 5
		treeView.Height = ui.TermHeight() - searchView.Height - debugView.Height
	}
	heights()

	ui.Body.Align()

	connectionsIndex := make(map[int]types.Node)
	pathToIndexMap := make(map[string]int)
	var distances map[string]int
	var filteredRoot *types.Container

	doRefilter := func() {
		pathToIndexMap := make(map[string]int)
		distances, _ = filter(conf, input)
		filteredRoot = filterTree(conf, distances)
		drawTree(treeView, connectionsIndex, distances, pathToIndexMap, filteredRoot)
		/*if bestMatchPath != "" {
			if index, ok := pathToIndexMap[bestMatchPath]; ok {
				treeView.CurrentSelection = index
			}
		}*/
	}
	doRefilter()

	events := make(chan ui.Event)

	go func(in <-chan ui.Event, out chan<- ui.Event) {
		for e := range in {
			out <- e
		}
		close(out)
	}(ui.EventCh(), events)
	for {
		ui.Render(ui.Body)
		ev := <-events
		if ev.Err != nil {
			debugView.Text = ev.Err.Error()
		}

		refilter := false
		switch ev.Type {
		case ui.EventResize:
			heights()
			ui.Body.Width = ev.Width
			ui.Body.Align()
			treeView.Debug += "  resize"
		case ui.EventKey:
			if ev.Key <= ui.KeyHome && ev.Key >= ui.KeyArrowRight {
				switch ev.Key {
				case ui.KeyHome:
					treeView.CurrentSelection = 0
				case ui.KeyEnd:
					treeView.CurrentSelection = len(treeView.Items) - 1
				case ui.KeyPgup:
					treeView.CurrentSelection -= treeView.Height - 3
				case ui.KeyPgdn:
					treeView.CurrentSelection += treeView.Height + 3
				case ui.KeyArrowDown:
					treeView.CurrentSelection++
				case ui.KeyArrowUp:
					treeView.CurrentSelection--
				case ui.KeyArrowLeft:
					selectedButton--
					selectButtons()
				case ui.KeyArrowRight:
					selectedButton++
					selectButtons()
				}
				if treeView.CurrentSelection > len(treeView.Items)-1 {
					treeView.CurrentSelection = len(treeView.Items) - 1
				} else if treeView.CurrentSelection < 0 {
					treeView.CurrentSelection = 0
				}
			} else if ev.Key == ui.KeyEnter {
				n := connectionsIndex[treeView.CurrentSelection]
				if c, ok := n.(*types.Connection); ok {
					if buttons[selectedButton] == connectButton {
						return c
					}
				} else if c, ok := n.(*types.Container); ok {
					if c.Expanded {
						c.Expanded = false
					} else {
						c.Expanded = true
					}
					drawTree(treeView, connectionsIndex, distances, pathToIndexMap, filteredRoot)
				}

			} else if ev.Key == ui.KeyEsc || ev.Key == ui.KeyCtrlC {
				return nil
			} else if ev.Ch >= ' ' && ev.Ch <= '~' {
				input += string(ev.Ch)
				searchView.Text = input

				refilter = true
			} else if ev.Key == ui.KeyBackspace || ev.Key == ui.KeyBackspace2 {
				if len(input) > 0 {
					input = input[:len(input)-1]
					searchView.Text = input
					refilter = true
				}
			}
		}

		if refilter {
			doRefilter()
		}

		if ev.Err == nil {
			if DEBUG {
				debugView.Text = fmt.Sprint(distances)
				debugView.Text += fmt.Sprintf(
					" ev: %d key: %x input: %s|\ncur: %d scroll: %d scrolledCur: %d len: %d\ninner: %d align: %s",
					ev.Type, ev.Key, input, treeView.CurrentSelection, treeView.scroll,
					treeView.scrolledSelection, len(treeView.Items), treeView.InnerHeight(), treeView.Debug)
				treeView.Debug = ""
			} else {
				n := connectionsIndex[treeView.CurrentSelection]
				if c, ok := n.(*types.Connection); ok {
					debugView.Text = fmt.Sprintf("%s %s:%d\n%s",
						c.Info.Protocol, c.Info.Host, c.Info.Port, c.Info.Description)
				} else if _, ok := n.(*types.Container); ok {
					debugView.Text = ""
				}
			}
		}
	}
}
Пример #25
0
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)
				}
			}
		}
	}
}
Пример #26
0
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.Border.Label = "Text Box"
	p.Border.FgColor = ui.ColorCyan

	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.ItemFgColor = ui.ColorYellow
	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"
	g.BarColor = ui.ColorRed
	g.Border.FgColor = ui.ColorWhite
	g.Border.LabelFgColor = ui.ColorCyan

	spark := ui.Sparkline{}
	spark.Height = 1
	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
	spark.LineColor = ui.ColorCyan
	spark.TitleColor = ui.ColorWhite

	spark1 := ui.Sparkline{}
	spark1.Height = 1
	spark1.Title = "srv 1:"
	spark1.Data = spdata
	spark1.TitleColor = ui.ColorWhite
	spark1.LineColor = ui.ColorRed

	sp := ui.NewSparklines(spark, spark1)
	sp.Width = 25
	sp.Height = 7
	sp.Border.Label = "Sparkline"
	sp.Y = 4
	sp.X = 25

	sinps := (func() []float64 {
		n := 220
		ps := make([]float64, n)
		for i := range ps {
			ps[i] = 1 + math.Sin(float64(i)/5)
		}
		return ps
	})()

	lc := ui.NewLineChart()
	lc.Border.Label = "dot-mode Line Chart"
	lc.Data = sinps
	lc.Width = 50
	lc.Height = 11
	lc.X = 0
	lc.Y = 14
	lc.AxesColor = ui.ColorWhite
	lc.LineColor = ui.ColorRed | ui.AttrBold
	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
	bc.BarColor = ui.ColorGreen
	bc.NumColor = ui.ColorBlack

	lc1 := ui.NewLineChart()
	lc1.Border.Label = "braille-mode Line Chart"
	lc1.Data = sinps
	lc1.Width = 26
	lc1.Height = 11
	lc1.X = 51
	lc1.Y = 14
	lc1.AxesColor = ui.ColorWhite
	lc1.LineColor = ui.ColorYellow | ui.AttrBold

	p1 := ui.NewPar("Hey!\nI am a borderless block!")
	p1.HasBorder = false
	p1.Width = 26
	p1.Height = 2
	p1.TextFgColor = ui.ColorMagenta
	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 = sinps[2*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)
		}
	}
}
Пример #27
0
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 (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
}
Пример #29
0
func Run(cliConnection plugin.CliConnection, args []string) {
	if len(args) == 0 {
		helper.CallCommandHelp("statistics", "Incorrect usage.\n")
		os.Exit(1)
	}

	var debugOutput, fullOutput bool
	for _, arg := range args[1:] {
		switch arg {
		case "--debug":
			debugOutput = true
		case "--full":
			fullOutput = true
		}
	}

	appName := args[0]
	appGuid := getAppGuid(cliConnection, appName)

	statsChan := make(chan Statistics)
	errChan := make(chan error)
	defer close(statsChan)
	defer close(errChan)

	go pollStats(cliConnection, appGuid, statsChan, errChan)

	// setup ui
	if !debugOutput {
		if err := newTerminalUI(appName); err != nil {
			fmt.Println("\nERROR:", err)
			os.Exit(1)
		}
		defer term.Close()
	}

	// main loop
	var nofInstances int
	for {
		select {

		// ui events
		case e := <-ui.EventCh():
			if e.Type == ui.EventKey {
				if e.Ch == 'q' || e.Key == ui.KeyCtrlC {
					term.Close()
					os.Exit(0)
				} else if e.Key == ui.KeyPgup {
					// ui shows max 8 instances
					if nofInstances < 8 {
						scaleApp(cliConnection, appName, nofInstances+1)
					}
				} else if e.Key == ui.KeyPgdn {
					if nofInstances > 1 {
						scaleApp(cliConnection, appName, nofInstances-1)
					}
				}
			}

			if e.Type == ui.EventResize {
				term.Resize()
			}

			if e.Type == ui.EventError {
				term.Close()
				fmt.Println("\nERROR:", e.Err)
				os.Exit(0)
			}

		case stats := <-statsChan:
			nofInstances = len(stats.Instances)

			// print to stdout if --debug is set
			if debugOutput {
				for _, idx := range stats.Instances {
					var data interface{}

					// print only usage metrics if --full is not set
					data = stats.Data[idx].Stats.Usage
					if fullOutput {
						data = stats.Data[idx]
					}

					output, err := json.Marshal(data)
					if err != nil {
						fmt.Println("\nERROR:", err)
						os.Exit(1)
					}
					fmt.Printf("{\"instance_index\":\"%s\",\"metrics\":%v}\n", idx, string(output))
				}
			} else {
				// render terminal dashboard
				term.UpdateStatistics(stats)
			}

		case err := <-errChan:
			if !debugOutput {
				term.Close()
			}
			fmt.Println("\nERROR:", err)
			os.Exit(1)

		case <-time.After(time.Second * 15):
			if !debugOutput {
				term.Close()
			}
			fmt.Println("\nTIMEOUT")
			fmt.Println("Querying metrics took too long.. Check your connectivity!")
			os.Exit(1)
		}
	}
}
Пример #30
0
// StartUI periodically refreshes the screen using recent data
func StartUI(
	opts map[string]interface{},
	statsCh chan *Stats,
	shutdownCh chan struct{},
) {

	cleanStats := &Stats{
		Varz:  &gnatsd.Varz{},
		Connz: &gnatsd.Connz{},
		Rates: &Rates{},
	}

	// Show empty values on first display
	text := generateParagraph(opts, cleanStats)
	par := ui.NewPar(text)
	par.Height = ui.TermHeight()
	par.Width = ui.TermWidth()
	par.HasBorder = false

	helpText := generateHelp()
	helpPar := ui.NewPar(helpText)
	helpPar.Height = ui.TermHeight()
	helpPar.Width = ui.TermWidth()
	helpPar.HasBorder = false

	// Top like view
	paraRow := ui.NewRow(ui.NewCol(ui.TermWidth(), 0, par))

	// Help view
	helpParaRow := ui.NewRow(ui.NewCol(ui.TermWidth(), 0, helpPar))

	// Create grids that we'll be using to toggle what to render
	topViewGrid := ui.NewGrid(paraRow)
	helpViewGrid := ui.NewGrid(helpParaRow)

	// Start with the topviewGrid by default
	ui.Body.Rows = topViewGrid.Rows
	ui.Body.Align()

	// Used to toggle back to previous mode
	viewMode := TopViewMode

	// Used for pinging the IU to refresh the screen with new values
	redraw := make(chan struct{})

	update := func() {
		for {
			stats := <-statsCh

			// Update top view text
			text = generateParagraph(opts, stats)
			par.Text = text

			redraw <- struct{}{}
		}
	}

	// Flags for capturing options
	waitingSortOption := false
	waitingLimitOption := false
	displaySubscriptions := false

	optionBuf := ""
	refreshOptionHeader := func() {
		// Need to mask what was typed before
		clrline := "\033[1;1H\033[6;1H                  "

		clrline += "  "
		for i := 0; i < len(optionBuf); i++ {
			clrline += "  "
		}
		fmt.Printf(clrline)
	}

	evt := ui.EventCh()

	ui.Render(ui.Body)

	go update()

	for {
		select {
		case e := <-evt:

			if waitingSortOption {

				if e.Type == ui.EventKey && e.Key == ui.KeyEnter {

					sortOpt := gnatsd.SortOpt(optionBuf)
					switch sortOpt {
					case SortByCid, SortBySubs, SortByPending, SortByOutMsgs, SortByInMsgs, SortByOutBytes, SortByInBytes:
						opts["sort"] = sortOpt
					default:
						go func() {
							// Has to be at least of the same length as sort by header
							emptyPadding := "       "
							fmt.Printf("\033[1;1H\033[6;1Hinvalid order: %s%s", optionBuf, emptyPadding)
							waitingSortOption = false
							time.Sleep(1 * time.Second)
							refreshOptionHeader()
							optionBuf = ""
						}()
						continue
					}

					refreshOptionHeader()
					waitingSortOption = false
					optionBuf = ""
					continue
				}

				// Handle backspace
				if e.Type == ui.EventKey && len(optionBuf) > 0 && (e.Key == ui.KeyBackspace || e.Key == ui.KeyBackspace2) {
					optionBuf = optionBuf[:len(optionBuf)-1]
					refreshOptionHeader()
				} else {
					optionBuf += string(e.Ch)
				}
				fmt.Printf("\033[1;1H\033[6;1Hsort by [%s]: %s", opts["sort"], optionBuf)
			}

			if waitingLimitOption {

				if e.Type == ui.EventKey && e.Key == ui.KeyEnter {

					var n int
					_, err := fmt.Sscanf(optionBuf, "%d", &n)
					if err == nil {
						opts["conns"] = n
					}

					waitingLimitOption = false
					optionBuf = ""
					refreshOptionHeader()
					continue
				}

				// Handle backspace
				if e.Type == ui.EventKey && len(optionBuf) > 0 && (e.Key == ui.KeyBackspace || e.Key == ui.KeyBackspace2) {
					optionBuf = optionBuf[:len(optionBuf)-1]
					refreshOptionHeader()
				} else {
					optionBuf += string(e.Ch)
				}
				fmt.Printf("\033[1;1H\033[6;1Hlimit   [%d]: %s", opts["conns"], optionBuf)
			}

			if e.Type == ui.EventKey && (e.Ch == 'q' || e.Key == ui.KeyCtrlC) {
				close(shutdownCh)
				cleanExit()
			}

			if e.Type == ui.EventKey && e.Ch == 's' && !(waitingLimitOption || waitingSortOption) {
				if displaySubscriptions {
					displaySubscriptions = false
					opts["subs"] = false
				} else {
					displaySubscriptions = true
					opts["subs"] = true
				}
			}

			if e.Type == ui.EventKey && viewMode == HelpViewMode {
				ui.Body.Rows = topViewGrid.Rows
				viewMode = TopViewMode
				continue
			}

			if e.Type == ui.EventKey && e.Ch == 'o' && !waitingLimitOption && viewMode == TopViewMode {
				fmt.Printf("\033[1;1H\033[6;1Hsort by [%s]:", opts["sort"])
				waitingSortOption = true
			}

			if e.Type == ui.EventKey && e.Ch == 'n' && !waitingSortOption && viewMode == TopViewMode {
				fmt.Printf("\033[1;1H\033[6;1Hlimit   [%d]:", opts["conns"])
				waitingLimitOption = true
			}

			if e.Type == ui.EventKey && (e.Ch == '?' || e.Ch == 'h') && !(waitingSortOption || waitingLimitOption) {
				if viewMode == TopViewMode {
					refreshOptionHeader()
					optionBuf = ""
				}

				ui.Body.Rows = helpViewGrid.Rows
				viewMode = HelpViewMode
				waitingLimitOption = false
				waitingSortOption = false
			}

			if e.Type == ui.EventResize {
				ui.Body.Width = ui.TermWidth()
				ui.Body.Align()
				go func() { redraw <- struct{}{} }()
			}

		case <-redraw:
			ui.Render(ui.Body)
		}
	}
}