自作エディターを作る! コンソールのサイズ/ファイル名、モード表示
今回はコンソールサイズを取得して、ページの行数を可変にしていきます。
今回やったこと
今回は前回の記事で書いたように、コンソールのサイズによって表示行数を可変にし、編集中のファイル名と現在のモードを表示するようにしました。またCEditEngineでやっていたファイルの表示をCEditControlに任せるようにしました。
各クラスの変更点は以下のようになっています。
- class CEditEngine - 表示やページの切り替えをやめて、バッファの編集操作のみを担うクラスにする。
- class CEditControl - 表示やページの切り替えをこのクラスでやる。コンソールのサイズで表示行数などを変える。編集中のファイル名と現在のモードを表示する。
- console.cpp - コンソールのサイズを取得するAPIを追加する。
今回の開発内容
コンソールサイズの取得
この記事を参考にしました。
MSizeは高さと幅をセットにした構造体です。取得した結果を返しているだけです。
ちなみに、コンソールにアクセスする関数をconsole.cppにまとめている理由としては、別のライブラリや別の環境でのAPIを導入したときに、変更箇所をconsole.cppのみに限定するためです。よくラップ関数を作ってやるやつですね。
編集中のファイル名の表示
CEditControlクラスは編集中のファイル名をm_filenameに持っているので、それを表示しているだけです。ファイル名の表示は1行目全部を反転させたかったので、コンソールの幅分の長さの文字列をつくって(あまりは空白で埋めます)、背景色を変更した状態でprintf()しています。
文字列の空白埋め
文字列の空白埋めはstringstreamを使っています。std::setw()で文字列長を指定し、std::setfill(' ')で空白埋めしました。
最後にsstream::str()でstringを出力しています。
前景色(文字色)、背景色の制御
制御文字をprintf()することで背景色や前景色を変えることができます。この記事が非常に参考になりました。一度変更したら、もとに戻すのを忘れずに…。
現在のモードの表示
これはそんなに語ることはありませんね。カーソル位置を調整してそこからprintf()すればいいです。カーソル位置の制御も制御文字をprintf()すればできます。こちらもこの記事に記載があります。
CEditEngineの役割の変更
これが今回一番悩みました。
CEditEngineクラスには今までエディタの描画も担当してもらっていて、なのでPageUp()、PageDown()もこのクラスのメソッドですし、現在どの行を表示しているか?などの情報も持っていました。
ですが、描画周りまで担当させてしまうと、コンソールとガチガチに組み合わさって移植性が下がっちゃうかな、と思って表示周りをCEditControlクラスに移しました。
(もともと今回の開発は、単独のアプリケーションとしてやろうとしていたものを、難しそうだから一旦コンソールで動くエディタとして作ろうとしているだけなので、今後の移植性を考えたときにCEditEngineにはあまり環境に依存するコードを入れたくないんですよね…。このこともあって、CEditEngineクラスからはconsole.cppの関数をあまり使いたくないです。)
次にやること
カーソルの移動をやりたいですね。十字キーは難しいらしいので、ひとまずアルファベットを適当に割り当ててやろうかな。折返しの事を考えて、論理行と物理行の概念を取り入れると思います。
あとは編集方式を考えないといけないですね。面倒なので最小は行エディタにしちゃおうかな?