// Since CGO currently can't handle varg C functions we'll mimic the // ncurses addstr functions. func (w *Window) Addstr(x, y int, str string, flags int32, v ...interface{}) { newstr := fmt.Sprintf(str, v...) w.MoveCursor(x, y) for i := 0; i < len(newstr); i++ { C.waddch(w.win, C.chtype(newstr[i])|C.chtype(flags)) } }
// Since CGO currently can't handle varg C functions we'll mimic the // ncurses addstr functions. func (win *Window) Addstr(x, y int, str string, flags int32, v ...interface{}) { newstr := fmt.Sprintf(str, v...) win.Move(x, y) for i := 0; i < len(newstr); i++ { C.waddch((*C.WINDOW)(win), C.chtype(newstr[i])|C.chtype(flags)) } }
// Since CGO currently can't handle varg C functions we'll mimic the // ncurses addstr functions. // Per Issue 635 the variadic function definition needs to end with // 'v ... interface {}' instead of 'v ...'. func (win *Window) Addstr(x, y int, str string, flags int32, v ...interface{}) { in() defer out() newstr := fmt.Sprintf(str, v) win.move(x, y) for _, ch := range newstr { C.waddch((*C.WINDOW)(win), C.chtype(ch)|C.chtype(flags)) } }
// Since CGO currently can't handle varg C functions we'll mimic the // ncurses addstr functions. func (win *Window) AddString(x, y int, str string, flags int32, v ...interface{}) { var resolvedString string if v != nil { resolvedString = fmt.Sprintf(str, v) } else { resolvedString = str } win.Move(x, y) for i := 0; i < len(resolvedString); i++ { C.waddch((*C.WINDOW)(win), C.chtype(resolvedString[i])|C.chtype(flags)) } }
func displayPickUpChoice() []entity.ID { var str *C.char C.clear() C.move(0, 0) str = C.CString("Pick up what?\n") C.addstr(str) C.free(unsafe.Pointer(str)) px, py := currentLevel.EntityLocation(player.EntityID()) itemsAvailable := currentLevel.ItemsAt(px, py) for i, eid := range itemsAvailable { C.addch(C.chtype(inventoryChar(byte(i)))) str = C.CString(" - ") C.addstr(str) C.free(unsafe.Pointer(str)) str = C.CString(currentLevel.EntityByID(eid).EntityName()) C.addstr(str) C.free(unsafe.Pointer(str)) } itemsChosen := make([]bool, len(itemsAvailable)) for { ch := C.getch() if ch == C.KEY_ENTER || ch == ' ' || ch == '\n' { break } if ch > C.int(255) { continue } if i := inventoryIndex(byte(ch)); (int(i) < len(itemsChosen)) && (i != 255) { if itemsChosen[i] { itemsChosen[i] = false C.mvaddch(C.int(i+1), 2, C.chtype('-')) } else { itemsChosen[i] = true C.mvaddch(C.int(i+1), 2, C.chtype('+')) } } } result := make([]entity.ID, 0, len(itemsAvailable)) for i, v := range itemsChosen { if v { result = append(result, itemsAvailable[i]) } } return result }
func (w *Window) Border(ls, rs, ts, bs, tl, tr, bl, br int) error { if C.wborder(w.win, C.chtype(ls), C.chtype(rs), C.chtype(ts), C.chtype(bs), C.chtype(tl), C.chtype(tr), C.chtype(bl), C.chtype(br)) == ERR { return Error } return nil }
// Border uses the characters supplied to draw a border around the window. // t, b, r, l, s correspond to top, bottom, right, left and side respectively. func (w *Window) Border(ls, rs, ts, bs, tl, tr, bl, br Char) error { res := C.wborder(w.win, C.chtype(ls), C.chtype(rs), C.chtype(ts), C.chtype(bs), C.chtype(tl), C.chtype(tr), C.chtype(bl), C.chtype(br)) if res == C.ERR { return errors.New("Failed to draw box around window") } return nil }
func displayInventory() { var str *C.char C.clear() C.move(0, 0) str = C.CString("Inventory contents:\n") C.addstr(str) C.free(unsafe.Pointer(str)) for i, v := range inventory { if inventory[i] != nil { C.addch(C.chtype(inventoryChar(byte(i)))) str = C.CString(" - ") C.addstr(str) C.free(unsafe.Pointer(str)) str = C.CString(v.name) C.addstr(str) C.free(unsafe.Pointer(str)) C.addch(C.chtype('\n')) } } }
func Init(theme *ColorTheme, black bool, mouse bool) { C.setlocale(C.LC_ALL, C.CString("")) tty := C.c_tty() if tty == nil { fmt.Println("Failed to open /dev/tty") os.Exit(2) } _screen = C.c_newterm(tty) if _screen == nil { fmt.Println("Invalid $TERM: " + os.Getenv("TERM")) os.Exit(2) } C.set_term(_screen) if mouse { C.mousemask(C.ALL_MOUSE_EVENTS, nil) C.mouseinterval(0) } C.noecho() C.raw() // stty dsusp undef C.nonl() C.keypad(C.stdscr, true) delay := 50 delayEnv := os.Getenv("ESCDELAY") if len(delayEnv) > 0 { num, err := strconv.Atoi(delayEnv) if err == nil && num >= 0 { delay = num } } C.set_escdelay(C.int(delay)) _color = theme != nil if _color { C.start_color() InitTheme(theme, black) initPairs(theme) C.bkgd(C.chtype(C.COLOR_PAIR(C.int(ColNormal)))) _colorFn = attrColored } else { _colorFn = attrMono } C.nodelay(C.stdscr, true) ch := C.getch() if ch != C.ERR { C.ungetch(ch) } C.nodelay(C.stdscr, false) }
func (r *FullscreenRenderer) Init() { C.setlocale(C.LC_ALL, C.CString("")) tty := C.c_tty() if tty == nil { errorExit("Failed to open /dev/tty") } _screen = C.c_newterm(tty) if _screen == nil { errorExit("Invalid $TERM: " + os.Getenv("TERM")) } C.set_term(_screen) if r.mouse { C.mousemask(C.ALL_MOUSE_EVENTS, nil) C.mouseinterval(0) } C.noecho() C.raw() // stty dsusp undef C.nonl() C.keypad(C.stdscr, true) delay := 50 delayEnv := os.Getenv("ESCDELAY") if len(delayEnv) > 0 { num, err := strconv.Atoi(delayEnv) if err == nil && num >= 0 { delay = num } } C.set_escdelay(C.int(delay)) if r.theme != nil { C.start_color() initTheme(r.theme, r.defaultTheme(), r.forceBlack) initPairs(r.theme) C.bkgd(C.chtype(C.COLOR_PAIR(C.int(ColNormal.index())))) _colorFn = attrColored } else { initTheme(r.theme, nil, r.forceBlack) _colorFn = attrMono } C.nodelay(C.stdscr, true) ch := C.getch() if ch != C.ERR { C.ungetch(ch) } C.nodelay(C.stdscr, false) }
func (r *FullscreenRenderer) NewWindow(top int, left int, width int, height int, border bool) Window { win := C.newwin(C.int(height), C.int(width), C.int(top), C.int(left)) if r.theme != nil { C.wbkgd(win, C.chtype(C.COLOR_PAIR(C.int(ColNormal.index())))) } if border { pair, attr := _colorFn(ColBorder, 0) C.wcolor_set(win, pair, nil) C.wattron(win, attr) C.box(win, 0, 0) C.wattroff(win, attr) C.wcolor_set(win, 0, nil) } return &CursesWindow{ impl: win, top: top, left: left, width: width, height: height, } }
func NewWindow(top int, left int, width int, height int, border bool) *Window { win := C.newwin(C.int(height), C.int(width), C.int(top), C.int(left)) if _color { C.wbkgd(win, C.chtype(C.COLOR_PAIR(C.int(ColNormal)))) } if border { pair, attr := _colorFn(ColBorder, 0) C.wcolor_set(win, pair, nil) C.wattron(win, attr) C.box(win, 0, 0) C.wattroff(win, attr) C.wcolor_set(win, 0, nil) } return &Window{ impl: (*WindowImpl)(win), Top: top, Left: left, Width: width, Height: height, } }
func (win *Window) Background(colour int) { C.wbkgd((*C.WINDOW)(win), C.chtype(colour)) }
func (window *Window) Addch(ch int) { C.waddch(window.cwin, C.chtype(ch)) }
func (win *Window) Box(verch, horch int) { C.box((*C.WINDOW)(win), C.chtype(verch), C.chtype(horch)) }
// Box draws a border around the given window. For complete control over the // characters used to draw the border use Border() func (w *Window) Box(vch, hch Char) error { if C.box(w.win, C.chtype(vch), C.chtype(hch)) == C.ERR { return errors.New("Failed to draw box around window") } return nil }
func (win *Window) AddGet(x, y int, c int32, flags int32) { C.mvwaddch((*C.WINDOW)(win), C.int(y), C.int(x), C.chtype(c)|C.chtype(flags)) }
// SlkAttributeOff turns off the given OR'd attributes withoiut turning any on func SlkAttributeOff(attr Char) error { if C.slk_attroff(C.chtype(attr)) == C.ERR { return errors.New("Soft-keys or terminal not initialized.") } return nil }
func (window *Window) Mvaddch(y, x int, ch rune) { C.mvwaddch(window.cwin, C.int(y), C.int(x), C.chtype(ch)) }
// MoveAddChar prints a single character to the window at the specified // y x coordinates. See AddChar for more info. func (w *Window) MoveAddChar(y, x int, ach Char) { C.mvwaddch(w.win, C.int(y), C.int(x), C.chtype(ach)) }
// VLine draws a verticle line starting at y, x and ending at height using // the specified character func (w *Window) VLine(y, x int, ch Char, wid int) { C.mvwvline(w.win, C.int(y), C.int(x), C.chtype(ch), C.int(wid)) }
// HLine draws a horizontal line starting at y, x and ending at width using // the specified character func (w *Window) HLine(y, x int, ch Char, wid int) { C.mvwhline(w.win, C.int(y), C.int(x), C.chtype(ch), C.int(wid)) return }
// AddChar prints a single character to the window. The character can be // OR'd together with attributes and colors. func (w *Window) AddChar(ach Char) { C.waddch(w.win, C.chtype(ach)) }
func (w *Window) Addch(x, y int, c int32, flags int32) { C.mvwaddch(w.win, C.int(y), C.int(x), C.chtype(c)|C.chtype(flags)) }
func (w *Window) Box(verch, horch int) { C.box(w.win, C.chtype(verch), C.chtype(horch)) }
// Grey sets the attributes of non-selectable items in the menu func (m *Menu) Grey(ch Char) { C.set_menu_grey(m.menu, C.chtype(ch)) }
func Mvaddch(y, x int, ch rune) { C.mvaddch(C.int(y), C.int(x), C.chtype(ch)) }
// SetBackground fills the background with the supplied attributes and/or // characters. func (w *Window) SetBackground(attr Char) { C.wbkgd(w.win, C.chtype(attr)) }
// SetForeground sets the attributes of the highlighted items in the menu func (m *Menu) SetForeground(ch Char) error { err := C.set_menu_fore(m.menu, C.chtype(ch)) return ncursesError(syscall.Errno(err)) }
func (w *Window) Background(colour int32) { C.wbkgd(w.win, C.chtype(colour)) }