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:
- Stops keystrokes from being echoed to the screen (noecho)
- Hides the cursor (curs_set(0))
- Turns off buffered input so keys can be processed as they e typed (cbreak)
- Makes the keyboards arrow keys generate recognizable key events (keypad=true)
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
- See this chapters introduction for information on installing Ncurses
- "Writing Programs with NCURSES" is a good general overview of the Ncurses library; its written for C programmers, but its useful for Rubyists because Rubys interfaces to Curses and Ncurses are little more than wrappers (http://dickey.his.com/ncurses/ncurses-intro.html)
Категории