今までのコードはキーボードからの入力をio::stdin().bytes()で読み込み、処理を行ってきましたがcrosstermでも入力処理を提供しています。
こちらはキーボードだけでなくマウスの入力やウィンドウリサイズも検知できるようです。
クロスプラットフォームでcrosstermの関数はよりリッチな機能を提供しているようですのでこちらを使うように書き直して見ます。
mainの内容が大きくなってきました。
書き直すついでに、機能毎に関数で切り出して整理してみました。
// イベントハンドラ
fn handle_events() {
// match式でResultを処理
match event::read() {
// キー入力処理
Ok(Event::Key(key_event)) if key_event.kind == KeyEventKind::Press => {
handle_key_events(key_event);
}
// エラーの場合
Err(err) => {
println!("Error: {}", err);
}
// その他入力(マウス等)
_ => {
// todo!()
}
};
}
// キー入力処理
fn handle_key_events(key_event: KeyEvent) {
// Ctrl や SHIFT等のコンビネーションキー処理
match key_event.modifiers {
// Ctrlが押されている場合
KeyModifiers::CONTROL => {
// 対のキーの処理
match key_event.code {
// Ctrl + qが入力されたら
KeyCode::Char('q') => {
// raw モードを解除
disable_raw_mode().unwrap();
// AlternateScreenから復帰
crossterm::execute!(stdout(), LeaveAlternateScreen).unwrap();
// アプリケーション終了処理
todo!("Process Exit");
}
_ => {}
}
}
...省略....
// 入力されたキーを画面出力
dbg_print_key_code(key_event);
}
event::read()でイベントの読み込みをしてキーボードのイベントであればhandle_key_eventsを呼び出す形となっています。
以前はqキーを押したら終了としていましたが、Ctrl + qを押したら終了としました。
main関数がだいぶスッキリしました。
// main 関数
fn main() {
// AlternateScreenへ移行
crossterm::execute!(stdout(), EnterAlternateScreen).unwrap();
// raw モードに移行
enable_raw_mode().unwrap();
loop {
// イベント処理
handle_events();
}
}
TOC
GitHubにコードをアップロードしています。
コードのコメントに書かれているfirst_stepなどをcargoコマンドに渡すと実行できます。
# Example
$ cargo run --examples first_step