<週刊 自分のごちうサーチを作る> #5 コントロールとのやりとり,ドラッグ&ドロップ
前回はこちら。
今回のお品書き。
検索レベルの設定
0 から 10 まで検索レベルを設定できるようにします。
- 0から10までの項目を追加する
- クリックされたとき,選択された項目の数値をフィールドにセットする
これでいけそうです。ではまず,WindowDidLoad
にメッセージボックス表示のコードを記述してある場合は削除しましょう。
検索レベルを保持するフィールドを用意して,コントロールの初期化を行うメソッドを作ってWindowDidLoad
から呼び出します。
一般的なコンボボックスとは異なり,NSPopupButton
の項目は NSMenu
すなわちメニューです。
- ルートとなるメニューを作る
- サブメニューアイテムを10個作る
- サブメニューアイテムのクリック時に検索レベルをセット
という流れになります。実装例がこちら。
8行目の Activated
が項目選択時のイベントハンドラです。ただしSelectItem
メソッドでコードから選択項目を変更したときにはトリガーされません。1行目で初期値を設定しているのはそのためです。
チェックボックスの状態を取得
「自動的にニコニコ動画を開く」チェックボックスは簡単です。これもフィールドを用意して,クリックされたときのイベントで変更することとします。
NSCellStateValue
には On, Off, Mixed の3状態があります。この辺はWindows Formsとさほど変わりません。もちろんActivated
イベントのsender
をキャストして状態を取得してもかまいません。
ドラッグ&ドロップの実装
前回作成したAcceptDropImageView
に実装していきます。いろいろ方法はありますが,今回は
- ローカルファイル がドロップされた
- URL がドロップされた
の2つのイベントを作成します。まずはURLまたはパスを通知するクラスを作っておきます。場所は参照できればどこでもかまいません。
もしひとつのイベントで済ませるなら,このクラスに種別をつけるか,Payloadを改めて解析し,ローカルパスなのかURLなのかを判別することになります。
ではイベントを作成し,ドラッグ操作の受け入れ設定を行います。
RegisterForDraggedTypes
で受け入れを行うNSPasteBoardのタイプを指定します。Cocoaの世界ではアプリケーション間のデータのやりとりはPasteboard Serverを経由して行われています。このビューが受け入れるタイプを指定しておくことで,データの転送対象であることを明示できます。
ではドラッグ操作がビュー内に進入してきたときに,受け入れ可能かどうか判別していきましょう。判別結果により,マウスポインタを変更します。
DraggingEntered
がドラッグ操作の進入時にトリガーされます。もちろん複数のファイルをドラッグされる可能性があるので,ここでは最初のものをターゲットにしています(3行目)。このメソッドが呼ばれた際には必ずPasteboard内に項目が存在するので,項目数のチェックを行う必要は特にありません。
NSPasteboardItem
クラスにはドラッグ操作内のアイテムの種別が設定されています。例えばFinderからファイルをドラッグ&ドロップするとこんな感じに。
これはアイテムのメタデータのキーになっています。この場合はpublic.file-url
キーでデータを引く(12行目GetStringForType
)とファイル参照パスを取得することができます。
12行目では参照パスから通常のファイルパスに変換するため,いったんNSUrl
にしてからPathプロパティでパスを取得しています。10.10以降では必ず行います。
戻り値NSDragOperation
によってシステムがマウスポインタの形状を変更します。ここでは受け入れを行う際にはCopy
としてマウスポインタの右下にプラス記号が表示されるようにしています。受け入れない場合はNone
で無視します。
さて,実際に判定を行っているのはCanConformsToImageUTI
というメソッドです。OSX 10.4から導入された,Uniform Type Identifier
という識別子を使って,画像ファイルっぽいかどうかを判定しています。
ここではNSString.PathExtension
で取得した拡張子部分が,システムの組み込みUTIのうち,public.image
UTIを継承しているかどうかを調べ,継承している場合にtrue
を返します。24行目で拡張子から最も近いUTIを得て,25行目で組み込みUTIを継承しているかどうか調べています。
では次に,ドロップがビュー内で行われた時の処理を実装していきます。
こちらのほうがシンプルです。判定部分はほとんど同じで,その中でイベントを発動させているだけです。受け入れを行った場合はtrue
を返すようにします。この戻り値はOSX のドロップアニメーションの挙動に影響します。false
の時はドラッグ開始位置にぐいっと戻るようなアニメーションが行われます。
コード全体はこのような感じになります。
次回予告
- ImageSearchEngine の初期化
- 画像,またはURLがドロップされたときの動作をコントローラに実装