+--------------------------------------------------+ |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
つづく