この記事で扱っていること
- キーコンフィグを変える方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWのプログラムでユーザーの操作を必要とするとき、ブールボタンを押して操作を行わせることはよくあると思います。
ボタンを押して何かを開始させるといった、特定の処理を実行させるためのトリガーとなる操作、ですね。
基本的には、ブールボタンの配置は初めプログラムを作った段階での配置で決まり、ユーザー側からはその決まった配置の状態から変更することはできないですが、「好きなようにボタン割り当てを行いたい」という要望もあるかと思います。
ゲームなんかでも、コントローラの各種ボタンの割り当てを自由に設定できる、いわゆるキーコンフィグですが、それをLabVIEWプログラムでも実装する、という例を紹介します。
どんな結果になるか
今回は適当にいくつかボタンがある場面を想定しています。
コントローラっぽく、AボタンBボタン、そして上下左右のボタンの計4つです。
当然、この組み合わせじゃないとできない、ということではなく、同じ考え方はボタンの数が増えたとしても適用できます。
ボタンを押すと、そのボタンに対応する操作が実行されたことを模擬するために画面にポップアップが出るようにしています。
例えば、下の図の左側は「A」のボタンを押したとき、右側は「Left」のボタンを押したときの反応だとします。
この状態でキーコンフィグのボタンを押すと別画面が開き、各ボタンの割り当てを設定することができます。
また、この割り当ては一度設定するとプログラムを止めて再び実行した時にも適用されるようにしています。
コンフィグ画面を閉じた後は、そのボタン割り当てに応じた処理が実行されるようになります。
下の図の右側では「A」のボタンを押したのに、元々「B」のボタンを押したときの反応が出ている状態です。
プログラムの構造
キーコンフィグの割り当てについては、各ボタンにどのボタン操作を割り当てたか、という情報を管理(今回のプログラムでは2次元文字列配列として扱っています)することで、コンフィグを変更したように扱えるようにしています。
メインのプログラムはステートマシンをベースに組んでいます。
各ケースを紹介していきます。
Initケースでは、各ボタンの割り当ての情報を保存するための配列を用意しています。
この配列には「実際のキーとそのキーに対応する操作名」を各キー毎に保存していくので2次元配列になっています。
2次元配列の行の数はボタンの数に、列の数は2とするようにします。
今回は全部で6つのボタンがあったので、6行としています。
1列目に、ボタンの種類を識別する文字列を、2列目は空欄にしておきます。
まず最初プログラムを動作させる段階でのボタン割り当ての配列を決めていきます。
そのために、config_preparation.viというサブVIを使用しています。
このサブVIは、後でコンフィグの画面として表示する別のサブVIの中でも使用しています。
以下がその内容です。
keyconfig.iniやkeyconfig_default.iniというINIファイルに、キーコンフィグの情報を保存しています。
さらに別のサブVIがありますが、この中ではiniファイルを読み取って2次元配列の2列目の情報を更新するようにしています。
行列にとっての2列目は要素番号としては「1」であることに注意します。
今回の例ではそれぞれに「A」や「Down」などの名称をつけており、INIファイルに書き込むようにしています。
INIファイルは2つ用意し、それぞれ以下の違いがあります。
・常にデフォルトの情報をもち上書き保存されることがないkeyconfig_default.ini
・ユーザーが指定したオリジナルのキーコンフィグ情報が保存されるkeyconfig.ini
これらを読み込む際に優先されるのはkeyconfig.iniです。もしkeyconfig.iniがなかった場合にはkeyconfig_default.iniが読み込まれるようにしています。
メインのプログラムに戻りまして、次はeventケースです。
ここではイベントストラクチャによってイベントを検出しています。
キーコンフィグのボタンの値変更時に発生するイベントの中で使われているkeyconfig.viが、実際にユーザーが設定時に操作するインタフェースとなっています。
また、停止ボタンを押したときにはendステートに移るようにしています。
キーコンフィグおよび停止以外のボタンが押された際には、どのボタン操作がなされたかによって処理を変えられるようにケースストラクチャで次のステートを指定できるようにしています。
各ボタンがどのステートに対応しているかを2次元配列のデータとして持っているので、指標配列の関数によって1列目(行列の数え方で言うと0列目)にある「どのボタン」が押されたかを検出(2次元配列の1列目にあるボタンの名前と各ボタンのラベルの名称を一致させています)し、その行番号を、2列目にある「何の機能に対応しているか」の行の指定に使っています。
途中で出てきたkeyconfig.viの中身は以下の通りです。
フロントパネル上の横線や矢印は、「装飾体」を使っています。
VIとしてはエラーの入出力部分やメインVIとやり取りする際の二次元配列の制御器や表示器がありますが、ユーザーがこのVI上でキーコンフィグを設定する際には表示されている必要がないため、ウィンドウのサイズを調整して見えないようにしておきます。
こちらもイベントストラクチャを使用しています。
いくつかのサブVIがありますが、全てプログラム全体をコンパクトにするために必要なものとなっています。
Whileループに入る前にあるのは、先ほど紹介したconfig_preparation.viです。
set itemステートでは、2次元配列のそれぞれのデータを抜き出して、各列挙体に反映させるようにしています。
こうすることで、keyconfig.ini(なければkeyconfig_default.ini)に書いてあった情報を基にフロントパネルの状態を初期化するような役割を果たします。
使われているstring_to_enum.viは、単純に「どの文字列がどの列挙体項目に対応しているか」を変換しているだけです。
eventケースでは、デフォルトに戻すか設定終了かの2つのイベントしかありません。
デフォルトに戻すのボタンが押された場合には、keyconfig_default.iniから読みだして2次元配列を更新し、set itemステートに移ってその中身を制御器の表示に反映させるようにします。
使っているread_config_file.viは既に説明した通りです。
設定終了が押されたときに実行されるendステートでは、その時点で各列挙体で選ばれていた項目をkeyconfig.iniに書き込むように処理します。
こうすることで、次回またコンフィグを開いた際に、前回最後に設定した状態を初めに表示させることができます。
使われているenum_to_string.viは、string_to_enum.viの逆で、列挙体の項目から文字列に変換しています。
また、write_config_file.viによってINIファイルに書き込む処理を行っています。
今回のプログラムを作って初めて動かすときにはまだkeyconfig_default.iniはないと思うので、keyconfig.iniとしてあらかじめデフォルトの状態のiniファイルを作ってから、そのファイルの名称をkeyconfig_default.iniに変更して作るのが簡単です。
なお、このkeyconfig.viというサブVIは、メインVIから呼び出された際にフロントパネルが表示されるようにしていないと意味がありません。
VIプロパティでの設定を忘れずにしておきます。
メインのプログラムに戻り、メインプログラムのフロントパネル上で押されたボタンに応じて処理が実行されるようにしておきます。
今回は「「Aに対応するボタンが押された時の動作」というポップアップを表示させる」という動作を行わせているだけですが、実際にはこの部分に対応する処理を書き込むようにします。
他のボタンに対しても同様です。
各ボタンが押された時の動作を書くようにします。
今回は単純に1ボタンダイアログの関数でそれぞれ異なるメッセージを出すようにしています。
最後はendで、メインプログラムのWhileループを止めてプログラムを終了します。
ブールの表示も変更したい場合
キーコンフィグを変更したとはいえ、ブールテキストが元のままだと混乱してしまうかもしれません(混乱してしまうような設定はそもそも避けるべき、という考え方もあるとは思いますが)。
そこで、キーコンフィグを変更した場合にブール制御器の表示も変更されるようにしておきます。
やることは簡単で、プロパティノードの「ブールテキスト」のテキストプロパティを変更するようにします。
こうすることで実際にボタンの表示の状態を変更することができます。
本記事では、キーコンフィグを変更する方法を紹介しました。
最終的にはユーザーが一番使いやすい形になることを目指してプログラムを作ることになるとは思いますが、操作に各ユーザーの希望を盛り込むのが難しい場合、いっそのことユーザーが設定できる余地を残しておくといった工夫を施す際に、本記事の内容が役に立てばうれしいです。
ここまで読んでいただきありがとうございました。
コメント