====== Curses ====== Curses とは仮想端末の画面を制御するために用意されたライブラリである。 一般的な出力メソッドでは仮想端末で下方向や右方向にしか文字列を出力できなかったが、Curses を使うと仮想端末の任意の場所に文字列を出力でき、さらに色なども変更できる。 * [[https://github.com/ruby/curses]] 大学の環境ではすぐに Curses を利用できる。 その他の環境で利用できない場合は、次のように gem でインストールする必要がある。 % gem install curses ===== 基本の形式 ===== Curses は以下の形のプログラムが基本となる。 #!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- require "curses" # Cursesの初期化 Curses.init_screen begin <ここに処理を入れる> ensure # Cursesの終了処理 Curses.close_screen end プログラムの実行時に "warning: rb_safe_level will be removed in Ruby 3.0" と表示される場合は、次のように ruby にオプション "-W0" を付けて実行するとよい。 % ruby -W0 プログラム ===== メソッド ===== === カーソルの移動 === Curses.setpos(y, x) 仮想端末の画面の座標 (x, y) にカーソルを移動する。引数では y が先なので注意。 画面の行数は ''Curses.lines''、列数は ''Curses.cols'' で分かる。 {{ :ruby:curses_screen.png?nolink |画面上の座標}} === 文字の出力 === Curses.addch(文字) カーソルの位置に文字を出力する。 === 文字列の出力 === Curses.addstr(文字列) カーソルの位置に文字列を出力する。 === 画面表示の更新 === Curses.refresh ''Curses.addstr'' で文字列を出力をしても ''Curses.refresh'' を実行するまで画面に表示されない。 === カーソルの表示/非表示 === Curses.curs_set(番号) カーソルを表示するには番号に 1、非表示にするには番号に 0 を入力する。 === 文字の読み込み === Curses.getch 標準入力から1文字読み込む。 いわゆるキー入力である。 ---- ==== 色を使う ==== 色を使うにはまず、''Cursor.start_color'' を実行する。 Cursor.start_color === カラーペアの設定 === Curses.init_pair(カラーペア番号, 文字の色番号, 背景の色番号) 色を使うための準備として ''Curses.init_pair'' で文字と背景の色のペアをカラーペア番号(1以上の任意の整数)に設定する必要がある。 色番号は ''Curses::COLOR_BLUE'' や ''Curses::COLOR_BLACK'' などで指定するとよい。 === 色をつける === Curses.attrset(Curses.color_pair(カラーペア番号)) 文字に色をつけて出力するには、文字の出力前にカラーペア番号から選択する。 ===== プログラム例 ===== ==== プログラム例1 ==== プログラム curses1.rb は仮想端末の画面の四隅と中央に文字を出力する。 * 文字を出力したい座標にカーソルを ''Curses.setpos'' で移動して、''Curses.addch'' で文字を出力する。 * 出力した文字は ''Curses.refresh'' を実行するまで画面には表示されない。 #!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- require "curses" # Cursesの初期化 Curses.init_screen begin # 左上に"A"を出力 Curses.setpos(0, 0) Curses.addch("A") # 右上に"B"を出力 Curses.setpos(0, Curses.cols - 1) Curses.addch("B") # 左下に"C"を出力 Curses.setpos(Curses.lines - 1, 0) Curses.addch("C") # 右下に"D"を出力 Curses.setpos(Curses.lines - 1, Curses.cols - 1) Curses.addch("D") # 中央に"O"を出力 Curses.setpos(Curses.lines / 2, Curses.cols / 2) Curses.addch("O") # 画面表示を更新 Curses.refresh # キー入力があるまで待つ Curses.getch ensure # Cursesの終了処理 Curses.close_screen end ---- ==== プログラム例2 ==== プログラム curses2.rb は文字と背景の色を変えながら文字列を出力する。 #!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- require "curses" # Cursesの初期化 Curses.init_screen begin # 色の使用開始 Curses.start_color # カラーペア番号を設定 # 背景色を黒 Curses.init_pair( 1, Curses::COLOR_BLUE, Curses::COLOR_BLACK) Curses.init_pair( 2, Curses::COLOR_CYAN, Curses::COLOR_BLACK) Curses.init_pair( 3, Curses::COLOR_GREEN, Curses::COLOR_BLACK) Curses.init_pair( 4, Curses::COLOR_MAGENTA, Curses::COLOR_BLACK) Curses.init_pair( 5, Curses::COLOR_RED, Curses::COLOR_BLACK) Curses.init_pair( 6, Curses::COLOR_WHITE, Curses::COLOR_BLACK) Curses.init_pair( 7, Curses::COLOR_YELLOW, Curses::COLOR_BLACK) # 文字色を黒 Curses.init_pair( 8, Curses::COLOR_BLACK, Curses::COLOR_BLUE) Curses.init_pair( 9, Curses::COLOR_BLACK, Curses::COLOR_CYAN) Curses.init_pair(10, Curses::COLOR_BLACK, Curses::COLOR_GREEN) Curses.init_pair(11, Curses::COLOR_BLACK, Curses::COLOR_MAGENTA) Curses.init_pair(12, Curses::COLOR_BLACK, Curses::COLOR_RED) Curses.init_pair(13, Curses::COLOR_BLACK, Curses::COLOR_WHITE) Curses.init_pair(14, Curses::COLOR_BLACK, Curses::COLOR_YELLOW) # カラーペア番号で順に処理 1.upto(14) do |i| # 文字の色をセット Curses.attrset(Curses.color_pair(i)) # 文字列を出力 Curses.setpos(i, 0) Curses.addstr(sprintf("カラーペア番号 %d", i)) end # 画面表示を更新 Curses.refresh # キー入力があるまで待つ Curses.getch ensure # Cursesの終了処理 Curses.close_screen end ---- ==== プログラム例3 ==== プログラム curses3.rb はカーソルキーで "x" を移動する。 他のキーを押すと終了する。 #!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- require "curses" # Cursesの初期化 Curses.init_screen begin # 初期座標 x = y = 0 # カーソルを非表示 Curses.curs_set(0) # 入力文字を非表示 Curses.noecho # キーパッドを有効にする Curses.stdscr.keypad(true) # Enterキーが押されるまでループ while 1 # (x, y) に文字を出力 Curses.setpos(y, x) Curses.addch("x") # 画面表示を更新 Curses.refresh # キー入力があるまで待つ c = Curses.getch # (x, y) の文字を削除 Curses.setpos(y, x) Curses.delch # キー判定 case c when Curses::KEY_UP # 「↑」キー # 一番上の行でなければ上に移動 if y > 0 y -= 1 end when Curses::KEY_DOWN # 「↓」キー # 一番下の行でなければ下に移動 if y < Curses.lines - 1 y += 1 end when Curses::KEY_RIGHT # 「→」キー # 一番右の列でなければ右に移動 if x < Curses.cols - 1 x += 1 end when Curses::KEY_LEFT # 「←」キー # 一番左の列でなければ左に移動 if x > 0 x -= 1 end else # 他のキーでループを抜ける break end end ensure # Cursesの終了処理 Curses.close_screen end