func updateMsgWin(msg ncursesMsg, msgWin *gc.Window, workerCountWin *gc.Window) {
	var row int
	if msg.msgType == MSG_TYPE_RESULT {
		row = 1
	} else if msg.msgType == MSG_TYPE_INFO {
		row = 2
	} else {
		row = 3
	}
	msgWin.MovePrint(row, 1, fmt.Sprintf("%-40s", msg.msgStr))
	msgWin.Box(0, 0)
	msgWin.NoutRefresh()
	if msg.currentCount >= 0 {
		workerCountWin.MovePrint(1, 1, fmt.Sprintf("%5d", msg.currentCount))
		workerCountWin.NoutRefresh()
	}
}
func windowRunloop(
	infoMsgsCh chan<- ncursesMsg,
	exitCh chan<- int,
	changeNumRequestersCh chan<- interface{},
	win *gc.Window,
) {
	threadCount := 0
	for {
		switch win.GetChar() {
		case 'q':
			exitCh <- 0
		case 's', '+', '=', gc.KEY_UP:
			threadCount++
			increaseThreads(infoMsgsCh, changeNumRequestersCh, win, threadCount)
		case '-', gc.KEY_DOWN:
			threadCount--
			decreaseThreads(infoMsgsCh, changeNumRequestersCh, win, threadCount)
		}
	}
}
func updateBarsWin(msg currentBars, barsWin *gc.Window, colors colorsDefined, scale int64) {

	whiteOnBlack := colors.whiteOnBlack
	redOnBlack := colors.redOnBlack
	greenOnBlack := colors.greenOnBlack
	barsWin.Erase()
	barsWin.Box(0, 0)
	edibleCopy := make([]int64, len(msg.cols))
	copy(edibleCopy, msg.cols)
	barsHeight, barsWidth := barsWin.MaxYX()
	startI := len(edibleCopy) - barsWidth
	if startI < 0 {
		startI = 0
	}
	currentSec := time.Now().Second()
	prevSec := currentSec - 1
	if prevSec < 0 {
		prevSec = 59
	}
	for row := 0; row < barsHeight-2; row++ {
		for col := range edibleCopy[startI:len(edibleCopy)] {
			if edibleCopy[col]/scale > 0 {
				turnOffColor := int16(0)
				currChar := "="
				// row is an int--32-bit, right?
				if shouldShowFail(msg.failCols[col], scale, row) {
					barsWin.ColorOff(whiteOnBlack)
					barsWin.ColorOn(redOnBlack)
					currChar = "x"
					turnOffColor = redOnBlack

				} else if col == currentSec ||
					col == currentSec-1 {
					// current second is still in progress, so make the previous second
					// green too--not precisely correct, but close enough here
					barsWin.ColorOff(whiteOnBlack)
					barsWin.ColorOn(greenOnBlack)
					turnOffColor = greenOnBlack
				}

				barsWin.MovePrint(barsHeight-2-row, col+1, currChar)

				if turnOffColor != 0 {
					barsWin.ColorOff(turnOffColor)
					barsWin.ColorOn(whiteOnBlack)
				}

				edibleCopy[col] = edibleCopy[col] - scale
			}
		}
	}
	barsWin.NoutRefresh()
}
func drawDisplay(
	stdscr *gc.Window,
) (
	msgWin *gc.Window,
	workerCountWin *gc.Window,
	durWin *gc.Window,
	reqSecWin *gc.Window,
	barsWin *gc.Window,
	scaleWin *gc.Window,
	maxWin *gc.Window,
) {

	// print startup message
	stdscr.Print("Press 'q' to exit")
	stdscr.NoutRefresh()

	// Create message window
	// and enable the use of the
	// keypad on it so the arrow keys are available
	msgHeight, msgWidth := 5, 40
	msgY, msgX := 1, 0
	msgWin = createWindow(msgHeight, msgWidth, msgY, msgX)
	msgWin.Keypad(true)
	msgWin.Box(0, 0)
	msgWin.NoutRefresh()

	// Create the counter window, showing how many goroutines are active
	ctrHeight, ctrWidth := 3, 7
	ctrY := 2
	ctrX := msgWidth + 1
	stdscr.MovePrint(1, ctrX+1, "thrds")
	stdscr.NoutRefresh()
	workerCountWin = createWindow(ctrHeight, ctrWidth, ctrY, ctrX)
	workerCountWin.Box(0, 0)
	workerCountWin.NoutRefresh()

	// Create the avg duration window, showing 5 second moving average
	durHeight, durWidth := 4, 14
	durY := 2
	durX := ctrX + ctrWidth + 1
	stdscr.MovePrint(1, durX+1, "duration ms")
	stdscr.NoutRefresh()
	durWin = createWindow(durHeight, durWidth, durY, durX)
	durWin.Box(0, 0)
	durWin.NoutRefresh()

	// Create the requests/sec window,
	reqSecHeight, reqSecWidth := 3, 16
	reqSecY := 2
	reqSecX := durX + durWidth + 1
	stdscr.MovePrint(1, reqSecX+1, "req/s 1/5/60")
	stdscr.NoutRefresh()
	reqSecWin = createWindow(reqSecHeight, reqSecWidth, reqSecY, reqSecX)
	reqSecWin.Box(0, 0)
	reqSecWin.NoutRefresh()

	// Create the bars window, showing the moving display of bars
	secondsPerMinute := 60
	barsWidth := secondsPerMinute + 3 // we wrap after a minute
	barsHeight := 25                  // need to size this dynamically, TBD
	barsY := msgHeight + 1
	barsX := 9 // leave space for scale window
	barsWin = createWindow(barsHeight, barsWidth, barsY, barsX)
	barsWin.Box(0, 0)
	barsWin.NoutRefresh()

	// Max window, showing the max seen over the last 60 seconds
	maxWidth := 7
	maxHeight := 3
	maxY := barsY + barsHeight - 8
	maxX := 1
	stdscr.MovePrint(maxY, 1, "max:")
	stdscr.NoutRefresh()
	maxY += 1
	maxWin = createWindow(maxHeight, maxWidth, maxY, maxX)
	maxWin.Box(0, 0)
	maxWin.NoutRefresh()

	// Scale window, showing our current scaling factor for the bars display
	scaleWidth := 7
	scaleHeight := 3
	scaleY := barsY + barsHeight - 4
	scaleX := 1
	stdscr.MovePrint(scaleY, 1, "scale:")
	stdscr.NoutRefresh()
	scaleY += 1
	scaleWin = createWindow(scaleHeight, scaleWidth, scaleY, scaleX)
	scaleWin.Box(0, 0)
	scaleWin.MovePrint(1, 1, fmt.Sprintf("%5s", "1"))
	scaleWin.NoutRefresh()

	// Update will flush only the characters which have changed between the
	// physical screen and the virtual screen, minimizing the number of
	// characters which must be sent
	gc.Update()

	return
}
Example #5
0
func (cw *chatWin) handleInput(win *goncurses.Window) (line string) {
	k := win.GetChar()
	if k == 0 {
		return ""
	}

	// some systems send a DEL ASCII character instead of KEY_BACKSPACE
	// account for both just in case
	if k == 127 {
		k = goncurses.KEY_BACKSPACE
	}

	switch k {
	case goncurses.KEY_TAB: // tab
	// case goncurses.KEY_RETURN: // enter key vs. KEY_ENTER
	case goncurses.KEY_DOWN: // down arrow key
	case goncurses.KEY_UP: // up arrow key
	case goncurses.KEY_LEFT: // left arrow key
	case goncurses.KEY_RIGHT: // right arrow key
	case goncurses.KEY_HOME: // home key
	case goncurses.KEY_BACKSPACE: // backpace
		if len(cw.line) > 0 {
			cw.line = cw.line[:len(cw.line)-1]
		}
		y, x := win.CursorYX()
		// TODO: handle this more elegantly (e.g. tell ncurses not to print backspaces)
		// we have to do this three times because ncurses inserts two characters for backspace
		// this is likely wrong in some cases
		for i := 0; i < 3; i++ {
			y, x = cw.moveLeft(y, x)
			win.MoveDelChar(y, x)
		}
		win.Refresh()
	case goncurses.KEY_F1: // F1 key
	case goncurses.KEY_F2: // F2 key
	case goncurses.KEY_F3: // F3 key
	case goncurses.KEY_F4: // F4 key
	case goncurses.KEY_F5: // F5 key
	case goncurses.KEY_F6: // F6 key
	case goncurses.KEY_F7: // F7 key
	case goncurses.KEY_F8: // F8 key
	case goncurses.KEY_F9: // F9 key
	case goncurses.KEY_F10: // F10 key
	case goncurses.KEY_F11: // F11 key
	case goncurses.KEY_F12: // F12 key
	case goncurses.KEY_DL: // delete-line key
	case goncurses.KEY_IL: // insert-line key
	case goncurses.KEY_DC: // delete-character key
	case goncurses.KEY_IC: // insert-character key
	case goncurses.KEY_EIC: // sent by rmir or smir in insert mode
	case goncurses.KEY_CLEAR: // clear-screen or erase key3
	case goncurses.KEY_EOS: // clear-to-end-of-screen key
	case goncurses.KEY_EOL: // clear-to-end-of-line key
	case goncurses.KEY_SF: // scroll-forward key
	case goncurses.KEY_SR: // scroll-backward key
	case goncurses.KEY_PAGEDOWN: // page-down key (next-page)
	case goncurses.KEY_PAGEUP: // page-up key (prev-page)
	case goncurses.KEY_STAB: // set-tab key
	case goncurses.KEY_CTAB: // clear-tab key
	case goncurses.KEY_CATAB: // clear-all-tabs key
	case goncurses.KEY_RETURN: // enter key vs. KEY_ENTER
		fallthrough
	case goncurses.KEY_ENTER: // enter/send key
		line = cw.line
		cw.line = ""
		win.Erase()
		win.Print(PROMPT)
	case goncurses.KEY_PRINT: // print key
	case goncurses.KEY_LL: // lower-left key (home down)
	case goncurses.KEY_A1: // upper left of keypad
	case goncurses.KEY_A3: // upper right of keypad
	case goncurses.KEY_B2: // center of keypad
	case goncurses.KEY_C1: // lower left of keypad
	case goncurses.KEY_C3: // lower right of keypad
	case goncurses.KEY_BTAB: // back-tab key
	case goncurses.KEY_BEG: // begin key
	case goncurses.KEY_CANCEL: // cancel key
	case goncurses.KEY_CLOSE: // close key
	case goncurses.KEY_COMMAND: // command key
	case goncurses.KEY_COPY: // copy key
	case goncurses.KEY_CREATE: // create key
	case goncurses.KEY_END: // end key
	case goncurses.KEY_EXIT: // exit key
	case goncurses.KEY_FIND: // find key
	case goncurses.KEY_HELP: // help key
	case goncurses.KEY_MARK: // mark key
	case goncurses.KEY_MESSAGE: // message key
	case goncurses.KEY_MOVE: // move key
	case goncurses.KEY_NEXT: // next key
	case goncurses.KEY_OPEN: // open key
	case goncurses.KEY_OPTIONS: // options key
	case goncurses.KEY_PREVIOUS: // previous key
	case goncurses.KEY_REDO: // redo key
	case goncurses.KEY_REFERENCE: // reference key
	case goncurses.KEY_REFRESH: // refresh key
	case goncurses.KEY_REPLACE: // replace key
	case goncurses.KEY_RESTART: // restart key
	case goncurses.KEY_RESUME: // resume key
	case goncurses.KEY_SAVE: // save key
	case goncurses.KEY_SBEG: // shifted begin key
	case goncurses.KEY_SCANCEL: // shifted cancel key
	case goncurses.KEY_SCOMMAND: // shifted command key
	case goncurses.KEY_SCOPY: // shifted copy key
	case goncurses.KEY_SCREATE: // shifted create key
	case goncurses.KEY_SDC: // shifted delete-character key
	case goncurses.KEY_SDL: // shifted delete-line key
	case goncurses.KEY_SELECT: // select key
	case goncurses.KEY_SEND: // shifted end key
	case goncurses.KEY_SEOL: // shifted clear-to-end-of-line key
	case goncurses.KEY_SEXIT: // shifted exit key
	case goncurses.KEY_SFIND: // shifted find key
	case goncurses.KEY_SHELP: // shifted help key
	case goncurses.KEY_SHOME: // shifted home key
	case goncurses.KEY_SIC: // shifted insert-character key
	case goncurses.KEY_SLEFT: // shifted left-arrow key
	case goncurses.KEY_SMESSAGE: // shifted message key
	case goncurses.KEY_SMOVE: // shifted move key
	case goncurses.KEY_SNEXT: // shifted next key
	case goncurses.KEY_SOPTIONS: // shifted options key
	case goncurses.KEY_SPREVIOUS: // shifted previous key
	case goncurses.KEY_SPRINT: // shifted print key
	case goncurses.KEY_SREDO: // shifted redo key
	case goncurses.KEY_SREPLACE: // shifted replace key
	case goncurses.KEY_SRIGHT: // shifted right-arrow key
	case goncurses.KEY_SRSUME: // shifted resume key
	case goncurses.KEY_SSAVE: // shifted save key
	case goncurses.KEY_SSUSPEND: // shifted suspend key
	case goncurses.KEY_SUNDO: // shifted undo key
	case goncurses.KEY_SUSPEND: // suspend key
	case goncurses.KEY_UNDO: // undo key
	case goncurses.KEY_MOUSE: // any mouse event
	case goncurses.KEY_RESIZE: // Terminal resize event
	//case goncurses.KEY_EVENT: // We were interrupted by an event
	case goncurses.KEY_MAX:
	default:
		cw.line += goncurses.KeyString(k)
	}
	return
}