Setting Up and Tearing Down a Curses Program

Problem

To write a program that uses Curses or Ncurses, you have to write a lot of setup and cleanup code. Youd like to factor that out.

Solution

Heres a wrapper method that sets up the Curses library and passes the main screen object into a code block:

require curses module Curses def self.program main_screen = init_screen noecho cbreak curs_set(0) main_screen.keypad = true yield main_screen end end

Heres a simple Ruby program that uses the wrapper method to fill up the screen with random placements of a given string:

Curses.program do |scr| str = ARGV[0] || Test max_x = scr.maxx-str.size+1 max_y = scr.maxy 100.times do scr.setpos(rand(max_y), rand(max_x)) scr.addstr(str) end scr.getch end

Discussion

The initialization, which is hidden in Curses.program, does the following things:

The code is a little different if you e using the third-party ncurses binding instead of the curses library that comes with Ruby. The main difference is that with ncurses, you must write some of the cleanup code that the curses library handles automatically. A wrapper method is also a good place to set up the ncurses color code if you plan to use colored text (see Recipe 21.8 for more on this).

Heres an Ncurses.program method thats equivalent to Curses.program, except that it performs its cleanup manually by registering an at_exit block to run just before the interpreter exits. This wrapper also turns on color and initializes a few default color pairs. If your terminal has no color support, the color code will run but it won do anything.

require curses module Ncurses COLORS = [COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE] def self.program stdscr = Ncurses.initscr # Run ncurses cleanup code when the program exits. at_exit do echo nocbreak curs_set(1) stdscr.keypad(0) endwin end noecho cbreak curs_set(0) stdscr.keypad(1) start_color COLORS[1…COLORS.size].each_with_index do |color, i| init_pair(i+1, color, COLOR_BLACK) end yield stdscr end end

Heres the ncurses equivalent of the curses program given earlier:

Ncurses.program do |scr| str = ARGV[0] || Test max_y, max_x = [], [] scr.getmaxyx(max_y, max_x) max_y = max_y[0] max_x = max_x[0] - str.size + 1 100.times do scr.mvaddstr(rand(max_y), rand(max_x), str) end scr.getch end

See Also

Категории