+--------------------------------------------------+ |Header | +--------------------------------------------------+ |Body | | | | | | | | | | | +--------------------------------------------------+ |Label | +--------------------------------------------------+ |Footer | +--------------------------------------------------+
Cursesで枠を作る
| 作成日 | : | 2016/02/15 |
|---|---|---|
| 最終更新日 | : | 2020/07/05 |
Cursesで枠を作る
| 作成日 | : | 2016/02/15 |
|---|---|---|
| 最終更新日 | : | 2020/07/05 |
概要
Rubyでテキストエディタを作り始めます。 cursesを利用し画面を区切ります。
画面構成
cursesを用い画面を区切ります。 今回はEmacs風に以下のように画面を区切ることにします。
コマンド1. コマンド実行イメージ
HeaderとLabelの領域は色を反転させます。 また、EmacsではBodyとLabelの領域の組を複数持てますが、 当面は単一の構成で作成します。
Cursesモジュールの取り込み
以下のようにincludeすることでCurses.を省略できるようになります。
ソース1. モジュールの取り込み
require "curses" include Curses
ViewWindowクラス
そのまま、cursesを利用しても良いのですが扱いやすくするために ViewWindowクラスを定義します。
windowの親子構造の管理やパラメータの管理を目的とします。 windowを生成するための情報はハッシュで与えることにします。
ソース2. ViewWindowクラス
class ViewWindow
attr_accessor :parent, :param, :window
def initialize(parent, param)
@parent = parent
if (parent.nil?)
@parent_window = stdscr
else
@parent_window = @parent.window
end
@param = param;
@param[:size] = param[:size]
@param[:size][:width] = param[:size][:width]
@param[:size][:height] = param[:size][:height]
@window = @parent_window.subwin(param[:size][:height],
param[:size][:width],
param[:pos][:y],
param[:pos][:x])
if (param[:box])
@window.box(param[:box][:virtical_char],
param[:box][:horizontal_char],
param[:box][:joint_char]);
end
if (param[:attr])
@window.attrset(param[:attr])
end
end
def addstr(str)
@window.addstr(str.ljust(@param[:size][:width]))
end
def setpos(y, x)
@window.setpos(y, x)
end
def refresh
@window.refresh
end
end色の反転
文字の状態を変化させるにはWindowクラスのメソッドattrset()を 呼び値を設定します。 描画色を反転するにはCursesモジュールに組み込まれた定数A_REVERSEを 指定します。
Windowの生成
cursesを初期化し、各種Windowを生成します。 Windowのオブジェクトはwindowハッシュで管理します。
ソース3. Windowの生成
init_screen
window = {}
begin
# Main Windowの作成
param = {size: {width: cols, height: lines},
pos: {x: 0, y: 0}}
window[:main] = ViewWindow.new(nil, param)
# Header Windowの作成
param = {size: {width: window[:main].param[:size][:width], height: 1},
pos: {x: 0, y: 0},
attr: (::A_REVERSE)}
window[:header] = ViewWindow.new(window[:main], param)
# Footer Windowの作成
param = {size: {width: window[:main].param[:size][:width], height: 1},
pos: {x: 0, y: window[:main].param[:size][:height] - 1}}
window[:footer] = ViewWindow.new(window[:main], param)
# Label Windowの作成
param = {size: {width: window[:main].param[:size][:width], height: 1},
pos: {x: 0, y: window[:main].param[:size][:height] - 2},
attr: (::A_REVERSE)}
window[:label] = ViewWindow.new(window[:main], param)
# Body Windowの作成
param = {size: {width: window[:main].param[:size][:width],
height: window[:main].param[:size][:height] - 3},
pos: {x: 0, y: 1}}
window[:body] = ViewWindow.new(window[:main], param)
# Header Windowに表示する文字列の設定
str = "Menu"
window[:header].addstr(str.ljust(window[:main].param[:size][:width]))
window[:header].refresh
# Label Windowに表示する文字列の設定
str = "Label"
window[:label].addstr(str.ljust(window[:main].param[:size][:width]))
window[:label].refresh
# カーソル位置の設定
setpos(window[:body].param[:pos][:y],
window[:body].param[:pos][:x])
getch
ensure
close_screen
endつづく
