Cocoa Break Logo Top Soft Develop  脱力空間 Logo
Apple Web Badge
made by mi

概要 翻訳 ソース リンク がらくた

概要 Examples ADC Samples 3rd Parties etc CBOriginals

NumberInput_IMKit_Sample

以下は、Mac OS X 10.5.5 上の Xcode 3.1 で説明しています。このサンプルは、NumberInput 0 から NumberInput 4 までの 5 段階に分かれていて、何もしないものから次第に高度な機能をもつものへと拡張されていきます。

目次:
1 NumberInput 0        2 NumberInput 1        3 NumberInput 2
4 NumberInput 3        5 NumberInput 4        6 更新履歴
5.1 ReadMe の日本語訳
5.2 使ってみる
5.3 グループとファイル
5.4 NumberInputApplicationDelegate クラス
5.5 NumberInputController クラス

5 NumberInput 4

5.1 ReadMe の日本語訳

NumberInput プロジェクトのこのバージョンでは、環境設定と、ユーザーが環境設定を変更できるようにするメニュー項目が追加されます。

環境設定ウインドウと環境設定サポートを追加するには、環境設定をユーザーデフォルトデータベース内のキーと値の組に結び付けるために NSUserDefaultsController を使う preferences.nib を作成します。また、InputMethodKit が自動的に環境設定のデフォルト値を設定できるようにするため、preferences.plist を提供する必要もあります。最後に、テキスト入力メニューに環境設定メニュー項目を追加することによって、環境設定に対するユーザーのアクセス手段を提供します。

  1. Interface Builder において、preferences.nib という名前の nib ファイルを作成します。ここでコントロールをもつユーティリィティパネルを追加します。

    1. File's Owner(ファイル所有オブジェクト)を NSWindowController にして、それをパネルと接続します。

    2. 2 個のラジオボタンをもつマトリックスを追加します。最初のボタンのタグを 1 に設定し、2 番目のタグを 0 に設定します。

    3. nib ファイルに NSUserDefaultsController をドラッグします。モデルキーパスを verticalCandidate に設定します。

  2. NumberInput プロジェクトに preferences.plist を追加します。これは以下のようになるでしょう。

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>verticalCandidate</key> <integer>1</integer> </dict> </plist>
  3. InterfaceBuilder に戻って、MainMenu.nib 内に NSMenu を作成します。そのメニューに単一の NSMenuItem を追加し、「Preferences...」という名前を付けます。

  4. このサンプルの場合のメニューは、すべてのコントローラーの間で共有され、そのため、NumberInputApplicationDelegate 内に NSMenu である IBOutlet を作成します。

    また、メニューに対してアクセサ関数が提供されていることを確実にします。それから、IB に NumberInputApplicationDelegate を再読み込みさせ、新しいメニューアウトレットを NSMenu に接続します。

  5. 入力コントローラーに menu メソッドを追加します。この menu 関数は、IMKInputController で宣言されている menu メソッドをオーバーライドし、入力メソッドが選択され、テキスト入力メニューが更新される必要がある時はいつでも呼ばれることになります。

通常のように、これらの変更を行った後で、入力メソッドをビルドし、それを /Library/Input Methods/ へとコピーします。

そして、テキストエディットを開きます。NumberInput モードのどれかを選びます。テキスト入力メニューに「Preferences...」という項目が追加されているのを目にすることができます。この項目を選択すれば、環境設定パネルが表示されるはずです。

5.2 使ってみる

ビルドとインストール方法は、前回と同じです。このサンプルでは、ReadMe で説明されているように、環境設定が追加されています。まず、メニューに環境設定パネルを開くための項目が追加されています。

これを選ぶと、以下のようなパネルが表示されます。

このパネル内の設定は、候補ウインドウが垂直方向か水平方向を使うかを切り替えるものです。水平方向にすれば、候補ウインドウは以下のように表示されます。

5.3 グループとファイル

ReadMe で書かれているように、今回、プロジェクト内には preferences.nib、preferences.plist が追加されています。

preferences.plist の内容は以下のようになっています。

preferences.plist(省略)
<dict> <key>verticalCandidate</key> <integer>1</integer> </dict>

verticalCandidate キーに対してデフォルト値を提供しています。

preferences.nib は以下のようになっています。接続インスペクタは、パネル内のマトリックスを選択した状態のものです。

ReadMe に書かれているように、バインディングが設定されていることがわかります。

また、MainMenu.nib も修正されていて、メニューが追加されています。

接続インスペクタは、NumebrInputController を選択した状態のものです。_menu アウトレットが接続されているのがわかります。

クラスファイルは、ConversionEngine は前と同じです。NumberInputApplicationDelegate ではメニュー関係などの設定が、NumberInputController では環境設定に応じて候補ウインドウを表示するように修正されています。

