なぜSDLにはテキスト入力APIが必要なのか?
キーボードのキーを押せば, プログラムは文字イベントを受信する. そうではないのか?
常にそのように単純なわけではない. 1つの文字のために複数のキーが必要なことがあり, 1つのキーが複数の文字を生成することもある.
テキスト入力は, 世界中のユーザを考慮するならば(そしてそうすべきだ), 見た目ほど単純ではない. 中国語, 日本語, 韓国語などを見ればすぐにわかるだろう. これらのCJKと呼ばれる言語には数千の文字がある.
一万を超えるキーのあるキーボードは存在し得ない. その解決法がソフトウェア インプット メソッドである.
順序 | 説明 | 例 |
---|---|---|
1 | ユーザはインプットメソッド(IME)を有効にする. 通常はホットキーまたはGUIでインプットメソッドを選択する. | 2 | ユーザは選択した言語で入力を開始する. | 3 | ユーザは望むところまで入力を続ける. | 4 | ユーザは変換候補リストを開き, 変換テキストを選択する. IMEが自動的に変換リストを開くようにすることもできる. | 5 | ユーザは変換を確定する. IMEはアプリケーションにテキストを渡す. |
全ての環境で同じであるわけではないが, 概要としてはこれで十分である.
複数のスタイルのインプットメソッドについてはここで読める. SDLは"on-the-spot"モードに対応している. これは実装のとき重要である: アプリケーションは未変換テキストを表示する必要がある.
SDLではどのようにしてテキスト入力を扱えばよいか?
まずは例を示す:
#include "SDL.h"
extern void InitVideo();
extern void Redraw();
extern char *text;
extern char *composition;
extern Sint32 cursor;
extern Sint32 selection_len;
int main(int argc, char *argv[])
{
SDL_bool done = SDL_FALSE;
InitVideo();
/* ... */
SDL_StartTextInput();
while (!done) {
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
/* 終了 */
done = SDL_TRUE;
break;
case SDL_TEXTINPUT:
/* テキストの末尾に新しいテキストを追加する */
strcat(text, event.text.text);
break;
case SDL_TEXTEDITING:
/*
未変換テキストを更新する.
カーソル位置を更新する.
選択の長さを変換する(可能ならば).
*/
composition = event.edit.text;
cursor = event.edit.start;
selection_len = event.edit.length;
break;
}
}
Redraw();
}
SDL_Quit();
return 0;
}
注意すべき重要な点は, アプリケーションはSDL_StartTextInput()とSDL_StopTextInput()でテキスト入力の可不可を自由に設定できることである. もし対応していれば, SDL_SetTextInputRect()は変換候補リストをどこに開くかを決める.
アプリケーションは, 未変換テキストが変更された(または開始した)ならば, SDL_TextEditingEventイベントを受信する. このイベントには, 未変換テキストと, 未変換テキスト内のカーソルの位置が含まれている. もし対応していれば, 選択されたテキストの長さも含まれている.
アプリケーションは, 変換が確定し(IMEではない)通常のテキスト入力に戻ったときSDL_TextInputEventイベントを受信する. このイベントの受信は, 変換の確定, または未変換テキストの入力が始まっていない(直接入力)ことを示している.