// contact Menu Window Navigation input handler func contactsWindowNavigation(contactsMenuWin *gc.Window, contactMenu *gc.Menu) int { var c gc.Char var rawInput gc.Key for { gc.Update() rawInput = contactsMenuWin.GetChar() c = gc.Char(rawInput) if rawInput == gc.KEY_TAB || rawInput == gc.KEY_RETURN { return 0 } else if c == gc.Char(27) { return 1 } else if c == gc.Char('j') || rawInput == gc.KEY_DOWN { contactMenu.Driver(gc.REQ_DOWN) changeContact(contactsMenuWin, contactMenu) } else if c == gc.Char('k') || rawInput == gc.KEY_UP { contactMenu.Driver(gc.REQ_UP) changeContact(contactsMenuWin, contactMenu) } else if c == gc.Char('g') { contactMenu.Driver(gc.REQ_FIRST) changeContact(contactsMenuWin, contactMenu) } else if c == gc.Char('G') { contactMenu.Driver(gc.REQ_LAST) changeContact(contactsMenuWin, contactMenu) } else { continue } } }
// makes the menu inside the contacts window func makeContactsMenu(contacts []ts.Contact, contactsWin *gc.Window) ([]*gc.MenuItem, *gc.Menu, *gc.Window) { menu_items := make([]*gc.MenuItem, len(contacts)) var err error for i, val := range contacts { menu_items[i], err = gc.NewItem((val.Name), "") if err != nil { log.Fatal("Error making item for contact menu... ", err) } } contactMenu, err := gc.NewMenu(menu_items) if err != nil { log.Fatal("Error creating contact menu from menu_items... ", err) } contactsWinSizeY, contactsWinSizeX := contactsWin.MaxYX() contactsWin.Keypad(true) contactsMenuWin := contactsWin.Derived((contactsWinSizeY - 5), (contactsWinSizeX - 2), 3, 1) contactMenu.SetWindow(contactsMenuWin) contactMenu.Format(len(contacts), 1) contactMenu.Mark(" * ") title := "Contacts" contactsWin.MovePrint(1, (contactsWinSizeX/2)-(len(title)/2), title) contactsWin.HLine(2, 1, '-', contactsWinSizeX-2) contactsMenuWin.Keypad(true) contactsMenuWin.ScrollOk(true) return menu_items, contactMenu, contactsMenuWin }
func (h *Office) Draw(screen *gc.Window, y, x int) { f := h.Frames v, p := (*f)["Office"] if !p { frames := [][]string{[]string{ "<----->", "|XXXXX|", "| |", "|XXXXX|", "| |", "|XXXXX|", "[-----]"}, []string{ "<----->", "|XXXXX|", "| |", "| |", "| |", "|XXXXX|", "[-----]"}} (*f)["Office"] = frames v = frames } for ly, row := range v[h.Frame] { for lx, c := range row { screen.MoveAddChar(y+ly, x+lx, MapChar(c)) } } }
// Function to call to update the information in the information Window. func displayInfo(win *gc.Window, active, activeA int, userItems []*gc.MenuItem, userArticles map[string][]articleType) { win.Clear() win.MovePrint(1, 0, "Auteur : ", userItems[active].Name()) win.MovePrint(2, 0, "Date : ", userArticles[userItems[active].Name()][activeA].date) win.MovePrint(4, 0, userArticles[userItems[active].Name()][activeA].url) win.Refresh() }
// In addition to sending a message using janimo's library, also clears screen and resets buffer func sendMsg(inputWin *gc.Window, msgWin *gc.Window) { if len(inputBuffer) != 0 { msg := string(inputBuffer) to := currentContact err := ts.SendMessage(to, msg) if err != nil { gc.End() log.Fatal("SendMessage failed yo: ", err) } var b bytes.Buffer t := time.Now() if t.Hour() < 10 { b.WriteString("0") } b.WriteString(strconv.Itoa(t.Hour())) b.WriteString(":") if t.Minute() < 10 { b.WriteString("0") } b.WriteString(strconv.Itoa(t.Minute())) b.WriteString(": ") b.WriteString(msg) printToMsgWindow(b.String(), msgWin, true) b.Reset() insertMessage("You", currentContact, []byte(msg), nil) inputBuffer = []byte{} inputWin.Erase() } }
func (h *SmallHouse) Draw(screen *gc.Window, y, x int) { f := h.Frames var v [][]string var p bool if h.Dead { h.Frame = 0 v, p = (*f)["DeadSmallHouse"] if !p { frames := [][]string{[]string{ " ", "| ", "| |", "[---]"}, } (*f)["DeadSmallHouse"] = frames v = frames } } else { v, p = (*f)["SmallHouse"] if !p { frames := [][]string{[]string{ "<--->", "|X |", "| X|", "[---]"}, []string{ "<--->", "|X |", "| |", "[---]"}, []string{ "<--->", "| |", "| X|", "[---]"}, } (*f)["SmallHouse"] = frames v = frames } } for ly, row := range v[h.Frame] { for lx, c := range row { screen.MoveAddChar(y+ly, x+lx, MapChar(c)) } } }
//sets up the initial configuration of curses. Keeps code in main cleaner. func configCurses(stdscr *gc.Window) { if !gc.HasColors() { log.Fatal("Example requires a colour capable terminal") } if err := gc.StartColor(); err != nil { log.Fatal("Starting Colors failed:", err) } gc.Echo(false) if err := gc.InitPair(1, gc.C_RED, gc.C_BLACK); err != nil { log.Fatal("InitPair failed: ", err) } gc.InitPair(2, gc.C_BLUE, gc.C_BLACK) gc.InitPair(3, gc.C_GREEN, gc.C_BLACK) gc.InitPair(4, gc.C_YELLOW, gc.C_BLACK) gc.InitPair(5, gc.C_CYAN, gc.C_BLACK) gc.InitPair(6, gc.C_MAGENTA, gc.C_WHITE) gc.InitPair(7, gc.C_MAGENTA, gc.C_BLACK) //set background color to black stdscr.SetBackground(gc.Char(' ') | gc.ColorPair(0)) stdscr.Keypad(true) gc.Cursor(1) gc.CBreak(true) stdscr.Clear() }
func (h *BigFactory) Draw(screen *gc.Window, y, x int) { f := h.Frames v, p := (*f)["BigFactory"] if !p { frames := [][]string{[]string{ " ", "|| || ", "|| || <-> ", "|-------| |--", "| |", "| XXX XXX |", "[-----------]"}, []string{ "xx xx ", "|| || ", "|| || <-> ", "|-------| |--", "| |", "| XXX XXX |", "[-----------]"}, []string{ " ", "|| || ", "|| || | ", "|-------| |--", "| |", "| XXX |", "[-----------]"}} (*f)["BigFactory"] = frames v = frames } for ly, row := range v[h.Frame] { for lx, c := range row { screen.MoveAddChar(y+ly, x+lx, MapChar(c)) } } }
func PrintHiglighted(window *gc.Window, y int, x int, index int, selected int, text string, isActive bool) { if index == selected && isActive { window.AttrOn(gc.A_STANDOUT) } window.MovePrint(y, x, text) if index == selected && isActive { window.AttrOff(gc.A_STANDOUT) } }
func handleInput(stdscr *gc.Window, ship *Ship) bool { lines, cols := stdscr.MaxYX() y, x := ship.YX() k := stdscr.GetChar() switch byte(k) { case 0: break case 'a': x-- if x < 2 { x = 2 } case 'd': x++ if x > cols-3 { x = cols - 3 } case 's': y++ if y > lines-4 { y = lines - 4 } case 'w': y-- if y < 2 { y = 2 } case ' ': objects = append(objects, newBullet(y+1, x+4)) objects = append(objects, newBullet(y+3, x+4)) default: return false } ship.MoveWindow(y, x) return true }
func (a *Asteroid) Draw(w *gc.Window) { w.Overlay(a.Window) }
//creates the three Main big windows that make up the GUI func createMainWindows(stdscr *gc.Window) (*gc.Window, *gc.Window, *gc.Window, *gc.Window, *gc.Window) { rows, cols := stdscr.MaxYX() height, width := rows, int(float64(cols)*.2) var contactsWin, messageWinBorder, inputBorderWin, inputWin *gc.Window var err error contactsWin, err = gc.NewWindow(height, width, 0, 0) if err != nil { log.Fatal("Failed to create Contact Window:", err) } err = contactsWin.Border('|', '|', '-', '-', '+', '+', '+', '+') if err != nil { log.Fatal("Failed to create Border of Contact Window:", err) } // messageWinBorder is just the border. msgWin is the actual input window // doing this simplifies handling text a fair amount. // also the derived function never errors. Which seems dangerous begin_x := width + 1 height = int(float64(rows) * .8) width = int(float64(cols) * .8) messageWinBorder, err = gc.NewWindow(height, width, 0, begin_x) if err != nil { log.Fatal("Failed to create Message Border Window:", err) } err = messageWinBorder.Border('|', '|', '-', '-', '+', '+', '+', '+') if err != nil { log.Fatal("Failed to create Border of Message Window:", err) } msgWin, err := gc.NewWindow((height - 2), (width - 2), 1, (begin_x + 1)) if err != nil { log.Fatal("Failed to create the message Window:", err) } begin_y := int(float64(rows)*.8) + 1 height = int(float64(rows) * .2) inputBorderWin, err = gc.NewWindow(height, width, begin_y, begin_x) if err != nil { log.Fatal("Failed to create InputBorder Window:", err) } err = inputBorderWin.Border('|', '|', '-', '-', '+', '+', '+', '+') if err != nil { log.Fatal("Failed to create Border of the InputBorder Window:", err) } // inputBorderWin is just the border. InputWin is the actual input window // doing this simplifies handling text a fair amount. // also the derived function never errors. Which seems dangerous inputWin, err = gc.NewWindow((height - 2), (width - 2), (begin_y + 1), (begin_x + 1)) if err != nil { log.Fatal("Failed to create the inputWin Window:", err) } inputWin.ScrollOk(true) inputWin.Keypad(true) msgWin.ScrollOk(true) return contactsWin, messageWinBorder, msgWin, inputBorderWin, inputWin }
// handles keyboard input func inputHandler(inputWin *gc.Window, stdscr *gc.Window, contactsMenuWin *gc.Window, contactMenu *gc.Menu, msgWin *gc.Window) { var NLlocate = map[int]newLine{} var c gc.Char var rawInput gc.Key max_y, max_x := inputWin.MaxYX() for { rawInput = inputWin.GetChar() c = gc.Char(rawInput) // debugLog.Println(rawInput) // debugLog.Println(c) //Escape to Quit if c == gc.Char(27) { break } else if rawInput == gc.KEY_BACKSPACE || c == gc.Char(127) { //Delete Key y, x := inputWin.CursorYX() var del = byte('F') if x != 0 { inputWin.MoveDelChar(y, x-1) del = inputBuffer[placer] copy(inputBuffer[placer:len(inputBuffer)-1], inputBuffer[placer+1:]) inputBuffer = inputBuffer[0 : len(inputBuffer)-1] placer-- if del != byte('\n') && NLlocate[y+scroll]._cursorX > x { temp := newLine{NLlocate[y+scroll]._cursorX - 1, NLlocate[y+scroll]._placer - 1} NLlocate[y+scroll] = temp } //debugLog.Println(inputBuffer) } else if y != 0 { //when x==0 and y!=0 inputWin.Move(y-1, max_x-1) inputWin.MoveDelChar(y-1, max_x-1) del = inputBuffer[placer] copy(inputBuffer[placer:len(inputBuffer)-1], inputBuffer[placer+1:]) inputBuffer = inputBuffer[0 : len(inputBuffer)-1] //debugLog.Println(inputBuffer) placer-- } if del == byte('\n') { inputWin.Erase() inputWin.Print(string(inputBuffer)) inputWin.Move(y-1, NLlocate[y-1+scroll]._cursorX) temp, check := NLlocate[y+scroll] var temp_cursor = temp._cursorX var temp_placer = temp._placer if check && NLlocate[y-1+scroll]._cursorX+temp_cursor >= max_x { _newLine := newLine{NLlocate[y-1+scroll]._cursorX + temp_cursor - max_x, NLlocate[y+scroll]._placer - 1} NLlocate[y+scroll] = _newLine delete(NLlocate, y-1) } else if check { // check if there are any '\n' this line var largest = -1 // if yes, select all '\n' and move for i := range NLlocate { // placer by 1 and adjust cursor if i >= y+scroll { // accordingly if next_nl, ok := NLlocate[i+1]; ok { new_nl := newLine{next_nl._cursorX, next_nl._placer - 1} NLlocate[i] = new_nl } } if i > largest { largest = i } } delete(NLlocate, largest) // delete last map entry _newLine := newLine{NLlocate[y-1+scroll]._cursorX + temp_cursor, NLlocate[y-1+scroll]._placer + temp_placer - 1} NLlocate[y-1+scroll] = _newLine } else { delete(NLlocate, y-1+scroll) } } } else if c == gc.KEY_PAGEDOWN { //debugLog.Println("HIT DOWN") msgWin.Scroll(-10) msgWin.Refresh() inputWin.Refresh() } else if c == gc.KEY_PAGEUP { //debugLog.Println("HIT UP") msgWin.Scroll(10) msgWin.Refresh() inputWin.Refresh() } else if c == gc.KEY_LEFT { y, x := inputWin.CursorYX() if x != 0 { inputWin.Move(y, x-1) placer-- } else if y != 0 { inputWin.Move(y-1, max_x-1) placer-- } if len(inputBuffer) > 0 && inputBuffer[placer+1] == byte('\n') { inputWin.Move(y-1, NLlocate[y-1+scroll]._cursorX) } } else if c == gc.KEY_RIGHT { y, x := inputWin.CursorYX() placer++ if inputBuffer == nil || placer == len(inputBuffer) { inputBuffer = append(inputBuffer, byte(' ')) } if inputBuffer[placer] == byte('\n') || x >= max_x-1 { inputWin.Move(y+1, 0) } else { inputWin.Move(y, x+1) } } else if c == gc.KEY_UP { y, x := inputWin.CursorYX() if y == 0 && placer == 0 { continue } else if y == 0 && scroll > 0 { inputWin.Move(0, x) inputWin.Scroll(-1) scroll -= 1 if NLlocate[y-2+scroll]._placer != 0 { inputWin.Erase() inputWin.Print(string(inputBuffer[(NLlocate[y-2+scroll]._placer):])) } else if placer-max_x-x > 0 { inputWin.Erase() inputWin.Print(string(inputBuffer[(placer - x - max_x):])) } else { inputWin.Erase() inputWin.Print(string(inputBuffer)) } } if y != 0 { inputWin.Move(y-1, x) placer -= max_x if placer < 0 { placer = 0 } } if NLlocate[y-1+scroll]._placer != 0 { if NLlocate[y-1+scroll]._cursorX < x { placer = NLlocate[y-1+scroll]._placer inputWin.Move(y-1, NLlocate[y-1+scroll]._cursorX) } else { placer = NLlocate[y-1+scroll]._placer - (NLlocate[y-1+scroll]._cursorX - x) } } } else if c == gc.KEY_DOWN { y, x := inputWin.CursorYX() if y != max_y { inputWin.Move(y+1, x) if NLlocate[y+scroll]._placer == 0 { placer += max_x } else { placer = NLlocate[y+scroll]._placer + x + 1 } } else if y == max_y { inputWin.Scroll(1) scroll += 1 inputWin.Move(max_y-1, x) if NLlocate[y+scroll]._placer == 0 { placer += max_x } else { placer = NLlocate[y+scroll]._placer + x + 1 } } if placer >= len(inputBuffer) { for i := len(inputBuffer); i < placer+1; i++ { inputBuffer = append(inputBuffer, byte(' ')) } } } else if rawInput == gc.KEY_TAB { y, x := inputWin.CursorYX() gc.Cursor(0) escapeHandler := contactsWindowNavigation(contactsMenuWin, contactMenu) if escapeHandler == 1 { return } gc.Cursor(1) inputWin.Move(y, x) } else if rawInput == gc.KEY_RETURN { placer = -1 for i := range NLlocate { delete(NLlocate, i) } sendMsg(inputWin, globalMsgWin) } else if rawInput == gc.KEY_SRIGHT { y, x := inputWin.CursorYX() if inputBuffer == nil || placer == len(inputBuffer)-1 { if y == max_y-1 { scroll++ } inputWin.Print("\n") temp := newLine{x, placer} NLlocate[y+scroll] = temp placer++ inputBuffer = append(inputBuffer, byte('\n')) } else { inputWin.Erase() inputBuffer = append(inputBuffer, byte('\n')) copy(inputBuffer[placer+1:], inputBuffer[placer:]) inputBuffer[placer+1] = byte('\n') inputWin.Print(string(inputBuffer)) temp := newLine{x, placer} placer++ nextholder, check := NLlocate[y+1+scroll] if check { for i := range NLlocate { if i == y+scroll { _newLine := newLine{NLlocate[i]._cursorX + 1 - x, NLlocate[i]._placer + 1} nextholder := NLlocate[i+1] _ = nextholder NLlocate[i+1] = _newLine } else if i > y { temp := NLlocate[i+1] NLlocate[i+1] = nextholder nextholder = temp } } } NLlocate[y+scroll] = temp inputWin.Move(y+1, 0) } } else if rawInput == gc.KEY_SLEFT { } else { y, x := inputWin.CursorYX() if inputBuffer == nil || placer == len(inputBuffer)-1 { inputWin.Print(string(c)) inputBuffer = append(inputBuffer, byte(c)) } else { inputWin.Erase() inputBuffer = append(inputBuffer, byte(c)) copy(inputBuffer[placer+1:], inputBuffer[placer:]) inputBuffer[placer+1] = byte(c) inputWin.Print(string(inputBuffer)) for i := range NLlocate { if i > y+scroll { tempLine := newLine{NLlocate[i]._cursorX, NLlocate[i]._placer + 1} NLlocate[i] = tempLine } } if NLlocate[y+scroll]._cursorX >= x { if NLlocate[y+scroll]._cursorX == max_x { copy(inputBuffer[NLlocate[y+scroll]._placer:len(inputBuffer)-1], inputBuffer[NLlocate[y+scroll]._placer+1:]) inputBuffer = inputBuffer[0 : len(inputBuffer)-1] delete(NLlocate, y) } else { temp := newLine{NLlocate[y+scroll]._cursorX + 1, NLlocate[y+scroll]._placer + 1} NLlocate[y+scroll] = temp } } } placer++ inputWin.Move(y, x+1) } } }
// Hello dialog. So the nooblets know the controls func doHello(stdscr *gc.Window) { stdscr.Refresh() y, x := stdscr.MaxYX() center_x := int(x / 2) center_y := int(y / 2) stdscr.MovePrintln(center_y-6, center_x-4, "Controls:") stdscr.MovePrintln(center_y-5, center_x-12, "Escape: Exit the program.") stdscr.MovePrintln(center_y-4, center_x-30, "Tab: Switch between the input window and the Message window.") stdscr.MovePrintln(center_y-3, center_x-11, "Return: Send a message") stdscr.MovePrintln(center_y-2, center_x-44, `Shift + Right Arrow: put in a new line '\n' character (like shift+return in facebook chat)`) stdscr.MovePrintln(center_y-1, center_x-30, "Page-Up / Page-Down: Scroll up in the message history window") }
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 }
// Prints messages to the message window func printToMsgWindow(msg string, msgWin *gc.Window, amSending bool) { lines := int(len(msg)/(msgWinSize_x-1)) + 1 if amSending == true { msgWin.Scroll(lines) msgWin.ColorOn(2) msgWin.MovePrint((msgWinSize_y - lines), 0, msg) } else { if strings.ContainsAny(msg, "\n") { printByLineBreakdown := strings.Split(msg, "\n") for i, val := range printByLineBreakdown { if i != 0 { msgWin.Scroll(1) } lines2 := int(len(val)/(msgWinSize_x-1)) + 1 if lines2 > 1 { msgWin.Scroll(lines2) msgWin.ColorOn(1) msgWin.MovePrint((msgWinSize_y - lines2), int(msgWinSize_x*3/4), val) } else { msgWin.Scroll(lines2) msgWin.ColorOn(1) space_buf := (msgWinSize_x) - len(val) msgWin.MovePrint((msgWinSize_y - lines), space_buf, val) msgWin.Scroll(-1) } } } else { if lines > 1 { msgWin.Scroll(lines) msgWin.ColorOn(1) msgWin.MovePrint((msgWinSize_y - lines), int(msgWinSize_x*3/4), msg) } else { msgWin.Scroll(lines) msgWin.ColorOn(1) space_buf := (msgWinSize_x) - len(msg) msgWin.MovePrint((msgWinSize_y - lines), space_buf, msg) msgWin.Scroll(-1) } } } msgWin.Refresh() globalInputWin.Refresh() }
func (s *Ship) Draw(w *gc.Window) { w.Overlay(s.Window) }
func main() { f, err := os.Create("err.log") if err != nil { log.Fatal(err) } defer f.Close() log.SetOutput(f) var stdscr *gc.Window stdscr, err = gc.Init() if err != nil { log.Println("Init:", err) } defer gc.End() rand.Seed(time.Now().Unix()) gc.StartColor() gc.Cursor(0) gc.Echo(false) gc.HalfDelay(1) gc.InitPair(1, gc.C_WHITE, gc.C_BLACK) gc.InitPair(2, gc.C_YELLOW, gc.C_BLACK) gc.InitPair(3, gc.C_MAGENTA, gc.C_BLACK) gc.InitPair(4, gc.C_RED, gc.C_BLACK) gc.InitPair(5, gc.C_BLUE, gc.C_BLACK) gc.InitPair(6, gc.C_GREEN, gc.C_BLACK) lines, cols := stdscr.MaxYX() pl, pc := lines, cols*3 ship := newShip(lines/2, 5) objects = append(objects, ship) field := genStarfield(pl, pc) text := stdscr.Duplicate() c := time.NewTicker(time.Second / 2) c2 := time.NewTicker(time.Second / 16) px := 0 loop: for { text.MovePrintf(0, 0, "Life: [%-5s]", lifeToText(ship.life)) stdscr.Erase() stdscr.Copy(field.Window, 0, px, 0, 0, lines-1, cols-1, true) drawObjects(stdscr) stdscr.Overlay(text) stdscr.Refresh() select { case <-c.C: spawnAsteroid(stdscr.MaxYX()) if px+cols >= pc { break loop } px++ case <-c2.C: updateObjects(stdscr.MaxYX()) drawObjects(stdscr) default: if !handleInput(stdscr, ship) || ship.Expired(-1, -1) { break loop } } } msg := "Game Over" end, err := gc.NewWindow(5, len(msg)+4, (lines/2)-2, (cols-len(msg))/2) if err != nil { log.Fatal("game over:", err) } end.MovePrint(2, 2, msg) end.Box(gc.ACS_VLINE, gc.ACS_HLINE) end.Refresh() gc.Nap(2000) }
func (e *Explosion) Draw(w *gc.Window) { w.Overlay(e.Window) }
func (b *Bullet) Draw(w *gc.Window) { w.Overlay(b.Window) }
func (c *Circuit) display() { stdscr, err := gc.Init() if err != nil { log.Println(err) } defer gc.End() rows, cols := stdscr.MaxYX() height, width := len(c.circuit)+1, len(c.circuit[0])+1 y, x := (rows-height)/2, (cols-width)/2 var win *gc.Window win, err = gc.NewWindow(height, width, y, x) if err != nil { log.Println(err) } defer win.Delete() win.Timeout(500) for i := 0; i != height-1; i++ { for j := 0; j != width-1; j++ { if c.circuit[i][j] == "" { continue } char := gc.Char([]rune(c.circuit[i][j])[0]) win.MoveAddChar(i, j, char) } } main: for { for _, com := range c.Components { com.Update() } for _, com := range c.Components { cx, cy, _, _ := com.Space() for coord, out := range com.Visual() { char := gc.Char([]rune(*out)[0]) win.MoveAddChar(cx+coord.X, cy+coord.Y, char) } } win.NoutRefresh() gc.Update() switch win.GetChar() { case 'q': break main } } }
func printmenu(w *gc.Window, menu []string, active int) { y, x := 2, 2 w.Box(0, 0) for i, s := range menu { if i == active { w.AttrOn(gc.A_REVERSE) w.MovePrint(y+i, x, s) w.AttrOff(gc.A_REVERSE) } else { w.MovePrint(y+i, x, s) } } w.Refresh() }
func windw() { stdscr, err := gc.Init() if err != nil { log.Fatal(err) } defer gc.End() // Turn off character echo, hide the cursor and disable input buffering gc.Echo(false) gc.CBreak(true) gc.Cursor(0) stdscr.Print("Use arrow keys to move the window. Press 'q' to exit") stdscr.NoutRefresh() // Determine the center of the screen and offset those coordinates by // half of the window size we are about to create. These coordinates will // be used to move our window around the screen rows, cols := stdscr.MaxYX() height, width := 20, 40 y, x := (rows-height)/2, (cols-width)/2 // Create a new window centered on the screen and enable the use of the // keypad on it so the arrow keys are available var win *gc.Window win, err = gc.NewWindow(height, width, y, x) if err != nil { log.Fatal(err) } win.Keypad(true) windw: for { // Clear the section of screen where the box is currently located so // that it is blanked by calling Erase on the window and refreshing it // so that the chances are sent to the virtual screen but not actually // output to the terminal win.Erase() win.NoutRefresh() // Move the window to it's new location (if any) and redraw it win.MoveWindow(y, x) win.Box(gc.ACS_VLINE, gc.ACS_HLINE) win.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() // In order for the window to display correctly, we must call GetChar() // on it rather than stdscr switch win.GetChar() { case 'q': break windw case 'h': if x > 0 { x-- } case 'l': if x < cols-width { x++ } case 'k': if y > 1 { y-- } case 'j': if y < rows-height { y++ } } } win.Delete() }