// New creates a new edit info console GUI. // func New(log cdtype.Logger, packs packages.AppletPackages) *Editor { ed := &Editor{ applets: termui.NewList(), fields: termui.NewList(), appinfo: termui.NewList(), locked: termui.NewPar(""), desc: termui.NewPar(""), title: termui.NewPar(infoText), packs: packs, log: log, } ed.applets.ItemFgColor = termui.ColorYellow ed.applets.BorderLabel = "[ Applets ]" ed.applets.Width = 20 // TODO autodetect. ed.applets.BorderBottom = false ed.applets.BorderFg = termui.ColorCyan ed.fields.BorderLabel = "[ Fields ]" ed.fields.X = ed.applets.Width ed.fields.Height = 6 + 2 + 2 // last 2 for blank lines around text ed.fields.Width = len(fields[1]) + 2 ed.fields.BorderLeft = false ed.fields.BorderBottom = false ed.fields.BorderFg = termui.ColorCyan ed.appinfo.BorderLabel = "[ Value ]" ed.appinfo.X = ed.fields.X + ed.fields.Width ed.appinfo.Height = 6 + 2 + 2 // last 2 for blank lines around text ed.appinfo.BorderLeft = false ed.appinfo.BorderRight = false ed.appinfo.BorderBottom = false ed.appinfo.BorderFg = termui.ColorCyan ed.locked.BorderLabel = "[ Details ]" ed.locked.X = ed.applets.Width ed.locked.Y = ed.fields.Height - 1 // offset 1 for border ed.locked.Height = 6 ed.locked.BorderBottom = false ed.locked.BorderLeft = false ed.locked.BorderRight = false ed.locked.BorderFg = termui.ColorCyan ed.desc.BorderLabel = "[ Description ]" ed.desc.X = ed.applets.Width ed.desc.BorderBottom = false ed.desc.BorderLeft = false ed.desc.BorderRight = false ed.desc.BorderFg = termui.ColorCyan ed.title.BorderLabel = "[ Edit applet info ]" ed.title.Height = 2 ed.title.TextFgColor = termui.ColorWhite ed.title.BorderBottom = false ed.title.BorderLeft = false ed.title.BorderRight = false ed.title.BorderFg = termui.ColorCyan return ed }
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() }
// NewScrollingList returns a new *ScrollingList with current theme. func NewScrollingList() *ScrollingList { l := &ScrollingList{} l.List = *ui.NewList() l.Scroller = Scroller{} l.Scroller.block = &l.List.Block return l }
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 createContainerList() *ui.List { list := ui.NewList() list.ItemFgColor = ui.ColorCyan list.BorderFg = ui.ColorBlack list.Border = true return list }
func (p *TicketListPage) Create() { log.Debugf("TicketListPage.Create(): self: %s (%p)", p.Id(), p) log.Debugf("TicketListPage.Create(): currentPage: %s (%p)", currentPage.Id(), currentPage) ui.Clear() ls := ui.NewList() p.uiList = ls if p.statusBar == nil { p.statusBar = new(StatusBar) } if p.commandBar == nil { p.commandBar = commandBar } query := p.ActiveQuery.JQL if sort := p.ActiveSort.JQL; sort != "" { re := regexp.MustCompile(`(?i)\s+ORDER\s+BY.+$`) query = re.ReplaceAllString(query, ``) + " " + sort } if len(p.cachedResults) == 0 { p.cachedResults = JiraQueryAsStrings(query, p.ActiveQuery.Template) } if p.selectedLine >= len(p.cachedResults) { p.selectedLine = len(p.cachedResults) - 1 } p.displayLines = make([]string, len(p.cachedResults)) ls.ItemFgColor = ui.ColorYellow ls.BorderLabel = fmt.Sprintf("%s: %s", p.ActiveQuery.Name, p.ActiveQuery.JQL) ls.Height = ui.TermHeight() - 2 ls.Width = ui.TermWidth() ls.Y = 0 p.statusBar.Create() p.commandBar.Create() p.Update() }
func (p *LabelListPage) Create() { ui.Clear() ls := ui.NewList() p.uiList = ls if p.statusBar == nil { p.statusBar = new(StatusBar) } if p.commandBar == nil { p.commandBar = commandBar } queryName := p.ActiveQuery.Name queryJQL := p.ActiveQuery.JQL p.labelCounts = countLabelsFromQuery(queryJQL) p.cachedResults = p.labelsAsSortedList() p.isPopulated = true p.displayLines = make([]string, len(p.cachedResults)) ls.ItemFgColor = ui.ColorYellow ls.BorderLabel = fmt.Sprintf("Label view -- %s: %s", queryName, queryJQL) ls.Height = ui.TermHeight() - 2 ls.Width = ui.TermWidth() ls.Y = 0 p.statusBar.Create() p.commandBar.Create() p.Update() }
func NewUi() Ui { headerWidget := termui.NewPar(fmt.Sprintf("podcastd v%s\nCopyright 2015 Philippe Gerber\nhttps://github.com/bigwhoop/podcastd", VERSION)) headerWidget.Height = 5 headerWidget.HasBorder = false headerWidget.PaddingTop = 1 headerWidget.PaddingBottom = 1 headerWidget.PaddingLeft = 1 infoWidget := termui.NewPar("") infoWidget.HasBorder = false infoWidget.Text = fmt.Sprintf("Press 'q' to quit") feedsWidget := termui.NewList() feedsWidget.Border.Label = "Feeds" return Ui{ termui.TermWidth(), headerWidget, infoWidget, feedsWidget, make(map[string]bool, 0), make([]*termui.Gauge, 0), make(map[string]curl.ProgressStatus, 0), } }
// songsWidget Provides the song list widget func songsWidget() *termui.List { w := termui.NewList() w.Items = []string{"Downloading..."} w.BorderLabel = "Song list" w.Height = 5 return w }
func NewSelectList() *SelectList { s := &SelectList{Block: *ui.NewBlock()} s.upperList = *ui.NewList() s.lowerList = *ui.NewList() s.upperList.HasBorder = false s.lowerList.HasBorder = false s.HasBorder = true s.middle = *ui.NewPar("") s.middle.Height = 1 s.middle.HasBorder = false s.middle.TextBgColor = ui.ColorBlue s.upperList.Overflow = "wrap" s.lowerList.Overflow = "wrap" return s }
func (p *CommandBar) Create() { ls := ui.NewList() p.uiList = ls ls.ItemFgColor = ui.ColorGreen ls.Border = false ls.Height = 1 ls.Width = ui.TermWidth() ls.X = 0 ls.Y = ui.TermHeight() - 1 p.Update() }
func (p *TicketShowPage) Create() { log.Debugf("TicketShowPage.Create(): self: %s (%p)", p.Id(), p) log.Debugf("TicketShowPage.Create(): currentPage: %s (%p)", currentPage.Id(), currentPage) p.opts = getJiraOpts() if p.TicketId == "" { p.TicketId = ticketListPage.GetSelectedTicketId() } if p.MaxWrapWidth == 0 { if m := p.opts["max_wrap"]; m != nil { p.MaxWrapWidth = uint(m.(int64)) } else { p.MaxWrapWidth = defaultMaxWrapWidth } } ui.Clear() ls := ui.NewList() if p.statusBar == nil { p.statusBar = new(StatusBar) } if p.commandBar == nil { p.commandBar = commandBar } p.uiList = ls if p.Template == "" { if templateOpt := p.opts["template"]; templateOpt == nil { p.Template = "jira_ui_view" } else { p.Template = templateOpt.(string) } } innerWidth := uint(ui.TermWidth()) - 3 if innerWidth < p.MaxWrapWidth { p.WrapWidth = innerWidth } else { p.WrapWidth = p.MaxWrapWidth } if p.apiBody == nil { p.apiBody, _ = FetchJiraTicket(p.TicketId) } p.cachedResults = WrapText(JiraTicketAsStrings(p.apiBody, p.Template), p.WrapWidth) p.displayLines = make([]string, len(p.cachedResults)) if p.selectedLine >= len(p.cachedResults) { p.selectedLine = len(p.cachedResults) - 1 } ls.ItemFgColor = ui.ColorYellow ls.Height = ui.TermHeight() - 2 ls.Width = ui.TermWidth() ls.Border = true ls.BorderLabel = fmt.Sprintf("%s %s", p.TicketId, p.ticketTrailAsString()) ls.Y = 0 p.statusBar.Create() p.commandBar.Create() p.Update() }
func (d *Dash) drawView() { st := d.sum() d.view = termui.NewList() d.view.ItemFgColor = termui.ColorYellow d.view.BorderLabel = "overview" d.view.Height = d.height d.view.Width = d.width d.view.X = 40 d.view.Y = 0 d.view.Items = st.List() }
func (p *StatusBar) Create() { ls := ui.NewList() p.uiList = ls ls.ItemFgColor = ui.ColorWhite ls.ItemBgColor = ui.ColorRed ls.Bg = ui.ColorRed ls.Border = false ls.Height = 1 ls.Width = ui.TermWidth() ls.X = 0 ls.Y = ui.TermHeight() - 2 p.Update() }
func (p *BaseListPage) Create() { ui.Clear() ls := ui.NewList() p.uiList = ls p.cachedResults = make([]string, 0) p.displayLines = make([]string, len(p.cachedResults)) ls.ItemFgColor = ui.ColorYellow ls.BorderLabel = "Updating, please wait" ls.Height = ui.TermHeight() ls.Width = ui.TermWidth() ls.Y = 0 p.Update() }
// 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 (p *BaseInputBox) Create() { ls := ui.NewList() var strs []string p.uiList = ls ls.Items = strs ls.ItemFgColor = ui.ColorGreen ls.BorderFg = ui.ColorRed ls.Height = 1 ls.Width = 30 ls.Overflow = "wrap" ls.X = ui.TermWidth()/2 - ls.Width/2 ls.Y = ui.TermHeight()/2 - ls.Height/2 p.Update() }
func (p *PasswordInputBox) Create() { ls := ui.NewList() p.uiList = ls var strs []string ls.Items = strs ls.ItemFgColor = ui.ColorGreen ls.BorderLabel = "Enter Password:" ls.BorderFg = ui.ColorRed ls.Height = 3 ls.Width = 30 ls.X = ui.TermWidth()/2 - ls.Width/2 ls.Y = ui.TermHeight()/2 - ls.Height/2 p.Update() }
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 }
func (ui *tatui) initMessage() { strs := []string{"[Loading...](fg-black,bg-white)"} ls := termui.NewList() ls.BorderTop, ls.BorderLeft, ls.BorderRight, ls.BorderBottom = true, false, false, false ls.Items = strs ls.ItemFgColor = termui.ColorWhite ls.BorderLabel = "Message" ls.Overflow = "wrap" ls.Width = 25 ls.Y = 0 ls.Height = termui.TermHeight() - uiHeightTop - uiHeightSend _, ok := ui.uilists[uiMessages][ui.selectedPaneMessages] if ok && ui.uilists[uiMessages][ui.selectedPaneMessages].position >= 0 && ui.uilists[uiMessages][ui.selectedPaneMessages].position < len(ui.currentListMessages[ui.selectedPaneMessages]) { ui.currentMessage = ui.currentListMessages[ui.selectedPaneMessages][ui.uilists[uiMessages][ui.selectedPaneMessages].position] ui.uilists[uiMessage][0] = &uilist{uiType: uiMessage, list: ls, position: 0, page: 0, update: ui.updateMessage} } }
func (p *SortOrderPage) Create() { ls := ui.NewList() p.uiList = ls p.selectedLine = 0 p.firstDisplayLine = 0 if len(p.cachedResults) == 0 { p.cachedResults = getSorts() p.displayLines = make([]string, len(p.cachedResults)) } ls.ItemFgColor = ui.ColorGreen ls.BorderLabel = "Sort By..." ls.BorderFg = ui.ColorRed ls.Height = 10 ls.Width = 50 ls.X = ui.TermWidth()/2 - ls.Width/2 ls.Y = ui.TermHeight()/2 - ls.Height/2 p.Update() }
func (ui *tatui) initMessages() { for k := range ui.currentFilterMessages[ui.currentTopic.Topic] { strs := []string{"[Loading...](fg-black,bg-white)"} ls := termui.NewList() ls.BorderTop, ls.BorderLeft, ls.BorderRight, ls.BorderBottom = true, false, false, false ls.Items = strs ls.ItemFgColor = termui.ColorWhite ls.BorderLabel = "Messages" ls.Width = 25 ls.Y = 0 ls.Height = (termui.TermHeight() - uiHeightTop - uiHeightSend) / len(ui.currentFilterMessages[ui.currentTopic.Topic]) if _, ok := ui.uilists[uiMessages]; !ok { ui.uilists[uiMessages] = make(map[int]*uilist) } ui.uilists[uiMessages][k] = &uilist{uiType: uiMessages, list: ls, position: 0, page: 0, update: ui.updateMessages} } ui.applyLabelOnMsgPanes() ui.render() }
func markdownList() *termui.List { strs := []string{ "[0] github.com/gizak/termui", "[1] 笀耔 [澉 灊灅甗](RED) 郔镺 笀耔 澉 [灊灅甗](yellow) 郔镺", "[2] こんにちは世界", "[3] keyboard.go", "[4] [output](RED).go", "[5] random_out.go", "[6] [dashboard](BOLD).go", "[7] nsf/termbox-go", "[8] OVERFLOW!!!!!!![!!!!!!!!!!!!](red,bold)!!!"} list := termui.NewList() list.Items = strs list.Height = 15 list.Width = 26 list.RendererFactory = termui.MarkdownTextRendererFactory{} return list }
func draw() { display = ui.NewPar("") display.Height = 1 display.Border = false prompt = ui.NewPar(promptMsg) prompt.Height = 1 prompt.Border = false help := ui.NewPar(`:c, :h for profiles; :f to filter; ↓ and ↑ to paginate`) help.Height = 1 help.Border = false help.TextBgColor = ui.ColorBlue help.Bg = ui.ColorBlue help.TextFgColor = ui.ColorWhite gs := ui.Sparkline{} gs.Title = "goroutines" gs.Height = 4 gs.LineColor = ui.ColorCyan ts := ui.Sparkline{} ts.Title = "threads" ts.Height = 4 ts.LineColor = ui.ColorCyan sp = ui.NewSparklines(gs, ts) sp.Height = 10 sp.Border = false ls = ui.NewList() ls.Border = false ui.Body.AddRows( ui.NewRow(ui.NewCol(4, 0, prompt), ui.NewCol(8, 0, help)), ui.NewRow(ui.NewCol(12, 0, sp)), ui.NewRow(ui.NewCol(12, 0, display)), ui.NewRow(ui.NewCol(12, 0, ls)), ) }
func escapeList() *termui.List { strs := []string{ "[0] github.com/gizak/termui", "[1] 笀耔 \033[31m澉 灊灅甗 \033[0m郔镺 笀耔 澉 \033[33m灊灅甗 郔镺", "[2] こんにちは世界", "[3] keyboard.go", "[4] \033[31moutput\033[0m.go", "[5] random_out.go", "[6] \033[1mdashboard\033[0m.go", "[7] nsf/termbox-go", "[8] OVERFLOW!!!!!!!\033[31;1m!!!!!!!!!!!!\033[0m!!!", } list := termui.NewList() list.RendererFactory = termui.EscapeCodeRendererFactory{} list.Items = strs list.Height = 15 list.Width = 26 list.Y = 15 return list }
func (ui *tatui) initTopics() { strs := []string{"[Loading...](fg-black,bg-white)"} ls := termui.NewList() ls.BorderTop, ls.BorderLeft, ls.BorderRight, ls.BorderBottom = true, false, false, false ls.Items = strs ls.ItemFgColor = termui.ColorWhite if ui.onlyFavorites == "true" { ls.BorderLabel = " ★ Favorites Topics ★ " } else if ui.onlyUnread { ls.BorderLabel = " ✉ Unread Topics ✉ " } else { ls.BorderLabel = " All Topics " } ls.Width = 25 ls.Y = 0 ls.Height = termui.TermHeight() - uiHeightTop - uiHeightSend m := make(map[int]*uilist) m[0] = &uilist{uiType: uiTopics, list: ls, position: 0, page: 0, update: ui.updateTopics} ui.uilists[uiTopics] = m }
func (p *HelpPage) Create() { ui.Clear() ls := ui.NewList() p.uiList = ls if p.statusBar == nil { p.statusBar = new(StatusBar) } if p.commandBar == nil { p.commandBar = commandBar } if len(p.cachedResults) == 0 { p.cachedResults = HelpTextAsStrings(nil, "jira_ui_help") } p.displayLines = make([]string, len(p.cachedResults)) ls.ItemFgColor = ui.ColorYellow ls.BorderLabel = "Help" ls.Height = ui.TermHeight() - 2 ls.Width = ui.TermWidth() ls.Y = 0 p.statusBar.Create() p.commandBar.Create() p.Update() }
func (p *QueryPage) Create() { log.Debugf("QueryPage.Create(): self: %s (%p)", p.Id(), p) log.Debugf("QueryPage.Create(): currentPage: %s (%p)", currentPage.Id(), currentPage) ui.Clear() ls := ui.NewList() p.uiList = ls if p.statusBar == nil { p.statusBar = new(StatusBar) } if p.commandBar == nil { p.commandBar = commandBar } p.cachedResults = getQueries() p.displayLines = make([]string, len(p.cachedResults)) ls.ItemFgColor = ui.ColorYellow ls.BorderLabel = "Queries" ls.Height = ui.TermHeight() - 2 ls.Width = ui.TermWidth() ls.Y = 0 p.statusBar.Create() p.commandBar.Create() p.Update() }
func main() { //set log file logFileName := "btc.log" logFile, logErr := os.OpenFile(logFileName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666) if logErr != nil { fmt.Println("Fail to find", *logFile, "cServer start Failed") return } log.SetOutput(logFile) log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) log.Printf("cpu num %d", runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU()) if err := ui.Init(); err != nil { log.Printf("ui init err : %s", err) return } defer ui.Close() par = ui.NewPar("Last Price") par.Height = 3 par.TextFgColor = ui.ColorWhite par.BorderLabel = "Last Price" infoPar = ui.NewPar("Price Info") infoPar.Height = 3 infoPar.TextFgColor = ui.ColorWhite infoPar.BorderLabel = "Price Info" currentTime := time.Now().Format("2006-01-02 15:04:05") timePar := ui.NewPar(currentTime) timePar.Height = 3 timePar.TextFgColor = ui.ColorYellow timePar.BorderLabel = "Current Time" strItems := []string{} delegateList = ui.NewList() delegateList.Items = strItems delegateList.ItemFgColor = ui.ColorYellow delegateList.BorderLabel = "Delegate List" delegateList.Height = 23 dealList = ui.NewList() dealList.Items = strItems dealList.ItemFgColor = ui.ColorYellow dealList.Height = 23 dealList.BorderLabel = "Deal List" ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, par), ui.NewCol(6, 0, timePar))) ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 0, infoPar))) ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, delegateList), ui.NewCol(6, 0, dealList))) ui.Body.Align() ui.Render(ui.Body) // websocket connect log.Printf("connecting to %s", url) c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatal("dial:", err) } defer c.Close() // message done chan done := make(chan struct{}) exit := func() { err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { log.Printf("write close: %s", err) } else { select { case <-done: case <-time.After(time.Second): } c.Close() } ui.StopLoop() } ui.Handle("/sys/kbd/q", func(ui.Event) { exit() }) ui.Handle("/sys/kbd/p", func(ui.Event) { if !uiPaused { uiPaused = true } else { uiPaused = false } }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() ui.Body.Align() ui.Render(ui.Body) }) ui.Handle("/timer/1s", func(e ui.Event) { currentTime := time.Now().Format("2006-01-02 15:04:05") timePar.Text = currentTime }) go func() { for { //or use message if !uiPaused { time.Sleep(time.Millisecond * 50) ui.Render(ui.Body) } else { time.Sleep(time.Millisecond * 200) } } }() //----------------------- stocket message -------------- msgChan := make(chan []byte) //获取消息 go func() { defer c.Close() defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Printf("read err: %s", err) return } msgChan <- message } }() //订阅消息 sendSubChannel(c) //heart check via pingChan go func() { defer close(pingChan) for { if c.WriteMessage(websocket.TextMessage, []byte("{\"event\": \"ping\"}")); err != nil { log.Printf("send ping message err: %s", err) break } log.Println("send ping message") select { case <-pingChan: log.Println("server is alive") //收到数据 1s 后继续发送心跳 time.Sleep(time.Second) case <-time.After(time.Second * 1): //超时 重新连接 socket reConnectTimes := 0 for { if reConnectTimes > 5 { log.Fatal("websocket connect failed") break } _c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Println("re-connect websocket faild dial:", err) log.Println("after 3s retry connect websocket") reConnectTimes++ time.Sleep(time.Second * 3) } else { log.Println("re-connect websocket success") c = _c sendSubChannel(c) break } } } } }() //开启10个worker 处理消息 for i := 0; i < 10; i++ { go processMessage(msgChan) } //开始阻塞 循环terminal ui ui.Loop() }
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) } } }