ページ

2009年6月22日月曜日

ホットキー変更対応(11) - キー入力を捉える (NSTextView)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

IntefaceBuilderではテキストボックス関連のクラスはすべて NSTextFieldが割り当てられている。



通常の用途ではこれで良いのだが、今回のような用途ではオーバスペックで逆に使いづらい。やりたいのは下記のこと。
 ・キー文字の表示
 ・キー入力のハンドリング
 ・レスポンダーになれる

NSTextFieldの場合、入力された「文字列」を扱うのは便利なのだが「キー値」が扱えない。NSTextFieldの派生クラスを作っても - [NSResponder keyDown:] が呼ばれないから。

NSTextFieldで入力キーを扱う方法には、以前紹介した(ファイル名変更(その4)NSTextFieldでESCキーをハンドリングする CommentsAdd Star)、デリゲートメソッド - [NSTextField control:textView:doCommandBySelector:] があるが、特定の文字だけのハンドリングならともかく、ほとんどすべての文字を対象にするには十分でない。


そこで NSTextFieldではなく、その下請けにあたる NSTextView クラスを試してみる。InterfaceBuilderからは作れないようなので、プログラムコードからインスタンスを生成する。

まず NSTextView のサブクラスを定義する。
TextView.h

@interface TextView : NSTextView


キーイベントをデバッグコンソールへ出力させる。
TextView.m
@implementation TextView

- (void)keyDown:(NSEvent *)theEvent
{
NSLog(@"%@", theEvent);
}


このクラスのインスタンスを AppControllerで作成し、ウィンドウへ貼付ける。
AppController.m
- awakeFromNib
{
_text_view = [[TextView alloc] initWithFrame:NSMakeRect(10,10,100,25)];
[[_window contentView] addSubview:_text_view];
[_window makeFirstResponder:_text_view];
[_text_view insertText:@"Hello"];
}


実行してみよう。


NSTextView の上でキーボードをたたいてみる。

2009-06-22 22:29:20.225 HotkeyUI[7058:10b] NSEvent: type=KeyDown loc=(0,119) time=134100.3 flags=0x20102 win=0x0 winNum=15724 ctxt=0x1515f chars="A" unmodchars="A" repeat=0 keyCode=0
2009-06-22 22:29:21.040 HotkeyUI[7058:10b] NSEvent: type=KeyDown loc=(0,119) time=134101.2 flags=0x20102 win=0x0 winNum=15724 ctxt=0x1515f chars="B" unmodchars="B" repeat=0 keyCode=11
2009-06-22 22:29:23.089 HotkeyUI[7058:10b] NSEvent: type=KeyDown loc=(0,119) time=134103.2 flags=0x100108 win=0x0 winNum=15724 ctxt=0x1515f chars="c" unmodchars="c" repeat=0 keyCode=8


- [NSResponder keyDown:] が呼ばれた。

なお入力された文字は NSTextView には反映されない(何を入力しても初期表示 "Hello"のまま)。今回表示は自前で対処するのでこれは好都合。よしこれで進めていこう。