// 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 }
//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() }
//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 }
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() }