Example #1
0
func startUI(update chan *network.RoomUpdate, activity chan string, cmd chan<- network.GameMsg, character string) {
	err := ui.Init()
	if err != nil {
		panic(err)
	}
	defer ui.Close()

	//ui.UseTheme("helloworld")
	height := ui.TermHeight()

	descPar := ui.NewPar("")
	descPar.Height = ((height - 3) / 2) - 5
	//descPar.Width = 50
	descPar.TextFgColor = ui.ColorWhite
	descPar.Border.Label = ""
	descPar.Border.FgColor = ui.ColorCyan

	exitPar := ui.NewPar("")
	exitPar.Height = 5
	exitPar.TextFgColor = ui.ColorWhite
	exitPar.Border.Label = "Exits"
	exitPar.Border.FgColor = ui.ColorCyan

	entityList := ui.NewList()
	entityList.ItemFgColor = ui.ColorYellow
	entityList.Border.Label = "Entities"
	entityList.Height = (height - 3) / 2
	entityList.Y = 0

	activityList := ui.NewList()
	activityList.ItemFgColor = ui.ColorWhite
	activityList.Border.Label = "Activity"
	activityList.Height = (height - 3) / 2
	activityList.Y = 0

	cmdPar := ui.NewPar("")
	cmdPar.Height = 3
	//cmdPar.Width = 50
	cmdPar.TextFgColor = ui.ColorWhite
	cmdPar.Border.Label = "Enter Command"
	cmdPar.Border.FgColor = ui.ColorCyan

	// build
	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(4, 0, entityList),
			ui.NewCol(8, 0, descPar, exitPar)),
		ui.NewRow(
			ui.NewCol(12, 0, activityList)),
		ui.NewRow(
			ui.NewCol(12, 0, cmdPar)))

	ui.Body.Align()

	ui.Render(ui.Body)

	evt := ui.EventCh()
	redraw := make(chan bool)
	done := make(chan bool)

	clearActivity := false
	var prevCmds []string
	prevCmd := 0

	for {
		select {
		// Get an event from the keyboard, mouse, screen resize, etc
		case e := <-evt:
			switch e.Type {
			case ui.EventKey:
				switch e.Ch {
				case 0: // e.Key is valid if e.Ch is 0
					switch e.Key {
					case ui.KeyBackspace2:
						fallthrough
					case ui.KeyBackspace:
						len := len(cmdPar.Text)
						if len > 0 {
							cmdPar.Text = cmdPar.Text[:len-1]
							go func() { redraw <- true }()
						}
					case ui.KeySpace:
						cmdPar.Text += " "
						go func() { redraw <- true }()
					case ui.KeyEsc:
						fallthrough
					case ui.KeyCtrlC:
						return
					case ui.KeyEnter:
						msg, err := parseCmd(cmdPar.Text)
						if err != nil {
							//TODO: alert the user somehow
							break
						}
						// Set a flag so we know to clear the activity list on the next update
						if msg.CmdReq.Cmd == "go" {
							// go command will produce a room update or an error msg
							// both with set this back to false, the room update after clearing the list
							clearActivity = true
						}
						cmd <- msg
						prevCmds = append(prevCmds, cmdPar.Text)
						prevCmd = len(prevCmds)
						cmdPar.Text = ""
						go func() { redraw <- true }()
					case ui.KeyArrowUp:
						if prevCmd > 0 {
							prevCmd--
							cmdPar.Text = prevCmds[prevCmd]
							go func() { redraw <- true }()
						}
					case ui.KeyArrowDown:
						if prevCmd < (len(prevCmds) - 1) {
							prevCmd++
							cmdPar.Text = prevCmds[prevCmd]
							go func() { redraw <- true }()
						} else if prevCmd == (len(prevCmds) - 1) {
							prevCmd++
							cmdPar.Text = ""
							go func() { redraw <- true }()
						}
						//default:
						//  cmdPar.Text += strconv.Itoa(int(e.Key))
						//  go func() { redraw <- true }()
					}
				default:
					cmdPar.Text += string(e.Ch)
					go func() { redraw <- true }()
				}
			case ui.EventResize:
				height := ui.TermHeight()
				descPar.Height = ((height - 3) / 2) - 5
				entityList.Height = (height - 3) / 2
				activityList.Height = (height - 3) / 2

				if len(activityList.Items) > (activityList.Height - 2) {
					//Slice the top off
					activityList.Items = activityList.Items[len(activityList.Items)-(activityList.Height-2) : len(activityList.Items)]
				}

				ui.Body.Width = ui.TermWidth()
				ui.Body.Align()
				go func() { redraw <- true }()
			}
		// We got a room update from the server
		case u := <-update:
			var entities []string
			for _, pc := range u.Pcs {
				entities = append(entities, pc+" (PC)")
			}
			entities = append(entities, u.Npcs...)
			entityList.Items = entities

			if clearActivity {
				activityList.Items = nil
				clearActivity = false
			}
			if u.Message != "" {
				addActivity(activityList, u.Message)
			}

			exitStr := ""
			if u.North {
				exitStr += "       ^ North\n"
			} else {
				exitStr += "              \n"
			}
			if u.West {
				exitStr += "West < "
			} else {
				exitStr += "       "
			}
			if u.East {
				exitStr += "  > East \n"
			} else {
				exitStr += "         \n"
			}
			if u.South {
				exitStr += "       v South"
			}

			exitPar.Text = exitStr
			descPar.Text = u.Desc
			descPar.Border.Label = u.Name

			go func() { redraw <- true }()

		// Local write request to activity dialog
		case a := <-activity:
			clearActivity = false
			addActivity(activityList, a)
			go func() { redraw <- true }()
		// Request to redraw
		case <-redraw:
			ui.Render(ui.Body)
		// We are done
		case <-done:
			return
		}
	}
}
Example #2
0
func createUi(state *render.RenderState) {
	err := ui.Init()
	if err != nil {
		panic(err)
	}
	defer ui.Close()
	ui.UseTheme("helloworld")

	bc := ui.NewBarChart()
	data := []int{}
	bclabels := []string{}
	bc.Border.Label = "SumoCLI"
	bc.Data = data
	//bc.Width = 26
	bc.Height = ui.TermHeight() - 10
	bc.DataLabels = bclabels
	bc.TextColor = ui.ColorGreen
	bc.BarColor = ui.ColorRed
	bc.NumColor = ui.ColorYellow

	// build layout
	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(12, 0, bc)))

	// calculate layout
	ui.Body.Align()

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

	update := func() error {
		//fmt.Println("updating")
		bars := render.Columns(*state.Messages)
		columns := render.ColumnNames(bars)
		query, ok := (*state.Meta)["_queryString"]
		if ok && query.(string) != bc.Border.Label {
			bc.Border.Label = query.(string)
		}

		dataCol := render.NumericColumn(columns)
		data := []int{}
		labels := []string{}
		extractor := render.LabelExtractor(columns)
		for _, msg := range *state.Messages {
			labels = append(labels, extractor(msg))
			// go is the worst
			floatVal, _ := strconv.ParseFloat(fmt.Sprint(msg[dataCol]), 64)
			rowData := int(floatVal)
			data = append(data, rowData)
		}
		bc.Data = data
		var numCols int
		if len(data) > 0 {
			numCols = len(data)
		} else {
			numCols = 1
		}

		newBarWidth := (ui.TermWidth() - 10) / numCols
		if int(newBarWidth) != int(bc.BarWidth) {
			bc.BarWidth = newBarWidth
		}

		if len(labels) != len(bc.DataLabels) {
			bc.DataLabels = labels
		}
		redraw <- true
		return nil
	}

	state.Flush = update
	evt := ui.EventCh()

	ui.Render(ui.Body)
	go update()

	for {
		select {
		case e := <-evt:
			if e.Type == ui.EventKey && e.Ch == 'q' {
				return
			}
			if e.Type == ui.EventResize {
				ui.Body.Width = ui.TermWidth()
				ui.Body.Align()
				go func() { redraw <- true }()
			}
		case <-done:
			return
		case <-redraw:
			ui.Render(ui.Body)
		}
	}
}