5.4 NumberInputApplicationDelegate クラス

インターフェースでは、メニュー関係のインスタンス変数とメソッドが追加されています。

NumberInputApplicationDelegate.h > インターフェース宣言
@interface NumberInputApplicationDelegate : NSObject { IBOutlet ConversionEngine* _conversionEngine; IBOutlet NSMenu* _menu; // メニュー } -(ConversionEngine*)conversionEngine; -(NSMenu*)menu; @end

このアウトレットは、MainMenu.nib 内でメニューに接続されていたものです。

実装ファイルでは、menu メソッドだけではなく、awakeFromNib も実装されています。

NumberInputApplicationDelegate.m > menu
// このメソッドは、コントローラーが共有 NSMenu にアクセスできるように追加されている -(NSMenu*)menu { return _menu; }
NumberInputApplicationDelegate.m > awakeFromNib
// アクションメソッドを設定できるように awakeFromNib 項目が追加されている // アクションなしの任意のメニュー項目は、テキスト入力メニュー内で表示される時、無効になることに注意 -(void)awakeFromNib { NSMenuItem* preferences = [_menu itemWithTag:1]; // 項目を取得 if ( preferences ) { [preferences setAction:@selector(showPreferences:)]; // その項目にアクションを設定 } }

どちらも簡単なので、コメント等を参考にすぐわかると思います。

5.5 NumberInputController クラス

ヘッダファイルは、前回と全く同じです。実装ファイルでは、convert: client: で候補ウインドウを環境設定で指定されたように表示されるよう修正しているほか、スーパークラスから継承している menu メソッドもオーバーライドされています。これは、以前のプロジェクトで存在して、エラーを起こしていたものです。今回は、アプリケーションの委任に menu メソッドがあるため、きちんと動作します。

NumberInputController.m > convert: client:
- (BOOL)convert:(NSString*)trigger client:(id)sender { NSString* originalText = [self originalBuffer]; NSString* convertedString = [self composedBuffer]; BOOL handled = NO; if ( _didConvert && convertedString && [convertedString length] > 0 ) { extern IMKCandidates* candidates; if ( candidates ) { // 候補の方向を取得するため環境設定を読む NSInteger vertical = [[NSUserDefaults standardUserDefaults] integerForKey: @"verticalCandidate"]; if ( vertical ) { [candidates setPanelType:kIMKSingleColumnScrollingCandidatePanel]; } else { [candidates setPanelType:kIMKSingleRowSteppingCandidatePanel]; } _currentClient = sender; [candidates updateCandidates]; // これは候補を更新 [candidates show:kIMKLocateCandidatesBelowHint]; // これは候補を表示 // 可能なら、ユーザーの現在の挿入点の下に表示する } else { NSString* completeString = [convertedString stringByAppendingString:trigger]; [sender insertText:completeString replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; [self setComposedBuffer:@""]; [self setOriginalBuffer:@""]; _insertionIndex = 0; _didConvert = NO; handled = YES; } } else if ( originalText && [originalText length] > 0 ) { convertedString = [[[NSApp delegate] conversionEngine] convert:originalText]; [self setComposedBuffer:convertedString]; if ( [trigger isEqual: @" "] ) { [sender setMarkedText:convertedString selectionRange:NSMakeRange(_insertionIndex, 0) replacementRange:NSMakeRange(NSNotFound,NSNotFound)]; _didConvert = YES; } else { [self commitComposition:sender]; [sender insertText:trigger replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; } handled = YES; } return handled; }

修正部分は非常に簡単です。単に環境設定の値を読んで、それによって候補ウインドウのパネルタイプを設定しているだけです。

NumberInputController.m > menu
-(NSMenu*)menu { return [[NSApp delegate] menu]; }

これは単に先ほど説明した、アプリケーション委任の共有メニューを取得しているだけです。もし、モードごとや、状態ごとにメニューが違ったりするなら、ここでメニューを切り替えることになります。

さて、これでこのサンプルの説明は終わりました。そして、このサンプル群全体もこれで完成形です。

まだ未完成ですが、BasicInputMethod の解説を見てもらえれば、テキストサービスコンポーネントの形の入力メソッドに比べて、入力メソッドキット利用の入力メソッドがどれほど簡単に実装できるかがわかると思います。もっと細かいことをしようとすれば、NSConnection を通じたやりとりなどが必要になってくるかもしれませんが、単なる変換では、このようにすごく簡単に実装できます。

6 更新履歴

2008.09.21

10.5.5 Xcode 3.1 で解説作成完了。

前へ  

管理人:神吉 秀典 E-mail:puer@ba.wakwak.com